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.60 by root, Mon Oct 26 03:43:22 2009 UTC vs.
Revision 1.75 by root, Sun Nov 18 15:19:48 2018 UTC

1/* 1/*
2 * This file is part of Deliantra, the Roguelike Realtime MMORPG. 2 * This file is part of Deliantra, the Roguelike Realtime MMORPG.
3 * 3 *
4 * Copyright (©) 2017,2018 Marc Alexander Lehmann / the Deliantra team
4 * Copyright (©) 2005,2006,2007,2008,2009 Marc Alexander Lehmann / Robin Redeker / the Deliantra team 5 * Copyright (©) 2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team 6 * Copyright (©) 2002 Mark Wedel & Crossfire Development Team
6 * Copyright (©) 1992,2007 Frank Tore Johansen 7 * Copyright (©) 1992 Frank Tore Johansen
7 * 8 *
8 * Deliantra is free software: you can redistribute it and/or modify it under 9 * Deliantra is free software: you can redistribute it and/or modify it under
9 * the terms of the Affero GNU General Public License as published by the 10 * the terms of the Affero GNU General Public License as published by the
10 * Free Software Foundation, either version 3 of the License, or (at your 11 * Free Software Foundation, either version 3 of the License, or (at your
11 * option) any later version. 12 * option) any later version.
12 * 13 *
13 * This program is distributed in the hope that it will be useful, 14 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details. 17 * GNU General Public License for more details.
17 * 18 *
18 * You should have received a copy of the Affero GNU General Public License 19 * You should have received a copy of the Affero GNU General Public License
19 * and the GNU General Public License along with this program. If not, see 20 * and the GNU General Public License along with this program. If not, see
20 * <http://www.gnu.org/licenses/>. 21 * <http://www.gnu.org/licenses/>.
21 * 22 *
22 * The authors can be reached via e-mail to <support@deliantra.net> 23 * The authors can be reached via e-mail to <support@deliantra.net>
23 */ 24 */
24 25
25#include <global.h> 26#include <global.h>
26 27
52 * 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
53 * 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
54 * re-loaded. As such, just exit this function if that is the case. 55 * re-loaded. As such, just exit this function if that is the case.
55 */ 56 */
56 57
57 if (QUERY_FLAG (ol->ob, FLAG_FREED)) 58 if (ol->ob->flag [FLAG_FREED])
58 return; 59 return;
59 60
60 object *tmp = ol->ob; 61 object *tmp = ol->ob;
61 62
62 /* if the criteria isn't appropriate, don't do anything */ 63 /* if the criteria isn't appropriate, don't do anything */
63 if (state && !QUERY_FLAG (tmp, FLAG_ACTIVATE_ON_PUSH)) 64 if (state && !tmp->flag [FLAG_ACTIVATE_ON_PUSH])
64 continue; 65 continue;
65 66
66 if (!state && !QUERY_FLAG (tmp, FLAG_ACTIVATE_ON_RELEASE)) 67 if (!state && !tmp->flag [FLAG_ACTIVATE_ON_RELEASE])
67 continue; 68 continue;
68 69
69 switch (tmp->type) 70 switch (tmp->type)
70 { 71 {
71 case GATE: 72 case GATE:
77 tmp->value = tmp->stats.maxsp ? !state : state; 78 tmp->value = tmp->stats.maxsp ? !state : state;
78 tmp->set_speed (0.5); 79 tmp->set_speed (0.5);
79 break; 80 break;
80 81
81 case T_HANDLE: 82 case T_HANDLE:
82 SET_ANIMATION (tmp, (tmp->value = tmp->stats.maxsp ? !state : state)); 83 tmp->value = tmp->stats.maxsp ? !state : state;
83 update_object (tmp, UP_OBJ_FACE); 84 tmp->update_anim_frame (tmp->value);
84 break; 85 break;
85 86
86 case SIGN: 87 case SIGN:
87 if (!tmp->stats.food || tmp->last_eat < tmp->stats.food) 88 if (!tmp->stats.food || tmp->last_eat < tmp->stats.food)
88 { 89 {
99 break; 100 break;
100 101
101 case ALTAR: 102 case ALTAR:
102 tmp->play_sound (tmp->sound ? tmp->sound : sound_find ("trigger_altar")); 103 tmp->play_sound (tmp->sound ? tmp->sound : sound_find ("trigger_altar"));
103 tmp->value = 1; 104 tmp->value = 1;
104 SET_ANIMATION (tmp, tmp->value); 105 tmp->update_anim_frame (tmp->value);
105 update_object (tmp, UP_OBJ_FACE);
106 break; 106 break;
107 107
108 case BUTTON: 108 case BUTTON:
109 case PEDESTAL: 109 case PEDESTAL:
110 tmp->play_sound (tmp->sound ? tmp->sound : sound_find ("trigger_button")); 110 tmp->play_sound (tmp->sound ? tmp->sound : sound_find ("trigger_button"));
111 tmp->value = state; 111 tmp->value = state;
112 SET_ANIMATION (tmp, tmp->value); 112 tmp->update_anim_frame (tmp->value);
113 update_object (tmp, UP_OBJ_FACE);
114 break; 113 break;
115 114
116 case MOOD_FLOOR: 115 case MOOD_FLOOR:
117 do_mood_floor (tmp, activator); 116 do_mood_floor (tmp, activator);
118 break; 117 break;
137 } 136 }
138 break; 137 break;
139 138
140 case DIRECTOR: 139 case DIRECTOR:
141 case FIREWALL: 140 case FIREWALL:
142 if (!QUERY_FLAG (tmp, FLAG_ANIMATE) && tmp->type == FIREWALL) 141 if (!tmp->flag [FLAG_ANIMATE] && tmp->type == FIREWALL)
143 move_firewall (tmp); 142 move_firewall (tmp);
144 else 143 else
145 { 144 {
146 tmp->stats.sp = absdir (tmp->stats.sp + tmp->stats.maxsp); /* next direction */ 145 tmp->stats.sp = absdir (tmp->stats.sp + tmp->stats.maxsp); /* next direction */
147 animate_turning (tmp); 146 animate_turning (tmp);
236 235
237 object *tmp = ol->ob; 236 object *tmp = ol->ob;
238 237
239 if (tmp->type == BUTTON) 238 if (tmp->type == BUTTON)
240 { 239 {
241 sint32 total = 0; 240 weight_t total = 0;
242 241
243 for (object *ab = tmp->above; ab; ab = ab->above) 242 for (object *ab = tmp->above; ab; ab = ab->above)
244 /* Basically, if the move_type matches that on what the 243 /* Basically, if the move_type matches that on what the
245 * button wants, we count it. The second check is so that 244 * button wants, we count it. The second check is so that
246 * objects who don't move (swords, etc) will count. Note that 245 * objects who don't move (swords, etc) will count. Note that
305 //LOG(llevDebug, "update_button: %s (%d, %d=%d)\n", &op->name, op->count, op->value, old_value); 304 //LOG(llevDebug, "update_button: %s (%d, %d=%d)\n", &op->name, op->count, op->value, old_value);
306 305
307 /* If this button hasn't changed, don't do anything */ 306 /* If this button hasn't changed, don't do anything */
308 if (op->value != old_value) 307 if (op->value != old_value)
309 { 308 {
310 SET_ANIMATION (op, op->value); 309 op->update_anim_frame (op->value);
311 update_object (op, UP_OBJ_FACE);
312 push_button (op, originator); /* Make all other buttons the same */ 310 push_button (op, originator); /* Make all other buttons the same */
313 } 311 }
314} 312}
315 313
316void 314void
327 * but it can't handle animations in the 8 directions 325 * but it can't handle animations in the 8 directions
328 */ 326 */
329void 327void
330animate_turning (object *op) /* only one part objects */ 328animate_turning (object *op) /* only one part objects */
331{ 329{
332 if (++op->state >= NUM_ANIMATIONS (op) / 8) 330 if (++op->state >= op->anim_frames () / 8)
333 op->state = 0; 331 op->state = 0;
334 SET_ANIMATION (op, (op->stats.sp - 1) * NUM_ANIMATIONS (op) / 8 + op->state); 332
335 update_object (op, UP_OBJ_FACE); 333 op->update_anim_frame ((op->stats.sp - 1) * op->anim_frames () / 8 + op->state);
336} 334}
337 335
338#define ARCH_SACRIFICE(xyz) ((xyz)->slaying) 336#define ARCH_SACRIFICE(xyz) ((xyz)->slaying)
339#define NROF_SACRIFICE(xyz) ((uint32)(xyz)->stats.food) 337#define NROF_SACRIFICE(xyz) ((uint32)(xyz)->stats.food)
340 338
346 * 344 *
347 * 0.93.4: Linked objects (ie, objects that are connected) can not be 345 * 0.93.4: Linked objects (ie, objects that are connected) can not be
348 * sacrificed. This fixes a bug of trying to put multiple altars/related 346 * sacrificed. This fixes a bug of trying to put multiple altars/related
349 * objects on the same space that take the same sacrifice. 347 * objects on the same space that take the same sacrifice.
350 */ 348 */
351
352int 349int
353check_altar_sacrifice (object *altar, object *sacrifice, object *originator) 350check_altar_sacrifice (object *altar, object *sacrifice, object *originator)
354{ 351{
355 if (sacrifice->flag [FLAG_UNPAID]) 352 if (sacrifice->flag [FLAG_UNPAID]
353 || sacrifice->flag [FLAG_IS_LINKED]
354 || sacrifice->is_player ())
356 return 0; 355 return 0;
357 356
358 if (is_match_expr (ARCH_SACRIFICE (altar))) 357 if (is_match_expr (ARCH_SACRIFICE (altar)))
359 return match (ARCH_SACRIFICE (altar), altar, originator); 358 return match (ARCH_SACRIFICE (altar), sacrifice, altar, originator);
360 359
361 if (!QUERY_FLAG (sacrifice, FLAG_ALIVE) 360 if (!sacrifice->flag [FLAG_ALIVE])
362 && !QUERY_FLAG (sacrifice, FLAG_IS_LINKED)
363 && sacrifice->type != PLAYER)
364 { 361 {
365 if (ARCH_SACRIFICE (altar) == shstr_money 362 if (ARCH_SACRIFICE (altar) == shstr_money
366 && sacrifice->type == MONEY 363 && sacrifice->type == MONEY
367 && sacrifice->nrof * sacrifice->value >= NROF_SACRIFICE (altar)) 364 && sacrifice->nrof * sacrifice->value >= NROF_SACRIFICE (altar))
368 return 1; 365 return 1;
424 new_info_map (NDI_BLACK, altar->map, altar->msg); 421 new_info_map (NDI_BLACK, altar->map, altar->msg);
425 422
426 return 1; 423 return 1;
427} 424}
428 425
429void 426static void
430trigger_move (object *op, int state, object *originator) /* 1 down and 0 up */ 427trigger_move (object *op, int state, object *originator) /* 1 down and 0 up */
431{ 428{
432 op->stats.wc = state; 429 op->stats.wc = state;
433 430
434 if (state) 431 if (state)
460int 457int
461check_trigger (object *op, object *cause, object *originator) 458check_trigger (object *op, object *cause, object *originator)
462{ 459{
463 object *tmp; 460 object *tmp;
464 int push = 0, tot = 0; 461 int push = 0, tot = 0;
465 int in_movement = op->stats.wc || op->speed; 462 int in_movement = op->stats.wc || op->has_active_speed ();
466 463
467 switch (op->type) 464 switch (op->type)
468 { 465 {
469 case TRIGGER_BUTTON: 466 case TRIGGER_BUTTON:
470 if (op->weight > 0) 467 if (op->weight > 0)
487 484
488 if (op->stats.ac == push) 485 if (op->stats.ac == push)
489 return 0; 486 return 0;
490 487
491 op->stats.ac = push; 488 op->stats.ac = push;
492 if (NUM_ANIMATIONS (op) > 1) 489 op->update_anim_frame (push);
493 {
494 SET_ANIMATION (op, push);
495 update_object (op, UP_OBJ_FACE);
496 }
497 490
498 if (in_movement || !push) 491 if (in_movement || !push)
499 return 0; 492 return 0;
500 } 493 }
501 494
522 515
523 if (op->stats.ac == push) 516 if (op->stats.ac == push)
524 return 0; 517 return 0;
525 518
526 op->stats.ac = push; 519 op->stats.ac = push;
527 520 op->update_anim_frame (push);
528 if (NUM_ANIMATIONS (op) > 1)
529 {
530 SET_ANIMATION (op, push);
531 update_object (op, UP_OBJ_FACE);
532 }
533
534 update_object (op, UP_OBJ_FACE);
535 521
536 if (in_movement || !push) 522 if (in_movement || !push)
537 return 0; 523 return 0;
538 } 524 }
539 525
546 if (in_movement) 532 if (in_movement)
547 return 0; 533 return 0;
548 534
549 if (operate_altar (op, &cause)) /* TODO: originator? */ 535 if (operate_altar (op, &cause)) /* TODO: originator? */
550 { 536 {
551 if (NUM_ANIMATIONS (op) > 1) 537 op->update_anim_frame (1);
552 {
553 SET_ANIMATION (op, 1);
554 update_object (op, UP_OBJ_FACE);
555 }
556 538
557 if (op->last_sp >= 0) 539 if (op->last_sp >= 0)
558 { 540 {
559 trigger_move (op, 1, cause); 541 trigger_move (op, 1, cause);
560 542
562 op->last_sp = -op->last_sp; 544 op->last_sp = -op->last_sp;
563 } 545 }
564 else 546 else
565 { 547 {
566 /* for trigger altar with last_sp, the ON/OFF 548 /* for trigger altar with last_sp, the ON/OFF
567 * status (-> +/- value) is "simulated": 549 * status (-> +/- value) is "simulated":
568 */ 550 */
569 op->value = !op->value; 551 op->value = !op->value;
570 trigger_move (op, 1, cause); 552 trigger_move (op, 1, cause);
571 op->last_sp = -op->last_sp; 553 op->last_sp = -op->last_sp;
572 op->value = !op->value; 554 op->value = !op->value;
577 else 559 else
578 return 0; 560 return 0;
579 } 561 }
580 else 562 else
581 { 563 {
582 if (NUM_ANIMATIONS (op) > 1) 564 op->update_anim_frame (0);
583 {
584 SET_ANIMATION (op, 0);
585 update_object (op, UP_OBJ_FACE);
586 }
587 565
588 /* If trigger_altar has "last_sp > 0" set on the map, 566 /* If trigger_altar has "last_sp > 0" set on the map,
589 * it will push the connected value only once per sacrifice. 567 * it will push the connected value only once per sacrifice.
590 * Otherwise (default), the connected value will be 568 * Otherwise (default), the connected value will be
591 * pushed twice: First by sacrifice, second by reset! -AV 569 * pushed twice: First by sacrifice, second by reset! -AV
592 */ 570 */
593 if (!op->last_sp) 571 if (!op->last_sp)
594 trigger_move (op, 0, cause); 572 trigger_move (op, 0, cause);
595 else 573 else
596 { 574 {
608 return 0; 586 return 0;
609 587
610 push = 1; 588 push = 1;
611 } 589 }
612 590
613 if (NUM_ANIMATIONS (op) > 1) 591 op->update_anim_frame (push);
614 {
615 SET_ANIMATION (op, push);
616 update_object (op, UP_OBJ_FACE);
617 }
618 592
619 trigger_move (op, push, cause); 593 trigger_move (op, push, cause);
620 return 1; 594 return 1;
621 595
622 default: 596 default:
739 return obp; 713 return obp;
740 714
741 return 0; 715 return 0;
742} 716}
743 717
744/* This routine makes monsters who are 718/* This routine makes monsters who are
745 * standing on the 'mood floor' change their 719 * standing on the 'mood floor' change their
746 * disposition if it is different. 720 * disposition if it is different.
747 * If floor is to be triggered must have 721 * If floor is to be triggered must have
748 * a speed of zero (default is 1 for all 722 * a speed of zero (default is 1 for all
749 * but the charm floor type). 723 * but the charm floor type).
750 * by b.t. thomas@nomad.astro.psu.edu 724 * by b.t. thomas@nomad.astro.psu.edu
751 */ 725 */
761 return; 735 return;
762 736
763 object *tmp; 737 object *tmp;
764 738
765 for (tmp = ms.top; tmp; tmp = tmp->below) 739 for (tmp = ms.top; tmp; tmp = tmp->below)
766 if (QUERY_FLAG (tmp, FLAG_MONSTER)) 740 if (tmp->flag [FLAG_MONSTER])
767 break; 741 break;
768 742
769 /* doesn't effect players, and if there is a player on this space, won't also 743 /* doesn't effect players, and if there is a player on this space, won't also
770 * be a monster here. 744 * be a monster here.
771 */ 745 */
774 return; 748 return;
775 749
776 switch (op->last_sp) 750 switch (op->last_sp)
777 { 751 {
778 case 0: /* furious--make all monsters mad */ 752 case 0: /* furious--make all monsters mad */
779 if (QUERY_FLAG (tmp, FLAG_UNAGGRESSIVE)) 753 if (tmp->flag [FLAG_UNAGGRESSIVE])
780 CLEAR_FLAG (tmp, FLAG_UNAGGRESSIVE); 754 tmp->clr_flag (FLAG_UNAGGRESSIVE);
781 755
782 if (QUERY_FLAG (tmp, FLAG_FRIENDLY)) 756 if (tmp->flag [FLAG_FRIENDLY])
783 { 757 {
784 tmp->attack_movement = 0; 758 tmp->attack_movement = 0;
785 /* lots of checks here, but want to make sure we don't 759 /* lots of checks here, but want to make sure we don't
786 * dereference a null value 760 * dereference a null value
787 */ 761 */
796 remove_friendly_object (tmp); 770 remove_friendly_object (tmp);
797 } 771 }
798 break; 772 break;
799 773
800 case 1: /* angry -- get neutral monsters mad */ 774 case 1: /* angry -- get neutral monsters mad */
801 if (QUERY_FLAG (tmp, FLAG_UNAGGRESSIVE) && !QUERY_FLAG (tmp, FLAG_FRIENDLY)) 775 if (tmp->flag [FLAG_UNAGGRESSIVE] && !tmp->flag [FLAG_FRIENDLY])
802 CLEAR_FLAG (tmp, FLAG_UNAGGRESSIVE); 776 tmp->clr_flag (FLAG_UNAGGRESSIVE);
803 break; 777 break;
804 778
805 case 2: /* calm -- pacify unfriendly monsters */ 779 case 2: /* calm -- pacify unfriendly monsters */
806 SET_FLAG (tmp, FLAG_UNAGGRESSIVE); 780 tmp->set_flag (FLAG_UNAGGRESSIVE);
807 break; 781 break;
808 782
809 case 3: /* make all monsters fall asleep */ 783 case 3: /* make all monsters fall asleep */
810 SET_FLAG (tmp, FLAG_SLEEP); 784 tmp->set_flag (FLAG_SLEEP);
811 break; 785 break;
812 786
813 case 4: /* charm all monsters */ 787 case 4: /* charm all monsters */
814 if (op == source) 788 if (op == source)
815 break; /* only if 'connected' */ 789 break; /* only if 'connected' */
816 790
817 if (object *pl = source->ms ().player ()) 791 if (object *pl = source->ms ().player ())
818 { 792 {
819 tmp->set_owner (pl); 793 tmp->set_owner (pl);
820 SET_FLAG (tmp, FLAG_MONSTER); 794 tmp->set_flag (FLAG_MONSTER);
821 795
822 tmp->stats.exp = 0; 796 tmp->stats.exp = 0;
823 797
824 add_friendly_object (tmp); 798 add_friendly_object (tmp);
825 tmp->attack_movement = PETMOVE; 799 tmp->attack_movement = PETMOVE;
826 } 800 }
827 break; 801 break;
828 802
829 case 6: // kill monsters 803 case 6: // kill monsters
830 if (!QUERY_FLAG (tmp, FLAG_FRIENDLY)) 804 if (!tmp->flag [FLAG_FRIENDLY])
831 break; 805 break;
832 806
833 // FALL THROUGH 807 // FALL THROUGH
834 case 5: // kill all alives 808 case 5: // kill all alives
835 if (!tmp->flag [FLAG_PRECIOUS]) 809 if (!tmp->flag [FLAG_PRECIOUS])
875 return tmp; 849 return tmp;
876 } 850 }
877 return NULL; 851 return NULL;
878} 852}
879 853
880/* check_inv(), a function to search the inventory, 854/* check_inv(), a function to search the inventory,
881 * of a player and then based on a set of conditions, 855 * of a player and then based on a set of conditions,
882 * the square will activate connected items. 856 * the square will activate connected items.
883 * Monsters can't trigger this square (for now) 857 * Monsters can't trigger this square (for now)
884 * Values are: last_sp = 1/0 obj/no obj triggers 858 * Values are: last_sp = 1/0 obj/no obj triggers
885 * last_heal = 1/0 remove/dont remove obj if triggered 859 * last_heal = 1/0 remove/dont remove obj if triggered
886 * -b.t. (thomas@nomad.astro.psu.edu 860 * -b.t. (thomas@nomad.astro.psu.edu
887 * 861 *
888 * Tue Dec 19 15:34:00 CET 2006 elmex: changed the function to ignore op 862 * Tue Dec 19 15:34:00 CET 2006 elmex: changed the function to ignore op
889 * because the check-inventory semantic essentially only applies when 863 * because the check-inventory semantic essentially only applies when
890 * something is above the inventory checker. 864 * something is above the inventory checker.
891 * The semantic prior this change was: trigger if something has moved on or off 865 * The semantic prior this change was: trigger if something has moved on or off
894 * away, and then leaves the inventory checker. That would've caused an always-enabled 868 * away, and then leaves the inventory checker. That would've caused an always-enabled
895 * state in the inventory checker. This won't happen anymore now. 869 * state in the inventory checker. This won't happen anymore now.
896 * 870 *
897 * Wed Jan 10 11:34:26 CET 2007 elmex: fixed this function, we now check 871 * Wed Jan 10 11:34:26 CET 2007 elmex: fixed this function, we now check
898 * whether op is on this mapspace or not, because the value (1|0) depends 872 * whether op is on this mapspace or not, because the value (1|0) depends
899 * on this information. also make sure to only push_button if op has 873 * on this information. also make sure to only push_button if op has
900 * a matching item (because when we do a push_button with value=0 timed gates 874 * a matching item (because when we do a push_button with value=0 timed gates
901 * will still open)! (i hope i got the semantics right this time) 875 * will still open)! (i hope i got the semantics right this time)
902 * 876 *
903 */ 877 */
904void 878void

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines