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.25 by root, Mon Sep 11 01:16:20 2006 UTC vs.
Revision 1.28 by root, Mon Sep 11 12:10:21 2006 UTC

1
2/*
3 * static char *rcsid_object_c =
4 * "$Id: object.C,v 1.25 2006/09/11 01:16:20 root Exp $";
5 */
6
7/* 1/*
8 CrossFire, A Multiplayer game for X-windows 2 CrossFire, A Multiplayer game for X-windows
9 3
10 Copyright (C) 2001 Mark Wedel & Crossfire Development Team 4 Copyright (C) 2001 Mark Wedel & Crossfire Development Team
11 Copyright (C) 1992 Frank Tore Johansen 5 Copyright (C) 1992 Frank Tore Johansen
29 23
30/* Eneq(@csd.uu.se): Added weight-modifiers in environment of objects. 24/* Eneq(@csd.uu.se): Added weight-modifiers in environment of objects.
31 sub/add_weight will transcend the environment updating the carrying 25 sub/add_weight will transcend the environment updating the carrying
32 variable. */ 26 variable. */
33#include <global.h> 27#include <global.h>
34#ifndef WIN32 /* ---win32 exclude headers */
35# include <stdio.h> 28#include <stdio.h>
36# include <sys/types.h> 29#include <sys/types.h>
37# include <sys/uio.h> 30#include <sys/uio.h>
38#endif /* win32 */
39#include <object.h> 31#include <object.h>
40#include <funcpoint.h> 32#include <funcpoint.h>
41#include <skills.h> 33#include <skills.h>
42#include <loader.h> 34#include <loader.h>
35
43int nrofallocobjects = 0; 36int nrofallocobjects = 0;
44 37
45object *objects; /* Pointer to the list of used objects */ 38object *objects; /* Pointer to the list of used objects */
46object *active_objects; /* List of active objects that need to be processed */ 39object *active_objects; /* List of active objects that need to be processed */
47 40
249/* 242/*
250 * sum_weight() is a recursive function which calculates the weight 243 * sum_weight() is a recursive function which calculates the weight
251 * an object is carrying. It goes through in figures out how much 244 * an object is carrying. It goes through in figures out how much
252 * containers are carrying, and sums it up. 245 * containers are carrying, and sums it up.
253 */ 246 */
254signed long 247long
255sum_weight (object *op) 248sum_weight (object *op)
256{ 249{
257 signed long sum; 250 long sum;
258 object *inv; 251 object *inv;
259 252
260 for (sum = 0, inv = op->inv; inv != NULL; inv = inv->below) 253 for (sum = 0, inv = op->inv; inv != NULL; inv = inv->below)
261 { 254 {
262 if (inv->inv) 255 if (inv->inv)
891 /* if the object is being removed, we can't make intelligent 884 /* if the object is being removed, we can't make intelligent
892 * decisions, because remove_ob can't really pass the object 885 * decisions, because remove_ob can't really pass the object
893 * that is being removed. 886 * that is being removed.
894 */ 887 */
895 else if (action == UP_OBJ_CHANGE || action == UP_OBJ_REMOVE) 888 else if (action == UP_OBJ_CHANGE || action == UP_OBJ_REMOVE)
896 {
897 update_now = 1; 889 update_now = 1;
898 }
899 else if (action == UP_OBJ_FACE) 890 else if (action == UP_OBJ_FACE)
900 {
901 /* Nothing to do for that case */ 891 /* Nothing to do for that case */;
902 }
903 else 892 else
904 {
905 LOG (llevError, "update_object called with invalid action: %d\n", action); 893 LOG (llevError, "update_object called with invalid action: %d\n", action);
906 }
907 894
908 if (update_now) 895 if (update_now)
909 { 896 {
910 SET_MAP_FLAGS (op->map, op->x, op->y, flags | P_NO_ERROR | P_NEED_UPDATE); 897 SET_MAP_FLAGS (op->map, op->x, op->y, flags | P_NO_ERROR | P_NEED_UPDATE);
911 update_position (op->map, op->x, op->y); 898 update_position (op->map, op->x, op->y);
1126 */ 1113 */
1127 1114
1128void 1115void
1129remove_ob (object *op) 1116remove_ob (object *op)
1130{ 1117{
1118 object *tmp, *last = NULL;
1131 object * 1119 object *otmp;
1132 tmp, * 1120
1133 last = NULL; 1121 tag_t tag;
1134 object *
1135 otmp;
1136 tag_t
1137 tag;
1138 int
1139 check_walk_off; 1122 int check_walk_off;
1140 mapstruct * 1123 mapstruct *m;
1141 m;
1142 sint16
1143 x,
1144 y;
1145 1124
1125 sint16 x, y;
1146 1126
1147 if (QUERY_FLAG (op, FLAG_REMOVED)) 1127 if (QUERY_FLAG (op, FLAG_REMOVED))
1148 { 1128 {
1149 dump_object (op); 1129 dump_object (op);
1150 LOG (llevError, "Trying to remove removed object.\n%s\n", errmsg); 1130 LOG (llevError, "Trying to remove removed object.\n%s\n", errmsg);
1159 * so is easily enough restarted without any real problems. 1139 * so is easily enough restarted without any real problems.
1160 * MSW 2001-07-01 1140 * MSW 2001-07-01
1161 */ 1141 */
1162 abort (); 1142 abort ();
1163 } 1143 }
1144
1164 if (op->more != NULL) 1145 if (op->more != NULL)
1165 remove_ob (op->more); 1146 remove_ob (op->more);
1166 1147
1167 SET_FLAG (op, FLAG_REMOVED); 1148 SET_FLAG (op, FLAG_REMOVED);
1168 1149
1237 else 1218 else
1238 SET_MAP_TOP (m, x, y, op->below); /* we were top, set new top */ 1219 SET_MAP_TOP (m, x, y, op->below); /* we were top, set new top */
1239 1220
1240 /* Relink the object below us, if there is one */ 1221 /* Relink the object below us, if there is one */
1241 if (op->below) 1222 if (op->below)
1242 {
1243 op->below->above = op->above; 1223 op->below->above = op->above;
1244 }
1245 else 1224 else
1246 { 1225 {
1247 /* Nothing below, which means we need to relink map object for this space 1226 /* Nothing below, which means we need to relink map object for this space
1248 * use translated coordinates in case some oddness with map tiling is 1227 * use translated coordinates in case some oddness with map tiling is
1249 * evident 1228 * evident
1254 LOG (llevError, "remove_ob: GET_MAP_OB does not return object to be removed even though it appears to be on the bottom?\n%s\n", 1233 LOG (llevError, "remove_ob: GET_MAP_OB does not return object to be removed even though it appears to be on the bottom?\n%s\n",
1255 errmsg); 1234 errmsg);
1256 dump_object (GET_MAP_OB (m, x, y)); 1235 dump_object (GET_MAP_OB (m, x, y));
1257 LOG (llevError, "%s\n", errmsg); 1236 LOG (llevError, "%s\n", errmsg);
1258 } 1237 }
1238
1259 SET_MAP_OB (m, x, y, op->above); /* goes on above it. */ 1239 SET_MAP_OB (m, x, y, op->above); /* goes on above it. */
1260 } 1240 }
1241
1261 op->above = NULL; 1242 op->above = NULL;
1262 op->below = NULL; 1243 op->below = NULL;
1263 1244
1264 if (op->map->in_memory == MAP_SAVING) 1245 if (op->map->in_memory == MAP_SAVING)
1265 return; 1246 return;
1266 1247
1267 tag = op->count; 1248 tag = op->count;
1268 check_walk_off = !QUERY_FLAG (op, FLAG_NO_APPLY); 1249 check_walk_off = !QUERY_FLAG (op, FLAG_NO_APPLY);
1250
1269 for (tmp = GET_MAP_OB (m, x, y); tmp != NULL; tmp = tmp->above) 1251 for (tmp = GET_MAP_OB (m, x, y); tmp != NULL; tmp = tmp->above)
1270 { 1252 {
1271 /* No point updating the players look faces if he is the object 1253 /* No point updating the players look faces if he is the object
1272 * being removed. 1254 * being removed.
1273 */ 1255 */
1281 if (tmp->container == op) 1263 if (tmp->container == op)
1282 { 1264 {
1283 CLEAR_FLAG (op, FLAG_APPLIED); 1265 CLEAR_FLAG (op, FLAG_APPLIED);
1284 tmp->container = NULL; 1266 tmp->container = NULL;
1285 } 1267 }
1268
1286 tmp->contr->socket.update_look = 1; 1269 tmp->contr->socket.update_look = 1;
1287 } 1270 }
1288 /* See if player moving off should effect something */ 1271 /* See if player moving off should effect something */
1289 if (check_walk_off && ((op->move_type & tmp->move_off) && (op->move_type & ~tmp->move_off & ~tmp->move_block) == 0)) 1272 if (check_walk_off && ((op->move_type & tmp->move_off) && (op->move_type & ~tmp->move_off & ~tmp->move_block) == 0))
1290 { 1273 {
1291
1292 move_apply (tmp, op, NULL); 1274 move_apply (tmp, op, NULL);
1275
1293 if (was_destroyed (op, tag)) 1276 if (was_destroyed (op, tag))
1294 { 1277 {
1295 LOG (llevError, "BUG: remove_ob(): name %s, archname %s destroyed " "leaving object\n", &tmp->name, &tmp->arch->name); 1278 LOG (llevError, "BUG: remove_ob(): name %s, archname %s destroyed " "leaving object\n", &tmp->name, &tmp->arch->name);
1296 } 1279 }
1297 } 1280 }
1298 1281
1299 /* Eneq(@csd.uu.se): Fixed this to skip tmp->above=tmp */ 1282 /* Eneq(@csd.uu.se): Fixed this to skip tmp->above=tmp */
1300 1283
1301 if (tmp->above == tmp) 1284 if (tmp->above == tmp)
1302 tmp->above = NULL; 1285 tmp->above = NULL;
1286
1303 last = tmp; 1287 last = tmp;
1304 } 1288 }
1289
1305 /* last == NULL of there are no objects on this space */ 1290 /* last == NULL of there are no objects on this space */
1306 if (last == NULL) 1291 if (last == NULL)
1307 { 1292 {
1308 /* set P_NEED_UPDATE, otherwise update_position will complain. In theory, 1293 /* set P_NEED_UPDATE, otherwise update_position will complain. In theory,
1309 * we could preserve the flags (GET_MAP_FLAGS), but update_position figures 1294 * we could preserve the flags (GET_MAP_FLAGS), but update_position figures
1316 else 1301 else
1317 update_object (last, UP_OBJ_REMOVE); 1302 update_object (last, UP_OBJ_REMOVE);
1318 1303
1319 if (QUERY_FLAG (op, FLAG_BLOCKSVIEW) || (op->glow_radius != 0)) 1304 if (QUERY_FLAG (op, FLAG_BLOCKSVIEW) || (op->glow_radius != 0))
1320 update_all_los (op->map, op->x, op->y); 1305 update_all_los (op->map, op->x, op->y);
1321
1322} 1306}
1323 1307
1324/* 1308/*
1325 * merge_ob(op,top): 1309 * merge_ob(op,top):
1326 * 1310 *
1438 1422
1439 if (op->more != NULL) 1423 if (op->more != NULL)
1440 { 1424 {
1441 /* The part may be on a different map. */ 1425 /* The part may be on a different map. */
1442 1426
1443 object *
1444 more = op->more; 1427 object *more = op->more;
1445 1428
1446 /* We really need the caller to normalize coordinates - if 1429 /* We really need the caller to normalize coordinates - if
1447 * we set the map, that doesn't work if the location is within 1430 * we set the map, that doesn't work if the location is within
1448 * a map and this is straddling an edge. So only if coordinate 1431 * a map and this is straddling an edge. So only if coordinate
1449 * is clear wrong do we normalize it. 1432 * is clear wrong do we normalize it.
1450 */ 1433 */
1451 if (OUT_OF_REAL_MAP (more->map, more->x, more->y)) 1434 if (OUT_OF_REAL_MAP (more->map, more->x, more->y))
1452 {
1453 more->map = get_map_from_coord (m, &more->x, &more->y); 1435 more->map = get_map_from_coord (m, &more->x, &more->y);
1454 }
1455 else if (!more->map) 1436 else if (!more->map)
1456 { 1437 {
1457 /* For backwards compatibility - when not dealing with tiled maps, 1438 /* For backwards compatibility - when not dealing with tiled maps,
1458 * more->map should always point to the parent. 1439 * more->map should always point to the parent.
1459 */ 1440 */
1462 1443
1463 if (insert_ob_in_map (more, more->map, originator, flag) == NULL) 1444 if (insert_ob_in_map (more, more->map, originator, flag) == NULL)
1464 { 1445 {
1465 if (!op->head) 1446 if (!op->head)
1466 LOG (llevError, "BUG: insert_ob_in_map(): inserting op->more killed op\n"); 1447 LOG (llevError, "BUG: insert_ob_in_map(): inserting op->more killed op\n");
1448
1467 return NULL; 1449 return NULL;
1468 } 1450 }
1469 } 1451 }
1470 1452
1471 CLEAR_FLAG (op, FLAG_REMOVED); 1453 CLEAR_FLAG (op, FLAG_REMOVED);
1536 1518
1537 while (top != NULL) 1519 while (top != NULL)
1538 { 1520 {
1539 if (QUERY_FLAG (top, FLAG_IS_FLOOR) || QUERY_FLAG (top, FLAG_OVERLAY_FLOOR)) 1521 if (QUERY_FLAG (top, FLAG_IS_FLOOR) || QUERY_FLAG (top, FLAG_OVERLAY_FLOOR))
1540 floor = top; 1522 floor = top;
1523
1541 if (QUERY_FLAG (top, FLAG_NO_PICK) && (top->move_type & (MOVE_FLY_LOW | MOVE_FLY_HIGH)) && !QUERY_FLAG (top, FLAG_IS_FLOOR)) 1524 if (QUERY_FLAG (top, FLAG_NO_PICK) && (top->move_type & (MOVE_FLY_LOW | MOVE_FLY_HIGH)) && !QUERY_FLAG (top, FLAG_IS_FLOOR))
1542 { 1525 {
1543 /* We insert above top, so we want this object below this */ 1526 /* We insert above top, so we want this object below this */
1544 top = top->below; 1527 top = top->below;
1545 break; 1528 break;
1546 } 1529 }
1530
1547 last = top; 1531 last = top;
1548 top = top->above; 1532 top = top->above;
1549 } 1533 }
1534
1550 /* Don't want top to be NULL, so set it to the last valid object */ 1535 /* Don't want top to be NULL, so set it to the last valid object */
1551 top = last; 1536 top = last;
1552 1537
1553 /* We let update_position deal with figuring out what the space 1538 /* We let update_position deal with figuring out what the space
1554 * looks like instead of lots of conditions here. 1539 * looks like instead of lots of conditions here.
1633 * of effect may be sufficient. 1618 * of effect may be sufficient.
1634 */ 1619 */
1635 if (MAP_DARKNESS (op->map) && (op->glow_radius != 0)) 1620 if (MAP_DARKNESS (op->map) && (op->glow_radius != 0))
1636 update_all_los (op->map, op->x, op->y); 1621 update_all_los (op->map, op->x, op->y);
1637 1622
1638
1639 /* updates flags (blocked, alive, no magic, etc) for this map space */ 1623 /* updates flags (blocked, alive, no magic, etc) for this map space */
1640 update_object (op, UP_OBJ_INSERT); 1624 update_object (op, UP_OBJ_INSERT);
1641
1642 1625
1643 /* Don't know if moving this to the end will break anything. However, 1626 /* Don't know if moving this to the end will break anything. However,
1644 * we want to have update_look set above before calling this. 1627 * we want to have update_look set above before calling this.
1645 * 1628 *
1646 * check_move_on() must be after this because code called from 1629 * check_move_on() must be after this because code called from
1996 */ 1979 */
1997 1980
1998int 1981int
1999check_move_on (object *op, object *originator) 1982check_move_on (object *op, object *originator)
2000{ 1983{
2001 object * 1984 object *tmp;
2002 tmp; 1985 tag_t tag;
2003 tag_t 1986 mapstruct *m = op->map;
2004 tag;
2005 mapstruct *
2006 m = op->map;
2007 int
2008 x = op->x, y = op->y; 1987 int x = op->x, y = op->y;
2009 MoveType 1988
2010 move_on, 1989 MoveType move_on, move_slow, move_block;
2011 move_slow,
2012 move_block;
2013 1990
2014 if (QUERY_FLAG (op, FLAG_NO_APPLY)) 1991 if (QUERY_FLAG (op, FLAG_NO_APPLY))
2015 return 0; 1992 return 0;
2016 1993
2017 tag = op->count; 1994 tag = op->count;
2047 * we don't need to check all of them. 2024 * we don't need to check all of them.
2048 */ 2025 */
2049 if ((tmp->move_type & MOVE_FLY_LOW) && QUERY_FLAG (tmp, FLAG_NO_PICK)) 2026 if ((tmp->move_type & MOVE_FLY_LOW) && QUERY_FLAG (tmp, FLAG_NO_PICK))
2050 break; 2027 break;
2051 } 2028 }
2029
2052 for (; tmp != NULL; tmp = tmp->below) 2030 for (; tmp; tmp = tmp->below)
2053 { 2031 {
2054 if (tmp == op) 2032 if (tmp == op)
2055 continue; /* Can't apply yourself */ 2033 continue; /* Can't apply yourself */
2056 2034
2057 /* Check to see if one of the movement types should be slowed down. 2035 /* Check to see if one of the movement types should be slowed down.
2064 { 2042 {
2065 if ((!op->move_type && tmp->move_slow & MOVE_WALK) || 2043 if ((!op->move_type && tmp->move_slow & MOVE_WALK) ||
2066 ((op->move_type & tmp->move_slow) && (op->move_type & ~tmp->move_slow & ~tmp->move_block) == 0)) 2044 ((op->move_type & tmp->move_slow) && (op->move_type & ~tmp->move_slow & ~tmp->move_block) == 0))
2067 { 2045 {
2068 2046
2069 float
2070 diff;
2071
2072 diff = tmp->move_slow_penalty * FABS (op->speed); 2047 float diff = tmp->move_slow_penalty * FABS (op->speed);
2048
2073 if (op->type == PLAYER) 2049 if (op->type == PLAYER)
2074 {
2075 if ((QUERY_FLAG (tmp, FLAG_IS_HILLY) && find_skill_by_number (op, SK_CLIMBING)) || 2050 if ((QUERY_FLAG (tmp, FLAG_IS_HILLY) && find_skill_by_number (op, SK_CLIMBING)) ||
2076 (QUERY_FLAG (tmp, FLAG_IS_WOODED) && find_skill_by_number (op, SK_WOODSMAN))) 2051 (QUERY_FLAG (tmp, FLAG_IS_WOODED) && find_skill_by_number (op, SK_WOODSMAN)))
2077 {
2078 diff /= 4.0; 2052 diff /= 4.0;
2079 } 2053
2080 }
2081 op->speed_left -= diff; 2054 op->speed_left -= diff;
2082 } 2055 }
2083 } 2056 }
2084 2057
2085 /* Basically same logic as above, except now for actual apply. */ 2058 /* Basically same logic as above, except now for actual apply. */
2086 if ((!op->move_type && tmp->move_on & MOVE_WALK) || 2059 if ((!op->move_type && tmp->move_on & MOVE_WALK) ||
2087 ((op->move_type & tmp->move_on) && (op->move_type & ~tmp->move_on & ~tmp->move_block) == 0)) 2060 ((op->move_type & tmp->move_on) && (op->move_type & ~tmp->move_on & ~tmp->move_block) == 0))
2088 { 2061 {
2089
2090 move_apply (tmp, op, originator); 2062 move_apply (tmp, op, originator);
2063
2091 if (was_destroyed (op, tag)) 2064 if (was_destroyed (op, tag))
2092 return 1; 2065 return 1;
2093 2066
2094 /* what the person/creature stepped onto has moved the object 2067 /* what the person/creature stepped onto has moved the object
2095 * someplace new. Don't process any further - if we did, 2068 * someplace new. Don't process any further - if we did,
2097 */ 2070 */
2098 if (op->map != m || op->x != x || op->y != y) 2071 if (op->map != m || op->x != x || op->y != y)
2099 return 0; 2072 return 0;
2100 } 2073 }
2101 } 2074 }
2075
2102 return 0; 2076 return 0;
2103} 2077}
2104 2078
2105/* 2079/*
2106 * present_arch(arch, map, x, y) searches for any objects with 2080 * present_arch(arch, map, x, y) searches for any objects with

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines