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.31 by root, Tue Jan 2 11:08:36 2007 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. */
1024void 961void
1025move_player_changer (object *op) 962move_player_changer (object *op)
1026{ 963{
1027 object *player; 964 object *player;
1028 object *walk; 965 object *walk;
1029 char c;
1030 966
1031 if (!op->above || !EXIT_PATH (op)) 967 if (!op->above || !EXIT_PATH (op))
1032 return; 968 return;
1033 969
1034 /* This isn't all that great - means that the player_mover 970 /* This isn't all that great - means that the player_mover
1035 * needs to be on top. 971 * needs to be on top.
1036 */ 972 */
1037 if (op->above->type == PLAYER) 973 if (op->above->type == PLAYER)
1038 { 974 {
1039 if (INVOKE_OBJECT (TRIGGER, op, ARG_OBJECT (player))) 975 if (INVOKE_OBJECT (TRIGGER, op, ARG_OBJECT (player)))
1040 return; 976 return;
977
1041 player = op->above; 978 player = op->above;
1042 979
1043 for (walk = op->inv; walk != NULL; walk = walk->below) 980 for (walk = op->inv; walk; walk = walk->below)
1044 apply_changes_to_player (player, walk); 981 apply_changes_to_player (player, walk);
1045 982
1046 player->update_stats (); 983 player->update_stats ();
1047 984
1048 esrv_send_inventory (op->above, op->above); 985 esrv_send_inventory (op->above, op->above);
1049 esrv_update_item (UPD_FACE, op->above, op->above); 986 esrv_update_item (UPD_FACE, op->above, op->above);
1050 987
1051 /* update players death & WoR home-position */ 988 /* update players death & WoR home-position */
1052 sscanf (EXIT_PATH (op), "%c", &c); 989 if (*EXIT_PATH (op) == '/')
1053 if (c == '/')
1054 { 990 {
1055 player->contr->savebed_map = EXIT_PATH (op); 991 player->contr->savebed_map = EXIT_PATH (op);
1056 player->contr->bed_x = EXIT_X (op); 992 player->contr->bed_x = EXIT_X (op);
1057 player->contr->bed_y = EXIT_Y (op); 993 player->contr->bed_y = EXIT_Y (op);
1058 } 994 }
1059 else 995 else
1060 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));
1061 997
1062 op->above->enter_exit (op); 998 op->above->enter_exit (op);
1063 player->contr->save ();
1064 } 999 }
1065} 1000}
1066 1001
1067/* firewalls fire other spells. 1002/* firewalls fire other spells.
1068 * The direction of the wall is stored in op->stats.sp. 1003 * The direction of the wall is stored in op->stats.sp.
1206 return; 1141 return;
1207 } 1142 }
1208 1143
1209 if (op->above == NULL) 1144 if (op->above == NULL)
1210 return; 1145 return;
1146
1211 for (tmp = op->above; tmp != NULL; tmp = tmp->above) 1147 for (tmp = op->above; tmp; tmp = tmp->above)
1212 { 1148 {
1213 if (strcmp (op->other_arch->name, tmp->arch->name) == 0) 1149 if (op->other_arch->name == tmp->arch->name)
1214 { 1150 {
1215 if (op->level <= 0) 1151 if (op->level <= 0)
1216 tmp->destroy (); 1152 tmp->destroy ();
1217 else 1153 else
1218 { 1154 {
1309 with a specific code as the slaying field. 1245 with a specific code as the slaying field.
1310 At that time, it writes the contents of its own message 1246 At that time, it writes the contents of its own message
1311 field to the player. The marker will decrement hp to 1247 field to the player. The marker will decrement hp to
1312 0 and then delete itself every time it grants a mark. 1248 0 and then delete itself every time it grants a mark.
1313 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.*/
1314
1315void 1250void
1316move_marker (object *op) 1251move_marker (object *op)
1317{ 1252{
1318 if (object *tmp = op->ms ().player ()) 1253 if (object *tmp = op->ms ().player ())
1319 { 1254 {
1320 object *tmp2; 1255 object *tmp2;
1321 1256
1322 /* remove an old force with a slaying field == op->name */ 1257 /* remove an old force with a slaying field == op->name */
1323 for (tmp2 = tmp->inv; tmp2; tmp2 = tmp2->below) 1258 for (tmp2 = tmp->inv; tmp2; tmp2 = tmp2->below)
1324 if (tmp2->type == FORCE && tmp2->slaying && !strcmp (tmp2->slaying, op->name)) 1259 if (tmp2->type == FORCE && tmp2->slaying && tmp2->slaying == op->name)
1325 { 1260 {
1326 tmp2->destroy (); 1261 tmp2->destroy ();
1327 break; 1262 break;
1328 } 1263 }
1329 1264
1330 /* 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
1331 * place 1266 * place
1332 */ 1267 */
1333 for (tmp2 = tmp->inv; tmp2; tmp2 = tmp2->below) 1268 for (tmp2 = tmp->inv; tmp2; tmp2 = tmp2->below)
1334 if (tmp2->type == FORCE && tmp2->slaying && !strcmp (tmp2->slaying, op->slaying)) 1269 if (tmp2->type == FORCE && tmp2->slaying && tmp2->slaying == op->slaying)
1335 break; 1270 break;
1336 1271
1337 /* if we didn't find our own MARK */ 1272 /* if we didn't find our own MARK */
1338 if (tmp2 == NULL) 1273 if (!tmp2)
1339 { 1274 {
1340 object *force = get_archetype (FORCE_NAME); 1275 object *force = get_archetype (FORCE_NAME);
1341 1276
1342 if (op->stats.food) 1277 if (op->stats.food)
1343 { 1278 {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines