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.29 by elmex, Sat Dec 30 21:07:46 2006 UTC vs.
Revision 1.45 by root, Sun Apr 22 13:06:45 2007 UTC

1/* 1/*
2 CrossFire, A Multiplayer game for X-windows 2 * CrossFire, A Multiplayer game
3 3 *
4 * Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team
4 Copyright (C) 2002 Mark Wedel & Crossfire Development Team 5 * Copyright (C) 2002 Mark Wedel & Crossfire Development Team
5 Copyright (C) 1992 Frank Tore Johansen 6 * Copyright (C) 1992 Frank Tore Johansen
6 7 *
7 This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or 10 * the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version. 11 * (at your option) any later version.
11 12 *
12 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,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details. 16 * GNU General Public License for more details.
16 17 *
17 You should have received a copy of the GNU General Public License 18 * You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software 19 * along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 21 *
21 The authors can be reached via e-mail at <crossfire@schmorp.de> 22 * The authors can be reached via e-mail at <crossfire@schmorp.de>
22*/ 23 */
23 24
24/* 25/*
25 * 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
26 * collected in this file. 27 * collected in this file.
27 */ 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 */
37
38void 37void
39remove_door (object *op) 38remove_door (object *op)
40{ 39{
41 int i; 40 int i;
42 object *tmp; 41 object *tmp;
88 } 87 }
89 88
90 op->destroy (); 89 op->destroy ();
91} 90}
92 91
93/* Will generate a monster according to content
94 * of generator.
95 */
96void 92void
97generate_monster_inv (object *gen) 93generate_monster (object *gen)
98{ 94{
99 int i;
100 object *op, *head = NULL;
101
102 int qty = 0;
103
104 /* Code below assumes the generator is on a map, as it tries
105 * to place the monster on the map. So if the generator
106 * isn't on a map, complain and exit.
107 */
108 if (gen->map == NULL)
109 {
110 //LOG(llevError,"Generator (%s) not on a map?\n", gen->name);
111 return;
112 }
113 /*First count numer of objects in inv */
114 for (op = gen->inv; op; op = op->below)
115 qty++;
116 if (!qty)
117 {
118 LOG (llevError, "Generator (%s) has no inventory in generate_monster_inv?\n", &gen->name);
119 return; /*No inventory */
120 }
121 qty = rndm (0, qty - 1);
122 for (op = gen->inv; qty; qty--)
123 op = op->below;
124 i = find_free_spot (op, gen->map, gen->x, gen->y, 1, 9);
125 if (i == -1)
126 return;
127 head = object_create_clone (op);
128 CLEAR_FLAG (head, FLAG_IS_A_TEMPLATE);
129 unflag_inv (head, FLAG_IS_A_TEMPLATE);
130 if (rndm (0, 9))
131 generate_artifact (head, gen->map->difficulty);
132 insert_ob_in_map_at (head, gen->map, gen, 0, gen->x + freearr_x[i], gen->y + freearr_y[i]);
133 if (QUERY_FLAG (head, FLAG_FREED))
134 return;
135 if (head->has_random_items ())
136 create_treasure (head->randomitems, head, GT_APPLY, gen->map->difficulty, 0);
137}
138
139void
140generate_monster_arch (object *gen)
141{
142 int i;
143 object *op, *head = NULL, *prev = NULL;
144 archetype *at = gen->other_arch;
145
146 if (!gen->other_arch)
147 return;
148
149 /* Code below assumes the generator is on a map, as it tries
150 * to place the monster on the map. So if the generator
151 * isn't on a map, complain and exit.
152 */
153 if (!gen->map) 95 if (!gen->map)
154 return; 96 return;
155 97
156 i = find_free_spot (&at->clone, gen->map, gen->x, gen->y, 1, 9);
157 if (i == -1)
158 return;
159
160 while (at)
161 {
162 op = arch_to_object (at);
163 op->x = gen->x + freearr_x[i] + at->clone.x;
164 op->y = gen->y + freearr_y[i] + at->clone.y;
165
166 if (head)
167 op->head = head, prev->more = op;
168
169 if (rndm (0, 9))
170 generate_artifact (op, gen->map->difficulty);
171
172 insert_ob_in_map (op, gen->map, gen, 0);
173 if (QUERY_FLAG (op, FLAG_FREED))
174 return;
175
176 if (op->has_random_items ())
177 create_treasure (op->randomitems, op, GT_APPLY, gen->map->difficulty, 0);
178
179 if (head == NULL)
180 head = op;
181
182 prev = op;
183 at = at->more;
184 }
185}
186
187void
188generate_monster (object *gen)
189{
190
191 if (GENERATE_SPEED (gen) && rndm (0, GENERATE_SPEED (gen) - 1)) 98 if (GENERATE_SPEED (gen) && rndm (0, GENERATE_SPEED (gen) - 1))
192 return; 99 return;
193 100
101 object *op;
102
194 if (QUERY_FLAG (gen, FLAG_CONTENT_ON_GEN)) 103 if (QUERY_FLAG (gen, FLAG_CONTENT_ON_GEN))
195 generate_monster_inv (gen); 104 {
105 // either copy one item form the inventory...
106 if (!gen->inv)
107 return;
108
109 // first select one item from the inventory
110 int index = 0;
111 for (object *tmp = gen->inv; tmp; tmp = tmp->below)
112 if (!rndm (++index))
113 op = tmp;
114
115 op = object_create_clone (op);
116
117 CLEAR_FLAG (op, FLAG_IS_A_TEMPLATE);
118 unflag_inv (op, FLAG_IS_A_TEMPLATE);
119 }
196 else 120 else
197 generate_monster_arch (gen); 121 {
122 // ...or use other_arch
123 if (archetype *at = gen->other_arch)
124 op = arch_to_object (at);
125 else
126 return;
127 }
198 128
129 op->expand_tail ();
130
131 int i = find_free_spot (op, gen->map, gen->x, gen->y, 1, 9);
132 if (i >= 0)
133 {
134 if (insert_ob_in_map_at (op, gen->map, gen, 0, gen->x + freearr_x[i], gen->y + freearr_y[i]))
135 {
136 if (rndm (0, 9))
137 generate_artifact (op, gen->map->difficulty);
138
139 if (op->has_random_items ())
140 create_treasure (op->randomitems, op, GT_APPLY, gen->map->difficulty);
141
142 return;
143 }
144 }
145
146 op->destroy ();
199} 147}
200 148
201void 149void
202remove_force (object *op) 150remove_force (object *op)
203{ 151{
246 return; 194 return;
247 } 195 }
248 196
249 if (op->stats.food == 1) 197 if (op->stats.food == 1)
250 { 198 {
251 /* need to remove the object before fix_player is called, else fix_player 199 /* need to unapply the object before update_stats is called, else fix_player
252 * will not do anything. 200 * will not do anything.
253 */ 201 */
254 if (op->env->type == PLAYER) 202 if (op->env->type == PLAYER)
255 { 203 {
256 CLEAR_FLAG (op, FLAG_APPLIED); 204 CLEAR_FLAG (op, FLAG_APPLIED);
265 if (op->env->type == PLAYER) 213 if (op->env->type == PLAYER)
266 { 214 {
267 op->env->stats.food--; 215 op->env->stats.food--;
268 new_draw_info (NDI_UNIQUE, 0, op->env, "You feel very sick..."); 216 new_draw_info (NDI_UNIQUE, 0, op->env, "You feel very sick...");
269 } 217 }
218
270 (void) hit_player (op->env, op->stats.dam, op, AT_INTERNAL, 1); 219 hit_player (op->env, op->stats.dam, op, AT_INTERNAL, 1);
271} 220}
272 221
273 222
274void 223void
275move_gate (object *op) 224move_gate (object *op)
455 404
456 if (op->stats.hp) 405 if (op->stats.hp)
457 { 406 {
458 for (tmp2 = tmp->inv; tmp2; tmp2 = tmp2->below) 407 for (tmp2 = tmp->inv; tmp2; tmp2 = tmp2->below)
459 { 408 {
460 if (op->slaying && !strcmp (op->slaying, tmp->name)) 409 if (op->slaying && op->slaying == tmp->name)
461 detected = 1; 410 detected = 1;
411
462 if (tmp2->type == FORCE && tmp2->slaying && !strcmp (tmp2->slaying, op->slaying)) 412 if (tmp2->type == FORCE && tmp2->slaying && tmp2->slaying == op->slaying)
463 detected = 1; 413 detected = 1;
464 } 414 }
465 } 415 }
416
466 if (op->slaying && !strcmp (op->slaying, tmp->name)) 417 if (op->slaying && op->slaying == tmp->name)
467 {
468 detected = 1; 418 detected = 1;
469 }
470 else if (tmp->type == SPECIAL_KEY && tmp->slaying == op->slaying) 419 else if (tmp->type == SPECIAL_KEY && tmp->slaying == op->slaying)
471 detected = 1; 420 detected = 1;
472 } 421 }
473 422
474 /* the detector sets the button if detection is found */ 423 /* the detector sets the button if detection is found */
604void 553void
605fix_stopped_item (object *op, maptile *map, object *originator) 554fix_stopped_item (object *op, maptile *map, object *originator)
606{ 555{
607 if (map == NULL) 556 if (map == NULL)
608 return; 557 return;
558
609 if (QUERY_FLAG (op, FLAG_REMOVED)) 559 if (QUERY_FLAG (op, FLAG_REMOVED))
610 insert_ob_in_map (op, map, originator, 0); 560 insert_ob_in_map (op, map, originator, 0);
611 else if (op->type == ARROW) 561 else if (op->type == ARROW)
612 merge_ob (op, NULL); /* only some arrows actually need this */ 562 merge_ob (op, NULL); /* only some arrows actually need this */
613} 563}
614
615 564
616object * 565object *
617fix_stopped_arrow (object *op) 566fix_stopped_arrow (object *op)
618{ 567{
619 if (rndm (0, 99) < op->stats.food) 568 if (rndm (0, 99) < op->stats.food)
648 op->stats.hp = 0; 597 op->stats.hp = 0;
649 op->stats.grace = 0; 598 op->stats.grace = 0;
650 op->level = 0; 599 op->level = 0;
651 op->face = op->arch->clone.face; 600 op->face = op->arch->clone.face;
652 op->owner = NULL; /* So that stopped arrows will be saved */ 601 op->owner = NULL; /* So that stopped arrows will be saved */
653 update_object (op, UP_OBJ_FACE); 602 update_object (op, UP_OBJ_CHANGE);
654 return op; 603 return op;
655} 604}
656 605
657/* stop_arrow() - what to do when a non-living flying object 606/* stop_arrow() - what to do when a non-living flying object
658 * has to stop. Sept 96 - I added in thrown object code in 607 * has to stop. Sept 96 - I added in thrown object code in
684 } 633 }
685} 634}
686 635
687/* Move an arrow along its course. op is the arrow or thrown object. 636/* Move an arrow along its course. op is the arrow or thrown object.
688 */ 637 */
689
690void 638void
691move_arrow (object *op) 639move_arrow (object *op)
692{ 640{
693 object *tmp; 641 object *tmp;
694 sint16 new_x, new_y; 642 sint16 new_x, new_y;
765 * as below. (Note that for living creatures there is a small 713 * as below. (Note that for living creatures there is a small
766 * chance that reflect_missile fails.) 714 * chance that reflect_missile fails.)
767 */ 715 */
768 if (QUERY_FLAG (tmp, FLAG_REFL_MISSILE) && (rndm (0, 99)) < (90 - op->level / 10)) 716 if (QUERY_FLAG (tmp, FLAG_REFL_MISSILE) && (rndm (0, 99)) < (90 - op->level / 10))
769 { 717 {
770 int number = op->face->number; 718 int number = op->face;
771 719
772 op->direction = absdir (op->direction + 4); 720 op->direction = absdir (op->direction + 4);
773 op->state = 0; 721 update_turn_face (op);
774
775 if (GET_ANIM_ID (op))
776 {
777 number += 4;
778
779 if (number > GET_ANIMATION (op, 8))
780 number -= 8;
781
782 op->face = &new_faces[number];
783 }
784
785 was_reflected = 1; /* skip normal movement calculations */ 722 was_reflected = 1; /* skip normal movement calculations */
786 } 723 }
787 else 724 else
788 { 725 {
789 /* Attack the object. */ 726 /* Attack the object. */
1019/* This object will teleport someone to a different map 956/* This object will teleport someone to a different map
1020 and will also apply changes to the player from its inventory. 957 and will also apply changes to the player from its inventory.
1021 This was invented for giving classes, but there's no reason it 958 This was invented for giving classes, but there's no reason it
1022 can't be generalized. 959 can't be generalized.
1023*/ 960*/
1024
1025void 961void
1026move_player_changer (object *op) 962move_player_changer (object *op)
1027{ 963{
1028 object *player; 964 object *player;
1029 object *walk; 965 object *walk;
1030 char c;
1031 966
1032 if (!op->above || !EXIT_PATH (op)) 967 if (!op->above || !EXIT_PATH (op))
1033 return; 968 return;
1034 969
1035 /* This isn't all that great - means that the player_mover 970 /* This isn't all that great - means that the player_mover
1036 * needs to be on top. 971 * needs to be on top.
1037 */ 972 */
1038 if (op->above->type == PLAYER) 973 if (op->above->type == PLAYER)
1039 { 974 {
1040 if (INVOKE_OBJECT (TRIGGER, op, ARG_OBJECT (player))) 975 if (INVOKE_OBJECT (TRIGGER, op, ARG_OBJECT (player)))
1041 return; 976 return;
977
1042 player = op->above; 978 player = op->above;
1043 979
1044 for (walk = op->inv; walk != NULL; walk = walk->below) 980 for (walk = op->inv; walk; walk = walk->below)
1045 apply_changes_to_player (player, walk); 981 apply_changes_to_player (player, walk);
1046 982
1047 player->update_stats (); 983 player->update_stats ();
1048 984
1049 esrv_send_inventory (op->above, op->above); 985 esrv_send_inventory (op->above, op->above);
1050 esrv_update_item (UPD_FACE, op->above, op->above); 986 esrv_update_item (UPD_FACE, op->above, op->above);
1051 987
1052 /* update players death & WoR home-position */ 988 /* update players death & WoR home-position */
1053 sscanf (EXIT_PATH (op), "%c", &c); 989 if (*EXIT_PATH (op) == '/')
1054 if (c == '/')
1055 { 990 {
1056 strcpy (player->contr->savebed_map, EXIT_PATH (op)); 991 player->contr->savebed_map = EXIT_PATH (op);
1057 player->contr->bed_x = EXIT_X (op); 992 player->contr->bed_x = EXIT_X (op);
1058 player->contr->bed_y = EXIT_Y (op); 993 player->contr->bed_y = EXIT_Y (op);
1059 } 994 }
1060 else 995 else
1061 LOG (llevDebug, "WARNING: destination '%s' in player_changer must be an absolute path!\n", &EXIT_PATH (op)); 996 LOG (llevDebug, "WARNING: destination '%s' in player_changer must be an absolute path!\n", &EXIT_PATH (op));
1062 997
1063 op->above->enter_exit (op); 998 op->above->enter_exit (op);
1064 player->contr->save ();
1065 } 999 }
1066} 1000}
1067 1001
1068/* firewalls fire other spells. 1002/* firewalls fire other spells.
1069 * The direction of the wall is stored in op->stats.sp. 1003 * The direction of the wall is stored in op->stats.sp.
1207 return; 1141 return;
1208 } 1142 }
1209 1143
1210 if (op->above == NULL) 1144 if (op->above == NULL)
1211 return; 1145 return;
1146
1212 for (tmp = op->above; tmp != NULL; tmp = tmp->above) 1147 for (tmp = op->above; tmp; tmp = tmp->above)
1213 { 1148 {
1214 if (strcmp (op->other_arch->name, tmp->arch->name) == 0) 1149 if (op->other_arch->name == tmp->arch->name)
1215 { 1150 {
1216 if (op->level <= 0) 1151 if (op->level <= 0)
1217 tmp->destroy (); 1152 tmp->destroy ();
1218 else 1153 else
1219 { 1154 {
1310 with a specific code as the slaying field. 1245 with a specific code as the slaying field.
1311 At that time, it writes the contents of its own message 1246 At that time, it writes the contents of its own message
1312 field to the player. The marker will decrement hp to 1247 field to the player. The marker will decrement hp to
1313 0 and then delete itself every time it grants a mark. 1248 0 and then delete itself every time it grants a mark.
1314 unless hp was zero to start with, in which case it is infinite.*/ 1249 unless hp was zero to start with, in which case it is infinite.*/
1315
1316void 1250void
1317move_marker (object *op) 1251move_marker (object *op)
1318{ 1252{
1319 if (object *tmp = op->ms ().player ()) 1253 if (object *tmp = op->ms ().player ())
1320 { 1254 {
1321 object *tmp2; 1255 object *tmp2;
1322 1256
1323 /* remove an old force with a slaying field == op->name */ 1257 /* remove an old force with a slaying field == op->name */
1324 for (tmp2 = tmp->inv; tmp2; tmp2 = tmp2->below) 1258 for (tmp2 = tmp->inv; tmp2; tmp2 = tmp2->below)
1325 if (tmp2->type == FORCE && tmp2->slaying && !strcmp (tmp2->slaying, op->name)) 1259 if (tmp2->type == FORCE && tmp2->slaying && tmp2->slaying == op->name)
1326 { 1260 {
1327 tmp2->destroy (); 1261 tmp2->destroy ();
1328 break; 1262 break;
1329 } 1263 }
1330 1264
1331 /* cycle through his inventory to look for the MARK we want to 1265 /* cycle through his inventory to look for the MARK we want to
1332 * place 1266 * place
1333 */ 1267 */
1334 for (tmp2 = tmp->inv; tmp2; tmp2 = tmp2->below) 1268 for (tmp2 = tmp->inv; tmp2; tmp2 = tmp2->below)
1335 if (tmp2->type == FORCE && tmp2->slaying && !strcmp (tmp2->slaying, op->slaying)) 1269 if (tmp2->type == FORCE && tmp2->slaying && tmp2->slaying == op->slaying)
1336 break; 1270 break;
1337 1271
1338 /* if we didn't find our own MARK */ 1272 /* if we didn't find our own MARK */
1339 if (tmp2 == NULL) 1273 if (!tmp2)
1340 { 1274 {
1341 object *force = get_archetype (FORCE_NAME); 1275 object *force = get_archetype (FORCE_NAME);
1342 1276
1343 if (op->stats.food) 1277 if (op->stats.food)
1344 { 1278 {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines