ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/button.C
(Generate patch)

Comparing deliantra/server/common/button.C (file contents):
Revision 1.1 by elmex, Sun Aug 13 17:16:00 2006 UTC vs.
Revision 1.11 by root, Sat Sep 16 22:24:12 2006 UTC

1/*
2 * static char *rcsid_button_c =
3 * "$Id: button.C,v 1.1 2006/08/13 17:16:00 elmex Exp $";
4 */
5
6/* 1/*
7 CrossFire, A Multiplayer game for X-windows 2 CrossFire, A Multiplayer game for X-windows
8 3
9 Copyright (C) 2002 Mark Wedel & Crossfire Development Team 4 Copyright (C) 2002 Mark Wedel & Crossfire Development Team
10 Copyright (C) 1992 Frank Tore Johansen 5 Copyright (C) 1992 Frank Tore Johansen
21 16
22 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software 18 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 20
26 The authors can be reached via e-mail at crossfire-devel@real-time.com 21 The authors can be reached via e-mail at <crossfire@schmorp.de>
27*/ 22*/
28 23
29#include <global.h> 24#include <global.h>
30#include <funcpoint.h> 25#include <funcpoint.h>
31 26
32/* 27/*
33 * This code is no longer highly inefficient 8) 28 * This code is no longer highly inefficient 8)
34 */ 29 */
35 30
36/* 31/*
32 * elmex:
33 * This function takes a objectlink list with all the objects are going to be activated.
34 * state is a true/false flag that will actiavte objects that have FLAG_ACTIVATE_ON_PUSH/RELEASE set.
35 * The source argument can be 0 or the source object for this activation.
36 */
37void
38activate_connection_link (objectlink * ol, bool state, object *source = 0)
39{
40 object *tmp = 0;
41
42 for (; ol; ol = ol->next)
43 {
44 if (!ol->ob || ol->ob->count != ol->id)
45 {
46 LOG (llevError, "Internal error in activate_connection_link (%ld).\n", ol->id);
47 continue;
48 }
49 /* a button link object can become freed when the map is saving. As
50 * a map is saved, objects are removed and freed, and if an object is
51 * on top of a button, this function is eventually called. If a map
52 * is getting moved out of memory, the status of buttons and levers
53 * probably isn't important - it will get sorted out when the map is
54 * re-loaded. As such, just exit this function if that is the case.
55 */
56
57 if (QUERY_FLAG (ol->ob, FLAG_FREED))
58 return;
59 tmp = ol->ob;
60
61 /* if the criteria isn't appropriate, don't do anything */
62 if (state && !QUERY_FLAG (tmp, FLAG_ACTIVATE_ON_PUSH))
63 continue;
64 if (!state && !QUERY_FLAG (tmp, FLAG_ACTIVATE_ON_RELEASE))
65 continue;
66
67 switch (tmp->type)
68 {
69 case GATE:
70 case HOLE:
71 tmp->value = tmp->stats.maxsp ? !state : state;
72 tmp->speed = 0.5;
73 update_ob_speed (tmp);
74 break;
75
76 case CF_HANDLE:
77 SET_ANIMATION (tmp, (tmp->value = tmp->stats.maxsp ? !state : state));
78 update_object (tmp, UP_OBJ_FACE);
79 break;
80
81 case SIGN:
82 if (!tmp->stats.food || tmp->last_eat < tmp->stats.food)
83 {
84 new_info_map (NDI_UNIQUE | NDI_NAVY, tmp->map, tmp->msg);
85 if (tmp->stats.food)
86 tmp->last_eat++;
87 }
88 break;
89
90 case ALTAR:
91 tmp->value = 1;
92 SET_ANIMATION (tmp, tmp->value);
93 update_object (tmp, UP_OBJ_FACE);
94 break;
95
96 case BUTTON:
97 case PEDESTAL:
98 tmp->value = state;
99 SET_ANIMATION (tmp, tmp->value);
100 update_object (tmp, UP_OBJ_FACE);
101 break;
102
103 case MOOD_FLOOR:
104 do_mood_floor (tmp, source);
105 break;
106
107 case TIMED_GATE:
108 tmp->speed = tmp->arch->clone.speed;
109 update_ob_speed (tmp); /* original values */
110 tmp->value = tmp->arch->clone.value;
111 tmp->stats.sp = 1;
112 tmp->stats.hp = tmp->stats.maxhp;
113 /* Handle multipart gates. We copy the value for the other parts
114 * from the head - this ensures that the data will consistent
115 */
116 for (tmp = tmp->more; tmp != NULL; tmp = tmp->more)
117 {
118 tmp->speed = tmp->head->speed;
119 tmp->value = tmp->head->value;
120 tmp->stats.sp = tmp->head->stats.sp;
121 tmp->stats.hp = tmp->head->stats.hp;
122 update_ob_speed (tmp);
123 }
124 break;
125
126 case DIRECTOR:
127 case FIREWALL:
128 if (!QUERY_FLAG (tmp, FLAG_ANIMATE) && tmp->type == FIREWALL)
129 move_firewall (tmp);
130 else
131 {
132 if ((tmp->stats.sp += tmp->stats.maxsp) > 8) /* next direction */
133 tmp->stats.sp = ((tmp->stats.sp - 1) % 8) + 1;
134 animate_turning (tmp);
135 }
136 break;
137
138 case TELEPORTER:
139 move_teleporter (tmp);
140 break;
141
142 case CREATOR:
143 move_creator (tmp);
144 break;
145
146 case TRIGGER_MARKER:
147 move_marker (tmp);
148 break;
149
150 case DUPLICATOR:
151 move_duplicator (tmp);
152 break;
153 }
154 }
155}
156
157/*
158 * elmex:
159 * This is the new push_button function, it got split up so that
160 * you can activate connections without a button now!
161 * old but still valid comment:
162 *
37 * Push the specified object. This can affect other buttons/gates/handles 163 * Push the specified object. This can affect other buttons/gates/handles
38 * altars/pedestals/holes in the whole map. 164 * altars/pedestals/holes in the whole map.
39 * Changed the routine to loop through _all_ objects. 165 * Changed the routine to loop through _all_ objects.
40 * Better hurry with that linked list... 166 * Better hurry with that linked list...
41 */ 167 *
42
43void push_button(object *op) {
44 object *tmp;
45 objectlink *ol;
46
47/* LOG(llevDebug, "push_button: %s (%d)\n", op->name, op->count); */
48 for (ol = get_button_links(op); ol; ol = ol->next) {
49 if (!ol->ob || ol->ob->count != ol->id) {
50 LOG(llevError, "Internal error in push_button (%s).\n", op->name);
51 continue;
52 }
53 /* a button link object can become freed when the map is saving. As
54 * a map is saved, objects are removed and freed, and if an object is
55 * on top of a button, this function is eventually called. If a map
56 * is getting moved out of memory, the status of buttons and levers
57 * probably isn't important - it will get sorted out when the map is
58 * re-loaded. As such, just exit this function if that is the case.
59 */ 168 */
60 169void
61 if (QUERY_FLAG(ol->ob, FLAG_FREED)) return; 170push_button (object *op)
62 tmp = ol->ob; 171{
172 oblinkpt *obp = get_button_links (op);
63 173
64 /* if the criteria isn't appropriate, don't do anything */ 174 if (!obp)
65 if (op->value && !QUERY_FLAG(tmp, FLAG_ACTIVATE_ON_PUSH)) continue; 175 return;
66 if (!op->value && !QUERY_FLAG(tmp, FLAG_ACTIVATE_ON_RELEASE)) continue;
67 176
68 switch(tmp->type) { 177 if (INVOKE_MAP (TRIGGER, op->map, ARG_INT64 (obp->value), ARG_INT (op->value)))
178 return;
69 179
70 case GATE: 180 activate_connection_link (obp->link, op->value, op);
71 case HOLE: 181}
72 tmp->value=tmp->stats.maxsp?!op->value:op->value;
73 tmp->speed=0.5;
74 update_ob_speed(tmp);
75 break;
76 182
77 case CF_HANDLE: 183/*
78 SET_ANIMATION(tmp, (tmp->value=tmp->stats.maxsp?!op->value:op->value)); 184 * elmex:
79 update_object(tmp,UP_OBJ_FACE); 185 * This activates a connection, similar to push_button (object *op) but it takes
80 break; 186 * only a map, a connection value and a true or false flag that indicated whether
81 187 * the connection was 'state' or 'released'. So that you can activate objects
82 case SIGN: 188 * who have FLAG_ACTIVATE_ON_PUSH/RELEASE set properly.
83 if (!tmp->stats.food || tmp->last_eat < tmp->stats.food) { 189 *
84 new_info_map(NDI_UNIQUE | NDI_NAVY,tmp->map,tmp->msg);
85 if (tmp->stats.food) tmp->last_eat++;
86 }
87 break;
88
89 case ALTAR:
90 tmp->value = 1;
91 SET_ANIMATION(tmp, tmp->value);
92 update_object(tmp,UP_OBJ_FACE);
93 break;
94
95 case BUTTON:
96 case PEDESTAL:
97 tmp->value=op->value;
98 SET_ANIMATION(tmp, tmp->value);
99 update_object(tmp,UP_OBJ_FACE);
100 break;
101
102 case MOOD_FLOOR:
103 do_mood_floor(tmp, op);
104 break;
105
106 case TIMED_GATE:
107 tmp->speed = tmp->arch->clone.speed;
108 update_ob_speed(tmp); /* original values */
109 tmp->value = tmp->arch->clone.value;
110 tmp->stats.sp = 1;
111 tmp->stats.hp = tmp->stats.maxhp;
112 /* Handle multipart gates. We copy the value for the other parts
113 * from the head - this ensures that the data will consistent
114 */ 190 */
115 for (tmp=tmp->more; tmp!=NULL; tmp=tmp->more) { 191void
116 tmp->speed = tmp->head->speed; 192activate_connection (maptile *map, long connection, bool state)
117 tmp->value = tmp->head->value; 193{
118 tmp->stats.sp = tmp->head->stats.sp; 194 if (INVOKE_MAP (TRIGGER, map, ARG_INT64 (connection), ARG_INT (state)))
119 tmp->stats.hp = tmp->head->stats.hp; 195 return;
120 update_ob_speed(tmp);
121 }
122 break;
123 196
124 case DIRECTOR: 197 oblinkpt *obp = get_connection_links (map, connection);
125 case FIREWALL:
126 if(!QUERY_FLAG(tmp,FLAG_ANIMATE)&&tmp->type==FIREWALL) move_firewall(tmp);
127 else {
128 if ((tmp->stats.sp += tmp->stats.maxsp) > 8) /* next direction */
129 tmp->stats.sp = ((tmp->stats.sp-1)%8)+1;
130 animate_turning(tmp);
131 }
132 break;
133 198
134 case TELEPORTER: 199 if (obp)
135 move_teleporter(tmp); 200 activate_connection_link (obp->link, state);
136 break;
137
138 case CREATOR:
139 move_creator(tmp);
140 break;
141
142 case TRIGGER_MARKER:
143 move_marker(tmp);
144 break;
145
146 case DUPLICATOR:
147 move_duplicator(tmp);
148 break;
149 }
150 }
151} 201}
152 202
153/* 203/*
154 * Updates everything connected with the button op. 204 * Updates everything connected with the button op.
155 * After changing the state of a button, this function must be called 205 * After changing the state of a button, this function must be called
156 * to make sure that all gates and other buttons connected to the 206 * to make sure that all gates and other buttons connected to the
157 * button reacts to the (eventual) change of state. 207 * button reacts to the (eventual) change of state.
158 */ 208 */
159 209
210void
160void update_button(object *op) { 211update_button (object *op)
212{
161 object *ab,*tmp,*head; 213 object *ab, *tmp, *head;
162 int tot,any_down=0, old_value=op->value; 214 int tot, any_down = 0, old_value = op->value;
215 oblinkpt *obp = 0;
163 objectlink *ol; 216 objectlink *ol;
164 217
218 obp = get_button_links (op);
165 /* LOG(llevDebug, "update_button: %s (%d)\n", op->name, op->count); */ 219 /* LOG(llevDebug, "update_button: %s (%d)\n", op->name, op->count); */
220 if (obp)
166 for (ol = get_button_links(op); ol; ol = ol->next) { 221 for (ol = obp->link; ol; ol = ol->next)
222 {
167 if (!ol->ob || ol->ob->count != ol->id) { 223 if (!ol->ob || ol->ob->count != ol->id)
224 {
168 LOG(llevDebug, "Internal error in update_button (%s).\n", op->name); 225 LOG (llevDebug, "Internal error in update_button (%s).\n", &op->name);
169 continue; 226 continue;
170 } 227 }
171 tmp = ol->ob; 228 tmp = ol->ob;
172 if (tmp->type==BUTTON) { 229 if (tmp->type == BUTTON)
230 {
173 for(ab=tmp->above,tot=0;ab!=NULL;ab=ab->above) 231 for (ab = tmp->above, tot = 0; ab != NULL; ab = ab->above)
174 /* Bug? The pedestal code below looks for the head of 232 /* Bug? The pedestal code below looks for the head of
175 * the object, this bit doesn't. I'd think we should check 233 * the object, this bit doesn't. I'd think we should check
176 * for head here also. Maybe it also makese sense to 234 * for head here also. Maybe it also makese sense to
177 * make the for ab=tmp->above loop common, and alter 235 * make the for ab=tmp->above loop common, and alter
178 * behaviour based on object within that loop? 236 * behaviour based on object within that loop?
179 */ 237 */
180 238
181 /* Basically, if the move_type matches that on what the 239 /* Basically, if the move_type matches that on what the
182 * button wants, we count it. The second check is so that 240 * button wants, we count it. The second check is so that
183 * objects don't move (swords, etc) will count. Note that 241 * objects don't move (swords, etc) will count. Note that
184 * this means that more work is needed to make buttons 242 * this means that more work is needed to make buttons
185 * that are only triggered by flying objects. 243 * that are only triggered by flying objects.
186 */ 244 */
187 if ((ab->move_type & tmp->move_on) || ab->move_type==0 ) 245 if ((ab->move_type & tmp->move_on) || ab->move_type == 0)
188 tot+=ab->weight*(ab->nrof?ab->nrof:1)+ab->carrying; 246 tot += ab->weight * (ab->nrof ? ab->nrof : 1) + ab->carrying;
189 247
190 tmp->value=(tot>=tmp->weight)?1:0; 248 tmp->value = (tot >= tmp->weight) ? 1 : 0;
191 if(tmp->value) 249 if (tmp->value)
192 any_down=1; 250 any_down = 1;
251 }
193 } else if (tmp->type == PEDESTAL) { 252 else if (tmp->type == PEDESTAL)
253 {
194 tmp->value = 0; 254 tmp->value = 0;
195 for(ab=tmp->above; ab!=NULL; ab=ab->above) { 255 for (ab = tmp->above; ab != NULL; ab = ab->above)
256 {
196 head = ab->head ? ab->head : ab; 257 head = ab->head ? ab->head : ab;
197 /* Same note regarding move_type for buttons above apply here. */ 258 /* Same note regarding move_type for buttons above apply here. */
198 if ( ((head->move_type & tmp->move_on) || ab->move_type==0) && 259 if (((head->move_type & tmp->move_on) || ab->move_type == 0) &&
199 (head->race==tmp->slaying || 260 (head->race == tmp->slaying ||
200 ((head->type==SPECIAL_KEY) && (head->slaying==tmp->slaying)) || 261 ((head->type == SPECIAL_KEY) && (head->slaying == tmp->slaying)) ||
201 (!strcmp (tmp->slaying, "player") && 262 (!strcmp (tmp->slaying, "player") && head->type == PLAYER)))
202 head->type == PLAYER))) 263 tmp->value = 1;
203 tmp->value = 1; 264 }
204 }
205 if(tmp->value) 265 if (tmp->value)
206 any_down=1; 266 any_down = 1;
207 } 267 }
208 } 268 }
209 if(any_down) /* If any other buttons were down, force this to remain down */ 269 if (any_down) /* If any other buttons were down, force this to remain down */
210 op->value=1; 270 op->value = 1;
211 271
212 /* If this button hasn't changed, don't do anything */ 272 /* If this button hasn't changed, don't do anything */
213 if (op->value != old_value) { 273 if (op->value != old_value)
274 {
214 SET_ANIMATION(op, op->value); 275 SET_ANIMATION (op, op->value);
215 update_object(op, UP_OBJ_FACE); 276 update_object (op, UP_OBJ_FACE);
216 push_button(op); /* Make all other buttons the same */ 277 push_button (op); /* Make all other buttons the same */
217 } 278 }
218} 279}
219 280
220/* 281/*
221 * Updates every button on the map (by calling update_button() for them). 282 * Updates every button on the map (by calling update_button() for them).
222 */ 283 */
223 284
224void update_buttons(mapstruct *m) { 285void
286update_buttons (maptile *m)
287{
225 objectlink *ol; 288 objectlink *ol;
226 oblinkpt *obp; 289 oblinkpt *obp;
290
227 for (obp = m->buttons; obp; obp = obp->next) 291 for (obp = m->buttons; obp; obp = obp->next)
228 for (ol = obp->link; ol; ol = ol->next) { 292 for (ol = obp->link; ol; ol = ol->next)
293 {
229 if (!ol->ob || ol->ob->count != ol->id) { 294 if (!ol->ob || ol->ob->count != ol->id)
295 {
230 LOG(llevError, "Internal error in update_button (%s (%dx%d):%d, connected %ld).\n", 296 LOG (llevError, "Internal error in update_button (%s (%dx%d):%d, connected %ld).\n",
231 ol->ob?ol->ob->name:"null", 297 ol->ob ? (const char *) ol->ob->name : "null", ol->ob ? ol->ob->x : -1, ol->ob ? ol->ob->y : -1, ol->id, obp->value);
232 ol->ob?ol->ob->x:-1,
233 ol->ob?ol->ob->y:-1,
234 ol->id,
235 obp->value);
236 continue; 298 continue;
299 }
300 if (ol->ob->type == BUTTON || ol->ob->type == PEDESTAL)
301 {
302 update_button (ol->ob);
303 break;
304 }
237 } 305 }
238 if (ol->ob->type==BUTTON || ol->ob->type==PEDESTAL)
239 {
240 update_button(ol->ob);
241 break;
242 }
243 }
244} 306}
245 307
308void
246void use_trigger(object *op) 309use_trigger (object *op)
247{ 310{
248 311
249 /* Toggle value */ 312 /* Toggle value */
250 op->value = !op->value; 313 op->value = !op->value;
251 push_button(op); 314 push_button (op);
252} 315}
253 316
254/* 317/*
255 * Note: animate_object should be used instead of this, 318 * Note: animate_object should be used instead of this,
256 * but it can't handle animations in the 8 directions 319 * but it can't handle animations in the 8 directions
257 */ 320 */
258 321
322void
259void animate_turning(object *op) /* only one part objects */ 323animate_turning (object *op) /* only one part objects */
260{ 324{
261 if (++op->state >= NUM_ANIMATIONS(op)/8) 325 if (++op->state >= NUM_ANIMATIONS (op) / 8)
262 op->state=0; 326 op->state = 0;
263 SET_ANIMATION(op, (op->stats.sp-1) * NUM_ANIMATIONS(op) / 8 + 327 SET_ANIMATION (op, (op->stats.sp - 1) * NUM_ANIMATIONS (op) / 8 + op->state);
264 op->state);
265 update_object(op,UP_OBJ_FACE); 328 update_object (op, UP_OBJ_FACE);
266} 329}
267 330
268#define ARCH_SACRIFICE(xyz) ((xyz)->slaying) 331#define ARCH_SACRIFICE(xyz) ((xyz)->slaying)
269#define NROF_SACRIFICE(xyz) ((uint32)(xyz)->stats.food) 332#define NROF_SACRIFICE(xyz) ((uint32)(xyz)->stats.food)
270 333
276 * 339 *
277 * 0.93.4: Linked objects (ie, objects that are connected) can not be 340 * 0.93.4: Linked objects (ie, objects that are connected) can not be
278 * sacrificed. This fixes a bug of trying to put multiple altars/related 341 * sacrificed. This fixes a bug of trying to put multiple altars/related
279 * objects on the same space that take the same sacrifice. 342 * objects on the same space that take the same sacrifice.
280 */ 343 */
281 344
345int
282int check_altar_sacrifice (const object *altar, const object *sacrifice) 346check_altar_sacrifice (const object *altar, const object *sacrifice)
283{ 347{
284 if ( ! QUERY_FLAG (sacrifice, FLAG_ALIVE) 348 if (!QUERY_FLAG (sacrifice, FLAG_ALIVE) && !QUERY_FLAG (sacrifice, FLAG_IS_LINKED) && sacrifice->type != PLAYER)
285 && ! QUERY_FLAG (sacrifice, FLAG_IS_LINKED)
286 && sacrifice->type != PLAYER)
287 { 349 {
288 if ((ARCH_SACRIFICE(altar) == sacrifice->arch->name || 350 if ((ARCH_SACRIFICE (altar) == sacrifice->arch->name ||
289 ARCH_SACRIFICE(altar) == sacrifice->name || 351 ARCH_SACRIFICE (altar) == sacrifice->name ||
290 ARCH_SACRIFICE(altar) == sacrifice->slaying || 352 ARCH_SACRIFICE (altar) == sacrifice->slaying ||
291 (!strcmp(ARCH_SACRIFICE(altar),query_base_name(sacrifice,0)))) 353 (!strcmp (ARCH_SACRIFICE (altar), query_base_name (sacrifice, 0))))
292 && NROF_SACRIFICE(altar) <= (sacrifice->nrof?sacrifice->nrof:1)) 354 && NROF_SACRIFICE (altar) <= (sacrifice->nrof ? sacrifice->nrof : 1))
293 return 1; 355 return 1;
294 if (strcmp (ARCH_SACRIFICE(altar), "money") == 0 356 if (strcmp (ARCH_SACRIFICE (altar), "money") == 0
295 && sacrifice->type == MONEY
296 && sacrifice->nrof * sacrifice->value >= NROF_SACRIFICE(altar)) 357 && sacrifice->type == MONEY && sacrifice->nrof * sacrifice->value >= NROF_SACRIFICE (altar))
297 return 1; 358 return 1;
298 } 359 }
299 return 0; 360 return 0;
300} 361}
301
302 362
303/* 363/*
304 * operate_altar checks if sacrifice was accepted and removes sacrificed 364 * operate_altar checks if sacrifice was accepted and removes sacrificed
305 * objects. If sacrifice was succeed return 1 else 0. Might be better to 365 * objects. If sacrifice was succeed return 1 else 0. Might be better to
306 * call check_altar_sacrifice (above) than depend on the return value, 366 * call check_altar_sacrifice (above) than depend on the return value,
307 * since operate_altar will remove the sacrifice also. 367 * since operate_altar will remove the sacrifice also.
308 * 368 *
309 * If this function returns 1, '*sacrifice' is modified to point to the 369 * If this function returns 1, '*sacrifice' is modified to point to the
310 * remaining sacrifice, or is set to NULL if the sacrifice was used up. 370 * remaining sacrifice, or is set to NULL if the sacrifice was used up.
311 */ 371 */
312 372int
313int operate_altar (object *altar, object **sacrifice) 373operate_altar (object *altar, object **sacrifice)
314{ 374{
315
316 if ( ! altar->map) { 375 if (!altar->map)
376 {
317 LOG (llevError, "BUG: operate_altar(): altar has no map\n"); 377 LOG (llevError, "BUG: operate_altar(): altar has no map\n");
318 return 0; 378 return 0;
319 } 379 }
320 380
321 if (!altar->slaying || altar->value) 381 if (!altar->slaying || altar->value)
322 return 0; 382 return 0;
323 383
324 if ( ! check_altar_sacrifice (altar, *sacrifice)) 384 if (!check_altar_sacrifice (altar, *sacrifice))
325 return 0; 385 return 0;
326 386
327 /* check_altar_sacrifice should have already verified that enough money 387 /* check_altar_sacrifice should have already verified that enough money
328 * has been dropped. 388 * has been dropped.
329 */ 389 */
330 if (!strcmp(ARCH_SACRIFICE(altar), "money")) { 390 if (!strcmp (ARCH_SACRIFICE (altar), "money"))
391 {
331 int number=NROF_SACRIFICE(altar) / (*sacrifice)->value; 392 int number = NROF_SACRIFICE (altar) / (*sacrifice)->value;
332 393
333 /* Round up any sacrifices. Altars don't make change either */ 394 /* Round up any sacrifices. Altars don't make change either */
334 if (NROF_SACRIFICE(altar) % (*sacrifice)->value) number++; 395 if (NROF_SACRIFICE (altar) % (*sacrifice)->value)
396 number++;
397
335 *sacrifice = decrease_ob_nr (*sacrifice, number); 398 *sacrifice = decrease_ob_nr (*sacrifice, number);
336 } 399 }
337 else 400 else
338 *sacrifice = decrease_ob_nr (*sacrifice, NROF_SACRIFICE(altar)); 401 *sacrifice = decrease_ob_nr (*sacrifice, NROF_SACRIFICE (altar));
339 402
340 if (altar->msg) 403 if (altar->msg)
341 new_info_map(NDI_BLACK, altar->map, altar->msg); 404 new_info_map (NDI_BLACK, altar->map, altar->msg);
405
342 return 1; 406 return 1;
343} 407}
344 408
409void
345void trigger_move (object *op, int state) /* 1 down and 0 up */ 410trigger_move (object *op, int state) /* 1 down and 0 up */
346{ 411{
347 op->stats.wc = state; 412 op->stats.wc = state;
348 if (state) { 413 if (state)
349 use_trigger(op); 414 {
350 if (op->stats.exp > 0) /* check sanity */
351 op->speed = 1.0 / op->stats.exp;
352 else
353 op->speed = 1.0;
354 update_ob_speed(op);
355 op->speed_left = -1;
356 } else {
357 use_trigger(op); 415 use_trigger (op);
358 op->speed = 0; 416 if (op->stats.exp > 0) /* check sanity */
417 op->speed = 1.0 / op->stats.exp;
418 else
419 op->speed = 1.0;
359 update_ob_speed(op); 420 update_ob_speed (op);
421 op->speed_left = -1;
422 }
423 else
424 {
425 use_trigger (op);
426 op->speed = 0;
427 update_ob_speed (op);
360 } 428 }
361} 429}
362 430
363 431
364/* 432/*
371 * 439 *
372 * TRIGGER: Returns 1 if handle could be moved, 0 if not. 440 * TRIGGER: Returns 1 if handle could be moved, 0 if not.
373 * 441 *
374 * TRIGGER_BUTTON, TRIGGER_PEDESTAL: Returns 0. 442 * TRIGGER_BUTTON, TRIGGER_PEDESTAL: Returns 0.
375 */ 443 */
444int
376int check_trigger (object *op, object *cause) 445check_trigger (object *op, object *cause)
377{ 446{
378 object *tmp; 447 object *tmp;
379 int push = 0, tot = 0; 448 int push = 0, tot = 0;
380 int in_movement = op->stats.wc || op->speed; 449 int in_movement = op->stats.wc || op->speed;
381 450
382 switch (op->type) { 451 switch (op->type)
452 {
383 case TRIGGER_BUTTON: 453 case TRIGGER_BUTTON:
384 if (op->weight > 0) { 454 if (op->weight > 0)
385 if (cause) { 455 {
456 if (cause)
457 {
386 for (tmp = op->above; tmp; tmp = tmp->above) 458 for (tmp = op->above; tmp; tmp = tmp->above)
387 /* Comment reproduced from update_buttons(): */ 459 /* Comment reproduced from update_buttons(): */
388 /* Basically, if the move_type matches that on what the 460 /* Basically, if the move_type matches that on what the
389 * button wants, we count it. The second check is so that 461 * button wants, we count it. The second check is so that
390 * objects that don't move (swords, etc) will count. Note that 462 * objects that don't move (swords, etc) will count. Note that
391 * this means that more work is needed to make buttons 463 * this means that more work is needed to make buttons
392 * that are only triggered by flying objects. 464 * that are only triggered by flying objects.
393 */ 465 */
394 466
395 if ((tmp->move_type & op->move_on) || tmp->move_type==0) { 467 if ((tmp->move_type & op->move_on) || tmp->move_type == 0)
396 tot += tmp->weight * (tmp->nrof ? tmp->nrof : 1) 468 {
397 + tmp->carrying; 469 tot += tmp->weight * (tmp->nrof ? tmp->nrof : 1) + tmp->carrying;
398 } 470 }
399 if (tot >= op->weight) 471 if (tot >= op->weight)
400 push = 1; 472 push = 1;
401 if (op->stats.ac == push) 473 if (op->stats.ac == push)
402 return 0; 474 return 0;
403 op->stats.ac = push; 475 op->stats.ac = push;
404 if (NUM_ANIMATIONS(op) > 1) { 476 if (NUM_ANIMATIONS (op) > 1)
477 {
405 SET_ANIMATION (op, push); 478 SET_ANIMATION (op, push);
406 update_object (op, UP_OBJ_FACE); 479 update_object (op, UP_OBJ_FACE);
407 } 480 }
408 if (in_movement || ! push) 481 if (in_movement || !push)
409 return 0; 482 return 0;
410 } 483 }
411 trigger_move (op, push); 484 trigger_move (op, push);
412 } 485 }
413 return 0; 486 return 0;
414 487
415 case TRIGGER_PEDESTAL: 488 case TRIGGER_PEDESTAL:
416 if (cause) { 489 if (cause)
490 {
417 for (tmp = op->above; tmp; tmp = tmp->above) { 491 for (tmp = op->above; tmp; tmp = tmp->above)
418 object *head = tmp->head ? tmp->head : tmp;
419
420 /* See comment in TRIGGER_BUTTON about move_types */
421 if (((head->move_type & op->move_on) || head->move_type==0)
422 && (head->race==op->slaying ||
423 (!strcmp (op->slaying, "player") && head->type == PLAYER))) {
424 push = 1;
425 break;
426 }
427 }
428 if (op->stats.ac == push)
429 return 0;
430 op->stats.ac = push;
431 if (NUM_ANIMATIONS(op) > 1) {
432 SET_ANIMATION (op, push);
433 update_object (op, UP_OBJ_FACE);
434 } 492 {
435 update_object(op,UP_OBJ_FACE); 493 object *head = tmp->head ? tmp->head : tmp;
436 if (in_movement || ! push)
437 return 0;
438 }
439 trigger_move (op, push);
440 return 0;
441 494
442 case TRIGGER_ALTAR: 495 /* See comment in TRIGGER_BUTTON about move_types */
443 if (cause) { 496 if (((head->move_type & op->move_on) || head->move_type == 0)
444 if (in_movement) 497 && (head->race == op->slaying || (!strcmp (op->slaying, "player") && head->type == PLAYER)))
445 return 0; 498 {
446 if (operate_altar (op, &cause)) { 499 push = 1;
447 if (NUM_ANIMATIONS(op) > 1) { 500 break;
448 SET_ANIMATION (op, 1);
449 update_object(op, UP_OBJ_FACE);
450 } 501 }
451 if (op->last_sp >= 0) { 502 }
452 trigger_move (op, 1); 503 if (op->stats.ac == push)
453 if (op->last_sp > 0) 504 return 0;
454 op->last_sp = -op->last_sp; 505 op->stats.ac = push;
455 }
456 else {
457 /* for trigger altar with last_sp, the ON/OFF
458 * status (-> +/- value) is "simulated":
459 */
460 op->value = !op->value;
461 trigger_move (op, 1);
462 op->last_sp = -op->last_sp;
463 op->value = !op->value;
464 }
465 return cause == NULL;
466 } else {
467 return 0;
468 }
469 } else {
470 if (NUM_ANIMATIONS(op) > 1) { 506 if (NUM_ANIMATIONS (op) > 1)
471 SET_ANIMATION (op, 0);
472 update_object(op, UP_OBJ_FACE);
473 } 507 {
474
475 /* If trigger_altar has "last_sp > 0" set on the map,
476 * it will push the connected value only once per sacrifice.
477 * Otherwise (default), the connected value will be
478 * pushed twice: First by sacrifice, second by reset! -AV
479 */
480 if (!op->last_sp)
481 trigger_move (op, 0);
482 else {
483 op->stats.wc = 0;
484 op->value = !op->value;
485 op->speed = 0;
486 update_ob_speed(op);
487 }
488 }
489 return 0;
490
491 case TRIGGER:
492 if (cause) {
493 if (in_movement)
494 return 0;
495 push = 1;
496 }
497 if (NUM_ANIMATIONS(op) > 1) {
498 SET_ANIMATION (op, push); 508 SET_ANIMATION (op, push);
499 update_object(op, UP_OBJ_FACE); 509 update_object (op, UP_OBJ_FACE);
510 }
511 update_object (op, UP_OBJ_FACE);
512 if (in_movement || !push)
513 return 0;
500 } 514 }
501 trigger_move (op, push); 515 trigger_move (op, push);
516 return 0;
517
518 case TRIGGER_ALTAR:
519 if (cause)
520 {
521 if (in_movement)
522 return 0;
523 if (operate_altar (op, &cause))
524 {
525 if (NUM_ANIMATIONS (op) > 1)
526 {
527 SET_ANIMATION (op, 1);
528 update_object (op, UP_OBJ_FACE);
529 }
530 if (op->last_sp >= 0)
531 {
532 trigger_move (op, 1);
533 if (op->last_sp > 0)
534 op->last_sp = -op->last_sp;
535 }
536 else
537 {
538 /* for trigger altar with last_sp, the ON/OFF
539 * status (-> +/- value) is "simulated":
540 */
541 op->value = !op->value;
542 trigger_move (op, 1);
543 op->last_sp = -op->last_sp;
544 op->value = !op->value;
545 }
546 return cause == NULL;
547 }
548 else
549 {
550 return 0;
551 }
552 }
553 else
554 {
555 if (NUM_ANIMATIONS (op) > 1)
556 {
557 SET_ANIMATION (op, 0);
558 update_object (op, UP_OBJ_FACE);
559 }
560
561 /* If trigger_altar has "last_sp > 0" set on the map,
562 * it will push the connected value only once per sacrifice.
563 * Otherwise (default), the connected value will be
564 * pushed twice: First by sacrifice, second by reset! -AV
565 */
566 if (!op->last_sp)
567 trigger_move (op, 0);
568 else
569 {
570 op->stats.wc = 0;
571 op->value = !op->value;
572 op->speed = 0;
573 update_ob_speed (op);
574 }
575 }
576 return 0;
577
578 case TRIGGER:
579 if (cause)
580 {
581 if (in_movement)
582 return 0;
583 push = 1;
584 }
585 if (NUM_ANIMATIONS (op) > 1)
586 {
587 SET_ANIMATION (op, push);
588 update_object (op, UP_OBJ_FACE);
589 }
590 trigger_move (op, push);
502 return 1; 591 return 1;
503 592
504 default: 593 default:
505 LOG(llevDebug, "Unknown trigger type: %s (%d)\n", op->name, op->type); 594 LOG (llevDebug, "Unknown trigger type: %s (%d)\n", &op->name, op->type);
506 return 0; 595 return 0;
507 } 596 }
508} 597}
509 598
599void
510void add_button_link(object *button, mapstruct *map, int connected) { 600add_button_link (object *button, maptile *map, int connected)
601{
511 oblinkpt *obp; 602 oblinkpt *obp;
512 objectlink *ol = get_objectlink(); 603 objectlink *ol = get_objectlink ();
513 604
514 if (!map) { 605 if (!map)
606 {
515 LOG(llevError, "Tried to add button-link without map.\n"); 607 LOG (llevError, "Tried to add button-link without map.\n");
516 return; 608 return;
517 } 609 }
610 if (!editor)
518 if (!editor) button->path_attuned = connected; /* peterm: I need this so I can rebuild 611 button->path_attuned = connected; /* peterm: I need this so I can rebuild
519 a connected map from a template map. */ 612 a connected map from a template map. */
613
520/* LOG(llevDebug,"adding button %s (%d)\n", button->name, connected);*/ 614/* LOG(llevDebug,"adding button %s (%d)\n", button->name, connected);*/
521 615
522 SET_FLAG(button,FLAG_IS_LINKED); 616 SET_FLAG (button, FLAG_IS_LINKED);
523 617
524 ol->ob = button; 618 ol->ob = button;
525 ol->id = button->count; 619 ol->id = button->count;
526 620
527 for (obp = map->buttons; obp && obp->value != connected; obp = obp->next); 621 for (obp = map->buttons; obp && obp->value != connected; obp = obp->next);
528 622
529 if (obp) { 623 if (obp)
624 {
530 ol->next = obp->link; 625 ol->next = obp->link;
531 obp->link = ol; 626 obp->link = ol;
627 }
532 } else { 628 else
629 {
533 obp = get_objectlinkpt(); 630 obp = get_objectlinkpt ();
534 obp->value = connected; 631 obp->value = connected;
535 632
536 obp->next = map->buttons; 633 obp->next = map->buttons;
537 map->buttons = obp; 634 map->buttons = obp;
538 obp->link = ol; 635 obp->link = ol;
539 } 636 }
540} 637}
541 638
542/* 639/*
543 * Remove the object from the linked lists of buttons in the map. 640 * Remove the object from the linked lists of buttons in the map.
544 * This is only needed by editors. 641 * This is only needed by editors.
545 */ 642 */
546 643
644void
547void remove_button_link(object *op) { 645remove_button_link (object *op)
646{
548 oblinkpt *obp; 647 oblinkpt *obp;
549 objectlink **olp, *ol; 648 objectlink **olp, *ol;
550 649
551 if (op->map == NULL) { 650 if (op->map == NULL)
651 {
552 LOG(llevError, "remove_button_link() in object without map.\n"); 652 LOG (llevError, "remove_button_link() in object without map.\n");
553 return; 653 return;
554 } 654 }
555 if (!QUERY_FLAG(op,FLAG_IS_LINKED)) { 655 if (!QUERY_FLAG (op, FLAG_IS_LINKED))
656 {
556 LOG(llevError, "remove_button_linked() in unlinked object.\n"); 657 LOG (llevError, "remove_button_linked() in unlinked object.\n");
557 return; 658 return;
558 } 659 }
559 for (obp = op->map->buttons; obp; obp = obp->next) 660 for (obp = op->map->buttons; obp; obp = obp->next)
560 for (olp = &obp->link; (ol = *olp); olp = &ol->next) 661 for (olp = &obp->link; (ol = *olp); olp = &ol->next)
561 if (ol->ob == op) { 662 if (ol->ob == op)
663 {
664
562/* LOG(llevDebug, "Removed link %d in button %s and map %s.\n", 665/* LOG(llevDebug, "Removed link %d in button %s and map %s.\n",
563 obp->value, op->name, op->map->path); 666 obp->value, op->name, op->map->path);
564*/ 667*/
565 *olp = ol->next; 668 *olp = ol->next;
566 free(ol); 669 free (ol);
567 return; 670 return;
568 } 671 }
569 LOG(llevError, "remove_button_linked(): couldn't find object.\n"); 672 LOG (llevError, "remove_button_linked(): couldn't find object.\n");
570 CLEAR_FLAG(op,FLAG_IS_LINKED); 673 CLEAR_FLAG (op, FLAG_IS_LINKED);
571} 674}
572 675
676/*
677 * Gets the objectlink for this connection from the map.
678 */
679oblinkpt *
680get_connection_links (maptile *map, long connection)
681{
682 for (oblinkpt * obp = map->buttons; obp; obp = obp->next)
683 if (obp->value == connection)
684 return obp;
685 return 0;
686}
687
573/* 688/*
574 * Return the first objectlink in the objects linked to this one 689 * Return the first objectlink in the objects linked to this one
575 */ 690 */
576 691
692oblinkpt *
577objectlink *get_button_links(const object *button) { 693get_button_links (const object *button)
694{
578 oblinkpt *obp; 695 oblinkpt *obp;
579 objectlink *ol; 696 objectlink *ol;
580 697
581 if (!button->map) 698 if (!button->map)
582 return NULL; 699 return NULL;
583 for (obp = button->map->buttons; obp; obp = obp->next) 700 for (obp = button->map->buttons; obp; obp = obp->next)
584 for (ol = obp->link; ol; ol = ol->next) 701 for (ol = obp->link; ol; ol = ol->next)
585 if (ol->ob == button && ol->id == button->count) 702 if (ol->ob == button && ol->id == button->count)
586 return obp->link; 703 return obp;
587 return NULL; 704 return NULL;
588} 705}
589 706
590/* 707/*
591 * Made as a separate function to increase efficiency 708 * Made as a separate function to increase efficiency
592 */ 709 */
593 710
711int
594int get_button_value(const object *button) { 712get_button_value (const object *button)
713{
595 oblinkpt *obp; 714 oblinkpt *obp;
596 objectlink *ol; 715 objectlink *ol;
597 716
598 if (!button->map) 717 if (!button->map)
599 return 0; 718 return 0;
610 * If floor is to be triggered must have 729 * If floor is to be triggered must have
611 * a speed of zero (default is 1 for all 730 * a speed of zero (default is 1 for all
612 * but the charm floor type). 731 * but the charm floor type).
613 * by b.t. thomas@nomad.astro.psu.edu 732 * by b.t. thomas@nomad.astro.psu.edu
614 */ 733 */
615 734
735void
616void do_mood_floor(object *op, object *op2) { 736do_mood_floor (object *op, object *source)
737{
617 object *tmp; 738 object *tmp;
618 object *tmp2; 739 object *tmp2;
619 740
741 if (!source)
742 source = op;
743
620 for (tmp = GET_MAP_OB(op->map, op->x, op->y); tmp; tmp=tmp->above) 744 for (tmp = GET_MAP_OB (op->map, op->x, op->y); tmp; tmp = tmp->above)
621 if (QUERY_FLAG(tmp, FLAG_MONSTER)) break; 745 if (QUERY_FLAG (tmp, FLAG_MONSTER))
746 break;
622 747
623 /* doesn't effect players, and if there is a player on this space, won't also 748 /* doesn't effect players, and if there is a player on this space, won't also
624 * be a monster here. 749 * be a monster here.
625 */ 750 */
626 if (!tmp || tmp->type == PLAYER) return; 751 if (!tmp || tmp->type == PLAYER)
752 return;
627 753
628 switch(op->last_sp) { 754 switch (op->last_sp)
755 {
629 case 0: /* furious--make all monsters mad */ 756 case 0: /* furious--make all monsters mad */
630 if(QUERY_FLAG(tmp, FLAG_UNAGGRESSIVE))
631 CLEAR_FLAG(tmp, FLAG_UNAGGRESSIVE);
632 if(QUERY_FLAG(tmp, FLAG_FRIENDLY)) {
633 CLEAR_FLAG(tmp, FLAG_FRIENDLY);
634 remove_friendly_object(tmp);
635 tmp->attack_movement = 0;
636 /* lots of checks here, but want to make sure we don't
637 * dereference a null value
638 */
639 if (tmp->type == GOLEM && tmp->owner && tmp->owner->type==PLAYER &&
640 tmp->owner->contr->ranges[range_golem]==tmp) {
641 tmp->owner->contr->ranges[range_golem]=NULL;
642 tmp->owner->contr->golem_count = 0;
643 }
644 tmp->owner = 0;
645 }
646 break;
647 case 1: /* angry -- get neutral monsters mad */
648 if(QUERY_FLAG(tmp, FLAG_UNAGGRESSIVE)&& 757 if (QUERY_FLAG (tmp, FLAG_UNAGGRESSIVE))
649 !QUERY_FLAG(tmp, FLAG_FRIENDLY))
650 CLEAR_FLAG(tmp, FLAG_UNAGGRESSIVE); 758 CLEAR_FLAG (tmp, FLAG_UNAGGRESSIVE);
651 break; 759 if (QUERY_FLAG (tmp, FLAG_FRIENDLY))
760 {
761 CLEAR_FLAG (tmp, FLAG_FRIENDLY);
762 remove_friendly_object (tmp);
763 tmp->attack_movement = 0;
764 /* lots of checks here, but want to make sure we don't
765 * dereference a null value
766 */
767 if (tmp->type == GOLEM && tmp->owner && tmp->owner->type == PLAYER && tmp->owner->contr->ranges[range_golem] == tmp)
768 {
769 tmp->owner->contr->ranges[range_golem] = NULL;
770 tmp->owner->contr->golem_count = 0;
771 }
772 tmp->owner = 0;
773 }
774 break;
775 case 1: /* angry -- get neutral monsters mad */
776 if (QUERY_FLAG (tmp, FLAG_UNAGGRESSIVE) && !QUERY_FLAG (tmp, FLAG_FRIENDLY))
777 CLEAR_FLAG (tmp, FLAG_UNAGGRESSIVE);
778 break;
652 case 2: /* calm -- pacify unfriendly monsters */ 779 case 2: /* calm -- pacify unfriendly monsters */
653 if(!QUERY_FLAG(tmp, FLAG_UNAGGRESSIVE)) 780 if (!QUERY_FLAG (tmp, FLAG_UNAGGRESSIVE))
654 SET_FLAG(tmp, FLAG_UNAGGRESSIVE); 781 SET_FLAG (tmp, FLAG_UNAGGRESSIVE);
655 break; 782 break;
656 case 3: /* make all monsters fall asleep */ 783 case 3: /* make all monsters fall asleep */
657 if(!QUERY_FLAG(tmp, FLAG_SLEEP)) 784 if (!QUERY_FLAG (tmp, FLAG_SLEEP))
658 SET_FLAG(tmp, FLAG_SLEEP); 785 SET_FLAG (tmp, FLAG_SLEEP);
659 break; 786 break;
660 case 4: /* charm all monsters */ 787 case 4: /* charm all monsters */
788 if (op == source)
789 break; /* only if 'connected' */
661 790
662 if(op == op2) break; /* only if 'connected' */
663
664 for(tmp2=get_map_ob(op2->map,op2->x,op2->y); /* finding an owner */ 791 for (tmp2 = get_map_ob (source->map, source->x, source->y); /* finding an owner */
665 tmp2->type!=PLAYER;tmp2=tmp2->above) 792 tmp2->type != PLAYER; tmp2 = tmp2->above)
666 if(tmp2->above==NULL) break; 793 if (tmp2->above == NULL)
794 break;
667 795
668 if (tmp2->type != PLAYER) 796 if (tmp2->type != PLAYER)
669 break; 797 break;
670 set_owner(tmp,tmp2); 798 set_owner (tmp, tmp2);
671 SET_FLAG(tmp,FLAG_MONSTER); 799 SET_FLAG (tmp, FLAG_MONSTER);
672 tmp->stats.exp = 0; 800 tmp->stats.exp = 0;
673 SET_FLAG(tmp, FLAG_FRIENDLY); 801 SET_FLAG (tmp, FLAG_FRIENDLY);
674 add_friendly_object (tmp); 802 add_friendly_object (tmp);
675 tmp->attack_movement = PETMOVE; 803 tmp->attack_movement = PETMOVE;
676 break; 804 break;
677 805
678 default: 806 default:
679 break; 807 break;
680
681 } 808 }
682} 809}
683 810
684/* this function returns the object it matches, or NULL if non. 811/* this function returns the object it matches, or NULL if non.
685 * It will descend through containers to find the object. 812 * It will descend through containers to find the object.
686 * slaying = match object slaying flag 813 * slaying = match object slaying flag
687 * race = match object archetype name flag 814 * race = match object archetype name flag
688 * hp = match object type (excpt type '0'== PLAYER) 815 * hp = match object type (excpt type '0'== PLAYER)
689 */ 816 */
690 817
818object *
691object * check_inv_recursive(object *op, const object *trig) 819check_inv_recursive (object *op, const object *trig)
692{ 820{
693 object *tmp,*ret=NULL; 821 object *tmp, *ret = NULL;
694 822
695 /* First check the object itself. */ 823 /* First check the object itself. */
696 if((trig->stats.hp && (op->type == trig->stats.hp)) 824 if ((trig->stats.hp && (op->type == trig->stats.hp))
697 || (trig->slaying && (op->slaying == trig->slaying)) 825 || (trig->slaying && (op->slaying == trig->slaying)) || (trig->race && (op->arch->name == trig->race)))
698 || (trig->race && (op->arch->name == trig->race)))
699 return op; 826 return op;
700 827
701 for(tmp=op->inv; tmp; tmp=tmp->below) { 828 for (tmp = op->inv; tmp; tmp = tmp->below)
702 if (tmp->inv) { 829 {
830 if (tmp->inv)
831 {
703 ret=check_inv_recursive(tmp, trig); 832 ret = check_inv_recursive (tmp, trig);
704 if (ret) return ret; 833 if (ret)
705 } 834 return ret;
835 }
706 else if((trig->stats.hp && (tmp->type == trig->stats.hp)) 836 else if ((trig->stats.hp && (tmp->type == trig->stats.hp))
707 || (trig->slaying && (tmp->slaying == trig->slaying)) 837 || (trig->slaying && (tmp->slaying == trig->slaying)) || (trig->race && (tmp->arch->name == trig->race)))
708 || (trig->race && (tmp->arch->name == trig->race)))
709 return tmp; 838 return tmp;
710 } 839 }
711 return NULL; 840 return NULL;
712} 841}
713 842
714/* check_inv(), a function to search the inventory, 843/* check_inv(), a function to search the inventory,
715 * of a player and then based on a set of conditions, 844 * of a player and then based on a set of conditions,
716 * the square will activate connected items. 845 * the square will activate connected items.
718 * Values are: last_sp = 1/0 obj/no obj triggers 847 * Values are: last_sp = 1/0 obj/no obj triggers
719 * last_heal = 1/0 remove/dont remove obj if triggered 848 * last_heal = 1/0 remove/dont remove obj if triggered
720 * -b.t. (thomas@nomad.astro.psu.edu 849 * -b.t. (thomas@nomad.astro.psu.edu
721 */ 850 */
722 851
852void
723void check_inv (object *op, object *trig) { 853check_inv (object *op, object *trig)
854{
724object *match; 855 object *match;
725 856
726 if(op->type != PLAYER) return; 857 if (op->type != PLAYER)
858 return;
727 match = check_inv_recursive(op,trig); 859 match = check_inv_recursive (op, trig);
728 if (match && trig->last_sp) { 860 if (match && trig->last_sp)
861 {
729 if(trig->last_heal) 862 if (trig->last_heal)
730 decrease_ob(match); 863 decrease_ob (match);
731 use_trigger(trig); 864 use_trigger (trig);
732 } 865 }
733 else if (!match && !trig->last_sp) 866 else if (!match && !trig->last_sp)
734 use_trigger(trig); 867 use_trigger (trig);
735} 868}
736 869
737 870
738/* This does a minimal check of the button link consistency for object 871/* This does a minimal check of the button link consistency for object
739 * map. All it really does it much sure the object id link that is set 872 * map. All it really does it much sure the object id link that is set
740 * matches what the object has. 873 * matches what the object has.
741 */ 874 */
875void
742void verify_button_links(const mapstruct *map) { 876verify_button_links (const maptile *map)
877{
743 oblinkpt *obp; 878 oblinkpt *obp;
744 objectlink *ol; 879 objectlink *ol;
745 880
746 if (!map) return; 881 if (!map)
882 return;
747 883
748 for (obp = map->buttons; obp; obp = obp->next) { 884 for (obp = map->buttons; obp; obp = obp->next)
885 {
749 for (ol=obp->link; ol; ol=ol->next) { 886 for (ol = obp->link; ol; ol = ol->next)
887 {
750 if (ol->id!=ol->ob->count) 888 if (ol->id != ol->ob->count)
751 LOG(llevError,"verify_button_links: object %s on list is corrupt (%d!=%d)\n",ol->ob->name, ol->id, ol->ob->count); 889 LOG (llevError, "verify_button_links: object %s on list is corrupt (%d!=%d)\n", &ol->ob->name, ol->id, ol->ob->count);
752 } 890 }
753 } 891 }
754} 892}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines