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.8 by root, Mon Sep 11 20:28:37 2006 UTC vs.
Revision 1.15 by elmex, Tue Dec 19 13:41:45 2006 UTC

1
2/*
3 * static char *rcsid_button_c =
4 * "$Id: button.C,v 1.8 2006/09/11 20:28:37 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);
224 obp = get_button_links (op); 219 obp = get_button_links (op);
225 /* LOG(llevDebug, "update_button: %s (%d)\n", op->name, op->count); */ 220 /* LOG(llevDebug, "update_button: %s (%d)\n", op->name, op->count); */
226 if (obp) 221 if (obp)
227 for (ol = obp->link; ol; ol = ol->next) 222 for (ol = obp->link; ol; ol = ol->next)
228 { 223 {
229 if (!ol->ob || ol->ob->count != ol->id) 224 if (!ol->ob)
230 { 225 {
231 LOG (llevDebug, "Internal error in update_button (%s).\n", &op->name); 226 LOG (llevDebug, "Internal error in update_button (%s).\n", &op->name);
232 continue; 227 continue;
233 } 228 }
229
234 tmp = ol->ob; 230 tmp = ol->ob;
235 if (tmp->type == BUTTON) 231 if (tmp->type == BUTTON)
236 { 232 {
237 for (ab = tmp->above, tot = 0; ab != NULL; ab = ab->above) 233 for (ab = tmp->above, tot = 0; ab != NULL; ab = ab->above)
238 /* Bug? The pedestal code below looks for the head of 234 /* Bug? The pedestal code below looks for the head of
287/* 283/*
288 * 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).
289 */ 285 */
290 286
291void 287void
292update_buttons (mapstruct *m) 288update_buttons (maptile *m)
293{ 289{
294 objectlink *ol; 290 objectlink *ol;
295 oblinkpt *obp; 291 oblinkpt *obp;
296 292
297 for (obp = m->buttons; obp; obp = obp->next) 293 for (obp = m->buttons; obp; obp = obp->next)
298 for (ol = obp->link; ol; ol = ol->next) 294 for (ol = obp->link; ol; ol = ol->next)
299 { 295 {
300 if (!ol->ob || ol->ob->count != ol->id) 296 if (!ol->ob)
301 { 297 {
302 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",
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); 299 ol->ob ? (const char *) ol->ob->name : "null", ol->ob ? ol->ob->x : -1, ol->ob ? ol->ob->y : -1, obp->value);
304 continue; 300 continue;
305 } 301 }
302
306 if (ol->ob->type == BUTTON || ol->ob->type == PEDESTAL) 303 if (ol->ob->type == BUTTON || ol->ob->type == PEDESTAL)
307 { 304 {
308 update_button (ol->ob); 305 update_button (ol->ob);
309 break; 306 break;
310 } 307 }
364 return 1; 361 return 1;
365 } 362 }
366 return 0; 363 return 0;
367} 364}
368 365
369
370/* 366/*
371 * operate_altar checks if sacrifice was accepted and removes sacrificed 367 * operate_altar checks if sacrifice was accepted and removes sacrificed
372 * 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
373 * call check_altar_sacrifice (above) than depend on the return value, 369 * call check_altar_sacrifice (above) than depend on the return value,
374 * since operate_altar will remove the sacrifice also. 370 * since operate_altar will remove the sacrifice also.
375 * 371 *
376 * 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
377 * 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.
378 */ 374 */
379
380int 375int
381operate_altar (object *altar, object **sacrifice) 376operate_altar (object *altar, object **sacrifice)
382{ 377{
383
384 if (!altar->map) 378 if (!altar->map)
385 { 379 {
386 LOG (llevError, "BUG: operate_altar(): altar has no map\n"); 380 LOG (llevError, "BUG: operate_altar(): altar has no map\n");
387 return 0; 381 return 0;
388 } 382 }
401 int number = NROF_SACRIFICE (altar) / (*sacrifice)->value; 395 int number = NROF_SACRIFICE (altar) / (*sacrifice)->value;
402 396
403 /* Round up any sacrifices. Altars don't make change either */ 397 /* Round up any sacrifices. Altars don't make change either */
404 if (NROF_SACRIFICE (altar) % (*sacrifice)->value) 398 if (NROF_SACRIFICE (altar) % (*sacrifice)->value)
405 number++; 399 number++;
400
406 *sacrifice = decrease_ob_nr (*sacrifice, number); 401 *sacrifice = decrease_ob_nr (*sacrifice, number);
407 } 402 }
408 else 403 else
409 *sacrifice = decrease_ob_nr (*sacrifice, NROF_SACRIFICE (altar)); 404 *sacrifice = decrease_ob_nr (*sacrifice, NROF_SACRIFICE (altar));
410 405
411 if (altar->msg) 406 if (altar->msg)
412 new_info_map (NDI_BLACK, altar->map, altar->msg); 407 new_info_map (NDI_BLACK, altar->map, altar->msg);
408
413 return 1; 409 return 1;
414} 410}
415 411
416void 412void
417trigger_move (object *op, int state) /* 1 down and 0 up */ 413trigger_move (object *op, int state) /* 1 down and 0 up */
602 return 0; 598 return 0;
603 } 599 }
604} 600}
605 601
606void 602void
607add_button_link (object *button, mapstruct *map, int connected) 603add_button_link (object *button, maptile *map, int connected)
608{ 604{
609 oblinkpt *obp; 605 oblinkpt *obp;
610 objectlink *ol = get_objectlink (); 606 objectlink *ol = get_objectlink ();
611 607
612 if (!map) 608 if (!map)
621/* LOG(llevDebug,"adding button %s (%d)\n", button->name, connected);*/ 617/* LOG(llevDebug,"adding button %s (%d)\n", button->name, connected);*/
622 618
623 SET_FLAG (button, FLAG_IS_LINKED); 619 SET_FLAG (button, FLAG_IS_LINKED);
624 620
625 ol->ob = button; 621 ol->ob = button;
626 ol->id = button->count;
627 622
628 for (obp = map->buttons; obp && obp->value != connected; obp = obp->next); 623 for (obp = map->buttons; obp && obp->value != connected; obp = obp->next);
629 624
630 if (obp) 625 if (obp)
631 { 626 {
657 if (op->map == NULL) 652 if (op->map == NULL)
658 { 653 {
659 LOG (llevError, "remove_button_link() in object without map.\n"); 654 LOG (llevError, "remove_button_link() in object without map.\n");
660 return; 655 return;
661 } 656 }
657
662 if (!QUERY_FLAG (op, FLAG_IS_LINKED)) 658 if (!QUERY_FLAG (op, FLAG_IS_LINKED))
663 { 659 {
664 LOG (llevError, "remove_button_linked() in unlinked object.\n"); 660 LOG (llevError, "remove_button_linked() in unlinked object.\n");
665 return; 661 return;
666 } 662 }
663
667 for (obp = op->map->buttons; obp; obp = obp->next) 664 for (obp = op->map->buttons; obp; obp = obp->next)
668 for (olp = &obp->link; (ol = *olp); olp = &ol->next) 665 for (olp = &obp->link; (ol = *olp); olp = &ol->next)
669 if (ol->ob == op) 666 if (ol->ob == op)
670 { 667 {
671 668
672/* 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",
673 obp->value, op->name, op->map->path); 670 obp->value, op->name, op->map->path);
674*/ 671*/
675 *olp = ol->next; 672 *olp = ol->next;
676 free (ol); 673 delete ol;
677 return; 674 return;
678 } 675 }
676
679 LOG (llevError, "remove_button_linked(): couldn't find object.\n"); 677 LOG (llevError, "remove_button_linked(): couldn't find object.\n");
680 CLEAR_FLAG (op, FLAG_IS_LINKED); 678 CLEAR_FLAG (op, FLAG_IS_LINKED);
681} 679}
682 680
683/* 681/*
684 * Gets the objectlink for this connection from the map. 682 * Gets the objectlink for this connection from the map.
685 */ 683 */
686oblinkpt * 684oblinkpt *
687get_connection_links (mapstruct *map, long connection) 685get_connection_links (maptile *map, long connection)
688{ 686{
689 for (oblinkpt * obp = map->buttons; obp; obp = obp->next) 687 for (oblinkpt * obp = map->buttons; obp; obp = obp->next)
690 if (obp->value == connection) 688 if (obp->value == connection)
691 return obp; 689 return obp;
690
692 return 0; 691 return 0;
693} 692}
694 693
695/* 694/*
696 * Return the first objectlink in the objects linked to this one 695 * Return the first objectlink in the objects linked to this one
702 oblinkpt *obp; 701 oblinkpt *obp;
703 objectlink *ol; 702 objectlink *ol;
704 703
705 if (!button->map) 704 if (!button->map)
706 return NULL; 705 return NULL;
706
707 for (obp = button->map->buttons; obp; obp = obp->next) 707 for (obp = button->map->buttons; obp; obp = obp->next)
708 for (ol = obp->link; ol; ol = ol->next) 708 for (ol = obp->link; ol; ol = ol->next)
709 if (ol->ob == button && ol->id == button->count) 709 if (ol->ob == button)
710 return obp; 710 return obp;
711
711 return NULL; 712 return NULL;
712} 713}
713 714
714/* 715/*
715 * Made as a separate function to increase efficiency 716 * Made as a separate function to increase efficiency
723 724
724 if (!button->map) 725 if (!button->map)
725 return 0; 726 return 0;
726 for (obp = button->map->buttons; obp; obp = obp->next) 727 for (obp = button->map->buttons; obp; obp = obp->next)
727 for (ol = obp->link; ol; ol = ol->next) 728 for (ol = obp->link; ol; ol = ol->next)
728 if (ol->ob == button && ol->id == button->count) 729 if (ol->ob == button)
729 return obp->value; 730 return obp->value;
730 return 0; 731 return 0;
731} 732}
732 733
733/* This routine makes monsters who are 734/* This routine makes monsters who are
770 tmp->attack_movement = 0; 771 tmp->attack_movement = 0;
771 /* lots of checks here, but want to make sure we don't 772 /* lots of checks here, but want to make sure we don't
772 * dereference a null value 773 * dereference a null value
773 */ 774 */
774 if (tmp->type == GOLEM && tmp->owner && tmp->owner->type == PLAYER && tmp->owner->contr->ranges[range_golem] == tmp) 775 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; 776 tmp->owner->contr->ranges[range_golem] = 0;
777 tmp->owner->contr->golem_count = 0; 777
778 }
779 tmp->owner = 0; 778 tmp->owner = 0;
780 } 779 }
781 break; 780 break;
782 case 1: /* angry -- get neutral monsters mad */ 781 case 1: /* angry -- get neutral monsters mad */
783 if (QUERY_FLAG (tmp, FLAG_UNAGGRESSIVE) && !QUERY_FLAG (tmp, FLAG_FRIENDLY)) 782 if (QUERY_FLAG (tmp, FLAG_UNAGGRESSIVE) && !QUERY_FLAG (tmp, FLAG_FRIENDLY))
800 if (tmp2->above == NULL) 799 if (tmp2->above == NULL)
801 break; 800 break;
802 801
803 if (tmp2->type != PLAYER) 802 if (tmp2->type != PLAYER)
804 break; 803 break;
805 set_owner (tmp, tmp2); 804 tmp->set_owner (tmp2);
806 SET_FLAG (tmp, FLAG_MONSTER); 805 SET_FLAG (tmp, FLAG_MONSTER);
807 tmp->stats.exp = 0; 806 tmp->stats.exp = 0;
808 SET_FLAG (tmp, FLAG_FRIENDLY); 807 SET_FLAG (tmp, FLAG_FRIENDLY);
809 add_friendly_object (tmp); 808 add_friendly_object (tmp);
810 tmp->attack_movement = PETMOVE; 809 tmp->attack_movement = PETMOVE;
855 * last_heal = 1/0 remove/dont remove obj if triggered 854 * last_heal = 1/0 remove/dont remove obj if triggered
856 * -b.t. (thomas@nomad.astro.psu.edu 855 * -b.t. (thomas@nomad.astro.psu.edu
857 */ 856 */
858 857
859void 858void
860check_inv (object *op, object *trig) 859check_inv (object *op, object *trig, bool move_on)
861{ 860{
862 object *match; 861 object *match;
863 862
864 if (op->type != PLAYER) 863 if (op->type != PLAYER)
865 return; 864 return;
866 match = check_inv_recursive (op, trig); 865 match = check_inv_recursive (op, trig);
867 if (match && trig->last_sp) 866 if (match && trig->last_sp)
868 { 867 {
869 if (trig->last_heal) 868 if (trig->last_heal)
870 decrease_ob (match); 869 decrease_ob (match);
871 use_trigger (trig); 870
871 trig->value = move_on ? 1 : 0;
872
873 push_button (trig);
872 } 874 }
873 else if (!match && !trig->last_sp) 875 else if (!match && !trig->last_sp)
874 use_trigger (trig);
875}
876
877
878/* This does a minimal check of the button link consistency for object
879 * map. All it really does it much sure the object id link that is set
880 * matches what the object has.
881 */
882void
883verify_button_links (const mapstruct *map)
884{
885 oblinkpt *obp;
886 objectlink *ol;
887
888 if (!map)
889 return;
890
891 for (obp = map->buttons; obp; obp = obp->next)
892 {
893 for (ol = obp->link; ol; ol = ol->next)
894 {
895 if (ol->id != ol->ob->count)
896 LOG (llevError, "verify_button_links: object %s on list is corrupt (%d!=%d)\n", &ol->ob->name, ol->id, ol->ob->count);
897 }
898 } 876 {
877 trig->value = move_on ? 1 : 0;
878 push_button (trig);
879 }
899} 880}
881

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines