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.26 by root, Mon Sep 11 11:46:52 2006 UTC

1 1
2/* 2/*
3 * static char *rcsid_object_c = 3 * static char *rcsid_object_c =
4 * "$Id: object.C,v 1.25 2006/09/11 01:16:20 root Exp $"; 4 * "$Id: object.C,v 1.26 2006/09/11 11:46:52 root Exp $";
5 */ 5 */
6 6
7/* 7/*
8 CrossFire, A Multiplayer game for X-windows 8 CrossFire, A Multiplayer game for X-windows
9 9
1126 */ 1126 */
1127 1127
1128void 1128void
1129remove_ob (object *op) 1129remove_ob (object *op)
1130{ 1130{
1131 object *tmp, *last = NULL;
1131 object * 1132 object *otmp;
1132 tmp, * 1133
1133 last = NULL; 1134 tag_t tag;
1134 object *
1135 otmp;
1136 tag_t
1137 tag;
1138 int
1139 check_walk_off; 1135 int check_walk_off;
1140 mapstruct * 1136 mapstruct *m;
1141 m;
1142 sint16
1143 x,
1144 y;
1145 1137
1138 sint16 x, y;
1146 1139
1147 if (QUERY_FLAG (op, FLAG_REMOVED)) 1140 if (QUERY_FLAG (op, FLAG_REMOVED))
1148 { 1141 {
1149 dump_object (op); 1142 dump_object (op);
1150 LOG (llevError, "Trying to remove removed object.\n%s\n", errmsg); 1143 LOG (llevError, "Trying to remove removed object.\n%s\n", errmsg);
1159 * so is easily enough restarted without any real problems. 1152 * so is easily enough restarted without any real problems.
1160 * MSW 2001-07-01 1153 * MSW 2001-07-01
1161 */ 1154 */
1162 abort (); 1155 abort ();
1163 } 1156 }
1157
1164 if (op->more != NULL) 1158 if (op->more != NULL)
1165 remove_ob (op->more); 1159 remove_ob (op->more);
1166 1160
1167 SET_FLAG (op, FLAG_REMOVED); 1161 SET_FLAG (op, FLAG_REMOVED);
1168 1162
1237 else 1231 else
1238 SET_MAP_TOP (m, x, y, op->below); /* we were top, set new top */ 1232 SET_MAP_TOP (m, x, y, op->below); /* we were top, set new top */
1239 1233
1240 /* Relink the object below us, if there is one */ 1234 /* Relink the object below us, if there is one */
1241 if (op->below) 1235 if (op->below)
1242 {
1243 op->below->above = op->above; 1236 op->below->above = op->above;
1244 }
1245 else 1237 else
1246 { 1238 {
1247 /* Nothing below, which means we need to relink map object for this space 1239 /* 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 1240 * use translated coordinates in case some oddness with map tiling is
1249 * evident 1241 * 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", 1246 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); 1247 errmsg);
1256 dump_object (GET_MAP_OB (m, x, y)); 1248 dump_object (GET_MAP_OB (m, x, y));
1257 LOG (llevError, "%s\n", errmsg); 1249 LOG (llevError, "%s\n", errmsg);
1258 } 1250 }
1251
1259 SET_MAP_OB (m, x, y, op->above); /* goes on above it. */ 1252 SET_MAP_OB (m, x, y, op->above); /* goes on above it. */
1260 } 1253 }
1254
1261 op->above = NULL; 1255 op->above = NULL;
1262 op->below = NULL; 1256 op->below = NULL;
1263 1257
1264 if (op->map->in_memory == MAP_SAVING) 1258 if (op->map->in_memory == MAP_SAVING)
1265 return; 1259 return;
1266 1260
1267 tag = op->count; 1261 tag = op->count;
1268 check_walk_off = !QUERY_FLAG (op, FLAG_NO_APPLY); 1262 check_walk_off = !QUERY_FLAG (op, FLAG_NO_APPLY);
1263
1269 for (tmp = GET_MAP_OB (m, x, y); tmp != NULL; tmp = tmp->above) 1264 for (tmp = GET_MAP_OB (m, x, y); tmp != NULL; tmp = tmp->above)
1270 { 1265 {
1271 /* No point updating the players look faces if he is the object 1266 /* No point updating the players look faces if he is the object
1272 * being removed. 1267 * being removed.
1273 */ 1268 */
1281 if (tmp->container == op) 1276 if (tmp->container == op)
1282 { 1277 {
1283 CLEAR_FLAG (op, FLAG_APPLIED); 1278 CLEAR_FLAG (op, FLAG_APPLIED);
1284 tmp->container = NULL; 1279 tmp->container = NULL;
1285 } 1280 }
1281
1286 tmp->contr->socket.update_look = 1; 1282 tmp->contr->socket.update_look = 1;
1287 } 1283 }
1288 /* See if player moving off should effect something */ 1284 /* 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)) 1285 if (check_walk_off && ((op->move_type & tmp->move_off) && (op->move_type & ~tmp->move_off & ~tmp->move_block) == 0))
1290 { 1286 {
1291
1292 move_apply (tmp, op, NULL); 1287 move_apply (tmp, op, NULL);
1288
1293 if (was_destroyed (op, tag)) 1289 if (was_destroyed (op, tag))
1294 { 1290 {
1295 LOG (llevError, "BUG: remove_ob(): name %s, archname %s destroyed " "leaving object\n", &tmp->name, &tmp->arch->name); 1291 LOG (llevError, "BUG: remove_ob(): name %s, archname %s destroyed " "leaving object\n", &tmp->name, &tmp->arch->name);
1296 } 1292 }
1297 } 1293 }
1298 1294
1299 /* Eneq(@csd.uu.se): Fixed this to skip tmp->above=tmp */ 1295 /* Eneq(@csd.uu.se): Fixed this to skip tmp->above=tmp */
1300 1296
1301 if (tmp->above == tmp) 1297 if (tmp->above == tmp)
1302 tmp->above = NULL; 1298 tmp->above = NULL;
1299
1303 last = tmp; 1300 last = tmp;
1304 } 1301 }
1302
1305 /* last == NULL of there are no objects on this space */ 1303 /* last == NULL of there are no objects on this space */
1306 if (last == NULL) 1304 if (last == NULL)
1307 { 1305 {
1308 /* set P_NEED_UPDATE, otherwise update_position will complain. In theory, 1306 /* set P_NEED_UPDATE, otherwise update_position will complain. In theory,
1309 * we could preserve the flags (GET_MAP_FLAGS), but update_position figures 1307 * we could preserve the flags (GET_MAP_FLAGS), but update_position figures
1316 else 1314 else
1317 update_object (last, UP_OBJ_REMOVE); 1315 update_object (last, UP_OBJ_REMOVE);
1318 1316
1319 if (QUERY_FLAG (op, FLAG_BLOCKSVIEW) || (op->glow_radius != 0)) 1317 if (QUERY_FLAG (op, FLAG_BLOCKSVIEW) || (op->glow_radius != 0))
1320 update_all_los (op->map, op->x, op->y); 1318 update_all_los (op->map, op->x, op->y);
1321
1322} 1319}
1323 1320
1324/* 1321/*
1325 * merge_ob(op,top): 1322 * merge_ob(op,top):
1326 * 1323 *
1438 1435
1439 if (op->more != NULL) 1436 if (op->more != NULL)
1440 { 1437 {
1441 /* The part may be on a different map. */ 1438 /* The part may be on a different map. */
1442 1439
1443 object *
1444 more = op->more; 1440 object *more = op->more;
1445 1441
1446 /* We really need the caller to normalize coordinates - if 1442 /* We really need the caller to normalize coordinates - if
1447 * we set the map, that doesn't work if the location is within 1443 * 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 1444 * a map and this is straddling an edge. So only if coordinate
1449 * is clear wrong do we normalize it. 1445 * is clear wrong do we normalize it.
1450 */ 1446 */
1451 if (OUT_OF_REAL_MAP (more->map, more->x, more->y)) 1447 if (OUT_OF_REAL_MAP (more->map, more->x, more->y))
1452 {
1453 more->map = get_map_from_coord (m, &more->x, &more->y); 1448 more->map = get_map_from_coord (m, &more->x, &more->y);
1454 }
1455 else if (!more->map) 1449 else if (!more->map)
1456 { 1450 {
1457 /* For backwards compatibility - when not dealing with tiled maps, 1451 /* For backwards compatibility - when not dealing with tiled maps,
1458 * more->map should always point to the parent. 1452 * more->map should always point to the parent.
1459 */ 1453 */
1462 1456
1463 if (insert_ob_in_map (more, more->map, originator, flag) == NULL) 1457 if (insert_ob_in_map (more, more->map, originator, flag) == NULL)
1464 { 1458 {
1465 if (!op->head) 1459 if (!op->head)
1466 LOG (llevError, "BUG: insert_ob_in_map(): inserting op->more killed op\n"); 1460 LOG (llevError, "BUG: insert_ob_in_map(): inserting op->more killed op\n");
1461
1467 return NULL; 1462 return NULL;
1468 } 1463 }
1469 } 1464 }
1470 1465
1471 CLEAR_FLAG (op, FLAG_REMOVED); 1466 CLEAR_FLAG (op, FLAG_REMOVED);
1536 1531
1537 while (top != NULL) 1532 while (top != NULL)
1538 { 1533 {
1539 if (QUERY_FLAG (top, FLAG_IS_FLOOR) || QUERY_FLAG (top, FLAG_OVERLAY_FLOOR)) 1534 if (QUERY_FLAG (top, FLAG_IS_FLOOR) || QUERY_FLAG (top, FLAG_OVERLAY_FLOOR))
1540 floor = top; 1535 floor = top;
1536
1541 if (QUERY_FLAG (top, FLAG_NO_PICK) && (top->move_type & (MOVE_FLY_LOW | MOVE_FLY_HIGH)) && !QUERY_FLAG (top, FLAG_IS_FLOOR)) 1537 if (QUERY_FLAG (top, FLAG_NO_PICK) && (top->move_type & (MOVE_FLY_LOW | MOVE_FLY_HIGH)) && !QUERY_FLAG (top, FLAG_IS_FLOOR))
1542 { 1538 {
1543 /* We insert above top, so we want this object below this */ 1539 /* We insert above top, so we want this object below this */
1544 top = top->below; 1540 top = top->below;
1545 break; 1541 break;
1546 } 1542 }
1543
1547 last = top; 1544 last = top;
1548 top = top->above; 1545 top = top->above;
1549 } 1546 }
1547
1550 /* Don't want top to be NULL, so set it to the last valid object */ 1548 /* Don't want top to be NULL, so set it to the last valid object */
1551 top = last; 1549 top = last;
1552 1550
1553 /* We let update_position deal with figuring out what the space 1551 /* We let update_position deal with figuring out what the space
1554 * looks like instead of lots of conditions here. 1552 * looks like instead of lots of conditions here.
1633 * of effect may be sufficient. 1631 * of effect may be sufficient.
1634 */ 1632 */
1635 if (MAP_DARKNESS (op->map) && (op->glow_radius != 0)) 1633 if (MAP_DARKNESS (op->map) && (op->glow_radius != 0))
1636 update_all_los (op->map, op->x, op->y); 1634 update_all_los (op->map, op->x, op->y);
1637 1635
1638
1639 /* updates flags (blocked, alive, no magic, etc) for this map space */ 1636 /* updates flags (blocked, alive, no magic, etc) for this map space */
1640 update_object (op, UP_OBJ_INSERT); 1637 update_object (op, UP_OBJ_INSERT);
1641
1642 1638
1643 /* Don't know if moving this to the end will break anything. However, 1639 /* 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. 1640 * we want to have update_look set above before calling this.
1645 * 1641 *
1646 * check_move_on() must be after this because code called from 1642 * check_move_on() must be after this because code called from
1996 */ 1992 */
1997 1993
1998int 1994int
1999check_move_on (object *op, object *originator) 1995check_move_on (object *op, object *originator)
2000{ 1996{
2001 object * 1997 object *tmp;
2002 tmp; 1998 tag_t tag;
2003 tag_t 1999 mapstruct *m = op->map;
2004 tag;
2005 mapstruct *
2006 m = op->map;
2007 int
2008 x = op->x, y = op->y; 2000 int x = op->x, y = op->y;
2009 MoveType 2001
2010 move_on, 2002 MoveType move_on, move_slow, move_block;
2011 move_slow,
2012 move_block;
2013 2003
2014 if (QUERY_FLAG (op, FLAG_NO_APPLY)) 2004 if (QUERY_FLAG (op, FLAG_NO_APPLY))
2015 return 0; 2005 return 0;
2016 2006
2017 tag = op->count; 2007 tag = op->count;
2047 * we don't need to check all of them. 2037 * we don't need to check all of them.
2048 */ 2038 */
2049 if ((tmp->move_type & MOVE_FLY_LOW) && QUERY_FLAG (tmp, FLAG_NO_PICK)) 2039 if ((tmp->move_type & MOVE_FLY_LOW) && QUERY_FLAG (tmp, FLAG_NO_PICK))
2050 break; 2040 break;
2051 } 2041 }
2042
2052 for (; tmp != NULL; tmp = tmp->below) 2043 for (; tmp; tmp = tmp->below)
2053 { 2044 {
2054 if (tmp == op) 2045 if (tmp == op)
2055 continue; /* Can't apply yourself */ 2046 continue; /* Can't apply yourself */
2056 2047
2057 /* Check to see if one of the movement types should be slowed down. 2048 /* Check to see if one of the movement types should be slowed down.
2064 { 2055 {
2065 if ((!op->move_type && tmp->move_slow & MOVE_WALK) || 2056 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)) 2057 ((op->move_type & tmp->move_slow) && (op->move_type & ~tmp->move_slow & ~tmp->move_block) == 0))
2067 { 2058 {
2068 2059
2069 float
2070 diff;
2071
2072 diff = tmp->move_slow_penalty * FABS (op->speed); 2060 float diff = tmp->move_slow_penalty * FABS (op->speed);
2061
2073 if (op->type == PLAYER) 2062 if (op->type == PLAYER)
2074 {
2075 if ((QUERY_FLAG (tmp, FLAG_IS_HILLY) && find_skill_by_number (op, SK_CLIMBING)) || 2063 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))) 2064 (QUERY_FLAG (tmp, FLAG_IS_WOODED) && find_skill_by_number (op, SK_WOODSMAN)))
2077 {
2078 diff /= 4.0; 2065 diff /= 4.0;
2079 } 2066
2080 }
2081 op->speed_left -= diff; 2067 op->speed_left -= diff;
2082 } 2068 }
2083 } 2069 }
2084 2070
2085 /* Basically same logic as above, except now for actual apply. */ 2071 /* Basically same logic as above, except now for actual apply. */
2086 if ((!op->move_type && tmp->move_on & MOVE_WALK) || 2072 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)) 2073 ((op->move_type & tmp->move_on) && (op->move_type & ~tmp->move_on & ~tmp->move_block) == 0))
2088 { 2074 {
2089
2090 move_apply (tmp, op, originator); 2075 move_apply (tmp, op, originator);
2076
2091 if (was_destroyed (op, tag)) 2077 if (was_destroyed (op, tag))
2092 return 1; 2078 return 1;
2093 2079
2094 /* what the person/creature stepped onto has moved the object 2080 /* what the person/creature stepped onto has moved the object
2095 * someplace new. Don't process any further - if we did, 2081 * someplace new. Don't process any further - if we did,
2097 */ 2083 */
2098 if (op->map != m || op->x != x || op->y != y) 2084 if (op->map != m || op->x != x || op->y != y)
2099 return 0; 2085 return 0;
2100 } 2086 }
2101 } 2087 }
2088
2102 return 0; 2089 return 0;
2103} 2090}
2104 2091
2105/* 2092/*
2106 * present_arch(arch, map, x, y) searches for any objects with 2093 * present_arch(arch, map, x, y) searches for any objects with

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines