--- deliantra/server/common/object.C 2011/05/01 16:58:15 1.345
+++ deliantra/server/common/object.C 2012/12/12 02:13:04 1.359
@@ -1,24 +1,24 @@
/*
* This file is part of Deliantra, the Roguelike Realtime MMORPG.
- *
- * Copyright (©) 2005,2006,2007,2008,2009,2010,2011 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
+ *
+ * Copyright (©) 2005,2006,2007,2008,2009,2010,2011,2012 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
* Copyright (©) 2001 Mark Wedel & Crossfire Development Team
* Copyright (©) 1992 Frank Tore Johansen
- *
+ *
* Deliantra is free software: you can redistribute it and/or modify it under
* the terms of the Affero 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.
- *
+ *
* You should have received a copy of the Affero GNU General Public License
* and the GNU General Public License along with this program. If not, see
* .
- *
+ *
* The authors can be reached via e-mail to
*/
@@ -353,15 +353,15 @@
*/
}
- /* Don't merge objects that are applied. With the new 'body' code,
+ /* Don't merge objects that are applied. With the new 'body' code,
* it is possible for most any character to have more than one of
* some items equipped, and we don't want those to merge.
*/
if (ob1->flag [FLAG_APPLIED] || ob2->flag [FLAG_APPLIED])
return 0;
- /* Note sure why the following is the case - either the object has to
- * be animated or have a very low speed. Is this an attempted monster
+ /* Not sure why the following is the case - either the object has to
+ * be animated or have a very low speed. Is this an attempted monster
* check?
*/
if (!ob1->flag [FLAG_ANIMATE] && ob1->has_active_speed ())
@@ -448,12 +448,13 @@
}
// adjust weight per container type ("of holding")
-static uint32
-weight_adjust_for (object *op, uint32 weight)
+static weight_t
+weight_adjust_for (object *op, weight_t weight)
{
- return op->type == CONTAINER
- ? weight - weight * op->stats.Str / 100
- : weight;
+ if (op->type == CONTAINER)
+ weight -= weight * op->stats.Str / 100;
+
+ return weight;
}
/*
@@ -461,22 +462,22 @@
* and also updates how much the environment(s) is/are carrying.
*/
static void
-adjust_weight (object *op, sint32 sub, sint32 add)
+adjust_weight (object *op, weight_t sub, weight_t add)
{
while (op)
{
- sint32 ocarrying = op->carrying;
+ weight_t carrying = (weight_t)op->carrying
+ - weight_adjust_for (op, sub)
+ + weight_adjust_for (op, add);
- op->carrying -= weight_adjust_for (op, sub);
- op->carrying += weight_adjust_for (op, add);
+ sub = op->carrying;
+ op->carrying = carrying;
+ add = op->carrying;
if (object *pl = op->visible_to ())
if (pl != op) // player is handled lazily
esrv_update_item (UPD_WEIGHT, pl, op);
- sub = ocarrying;
- add = op->carrying;
-
op = op->env;
}
}
@@ -489,7 +490,7 @@
void
object::update_weight ()
{
- sint32 sum = 0;
+ weight_t sum = 0;
for (object *op = inv; op; op = op->below)
{
@@ -637,7 +638,7 @@
/* copy the body_info to the body_used - this is only really
* need for monsters, but doesn't hurt to do it for everything.
* by doing so, when a monster is created, it has good starting
- * values for the body_used info, so when items are created
+ * values for the body_used info, so when items are created
* for it, they can be properly equipped.
*/
for (int i = NUM_BODY_LOCATIONS; i--; )
@@ -739,7 +740,7 @@
mapspace &m = op->ms ();
if (!(m.flags_ & P_UPTODATE))
- /* nop */;
+ m.update_up (); // nothing to do except copy up
else if (action == UP_OBJ_INSERT)
{
#if 0
@@ -770,7 +771,7 @@
else if (action == UP_OBJ_CHANGE || action == UP_OBJ_REMOVE)
m.invalidate ();
else if (action == UP_OBJ_FACE)
- /* Nothing to do for that case */ ;
+ m.update_up (); // nothing to do for that case, except copy up
else
LOG (llevError, "update_object called with invalid action: %d\n", action);
@@ -900,7 +901,7 @@
*/
if (!drop_to_ground
|| !map
- || map->in_memory != MAP_ACTIVE
+ || !map->linkable ()
|| map->no_drop
|| ms ().move_block == MOVE_ALL)
{
@@ -1007,25 +1008,6 @@
++free_count;
}
-static struct freed_map : maptile
-{
- freed_map ()
- : maptile (3, 3)
- {
- path = "";
- name = "/internal/freed_objects_map";
- no_drop = 1;
- no_reset = 1;
-
- in_memory = MAP_ACTIVE;
- }
-
- ~freed_map ()
- {
- destroy ();
- }
-} freed_map; // freed objects are moved here to avoid crashes
-
void
object::do_destroy ()
{
@@ -1201,9 +1183,6 @@
ms.invalidate ();
- if (map->in_memory == MAP_SAVING)
- return;
-
int check_walk_off = !flag [FLAG_NO_APPLY];
if (object *pl = ms.player ())
@@ -1604,9 +1583,9 @@
&& ms.volume () < m->max_volume))
return true;
- if (originator && originator->is_player ())
- originator->contr->failmsgf (
- "No matter how hard you try, you just cannot put the %s here H",
+ if (originator)
+ originator->failmsgf (
+ "No matter how hard you try, you just cannot put the %s here! H",
query_name ()
);
@@ -1630,7 +1609,7 @@
if (nrof > nr)
{
- sint64 oweight = total_weight ();
+ weight_t oweight = total_weight ();
nrof -= nr;
@@ -1724,15 +1703,15 @@
/* return the original object and remove inserted object
(client prefers the original object) */
- // carring must be 0 for mergable objects
- sint64 oweight = tmp->weight * tmp->nrof;
+ // carrying must be 0 for mergable objects
+ weight_t oweight = weight_t (tmp->weight) * tmp->nrof;
tmp->nrof += op->nrof;
if (object *pl = tmp->visible_to ())
esrv_update_item (UPD_NROF, pl, tmp);
- adjust_weight (this, oweight, tmp->weight * tmp->nrof);
+ adjust_weight (this, oweight, weight_t (tmp->weight) * tmp->nrof);
op->destroy ();
op = tmp;
@@ -2032,7 +2011,7 @@
find_free_spot (const object *ob, maptile *m, int x, int y, int start, int stop)
{
int altern[SIZEOFFREE];
- int index = 0, flag;
+ int index = 0;
for (int i = start; i < stop; i++)
{
@@ -2154,7 +2133,7 @@
int
find_dir (maptile *m, int x, int y, object *exclude)
{
- int max = SIZEOFFREE, mflags;
+ int max = SIZEOFFREE;
MoveType move_type;
if (exclude && exclude->head_ () != exclude)
@@ -2415,6 +2394,8 @@
!item->flag [FLAG_ALIVE] && !item->invisible && (who->is_player () || item->weight < who->weight / 3));
}
+//-GPL
+
/*
* create clone from object to another
*/
@@ -2637,6 +2618,8 @@
: region::default_region ();
}
+//+GPL
+
void
object::open_container (object *new_container)
{
@@ -2703,6 +2686,38 @@
// contr->ns->floorbox_reset ();
}
+//-GPL
+
+// prefetch some flat area around the player
+static void
+prefetch_surrounding_area (object *op, maptile *map, int range)
+{
+ for (maprect *rect = map->split_to_tiles (mapwalk_buf,
+ op->x - range , op->y - range ,
+ op->x + range + 1, op->y + range + 1);
+ rect->m;
+ ++rect)
+ {
+ rect->m->touch ();
+ rect->m->activate ();
+ }
+}
+
+// prefetch a generous area around the player, also up and down
+void
+object::prefetch_surrounding_maps ()
+{
+ prefetch_surrounding_area (this, map, 40);
+
+ if (maptile *m = map->tile_available (TILE_DOWN))
+ prefetch_surrounding_area (this, m, 20);
+
+ if (maptile *m = map->tile_available (TILE_UP))
+ prefetch_surrounding_area (this, m, 20);
+}
+
+//+GPL
+
object *
object::force_find (shstr_tmp name)
{
@@ -2716,8 +2731,6 @@
return 0;
}
-//-GPL
-
void
object::force_set_timer (int duration)
{