--- deliantra/server/common/object.C 2007/05/17 21:11:42 1.154 +++ deliantra/server/common/object.C 2007/08/01 01:07:42 1.169 @@ -1,25 +1,24 @@ /* - * CrossFire, A Multiplayer game + * This file is part of Crossfire TRT, the Roguelike Realtime MORPG. * - * Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team - * Copyright (C) 2001 Mark Wedel & Crossfire Development Team - * Copyright (C) 1992 Frank Tore Johansen + * 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 * - * This program is free software; you can redistribute it and/or modify + * 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 + * 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 + * 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 this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * The authors can be reached via e-mail at + * along with this program. If not, see . + * + * The authors can be reached via e-mail to */ /* Eneq(@csd.uu.se): Added weight-modifiers in environment of objects. @@ -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. */ @@ -497,8 +496,9 @@ update_stats (); new_draw_info_format (NDI_UNIQUE, 0, this, - "You try to balance your applied items all at once, but the %s is too much. " - "You need to unapply some items first.", &ob->name); + "You try to balance all your items at once, " + "but the %s is just too much for your body. " + "[You need to unapply some items first.]", &ob->name); return false; } @@ -938,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 @@ -961,6 +962,8 @@ if (destroy_inventory) destroy_inv (false); + play_sound (sound_die); + attachable::destroy (); } @@ -1117,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; } @@ -1182,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); @@ -1206,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); @@ -1238,7 +1236,7 @@ { assert (!op->flag [FLAG_FREED]); - object *tmp, *top, *floor = NULL; + object *top, *floor = NULL; op->remove (); @@ -1264,15 +1262,8 @@ } if (object *more = op->more) - { - if (!insert_ob_in_map (more, m, originator, flag)) - { - if (!op->head) - LOG (llevError, "BUG: insert_ob_in_map(): inserting op->more killed op\n"); - - return 0; - } - } + if (!insert_ob_in_map (more, m, originator, flag)) + return 0; CLEAR_FLAG (op, FLAG_REMOVED); @@ -1289,7 +1280,7 @@ /* this has to be done after we translate the coordinates. */ if (op->nrof && !(flag & INS_NO_MERGE)) - for (tmp = ms.bot; tmp; tmp = tmp->above) + for (object *tmp = ms.bot; tmp; tmp = tmp->above) if (object::can_merge (op, tmp)) { op->nrof += tmp->nrof; @@ -1388,7 +1379,6 @@ top = last->below; } } /* If objects on this space */ - if (flag & INS_MAP_LOAD) top = ms.top; @@ -1468,7 +1458,7 @@ */ /* if this is not the head or flag has been passed, don't check walk on status */ - if (!(flag & INS_NO_WALK_ON) && !op->head) + if (!(flag & INS_NO_WALK_ON) && op->head_ () == op) { if (check_move_on (op, originator)) return 0; @@ -1476,7 +1466,7 @@ /* If we are a multi part object, lets work our way through the check * walk on's. */ - for (tmp = op->more; tmp != NULL; tmp = tmp->more) + for (object *tmp = op->more; tmp; tmp = tmp->more) if (check_move_on (tmp, originator)) return 0; } @@ -1496,7 +1486,7 @@ /* first search for itself and remove any old instances */ for (tmp = op->ms ().bot; tmp; tmp = tmp->above) - if (!strcmp (tmp->arch->name, arch_string)) /* same archetype */ + if (!strcmp (tmp->arch->archname, arch_string)) /* same archetype */ tmp->destroy (); tmp1 = arch_to_object (archetype::find (arch_string)); @@ -2134,7 +2124,7 @@ MoveType blocked, move_type; - if (exclude && exclude->head) + if (exclude && exclude->head_ () != exclude) { exclude = exclude->head; move_type = exclude->move_type; @@ -2167,7 +2157,7 @@ { for (tmp = ms.bot; tmp; tmp = tmp->above) if ((tmp->flag [FLAG_MONSTER] || tmp->type == PLAYER) - && (tmp != exclude || (tmp->head && tmp->head != exclude))) + && (tmp != exclude || (tmp->head_ () != tmp && tmp->head_ () != exclude))) break; if (tmp) @@ -2372,17 +2362,15 @@ object * object_create_clone (object *asrc) { - object *dst = 0, *tmp, *src, *part, *prev, *item; + object *dst = 0, *tmp, *src, *prev, *item; if (!asrc) return 0; - src = asrc; - if (src->head) - src = src->head; + src = asrc->head_ (); prev = 0; - for (part = src; part; part = part->more) + for (object *part = src; part; part = part->more) { tmp = part->clone (); tmp->x -= src->x; @@ -2505,7 +2493,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 { @@ -2584,7 +2572,6 @@ item = item->env; } - const char * object::flag_desc (char *desc, int len) const { @@ -2656,13 +2643,10 @@ const materialtype_t * object::dominant_material () const { - if (materialtype_t *mat = name_to_material (materialname)) - return mat; + if (materialtype_t *mt = name_to_material (materialname)) + return mt; - // omfg this is slow, this has to be temporary :) - shstr unknown ("unknown"); - - return name_to_material (unknown); + return name_to_material (shstr_unknown); } void @@ -2716,4 +2700,41 @@ } } +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); +} + +void +object::play_sound (faceidx sound) const +{ + if (map) + map->play_sound (sound, x, y); +}