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 "../event/script.h"
24 #include "../hud.h"
25 #include "../inventory.h"
26 #include "../system/error.h"
27 #include "objective.h"
28 #include "trigger.h"
29
30 static Trigger trigger[MAX_TRIGGERS];
31 static Type type[] = {
32 {UPDATE_OBJECTIVE, "UPDATE_OBJECTIVE"},
33 {ACTIVATE_ENTITY, "ACTIVATE_ENTITY"},
34 {DEACTIVATE_ENTITY, "DEACTIVATE_ENTITY"},
35 {RUN_SCRIPT, "RUN_SCRIPT"},
36 {UPDATE_TRIGGER, "UPDATE_TRIGGER"},
37 {KILL_ENTITY, "KILL_ENTITY"},
38 {REMOVE_INVENTORY_ITEM, "REMOVE_INVENTORY_ITEM"},
39 {UPDATE_EXIT, "UPDATE_EXIT"}
40 };
41 static int length = sizeof(type) / sizeof(Type);
42
43 static void addTrigger(char *, int, int, int, char *);
44
freeTriggers()45 void freeTriggers()
46 {
47 /* Clear the list */
48
49 memset(trigger, 0, sizeof(Trigger) * MAX_TRIGGERS);
50 }
51
addTriggerFromResource(char * key[],char * value[])52 void addTriggerFromResource(char *key[], char *value[])
53 {
54 int i, triggerName, count, targetType, targetName, total;
55
56 total = triggerName = count = targetType = targetName = -1;
57
58 for (i=0;i<MAX_PROPS_FILES;i++)
59 {
60 if (strcmpignorecase("TRIGGER_NAME", key[i]) == 0)
61 {
62 triggerName = i;
63 }
64
65 else if (strcmpignorecase("TRIGGER_COUNT", key[i]) == 0)
66 {
67 count = i;
68 }
69
70 else if (strcmpignorecase("TRIGGER_TOTAL", key[i]) == 0)
71 {
72 total = i;
73 }
74
75 else if (strcmpignorecase("TRIGGER_TYPE", key[i]) == 0)
76 {
77 targetType = i;
78 }
79
80 else if (strcmpignorecase("TRIGGER_TARGET", key[i]) == 0)
81 {
82 targetName = i;
83 }
84 }
85
86 if (total == -1 && count != -1)
87 {
88 total = count;
89
90 count = 0;
91 }
92
93 if (triggerName == -1 || count == -1 || targetType == -1 || targetName == -1 || total == -1)
94 {
95 showErrorAndExit("Trigger is missing resources");
96 }
97
98 addTrigger(value[triggerName], atoi(value[count]), atoi(value[total]), getTriggerTypeByName(value[targetType]), value[targetName]);
99 }
100
addTrigger(char * triggerName,int count,int total,int targetType,char * targetName)101 static void addTrigger(char *triggerName, int count, int total, int targetType, char *targetName)
102 {
103 int i;
104
105 for (i=0;i<MAX_TRIGGERS;i++)
106 {
107 if (trigger[i].inUse == FALSE)
108 {
109 trigger[i].inUse = TRUE;
110
111 trigger[i].count = count;
112 trigger[i].total = total;
113 trigger[i].targetType = targetType;
114
115 STRNCPY(trigger[i].triggerName, triggerName, sizeof(trigger[i].triggerName));
116 STRNCPY(trigger[i].targetName, targetName, sizeof(trigger[i].targetName));
117
118 return;
119 }
120 }
121
122 showErrorAndExit("No free slots to add Trigger \"%s\"", triggerName);
123 }
124
fireTrigger(char * name)125 void fireTrigger(char *name)
126 {
127 int i;
128 char message[MAX_MESSAGE_LENGTH];
129
130 if (strlen(name) == 0)
131 {
132 return;
133 }
134
135 for (i=0;i<MAX_TRIGGERS;i++)
136 {
137 if (trigger[i].inUse == TRUE && strcmpignorecase(trigger[i].triggerName, name) == 0)
138 {
139 trigger[i].count++;
140
141 if (trigger[i].targetType == UPDATE_OBJECTIVE)
142 {
143 SNPRINTF(message, MAX_MESSAGE_LENGTH, "%s (%d / %d)", _(trigger[i].targetName), trigger[i].count, trigger[i].total);
144
145 freeMessageQueue();
146
147 setInfoBoxMessage(60, 255, 255, 255, message);
148 }
149
150 if (trigger[i].count == trigger[i].total)
151 {
152 switch (trigger[i].targetType)
153 {
154 case UPDATE_OBJECTIVE:
155 updateObjective(trigger[i].targetName);
156 break;
157
158 case ACTIVATE_ENTITY:
159 activateEntitiesWithRequiredName(trigger[i].targetName, TRUE);
160 break;
161
162 case DEACTIVATE_ENTITY:
163 activateEntitiesWithRequiredName(trigger[i].targetName, FALSE);
164 break;
165
166 case RUN_SCRIPT:
167 runScript(trigger[i].targetName);
168 break;
169
170 case KILL_ENTITY:
171 killEntity(trigger[i].targetName);
172 break;
173
174 case REMOVE_INVENTORY_ITEM:
175 removeInventoryItemByObjectiveName(trigger[i].targetName);
176 break;
177
178 case UPDATE_TRIGGER:
179 fireTrigger(trigger[i].targetName);
180 break;
181
182 default:
183
184 break;
185 }
186
187 trigger[i].inUse = FALSE;
188 }
189 }
190 }
191 }
192
removeTrigger(char * name)193 void removeTrigger(char *name)
194 {
195 int i;
196
197 for (i=0;i<MAX_TRIGGERS;i++)
198 {
199 if (trigger[i].inUse == TRUE && strcmpignorecase(trigger[i].triggerName, name) == 0)
200 {
201 trigger[i].inUse = FALSE;
202
203 break;
204 }
205 }
206 }
207
updateTrigger(char * name,int value)208 void updateTrigger(char *name, int value)
209 {
210 int i;
211
212 if (strlen(name) == 0)
213 {
214 return;
215 }
216
217 for (i=0;i<MAX_TRIGGERS;i++)
218 {
219 if (trigger[i].inUse == TRUE && strcmpignorecase(trigger[i].triggerName, name) == 0)
220 {
221 printf("Modifying trigger value from %d to %d\n", trigger[i].count, (trigger[i].count - value));
222
223 trigger[i].count -= value;
224 }
225 }
226 }
227
writeTriggersToFile(FILE * fp)228 void writeTriggersToFile(FILE *fp)
229 {
230 int i;
231
232 for (i=0;i<MAX_TRIGGERS;i++)
233 {
234 if (trigger[i].inUse == TRUE)
235 {
236 fprintf(fp, "{\n");
237 fprintf(fp, "TYPE TRIGGER\n");
238 fprintf(fp, "TRIGGER_NAME %s\n", trigger[i].triggerName);
239 fprintf(fp, "TRIGGER_COUNT %d\n", trigger[i].count);
240 fprintf(fp, "TRIGGER_TOTAL %d\n", trigger[i].total);
241 fprintf(fp, "TRIGGER_TYPE %s\n", getTriggerTypeByID(trigger[i].targetType));
242 fprintf(fp, "TRIGGER_TARGET %s\n", trigger[i].targetName);
243 fprintf(fp, "}\n\n");
244 }
245 }
246 }
247
getTriggerTypeByName(char * name)248 int getTriggerTypeByName(char *name)
249 {
250 int i;
251
252 for (i=0;i<length;i++)
253 {
254 if (strcmpignorecase(name, type[i].name) == 0)
255 {
256 return type[i].id;
257 }
258 }
259
260 showErrorAndExit("Unknown Trigger Type %s", name);
261
262 return 0;
263 }
264
getTriggerTypeByID(int id)265 char *getTriggerTypeByID(int id)
266 {
267 int i;
268
269 for (i=0;i<length;i++)
270 {
271 if (id == type[i].id)
272 {
273 return type[i].name;
274 }
275 }
276
277 showErrorAndExit("Unknown Trigger ID %d", id);
278
279 return 0;
280 }
281