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.28 by root, Mon Sep 11 12:10:21 2006 UTC vs.
Revision 1.29 by root, Mon Sep 11 12:38:36 2006 UTC

1
1/* 2/*
2 CrossFire, A Multiplayer game for X-windows 3 CrossFire, A Multiplayer game for X-windows
3 4
4 Copyright (C) 2001 Mark Wedel & Crossfire Development Team 5 Copyright (C) 2001 Mark Wedel & Crossfire Development Team
5 Copyright (C) 1992 Frank Tore Johansen 6 Copyright (C) 1992 Frank Tore Johansen
207 if (!QUERY_FLAG (ob1, FLAG_ANIMATE) && FABS ((ob1)->speed) > MIN_ACTIVE_SPEED) 208 if (!QUERY_FLAG (ob1, FLAG_ANIMATE) && FABS ((ob1)->speed) > MIN_ACTIVE_SPEED)
208 return 0; 209 return 0;
209 210
210 switch (ob1->type) 211 switch (ob1->type)
211 { 212 {
212 case SCROLL: 213 case SCROLL:
213 if (ob1->level != ob2->level) 214 if (ob1->level != ob2->level)
214 return 0; 215 return 0;
215 break; 216 break;
216 } 217 }
217 218
218 if (ob1->key_values != NULL || ob2->key_values != NULL) 219 if (ob1->key_values != NULL || ob2->key_values != NULL)
219 { 220 {
220 /* At least one of these has key_values. */ 221 /* At least one of these has key_values. */
886 * that is being removed. 887 * that is being removed.
887 */ 888 */
888 else if (action == UP_OBJ_CHANGE || action == UP_OBJ_REMOVE) 889 else if (action == UP_OBJ_CHANGE || action == UP_OBJ_REMOVE)
889 update_now = 1; 890 update_now = 1;
890 else if (action == UP_OBJ_FACE) 891 else if (action == UP_OBJ_FACE)
891 /* Nothing to do for that case */; 892 /* Nothing to do for that case */ ;
892 else 893 else
893 LOG (llevError, "update_object called with invalid action: %d\n", action); 894 LOG (llevError, "update_object called with invalid action: %d\n", action);
894 895
895 if (update_now) 896 if (update_now)
896 { 897 {
900 901
901 if (op->more != NULL) 902 if (op->more != NULL)
902 update_object (op->more, action); 903 update_object (op->more, action);
903} 904}
904 905
905static unordered_vector<object *> mortals; 906static unordered_vector < object *>mortals;
906static std::vector<object *> freed; 907static
908std::vector < object *>
909 freed;
907 910
908void object::free_mortals () 911void object::free_mortals ()
909{ 912{
910 for (unordered_vector<object *>::iterator i = mortals.begin (); i != mortals.end (); ) 913 for (unordered_vector < object *>::iterator i = mortals.begin (); i != mortals.end ();)
911 if (!(*i)->refcount) 914 if (!(*i)->refcount)
912 { 915 {
913 freed.push_back (*i); 916 freed.push_back (*i);
914 mortals.erase (i); 917 mortals.erase (i);
915 } 918 }
965 objects = next; 968 objects = next;
966} 969}
967 970
968object *object::create () 971object *object::create ()
969{ 972{
970 object *op; 973 object *
974 op;
971 975
972 if (freed.empty ()) 976 if (freed.empty ())
973 op = new object; 977 op = new object;
978
974 else 979 else
975 { 980 {
976 // highly annoying, but the only way to get it stable right now 981 // highly annoying, but the only way to get it stable right now
977 op = freed.back (); freed.pop_back (); 982 op = freed.back ();
983 freed.pop_back ();
978 op->~object (); 984 op->~object ();
979 new ((void *)op) object; 985 new ((void *) op) object;
980 } 986 }
981 987
982 op->link (); 988 op->link ();
983 return op; 989 return op;
984} 990}
993 * If free_inventory is set, free inventory as well. Else drop items in 999 * If free_inventory is set, free inventory as well. Else drop items in
994 * inventory to the ground. 1000 * inventory to the ground.
995 */ 1001 */
996void object::free (bool free_inventory) 1002void object::free (bool free_inventory)
997{ 1003{
1004 if (QUERY_FLAG (this, FLAG_FREED))
1005 return;
1006
998 if (!QUERY_FLAG (this, FLAG_REMOVED)) 1007 if (!QUERY_FLAG (this, FLAG_REMOVED))
999 { 1008 remove_ob (this);
1000 LOG (llevDebug, "Free object called with non removed object\n");
1001 dump_object (this);
1002#ifdef MANY_CORES
1003 abort ();
1004#endif
1005 }
1006 1009
1007 if (QUERY_FLAG (this, FLAG_FRIENDLY)) 1010 if (QUERY_FLAG (this, FLAG_FRIENDLY))
1008 {
1009 LOG (llevMonster, "Warning: tried to free friendly object.\n");
1010 remove_friendly_object (this); 1011 remove_friendly_object (this);
1011 }
1012 1012
1013 if (QUERY_FLAG (this, FLAG_FREED)) 1013 SET_FLAG (this, FLAG_FREED);
1014 {
1015 dump_object (this);
1016 LOG (llevError, "Trying to free freed object.\n%s\n", errmsg);
1017 return;
1018 }
1019 1014
1020 if (more) 1015 if (more)
1021 { 1016 {
1022 more->free (free_inventory); 1017 more->free (free_inventory);
1023 more = 0; 1018 more = 0;
1029 * if some form of movement is allowed, let objects 1024 * if some form of movement is allowed, let objects
1030 * drop on that space. 1025 * drop on that space.
1031 */ 1026 */
1032 if (free_inventory || !map || map->in_memory != MAP_IN_MEMORY || (GET_MAP_MOVE_BLOCK (map, x, y) == MOVE_ALL)) 1027 if (free_inventory || !map || map->in_memory != MAP_IN_MEMORY || (GET_MAP_MOVE_BLOCK (map, x, y) == MOVE_ALL))
1033 { 1028 {
1034 object * 1029 object *op = inv;
1035 op = inv;
1036 1030
1037 while (op) 1031 while (op)
1038 { 1032 {
1039 object *
1040 tmp = op->below; 1033 object *tmp = op->below;
1041
1042 remove_ob (op);
1043 op->free (free_inventory); 1034 op->free (free_inventory);
1044 op = tmp; 1035 op = tmp;
1045 } 1036 }
1046 } 1037 }
1047 else 1038 else
1048 { /* Put objects in inventory onto this space */ 1039 { /* Put objects in inventory onto this space */
1049 object * 1040 object *op = inv;
1050 op = inv;
1051 1041
1052 while (op) 1042 while (op)
1053 { 1043 {
1054 object *
1055 tmp = op->below; 1044 object *tmp = op->below;
1056 1045
1057 remove_ob (op); 1046 remove_ob (op);
1058 1047
1059 if (QUERY_FLAG (op, FLAG_STARTEQUIP) 1048 if (QUERY_FLAG (op, FLAG_STARTEQUIP)
1060 || QUERY_FLAG (op, FLAG_NO_DROP) || op->type == RUNE || op->type == TRAP || QUERY_FLAG (op, FLAG_IS_A_TEMPLATE)) 1049 || QUERY_FLAG (op, FLAG_NO_DROP) || op->type == RUNE || op->type == TRAP || QUERY_FLAG (op, FLAG_IS_A_TEMPLATE))
1077 speed = 0; 1066 speed = 0;
1078 update_ob_speed (this); 1067 update_ob_speed (this);
1079 1068
1080 unlink (); 1069 unlink ();
1081 1070
1082 SET_FLAG (this, FLAG_FREED);
1083
1084 mortals.push_back (this); 1071 mortals.push_back (this);
1085} 1072}
1086 1073
1087/* 1074/*
1088 * sub_weight() recursively (outwards) subtracts a number from the 1075 * sub_weight() recursively (outwards) subtracts a number from the
1113 */ 1100 */
1114 1101
1115void 1102void
1116remove_ob (object *op) 1103remove_ob (object *op)
1117{ 1104{
1118 object *tmp, *last = NULL;
1119 object *otmp; 1105 object *
1106 tmp, *
1107 last = NULL;
1108 object *
1109 otmp;
1120 1110
1121 tag_t tag; 1111 tag_t
1112 tag;
1113 int
1122 int check_walk_off; 1114 check_walk_off;
1123 mapstruct *m; 1115 mapstruct *
1116 m;
1124 1117
1125 sint16 x, y; 1118 sint16
1119 x,
1120 y;
1126 1121
1127 if (QUERY_FLAG (op, FLAG_REMOVED)) 1122 if (QUERY_FLAG (op, FLAG_REMOVED))
1128 { 1123 return;
1129 dump_object (op);
1130 LOG (llevError, "Trying to remove removed object.\n%s\n", errmsg);
1131 1124
1132 /* Changed it to always dump core in this case. As has been learned 1125 SET_FLAG (op, FLAG_REMOVED);
1133 * in the past, trying to recover from errors almost always
1134 * make things worse, and this is a real error here - something
1135 * that should not happen.
1136 * Yes, if this was a mission critical app, trying to do something
1137 * to recover may make sense, but that is because failure of the app
1138 * may have other disastrous problems. Cf runs out of a script
1139 * so is easily enough restarted without any real problems.
1140 * MSW 2001-07-01
1141 */
1142 abort ();
1143 }
1144 1126
1145 if (op->more != NULL) 1127 if (op->more != NULL)
1146 remove_ob (op->more); 1128 remove_ob (op->more);
1147
1148 SET_FLAG (op, FLAG_REMOVED);
1149 1129
1150 /* 1130 /*
1151 * In this case, the object to be removed is in someones 1131 * In this case, the object to be removed is in someones
1152 * inventory. 1132 * inventory.
1153 */ 1133 */
1179 */ 1159 */
1180 op->x = op->env->x, op->y = op->env->y; 1160 op->x = op->env->x, op->y = op->env->y;
1181 op->map = op->env->map; 1161 op->map = op->env->map;
1182 op->above = NULL, op->below = NULL; 1162 op->above = NULL, op->below = NULL;
1183 op->env = NULL; 1163 op->env = NULL;
1184 return; 1164 }
1165 else if (op->map)
1185 } 1166 {
1186
1187 /* If we get here, we are removing it from a map */
1188 if (op->map == NULL)
1189 return;
1190
1191 x = op->x; 1167 x = op->x;
1192 y = op->y; 1168 y = op->y;
1193 m = get_map_from_coord (op->map, &x, &y); 1169 m = get_map_from_coord (op->map, &x, &y);
1194 1170
1195 if (!m) 1171 if (!m)
1196 { 1172 {
1197 LOG (llevError, "remove_ob called when object was on map but appears to not be within valid coordinates? %s (%d,%d)\n", 1173 LOG (llevError, "remove_ob called when object was on map but appears to not be within valid coordinates? %s (%d,%d)\n",
1198 op->map->path, op->x, op->y); 1174 op->map->path, op->x, op->y);
1199 /* in old days, we used to set x and y to 0 and continue. 1175 /* in old days, we used to set x and y to 0 and continue.
1200 * it seems if we get into this case, something is probablye 1176 * it seems if we get into this case, something is probablye
1201 * screwed up and should be fixed. 1177 * screwed up and should be fixed.
1178 */
1179 abort ();
1180 }
1181
1182 if (op->map != m)
1183 LOG (llevDebug, "remove_ob: Object not really on map it claimed to be on? %s != %s, %d,%d != %d,%d\n",
1184 op->map->path, m->path, op->x, op->y, x, y);
1185
1186 /* Re did the following section of code - it looks like it had
1187 * lots of logic for things we no longer care about
1202 */ 1188 */
1203 abort ();
1204 }
1205 if (op->map != m)
1206 {
1207 LOG (llevDebug, "remove_ob: Object not really on map it claimed to be on? %s != %s, %d,%d != %d,%d\n",
1208 op->map->path, m->path, op->x, op->y, x, y);
1209 }
1210 1189
1211 /* Re did the following section of code - it looks like it had
1212 * lots of logic for things we no longer care about
1213 */
1214
1215 /* link the object above us */ 1190 /* link the object above us */
1216 if (op->above) 1191 if (op->above)
1217 op->above->below = op->below; 1192 op->above->below = op->below;
1218 else 1193 else
1219 SET_MAP_TOP (m, x, y, op->below); /* we were top, set new top */ 1194 SET_MAP_TOP (m, x, y, op->below); /* we were top, set new top */
1220 1195
1221 /* Relink the object below us, if there is one */ 1196 /* Relink the object below us, if there is one */
1222 if (op->below) 1197 if (op->below)
1223 op->below->above = op->above; 1198 op->below->above = op->above;
1224 else 1199 else
1225 { 1200 {
1226 /* Nothing below, which means we need to relink map object for this space 1201 /* Nothing below, which means we need to relink map object for this space
1227 * use translated coordinates in case some oddness with map tiling is 1202 * use translated coordinates in case some oddness with map tiling is
1228 * evident 1203 * evident
1229 */
1230 if (GET_MAP_OB (m, x, y) != op)
1231 {
1232 dump_object (op);
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",
1234 errmsg);
1235 dump_object (GET_MAP_OB (m, x, y));
1236 LOG (llevError, "%s\n", errmsg);
1237 }
1238
1239 SET_MAP_OB (m, x, y, op->above); /* goes on above it. */
1240 }
1241
1242 op->above = NULL;
1243 op->below = NULL;
1244
1245 if (op->map->in_memory == MAP_SAVING)
1246 return;
1247
1248 tag = op->count;
1249 check_walk_off = !QUERY_FLAG (op, FLAG_NO_APPLY);
1250
1251 for (tmp = GET_MAP_OB (m, x, y); tmp != NULL; tmp = tmp->above)
1252 {
1253 /* No point updating the players look faces if he is the object
1254 * being removed.
1255 */
1256
1257 if (tmp->type == PLAYER && tmp != op)
1258 {
1259 /* If a container that the player is currently using somehow gets
1260 * removed (most likely destroyed), update the player view
1261 * appropriately.
1262 */ 1204 */
1263 if (tmp->container == op) 1205 if (GET_MAP_OB (m, x, y) != op)
1264 { 1206 {
1265 CLEAR_FLAG (op, FLAG_APPLIED); 1207 dump_object (op);
1266 tmp->container = NULL; 1208 LOG (llevError,
1209 "remove_ob: GET_MAP_OB does not return object to be removed even though it appears to be on the bottom?\n%s\n", errmsg);
1210 dump_object (GET_MAP_OB (m, x, y));
1211 LOG (llevError, "%s\n", errmsg);
1267 } 1212 }
1268 1213
1269 tmp->contr->socket.update_look = 1; 1214 SET_MAP_OB (m, x, y, op->above); /* goes on above it. */
1270 }
1271 /* See if player moving off should effect something */
1272 if (check_walk_off && ((op->move_type & tmp->move_off) && (op->move_type & ~tmp->move_off & ~tmp->move_block) == 0))
1273 { 1215 }
1274 move_apply (tmp, op, NULL);
1275 1216
1276 if (was_destroyed (op, tag)) 1217 op->above = 0;
1218 op->below = 0;
1219
1220 if (op->map->in_memory == MAP_SAVING)
1221 return;
1222
1223 tag = op->count;
1224 check_walk_off = !QUERY_FLAG (op, FLAG_NO_APPLY);
1225
1226 for (tmp = GET_MAP_OB (m, x, y); tmp != NULL; tmp = tmp->above)
1227 {
1228 /* No point updating the players look faces if he is the object
1229 * being removed.
1230 */
1231
1232 if (tmp->type == PLAYER && tmp != op)
1277 { 1233 {
1278 LOG (llevError, "BUG: remove_ob(): name %s, archname %s destroyed " "leaving object\n", &tmp->name, &tmp->arch->name); 1234 /* If a container that the player is currently using somehow gets
1235 * removed (most likely destroyed), update the player view
1236 * appropriately.
1237 */
1238 if (tmp->container == op)
1239 {
1240 CLEAR_FLAG (op, FLAG_APPLIED);
1241 tmp->container = NULL;
1242 }
1243
1244 tmp->contr->socket.update_look = 1;
1279 } 1245 }
1246
1247 /* See if player moving off should effect something */
1248 if (check_walk_off && ((op->move_type & tmp->move_off) && (op->move_type & ~tmp->move_off & ~tmp->move_block) == 0))
1249 {
1250 move_apply (tmp, op, NULL);
1251
1252 if (was_destroyed (op, tag))
1253 {
1254 LOG (llevError, "BUG: remove_ob(): name %s, archname %s destroyed " "leaving object\n", &tmp->name, &tmp->arch->name);
1255 }
1280 } 1256 }
1281 1257
1282 /* Eneq(@csd.uu.se): Fixed this to skip tmp->above=tmp */ 1258 /* Eneq(@csd.uu.se): Fixed this to skip tmp->above=tmp */
1283 1259
1284 if (tmp->above == tmp) 1260 if (tmp->above == tmp)
1285 tmp->above = NULL; 1261 tmp->above = NULL;
1286 1262
1287 last = tmp; 1263 last = tmp;
1288 } 1264 }
1289 1265
1290 /* last == NULL of there are no objects on this space */ 1266 /* last == NULL of there are no objects on this space */
1291 if (last == NULL) 1267 if (last == NULL)
1292 { 1268 {
1293 /* set P_NEED_UPDATE, otherwise update_position will complain. In theory, 1269 /* set P_NEED_UPDATE, otherwise update_position will complain. In theory,
1294 * we could preserve the flags (GET_MAP_FLAGS), but update_position figures 1270 * we could preserve the flags (GET_MAP_FLAGS), but update_position figures
1295 * those out anyways, and if there are any flags set right now, they won't 1271 * those out anyways, and if there are any flags set right now, they won't
1296 * be correct anyways. 1272 * be correct anyways.
1297 */ 1273 */
1298 SET_MAP_FLAGS (op->map, op->x, op->y, P_NEED_UPDATE); 1274 SET_MAP_FLAGS (op->map, op->x, op->y, P_NEED_UPDATE);
1299 update_position (op->map, op->x, op->y); 1275 update_position (op->map, op->x, op->y);
1300 } 1276 }
1301 else 1277 else
1302 update_object (last, UP_OBJ_REMOVE); 1278 update_object (last, UP_OBJ_REMOVE);
1303 1279
1304 if (QUERY_FLAG (op, FLAG_BLOCKSVIEW) || (op->glow_radius != 0)) 1280 if (QUERY_FLAG (op, FLAG_BLOCKSVIEW) || (op->glow_radius != 0))
1305 update_all_los (op->map, op->x, op->y); 1281 update_all_los (op->map, op->x, op->y);
1282 }
1306} 1283}
1307 1284
1308/* 1285/*
1309 * merge_ob(op,top): 1286 * merge_ob(op,top):
1310 * 1287 *
1317object * 1294object *
1318merge_ob (object *op, object *top) 1295merge_ob (object *op, object *top)
1319{ 1296{
1320 if (!op->nrof) 1297 if (!op->nrof)
1321 return 0; 1298 return 0;
1299
1322 if (top == NULL) 1300 if (top == NULL)
1323 for (top = op; top != NULL && top->above != NULL; top = top->above); 1301 for (top = op; top != NULL && top->above != NULL; top = top->above);
1302
1324 for (; top != NULL; top = top->below) 1303 for (; top != NULL; top = top->below)
1325 { 1304 {
1326 if (top == op) 1305 if (top == op)
1327 continue; 1306 continue;
1328 if (CAN_MERGE (op, top)) 1307 if (CAN_MERGE (op, top))
1334 remove_ob (op); 1313 remove_ob (op);
1335 free_object (op); 1314 free_object (op);
1336 return top; 1315 return top;
1337 } 1316 }
1338 } 1317 }
1318
1339 return NULL; 1319 return NULL;
1340} 1320}
1341 1321
1342/* 1322/*
1343 * same as insert_ob_in_map except it handle separate coordinates and do a clean 1323 * same as insert_ob_in_map except it handle separate coordinates and do a clean
1344 * job preparing multi-part monsters 1324 * job preparing multi-part monsters
1345 */ 1325 */
1346object * 1326object *
1347insert_ob_in_map_at (object *op, mapstruct *m, object *originator, int flag, int x, int y) 1327insert_ob_in_map_at (object *op, mapstruct *m, object *originator, int flag, int x, int y)
1348{ 1328{
1349 object * 1329 object *tmp;
1350 tmp;
1351 1330
1352 if (op->head) 1331 if (op->head)
1353 op = op->head; 1332 op = op->head;
1333
1354 for (tmp = op; tmp; tmp = tmp->more) 1334 for (tmp = op; tmp; tmp = tmp->more)
1355 { 1335 {
1356 tmp->x = x + tmp->arch->clone.x; 1336 tmp->x = x + tmp->arch->clone.x;
1357 tmp->y = y + tmp->arch->clone.y; 1337 tmp->y = y + tmp->arch->clone.y;
1358 } 1338 }
1339
1359 return insert_ob_in_map (op, m, originator, flag); 1340 return insert_ob_in_map (op, m, originator, flag);
1360} 1341}
1361 1342
1362/* 1343/*
1363 * insert_ob_in_map (op, map, originator, flag): 1344 * insert_ob_in_map (op, map, originator, flag):
1654 * op is the object to insert it under: supplies x and the map. 1635 * op is the object to insert it under: supplies x and the map.
1655 */ 1636 */
1656void 1637void
1657replace_insert_ob_in_map (const char *arch_string, object *op) 1638replace_insert_ob_in_map (const char *arch_string, object *op)
1658{ 1639{
1659 object *tmp; 1640 object *
1641 tmp;
1660 object *tmp1; 1642 object *
1643 tmp1;
1661 1644
1662 /* first search for itself and remove any old instances */ 1645 /* first search for itself and remove any old instances */
1663 1646
1664 for (tmp = GET_MAP_OB (op->map, op->x, op->y); tmp != NULL; tmp = tmp->above) 1647 for (tmp = GET_MAP_OB (op->map, op->x, op->y); tmp != NULL; tmp = tmp->above)
1665 { 1648 {
1696 if (orig_ob->nrof < nr) 1679 if (orig_ob->nrof < nr)
1697 { 1680 {
1698 sprintf (errmsg, "There are only %d %ss.", orig_ob->nrof ? orig_ob->nrof : 1, &orig_ob->name); 1681 sprintf (errmsg, "There are only %d %ss.", orig_ob->nrof ? orig_ob->nrof : 1, &orig_ob->name);
1699 return NULL; 1682 return NULL;
1700 } 1683 }
1684
1701 newob = object_create_clone (orig_ob); 1685 newob = object_create_clone (orig_ob);
1686
1702 if ((orig_ob->nrof -= nr) < 1) 1687 if ((orig_ob->nrof -= nr) < 1)
1703 { 1688 {
1704 if (!is_removed) 1689 if (!is_removed)
1705 remove_ob (orig_ob); 1690 remove_ob (orig_ob);
1706 free_object2 (orig_ob, 1); 1691 free_object2 (orig_ob, 1);
1714 strcpy (errmsg, "Tried to split object whose map is not in memory."); 1699 strcpy (errmsg, "Tried to split object whose map is not in memory.");
1715 LOG (llevDebug, "Error, Tried to split object whose map is not in memory.\n"); 1700 LOG (llevDebug, "Error, Tried to split object whose map is not in memory.\n");
1716 return NULL; 1701 return NULL;
1717 } 1702 }
1718 } 1703 }
1704
1719 newob->nrof = nr; 1705 newob->nrof = nr;
1720 1706
1721 return newob; 1707 return newob;
1722} 1708}
1723 1709
1730 */ 1716 */
1731 1717
1732object * 1718object *
1733decrease_ob_nr (object *op, uint32 i) 1719decrease_ob_nr (object *op, uint32 i)
1734{ 1720{
1735 object * 1721 object *tmp;
1736 tmp;
1737 player * 1722 player *pl;
1738 pl;
1739 1723
1740 if (i == 0) /* objects with op->nrof require this check */ 1724 if (i == 0) /* objects with op->nrof require this check */
1741 return op; 1725 return op;
1742 1726
1743 if (i > op->nrof) 1727 if (i > op->nrof)
1744 i = op->nrof; 1728 i = op->nrof;
1745 1729
1746 if (QUERY_FLAG (op, FLAG_REMOVED)) 1730 if (QUERY_FLAG (op, FLAG_REMOVED))
1747 {
1748 op->nrof -= i; 1731 op->nrof -= i;
1749 }
1750 else if (op->env != NULL) 1732 else if (op->env != NULL)
1751 { 1733 {
1752 /* is this object in the players inventory, or sub container 1734 /* is this object in the players inventory, or sub container
1753 * therein? 1735 * therein?
1754 */ 1736 */
1789 } 1771 }
1790 } 1772 }
1791 } 1773 }
1792 else 1774 else
1793 { 1775 {
1794 object *
1795 above = op->above; 1776 object *above = op->above;
1796 1777
1797 if (i < op->nrof) 1778 if (i < op->nrof)
1798 {
1799 op->nrof -= i; 1779 op->nrof -= i;
1800 }
1801 else 1780 else
1802 { 1781 {
1803 remove_ob (op); 1782 remove_ob (op);
1804 op->nrof = 0; 1783 op->nrof = 0;
1805 } 1784 }
1785
1806 /* Since we just removed op, op->above is null */ 1786 /* Since we just removed op, op->above is null */
1807 for (tmp = above; tmp != NULL; tmp = tmp->above) 1787 for (tmp = above; tmp != NULL; tmp = tmp->above)
1808 if (tmp->type == PLAYER) 1788 if (tmp->type == PLAYER)
1809 { 1789 {
1810 if (op->nrof) 1790 if (op->nrof)
1813 esrv_del_item (tmp->contr, op->count); 1793 esrv_del_item (tmp->contr, op->count);
1814 } 1794 }
1815 } 1795 }
1816 1796
1817 if (op->nrof) 1797 if (op->nrof)
1818 {
1819 return op; 1798 return op;
1820 }
1821 else 1799 else
1822 { 1800 {
1823 free_object (op); 1801 free_object (op);
1824 return NULL; 1802 return NULL;
1825 } 1803 }
1834add_weight (object *op, signed long weight) 1812add_weight (object *op, signed long weight)
1835{ 1813{
1836 while (op != NULL) 1814 while (op != NULL)
1837 { 1815 {
1838 if (op->type == CONTAINER) 1816 if (op->type == CONTAINER)
1839 {
1840 weight = (signed long) (weight * (100 - op->stats.Str) / 100); 1817 weight = (signed long) (weight * (100 - op->stats.Str) / 100);
1841 } 1818
1842 op->carrying += weight; 1819 op->carrying += weight;
1843 op = op->env; 1820 op = op->env;
1844 } 1821 }
1845} 1822}
1846 1823
1869 { 1846 {
1870 dump_object (op); 1847 dump_object (op);
1871 LOG (llevError, "Trying to insert (ob) inserted object.\n%s\n", errmsg); 1848 LOG (llevError, "Trying to insert (ob) inserted object.\n%s\n", errmsg);
1872 return op; 1849 return op;
1873 } 1850 }
1851
1874 if (where == NULL) 1852 if (where == NULL)
1875 { 1853 {
1876 dump_object (op); 1854 dump_object (op);
1877 LOG (llevError, "Trying to put object in NULL.\n%s\n", errmsg); 1855 LOG (llevError, "Trying to put object in NULL.\n%s\n", errmsg);
1878 return op; 1856 return op;
1879 } 1857 }
1858
1880 if (where->head) 1859 if (where->head)
1881 { 1860 {
1882 LOG (llevDebug, "Warning: Tried to insert object wrong part of multipart object.\n"); 1861 LOG (llevDebug, "Warning: Tried to insert object wrong part of multipart object.\n");
1883 where = where->head; 1862 where = where->head;
1884 } 1863 }
1864
1885 if (op->more) 1865 if (op->more)
1886 { 1866 {
1887 LOG (llevError, "Tried to insert multipart object %s (%d)\n", &op->name, op->count); 1867 LOG (llevError, "Tried to insert multipart object %s (%d)\n", &op->name, op->count);
1888 return op; 1868 return op;
1889 } 1869 }
1870
1890 CLEAR_FLAG (op, FLAG_OBJ_ORIGINAL); 1871 CLEAR_FLAG (op, FLAG_OBJ_ORIGINAL);
1891 CLEAR_FLAG (op, FLAG_REMOVED); 1872 CLEAR_FLAG (op, FLAG_REMOVED);
1892 if (op->nrof) 1873 if (op->nrof)
1893 { 1874 {
1894 for (tmp = where->inv; tmp != NULL; tmp = tmp->below) 1875 for (tmp = where->inv; tmp != NULL; tmp = tmp->below)
1979 */ 1960 */
1980 1961
1981int 1962int
1982check_move_on (object *op, object *originator) 1963check_move_on (object *op, object *originator)
1983{ 1964{
1984 object *tmp; 1965 object *
1985 tag_t tag; 1966 tmp;
1986 mapstruct *m = op->map; 1967 tag_t
1968 tag;
1969 mapstruct *
1970 m = op->map;
1971 int
1987 int x = op->x, y = op->y; 1972 x = op->x, y = op->y;
1988 1973
1989 MoveType move_on, move_slow, move_block; 1974 MoveType
1975 move_on,
1976 move_slow,
1977 move_block;
1990 1978
1991 if (QUERY_FLAG (op, FLAG_NO_APPLY)) 1979 if (QUERY_FLAG (op, FLAG_NO_APPLY))
1992 return 0; 1980 return 0;
1993 1981
1994 tag = op->count; 1982 tag = op->count;
2042 { 2030 {
2043 if ((!op->move_type && tmp->move_slow & MOVE_WALK) || 2031 if ((!op->move_type && tmp->move_slow & MOVE_WALK) ||
2044 ((op->move_type & tmp->move_slow) && (op->move_type & ~tmp->move_slow & ~tmp->move_block) == 0)) 2032 ((op->move_type & tmp->move_slow) && (op->move_type & ~tmp->move_slow & ~tmp->move_block) == 0))
2045 { 2033 {
2046 2034
2035 float
2047 float diff = tmp->move_slow_penalty * FABS (op->speed); 2036 diff = tmp->move_slow_penalty * FABS (op->speed);
2048 2037
2049 if (op->type == PLAYER) 2038 if (op->type == PLAYER)
2050 if ((QUERY_FLAG (tmp, FLAG_IS_HILLY) && find_skill_by_number (op, SK_CLIMBING)) || 2039 if ((QUERY_FLAG (tmp, FLAG_IS_HILLY) && find_skill_by_number (op, SK_CLIMBING)) ||
2051 (QUERY_FLAG (tmp, FLAG_IS_WOODED) && find_skill_by_number (op, SK_WOODSMAN))) 2040 (QUERY_FLAG (tmp, FLAG_IS_WOODED) && find_skill_by_number (op, SK_WOODSMAN)))
2052 diff /= 4.0; 2041 diff /= 4.0;
2371find_dir (mapstruct *m, int x, int y, object *exclude) 2360find_dir (mapstruct *m, int x, int y, object *exclude)
2372{ 2361{
2373 int 2362 int
2374 i, 2363 i,
2375 max = SIZEOFFREE, mflags; 2364 max = SIZEOFFREE, mflags;
2376 sint16 2365
2377 nx, 2366 sint16 nx, ny;
2378 ny;
2379 object * 2367 object *
2380 tmp; 2368 tmp;
2381 mapstruct * 2369 mapstruct *
2382 mp; 2370 mp;
2383 MoveType 2371
2384 blocked, 2372 MoveType blocked, move_type;
2385 move_type;
2386 2373
2387 if (exclude && exclude->head) 2374 if (exclude && exclude->head)
2388 { 2375 {
2389 exclude = exclude->head; 2376 exclude = exclude->head;
2390 move_type = exclude->move_type; 2377 move_type = exclude->move_type;
2597 2584
2598 2585
2599int 2586int
2600can_see_monsterP (mapstruct *m, int x, int y, int dir) 2587can_see_monsterP (mapstruct *m, int x, int y, int dir)
2601{ 2588{
2602 sint16 2589 sint16 dx, dy;
2603 dx,
2604 dy;
2605 int 2590 int
2606 mflags; 2591 mflags;
2607 2592
2608 if (dir < 0) 2593 if (dir < 0)
2609 return 0; /* exit condition: invalid direction */ 2594 return 0; /* exit condition: invalid direction */
2740 fprintf (tempfile, obstr); 2725 fprintf (tempfile, obstr);
2741 fclose (tempfile); 2726 fclose (tempfile);
2742 2727
2743 op = get_object (); 2728 op = get_object ();
2744 2729
2745 object_thawer 2730 object_thawer thawer (filename);
2746 thawer (filename);
2747 2731
2748 if (thawer) 2732 if (thawer)
2749 load_object (thawer, op, 0); 2733 load_object (thawer, op, 0);
2750 2734
2751 LOG (llevDebug, " load str completed, object=%s\n", &op->name); 2735 LOG (llevDebug, " load str completed, object=%s\n", &op->name);
2875 if (last) 2859 if (last)
2876 last->next = field->next; 2860 last->next = field->next;
2877 else 2861 else
2878 op->key_values = field->next; 2862 op->key_values = field->next;
2879 2863
2880 delete
2881 field; 2864 delete field;
2882 } 2865 }
2883 } 2866 }
2884 return TRUE; 2867 return TRUE;
2885 } 2868 }
2886 /* IF we get here, key doesn't exist */ 2869 /* IF we get here, key doesn't exist */
2921 * Returns TRUE on success. 2904 * Returns TRUE on success.
2922 */ 2905 */
2923int 2906int
2924set_ob_key_value (object *op, const char *key, const char *value, int add_key) 2907set_ob_key_value (object *op, const char *key, const char *value, int add_key)
2925{ 2908{
2926 shstr
2927 key_ (key); 2909 shstr key_ (key);
2928 2910
2929 return set_ob_key_value_s (op, key_, value, add_key); 2911 return set_ob_key_value_s (op, key_, value, add_key);
2930} 2912}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines