From 6b6f16cfe753ae16af50406717ec4f389fbba86d Mon Sep 17 00:00:00 2001
From: jsalmon3 <>
Date: Thu, 26 Sep 2002 21:06:56 +0000
Subject: [PATCH] Fixed bug #611416: Objectives not saved

---
 doc/ChangeLog.html       |   1 +
 src/game/intro.cpp       | 104 +++++++++++++++++++++++++++++++++++++++
 src/game/savegame.cpp    |   2 +
 src/include/settings.h   |   6 ++-
 src/stratagus/script.cpp |   1 +
 5 files changed, 113 insertions(+), 1 deletion(-)

diff --git a/doc/ChangeLog.html b/doc/ChangeLog.html
index edb43a600..8ce62731b 100644
--- a/doc/ChangeLog.html
+++ b/doc/ChangeLog.html
@@ -943,6 +943,7 @@
 	Thierbach).
     <LI>Fixed bug #594439: Peasant Repairs when no resources (from Russell
 	Smith).
+    <LI>Fixed bug #611416: Objectives not saved (from Jimmy Salmon).
     <LI>+++
     </UL>
 </UL>
diff --git a/src/game/intro.cpp b/src/game/intro.cpp
index c04f60c6d..30525e830 100644
--- a/src/game/intro.cpp
+++ b/src/game/intro.cpp
@@ -1274,4 +1274,108 @@ global void CreditsCclRegister(void)
     gh_new_procedureN("credits",CclCredits);
 }
 
+/**
+**	Parse the add objective ccl function
+**
+**	The list contains the objective text followed by an optional number
+**	specifying where in the list it should be added.  If no number is
+**	given it is added at the end.
+*/
+local SCM CclAddObjective(SCM list)
+{
+    int i;
+    const char *obj;
+
+    obj=get_c_string(gh_car(list));
+
+    list=gh_cdr(list);
+    if( !gh_null_p(list) ) {
+	// Optional location number given
+	int num;
+
+	num=gh_scm2int(gh_car(list));
+	if( num<0 ) {
+	    num=0;
+	}
+
+	i=0;
+	while( i!=MAX_OBJECTIVES && GameIntro.Objectives[i] ) {
+	    ++i;
+	}
+	if( i==MAX_OBJECTIVES ) {
+	    fprintf(stderr,"Too many objectives: %s\n",obj);
+	    ExitFatal(-1);
+	}
+	if( num>i ) {
+	    num=i;
+	}
+	for( ; i>num; --i ) {
+	    GameIntro.Objectives[i]=GameIntro.Objectives[i-1];
+	}
+	GameIntro.Objectives[num]=strdup(obj);
+    } else {
+	// Add objective to the end of the list
+	i=0;
+	while( i!=MAX_OBJECTIVES && GameIntro.Objectives[i] ) {
+	    ++i;
+	}
+	if( i==MAX_OBJECTIVES ) {
+	    fprintf(stderr,"Too many objectives: %s\n",obj);
+	    ExitFatal(-1);
+	}
+	GameIntro.Objectives[i]=strdup(obj);
+    }
+
+    return SCM_UNSPECIFIED;
+}
+
+/**
+**	Parse the remove objective ccl function
+*/
+local SCM CclRemoveObjective(SCM objective)
+{
+    int num;
+
+    num=gh_scm2int(objective);
+    if( num<0 || num>=MAX_OBJECTIVES ) {
+	fprintf(stderr,"remove-objective: Invalid number: %d\n",num);
+	ExitFatal(-1);
+    }
+    if( !GameIntro.Objectives[num] ) {
+	fprintf(stderr,"remove-objective: No objective at location: %d\n",num);
+	ExitFatal(-1);
+    }
+
+    free(GameIntro.Objectives[num]);
+
+    if( num==MAX_OBJECTIVES-1 ) {
+	GameIntro.Objectives[num]=NULL;
+    }
+    for( ; num<MAX_OBJECTIVES-1 && GameIntro.Objectives[num]; ++num ) {
+	GameIntro.Objectives[num]=GameIntro.Objectives[num+1];
+    }
+
+    return SCM_UNSPECIFIED;
+}
+
+/**
+**	Register CCL functions for objectives
+*/
+global void ObjectivesCclRegister(void)
+{
+    gh_new_procedureN("add-objective",CclAddObjective);
+    gh_new_procedure1_0("remove-objective",CclRemoveObjective);
+}
+
+/**
+**	Save the objectives.
+*/
+global void SaveObjectives(FILE *file)
+{
+    int i;
+    for( i=0; i<MAX_OBJECTIVES && GameIntro.Objectives[i]; ++i ) {
+	fprintf(file,"(add-objective \"%s\")\n",GameIntro.Objectives[i]);
+    }
+}
+
 //@}
diff --git a/src/game/savegame.cpp b/src/game/savegame.cpp
index 30d7a5e7e..8dc7b17de 100644
--- a/src/game/savegame.cpp
+++ b/src/game/savegame.cpp
@@ -51,6 +51,7 @@
 #include "ai.h"
 #include "campaign.h"
 #include "trigger.h"
+#include "settings.h"
 
 #include "ccl.h"
 
@@ -129,6 +130,7 @@ global void SaveGame(const char* filename)
     SaveMissiles(file);
     SaveTriggers(file);
     SaveCampaign(file);
+    SaveObjectives(file);
 
     // FIXME: find all state information which must be saved.
 
diff --git a/src/include/settings.h b/src/include/settings.h
index f283273c3..9265ed6ef 100644
--- a/src/include/settings.h
+++ b/src/include/settings.h
@@ -156,8 +156,12 @@ extern void ShowCredits();
 extern void ShowPicture(const char* act,const char* title,const char* picture);
     /// Show stats
 extern void ShowStats();
-    /// Register Ccl
+    /// Register CCL functions for credits
 extern void CreditsCclRegister(void);
+    /// Register CCL functions for objectives
+extern void ObjectivesCclRegister(void);
+    /// Save the objectives
+extern void SaveObjectives(FILE *file);
     /// Create a game
 extern void CreateGame(char* filename,WorldMap* map);
     /// Init Setting to default values
diff --git a/src/stratagus/script.cpp b/src/stratagus/script.cpp
index efbf4a882..387d7fbc4 100644
--- a/src/stratagus/script.cpp
+++ b/src/stratagus/script.cpp
@@ -489,6 +489,7 @@ global void InitCcl(void)
     CampaignCclRegister();
     TriggerCclRegister();
     CreditsCclRegister();
+    ObjectivesCclRegister();
 
     EditorCclRegister();