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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines