*** empty log message ***
This commit is contained in:
parent
ee6388e291
commit
eba04f971b
6 changed files with 491 additions and 10 deletions
|
@ -1,6 +1,13 @@
|
|||
/*
|
||||
** A clone of a famous game.
|
||||
*/
|
||||
// ___________ _________ _____ __
|
||||
// \_ _____/______ ____ ____ \_ ___ \____________ _/ ____\/ |_
|
||||
// | __) \_ __ \_/ __ \_/ __ \/ \ \/\_ __ \__ \\ __\\ __\
|
||||
// | \ | | \/\ ___/\ ___/\ \____| | \// __ \| | | |
|
||||
// \___ / |__| \___ >\___ >\______ /|__| (____ /__| |__|
|
||||
// \/ \/ \/ \/ \/
|
||||
// ______________________ ______________________
|
||||
// T H E W A R B E G I N S
|
||||
// FreeCraft - A free fantasy real time strategy game engine
|
||||
//
|
||||
/**@name action_attack.c - The attack action. */
|
||||
/*
|
||||
** (c) Copyright 1998,1999 by Lutz Sammer
|
||||
|
|
113
ai/ai.cpp
113
ai/ai.cpp
|
@ -16,4 +16,117 @@
|
|||
*/
|
||||
|
||||
#ifdef NEW_AI // {
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Includes
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "clone.h"
|
||||
|
||||
#include "player.h"
|
||||
#include "unit.h"
|
||||
|
||||
#include "ai_local.h"
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Variables
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
global int AiSleep; /// Ai sleeps # frames
|
||||
global int AiTimeFactor = 100; /// Adjust the AI build times
|
||||
global int AiCostFactor = 100; /// Adjust the AI costs
|
||||
|
||||
global AiType* AiTypes; /// List of all AI types.
|
||||
global AiHelper AiHelpers; /// AI helper variables
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Functions
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
** Setup all at start.
|
||||
**
|
||||
** @param player The player structure pointer.
|
||||
*/
|
||||
global void AiInit(Player* player)
|
||||
{
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Callback Functions
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
** Called if a Unit is Attacked
|
||||
**
|
||||
** @param unit Pointer to unit that is being attacked.
|
||||
**
|
||||
*/
|
||||
global void AiHelpMe(Unit* unit)
|
||||
{
|
||||
DebugLevel0(__FUNCTION__": %d %d",unit->X,unit->Y);
|
||||
}
|
||||
|
||||
/**
|
||||
** Called if work complete (Buildings).
|
||||
**
|
||||
** @param unit Pointer to unit what builds the building.
|
||||
** @param what Pointer to unit building that was build.
|
||||
*/
|
||||
global void AiWorkComplete(Unit* unit,Unit* what)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
** Called if building can't be build.
|
||||
**
|
||||
** @param unit Pointer to unit what builds the building.
|
||||
** @param what Pointer to unit-type.
|
||||
*/
|
||||
global void AiCanNotBuild(Unit* unit,const UnitType* what)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
** Called if building place can't be reached.
|
||||
**
|
||||
** @param unit Pointer to unit what builds the building.
|
||||
** @param what Pointer to unit-type.
|
||||
*/
|
||||
global void AiCanNotReach(Unit* unit,const UnitType* what)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
** Called if training of an unit is completed.
|
||||
**
|
||||
** @param unit Pointer to unit.
|
||||
** @param what Pointer to type.
|
||||
*/
|
||||
global void AiTrainingComplete(Unit* unit,Unit* what)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
** This is called for each player, each frame.
|
||||
**
|
||||
** @param player The player structure pointer.
|
||||
*/
|
||||
global void AiEachFrame(Player* player)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
** This called for each player, each second.
|
||||
**
|
||||
** @param player The player structure pointer.
|
||||
*/
|
||||
global void AiEachSecond(Player* player)
|
||||
{
|
||||
// FIXME: Not needed, will be removed.
|
||||
}
|
||||
|
||||
#endif // } NEW_AI
|
||||
|
|
152
ai/ai_local.h
152
ai/ai_local.h
|
@ -20,6 +20,158 @@
|
|||
|
||||
//@{
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Includes
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
#include "player.h"
|
||||
#include "unittype.h"
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Declarations
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
** Ai Script commands.
|
||||
*/
|
||||
enum _ai_script_command_ {
|
||||
AiCmdNeed, /// need building/unit
|
||||
AiCmdBuild, /// build building
|
||||
AiCmdTrain, /// train unit
|
||||
AiCmdResearch, /// research upgrade
|
||||
AiCmdForce, /// Set force.
|
||||
};
|
||||
|
||||
/**
|
||||
** Ai Script.
|
||||
*/
|
||||
typedef struct _ai_script_ {
|
||||
unsigned char Cmd; /// command
|
||||
unsigned char Arg; /// argument
|
||||
unsigned char Cnt; /// counter
|
||||
} AiScript;
|
||||
|
||||
/**
|
||||
** Ai Type typedef.
|
||||
*/
|
||||
typedef struct _ai_type_ AiType;
|
||||
|
||||
/**
|
||||
** Ai Type structure.
|
||||
*/
|
||||
struct _ai_type_ {
|
||||
AiType* Next; /// Next ai type.
|
||||
|
||||
char* Name; /// Name of this ai.
|
||||
char* Race; /// for this race.
|
||||
char* Class; /// class of this ai.
|
||||
|
||||
// nice flags
|
||||
unsigned char AllExplored : 1; /// Ai sees unexplored area.
|
||||
unsigned char AllVisibile : 1; /// Ai sees invisibile area.
|
||||
|
||||
AiScript* Script; /// Main script
|
||||
};
|
||||
|
||||
/**
|
||||
** AI goal typedef.
|
||||
*/
|
||||
typedef struct _ai_goal_ AiGoal;
|
||||
|
||||
/**
|
||||
** AI Priority, will later be finer tuned.
|
||||
*/
|
||||
enum _ai_priority_ {
|
||||
AiPriorityVeryLow, /// very low
|
||||
AiPriorityLow, /// low
|
||||
AiPriorityMid, /// middle
|
||||
AiPriorityHigh, /// high
|
||||
AiPriorityVeryHigh, /// very high
|
||||
};
|
||||
|
||||
/**
|
||||
** Define the AI goals.
|
||||
*/
|
||||
struct _ai_goal_ {
|
||||
AiGoal* Next; /// double linked list of all goals
|
||||
AiGoal* Down; /// dependend goals.
|
||||
AiGoal* Prev; /// double linked list of all goals
|
||||
int Priority; /// Priority of this goal.
|
||||
};
|
||||
|
||||
/**
|
||||
** AI variables.
|
||||
*/
|
||||
typedef struct _player_ai_ {
|
||||
Player* Player; /// engine player structure.
|
||||
|
||||
AiType* AiType; /// AI type of this player AI.
|
||||
|
||||
// goals stuff.
|
||||
AiGoal* GoalHead; /// goals start of double linked list
|
||||
AiGoal* GoalNil1; /// goals dummy end of dl-list
|
||||
AiGoal* GoalTail; /// goals end of double linked list
|
||||
|
||||
AiGoal* WaitHead; /// wait start of double linked list
|
||||
AiGoal* WaitNil1; /// wait dummy end of dl-list
|
||||
AiGoal* WaitTail; /// wait end of double linked list
|
||||
|
||||
// scripting stuff.
|
||||
AiScript* Ip; /// AI script instruction pointer.
|
||||
AiScript** Sp; /// Ai script stack pointer.
|
||||
AiScript** Stack; /// Ai script stack.
|
||||
|
||||
UnitType* Priority[256]; /// Building order
|
||||
} PlayerAi;
|
||||
|
||||
/**
|
||||
** AI Unittable with counter in front.
|
||||
*/
|
||||
typedef struct _ai_unittable_ {
|
||||
unsigned Count; /// elements in table
|
||||
UnitType* Table[0]; /// the table (GNU feature used)
|
||||
} AiUnitTable;
|
||||
|
||||
/**
|
||||
** AI Helper.
|
||||
*/
|
||||
typedef struct _ai_helper_ {
|
||||
/**
|
||||
** The index is the unit that should be trained, giving a table of all
|
||||
** units/buildings which could train this unit.
|
||||
*/
|
||||
int TrainCount;
|
||||
AiUnitTable* Train;
|
||||
/**
|
||||
** The index is the unit that should be build, giving a table of all
|
||||
** units/buildings which could build this unit.
|
||||
*/
|
||||
int BuildCount;
|
||||
AiUnitTable* Build;
|
||||
/**
|
||||
** The index is the upgrade that should be made, giving a table of all
|
||||
** units/buildings which could do the upgrade.
|
||||
*/
|
||||
int UpgradeCount;
|
||||
AiUnitTable* Upgrade;
|
||||
/**
|
||||
** The index is the research that should be made, giving a table of all
|
||||
** units/buildings which could research this upgrade.
|
||||
*/
|
||||
int ResearchCount;
|
||||
AiUnitTable* Research;
|
||||
} AiHelper;
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Variables
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
extern AiType* AiTypes; /// List of all AI types.
|
||||
extern AiHelper AiHelpers; /// AI helper variables
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Functions
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
//@}
|
||||
|
||||
|
|
205
ai/script_ai.cpp
205
ai/script_ai.cpp
|
@ -17,19 +17,222 @@
|
|||
|
||||
//@{
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Includes
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "clone.h"
|
||||
|
||||
#if defined(USE_CCL) || defined(USE_CCL2) // {
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "unittype.h"
|
||||
#include "ccl.h"
|
||||
#include "ai_local.h"
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Functions
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
** Setup AI helper table.
|
||||
*/
|
||||
local void AiHelperSetupTable(int* count,AiUnitTable** table,UnitType* type)
|
||||
{
|
||||
if( type->Type>=*count ) {
|
||||
if( *table ) {
|
||||
*table=realloc(*table,(1+type->Type)*sizeof(UnitType*));
|
||||
memset(*table+*count,0,((1+type->Type)-*count)*sizeof(UnitType*));
|
||||
} else {
|
||||
*table=malloc((1+type->Type)*sizeof(UnitType*));
|
||||
memset(*table,0,(1+type->Type)*sizeof(UnitType*));
|
||||
}
|
||||
*count=type->Type+1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
** Insert new element.
|
||||
*/
|
||||
local void AiHelperInsert(AiUnitTable** table,UnitType* base)
|
||||
{
|
||||
int i;
|
||||
int n;
|
||||
|
||||
if( !*table ) {
|
||||
*table=malloc(sizeof(AiUnitTable*)+sizeof(UnitType*));
|
||||
(*table)->Count=1;
|
||||
(*table)->Table[0]=base;
|
||||
return;
|
||||
}
|
||||
n=(*table)->Count;
|
||||
for( i=0; i<n; ++i ) {
|
||||
if( (*table)->Table[i]==base ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
n++;
|
||||
*table=realloc(*table,sizeof(AiUnitTable*)+sizeof(UnitType*)*n);
|
||||
(*table)->Count=n;
|
||||
(*table)->Table[n-1]=base;
|
||||
}
|
||||
|
||||
/**
|
||||
** Define helper for Ai.
|
||||
*/
|
||||
local SCM CclDefineAiHelper(SCM list)
|
||||
{
|
||||
SCM sub_list;
|
||||
SCM value;
|
||||
int what;
|
||||
char* str;
|
||||
UnitType* base;
|
||||
UnitType* type;
|
||||
|
||||
while( !gh_null_p(list) ) {
|
||||
sub_list=gh_car(list);
|
||||
list=gh_cdr(list);
|
||||
|
||||
//
|
||||
// Type build,train,research/upgrade.
|
||||
//
|
||||
value=gh_car(sub_list);
|
||||
sub_list=gh_cdr(sub_list);
|
||||
if( gh_eq_p(value,gh_symbol2scm("build")) ) {
|
||||
what=0;
|
||||
} else if( gh_eq_p(value,gh_symbol2scm("train")) ) {
|
||||
what=1;
|
||||
} else if( gh_eq_p(value,gh_symbol2scm("upgrade")) ) {
|
||||
what=2;
|
||||
} else if( gh_eq_p(value,gh_symbol2scm("research")) ) {
|
||||
what=3;
|
||||
} else {
|
||||
fprintf(stderr,"unknown tag");
|
||||
continue;
|
||||
}
|
||||
//
|
||||
// Get the base unit type, which could handle the action.
|
||||
//
|
||||
value=gh_car(sub_list);
|
||||
sub_list=gh_cdr(sub_list);
|
||||
str=gh_scm2newstr(value,NULL);
|
||||
base=UnitTypeByIdent(str);
|
||||
if( !base ) {
|
||||
fprintf(stderr,"unknown unittype %s",str);
|
||||
free(str);
|
||||
continue;
|
||||
}
|
||||
DebugLevel0(__FUNCTION__": %s\n",base->Name);
|
||||
free(str);
|
||||
|
||||
//
|
||||
// Get the unit types, which could be produced
|
||||
//
|
||||
while( !gh_null_p(sub_list) ) {
|
||||
value=gh_car(sub_list);
|
||||
sub_list=gh_cdr(sub_list);
|
||||
str=gh_scm2newstr(value,NULL);
|
||||
type=UnitTypeByIdent(str);
|
||||
if( !type ) {
|
||||
fprintf(stderr,"unknown unittype %s",str);
|
||||
free(str);
|
||||
continue;
|
||||
}
|
||||
DebugLevel0(__FUNCTION__": > %s\n",type->Name);
|
||||
free(str);
|
||||
|
||||
switch( what ) {
|
||||
case 0: // build
|
||||
AiHelperSetupTable(
|
||||
&AiHelpers.BuildCount,&AiHelpers.Build,type);
|
||||
AiHelperInsert(
|
||||
&AiHelpers.Build+type->Type,base);
|
||||
break;
|
||||
case 1: // train
|
||||
AiHelperSetupTable(
|
||||
&AiHelpers.TrainCount,&AiHelpers.Train,type);
|
||||
AiHelperInsert(
|
||||
&AiHelpers.Train+type->Type,base);
|
||||
break;
|
||||
case 2: // upgrade
|
||||
AiHelperSetupTable(
|
||||
&AiHelpers.UpgradeCount,&AiHelpers.Upgrade,type);
|
||||
AiHelperInsert(
|
||||
&AiHelpers.Upgrade+type->Type,base);
|
||||
break;
|
||||
case 3: // research
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
** Define an Ai engine.
|
||||
*/
|
||||
local SCM CclDefineAi(SCM list)
|
||||
{
|
||||
SCM sub_list;
|
||||
SCM value;
|
||||
char* str;
|
||||
AiType* aitype;
|
||||
|
||||
aitype=malloc(sizeof(AiType));
|
||||
aitype->Next=AiTypes;
|
||||
AiTypes=aitype;
|
||||
|
||||
//
|
||||
// AI Name
|
||||
//
|
||||
value=gh_car(list);
|
||||
list=gh_cdr(list);
|
||||
str=gh_scm2newstr(value,NULL);
|
||||
DebugLevel0(__FUNCTION__": %s\n",str);
|
||||
aitype->Name=str;
|
||||
|
||||
//
|
||||
// AI Race
|
||||
//
|
||||
value=gh_car(list);
|
||||
list=gh_cdr(list);
|
||||
str=gh_scm2newstr(value,NULL);
|
||||
DebugLevel0(__FUNCTION__": %s\n",str);
|
||||
aitype->Race=str;
|
||||
|
||||
//
|
||||
// AI Class
|
||||
//
|
||||
value=gh_car(list);
|
||||
list=gh_cdr(list);
|
||||
str=gh_scm2newstr(value,NULL);
|
||||
DebugLevel0(__FUNCTION__": %s\n",str);
|
||||
aitype->Class=str;
|
||||
|
||||
//
|
||||
// AI Script
|
||||
//
|
||||
list=gh_car(list);
|
||||
while( !gh_null_p(list) ) {
|
||||
sub_list=gh_car(list);
|
||||
list=gh_cdr(list);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
** Register CCL features for unit-type.
|
||||
*/
|
||||
global void AiCclRegister(void)
|
||||
{
|
||||
// FIXME: Need to save memory here.
|
||||
// Loading all into memory isn't necessary.
|
||||
|
||||
gh_new_procedureN("define-ai-helper",CclDefineAiHelper);
|
||||
gh_new_procedureN("define-ai",CclDefineAi);
|
||||
}
|
||||
|
||||
#endif // } USE_CCL && USE_CCL2
|
||||
|
|
|
@ -79,6 +79,7 @@ extern void sgtk_init_gtk_gdk_glue();
|
|||
#include "ccl_sound.h"
|
||||
#include "ui.h"
|
||||
#include "font.h"
|
||||
#include "ai.h"
|
||||
|
||||
#endif // USE_CCL2
|
||||
|
||||
|
@ -763,6 +764,8 @@ global void CclInit(void)
|
|||
{
|
||||
char* sargv[5];
|
||||
char buf[1024];
|
||||
char* file;
|
||||
extern char* LibraryFileName(const char* file,char* buffer);
|
||||
|
||||
sargv[0] = "FreeCraft";
|
||||
sargv[1] = "-v1";
|
||||
|
@ -773,7 +776,7 @@ global void CclInit(void)
|
|||
#else
|
||||
sprintf(buf,"-l%s",FreeCraftLibPath);
|
||||
#endif
|
||||
sargv[4] = buf;
|
||||
sargv[4] = strdup(buf);
|
||||
siod_init(5,sargv);
|
||||
|
||||
init_subr_0("library-path",CclFreeCraftLibraryPath);
|
||||
|
@ -816,6 +819,7 @@ global void CclInit(void)
|
|||
SoundCclRegister();
|
||||
FontsCclRegister();
|
||||
UserInterfaceCclRegister();
|
||||
AiCclRegister();
|
||||
|
||||
init_subr_1("load-pud",CclLoadPud);
|
||||
init_subr_2("define-map",CclDefineMap);
|
||||
|
@ -830,7 +834,9 @@ global void CclInit(void)
|
|||
// Load and evaluate configuration file
|
||||
//
|
||||
CclInConfigFile=1;
|
||||
vload("data/ccl/freecraft.ccl",0,1);
|
||||
//file=LibraryFileName("freecraft.ccl",buf);
|
||||
file=LibraryFileName("ccl/freecraft.ccl",buf);
|
||||
vload(file,0,1);
|
||||
CclInConfigFile=0;
|
||||
}
|
||||
|
||||
|
|
|
@ -818,13 +818,13 @@ global ButtonAction AllButtons[] = {
|
|||
{ 2, 0, { "icon-human-shield2" },
|
||||
B_Research, 0, "upgrade-human-shield1",
|
||||
bc_CheckUpgrade, NULL,
|
||||
's', "UPGRADE ~!SHIELDS (Damage +2)",
|
||||
's', "UPGRADE ~!SHIELDS (Armor +2)",
|
||||
"unit-human-blacksmith"
|
||||
},
|
||||
{ 2, 0, { "icon-human-shield3" },
|
||||
B_Research, 0, "upgrade-human-shield2",
|
||||
bc_CheckUpgrade, NULL,
|
||||
's', "UPGRADE ~!SHIELDS (Damage +2)",
|
||||
's', "UPGRADE ~!SHIELDS (Armor +2)",
|
||||
"unit-human-blacksmith"
|
||||
},
|
||||
{ 3, 0, { "icon-ballista1" },
|
||||
|
@ -1561,13 +1561,13 @@ global ButtonAction AllButtons[] = {
|
|||
{ 2, 0, { "icon-orc-shield2" },
|
||||
B_Research, 0, "upgrade-orc-shield1",
|
||||
bc_CheckUpgrade, NULL,
|
||||
's', "UPGRADE ~!SHIELDS (Damage +2)",
|
||||
's', "UPGRADE ~!SHIELDS (Armor +2)",
|
||||
"unit-orc-blacksmith"
|
||||
},
|
||||
{ 2, 0, { "icon-orc-shield3" },
|
||||
B_Research, 0, "upgrade-orc-shield2",
|
||||
bc_CheckUpgrade, NULL,
|
||||
's', "UPGRADE ~!SHIELDS (Damage +2)",
|
||||
's', "UPGRADE ~!SHIELDS (Armor +2)",
|
||||
"unit-orc-blacksmith"
|
||||
},
|
||||
{ 3, 0, { "icon-catapult1" },
|
||||
|
|
Loading…
Add table
Reference in a new issue