From eba04f971b16180c88075d52fddc80c5145b9080 Mon Sep 17 00:00:00 2001
From: johns <>
Date: Sun, 2 Apr 2000 01:32:18 +0000
Subject: [PATCH] *** empty log message ***

---
 action/action_attack.cpp |  13 ++-
 ai/ai.cpp                | 113 +++++++++++++++++++++
 ai/ai_local.h            | 152 +++++++++++++++++++++++++++++
 ai/script_ai.cpp         | 205 ++++++++++++++++++++++++++++++++++++++-
 stratagus/script.cpp     |  10 +-
 ui/button_table.cpp      |   8 +-
 6 files changed, 491 insertions(+), 10 deletions(-)

diff --git a/action/action_attack.cpp b/action/action_attack.cpp
index eb016508b..e2bc846cd 100644
--- a/action/action_attack.cpp
+++ b/action/action_attack.cpp
@@ -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
diff --git a/ai/ai.cpp b/ai/ai.cpp
index 69d4ec507..d31a2af9c 100644
--- a/ai/ai.cpp
+++ b/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
diff --git a/ai/ai_local.h b/ai/ai_local.h
index 22dafb536..a3e2253e5 100644
--- a/ai/ai_local.h
+++ b/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
+----------------------------------------------------------------------------*/
 
 //@}
 
diff --git a/ai/script_ai.cpp b/ai/script_ai.cpp
index f21ec07a4..5f774eac4 100644
--- a/ai/script_ai.cpp
+++ b/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
diff --git a/stratagus/script.cpp b/stratagus/script.cpp
index 0612b400f..61a5f7b48 100644
--- a/stratagus/script.cpp
+++ b/stratagus/script.cpp
@@ -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;
 }
 
diff --git a/ui/button_table.cpp b/ui/button_table.cpp
index 6ceac6857..c79cce2e2 100644
--- a/ui/button_table.cpp
+++ b/ui/button_table.cpp
@@ -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" },