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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines