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.7 by root, Sun Sep 10 16:00:23 2006 UTC vs.
Revision 1.18 by root, Thu Dec 21 01:33:49 2006 UTC

1
2/*
3 * static char *rcsid_button_c =
4 * "$Id: button.C,v 1.7 2006/09/10 16:00: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
45{ 39{
46 object *tmp = 0; 40 object *tmp = 0;
47 41
48 for (; ol; ol = ol->next) 42 for (; ol; ol = ol->next)
49 { 43 {
50 if (!ol->ob || ol->ob->count != ol->id) 44 if (!ol->ob)
51 { 45 {
52 LOG (llevError, "Internal error in activate_connection_link (%ld).\n", ol->id); 46 LOG (llevError, "Internal error in activate_connection_link.\n");
53 continue; 47 continue;
54 } 48 }
49
55 /* 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
56 * 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
57 * 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
58 * 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
59 * 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
193 * 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
194 * who have FLAG_ACTIVATE_ON_PUSH/RELEASE set properly. 189 * who have FLAG_ACTIVATE_ON_PUSH/RELEASE set properly.
195 * 190 *
196 */ 191 */
197void 192void
198activate_connection (mapstruct *map, long connection, bool state) 193activate_connection (maptile *map, long connection, bool state)
199{ 194{
200 if (INVOKE_MAP (TRIGGER, map, ARG_INT64 (connection), ARG_INT (state))) 195 if (INVOKE_MAP (TRIGGER, map, ARG_INT64 (connection), ARG_INT (state)))
201 return; 196 return;
202 197
203 oblinkpt *obp = get_connection_links (map, connection); 198 oblinkpt *obp = get_connection_links (map, connection);
210 * Updates everything connected with the button op. 205 * Updates everything connected with the button op.
211 * 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
212 * 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
213 * button reacts to the (eventual) change of state. 208 * button reacts to the (eventual) change of state.
214 */ 209 */
215
216void 210void
217update_button (object *op) 211update_button (object *op)
218{ 212{
219 object *ab, *tmp, *head; 213 object *ab, *tmp, *head;
220 int tot, any_down = 0, old_value = op->value; 214 int tot, any_down = 0, old_value = op->value;
224 obp = get_button_links (op); 218 obp = get_button_links (op);
225 /* LOG(llevDebug, "update_button: %s (%d)\n", op->name, op->count); */ 219 /* LOG(llevDebug, "update_button: %s (%d)\n", op->name, op->count); */
226 if (obp) 220 if (obp)
227 for (ol = obp->link; ol; ol = ol->next) 221 for (ol = obp->link; ol; ol = ol->next)
228 { 222 {
229 if (!ol->ob || ol->ob->count != ol->id) 223 if (!ol->ob)
230 { 224 {
231 LOG (llevDebug, "Internal error in update_button (%s).\n", &op->name); 225 LOG (llevDebug, "Internal error in update_button (%s).\n", &op->name);
232 continue; 226 continue;
233 } 227 }
228
234 tmp = ol->ob; 229 tmp = ol->ob;
235 if (tmp->type == BUTTON) 230 if (tmp->type == BUTTON)
236 { 231 {
237 for (ab = tmp->above, tot = 0; ab != NULL; ab = ab->above) 232 for (ab = tmp->above, tot = 0; ab != NULL; ab = ab->above)
238 /* Bug? The pedestal code below looks for the head of 233 /* Bug? The pedestal code below looks for the head of
287/* 282/*
288 * Updates every button on the map (by calling update_button() for them). 283 * Updates every button on the map (by calling update_button() for them).
289 */ 284 */
290 285
291void 286void
292update_buttons (mapstruct *m) 287update_buttons (maptile *m)
293{ 288{
294 objectlink *ol; 289 objectlink *ol;
295 oblinkpt *obp; 290 oblinkpt *obp;
296 291
297 for (obp = m->buttons; obp; obp = obp->next) 292 for (obp = m->buttons; obp; obp = obp->next)
298 for (ol = obp->link; ol; ol = ol->next) 293 for (ol = obp->link; ol; ol = ol->next)
299 { 294 {
300 if (!ol->ob || ol->ob->count != ol->id) 295 if (!ol->ob)
301 { 296 {
302 LOG (llevError, "Internal error in update_button (%s (%dx%d):%d, connected %ld).\n", 297 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); 298 ol->ob ? (const char *) ol->ob->name : "null", ol->ob ? ol->ob->x : -1, ol->ob ? ol->ob->y : -1, obp->value);
304 continue; 299 continue;
305 } 300 }
301
306 if (ol->ob->type == BUTTON || ol->ob->type == PEDESTAL) 302 if (ol->ob->type == BUTTON || ol->ob->type == PEDESTAL)
307 { 303 {
308 update_button (ol->ob); 304 update_button (ol->ob);
309 break; 305 break;
310 } 306 }
357 ARCH_SACRIFICE (altar) == sacrifice->name || 353 ARCH_SACRIFICE (altar) == sacrifice->name ||
358 ARCH_SACRIFICE (altar) == sacrifice->slaying || 354 ARCH_SACRIFICE (altar) == sacrifice->slaying ||
359 (!strcmp (ARCH_SACRIFICE (altar), query_base_name (sacrifice, 0)))) 355 (!strcmp (ARCH_SACRIFICE (altar), query_base_name (sacrifice, 0))))
360 && NROF_SACRIFICE (altar) <= (sacrifice->nrof ? sacrifice->nrof : 1)) 356 && NROF_SACRIFICE (altar) <= (sacrifice->nrof ? sacrifice->nrof : 1))
361 return 1; 357 return 1;
358
362 if (strcmp (ARCH_SACRIFICE (altar), "money") == 0 359 if (strcmp (ARCH_SACRIFICE (altar), "money") == 0
363 && sacrifice->type == MONEY && sacrifice->nrof * sacrifice->value >= NROF_SACRIFICE (altar)) 360 && sacrifice->type == MONEY && sacrifice->nrof * sacrifice->value >= NROF_SACRIFICE (altar))
364 return 1; 361 return 1;
365 } 362 }
363
366 return 0; 364 return 0;
367} 365}
368
369 366
370/* 367/*
371 * operate_altar checks if sacrifice was accepted and removes sacrificed 368 * operate_altar checks if sacrifice was accepted and removes sacrificed
372 * objects. If sacrifice was succeed return 1 else 0. Might be better to 369 * objects. If sacrifice was succeed return 1 else 0. Might be better to
373 * call check_altar_sacrifice (above) than depend on the return value, 370 * call check_altar_sacrifice (above) than depend on the return value,
374 * since operate_altar will remove the sacrifice also. 371 * since operate_altar will remove the sacrifice also.
375 * 372 *
376 * If this function returns 1, '*sacrifice' is modified to point to the 373 * If this function returns 1, '*sacrifice' is modified to point to the
377 * remaining sacrifice, or is set to NULL if the sacrifice was used up. 374 * remaining sacrifice, or is set to NULL if the sacrifice was used up.
378 */ 375 */
379
380int 376int
381operate_altar (object *altar, object **sacrifice) 377operate_altar (object *altar, object **sacrifice)
382{ 378{
383
384 if (!altar->map) 379 if (!altar->map)
385 { 380 {
386 LOG (llevError, "BUG: operate_altar(): altar has no map\n"); 381 LOG (llevError, "BUG: operate_altar(): altar has no map\n");
387 return 0; 382 return 0;
388 } 383 }
401 int number = NROF_SACRIFICE (altar) / (*sacrifice)->value; 396 int number = NROF_SACRIFICE (altar) / (*sacrifice)->value;
402 397
403 /* Round up any sacrifices. Altars don't make change either */ 398 /* Round up any sacrifices. Altars don't make change either */
404 if (NROF_SACRIFICE (altar) % (*sacrifice)->value) 399 if (NROF_SACRIFICE (altar) % (*sacrifice)->value)
405 number++; 400 number++;
401
406 *sacrifice = decrease_ob_nr (*sacrifice, number); 402 *sacrifice = decrease_ob_nr (*sacrifice, number);
407 } 403 }
408 else 404 else
409 *sacrifice = decrease_ob_nr (*sacrifice, NROF_SACRIFICE (altar)); 405 *sacrifice = decrease_ob_nr (*sacrifice, NROF_SACRIFICE (altar));
410 406
411 if (altar->msg) 407 if (altar->msg)
412 new_info_map (NDI_BLACK, altar->map, altar->msg); 408 new_info_map (NDI_BLACK, altar->map, altar->msg);
409
413 return 1; 410 return 1;
414} 411}
415 412
416void 413void
417trigger_move (object *op, int state) /* 1 down and 0 up */ 414trigger_move (object *op, int state) /* 1 down and 0 up */
602 return 0; 599 return 0;
603 } 600 }
604} 601}
605 602
606void 603void
607add_button_link (object *button, mapstruct *map, int connected) 604add_button_link (object *button, maptile *map, int connected)
608{ 605{
609 oblinkpt *obp; 606 oblinkpt *obp;
610 objectlink *ol = get_objectlink (); 607 objectlink *ol = get_objectlink ();
611 608
612 if (!map) 609 if (!map)
621/* LOG(llevDebug,"adding button %s (%d)\n", button->name, connected);*/ 618/* LOG(llevDebug,"adding button %s (%d)\n", button->name, connected);*/
622 619
623 SET_FLAG (button, FLAG_IS_LINKED); 620 SET_FLAG (button, FLAG_IS_LINKED);
624 621
625 ol->ob = button; 622 ol->ob = button;
626 ol->id = button->count;
627 623
628 for (obp = map->buttons; obp && obp->value != connected; obp = obp->next); 624 for (obp = map->buttons; obp && obp->value != connected; obp = obp->next);
629 625
630 if (obp) 626 if (obp)
631 { 627 {
657 if (op->map == NULL) 653 if (op->map == NULL)
658 { 654 {
659 LOG (llevError, "remove_button_link() in object without map.\n"); 655 LOG (llevError, "remove_button_link() in object without map.\n");
660 return; 656 return;
661 } 657 }
658
662 if (!QUERY_FLAG (op, FLAG_IS_LINKED)) 659 if (!QUERY_FLAG (op, FLAG_IS_LINKED))
663 { 660 {
664 LOG (llevError, "remove_button_linked() in unlinked object.\n"); 661 LOG (llevError, "remove_button_linked() in unlinked object.\n");
665 return; 662 return;
666 } 663 }
664
667 for (obp = op->map->buttons; obp; obp = obp->next) 665 for (obp = op->map->buttons; obp; obp = obp->next)
668 for (olp = &obp->link; (ol = *olp); olp = &ol->next) 666 for (olp = &obp->link; (ol = *olp); olp = &ol->next)
669 if (ol->ob == op) 667 if (ol->ob == op)
670 { 668 {
671 669
672/* LOG(llevDebug, "Removed link %d in button %s and map %s.\n", 670/* LOG(llevDebug, "Removed link %d in button %s and map %s.\n",
673 obp->value, op->name, op->map->path); 671 obp->value, op->name, op->map->path);
674*/ 672*/
675 *olp = ol->next; 673 *olp = ol->next;
676 free (ol); 674 delete ol;
677 return; 675 return;
678 } 676 }
677
679 LOG (llevError, "remove_button_linked(): couldn't find object.\n"); 678 LOG (llevError, "remove_button_linked(): couldn't find object.\n");
680 CLEAR_FLAG (op, FLAG_IS_LINKED); 679 CLEAR_FLAG (op, FLAG_IS_LINKED);
681} 680}
682 681
683/* 682/*
684 * Gets the objectlink for this connection from the map. 683 * Gets the objectlink for this connection from the map.
685 */ 684 */
686oblinkpt * 685oblinkpt *
687get_connection_links (mapstruct *map, long connection) 686get_connection_links (maptile *map, long connection)
688{ 687{
689 for (oblinkpt * obp = map->buttons; obp; obp = obp->next) 688 for (oblinkpt * obp = map->buttons; obp; obp = obp->next)
690 if (obp->value == connection) 689 if (obp->value == connection)
691 return obp; 690 return obp;
691
692 return 0; 692 return 0;
693} 693}
694 694
695/* 695/*
696 * Return the first objectlink in the objects linked to this one 696 * Return the first objectlink in the objects linked to this one
702 oblinkpt *obp; 702 oblinkpt *obp;
703 objectlink *ol; 703 objectlink *ol;
704 704
705 if (!button->map) 705 if (!button->map)
706 return NULL; 706 return NULL;
707
707 for (obp = button->map->buttons; obp; obp = obp->next) 708 for (obp = button->map->buttons; obp; obp = obp->next)
708 for (ol = obp->link; ol; ol = ol->next) 709 for (ol = obp->link; ol; ol = ol->next)
709 if (ol->ob == button && ol->id == button->count) 710 if (ol->ob == button)
710 return obp; 711 return obp;
712
711 return NULL; 713 return NULL;
712} 714}
713 715
714/* 716/*
715 * Made as a separate function to increase efficiency 717 * Made as a separate function to increase efficiency
723 725
724 if (!button->map) 726 if (!button->map)
725 return 0; 727 return 0;
726 for (obp = button->map->buttons; obp; obp = obp->next) 728 for (obp = button->map->buttons; obp; obp = obp->next)
727 for (ol = obp->link; ol; ol = ol->next) 729 for (ol = obp->link; ol; ol = ol->next)
728 if (ol->ob == button && ol->id == button->count) 730 if (ol->ob == button)
729 return obp->value; 731 return obp->value;
730 return 0; 732 return 0;
731} 733}
732 734
733/* This routine makes monsters who are 735/* This routine makes monsters who are
758 if (!tmp || tmp->type == PLAYER) 760 if (!tmp || tmp->type == PLAYER)
759 return; 761 return;
760 762
761 switch (op->last_sp) 763 switch (op->last_sp)
762 { 764 {
763 case 0: /* furious--make all monsters mad */ 765 case 0: /* furious--make all monsters mad */
764 if (QUERY_FLAG (tmp, FLAG_UNAGGRESSIVE)) 766 if (QUERY_FLAG (tmp, FLAG_UNAGGRESSIVE))
765 CLEAR_FLAG (tmp, FLAG_UNAGGRESSIVE); 767 CLEAR_FLAG (tmp, FLAG_UNAGGRESSIVE);
766 if (QUERY_FLAG (tmp, FLAG_FRIENDLY)) 768 if (QUERY_FLAG (tmp, FLAG_FRIENDLY))
767 { 769 {
768 CLEAR_FLAG (tmp, FLAG_FRIENDLY); 770 CLEAR_FLAG (tmp, FLAG_FRIENDLY);
769 remove_friendly_object (tmp); 771 remove_friendly_object (tmp);
770 tmp->attack_movement = 0; 772 tmp->attack_movement = 0;
771 /* lots of checks here, but want to make sure we don't 773 /* lots of checks here, but want to make sure we don't
772 * dereference a null value 774 * dereference a null value
773 */ 775 */
774 if (tmp->type == GOLEM && tmp->owner && tmp->owner->type == PLAYER && tmp->owner->contr->ranges[range_golem] == tmp) 776 if (tmp->type == GOLEM && tmp->owner && tmp->owner->type == PLAYER && tmp->owner->contr->ranges[range_golem] == tmp)
775 {
776 tmp->owner->contr->ranges[range_golem] = NULL; 777 tmp->owner->contr->ranges[range_golem] = 0;
777 tmp->owner->contr->golem_count = 0; 778
778 }
779 tmp->owner = 0; 779 tmp->owner = 0;
780 } 780 }
781 break;
782 case 1: /* angry -- get neutral monsters mad */
783 if (QUERY_FLAG (tmp, FLAG_UNAGGRESSIVE) && !QUERY_FLAG (tmp, FLAG_FRIENDLY))
784 CLEAR_FLAG (tmp, FLAG_UNAGGRESSIVE);
785 break;
786 case 2: /* calm -- pacify unfriendly monsters */
787 if (!QUERY_FLAG (tmp, FLAG_UNAGGRESSIVE))
788 SET_FLAG (tmp, FLAG_UNAGGRESSIVE);
789 break;
790 case 3: /* make all monsters fall asleep */
791 if (!QUERY_FLAG (tmp, FLAG_SLEEP))
792 SET_FLAG (tmp, FLAG_SLEEP);
793 break;
794 case 4: /* charm all monsters */
795 if (op == source)
796 break; /* only if 'connected' */
797
798 for (tmp2 = GET_MAP_OB (source->map, source->x, source->y); /* finding an owner */
799 tmp2->type != PLAYER; tmp2 = tmp2->above)
800 if (tmp2->above == NULL)
801 break;
802
803 if (tmp2->type != PLAYER)
781 break; 804 break;
782 case 1: /* angry -- get neutral monsters mad */
783 if (QUERY_FLAG (tmp, FLAG_UNAGGRESSIVE) && !QUERY_FLAG (tmp, FLAG_FRIENDLY))
784 CLEAR_FLAG (tmp, FLAG_UNAGGRESSIVE);
785 break;
786 case 2: /* calm -- pacify unfriendly monsters */
787 if (!QUERY_FLAG (tmp, FLAG_UNAGGRESSIVE))
788 SET_FLAG (tmp, FLAG_UNAGGRESSIVE);
789 break;
790 case 3: /* make all monsters fall asleep */
791 if (!QUERY_FLAG (tmp, FLAG_SLEEP))
792 SET_FLAG (tmp, FLAG_SLEEP);
793 break;
794 case 4: /* charm all monsters */
795 if (op == source)
796 break; /* only if 'connected' */
797 805
798 for (tmp2 = get_map_ob (source->map, source->x, source->y); /* finding an owner */
799 tmp2->type != PLAYER; tmp2 = tmp2->above)
800 if (tmp2->above == NULL)
801 break;
802
803 if (tmp2->type != PLAYER)
804 break;
805 set_owner (tmp, tmp2); 806 tmp->set_owner (tmp2);
806 SET_FLAG (tmp, FLAG_MONSTER); 807 SET_FLAG (tmp, FLAG_MONSTER);
808
807 tmp->stats.exp = 0; 809 tmp->stats.exp = 0;
808 SET_FLAG (tmp, FLAG_FRIENDLY); 810 SET_FLAG (tmp, FLAG_FRIENDLY);
811
809 add_friendly_object (tmp); 812 add_friendly_object (tmp);
810 tmp->attack_movement = PETMOVE; 813 tmp->attack_movement = PETMOVE;
811 break; 814 break;
812 815
813 default: 816 default:
814 break; 817 break;
815
816 } 818 }
817} 819}
818 820
819/* this function returns the object it matches, or NULL if non. 821/* this function returns the object it matches, or NULL if non.
820 * It will descend through containers to find the object. 822 * It will descend through containers to find the object.
821 * slaying = match object slaying flag 823 * slaying = match object slaying flag
822 * race = match object archetype name flag 824 * race = match object archetype name flag
823 * hp = match object type (excpt type '0'== PLAYER) 825 * hp = match object type (excpt type '0'== PLAYER)
824 */ 826 */
825
826object * 827object *
827check_inv_recursive (object *op, const object *trig) 828check_inv_recursive (object *op, const object *trig)
828{ 829{
829 object *tmp, *ret = NULL; 830 object *tmp, *ret = NULL;
830 831
831 /* First check the object itself. */ 832 /* First check the object itself. */
832 if ((trig->stats.hp && (op->type == trig->stats.hp)) 833 if ((trig->stats.hp && (op->type == trig->stats.hp))
833 || (trig->slaying && (op->slaying == trig->slaying)) || (trig->race && (op->arch->name == trig->race))) 834 || (trig->slaying && (op->slaying == trig->slaying))
835 || (trig->race && (op->arch->name == trig->race)))
834 return op; 836 return op;
835 837
836 for (tmp = op->inv; tmp; tmp = tmp->below) 838 for (tmp = op->inv; tmp; tmp = tmp->below)
837 { 839 {
838 if (tmp->inv) 840 if (tmp->inv)
840 ret = check_inv_recursive (tmp, trig); 842 ret = check_inv_recursive (tmp, trig);
841 if (ret) 843 if (ret)
842 return ret; 844 return ret;
843 } 845 }
844 else if ((trig->stats.hp && (tmp->type == trig->stats.hp)) 846 else if ((trig->stats.hp && (tmp->type == trig->stats.hp))
845 || (trig->slaying && (tmp->slaying == trig->slaying)) || (trig->race && (tmp->arch->name == trig->race))) 847 || (trig->slaying && (tmp->slaying == trig->slaying))
848 || (trig->race && (tmp->arch->name == trig->race)))
846 return tmp; 849 return tmp;
847 } 850 }
848 return NULL; 851 return NULL;
849} 852}
850 853
853 * the square will activate connected items. 856 * the square will activate connected items.
854 * Monsters can't trigger this square (for now) 857 * Monsters can't trigger this square (for now)
855 * Values are: last_sp = 1/0 obj/no obj triggers 858 * Values are: last_sp = 1/0 obj/no obj triggers
856 * last_heal = 1/0 remove/dont remove obj if triggered 859 * last_heal = 1/0 remove/dont remove obj if triggered
857 * -b.t. (thomas@nomad.astro.psu.edu 860 * -b.t. (thomas@nomad.astro.psu.edu
858 */ 861 *
859 862 * Tue Dec 19 15:34:00 CET 2006 elmex: changed the function to ignore op
863 * because the check-inventory semantic essentially only applies when
864 * something is above the inventory checker.
865 * The semantic prior this change was: trigger if something has moved on or off
866 * and has a matching item. Imagine what happens if someone steps on the inventory
867 * checker with a matching item, has it, activates the connection, throws the item
868 * away, and then leaves the inventory checker. That would've caused an always-enabled
869 * state in the inventory checker. This won't happen anymore now.
870 *
871 */
860void 872void
861check_inv (object *op, object *trig) 873check_inv (object *op, object *trig)
862{ 874{
863 object *match; 875 trig->value = 0; // deactivate if none of the following conditions apply
864 876
865 if (op->type != PLAYER) 877 if (object *pl = trig->ms ().player ())
866 return; 878 {
867 match = check_inv_recursive (op, trig); 879 object *match = check_inv_recursive (pl, trig);
868 if (match && trig->last_sp)
869 {
870 if (trig->last_heal)
871 decrease_ob (match);
872 use_trigger (trig);
873 }
874 else if (!match && !trig->last_sp)
875 use_trigger (trig);
876}
877 880
878 881 if (match && trig->last_sp) // match == having
879/* This does a minimal check of the button link consistency for object
880 * map. All it really does it much sure the object id link that is set
881 * matches what the object has.
882 */
883void
884verify_button_links (const mapstruct *map)
885{
886 oblinkpt *obp;
887 objectlink *ol;
888
889 if (!map)
890 return;
891
892 for (obp = map->buttons; obp; obp = obp->next)
893 {
894 for (ol = obp->link; ol; ol = ol->next)
895 { 882 {
896 if (ol->id != ol->ob->count) 883 if (trig->last_heal)
897 LOG (llevError, "verify_button_links: object %s on list is corrupt (%d!=%d)\n", &ol->ob->name, ol->id, ol->ob->count); 884 decrease_ob (match);
885
886 trig->value = 1;
898 } 887 }
888 else if (!match && !trig->last_sp) // match == not having
889 trig->value = 1;
899 } 890 }
891
892 push_button (trig);
900} 893}
894

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines