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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines