ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/time.C
(Generate patch)

Comparing deliantra/server/server/time.C (file contents):
Revision 1.107 by root, Sun Apr 11 18:50:04 2010 UTC vs.
Revision 1.123 by root, Thu Nov 17 04:59:33 2016 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 (©) 2005,2006,2007,2008,2009,2010 Marc Alexander Lehmann / Robin Redeker / the Deliantra team 4 * Copyright (©) 2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 * Copyright (©) 2002 Mark Wedel & Crossfire Development Team 5 * Copyright (©) 2002 Mark Wedel & Crossfire Development Team
6 * Copyright (©) 1992 Frank Tore Johansen 6 * Copyright (©) 1992 Frank Tore Johansen
7 * 7 *
8 * Deliantra is free software: you can redistribute it and/or modify it under 8 * 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 9 * 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 10 * Free Software Foundation, either version 3 of the License, or (at your
11 * option) any later version. 11 * option) any later version.
12 * 12 *
13 * This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details. 16 * GNU General Public License for more details.
17 * 17 *
18 * You should have received a copy of the Affero GNU General Public License 18 * 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 19 * and the GNU General Public License along with this program. If not, see
20 * <http://www.gnu.org/licenses/>. 20 * <http://www.gnu.org/licenses/>.
21 * 21 *
22 * The authors can be reached via e-mail to <support@deliantra.net> 22 * The authors can be reached via e-mail to <support@deliantra.net>
23 */ 23 */
24 24
25/* 25/*
26 * Routines that is executed from objects based on their speed have been 26 * Routines that is executed from objects based on their speed have been
28 */ 28 */
29#include <global.h> 29#include <global.h>
30#include <spells.h> 30#include <spells.h>
31#include <sproto.h> 31#include <sproto.h>
32 32
33/* The following removes doors. The functions check to see if similar 33/* The following removes doors. The functions check to see if similar
34 * doors are next to the one that is being removed, and if so, set it 34 * doors are next to the one that is being removed, and if so, set it
35 * so those will be removed shortly (in a cascade like fashion.) 35 * so those will be removed shortly (in a cascade like fashion.)
36 */ 36 */
37void 37void
38remove_door (object *op) 38remove_door (object *op)
239{ /* 1 = going down, 0 = going up */ 239{ /* 1 = going down, 0 = going up */
240 object *tmp; 240 object *tmp;
241 241
242 if (op->stats.wc < 0 || (int) op->stats.wc >= NUM_ANIMATIONS (op)) 242 if (op->stats.wc < 0 || (int) op->stats.wc >= NUM_ANIMATIONS (op))
243 { 243 {
244 LOG (llevError, "Gate error: animation was %d, max=%d\n", op->stats.wc, NUM_ANIMATIONS (op)); 244 LOG (llevError, "%s: gate error: animation was %d, max=%d\n", op->debug_desc (), op->stats.wc, NUM_ANIMATIONS (op));
245 op->stats.wc = 0; 245 op->stats.wc = 0;
246 } 246 }
247 247
248 /* We're going down */ 248 /* We're going down */
249 if (op->value) 249 if (op->value)
272 /* We're going up */ 272 /* We're going up */
273 273
274 /* First, lets see if we are already at the top */ 274 /* First, lets see if we are already at the top */
275 if ((unsigned char) op->stats.wc == (NUM_ANIMATIONS (op) - 1)) 275 if ((unsigned char) op->stats.wc == (NUM_ANIMATIONS (op) - 1))
276 { 276 {
277
278 /* Check to make sure that only non pickable and non rollable 277 /* Check to make sure that only non pickable and non rollable
279 * objects are above the gate. If so, we finish closing the gate, 278 * objects are above the gate. If so, we finish closing the gate,
280 * otherwise, we fall through to the code below which should lower 279 * otherwise, we fall through to the code below which should lower
281 * the gate slightly. 280 * the gate slightly.
282 */ 281 */
502 move_apply (op, tmp, tmp); 501 move_apply (op, tmp, tmp);
503 } 502 }
504 } 503 }
505 504
506 SET_ANIMATION (op, op->stats.wc); 505 SET_ANIMATION (op, op->stats.wc);
507 update_object (op, UP_OBJ_FACE); 506 update_object (op, UP_OBJ_CHANGE);
508 return; 507 return;
509 } 508 }
510 509
511 /* We're closing */ 510 /* We're closing */
512 op->move_on = 0; 511 op->move_on = 0;
513 512
514 op->stats.wc++; 513 op->stats.wc++;
515 if ((int) op->stats.wc >= NUM_ANIMATIONS (op)) 514 if (op->stats.wc >= NUM_ANIMATIONS (op))
516 op->stats.wc = NUM_ANIMATIONS (op) - 1; 515 op->stats.wc = NUM_ANIMATIONS (op) - 1;
517 516
518 SET_ANIMATION (op, op->stats.wc); 517 SET_ANIMATION (op, op->stats.wc);
519 update_object (op, UP_OBJ_FACE); 518 update_object (op, UP_OBJ_CHANGE);
520 if ((unsigned char) op->stats.wc == (NUM_ANIMATIONS (op) - 1)) 519 if (op->stats.wc == (NUM_ANIMATIONS (op) - 1))
521 op->set_speed (0); /* closed, let's stop */ 520 op->set_speed (0); /* closed, let's stop */
522} 521}
523 522
524 523
525/* stop_item() returns a pointer to the stopped object. The stopped object 524/* stop_item() returns a pointer to the stopped object. The stopped object
610 op->stats.grace = 0; 609 op->stats.grace = 0;
611 op->level = 0; 610 op->level = 0;
612 op->face = op->arch->face; 611 op->face = op->arch->face;
613 op->owner = 0; 612 op->owner = 0;
614 613
614 op->clr_flag (FLAG_NO_PICK); /* fire_bow makes arrows NO_PICK so monsters (or anything else) don't pick them mid-flight */
615
615 update_object (op, UP_OBJ_CHANGE); 616 update_object (op, UP_OBJ_CHANGE);
616 617
617 return op; 618 return op;
618} 619}
619 620
655{ 656{
656 int was_reflected; 657 int was_reflected;
657 658
658 if (!op->map) 659 if (!op->map)
659 { 660 {
660 LOG (llevError, "BUG: Arrow had no map.\n"); 661 LOG (llevError | logBacktrace, "BUG: Arrow %s had no map.\n", op->debug_desc ());
661 op->destroy (); 662 op->destroy ();
662 return; 663 return;
663 } 664 }
664 665
665 /* we need to stop thrown objects at some point. Like here. */ 666 /* we need to stop thrown objects at some point. Like here. */
687 } 688 }
688 689
689 /* decrease the speed as it flies. 0.05 means a standard bow will shoot 690 /* decrease the speed as it flies. 0.05 means a standard bow will shoot
690 * about 17 squares. Tune as needed. 691 * about 17 squares. Tune as needed.
691 */ 692 */
692 op->speed -= 0.05; 693 op->set_speed (op->speed - 0.05);
693 694
694 /* if the arrow is moving too slow.. stop it. 0.5 was chosen as lower 695 /* if the arrow is moving too slow.. stop it. 0.5 was chosen as lower
695 values look rediculous. */ 696 values look ridiculous. */
696 if (op->speed < (op->type == ARROW ? 0.05 : MIN_ACTIVE_SPEED)) 697 if (op->speed < (op->type == ARROW ? 0.5 : MIN_ACTIVE_SPEED))
697 { 698 {
698 stop_arrow (op); 699 stop_arrow (op);
699 return; 700 return;
700 } 701 }
701 702
714 if (pos->flags () & P_IS_ALIVE) 715 if (pos->flags () & P_IS_ALIVE)
715 { 716 {
716 object *tmp; 717 object *tmp;
717 718
718 for (tmp = pos->bot; tmp; tmp = tmp->above) 719 for (tmp = pos->bot; tmp; tmp = tmp->above)
719 if (tmp->flag [FLAG_ALIVE]) 720 if (tmp->flag [FLAG_ALIVE] && tmp != op->owner)
720 break; 721 {
721
722 /* Not really fair, but don't let monsters hit themselves with 722 /* Not really fair, but don't let monsters hit themselves with
723 * their own arrow - this can be because they fire it then 723 * their own arrow - this can be because they fire it then
724 * move into it. 724 * move into it.
725 */ 725 */
726 if (tmp && tmp != op->owner) 726
727 {
728 /* Found living object, but it is reflecting the missile. Update 727 /* Found living object, but it is reflecting the missile. Update
729 * as below. (Note that for living creatures there is a small 728 * as below. (Note that for living creatures there is a small
730 * chance that reflect_missile fails.) 729 * chance that reflect_missile fails.)
731 */ 730 */
732 if (tmp->flag [FLAG_REFL_MISSILE] && (rndm (0, 99)) < (90 - op->level / 10)) 731 if (tmp->flag [FLAG_REFL_MISSILE] && (rndm (0, 99)) < (90 - op->level / 10))
733 { 732 {
734 int number = op->face;
735
736 op->direction = absdir (op->direction + 4); 733 op->direction = absdir (op->direction + 4);
737 update_turn_face (op); 734 update_turn_face (op);
738 was_reflected = 1; /* skip normal movement calculations */ 735 was_reflected = 1; /* skip normal movement calculations */
739 } 736 }
740 else 737 else
741 { 738 {
742 /* Attack the object. */ 739 /* Attack the object. */
743 op = hit_with_arrow (op, tmp); 740 op = hit_with_arrow (op, tmp);
744 741
745 if (!op) 742 if (!op)
746 return; 743 return;
747 } 744 }
748 } /* if this is not hitting its owner */ 745
749 } /* if there is something alive on this space */ 746 break;
747 }
748 }
750 749
751 if (OB_TYPE_MOVE_BLOCK (op, pos->move_block)) 750 if (OB_TYPE_MOVE_BLOCK (op, pos->move_block))
752 { 751 {
753 int retry = 0; 752 int retry = 0;
754 753
1004 } 1003 }
1005 1004
1006 cast_spell (op, op, op->stats.sp ? op->stats.sp : rndm (1, 8), spell, NULL); 1005 cast_spell (op, op, op->stats.sp ? op->stats.sp : rndm (1, 8), spell, NULL);
1007} 1006}
1008 1007
1009/* move_player_mover: this function takes a "player mover" as an 1008/* move_player_mover: this function takes a "player mover" as an
1010 * argument, and performs the function of a player mover, which is: 1009 * argument, and performs the function of a player mover, which is:
1011 * 1010 *
1012 * a player mover finds any players that are sitting on it. It 1011 * a player mover finds any players that are sitting on it. It
1013 * moves them in the op->stats.sp direction. speed is how often it'll move. 1012 * moves them in the op->stats.sp direction. speed is how often it'll move.
1014 * If attacktype is nonzero it will paralyze the player. If lifesave is set, 1013 * If attacktype is nonzero it will paralyze the player. If lifesave is set,
1016 * it'll paralyze the victim for hp*his speed/op->speed 1015 * it'll paralyze the victim for hp*his speed/op->speed
1017 */ 1016 */
1018static void 1017static void
1019move_player_mover (object *op) 1018move_player_mover (object *op)
1020{ 1019{
1021 int dir = op->stats.sp; 1020 int dir = 0;
1022 sint16 nx, ny;
1023 maptile *m;
1024
1025 /* Determine direction now for random movers so we do the right thing */
1026 if (!dir)
1027 dir = rndm (1, 8);
1028 1021
1029 for (object *victim = op->ms ().bot; victim; victim = victim->above) 1022 for (object *victim = op->ms ().bot; victim; victim = victim->above)
1030 { 1023 {
1031 if (victim->flag [FLAG_ALIVE] && !victim->flag [FLAG_WIZPASS] && 1024 if (victim->flag [FLAG_ALIVE]
1025 && !victim->flag [FLAG_WIZPASS]
1032 (victim->move_type & op->move_type || !victim->move_type)) 1026 && (victim->move_type & op->move_type || !victim->move_type))
1027 {
1028 if (op->flag [FLAG_LIFESAVE] && op->stats.hp-- < 0)
1033 { 1029 {
1030 op->destroy ();
1031 return;
1032 }
1033
1034 /* Determine direction only once so we do the right thing */
1035 // why is it the right thing, though?
1036 if (!dir)
1037 dir = op->stats.sp ? op->stats.sp : rndm (1, 8);
1038
1039 sint16 nx = op->x + freearr_x[dir];
1040 sint16 ny = op->y + freearr_y[dir];
1041 maptile *m = op->map;
1042 if (get_map_flags (m, &m, nx, ny, &nx, &ny) & P_OUT_OF_MAP)
1043 {
1044 LOG (llevError, "move_player_mover: Trying to push player off the map! map=%s (%d, %d)\n", &m->path, op->x, op->y);
1045 return;
1046 }
1034 1047
1035 if (victim->head) 1048 if (victim->head)
1036 victim = victim->head; 1049 victim = victim->head;
1037
1038 if (op->flag [FLAG_LIFESAVE] && op->stats.hp-- < 0)
1039 {
1040 op->remove ();
1041 return;
1042 }
1043
1044 nx = op->x + freearr_x[dir];
1045 ny = op->y + freearr_y[dir];
1046 m = op->map;
1047 if (get_map_flags (m, &m, nx, ny, &nx, &ny) & P_OUT_OF_MAP)
1048 {
1049 LOG (llevError, "move_player_mover: Trying to push player off the map! map=%s (%d, %d)\n", &m->path, op->x, op->y);
1050 return;
1051 }
1052 1050
1053 if (should_director_abort (op, victim)) 1051 if (should_director_abort (op, victim))
1054 return; 1052 return;
1055 1053
1056 for (object *nextmover = m->at (nx, ny).bot; nextmover; nextmover = nextmover->above) 1054 for (object *nextmover = m->at (nx, ny).bot; nextmover; nextmover = nextmover->above)
1165 int i; 1163 int i;
1166 object *ob_to_copy; 1164 object *ob_to_copy;
1167 1165
1168 /* select random object from inventory to copy */ 1166 /* select random object from inventory to copy */
1169 ob_to_copy = creator->inv; 1167 ob_to_copy = creator->inv;
1170 for (ob = creator->inv->below, i = 1; ob != NULL; ob = ob->below, i++) 1168 for (ob = creator->inv->below, i = 1; ob; ob = ob->below, i++)
1171 { 1169 {
1172 if (rndm (0, i) == 0) 1170 if (rndm (0, i) == 0)
1173 { 1171 {
1174 ob_to_copy = ob; 1172 ob_to_copy = ob;
1175 } 1173 }
1176 } 1174 }
1175
1177 new_ob = ob_to_copy->deep_clone (); 1176 new_ob = ob_to_copy->deep_clone ();
1178 new_ob->clr_flag (FLAG_IS_A_TEMPLATE); 1177 new_ob->clr_flag (FLAG_IS_A_TEMPLATE);
1179 unflag_inv (new_ob, FLAG_IS_A_TEMPLATE); 1178 unflag_inv (new_ob, FLAG_IS_A_TEMPLATE);
1180 } 1179 }
1181 else 1180 else
1198 return; 1197 return;
1199 } 1198 }
1200 1199
1201 // for now lets try to identify everything generated here, it mostly 1200 // for now lets try to identify everything generated here, it mostly
1202 // happens automated, so this will at least fix many identify-experience holes 1201 // happens automated, so this will at least fix many identify-experience holes
1202 if (new_ob->need_identify ())
1203 new_ob->set_flag (FLAG_IDENTIFIED); 1203 new_ob->set_flag (FLAG_IDENTIFIED);
1204 1204
1205 insert_ob_in_map_at (new_ob, creator->map, creator, 0, creator->x, creator->y); 1205 insert_ob_in_map_at (new_ob, creator->map, creator, 0, creator->x, creator->y);
1206 if (new_ob->flag [FLAG_FREED]) 1206 if (new_ob->flag [FLAG_FREED])
1207 return; 1207 return;
1208 1208
1483 1483
1484 case LAMP: 1484 case LAMP:
1485 case TORCH: 1485 case TORCH:
1486 move_lamp (op); 1486 move_lamp (op);
1487 break; 1487 break;
1488 }
1489}
1490 1488
1489 case PHYSICS: // hmm, bad naming
1490 move_physics (op);
1491 break;
1492 }
1493}
1494

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines