--- deliantra/server/common/map.C 2007/10/04 11:48:06 1.131
+++ deliantra/server/common/map.C 2008/12/23 01:51:27 1.152
@@ -1,11 +1,11 @@
/*
- * This file is part of Crossfire TRT, the Roguelike Realtime MORPG.
+ * This file is part of Deliantra, the Roguelike Realtime MMORPG.
*
- * Copyright (©) 2005,2006,2007 Marc Alexander Lehmann / Robin Redeker / the Crossfire TRT team
+ * Copyright (©) 2005,2006,2007,2008 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
* Copyright (©) 2001-2003,2007 Mark Wedel & Crossfire Development Team
* Copyright (©) 1992,2007 Frank Tore Johansen
*
- * Crossfire TRT is free software: you can redistribute it and/or modify
+ * Deliantra 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.
@@ -18,18 +18,17 @@
* 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
+ * The authors can be reached via e-mail to
*/
#include
#include "global.h"
-#include "funcpoint.h"
-
#include "loader.h"
-
#include "path.h"
+sint8 maptile::outdoor_darkness;
+
/* This rolls up wall, blocks_magic, blocks_view, etc, all into
* one function that just returns a P_.. value (see map.h)
* it will also do map translation for tiled maps, returning
@@ -247,10 +246,9 @@
tmp = next;
}
- /* sum_weight will go through and calculate what all the containers are
- * carrying.
- */
- sum_weight (container);
+ // go through and calculate what all the containers are carrying.
+ //TODO: remove
+ container->update_weight ();
}
void
@@ -264,6 +262,19 @@
tmp->flag [flag] = value;
}
+void
+maptile::post_load_original ()
+{
+ if (!spaces)
+ return;
+
+ set_object_flag (FLAG_OBJ_ORIGINAL);
+
+ for (mapspace *ms = spaces + size (); ms-- > spaces; )
+ for (object *tmp = ms->bot; tmp; tmp = tmp->above)
+ INVOKE_OBJECT (RESET, tmp);
+}
+
/* link_multipart_objects go through all the objects on the map looking
* for objects whose arch says they are multipart yet according to the
* info we have, they only have the head (as would be expected when
@@ -309,15 +320,16 @@
{
for (;;)
{
- coroapi::cede_to_tick_every (100); // cede once in a while
+ coroapi::cede_to_tick (); // cede once in a while
switch (f.kw)
{
case KW_arch:
if (object *op = object::read (f, this))
{
+ // TODO: why?
if (op->inv)
- sum_weight (op);
+ op->update_weight ();
if (IN_RANGE_EXC (op->x, 0, width) && IN_RANGE_EXC (op->y, 0, height))
{
@@ -644,6 +656,7 @@
case KW_per_player: thawer.get (per_player); break;
case KW_per_party: thawer.get (per_party); break;
case KW_no_reset: thawer.get (no_reset); break;
+ case KW_no_drop: thawer.get (no_drop); break;
case KW_region: default_region = region::find (thawer.get_str ()); break;
case KW_shopitems: shopitems = parse_shop_string (thawer.get_str ()); break;
@@ -703,10 +716,7 @@
unique = 1;
if (op->head_ () == op && (QUERY_FLAG (op, FLAG_UNIQUE) || unique))
- {
- op->destroy_inv (false);
- op->destroy ();
- }
+ op->destroy ();
op = above;
}
@@ -727,6 +737,7 @@
MAP_OUT (reset_timeout);
MAP_OUT (fixed_resettime);
MAP_OUT (no_reset);
+ MAP_OUT (no_drop);
MAP_OUT (difficulty);
if (default_region) MAP_OUT2 (region, default_region->name);
@@ -803,10 +814,7 @@
object *head = op->head_ ();
if (op == head)
- {
- op->destroy_inv (false);
- op->destroy ();
- }
+ op->destroy ();
else if (head->map != op->map)
{
LOG (llevDebug, "bad luck for object crossing map borders: %s", head->debug_desc ());
@@ -814,13 +822,13 @@
}
}
- sfree (spaces, size ()), spaces = 0;
+ sfree0 (spaces, size ());
}
if (buttons)
free_objectlinkpt (buttons), buttons = 0;
- sfree (regions, size ()); regions = 0;
+ sfree0 (regions, size ());
delete [] regionmap; regionmap = 0;
}
@@ -984,10 +992,17 @@
{
total_exp += op->stats.exp;
- if (archetype *at = type_to_archetype (GENERATE_TYPE (op)))
- total_exp += at->stats.exp * 8;
+ if (archetype *at = op->other_arch)
+ {
+ total_exp += at->stats.exp * 8;
+ monster_cnt++;
+ }
- monster_cnt++;
+ for (object *inv = op->inv; inv; inv = inv->below)
+ {
+ total_exp += op->stats.exp * 8;
+ monster_cnt++;
+ }
}
}
@@ -1036,6 +1051,7 @@
/* All clients need to get re-updated for the change */
update_all_map_los (this);
+
return 1;
}
@@ -1048,8 +1064,9 @@
void
mapspace::update_ ()
{
- object *tmp, *last = 0;
- uint8 flags = P_UPTODATE, light = 0, anywhere = 0;
+ object *last = 0;
+ uint8 flags = P_UPTODATE, anywhere = 0;
+ sint8 light = 0;
MoveType move_block = 0, move_slow = 0, move_on = 0, move_off = 0, move_allow = 0;
//object *middle = 0;
@@ -1060,15 +1077,10 @@
object *&middle = faces_obj[1] = 0;
object *&floor = faces_obj[2] = 0;
- for (tmp = bot; tmp; last = tmp, tmp = tmp->above)
+ for (object *tmp = bot; tmp; last = tmp, tmp = tmp->above)
{
- /* This could be made additive I guess (two lights better than
- * one). But if so, it shouldn't be a simple additive - 2
- * light bulbs do not illuminate twice as far as once since
- * it is a dissapation factor that is cubed.
- */
- if (tmp->glow_radius > light)
- light = tmp->glow_radius;
+ // Lights are additive, up to MAX_LIGHT_RADIUS, see los.C)
+ light += tmp->glow_radius;
/* This call is needed in order to update objects the player
* is standing in that have animations (ie, grass, fire, etc).
@@ -1097,6 +1109,7 @@
middle = tmp;
anywhere = 1;
}
+
/* Find the highest visible face around. If equal
* visibilities, we still want the one nearer to the
* top
@@ -1125,7 +1138,7 @@
if (QUERY_FLAG (tmp, FLAG_DAMNED)) flags |= P_NO_CLERIC;
}
- this->light = light;
+ this->light = min (light, MAX_LIGHT_RADIUS);
this->flags_ = flags;
this->move_block = move_block & ~move_allow;
this->move_on = move_on;
@@ -1155,7 +1168,7 @@
* 3) neither middle or top is set - need to set both.
*/
- for (tmp = last; tmp; tmp = tmp->below)
+ for (object *tmp = last; tmp; tmp = tmp->below)
{
/* Once we get to a floor, stop, since we already have a floor object */
if (QUERY_FLAG (tmp, FLAG_IS_FLOOR))
@@ -1223,7 +1236,7 @@
if (!tile_path[dir])
return 0;
- if (tile_map[dir] && (!load || tile_map[dir]->in_memory == MAP_IN_MEMORY))
+ if (tile_map[dir] && (!load || tile_map[dir]->in_memory == MAP_ACTIVE))
return 1;
if ((tile_map[dir] = find_async (tile_path[dir], this, load)))
@@ -1568,9 +1581,6 @@
object *
maptile::insert (object *op, int x, int y, object *originator, int flags)
{
- if (!op->flag [FLAG_REMOVED])
- op->remove ();
-
return insert_ob_in_map_at (op, this, originator, flags, x, y);
}
@@ -1590,11 +1600,9 @@
}
/* picks a random object from a style map.
- * Redone by MSW so it should be faster and not use static
- * variables to generate tables.
*/
object *
-maptile::pick_random_object () const
+maptile::pick_random_object (rand_gen &gen) const
{
/* while returning a null object will result in a crash, that
* is actually preferable to an infinite loop. That is because
@@ -1604,15 +1612,15 @@
*/
for (int i = 1000; --i;)
{
- object *pick = at (rndm (width), rndm (height)).bot;
+ object *pick = at (gen (width), gen (height)).bot;
// do not prefer big monsters just because they are big.
- if (pick && pick->head_ () == pick)
+ if (pick && pick->is_head ())
return pick->head_ ();
}
// instead of crashing in the unlikely(?) case, try to return *something*
- return get_archetype ("blocked");
+ return archetype::find ("bug");
}
void
@@ -1621,17 +1629,16 @@
if (!sound)
return;
- for_all_players (pl)
- if (pl->ob->map == this)
- if (client *ns = pl->ns)
- {
- int dx = x - pl->ob->x;
- int dy = y - pl->ob->y;
+ for_all_players_on_map (pl, this)
+ if (client *ns = pl->ns)
+ {
+ int dx = x - pl->ob->x;
+ int dy = y - pl->ob->y;
- int distance = idistance (dx, dy);
+ int distance = idistance (dx, dy);
- if (distance <= MAX_SOUND_DISTANCE)
- ns->play_sound (sound, dx, dy);
- }
+ if (distance <= MAX_SOUND_DISTANCE)
+ ns->play_sound (sound, dx, dy);
+ }
}