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.9 by root, Wed Sep 13 23:42:23 2006 UTC vs.
Revision 1.20 by root, Tue Dec 26 08:54:58 2006 UTC

1
2/*
3 * static char *rcsid_button_c =
4 * "$Id: button.C,v 1.9 2006/09/13 23:42:23 root Exp $";
5 */
6
7/* 1/*
8 CrossFire, A Multiplayer game for X-windows 2 CrossFire, A Multiplayer game for X-windows
9 3
10 Copyright (C) 2002 Mark Wedel & Crossfire Development Team 4 Copyright (C) 2002 Mark Wedel & Crossfire Development Team
11 Copyright (C) 1992 Frank Tore Johansen 5 Copyright (C) 1992 Frank Tore Johansen
22 16
23 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
24 along with this program; if not, write to the Free Software 18 along with this program; if not, write to the Free Software
25 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 20
27 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>
28*/ 22*/
29 23
30#include <global.h> 24#include <global.h>
31#include <funcpoint.h> 25#include <funcpoint.h>
32 26
41 * 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.
42 */ 36 */
43void 37void
44activate_connection_link (objectlink * ol, bool state, object *source = 0) 38activate_connection_link (objectlink * ol, bool state, object *source = 0)
45{ 39{
46 object *tmp = 0;
47
48 for (; ol; ol = ol->next) 40 for (; ol; ol = ol->next)
49 { 41 {
50 if (!ol->ob || ol->ob->count != ol->id) 42 if (!ol->ob)
51 { 43 {
52 LOG (llevError, "Internal error in activate_connection_link (%ld).\n", ol->id); 44 LOG (llevError, "Internal error in activate_connection_link.\n");
53 continue; 45 continue;
54 } 46 }
47
55 /* a button link object can become freed when the map is saving. As 48 /* a button link object can become freed when the map is saving. As
56 * a map is saved, objects are removed and freed, and if an object is 49 * a map is saved, objects are removed and freed, and if an object is
57 * on top of a button, this function is eventually called. If a map 50 * on top of a button, this function is eventually called. If a map
58 * is getting moved out of memory, the status of buttons and levers 51 * is getting moved out of memory, the status of buttons and levers
59 * probably isn't important - it will get sorted out when the map is 52 * probably isn't important - it will get sorted out when the map is
60 * re-loaded. As such, just exit this function if that is the case. 53 * re-loaded. As such, just exit this function if that is the case.
61 */ 54 */
62 55
63 if (QUERY_FLAG (ol->ob, FLAG_FREED)) 56 if (QUERY_FLAG (ol->ob, FLAG_FREED))
64 return; 57 return;
58
65 tmp = ol->ob; 59 object *tmp = ol->ob;
66 60
67 /* if the criteria isn't appropriate, don't do anything */ 61 /* if the criteria isn't appropriate, don't do anything */
68 if (state && !QUERY_FLAG (tmp, FLAG_ACTIVATE_ON_PUSH)) 62 if (state && !QUERY_FLAG (tmp, FLAG_ACTIVATE_ON_PUSH))
69 continue; 63 continue;
70 if (!state && !QUERY_FLAG (tmp, FLAG_ACTIVATE_ON_RELEASE)) 64 if (!state && !QUERY_FLAG (tmp, FLAG_ACTIVATE_ON_RELEASE))
71 continue; 65 continue;
72 66
73 switch (tmp->type) 67 switch (tmp->type)
74 { 68 {
75 case GATE: 69 case GATE:
76 case HOLE: 70 case HOLE:
77 tmp->value = tmp->stats.maxsp ? !state : state; 71 tmp->value = tmp->stats.maxsp ? !state : state;
78 tmp->speed = 0.5; 72 tmp->set_speed (0.5);
79 update_ob_speed (tmp);
80 break; 73 break;
81 74
82 case CF_HANDLE: 75 case CF_HANDLE:
83 SET_ANIMATION (tmp, (tmp->value = tmp->stats.maxsp ? !state : state)); 76 SET_ANIMATION (tmp, (tmp->value = tmp->stats.maxsp ? !state : state));
84 update_object (tmp, UP_OBJ_FACE); 77 update_object (tmp, UP_OBJ_FACE);
85 break; 78 break;
86 79
87 case SIGN: 80 case SIGN:
88 if (!tmp->stats.food || tmp->last_eat < tmp->stats.food) 81 if (!tmp->stats.food || tmp->last_eat < tmp->stats.food)
89 { 82 {
90 new_info_map (NDI_UNIQUE | NDI_NAVY, tmp->map, tmp->msg); 83 new_info_map (NDI_UNIQUE | NDI_NAVY, tmp->map, tmp->msg);
91 if (tmp->stats.food) 84 if (tmp->stats.food)
92 tmp->last_eat++; 85 tmp->last_eat++;
93 } 86 }
94 break; 87 break;
95 88
96 case ALTAR: 89 case ALTAR:
97 tmp->value = 1; 90 tmp->value = 1;
98 SET_ANIMATION (tmp, tmp->value); 91 SET_ANIMATION (tmp, tmp->value);
99 update_object (tmp, UP_OBJ_FACE); 92 update_object (tmp, UP_OBJ_FACE);
100 break; 93 break;
101 94
102 case BUTTON: 95 case BUTTON:
103 case PEDESTAL: 96 case PEDESTAL:
104 tmp->value = state; 97 tmp->value = state;
105 SET_ANIMATION (tmp, tmp->value); 98 SET_ANIMATION (tmp, tmp->value);
106 update_object (tmp, UP_OBJ_FACE); 99 update_object (tmp, UP_OBJ_FACE);
107 break; 100 break;
108 101
109 case MOOD_FLOOR: 102 case MOOD_FLOOR:
110 do_mood_floor (tmp, source); 103 do_mood_floor (tmp, source);
111 break; 104 break;
112 105
113 case TIMED_GATE: 106 case TIMED_GATE:
114 tmp->speed = tmp->arch->clone.speed; 107 tmp->set_speed (tmp->arch->clone.speed);
115 update_ob_speed (tmp); /* original values */
116 tmp->value = tmp->arch->clone.value; 108 tmp->value = tmp->arch->clone.value;
117 tmp->stats.sp = 1; 109 tmp->stats.sp = 1;
118 tmp->stats.hp = tmp->stats.maxhp; 110 tmp->stats.hp = tmp->stats.maxhp;
119 /* Handle multipart gates. We copy the value for the other parts 111 /* Handle multipart gates. We copy the value for the other parts
120 * from the head - this ensures that the data will consistent 112 * from the head - this ensures that the data will consistent
121 */ 113 */
122 for (tmp = tmp->more; tmp != NULL; tmp = tmp->more) 114 for (tmp = tmp->more; tmp; tmp = tmp->more)
123 { 115 {
124 tmp->speed = tmp->head->speed;
125 tmp->value = tmp->head->value; 116 tmp->value = tmp->head->value;
126 tmp->stats.sp = tmp->head->stats.sp; 117 tmp->stats.sp = tmp->head->stats.sp;
127 tmp->stats.hp = tmp->head->stats.hp; 118 tmp->stats.hp = tmp->head->stats.hp;
128 update_ob_speed (tmp); 119 tmp->set_speed (tmp->head->speed);
129 } 120 }
130 break; 121 break;
131 122
132 case DIRECTOR: 123 case DIRECTOR:
133 case FIREWALL: 124 case FIREWALL:
134 if (!QUERY_FLAG (tmp, FLAG_ANIMATE) && tmp->type == FIREWALL) 125 if (!QUERY_FLAG (tmp, FLAG_ANIMATE) && tmp->type == FIREWALL)
135 move_firewall (tmp); 126 move_firewall (tmp);
136 else 127 else
137 { 128 {
138 if ((tmp->stats.sp += tmp->stats.maxsp) > 8) /* next direction */ 129 if ((tmp->stats.sp += tmp->stats.maxsp) > 8) /* next direction */
139 tmp->stats.sp = ((tmp->stats.sp - 1) % 8) + 1; 130 tmp->stats.sp = ((tmp->stats.sp - 1) % 8) + 1;
140 animate_turning (tmp); 131 animate_turning (tmp);
141 } 132 }
142 break; 133 break;
143 134
144 case TELEPORTER: 135 case TELEPORTER:
145 move_teleporter (tmp); 136 move_teleporter (tmp);
146 break; 137 break;
147 138
148 case CREATOR: 139 case CREATOR:
149 move_creator (tmp); 140 move_creator (tmp);
150 break; 141 break;
151 142
152 case TRIGGER_MARKER: 143 case TRIGGER_MARKER:
153 move_marker (tmp); 144 move_marker (tmp);
154 break; 145 break;
155 146
156 case DUPLICATOR: 147 case DUPLICATOR:
157 move_duplicator (tmp); 148 move_duplicator (tmp);
158 break; 149 break;
159 } 150 }
160 } 151 }
161} 152}
162 153
163/* 154/*
193 * the connection was 'state' or 'released'. So that you can activate objects 184 * the connection was 'state' or 'released'. So that you can activate objects
194 * who have FLAG_ACTIVATE_ON_PUSH/RELEASE set properly. 185 * who have FLAG_ACTIVATE_ON_PUSH/RELEASE set properly.
195 * 186 *
196 */ 187 */
197void 188void
198activate_connection (mapstruct *map, long connection, bool state) 189activate_connection (maptile *map, long connection, bool state)
199{ 190{
200 if (INVOKE_MAP (TRIGGER, map, ARG_INT64 (connection), ARG_INT (state))) 191 if (INVOKE_MAP (TRIGGER, map, ARG_INT64 (connection), ARG_INT (state)))
201 return; 192 return;
202 193
203 oblinkpt *obp = get_connection_links (map, connection); 194 oblinkpt *obp = get_connection_links (map, connection);
210 * Updates everything connected with the button op. 201 * Updates everything connected with the button op.
211 * After changing the state of a button, this function must be called 202 * After changing the state of a button, this function must be called
212 * to make sure that all gates and other buttons connected to the 203 * to make sure that all gates and other buttons connected to the
213 * button reacts to the (eventual) change of state. 204 * button reacts to the (eventual) change of state.
214 */ 205 */
215
216void 206void
217update_button (object *op) 207update_button (object *op)
218{ 208{
219 object *ab, *tmp, *head; 209 object *ab, *tmp, *head;
220 int tot, any_down = 0, old_value = op->value; 210 int tot, any_down = 0, old_value = op->value;
224 obp = get_button_links (op); 214 obp = get_button_links (op);
225 /* LOG(llevDebug, "update_button: %s (%d)\n", op->name, op->count); */ 215 /* LOG(llevDebug, "update_button: %s (%d)\n", op->name, op->count); */
226 if (obp) 216 if (obp)
227 for (ol = obp->link; ol; ol = ol->next) 217 for (ol = obp->link; ol; ol = ol->next)
228 { 218 {
229 if (!ol->ob || ol->ob->count != ol->id) 219 if (!ol->ob)
230 { 220 {
231 LOG (llevDebug, "Internal error in update_button (%s).\n", &op->name); 221 LOG (llevDebug, "Internal error in update_button (%s).\n", &op->name);
232 continue; 222 continue;
233 } 223 }
224
234 tmp = ol->ob; 225 tmp = ol->ob;
235 if (tmp->type == BUTTON) 226 if (tmp->type == BUTTON)
236 { 227 {
237 for (ab = tmp->above, tot = 0; ab != NULL; ab = ab->above) 228 for (ab = tmp->above, tot = 0; ab != NULL; ab = ab->above)
238 /* Bug? The pedestal code below looks for the head of 229 /* Bug? The pedestal code below looks for the head of
287/* 278/*
288 * Updates every button on the map (by calling update_button() for them). 279 * Updates every button on the map (by calling update_button() for them).
289 */ 280 */
290 281
291void 282void
292update_buttons (mapstruct *m) 283update_buttons (maptile *m)
293{ 284{
294 objectlink *ol; 285 objectlink *ol;
295 oblinkpt *obp; 286 oblinkpt *obp;
296 287
297 for (obp = m->buttons; obp; obp = obp->next) 288 for (obp = m->buttons; obp; obp = obp->next)
298 for (ol = obp->link; ol; ol = ol->next) 289 for (ol = obp->link; ol; ol = ol->next)
299 { 290 {
300 if (!ol->ob || ol->ob->count != ol->id) 291 if (!ol->ob)
301 { 292 {
302 LOG (llevError, "Internal error in update_button (%s (%dx%d):%d, connected %ld).\n", 293 LOG (llevError, "Internal error in update_button (%s (%dx%d), connected %ld).\n",
303 ol->ob ? (const char *) ol->ob->name : "null", ol->ob ? ol->ob->x : -1, ol->ob ? ol->ob->y : -1, ol->id, obp->value); 294 ol->ob ? (const char *) ol->ob->name : "null", ol->ob ? ol->ob->x : -1, ol->ob ? ol->ob->y : -1, obp->value);
304 continue; 295 continue;
305 } 296 }
297
306 if (ol->ob->type == BUTTON || ol->ob->type == PEDESTAL) 298 if (ol->ob->type == BUTTON || ol->ob->type == PEDESTAL)
307 { 299 {
308 update_button (ol->ob); 300 update_button (ol->ob);
309 break; 301 break;
310 } 302 }
357 ARCH_SACRIFICE (altar) == sacrifice->name || 349 ARCH_SACRIFICE (altar) == sacrifice->name ||
358 ARCH_SACRIFICE (altar) == sacrifice->slaying || 350 ARCH_SACRIFICE (altar) == sacrifice->slaying ||
359 (!strcmp (ARCH_SACRIFICE (altar), query_base_name (sacrifice, 0)))) 351 (!strcmp (ARCH_SACRIFICE (altar), query_base_name (sacrifice, 0))))
360 && NROF_SACRIFICE (altar) <= (sacrifice->nrof ? sacrifice->nrof : 1)) 352 && NROF_SACRIFICE (altar) <= (sacrifice->nrof ? sacrifice->nrof : 1))
361 return 1; 353 return 1;
354
362 if (strcmp (ARCH_SACRIFICE (altar), "money") == 0 355 if (strcmp (ARCH_SACRIFICE (altar), "money") == 0
363 && sacrifice->type == MONEY && sacrifice->nrof * sacrifice->value >= NROF_SACRIFICE (altar)) 356 && sacrifice->type == MONEY && sacrifice->nrof * sacrifice->value >= NROF_SACRIFICE (altar))
364 return 1; 357 return 1;
365 } 358 }
359
366 return 0; 360 return 0;
367} 361}
368 362
369/* 363/*
370 * operate_altar checks if sacrifice was accepted and removes sacrificed 364 * operate_altar checks if sacrifice was accepted and removes sacrificed
417{ 411{
418 op->stats.wc = state; 412 op->stats.wc = state;
419 if (state) 413 if (state)
420 { 414 {
421 use_trigger (op); 415 use_trigger (op);
422 if (op->stats.exp > 0) /* check sanity */ 416 op->set_speed (op->stats.exp > 0 ? 1. / op->stats.exp : 1.);
423 op->speed = 1.0 / op->stats.exp;
424 else
425 op->speed = 1.0;
426 update_ob_speed (op);
427 op->speed_left = -1; 417 op->speed_left = -1;
428 } 418 }
429 else 419 else
430 { 420 {
431 use_trigger (op); 421 use_trigger (op);
432 op->speed = 0; 422 op->set_speed (0);
433 update_ob_speed (op);
434 } 423 }
435} 424}
436 425
437 426
438/* 427/*
573 trigger_move (op, 0); 562 trigger_move (op, 0);
574 else 563 else
575 { 564 {
576 op->stats.wc = 0; 565 op->stats.wc = 0;
577 op->value = !op->value; 566 op->value = !op->value;
578 op->speed = 0; 567 op->set_speed (0);
579 update_ob_speed (op);
580 } 568 }
581 } 569 }
582 return 0; 570 return 0;
583 571
584 case TRIGGER: 572 case TRIGGER:
585 if (cause) 573 if (cause)
586 { 574 {
587 if (in_movement) 575 if (in_movement)
588 return 0; 576 return 0;
577
589 push = 1; 578 push = 1;
590 } 579 }
580
591 if (NUM_ANIMATIONS (op) > 1) 581 if (NUM_ANIMATIONS (op) > 1)
592 { 582 {
593 SET_ANIMATION (op, push); 583 SET_ANIMATION (op, push);
594 update_object (op, UP_OBJ_FACE); 584 update_object (op, UP_OBJ_FACE);
595 } 585 }
586
596 trigger_move (op, push); 587 trigger_move (op, push);
597 return 1; 588 return 1;
598 589
599 default: 590 default:
600 LOG (llevDebug, "Unknown trigger type: %s (%d)\n", &op->name, op->type); 591 LOG (llevDebug, "Unknown trigger type: %s (%d)\n", &op->name, op->type);
601 return 0; 592 return 0;
602 } 593 }
603} 594}
604 595
605void 596void
606add_button_link (object *button, mapstruct *map, int connected) 597add_button_link (object *button, maptile *map, int connected)
607{ 598{
608 oblinkpt *obp; 599 oblinkpt *obp;
609 objectlink *ol = get_objectlink (); 600 objectlink *ol = get_objectlink ();
610 601
611 if (!map) 602 if (!map)
612 { 603 {
613 LOG (llevError, "Tried to add button-link without map.\n"); 604 LOG (llevError, "Tried to add button-link without map.\n");
614 return; 605 return;
615 } 606 }
616 if (!editor) 607
617 button->path_attuned = connected; /* peterm: I need this so I can rebuild 608 button->path_attuned = connected; /* peterm: I need this so I can rebuild
618 a connected map from a template map. */ 609 a connected map from a template map. */
619
620/* LOG(llevDebug,"adding button %s (%d)\n", button->name, connected);*/
621 610
622 SET_FLAG (button, FLAG_IS_LINKED); 611 SET_FLAG (button, FLAG_IS_LINKED);
623 612
624 ol->ob = button; 613 ol->ob = button;
625 ol->id = button->count;
626 614
627 for (obp = map->buttons; obp && obp->value != connected; obp = obp->next); 615 for (obp = map->buttons; obp && obp->value != connected; obp = obp->next)
616 ;
628 617
629 if (obp) 618 if (obp)
630 { 619 {
631 ol->next = obp->link; 620 ol->next = obp->link;
632 obp->link = ol; 621 obp->link = ol;
656 if (op->map == NULL) 645 if (op->map == NULL)
657 { 646 {
658 LOG (llevError, "remove_button_link() in object without map.\n"); 647 LOG (llevError, "remove_button_link() in object without map.\n");
659 return; 648 return;
660 } 649 }
650
661 if (!QUERY_FLAG (op, FLAG_IS_LINKED)) 651 if (!QUERY_FLAG (op, FLAG_IS_LINKED))
662 { 652 {
663 LOG (llevError, "remove_button_linked() in unlinked object.\n"); 653 LOG (llevError, "remove_button_linked() in unlinked object.\n");
664 return; 654 return;
665 } 655 }
656
666 for (obp = op->map->buttons; obp; obp = obp->next) 657 for (obp = op->map->buttons; obp; obp = obp->next)
667 for (olp = &obp->link; (ol = *olp); olp = &ol->next) 658 for (olp = &obp->link; (ol = *olp); olp = &ol->next)
668 if (ol->ob == op) 659 if (ol->ob == op)
669 { 660 {
670 661
671/* LOG(llevDebug, "Removed link %d in button %s and map %s.\n", 662/* LOG(llevDebug, "Removed link %d in button %s and map %s.\n",
672 obp->value, op->name, op->map->path); 663 obp->value, op->name, op->map->path);
673*/ 664*/
674 *olp = ol->next; 665 *olp = ol->next;
675 free (ol); 666 delete ol;
676 return; 667 return;
677 } 668 }
669
678 LOG (llevError, "remove_button_linked(): couldn't find object.\n"); 670 LOG (llevError, "remove_button_linked(): couldn't find object.\n");
679 CLEAR_FLAG (op, FLAG_IS_LINKED); 671 CLEAR_FLAG (op, FLAG_IS_LINKED);
680} 672}
681 673
682/* 674/*
683 * Gets the objectlink for this connection from the map. 675 * Gets the objectlink for this connection from the map.
684 */ 676 */
685oblinkpt * 677oblinkpt *
686get_connection_links (mapstruct *map, long connection) 678get_connection_links (maptile *map, long connection)
687{ 679{
688 for (oblinkpt * obp = map->buttons; obp; obp = obp->next) 680 for (oblinkpt * obp = map->buttons; obp; obp = obp->next)
689 if (obp->value == connection) 681 if (obp->value == connection)
690 return obp; 682 return obp;
683
691 return 0; 684 return 0;
692} 685}
693 686
694/* 687/*
695 * Return the first objectlink in the objects linked to this one 688 * Return the first objectlink in the objects linked to this one
701 oblinkpt *obp; 694 oblinkpt *obp;
702 objectlink *ol; 695 objectlink *ol;
703 696
704 if (!button->map) 697 if (!button->map)
705 return NULL; 698 return NULL;
699
706 for (obp = button->map->buttons; obp; obp = obp->next) 700 for (obp = button->map->buttons; obp; obp = obp->next)
707 for (ol = obp->link; ol; ol = ol->next) 701 for (ol = obp->link; ol; ol = ol->next)
708 if (ol->ob == button && ol->id == button->count) 702 if (ol->ob == button)
709 return obp; 703 return obp;
704
710 return NULL; 705 return NULL;
711} 706}
712 707
713/* 708/*
714 * Made as a separate function to increase efficiency 709 * Made as a separate function to increase efficiency
722 717
723 if (!button->map) 718 if (!button->map)
724 return 0; 719 return 0;
725 for (obp = button->map->buttons; obp; obp = obp->next) 720 for (obp = button->map->buttons; obp; obp = obp->next)
726 for (ol = obp->link; ol; ol = ol->next) 721 for (ol = obp->link; ol; ol = ol->next)
727 if (ol->ob == button && ol->id == button->count) 722 if (ol->ob == button)
728 return obp->value; 723 return obp->value;
729 return 0; 724 return 0;
730} 725}
731 726
732/* This routine makes monsters who are 727/* This routine makes monsters who are
769 tmp->attack_movement = 0; 764 tmp->attack_movement = 0;
770 /* lots of checks here, but want to make sure we don't 765 /* lots of checks here, but want to make sure we don't
771 * dereference a null value 766 * dereference a null value
772 */ 767 */
773 if (tmp->type == GOLEM && tmp->owner && tmp->owner->type == PLAYER && tmp->owner->contr->ranges[range_golem] == tmp) 768 if (tmp->type == GOLEM && tmp->owner && tmp->owner->type == PLAYER && tmp->owner->contr->ranges[range_golem] == tmp)
774 {
775 tmp->owner->contr->ranges[range_golem] = NULL; 769 tmp->owner->contr->ranges[range_golem] = 0;
776 tmp->owner->contr->golem_count = 0; 770
777 }
778 tmp->owner = 0; 771 tmp->owner = 0;
779 } 772 }
780 break; 773 break;
781 case 1: /* angry -- get neutral monsters mad */ 774 case 1: /* angry -- get neutral monsters mad */
782 if (QUERY_FLAG (tmp, FLAG_UNAGGRESSIVE) && !QUERY_FLAG (tmp, FLAG_FRIENDLY)) 775 if (QUERY_FLAG (tmp, FLAG_UNAGGRESSIVE) && !QUERY_FLAG (tmp, FLAG_FRIENDLY))
792 break; 785 break;
793 case 4: /* charm all monsters */ 786 case 4: /* charm all monsters */
794 if (op == source) 787 if (op == source)
795 break; /* only if 'connected' */ 788 break; /* only if 'connected' */
796 789
797 for (tmp2 = get_map_ob (source->map, source->x, source->y); /* finding an owner */ 790 for (tmp2 = GET_MAP_OB (source->map, source->x, source->y); /* finding an owner */
798 tmp2->type != PLAYER; tmp2 = tmp2->above) 791 tmp2->type != PLAYER; tmp2 = tmp2->above)
799 if (tmp2->above == NULL) 792 if (tmp2->above == NULL)
800 break; 793 break;
801 794
802 if (tmp2->type != PLAYER) 795 if (tmp2->type != PLAYER)
803 break; 796 break;
797
804 set_owner (tmp, tmp2); 798 tmp->set_owner (tmp2);
805 SET_FLAG (tmp, FLAG_MONSTER); 799 SET_FLAG (tmp, FLAG_MONSTER);
800
806 tmp->stats.exp = 0; 801 tmp->stats.exp = 0;
807 SET_FLAG (tmp, FLAG_FRIENDLY); 802 SET_FLAG (tmp, FLAG_FRIENDLY);
803
808 add_friendly_object (tmp); 804 add_friendly_object (tmp);
809 tmp->attack_movement = PETMOVE; 805 tmp->attack_movement = PETMOVE;
810 break; 806 break;
811 807
812 default: 808 default:
818 * It will descend through containers to find the object. 814 * It will descend through containers to find the object.
819 * slaying = match object slaying flag 815 * slaying = match object slaying flag
820 * race = match object archetype name flag 816 * race = match object archetype name flag
821 * hp = match object type (excpt type '0'== PLAYER) 817 * hp = match object type (excpt type '0'== PLAYER)
822 */ 818 */
823
824object * 819object *
825check_inv_recursive (object *op, const object *trig) 820check_inv_recursive (object *op, const object *trig)
826{ 821{
827 object *tmp, *ret = NULL; 822 object *tmp, *ret = NULL;
828 823
829 /* First check the object itself. */ 824 /* First check the object itself. */
830 if ((trig->stats.hp && (op->type == trig->stats.hp)) 825 if ((trig->stats.hp && (op->type == trig->stats.hp))
831 || (trig->slaying && (op->slaying == trig->slaying)) || (trig->race && (op->arch->name == trig->race))) 826 || (trig->slaying && (op->slaying == trig->slaying))
827 || (trig->race && (op->arch->name == trig->race)))
832 return op; 828 return op;
833 829
834 for (tmp = op->inv; tmp; tmp = tmp->below) 830 for (tmp = op->inv; tmp; tmp = tmp->below)
835 { 831 {
836 if (tmp->inv) 832 if (tmp->inv)
838 ret = check_inv_recursive (tmp, trig); 834 ret = check_inv_recursive (tmp, trig);
839 if (ret) 835 if (ret)
840 return ret; 836 return ret;
841 } 837 }
842 else if ((trig->stats.hp && (tmp->type == trig->stats.hp)) 838 else if ((trig->stats.hp && (tmp->type == trig->stats.hp))
843 || (trig->slaying && (tmp->slaying == trig->slaying)) || (trig->race && (tmp->arch->name == trig->race))) 839 || (trig->slaying && (tmp->slaying == trig->slaying))
840 || (trig->race && (tmp->arch->name == trig->race)))
844 return tmp; 841 return tmp;
845 } 842 }
846 return NULL; 843 return NULL;
847} 844}
848 845
851 * the square will activate connected items. 848 * the square will activate connected items.
852 * Monsters can't trigger this square (for now) 849 * Monsters can't trigger this square (for now)
853 * Values are: last_sp = 1/0 obj/no obj triggers 850 * Values are: last_sp = 1/0 obj/no obj triggers
854 * last_heal = 1/0 remove/dont remove obj if triggered 851 * last_heal = 1/0 remove/dont remove obj if triggered
855 * -b.t. (thomas@nomad.astro.psu.edu 852 * -b.t. (thomas@nomad.astro.psu.edu
856 */ 853 *
857 854 * Tue Dec 19 15:34:00 CET 2006 elmex: changed the function to ignore op
855 * because the check-inventory semantic essentially only applies when
856 * something is above the inventory checker.
857 * The semantic prior this change was: trigger if something has moved on or off
858 * and has a matching item. Imagine what happens if someone steps on the inventory
859 * checker with a matching item, has it, activates the connection, throws the item
860 * away, and then leaves the inventory checker. That would've caused an always-enabled
861 * state in the inventory checker. This won't happen anymore now.
862 *
863 */
858void 864void
859check_inv (object *op, object *trig) 865check_inv (object *op, object *trig)
860{ 866{
861 object *match; 867 trig->value = 0; // deactivate if none of the following conditions apply
862 868
863 if (op->type != PLAYER) 869 if (object *pl = trig->ms ().player ())
864 return; 870 {
865 match = check_inv_recursive (op, trig); 871 object *match = check_inv_recursive (pl, trig);
866 if (match && trig->last_sp)
867 {
868 if (trig->last_heal)
869 decrease_ob (match);
870 use_trigger (trig);
871 }
872 else if (!match && !trig->last_sp)
873 use_trigger (trig);
874}
875 872
876 873 if (match && trig->last_sp) // match == having
877/* This does a minimal check of the button link consistency for object
878 * map. All it really does it much sure the object id link that is set
879 * matches what the object has.
880 */
881void
882verify_button_links (const mapstruct *map)
883{
884 oblinkpt *obp;
885 objectlink *ol;
886
887 if (!map)
888 return;
889
890 for (obp = map->buttons; obp; obp = obp->next)
891 {
892 for (ol = obp->link; ol; ol = ol->next)
893 { 874 {
894 if (ol->id != ol->ob->count) 875 if (trig->last_heal)
895 LOG (llevError, "verify_button_links: object %s on list is corrupt (%d!=%d)\n", &ol->ob->name, ol->id, ol->ob->count); 876 decrease_ob (match);
877
878 trig->value = 1;
896 } 879 }
880 else if (!match && !trig->last_sp) // match == not having
881 trig->value = 1;
897 } 882 }
883
884 push_button (trig);
898} 885}
886

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines