First version of triggers.

This commit is contained in:
johns 2002-03-03 01:21:07 +00:00
parent 99e1b58f77
commit 5530e9e42f
10 changed files with 385 additions and 44 deletions

View file

@ -37,6 +37,7 @@
#include "unittype.h"
#include "map.h"
#include "campaign.h"
#include "settings.h"
/*----------------------------------------------------------------------------
-- Declarations
@ -246,12 +247,94 @@ local SCM CclDefineCampaign(SCM list)
return SCM_UNSPECIFIED;
}
/**
** Set the briefing.
**
** @param list List describing the briefing.
*/
local SCM CclBriefing(SCM list)
{
SCM value;
int voice;
int objective;
voice=objective=0;
//
// Parse the list: (still everything could be changed!)
//
while( !gh_null_p(list) ) {
value=gh_car(list);
list=gh_cdr(list);
if( gh_eq_p(value,gh_symbol2scm("type")) ) {
if( !gh_eq_p(gh_car(list),gh_symbol2scm("wc2")) ) {
// FIXME: this leaves a half initialized briefing
errl("Unsupported briefing type",value);
}
list=gh_cdr(list);
} else if ( gh_eq_p(value,gh_symbol2scm("title")) ) {
if( GameIntro.Title ) {
free(GameIntro.Title);
}
GameIntro.Title=gh_scm2newstr(gh_car(list),NULL);
list=gh_cdr(list);
} else if ( gh_eq_p(value,gh_symbol2scm("background")) ) {
if( GameIntro.Background ) {
free(GameIntro.Background);
}
GameIntro.Background=gh_scm2newstr(gh_car(list),NULL);
list=gh_cdr(list);
} else if ( gh_eq_p(value,gh_symbol2scm("text")) ) {
if( GameIntro.TextFile ) {
free(GameIntro.TextFile);
}
GameIntro.TextFile=gh_scm2newstr(gh_car(list),NULL);
list=gh_cdr(list);
} else if ( gh_eq_p(value,gh_symbol2scm("voice")) ) {
switch( voice ) {
case 0:
if( GameIntro.VoiceFile1 ) {
free(GameIntro.VoiceFile1);
}
GameIntro.VoiceFile1=gh_scm2newstr(gh_car(list),NULL);
break;
case 1:
if( GameIntro.VoiceFile2 ) {
free(GameIntro.VoiceFile2);
}
GameIntro.VoiceFile2=gh_scm2newstr(gh_car(list),NULL);
break;
default:
errl("Only two voice",value);
}
list=gh_cdr(list);
} else if ( gh_eq_p(value,gh_symbol2scm("objective")) ) {
if( objective==MAX_OBJECTIVES ) {
errl("Only too much objectives",value);
}
if( GameIntro.Objectives[objective] ) {
free(GameIntro.Objectives[objective]);
}
GameIntro.Objectives[objective]=gh_scm2newstr(gh_car(list),NULL);
list=gh_cdr(list);
++objective;
} else {
// FIXME: this leaves a half initialized briefing
errl("Unsupported tag",value);
}
}
return SCM_UNSPECIFIED;
}
/**
** Register CCL features for campaigns.
*/
global void CampaignCclRegister(void)
{
gh_new_procedureN("define-campaign",CclDefineCampaign);
gh_new_procedureN("briefing",CclBriefing);
}
/**
@ -269,8 +352,32 @@ global void SaveCampaign(FILE* file)
*/
global void CleanCampaign(void)
{
int i;
// FIXME: Can't clean campaign needed for continue.
DebugLevel0Fn("FIXME: Cleaning campaign not written\n");
if( GameIntro.Title ) {
free(GameIntro.Title);
}
if( GameIntro.Background ) {
free(GameIntro.Background);
}
if( GameIntro.TextFile ) {
free(GameIntro.TextFile);
}
if( GameIntro.VoiceFile2 ) {
free(GameIntro.VoiceFile1);
}
if( GameIntro.VoiceFile2 ) {
free(GameIntro.VoiceFile2);
}
for( i=0; i<MAX_OBJECTIVES; ++i ) {
if( GameIntro.Objectives[i] ) {
free(GameIntro.Objectives[i]);
}
}
memset(&GameIntro,0,sizeof(GameIntro));
}
//@}

View file

@ -196,7 +196,9 @@ global void CreateGame(char* filename, WorldMap* map)
}
}
ShowIntro();
if( GameIntro.Title ) {
ShowIntro(&GameIntro);
}
if( FlagRevealMap ) {
RevealMap();

View file

@ -39,40 +39,17 @@
#include "network.h"
#include "sound_server.h"
#include "sound.h"
#include "settings.h"
/*----------------------------------------------------------------------------
-- Declarations
----------------------------------------------------------------------------*/
#define MAX_OBJECTIVES 9
typedef struct _intro_ {
char* Title; /// Intro title
char* Background; /// Background picture
char* TextFile; /// Intro text file
char* VoiceFile1; /// Intro voice file
char* VoiceFile2; /// Intro voice file
char* Objectives[MAX_OBJECTIVES]; /// Objectives
} Intro; /// Intro definition
/*----------------------------------------------------------------------------
-- Variables
----------------------------------------------------------------------------*/
local Intro MyIntro[1] = {
{
"I. Welcome to FreeCraft",
"campaigns/human/interface/introscreen1.png",
"campaigns/human/level01h.txt.gz",
"campaigns/human/level01h-intro1.wav.gz",
"campaigns/human/level01h-intro2.wav.gz",
{
"- This is a dummy intro",
"- Kill all enemies",
"- Be the lonly surivor",
},
}
};
global Intro GameIntro; /// Game intro
/*----------------------------------------------------------------------------
-- Functions
@ -182,7 +159,7 @@ local void ScrollText(int x,int y,int i,const char* text)
**
** First version - only testing.
*/
global void ShowIntro(void)
global void ShowIntro(const Intro *intro)
{
EventCallback callbacks;
Graphic* background;
@ -192,13 +169,10 @@ global void ShowIntro(void)
int l;
int x;
int y;
const Intro* intro;
CLFile* file;
char buf[1024];
int stage;
intro=MyIntro;
VideoLockScreen();
VideoFillRectangle(ColorBlack,0,0,VideoWidth,VideoHeight);
VideoUnlockScreen();

View file

@ -46,6 +46,7 @@
#include "ui.h"
#include "ai.h"
#include "campaign.h"
#include "trigger.h"
/*----------------------------------------------------------------------------
-- Variables
@ -68,6 +69,7 @@ global void CleanModules(void)
CleanCursors();
CleanUserInterface();
CleanCampaign();
CleanTriggers();
CleanAi();
CleanPlayers();
CleanConstructions();

View file

@ -51,6 +51,7 @@
#include "player.h"
#include "ai.h"
#include "campaign.h"
#include "trigger.h"
#include "ccl.h"
@ -105,6 +106,7 @@ global void SaveGame(const char* filename)
SaveGroups(file);
SaveMissiles(file);
SaveAi(file);
SaveTriggers(file);
SaveCampaign(file);
// FIXME: find all state information which must be saved.

View file

@ -33,31 +33,247 @@
#include <stdlib.h>
#include <string.h>
#include "freecraft.h"
#include "ccl.h"
#include "unittype.h"
#include "player.h"
#include "trigger.h"
#include "campaign.h"
#include "interface.h"
/*----------------------------------------------------------------------------
-- Declarations
----------------------------------------------------------------------------*/
/// Get unit-type.
extern UnitType* CclGetUnitType(SCM ptr);
#define ANY_UNIT ((const UnitType*)0)
#define ALL_UNITS ((const UnitType*)-1)
#define ALL_FOODUNITS ((const UnitType*)-2)
#define ALL_BUILDINGS ((const UnitType*)-3)
/*----------------------------------------------------------------------------
-- Variables
----------------------------------------------------------------------------*/
local SCM Trigger; /// Current trigger
/*----------------------------------------------------------------------------
-- Functions
----------------------------------------------------------------------------*/
/**
** Get player number.
**
** @param player The player
**
** @return The player number, -1 matches any.
*/
local int TriggerGetPlayer(SCM player)
{
int ret;
if (gh_exact_p(player)) {
ret = gh_scm2int(player);
if (ret < 0 || ret > PlayerMax) {
errl("bad player", player);
}
return ret;
}
if (gh_eq_p(player, gh_symbol2scm("any"))) {
return -1;
} else if (gh_eq_p(player, gh_symbol2scm("this"))) {
return ThisPlayer->Player;
}
errl("bad player", player);
return 0;
}
/**
** Get the unit-type.
**
** @param unit The unit type.
**
** @return The unit-type pointer.
*/
local const UnitType* TriggerGetUnitType(SCM unit)
{
if (gh_eq_p(unit, gh_symbol2scm("any"))) {
return ANY_UNIT;
} else if (gh_eq_p(unit, gh_symbol2scm("all"))) {
return ALL_UNITS;
} else if (gh_eq_p(unit, gh_symbol2scm("units"))) {
return ALL_FOODUNITS;
} else if (gh_eq_p(unit, gh_symbol2scm("buildings"))) {
return ALL_BUILDINGS;
}
return CclGetUnitType(unit);
}
// --------------------------------------------------------------------------
// Conditions
/**
** Player has the quantity of unit-type.
*/
local SCM CclIfUnit(SCM player,SCM quantity,SCM unit)
{
int plynr;
int q;
int pn;
const UnitType* unittype;
plynr=TriggerGetPlayer(player);
q=gh_scm2int(quantity);
unittype=TriggerGetUnitType(unit);
if( plynr==-1 ) {
plynr=0;
pn=PlayerMax;
} else {
pn=plynr+1;
}
if( unittype==ANY_UNIT ) {
for( ; plynr<pn; ++plynr ) {
int j;
for( j=0; j<NumUnitTypes; ++j ) {
if( Players[plynr].UnitTypesCount[j]==q ) {
return SCM_BOOL_T;
}
}
}
} else if( unittype==ALL_UNITS ) {
for( ; plynr<pn; ++plynr ) {
if( Players[plynr].TotalNumUnits==q ) {
return SCM_BOOL_T;
}
}
} else if( unittype==ALL_FOODUNITS ) {
for( ; plynr<pn; ++plynr ) {
if( Players[plynr].NumFoodUnits==q ) {
return SCM_BOOL_T;
}
}
} else if( unittype==ALL_BUILDINGS ) {
for( ; plynr<pn; ++plynr ) {
if( Players[plynr].NumBuildings==q ) {
return SCM_BOOL_T;
}
}
} else {
for( ; plynr<pn; ++plynr ) {
DebugLevel3Fn("Player%d, %d == %s\n",plynr,q,unittype->Ident);
if( Players[plynr].UnitTypesCount[unittype->Type]==q ) {
return SCM_BOOL_T;
}
}
}
return SCM_BOOL_F;
}
// --------------------------------------------------------------------------
// Actions
/**
** Action condition player wins.
*/
local SCM CclActionVictory(void)
{
GameResult=GameVictory;
GamePaused=1;
GameRunning=0;
return SCM_UNSPECIFIED;
}
/**
** Action condition player lose.
*/
local SCM CclActionDefeat(void)
{
GameResult=GameDefeat;
GamePaused=1;
GameRunning=0;
return SCM_UNSPECIFIED;
}
/**
** Action condition player draw.
*/
local SCM CclActionDraw(void)
{
GameResult=GameDraw;
GamePaused=1;
GameRunning=0;
return SCM_UNSPECIFIED;
}
/**
** Add a trigger.
*/
local SCM CclAddTrigger(SCM condition,SCM action)
{
SCM var;
//
// Make a list of all triggers.
// A trigger is a pair of condition and action
//
var=gh_symbol2scm("*triggers*");
setvar(var,cons(cons(condition,action),symbol_value(var,NIL)),NIL);
return SCM_UNSPECIFIED;
}
/**
** Check trigger each frame.
*/
global void TriggersEachFrame(void)
{
SCM pair;
SCM val;
if( !Trigger ) {
Trigger=symbol_value(gh_symbol2scm("*triggers*"),NIL);
}
if( !gh_null_p(Trigger) ) { // Next trigger
pair=gh_car(Trigger);
Trigger=gh_cdr(Trigger);
if( !gh_null_p(val=gh_apply(car(pair),NIL)) ) {
gh_apply(cdr(pair),NIL);
}
} else {
Trigger=NULL;
}
}
/**
** Register CCL features for triggers.
*/
global void TriggerCclRegister(void)
{
gh_new_procedure2_0("add-trigger",CclAddTrigger);
// Conditions
gh_new_procedure3_0("if-unit",CclIfUnit);
// Actions
gh_new_procedure0_0("action-victory",CclActionVictory);
gh_new_procedure0_0("action-defeat",CclActionDefeat);
gh_new_procedure0_0("action-draw",CclActionDraw);
gh_define("*triggers*",NIL);
}
/**
** Save the trigger module.
*/
global void SaveTrigger(FILE* file)
global void SaveTriggers(FILE* file)
{
fprintf(file,"\n;;; -----------------------------------------\n");
fprintf(file,";;; MODULE: trigger $Id$\n\n");
@ -67,9 +283,16 @@ global void SaveTrigger(FILE* file)
/**
** Clean up the trigger module.
*/
global void CleanTrigger(void)
global void CleanTriggers(void)
{
SCM var;
DebugLevel0Fn("FIXME: Cleaning trigger not written\n");
var=gh_symbol2scm("*triggers*");
setvar(var,NIL,NIL);
Trigger=NULL;
}
//@}

View file

@ -38,6 +38,7 @@ typedef struct _settings_ Settings;
#endif
#include "player.h"
#include "map.h"
/*----------------------------------------------------------------------------
-- Settings __WIP__
@ -56,15 +57,15 @@ struct _settings_ {
// Individual presets:
// For single-player game only Presets[0] will be used..
struct {
unsigned Race; /// race of the player
unsigned Team; /// team of player -- NOT SELECTABLE YET
unsigned Race; /// Race of the player
unsigned Team; /// Team of player -- NOT SELECTABLE YET
} Presets[PlayerMax];
// Common settings:
unsigned Resources; /// preset resource factor
unsigned NumUnits; /// preset # of units
unsigned Opponents; /// preset # of ai-opponents
unsigned Terrain; /// terrain type (summer,winter,...)
unsigned Resources; /// Preset resource factor
unsigned NumUnits; /// Preset # of units
unsigned Opponents; /// Preset # of ai-opponents
unsigned Terrain; /// Terrain type (summer,winter,...)
};
#define SettingsPresetMapDefault (~0ul) /// Special: Use pud/cm supplied
@ -83,19 +84,32 @@ struct _settings_ {
#define SettingsNumUnitsMapDefault SettingsPresetMapDefault
#define SettingsNumUnits1 0
/*----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
#define MAX_OBJECTIVES 9
typedef struct _intro_ {
char* Title; /// Intro title
char* Background; /// Background picture
char* TextFile; /// Intro text file
char* VoiceFile1; /// Intro voice file
char* VoiceFile2; /// Intro voice file
char* Objectives[MAX_OBJECTIVES]; /// Objectives
} Intro; /// Intro definition
/*----------------------------------------------------------------------------
-- Variables
----------------------------------------------------------------------------*/
extern Settings GameSettings; /// Game Settings
extern Settings GameSettings; /// Game settings
extern Intro GameIntro; /// Game intro
/*----------------------------------------------------------------------------
-- Functions
----------------------------------------------------------------------------*/
/// Show level intro
extern void ShowIntro(void);
extern void ShowIntro(const Intro* intro);
/// Create a game
extern void CreateGame(char* filename,WorldMap* map);
/// Init Setting to default values

View file

@ -40,11 +40,11 @@
-- Functions
----------------------------------------------------------------------------*/
extern void CheckTriggers(void); /// test all triggers
extern void TriggersEachFrame(void); /// test triggers
extern void TriggerCclRegister(void); /// Register ccl features
extern void SaveTrigger(FILE*); /// Save the trigger module
extern void CleanTrigger(void); /// Cleanup the trigger module
extern void SaveTriggers(FILE*); /// Save the trigger module
extern void CleanTriggers(void); /// Cleanup the trigger module
//@}

View file

@ -51,6 +51,8 @@
#include "goal.h"
#include "ui.h"
#include "deco.h"
#include "trigger.h"
#include "campaign.h"
#ifdef USE_SDL
// FIXME: move to system api part!
@ -451,6 +453,7 @@ global void GameMainLoop(void)
UnitActions(); // handle units
MissileActions(); // handle missiles
PlayersEachFrame(); // handle players
TriggersEachFrame(); // handle triggers
MustRedraw&=~RedrawMinimap; // FIXME: this a little hack!
@ -527,6 +530,18 @@ global void GameMainLoop(void)
WaitEventsAndKeepSync();
}
NetworkQuit();
if( GameResult==GameDefeat ) {
fprintf(stderr,"You have lost!\n");
SetStatusLine("You have lost!");
ProcessMenu(MENU_LOST, 1);
}
if( GameResult==GameVictory ) {
fprintf(stderr,"You have won!\n");
SetStatusLine("You have won!");
ProcessMenu(MENU_VICTORY, 1);
}
}
//@}

View file

@ -52,6 +52,7 @@
#include "pathfinder.h"
#include "ai.h"
#include "campaign.h"
#include "trigger.h"
/*----------------------------------------------------------------------------
-- Variables
@ -574,6 +575,7 @@ global void InitCcl(void)
UserInterfaceCclRegister();
AiCclRegister();
CampaignCclRegister();
TriggerCclRegister();
init_subr_1("load-pud",CclLoadPud);
init_subr_2("define-map",CclDefineMap);