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.19 by root, Mon Dec 25 11:25:49 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->speed = 0.5;
79 update_ob_speed (tmp); 73 update_ob_speed (tmp);
80 break; 74 break;
81 75
82 case CF_HANDLE: 76 case CF_HANDLE:
83 SET_ANIMATION (tmp, (tmp->value = tmp->stats.maxsp ? !state : state)); 77 SET_ANIMATION (tmp, (tmp->value = tmp->stats.maxsp ? !state : state));
84 update_object (tmp, UP_OBJ_FACE); 78 update_object (tmp, UP_OBJ_FACE);
85 break; 79 break;
86 80
87 case SIGN: 81 case SIGN:
88 if (!tmp->stats.food || tmp->last_eat < tmp->stats.food) 82 if (!tmp->stats.food || tmp->last_eat < tmp->stats.food)
89 { 83 {
90 new_info_map (NDI_UNIQUE | NDI_NAVY, tmp->map, tmp->msg); 84 new_info_map (NDI_UNIQUE | NDI_NAVY, tmp->map, tmp->msg);
91 if (tmp->stats.food) 85 if (tmp->stats.food)
92 tmp->last_eat++; 86 tmp->last_eat++;
93 } 87 }
94 break; 88 break;
95 89
96 case ALTAR: 90 case ALTAR:
97 tmp->value = 1; 91 tmp->value = 1;
98 SET_ANIMATION (tmp, tmp->value); 92 SET_ANIMATION (tmp, tmp->value);
99 update_object (tmp, UP_OBJ_FACE); 93 update_object (tmp, UP_OBJ_FACE);
100 break; 94 break;
101 95
102 case BUTTON: 96 case BUTTON:
103 case PEDESTAL: 97 case PEDESTAL:
104 tmp->value = state; 98 tmp->value = state;
105 SET_ANIMATION (tmp, tmp->value); 99 SET_ANIMATION (tmp, tmp->value);
106 update_object (tmp, UP_OBJ_FACE); 100 update_object (tmp, UP_OBJ_FACE);
107 break; 101 break;
108 102
109 case MOOD_FLOOR: 103 case MOOD_FLOOR:
110 do_mood_floor (tmp, source); 104 do_mood_floor (tmp, source);
111 break; 105 break;
112 106
113 case TIMED_GATE: 107 case TIMED_GATE:
114 tmp->speed = tmp->arch->clone.speed; 108 tmp->speed = tmp->arch->clone.speed;
115 update_ob_speed (tmp); /* original values */ 109 update_ob_speed (tmp); /* original values */
116 tmp->value = tmp->arch->clone.value; 110 tmp->value = tmp->arch->clone.value;
117 tmp->stats.sp = 1; 111 tmp->stats.sp = 1;
118 tmp->stats.hp = tmp->stats.maxhp; 112 tmp->stats.hp = tmp->stats.maxhp;
119 /* Handle multipart gates. We copy the value for the other parts 113 /* Handle multipart gates. We copy the value for the other parts
120 * from the head - this ensures that the data will consistent 114 * from the head - this ensures that the data will consistent
121 */ 115 */
122 for (tmp = tmp->more; tmp != NULL; tmp = tmp->more) 116 for (tmp = tmp->more; tmp != NULL; tmp = tmp->more)
123 { 117 {
124 tmp->speed = tmp->head->speed; 118 tmp->speed = tmp->head->speed;
125 tmp->value = tmp->head->value; 119 tmp->value = tmp->head->value;
126 tmp->stats.sp = tmp->head->stats.sp; 120 tmp->stats.sp = tmp->head->stats.sp;
127 tmp->stats.hp = tmp->head->stats.hp; 121 tmp->stats.hp = tmp->head->stats.hp;
128 update_ob_speed (tmp); 122 update_ob_speed (tmp);
129 } 123 }
130 break; 124 break;
131 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/*
193 * 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
194 * who have FLAG_ACTIVATE_ON_PUSH/RELEASE set properly. 188 * who have FLAG_ACTIVATE_ON_PUSH/RELEASE set properly.
195 * 189 *
196 */ 190 */
197void 191void
198activate_connection (mapstruct *map, long connection, bool state) 192activate_connection (maptile *map, long connection, bool state)
199{ 193{
200 if (INVOKE_MAP (TRIGGER, map, ARG_INT64 (connection), ARG_INT (state))) 194 if (INVOKE_MAP (TRIGGER, map, ARG_INT64 (connection), ARG_INT (state)))
201 return; 195 return;
202 196
203 oblinkpt *obp = get_connection_links (map, connection); 197 oblinkpt *obp = get_connection_links (map, connection);
210 * Updates everything connected with the button op. 204 * Updates everything connected with the button op.
211 * 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
212 * 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
213 * button reacts to the (eventual) change of state. 207 * button reacts to the (eventual) change of state.
214 */ 208 */
215
216void 209void
217update_button (object *op) 210update_button (object *op)
218{ 211{
219 object *ab, *tmp, *head; 212 object *ab, *tmp, *head;
220 int tot, any_down = 0, old_value = op->value; 213 int tot, any_down = 0, old_value = op->value;
224 obp = get_button_links (op); 217 obp = get_button_links (op);
225 /* LOG(llevDebug, "update_button: %s (%d)\n", op->name, op->count); */ 218 /* LOG(llevDebug, "update_button: %s (%d)\n", op->name, op->count); */
226 if (obp) 219 if (obp)
227 for (ol = obp->link; ol; ol = ol->next) 220 for (ol = obp->link; ol; ol = ol->next)
228 { 221 {
229 if (!ol->ob || ol->ob->count != ol->id) 222 if (!ol->ob)
230 { 223 {
231 LOG (llevDebug, "Internal error in update_button (%s).\n", &op->name); 224 LOG (llevDebug, "Internal error in update_button (%s).\n", &op->name);
232 continue; 225 continue;
233 } 226 }
227
234 tmp = ol->ob; 228 tmp = ol->ob;
235 if (tmp->type == BUTTON) 229 if (tmp->type == BUTTON)
236 { 230 {
237 for (ab = tmp->above, tot = 0; ab != NULL; ab = ab->above) 231 for (ab = tmp->above, tot = 0; ab != NULL; ab = ab->above)
238 /* Bug? The pedestal code below looks for the head of 232 /* Bug? The pedestal code below looks for the head of
287/* 281/*
288 * 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).
289 */ 283 */
290 284
291void 285void
292update_buttons (mapstruct *m) 286update_buttons (maptile *m)
293{ 287{
294 objectlink *ol; 288 objectlink *ol;
295 oblinkpt *obp; 289 oblinkpt *obp;
296 290
297 for (obp = m->buttons; obp; obp = obp->next) 291 for (obp = m->buttons; obp; obp = obp->next)
298 for (ol = obp->link; ol; ol = ol->next) 292 for (ol = obp->link; ol; ol = ol->next)
299 { 293 {
300 if (!ol->ob || ol->ob->count != ol->id) 294 if (!ol->ob)
301 { 295 {
302 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), 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); 297 ol->ob ? (const char *) ol->ob->name : "null", ol->ob ? ol->ob->x : -1, ol->ob ? ol->ob->y : -1, obp->value);
304 continue; 298 continue;
305 } 299 }
300
306 if (ol->ob->type == BUTTON || ol->ob->type == PEDESTAL) 301 if (ol->ob->type == BUTTON || ol->ob->type == PEDESTAL)
307 { 302 {
308 update_button (ol->ob); 303 update_button (ol->ob);
309 break; 304 break;
310 } 305 }
357 ARCH_SACRIFICE (altar) == sacrifice->name || 352 ARCH_SACRIFICE (altar) == sacrifice->name ||
358 ARCH_SACRIFICE (altar) == sacrifice->slaying || 353 ARCH_SACRIFICE (altar) == sacrifice->slaying ||
359 (!strcmp (ARCH_SACRIFICE (altar), query_base_name (sacrifice, 0)))) 354 (!strcmp (ARCH_SACRIFICE (altar), query_base_name (sacrifice, 0))))
360 && NROF_SACRIFICE (altar) <= (sacrifice->nrof ? sacrifice->nrof : 1)) 355 && NROF_SACRIFICE (altar) <= (sacrifice->nrof ? sacrifice->nrof : 1))
361 return 1; 356 return 1;
357
362 if (strcmp (ARCH_SACRIFICE (altar), "money") == 0 358 if (strcmp (ARCH_SACRIFICE (altar), "money") == 0
363 && sacrifice->type == MONEY && sacrifice->nrof * sacrifice->value >= NROF_SACRIFICE (altar)) 359 && sacrifice->type == MONEY && sacrifice->nrof * sacrifice->value >= NROF_SACRIFICE (altar))
364 return 1; 360 return 1;
365 } 361 }
362
366 return 0; 363 return 0;
367} 364}
368 365
369/* 366/*
370 * operate_altar checks if sacrifice was accepted and removes sacrificed 367 * operate_altar checks if sacrifice was accepted and removes sacrificed
601 return 0; 598 return 0;
602 } 599 }
603} 600}
604 601
605void 602void
606add_button_link (object *button, mapstruct *map, int connected) 603add_button_link (object *button, maptile *map, int connected)
607{ 604{
608 oblinkpt *obp; 605 oblinkpt *obp;
609 objectlink *ol = get_objectlink (); 606 objectlink *ol = get_objectlink ();
610 607
611 if (!map) 608 if (!map)
612 { 609 {
613 LOG (llevError, "Tried to add button-link without map.\n"); 610 LOG (llevError, "Tried to add button-link without map.\n");
614 return; 611 return;
615 } 612 }
616 if (!editor) 613
617 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
618 a connected map from a template map. */ 615 a connected map from a template map. */
619
620/* LOG(llevDebug,"adding button %s (%d)\n", button->name, connected);*/
621 616
622 SET_FLAG (button, FLAG_IS_LINKED); 617 SET_FLAG (button, FLAG_IS_LINKED);
623 618
624 ol->ob = button; 619 ol->ob = button;
625 ol->id = button->count;
626 620
627 for (obp = map->buttons; obp && obp->value != connected; obp = obp->next); 621 for (obp = map->buttons; obp && obp->value != connected; obp = obp->next)
622 ;
628 623
629 if (obp) 624 if (obp)
630 { 625 {
631 ol->next = obp->link; 626 ol->next = obp->link;
632 obp->link = ol; 627 obp->link = ol;
656 if (op->map == NULL) 651 if (op->map == NULL)
657 { 652 {
658 LOG (llevError, "remove_button_link() in object without map.\n"); 653 LOG (llevError, "remove_button_link() in object without map.\n");
659 return; 654 return;
660 } 655 }
656
661 if (!QUERY_FLAG (op, FLAG_IS_LINKED)) 657 if (!QUERY_FLAG (op, FLAG_IS_LINKED))
662 { 658 {
663 LOG (llevError, "remove_button_linked() in unlinked object.\n"); 659 LOG (llevError, "remove_button_linked() in unlinked object.\n");
664 return; 660 return;
665 } 661 }
662
666 for (obp = op->map->buttons; obp; obp = obp->next) 663 for (obp = op->map->buttons; obp; obp = obp->next)
667 for (olp = &obp->link; (ol = *olp); olp = &ol->next) 664 for (olp = &obp->link; (ol = *olp); olp = &ol->next)
668 if (ol->ob == op) 665 if (ol->ob == op)
669 { 666 {
670 667
671/* LOG(llevDebug, "Removed link %d in button %s and map %s.\n", 668/* LOG(llevDebug, "Removed link %d in button %s and map %s.\n",
672 obp->value, op->name, op->map->path); 669 obp->value, op->name, op->map->path);
673*/ 670*/
674 *olp = ol->next; 671 *olp = ol->next;
675 free (ol); 672 delete ol;
676 return; 673 return;
677 } 674 }
675
678 LOG (llevError, "remove_button_linked(): couldn't find object.\n"); 676 LOG (llevError, "remove_button_linked(): couldn't find object.\n");
679 CLEAR_FLAG (op, FLAG_IS_LINKED); 677 CLEAR_FLAG (op, FLAG_IS_LINKED);
680} 678}
681 679
682/* 680/*
683 * Gets the objectlink for this connection from the map. 681 * Gets the objectlink for this connection from the map.
684 */ 682 */
685oblinkpt * 683oblinkpt *
686get_connection_links (mapstruct *map, long connection) 684get_connection_links (maptile *map, long connection)
687{ 685{
688 for (oblinkpt * obp = map->buttons; obp; obp = obp->next) 686 for (oblinkpt * obp = map->buttons; obp; obp = obp->next)
689 if (obp->value == connection) 687 if (obp->value == connection)
690 return obp; 688 return obp;
689
691 return 0; 690 return 0;
692} 691}
693 692
694/* 693/*
695 * Return the first objectlink in the objects linked to this one 694 * Return the first objectlink in the objects linked to this one
701 oblinkpt *obp; 700 oblinkpt *obp;
702 objectlink *ol; 701 objectlink *ol;
703 702
704 if (!button->map) 703 if (!button->map)
705 return NULL; 704 return NULL;
705
706 for (obp = button->map->buttons; obp; obp = obp->next) 706 for (obp = button->map->buttons; obp; obp = obp->next)
707 for (ol = obp->link; ol; ol = ol->next) 707 for (ol = obp->link; ol; ol = ol->next)
708 if (ol->ob == button && ol->id == button->count) 708 if (ol->ob == button)
709 return obp; 709 return obp;
710
710 return NULL; 711 return NULL;
711} 712}
712 713
713/* 714/*
714 * Made as a separate function to increase efficiency 715 * Made as a separate function to increase efficiency
722 723
723 if (!button->map) 724 if (!button->map)
724 return 0; 725 return 0;
725 for (obp = button->map->buttons; obp; obp = obp->next) 726 for (obp = button->map->buttons; obp; obp = obp->next)
726 for (ol = obp->link; ol; ol = ol->next) 727 for (ol = obp->link; ol; ol = ol->next)
727 if (ol->ob == button && ol->id == button->count) 728 if (ol->ob == button)
728 return obp->value; 729 return obp->value;
729 return 0; 730 return 0;
730} 731}
731 732
732/* This routine makes monsters who are 733/* This routine makes monsters who are
769 tmp->attack_movement = 0; 770 tmp->attack_movement = 0;
770 /* lots of checks here, but want to make sure we don't 771 /* lots of checks here, but want to make sure we don't
771 * dereference a null value 772 * dereference a null value
772 */ 773 */
773 if (tmp->type == GOLEM && tmp->owner && tmp->owner->type == PLAYER && tmp->owner->contr->ranges[range_golem] == tmp) 774 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; 775 tmp->owner->contr->ranges[range_golem] = 0;
776 tmp->owner->contr->golem_count = 0; 776
777 }
778 tmp->owner = 0; 777 tmp->owner = 0;
779 } 778 }
780 break; 779 break;
781 case 1: /* angry -- get neutral monsters mad */ 780 case 1: /* angry -- get neutral monsters mad */
782 if (QUERY_FLAG (tmp, FLAG_UNAGGRESSIVE) && !QUERY_FLAG (tmp, FLAG_FRIENDLY)) 781 if (QUERY_FLAG (tmp, FLAG_UNAGGRESSIVE) && !QUERY_FLAG (tmp, FLAG_FRIENDLY))
792 break; 791 break;
793 case 4: /* charm all monsters */ 792 case 4: /* charm all monsters */
794 if (op == source) 793 if (op == source)
795 break; /* only if 'connected' */ 794 break; /* only if 'connected' */
796 795
797 for (tmp2 = get_map_ob (source->map, source->x, source->y); /* finding an owner */ 796 for (tmp2 = GET_MAP_OB (source->map, source->x, source->y); /* finding an owner */
798 tmp2->type != PLAYER; tmp2 = tmp2->above) 797 tmp2->type != PLAYER; tmp2 = tmp2->above)
799 if (tmp2->above == NULL) 798 if (tmp2->above == NULL)
800 break; 799 break;
801 800
802 if (tmp2->type != PLAYER) 801 if (tmp2->type != PLAYER)
803 break; 802 break;
803
804 set_owner (tmp, tmp2); 804 tmp->set_owner (tmp2);
805 SET_FLAG (tmp, FLAG_MONSTER); 805 SET_FLAG (tmp, FLAG_MONSTER);
806
806 tmp->stats.exp = 0; 807 tmp->stats.exp = 0;
807 SET_FLAG (tmp, FLAG_FRIENDLY); 808 SET_FLAG (tmp, FLAG_FRIENDLY);
809
808 add_friendly_object (tmp); 810 add_friendly_object (tmp);
809 tmp->attack_movement = PETMOVE; 811 tmp->attack_movement = PETMOVE;
810 break; 812 break;
811 813
812 default: 814 default:
818 * It will descend through containers to find the object. 820 * It will descend through containers to find the object.
819 * slaying = match object slaying flag 821 * slaying = match object slaying flag
820 * race = match object archetype name flag 822 * race = match object archetype name flag
821 * hp = match object type (excpt type '0'== PLAYER) 823 * hp = match object type (excpt type '0'== PLAYER)
822 */ 824 */
823
824object * 825object *
825check_inv_recursive (object *op, const object *trig) 826check_inv_recursive (object *op, const object *trig)
826{ 827{
827 object *tmp, *ret = NULL; 828 object *tmp, *ret = NULL;
828 829
829 /* First check the object itself. */ 830 /* First check the object itself. */
830 if ((trig->stats.hp && (op->type == trig->stats.hp)) 831 if ((trig->stats.hp && (op->type == trig->stats.hp))
831 || (trig->slaying && (op->slaying == trig->slaying)) || (trig->race && (op->arch->name == trig->race))) 832 || (trig->slaying && (op->slaying == trig->slaying))
833 || (trig->race && (op->arch->name == trig->race)))
832 return op; 834 return op;
833 835
834 for (tmp = op->inv; tmp; tmp = tmp->below) 836 for (tmp = op->inv; tmp; tmp = tmp->below)
835 { 837 {
836 if (tmp->inv) 838 if (tmp->inv)
838 ret = check_inv_recursive (tmp, trig); 840 ret = check_inv_recursive (tmp, trig);
839 if (ret) 841 if (ret)
840 return ret; 842 return ret;
841 } 843 }
842 else if ((trig->stats.hp && (tmp->type == trig->stats.hp)) 844 else if ((trig->stats.hp && (tmp->type == trig->stats.hp))
843 || (trig->slaying && (tmp->slaying == trig->slaying)) || (trig->race && (tmp->arch->name == trig->race))) 845 || (trig->slaying && (tmp->slaying == trig->slaying))
846 || (trig->race && (tmp->arch->name == trig->race)))
844 return tmp; 847 return tmp;
845 } 848 }
846 return NULL; 849 return NULL;
847} 850}
848 851
851 * the square will activate connected items. 854 * the square will activate connected items.
852 * Monsters can't trigger this square (for now) 855 * Monsters can't trigger this square (for now)
853 * Values are: last_sp = 1/0 obj/no obj triggers 856 * Values are: last_sp = 1/0 obj/no obj triggers
854 * last_heal = 1/0 remove/dont remove obj if triggered 857 * last_heal = 1/0 remove/dont remove obj if triggered
855 * -b.t. (thomas@nomad.astro.psu.edu 858 * -b.t. (thomas@nomad.astro.psu.edu
856 */ 859 *
857 860 * Tue Dec 19 15:34:00 CET 2006 elmex: changed the function to ignore op
861 * because the check-inventory semantic essentially only applies when
862 * something is above the inventory checker.
863 * The semantic prior this change was: trigger if something has moved on or off
864 * and has a matching item. Imagine what happens if someone steps on the inventory
865 * checker with a matching item, has it, activates the connection, throws the item
866 * away, and then leaves the inventory checker. That would've caused an always-enabled
867 * state in the inventory checker. This won't happen anymore now.
868 *
869 */
858void 870void
859check_inv (object *op, object *trig) 871check_inv (object *op, object *trig)
860{ 872{
861 object *match; 873 trig->value = 0; // deactivate if none of the following conditions apply
862 874
863 if (op->type != PLAYER) 875 if (object *pl = trig->ms ().player ())
864 return; 876 {
865 match = check_inv_recursive (op, trig); 877 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 878
876 879 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 { 880 {
894 if (ol->id != ol->ob->count) 881 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); 882 decrease_ob (match);
883
884 trig->value = 1;
896 } 885 }
886 else if (!match && !trig->last_sp) // match == not having
887 trig->value = 1;
897 } 888 }
889
890 push_button (trig);
898} 891}
892

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines