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

Comparing deliantra/server/common/object.C (file contents):
Revision 1.312 by elmex, Sat Mar 20 00:42:08 2010 UTC vs.
Revision 1.320 by root, Wed Apr 7 19:54:44 2010 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 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 * Copyright (©) 2001,2007 Mark Wedel & Crossfire Development Team 5 * Copyright (©) 2001 Mark Wedel & Crossfire Development Team
6 * Copyright (©) 1992,2007 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.
574 } 574 }
575 575
576 this->owner = owner; 576 this->owner = owner;
577} 577}
578 578
579int
580object::slottype () const
581{
582 if (type == SKILL)
583 {
584 if (IS_COMBAT_SKILL (subtype)) return slot_combat;
585 if (IS_RANGED_SKILL (subtype)) return slot_ranged;
586 }
587 else
588 {
589 if (slot [body_combat].info) return slot_combat;
590 if (slot [body_range ].info) return slot_ranged;
591 }
592
593 return slot_none;
594}
595
596bool
597object::change_weapon (object *ob)
598{
599 if (current_weapon == ob)
600 return true;
601
602 if (chosen_skill)
603 chosen_skill->flag [FLAG_APPLIED] = false;
604
605 current_weapon = ob;
606 chosen_skill = !ob || ob->type == SKILL ? ob : find_skill_by_name (this, ob->skill);
607
608 if (chosen_skill)
609 chosen_skill->flag [FLAG_APPLIED] = true;
610
611 update_stats ();
612
613 if (ob)
614 {
615 // now check wether any body locations became invalid, in which case
616 // we cannot apply the weapon at the moment.
617 for (int i = 0; i < NUM_BODY_LOCATIONS; ++i)
618 if (slot[i].used < 0)
619 {
620 current_weapon = chosen_skill = 0;
621 update_stats ();
622
623 new_draw_info_format (NDI_UNIQUE, 0, this,
624 "You try to balance all your items at once, "
625 "but the %s is just too much for your body. "
626 "[You need to unapply some items first - use the 'body' command to see "
627 "how many items you cna wera on a specific body part.]", &ob->name);
628 return false;
629 }
630
631 //new_draw_info_format (NDI_UNIQUE, 0, this, "You switch to your %s.", &ob->name);
632 }
633 else
634 ;//new_draw_info_format (NDI_UNIQUE, 0, this, "You unwield your weapons.");
635
636 if (ob && !ob->flag [FLAG_APPLIED] && ob->type != SPELL)
637 {
638 LOG (llevError | logBacktrace, "%s changed to unapplied weapon %s",
639 &name, ob->debug_desc ());
640 return false;
641 }
642
643 return true;
644}
645
646/* Zero the key_values on op, decrementing the shared-string 579/* Zero the key_values on op, decrementing the shared-string
647 * refcounts and freeing the links. 580 * refcounts and freeing the links.
648 */ 581 */
649static void 582static void
650free_key_values (object *op) 583free_key_values (object *op)
1006 map->insert (op, x, y); 939 map->insert (op, x, y);
1007 } 940 }
1008 } 941 }
1009} 942}
1010 943
944/*
945 * Remove and free all objects in the inventory of the given object.
946 * Unlike destroy_inv, this assumes the *this is destroyed as well
947 * well, so we can (and have to!) take shortcuts.
948 */
949void
950object::destroy_inv_fast ()
951{
952 while (object *op = inv)
953 {
954 // remove from object the fast way
955 op->flag [FLAG_REMOVED] = true;
956 op->env = 0;
957 if ((inv = inv->below))
958 inv->above = 0;
959
960 // then destroy
961 op->destroy ();
962 }
963}
964
1011object *object::create () 965object *object::create ()
1012{ 966{
1013 object *op = new object; 967 object *op = new object;
1014 op->link (); 968 op->link ();
1015 return op; 969 return op;
1085 LOG (llevError | logBacktrace, "tried to destroy the tail of an object"); 1039 LOG (llevError | logBacktrace, "tried to destroy the tail of an object");
1086 head->destroy (); 1040 head->destroy ();
1087 return; 1041 return;
1088 } 1042 }
1089 1043
1090 destroy_inv (false); 1044 destroy_inv_fast ();
1091 1045
1092 if (is_head ()) 1046 if (is_head ())
1093 if (sound_destroy) 1047 if (sound_destroy)
1094 play_sound (sound_destroy); 1048 play_sound (sound_destroy);
1095 else if (flag [FLAG_MONSTER]) 1049 else if (flag [FLAG_MONSTER])
1149 below = 0; 1103 below = 0;
1150 env = 0; 1104 env = 0;
1151 1105
1152 if (pl && pl->is_player ()) 1106 if (pl && pl->is_player ())
1153 { 1107 {
1108 if (expect_false (pl->contr->combat_ob == this))
1109 {
1110 pl->apply (pl->contr->combat_ob, AP_UNAPPLY);
1111 pl->contr->combat_ob = 0;
1112 if (pl->contr->ranged_ob) pl->apply (pl->contr->ranged_ob);
1113 }
1114
1115 if (expect_false (pl->contr->ranged_ob == this))
1116 {
1117 pl->apply (pl->contr->ranged_ob, AP_UNAPPLY);
1118 pl->contr->ranged_ob = 0;
1119 if (pl->contr->combat_ob) pl->apply (pl->contr->combat_ob);
1120 }
1121
1154 pl->contr->queue_stats_update (); 1122 pl->contr->queue_stats_update ();
1155 1123
1156 if (glow_radius && pl->is_on_map ()) 1124 if (expect_false (glow_radius) && pl->is_on_map ())
1157 update_all_los (pl->map, pl->x, pl->y); 1125 update_all_los (pl->map, pl->x, pl->y);
1158 } 1126 }
1159 } 1127 }
1160 else if (map) 1128 else if (map)
1161 { 1129 {
1331 * Passing 0 for flag gives proper default values, so flag really only needs 1299 * Passing 0 for flag gives proper default values, so flag really only needs
1332 * to be set if special handling is needed. 1300 * to be set if special handling is needed.
1333 * 1301 *
1334 * Return value: 1302 * Return value:
1335 * new object if 'op' was merged with other object 1303 * new object if 'op' was merged with other object
1336 * NULL if 'op' was destroyed 1304 * NULL if there was an error (destroyed, blocked etc.)
1337 * just 'op' otherwise 1305 * just 'op' otherwise
1338 */ 1306 */
1339object * 1307object *
1340insert_ob_in_map (object *op, maptile *m, object *originator, int flag) 1308insert_ob_in_map (object *op, maptile *m, object *originator, int flag)
1341{ 1309{
2693 2661
2694 insert (force); 2662 insert (force);
2695 } 2663 }
2696} 2664}
2697 2665
2666void object::change_move_type (MoveType mt)
2667{
2668 if (move_type == mt)
2669 return;
2670
2671 if (is_on_map ())
2672 {
2673 // we are on the map, so handle move_on/off effects
2674 remove ();
2675 move_type = mt;
2676 map->insert (this, x, y, this);
2677 }
2678 else
2679 move_type = mt;
2680}
2681

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines