1 /*
2 Copyright (C) 2009-2021 Parallel Realities
3 
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8 
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 
13 See the GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
18 */
19 
20 #include "../headers.h"
21 
22 #include "../entity.h"
23 #include "../hud.h"
24 #include "../system/error.h"
25 #include "global_trigger.h"
26 #include "objective.h"
27 #include "trigger.h"
28 
29 static Objective objective[MAX_OBJECTIVES];
30 
31 static void addObjective(char *, char *);
32 
freeObjectives()33 void freeObjectives()
34 {
35 	/* Clear the list */
36 
37 	memset(objective, 0, sizeof(Objective) * MAX_OBJECTIVES);
38 }
39 
addObjectiveFromScript(char * line)40 void addObjectiveFromScript(char *line)
41 {
42 	char objectiveName[MAX_MESSAGE_LENGTH], completionTrigger[MAX_VALUE_LENGTH];
43 
44 	sscanf(line, "\"%[^\"]\" \"%[^\"]\"", objectiveName, completionTrigger);
45 
46 	addObjective(objectiveName, completionTrigger);
47 }
48 
addObjectiveFromResource(char * key[],char * value[])49 void addObjectiveFromResource(char *key[], char *value[])
50 {
51 	int i, objectiveName, completionTrigger;
52 
53 	objectiveName = completionTrigger = -1;
54 
55 	for (i=0;i<MAX_PROPS_FILES;i++)
56 	{
57 		if (strcmpignorecase("OBJECTIVE_NAME", key[i]) == 0)
58 		{
59 			objectiveName = i;
60 		}
61 
62 		else if (strcmpignorecase("COMPLETION_TRIGGER", key[i]) == 0)
63 		{
64 			completionTrigger = i;
65 		}
66 	}
67 
68 	if (objectiveName == -1)
69 	{
70 		showErrorAndExit("Objective name is missing");
71 	}
72 
73 	addObjective(value[objectiveName], completionTrigger == -1 ? "" : value[completionTrigger]);
74 }
75 
addObjective(char * objectiveName,char * completionTrigger)76 void addObjective(char *objectiveName, char *completionTrigger)
77 {
78 	int i;
79 
80 	if (strcmpignorecase(objectiveName, "Create a Disintegration Shield") == 0)
81 	{
82 		return;
83 	}
84 
85 	for (i=0;i<MAX_OBJECTIVES;i++)
86 	{
87 		/* Don't add duplicates */
88 
89 		if (objective[i].inUse == TRUE && strcmpignorecase(objective[i].name, objectiveName) == 0)
90 		{
91 			return;
92 		}
93 
94 		if (objective[i].inUse == FALSE)
95 		{
96 			objective[i].inUse = TRUE;
97 			objective[i].active = TRUE;
98 			objective[i].completed = FALSE;
99 
100 			STRNCPY(objective[i].name, objectiveName, sizeof(objective[i].name));
101 			STRNCPY(objective[i].completionTrigger, completionTrigger, sizeof(objective[i].completionTrigger));
102 
103 			setInfoBoxMessage(60, 255, 255, 255, _("New Objective: %s"), _(objective[i].name));
104 
105 			return;
106 		}
107 	}
108 
109 	showErrorAndExit("No free slots to add Objective \"%s\"", objectiveName);
110 }
111 
updateObjective(char * objectiveName)112 void updateObjective(char *objectiveName)
113 {
114 	int i;
115 
116 	for (i=0;i<MAX_OBJECTIVES;i++)
117 	{
118 		if (objective[i].inUse == TRUE && objective[i].active == TRUE && objective[i].completed == FALSE)
119 		{
120 			if (strcmpignorecase(objective[i].name, objectiveName) == 0)
121 			{
122 				freeMessageQueue();
123 
124 				setInfoBoxMessage(180, 0, 255, 0, _("Objective Completed: %s"), _(objective[i].name));
125 
126 				fireTrigger(objective[i].completionTrigger);
127 
128 				fireGlobalTrigger(objective[i].completionTrigger);
129 
130 				objective[i].inUse = FALSE;
131 			}
132 		}
133 	}
134 }
135 
modifyObjective(char * objectiveName,char * completionTrigger)136 void modifyObjective(char *objectiveName, char *completionTrigger)
137 {
138 	int i;
139 
140 	for (i=0;i<MAX_OBJECTIVES;i++)
141 	{
142 		if (objective[i].inUse == TRUE && objective[i].active == TRUE && objective[i].completed == FALSE)
143 		{
144 			if (strcmpignorecase(objective[i].name, objectiveName) == 0)
145 			{
146 				STRNCPY(objective[i].completionTrigger, completionTrigger, sizeof(objective[i].completionTrigger));
147 
148 				break;
149 			}
150 		}
151 	}
152 }
153 
removeObjective(char * objectiveName)154 void removeObjective(char *objectiveName)
155 {
156 	int i;
157 
158 	for (i=0;i<MAX_OBJECTIVES;i++)
159 	{
160 		if (strcmpignorecase(objective[i].name, objectiveName) == 0)
161 		{
162 			objective[i].inUse = FALSE;
163 
164 			break;
165 		}
166 	}
167 }
168 
getObjectiveFromScript(char * line)169 void getObjectiveFromScript(char *line)
170 {
171 	char command[15], objectiveName[MAX_VALUE_LENGTH], entityName[MAX_VALUE_LENGTH];
172 	int i, success, failure, found;
173 	Entity *e;
174 
175 	sscanf(line, "%s \"%[^\"]\" %s %d %d", command, objectiveName, entityName, &success, &failure);
176 
177 	e = getEntityByObjectiveName(entityName);
178 
179 	if (e == NULL)
180 	{
181 		showErrorAndExit("Could not find Entity %s to check Objective %s against", entityName, objectiveName);
182 	}
183 
184 	found = FALSE;
185 
186 	for (i=0;i<MAX_OBJECTIVES;i++)
187 	{
188 		if (objective[i].inUse == TRUE && strcmpignorecase(objective[i].name, objectiveName) == 0)
189 		{
190 			found = TRUE;
191 
192 			break;
193 		}
194 	}
195 
196 	e->health = found == TRUE ? success : failure;
197 }
198 
writeObjectivesToFile(FILE * fp)199 void writeObjectivesToFile(FILE *fp)
200 {
201 	int i;
202 
203 	for (i=0;i<MAX_OBJECTIVES;i++)
204 	{
205 		if (objective[i].inUse == TRUE)
206 		{
207 			fprintf(fp, "{\n");
208 			fprintf(fp, "TYPE OBJECTIVE\n");
209 			fprintf(fp, "OBJECTIVE_NAME %s\n", objective[i].name);
210 			fprintf(fp, "COMPLETION_TRIGGER %s\n", objective[i].completionTrigger);
211 			fprintf(fp, "}\n\n");
212 		}
213 	}
214 }
215