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.80 by root, Mon Sep 29 10:20:49 2008 UTC vs.
Revision 1.95 by root, Mon Oct 26 11:31:39 2009 UTC

3 * 3 *
4 * Copyright (©) 2005,2006,2007,2008 Marc Alexander Lehmann / Robin Redeker / the Deliantra team 4 * Copyright (©) 2005,2006,2007,2008 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team 5 * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team
6 * Copyright (©) 1992,2007 Frank Tore Johansen 6 * Copyright (©) 1992,2007 Frank Tore Johansen
7 * 7 *
8 * Deliantra is free software: you can redistribute it and/or modify 8 * Deliantra is free software: you can redistribute it and/or modify it under
9 * it under the terms of the GNU General Public License as published by 9 * the terms of the Affero GNU General Public License as published by the
10 * the Free Software Foundation, either version 3 of the License, or 10 * Free Software Foundation, either version 3 of the License, or (at your
11 * (at your 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 GNU General Public License 18 * You should have received a copy of the Affero GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>. 19 * and the GNU General Public License along with this program. If not, see
20 * <http://www.gnu.org/licenses/>.
20 * 21 *
21 * 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>
22 */ 23 */
23 24
24/* 25/*
57 tmp->map = op->map; 58 tmp->map = op->map;
58 tmp->level = op->level; 59 tmp->level = op->level;
59 insert_ob_in_map (tmp, op->map, op, 0); 60 insert_ob_in_map (tmp, op->map, op, 0);
60 } 61 }
61 62
62 op->destroy_inv (true); // be explicit about dropping 63 op->drop_and_destroy ();
63 op->destroy (true);
64} 64}
65 65
66void 66void
67remove_door2 (object *op) 67remove_door2 (object *op)
68{ 68{
87 tmp->map = op->map; 87 tmp->map = op->map;
88 tmp->level = op->level; 88 tmp->level = op->level;
89 insert_ob_in_map (tmp, op->map, op, 0); 89 insert_ob_in_map (tmp, op->map, op, 0);
90 } 90 }
91 91
92 op->destroy_inv (true); // be explicit about dropping 92 op->drop_and_destroy ();
93 op->destroy (true);
94} 93}
95 94
96void 95void
97generate_monster (object *gen) 96generate_monster (object *gen)
98{ 97{
99 if (!gen->map) 98 if (!gen->map)
100 return; 99 return;
101 100
102 if (GENERATE_SPEED (gen) && rndm (0, GENERATE_SPEED (gen) - 1)) 101 if (GENERATE_SPEED (gen) && rndm (0, GENERATE_SPEED (gen) - 1))
102 return;
103
104 // sleeping generators won't generate, this will make monsters like
105 // centipedes not generate more centipedes when being asleep.
106 if (gen->flag [FLAG_SLEEP])
103 return; 107 return;
104 108
105 object *op; 109 object *op;
106 int dir; 110 int dir;
107 111
151 create_treasure (op->randomitems, op, GT_APPLY, gen->map->difficulty); 155 create_treasure (op->randomitems, op, GT_APPLY, gen->map->difficulty);
152 156
153 return; 157 return;
154 } 158 }
155 159
156 op->destroy (true); 160 op->destroy ();
157} 161}
158 162
159void 163void
160remove_force (object *op) 164remove_force (object *op)
161{ 165{
173 CLEAR_FLAG (op, FLAG_APPLIED); 177 CLEAR_FLAG (op, FLAG_APPLIED);
174 change_abil (op->env, op); 178 change_abil (op->env, op);
175 op->env->update_stats (); 179 op->env->update_stats ();
176 } 180 }
177 181
178 op->destroy (true); 182 op->destroy ();
179} 183}
180 184
181void 185void
182remove_blindness (object *op) 186remove_blindness (object *op)
183{ 187{
190 { 194 {
191 change_abil (op->env, op); 195 change_abil (op->env, op);
192 op->env->update_stats (); 196 op->env->update_stats ();
193 } 197 }
194 198
195 op->destroy (true); 199 op->destroy ();
196} 200}
197 201
198void 202void
199poison_more (object *op) 203poison_more (object *op)
200{ 204{
201 if (op->env == NULL || !QUERY_FLAG (op->env, FLAG_ALIVE) || op->env->stats.hp < 0) 205 if (op->env == NULL || !QUERY_FLAG (op->env, FLAG_ALIVE) || op->env->stats.hp < 0)
202 { 206 {
203 op->destroy (true); 207 op->destroy ();
204 return; 208 return;
205 } 209 }
206 210
207 if (op->stats.food == 1) 211 if (op->stats.food == 1)
208 { 212 {
214 CLEAR_FLAG (op, FLAG_APPLIED); 218 CLEAR_FLAG (op, FLAG_APPLIED);
215 op->env->update_stats (); 219 op->env->update_stats ();
216 new_draw_info (NDI_UNIQUE, 0, op->env, "You feel much better now."); 220 new_draw_info (NDI_UNIQUE, 0, op->env, "You feel much better now.");
217 } 221 }
218 222
219 op->destroy (true); 223 op->destroy ();
220 return; 224 return;
221 } 225 }
222 226
223 if (op->env->type == PLAYER) 227 if (op->env->type == PLAYER)
224 { 228 {
439 if (op->stats.sp == 1) 443 if (op->stats.sp == 1)
440 { 444 {
441 if (detected && last == 0) 445 if (detected && last == 0)
442 { 446 {
443 op->value = 1; 447 op->value = 1;
444 push_button (op); 448 push_button (op, tmp);
445 } 449 }
446 450
447 if (!detected && last == 1) 451 if (!detected && last == 1)
448 { 452 {
449 op->value = 0; 453 op->value = 0;
450 push_button (op); 454 push_button (op, tmp);
451 } 455 }
452 } 456 }
453 else 457 else
454 { /* in this case, we unset buttons */ 458 { /* in this case, we unset buttons */
455 if (detected && last == 1) 459 if (detected && last == 1)
456 { 460 {
457 op->value = 0; 461 op->value = 0;
458 push_button (op); 462 push_button (op, tmp);
459 } 463 }
460 464
461 if (!detected && last == 0) 465 if (!detected && last == 0)
462 { 466 {
463 op->value = 1; 467 op->value = 1;
464 push_button (op); 468 push_button (op, tmp);
465 } 469 }
466 } 470 }
467} 471}
468 472
469void 473void
545 549
546 if (payload == NULL) 550 if (payload == NULL)
547 return NULL; 551 return NULL;
548 552
549 payload->remove (); 553 payload->remove ();
550 op->destroy (true); 554 op->destroy ();
551 return payload; 555 return payload;
552 } 556 }
553 557
554 case ARROW: 558 case ARROW:
555 if (op->has_active_speed ()) 559 if (op->has_active_speed ())
582fix_stopped_arrow (object *op) 586fix_stopped_arrow (object *op)
583{ 587{
584 if (rndm (0, 99) < op->stats.food) 588 if (rndm (0, 99) < op->stats.food)
585 { 589 {
586 /* Small chance of breaking */ 590 /* Small chance of breaking */
587 op->destroy (true); 591 op->destroy ();
588 return NULL; 592 return NULL;
589 } 593 }
590 594
591 op->set_speed (0); 595 op->set_speed (0);
592 op->direction = 0; 596 op->direction = 0;
596 600
597 // restore original wc, dam, attacktype and slaying 601 // restore original wc, dam, attacktype and slaying
598 op->stats.wc = op->stats.sp; 602 op->stats.wc = op->stats.sp;
599 op->stats.dam = op->stats.hp; 603 op->stats.dam = op->stats.hp;
600 op->attacktype = op->stats.grace; 604 op->attacktype = op->stats.grace;
605 op->slaying = op->custom_name;
601 606
602 if (op->spellarg)
603 {
604 op->slaying = op->spellarg;
605 free (op->spellarg);
606 op->spellarg = 0;
607 }
608 else
609 op->slaying = 0;
610
611 /* Reset these to zero, so that object::can_merge will work properly */ 607 /* Reset these to defaults, so that object::can_merge will work properly */
612 op->spellarg = NULL; 608 op->custom_name = 0;
613 op->stats.sp = 0; 609 op->stats.sp = 0;
614 op->stats.hp = 0; 610 op->stats.hp = 0;
615 op->stats.grace = 0; 611 op->stats.grace = 0;
616 op->level = 0; 612 op->level = 0;
617 op->face = op->arch->face; 613 op->face = op->arch->face;
618 op->owner = NULL; /* So that stopped arrows will be saved */ 614 op->owner = 0;
615
619 update_object (op, UP_OBJ_CHANGE); 616 update_object (op, UP_OBJ_CHANGE);
617
620 return op; 618 return op;
621} 619}
622 620
623/* stop_arrow() - what to do when a non-living flying object 621/* stop_arrow() - what to do when a non-living flying object
624 * has to stop. Sept 96 - I added in thrown object code in 622 * has to stop. Sept 96 - I added in thrown object code in
638 // replace this by straightforward drop to ground? 636 // replace this by straightforward drop to ground?
639 object *payload = op->inv; 637 object *payload = op->inv;
640 638
641 payload->owner = 0; 639 payload->owner = 0;
642 insert_ob_in_map (payload, op->map, payload, 0); 640 insert_ob_in_map (payload, op->map, payload, 0);
643 op->destroy (true); 641 op->destroy ();
644 } 642 }
645 else 643 else
646 { 644 {
647 op = fix_stopped_arrow (op); 645 op = fix_stopped_arrow (op);
648 646
659 int was_reflected; 657 int was_reflected;
660 658
661 if (!op->map) 659 if (!op->map)
662 { 660 {
663 LOG (llevError, "BUG: Arrow had no map.\n"); 661 LOG (llevError, "BUG: Arrow had no map.\n");
664 op->destroy (true); 662 op->destroy ();
665 return; 663 return;
666 } 664 }
667 665
668 /* we need to stop thrown objects at some point. Like here. */ 666 /* we need to stop thrown objects at some point. Like here. */
669 if (op->type == THROWN_OBJ) 667 if (op->type == THROWN_OBJ)
676 * bomb code, but there are potential other cases where that could happen, 674 * bomb code, but there are potential other cases where that could happen,
677 * and it is easy enough to clean it up here. 675 * and it is easy enough to clean it up here.
678 */ 676 */
679 if (!op->inv) 677 if (!op->inv)
680 { 678 {
681 op->destroy (true); 679 op->destroy ();
682 return; 680 return;
683 } 681 }
684 682
685 if (op->last_sp-- < 0) 683 if (op->last_sp-- < 0)
686 { 684 {
813 return; 811 return;
814 } 812 }
815 813
816 /* update object image for new facing */ 814 /* update object image for new facing */
817 /* many thrown objects *don't* have more than one face */ 815 /* many thrown objects *don't* have more than one face */
818 if (GET_ANIM_ID (op)) 816 if (op->has_anim ())
819 SET_ANIMATION (op, op->direction); 817 op->set_anim_frame (op->direction);
820 } /* object is reflected */ 818 } /* object is reflected */
821 } /* object ran into a wall */ 819 } /* object ran into a wall */
822 820
823 /* decrease the speed as it flies. 0.05 means a standard bow will shoot 821 /* decrease the speed as it flies. 0.05 means a standard bow will shoot
824 * about 17 squares. Tune as needed. 822 * about 17 squares. Tune as needed.
854 op->remove (); 852 op->remove ();
855 for (i = 0; i < op->stats.food; i++) 853 for (i = 0; i < op->stats.food; i++)
856 { 854 {
857 object *tmp = arch_to_object (op->other_arch); 855 object *tmp = arch_to_object (op->other_arch);
858 856
859 if (op->type == LAMP)
860 tmp->stats.food = op->stats.food - 1;
861
862 tmp->stats.hp = op->stats.hp; /* The only variable it keeps. */ 857 tmp->stats.hp = op->stats.hp; /* The only variable it keeps. */
863 858
864 if (env) 859 if (env)
865 env->insert (tmp); 860 env->insert (tmp);
866 else 861 else
867 { 862 {
868 j = find_first_free_spot (tmp, op->map, op->x, op->y); 863 j = find_first_free_spot (tmp, op->map, op->x, op->y);
869 if (j < 0) /* No free spot */ 864 if (j < 0) /* No free spot */
870 tmp->destroy (true); 865 tmp->destroy ();
871 else 866 else
872 { 867 {
873 mapxy pos (op); pos.move (j); 868 mapxy pos (op); pos.move (j);
874 869
875 if (pos.normalise ()) 870 if (pos.normalise ())
876 pos.insert (tmp, op); 871 pos.insert (tmp, op);
877 } 872 }
878 } 873 }
879 } 874 }
880 875
881 op->destroy (true); 876 op->destroy ();
882} 877}
883 878
884void 879void
885move_teleporter (object *op) 880move_teleporter (object *op)
886{ 881{
923 else if (EXIT_X (head) || EXIT_Y (head)) 918 else if (EXIT_X (head) || EXIT_Y (head))
924 { 919 {
925 if (out_of_map (head->map, EXIT_X (head), EXIT_Y (head))) 920 if (out_of_map (head->map, EXIT_X (head), EXIT_Y (head)))
926 { 921 {
927 LOG (llevError, "Removed illegal teleporter.\n"); 922 LOG (llevError, "Removed illegal teleporter.\n");
928 head->destroy (true); 923 head->destroy ();
929 return; 924 return;
930 } 925 }
931 926
932 if (INVOKE_OBJECT (TRIGGER, op, ARG_OBJECT (tmp))) 927 if (INVOKE_OBJECT (TRIGGER, op, ARG_OBJECT (tmp)))
933 return; 928 return;
1127 for (tmp = op->above; tmp; tmp = tmp->above) 1122 for (tmp = op->above; tmp; tmp = tmp->above)
1128 { 1123 {
1129 if (op->other_arch->archname == tmp->arch->archname) 1124 if (op->other_arch->archname == tmp->arch->archname)
1130 { 1125 {
1131 if (op->level <= 0) 1126 if (op->level <= 0)
1132 tmp->destroy (true); 1127 tmp->destroy ();
1133 else 1128 else
1134 { 1129 {
1135 uint64 new_nrof = (uint64) tmp->nrof * op->level; 1130 uint64 new_nrof = (uint64) tmp->nrof * op->level;
1136 1131
1137 if (new_nrof >= 1UL << 31) 1132 if (new_nrof >= 1UL << 31)
1167 { 1162 {
1168 creator->stats.hp = -1; 1163 creator->stats.hp = -1;
1169 return; 1164 return;
1170 } 1165 }
1171 1166
1172 if (creator->inv != NULL) 1167 if (creator->inv)
1173 { 1168 {
1174 object *ob; 1169 object *ob;
1175 int i; 1170 int i;
1176 object *ob_to_copy; 1171 object *ob_to_copy;
1177 1172
1202 } 1197 }
1203 1198
1204 /* Make sure this multipart object fits */ 1199 /* Make sure this multipart object fits */
1205 if (new_ob->arch->more && new_ob->blocked (creator->map, creator->x, creator->y)) 1200 if (new_ob->arch->more && new_ob->blocked (creator->map, creator->x, creator->y))
1206 { 1201 {
1207 op->destroy_inv (false); // remove when desttroy does this
1208 new_ob->destroy (true); 1202 new_ob->destroy ();
1209 return; 1203 return;
1210 } 1204 }
1211 1205
1212 // for now lets try to identify everything generated here, it mostly 1206 // for now lets try to identify everything generated here, it mostly
1213 // happens automated, so this will at least fix many identify-experience holes 1207 // happens automated, so this will at least fix many identify-experience holes
1234{ 1228{
1235 if (object *tmp = op->ms ().player ()) 1229 if (object *tmp = op->ms ().player ())
1236 { 1230 {
1237 /* remove an old force with a slaying field == op->name */ 1231 /* remove an old force with a slaying field == op->name */
1238 if (object *force = tmp->force_find (op->name)) 1232 if (object *force = tmp->force_find (op->name))
1239 force->destroy (true); 1233 force->destroy ();
1240 1234
1241 if (!tmp->force_find (op->slaying)) 1235 if (op->slaying && !tmp->force_find (op->slaying))
1242 { 1236 {
1243 tmp->force_add (op->slaying, op->stats.food); 1237 tmp->force_add (op->slaying, op->stats.food);
1244 1238
1245 if (op->msg) 1239 if (op->msg)
1246 new_draw_info (NDI_UNIQUE | NDI_NAVY, 0, tmp, op->msg); 1240 new_draw_info (NDI_UNIQUE | NDI_NAVY, 0, tmp, op->msg);
1250 op->stats.hp--; 1244 op->stats.hp--;
1251 1245
1252 if (op->stats.hp == 0) 1246 if (op->stats.hp == 0)
1253 { 1247 {
1254 /* marker expires--granted mark number limit */ 1248 /* marker expires--granted mark number limit */
1255 op->destroy (true); 1249 op->destroy ();
1256 return; 1250 return;
1257 } 1251 }
1258 } 1252 }
1259 } 1253 }
1260 } 1254 }
1255}
1256
1257// mapscript objects activate themselves (only) then their timer fires
1258// TODO: maybe they should simply trigger the link like any other object?
1259void
1260move_mapscript (object *op)
1261{
1262 op->set_speed (0);
1263 cfperl_mapscript_activate (op, true, op, 0);
1264}
1265
1266void move_lamp (object *op)
1267{
1268 // if the lamp/torch is off, we should disable it.
1269 if (!op->glow_radius)
1270 {
1271 op->set_speed (0);
1272 return;
1273 }
1274 else
1275 {
1276 // check whether the face might need to be updated
1277 // (currently this is needed to have already switched on torches
1278 // on maps, as they just set the glow_radius in the archetype)
1279 if (op->other_arch
1280 && (
1281 (op->flag [FLAG_ANIMATE] != op->other_arch->flag [FLAG_ANIMATE])
1282 || (op->flag [FLAG_ANIMATE]
1283 ? (op->animation_id != op->other_arch->animation_id)
1284 : (op->face != op->other_arch->face))
1285 ))
1286 get_animation_from_arch (op, op->other_arch);
1287 }
1288
1289 // lamps and torches on maps don't use up their fuel
1290 if (op->is_on_map ())
1291 return;
1292
1293 if (op->stats.food > 0)
1294 {
1295 op->stats.food--;
1296 return;
1297 }
1298
1299 apply_lamp (op, false);
1261} 1300}
1262 1301
1263void 1302void
1264process_object (object *op) 1303process_object (object *op)
1265{ 1304{
1305 op->remove (); // TODO: really necessary? 1344 op->remove (); // TODO: really necessary?
1306 1345
1307 if (QUERY_FLAG (op, FLAG_SEE_ANYWHERE)) 1346 if (QUERY_FLAG (op, FLAG_SEE_ANYWHERE))
1308 make_sure_not_seen (op); 1347 make_sure_not_seen (op);
1309 1348
1310 op->destroy_inv (false); // be explicit about dropping
1311 op->destroy (true); 1349 op->drop_and_destroy ();
1312 } 1350 }
1313 1351
1314 return; 1352 return;
1315 } 1353 }
1316 } 1354 }
1440 1478
1441 case PLAYER: 1479 case PLAYER:
1442 // players have their own speed-management, so undo the --speed_left 1480 // players have their own speed-management, so undo the --speed_left
1443 ++op->speed_left; 1481 ++op->speed_left;
1444 break; 1482 break;
1445 }
1446}
1447 1483
1484 case MAPSCRIPT:
1485 move_mapscript (op);
1486 break;
1487
1488 case LAMP:
1489 case TORCH:
1490 move_lamp (op);
1491 break;
1492 }
1493}
1494

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines