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 
32 static void addMapTrigger(char *, int, int, int, char *);
33 
freeMapTriggers()34 void freeMapTriggers()
35 {
36 	/* Clear the list */
37 
38 	memset(trigger, 0, sizeof(Trigger) * MAX_TRIGGERS);
39 }
40 
addMapTriggerFromScript(char * line)41 void addMapTriggerFromScript(char *line)
42 {
43 	char triggerName[MAX_VALUE_LENGTH], targetName[MAX_VALUE_LENGTH], targetType[MAX_VALUE_LENGTH];
44 
45 	sscanf(line, "\"%[^\"]\" %s \"%[^\"]\"", triggerName, targetType, targetName);
46 
47 	addMapTrigger(triggerName, 0, 1, getTriggerTypeByName(targetType), targetName);
48 }
49 
addMapTriggerFromResource(char * key[],char * value[])50 void addMapTriggerFromResource(char *key[], char *value[])
51 {
52 	int i, triggerName, count, targetType, targetName, total;
53 
54 	total = triggerName = count = targetType = targetName = -1;
55 
56 	for (i=0;i<MAX_PROPS_FILES;i++)
57 	{
58 		if (strcmpignorecase("TRIGGER_NAME", key[i]) == 0)
59 		{
60 			triggerName = i;
61 		}
62 
63 		else if (strcmpignorecase("TRIGGER_COUNT", key[i]) == 0)
64 		{
65 			count = i;
66 		}
67 
68 		else if (strcmpignorecase("TRIGGER_TOTAL", key[i]) == 0)
69 		{
70 			total = i;
71 		}
72 
73 		else if (strcmpignorecase("TRIGGER_TYPE", key[i]) == 0)
74 		{
75 			targetType = i;
76 		}
77 
78 		else if (strcmpignorecase("TRIGGER_TARGET", key[i]) == 0)
79 		{
80 			targetName = i;
81 		}
82 	}
83 
84 	if (total == -1 && count != -1)
85 	{
86 		total = count;
87 
88 		count = 0;
89 	}
90 
91 	if (triggerName == -1 || count == -1 || targetType == -1 || targetName == -1 || total == -1)
92 	{
93 		showErrorAndExit("Map Trigger is missing resources");
94 	}
95 
96 	addMapTrigger(value[triggerName], atoi(value[count]), atoi(value[total]), getTriggerTypeByName(value[targetType]), value[targetName]);
97 }
98 
addMapTrigger(char * triggerName,int count,int total,int targetType,char * targetName)99 static void addMapTrigger(char *triggerName, int count, int total, int targetType, char *targetName)
100 {
101 	int i;
102 
103 	for (i=0;i<MAX_TRIGGERS;i++)
104 	{
105 		if (trigger[i].inUse == FALSE)
106 		{
107 			trigger[i].inUse = TRUE;
108 
109 			trigger[i].count = count;
110 			trigger[i].total = total;
111 			trigger[i].targetType = targetType;
112 
113 			STRNCPY(trigger[i].triggerName, triggerName, sizeof(trigger[i].triggerName));
114 			STRNCPY(trigger[i].targetName, targetName, sizeof(trigger[i].targetName));
115 
116 			return;
117 		}
118 	}
119 
120 	showErrorAndExit("No free slots to add Map Trigger \"%s\"", triggerName);
121 }
122 
fireMapTrigger(char * name)123 void fireMapTrigger(char *name)
124 {
125 	int i;
126 	char message[MAX_MESSAGE_LENGTH];
127 
128 	if (strlen(name) == 0)
129 	{
130 		return;
131 	}
132 
133 	for (i=0;i<MAX_TRIGGERS;i++)
134 	{
135 		if (trigger[i].inUse == TRUE && strcmpignorecase(trigger[i].triggerName, name) == 0)
136 		{
137 			trigger[i].count++;
138 
139 			if (trigger[i].targetType == UPDATE_OBJECTIVE)
140 			{
141 				SNPRINTF(message, MAX_MESSAGE_LENGTH, "%s (%d / %d)", _(trigger[i].targetName), trigger[i].count, trigger[i].total);
142 
143 				freeMessageQueue();
144 
145 				setInfoBoxMessage(60, 255, 255, 255, message);
146 			}
147 
148 			if (trigger[i].count == trigger[i].total)
149 			{
150 				switch (trigger[i].targetType)
151 				{
152 					case UPDATE_OBJECTIVE:
153 						updateObjective(trigger[i].targetName);
154 					break;
155 
156 					case ACTIVATE_ENTITY:
157 						activateEntitiesWithRequiredName(trigger[i].targetName, TRUE);
158 					break;
159 
160 					case DEACTIVATE_ENTITY:
161 						activateEntitiesWithRequiredName(trigger[i].targetName, FALSE);
162 					break;
163 
164 					case RUN_SCRIPT:
165 						runScript(trigger[i].targetName);
166 					break;
167 
168 					case KILL_ENTITY:
169 						killEntity(trigger[i].targetName);
170 					break;
171 
172 					case REMOVE_INVENTORY_ITEM:
173 						removeInventoryItemByObjectiveName(trigger[i].targetName);
174 					break;
175 
176 					default:
177 
178 					break;
179 				}
180 
181 				trigger[i].inUse = FALSE;
182 			}
183 		}
184 	}
185 }
186 
updateMapTrigger(char * name,int value)187 void updateMapTrigger(char *name, int value)
188 {
189 	int i;
190 
191 	if (strlen(name) == 0)
192 	{
193 		return;
194 	}
195 
196 	for (i=0;i<MAX_TRIGGERS;i++)
197 	{
198 		if (trigger[i].inUse == TRUE && strcmpignorecase(trigger[i].triggerName, name) == 0)
199 		{
200 			trigger[i].count -= value;
201 		}
202 	}
203 }
204 
writeMapTriggersToFile(FILE * fp)205 void writeMapTriggersToFile(FILE *fp)
206 {
207 	int i;
208 
209 	for (i=0;i<MAX_TRIGGERS;i++)
210 	{
211 		if (trigger[i].inUse == TRUE)
212 		{
213 			fprintf(fp, "{\n");
214 			fprintf(fp, "TYPE MAP_TRIGGER\n");
215 			fprintf(fp, "TRIGGER_NAME %s\n", trigger[i].triggerName);
216 			fprintf(fp, "TRIGGER_COUNT %d\n", trigger[i].count);
217 			fprintf(fp, "TRIGGER_TOTAL %d\n", trigger[i].total);
218 			fprintf(fp, "TRIGGER_TYPE %s\n", getTriggerTypeByID(trigger[i].targetType));
219 			fprintf(fp, "TRIGGER_TARGET %s\n", trigger[i].targetName);
220 			fprintf(fp, "}\n\n");
221 		}
222 	}
223 }
224