--- deliantra/server/common/object.C 2007/06/04 12:19:08 1.158 +++ deliantra/server/common/object.C 2007/08/12 13:10:00 1.177 @@ -1,23 +1,22 @@ /* - * This file is part of Crossfire TRT, the Multiplayer Online Role Playing Game. + * This file is part of Crossfire TRT, the Roguelike Realtime MORPG. * * Copyright (©) 2005,2006,2007 Marc Alexander Lehmann / Robin Redeker / the Crossfire TRT team * Copyright (©) 2001,2007 Mark Wedel & Crossfire Development Team * Copyright (©) 1992,2007 Frank Tore Johansen * - * Crossfire TRT is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. + * Crossfire TRT is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with Crossfire TRT; if not, write to the Free Software Foundation, Inc. 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . * * The authors can be reached via e-mail to */ @@ -302,14 +301,14 @@ return 0; } - //TODO: generate an event or call into perl for additional checks if (ob1->self || ob2->self) { ob1->optimise (); ob2->optimise (); if (ob1->self || ob2->self) - return 0; + if (!cfperl_can_merge (ob1, ob2)) + return 0; } /* Everything passes, must be OK. */ @@ -939,18 +938,19 @@ y = 1; } - head = 0; - if (more) { more->destroy (); more = 0; } - // clear those pointers that likely might have circular references to us - owner = 0; - enemy = 0; - attacked_by = 0; + head = 0; + + // clear those pointers that likely might cause circular references + owner = 0; + enemy = 0; + attacked_by = 0; + current_weapon = 0; } void @@ -962,6 +962,12 @@ if (destroy_inventory) destroy_inv (false); + if (is_head ()) + if (sound_destroy) + play_sound (sound_destroy); + else if (flag [FLAG_MONSTER]) + play_sound (sound_find ("monster_destroy")); // quick hack, too lazy to create a generic mechanism + attachable::destroy (); } @@ -1085,28 +1091,24 @@ int check_walk_off = !flag [FLAG_NO_APPLY]; + if (object *pl = ms.player ()) + { + if (pl->container == this) + /* If a container that the player is currently using somehow gets + * removed (most likely destroyed), update the player view + * appropriately. + */ + pl->close_container (); + + pl->contr->ns->floorbox_update (); + } + for (tmp = ms.bot; tmp; tmp = tmp->above) { /* No point updating the players look faces if he is the object * being removed. */ - if (tmp->type == PLAYER && tmp != this) - { - /* If a container that the player is currently using somehow gets - * removed (most likely destroyed), update the player view - * appropriately. - */ - if (tmp->container == this) - { - flag [FLAG_APPLIED] = 0; - tmp->container = 0; - } - - if (tmp->contr->ns) - tmp->contr->ns->floorbox_update (); - } - /* See if object moving off should effect something */ if (check_walk_off && ((move_type & tmp->move_off) @@ -1118,11 +1120,6 @@ LOG (llevError, "BUG: remove_ob(): name %s, destroyed leaving object\n", tmp->debug_desc ()); } - /* Eneq(@csd.uu.se): Fixed this to skip tmp->above=tmp */ - //TODO: why is this horrible hacka fix? get rid of this code=bug! (schmorp) - if (tmp->above == tmp) - tmp->above = 0; - last = tmp; } @@ -1183,7 +1180,7 @@ object *prev = this; - for (archetype *at = arch->more; at; at = at->more) + for (archetype *at = (archetype *)arch->more; at; at = (archetype *)at->more) { object *op = arch_to_object (at); @@ -1207,8 +1204,8 @@ { for (object *tmp = op->head_ (); tmp; tmp = tmp->more) { - tmp->x = x + tmp->arch->clone.x; - tmp->y = y + tmp->arch->clone.y; + tmp->x = x + tmp->arch->x; + tmp->y = y + tmp->arch->y; } return insert_ob_in_map (op, m, originator, flag); @@ -1382,7 +1379,6 @@ top = last->below; } } /* If objects on this space */ - if (flag & INS_MAP_LOAD) top = ms.top; @@ -1432,8 +1428,7 @@ */ if (!(flag & INS_MAP_LOAD)) if (object *pl = ms.player ()) - if (pl->contr->ns) - pl->contr->ns->floorbox_update (); + pl->contr->ns->floorbox_update (); /* If this object glows, it may affect lighting conditions that are * visible to others on this map. But update_all_los is really @@ -2351,7 +2346,6 @@ * * Add a check so we can't pick up invisible objects (0.93.8) */ - int can_pick (const object *who, const object *item) { @@ -2497,7 +2491,7 @@ * it, we save the empty value so that when we load, * we get this value back again. */ - if (get_ob_key_link (&op->arch->clone, canonical_key)) + if (get_ob_key_link (op->arch, canonical_key)) field->value = 0; else { @@ -2576,7 +2570,6 @@ item = item->env; } - const char * object::flag_desc (char *desc, int len) const { @@ -2648,13 +2641,10 @@ const materialtype_t * object::dominant_material () const { - if (materialtype_t *mat = name_to_material (materialname)) - return mat; - - // omfg this is slow, this has to be temporary :) - shstr unknown ("unknown"); + if (materialtype_t *mt = name_to_material (materialname)) + return mt; - return name_to_material (unknown); + return name_to_material (shstr_unknown); } void @@ -2680,6 +2670,7 @@ esrv_update_item (UPD_FLAGS, this, old_container); new_draw_info_format (NDI_UNIQUE, 0, this, "You close %s.", query_name (old_container)); + play_sound (sound_find ("chest_close")); } if (new_container) @@ -2705,7 +2696,39 @@ esrv_update_item (UPD_FLAGS, this, new_container); esrv_send_inventory (this, new_container); + play_sound (sound_find ("chest_open")); } } +object * +object::force_find (const shstr name) +{ + /* cycle through his inventory to look for the MARK we want to + * place + */ + for (object *tmp = inv; tmp; tmp = tmp->below) + if (tmp->type == FORCE && tmp->slaying == name) + return splay (tmp); + + return 0; +} + +void +object::force_add (const shstr name, int duration) +{ + if (object *force = force_find (name)) + force->destroy (); + + object *force = get_archetype (FORCE_NAME); + + force->slaying = name; + force->stats.food = 1; + force->speed_left = -1.f; + + force->set_speed (duration ? 1.f / duration : 0.f); + force->flag [FLAG_IS_USED_UP] = true; + force->flag [FLAG_APPLIED] = true; + + insert (force); +}