I just checked the implementation you added for MAng. There are parts of code missing...
load2.c
--------
Code: Select all
static void rd_item(object_type *o_ptr)
{
...
/* Save the inscription */
if (note[0]) o_ptr->note = quark_add(note);
/* Monster holding object */
o_ptr->held_m_idx = read_int("held_m_idx");
end_section_read("item");
...
}
melee1.c
----------
Code: Select all
bool make_attack_normal(int Ind, int m_idx)
{
...
case RBE_EAT_ITEM:
...
/* Find an item */
for (k = 0; k < 10; k++)
{
object_type *i_ptr;
object_type object_type_body;
/* Pick an item */
i = rand_int(INVEN_PACK);
/* Obtain the item */
o_ptr = &p_ptr->inventory[i];
/* Accept real items */
if (!o_ptr->k_idx) continue;
/* Don't steal artifacts -CFT */
if (artifact_p(o_ptr)) continue;
/* Get a description */
object_desc(Ind, o_name, o_ptr, FALSE, 3);
/* Message */
msg_format(Ind, "%sour %s (%c) was stolen!",
((o_ptr->number > 1) ? "One of y" : "Y"),
o_name, index_to_label(i));
/* Get local object */
i_ptr = &object_type_body;
/* Obtain local object */
object_copy(i_ptr, o_ptr);
/* Modify number */
i_ptr->number = 1;
/* Carry the object */
monster_carry(Ind, m_idx, i_ptr);
/* Steal the items */
inven_item_increase(Ind, i, -1);
inven_item_optimize(Ind, i);
/* Obvious */
obvious = TRUE;
/* Blink away */
blinked = 2;
/* Done */
break;
}
...
}
monster2.c
-------------
here I'm gonna post the whole beginning of this file, since the deleteXXX and compactXXX functions have been greatly impacted
Code: Select all
#include "angband.h"
/*
* Excise a dungeon object from any stacks
*/
static void excise_object_idx(int o_idx)
{
object_type *j_ptr;
s16b this_o_idx, next_o_idx = 0;
s16b prev_o_idx = 0;
/* Object */
j_ptr = &o_list[o_idx];
/* Monster */
if (j_ptr->held_m_idx)
{
monster_type *m_ptr;
/* Monster */
m_ptr = &m_list[j_ptr->held_m_idx];
/* Scan all objects in the grid */
for (this_o_idx = m_ptr->hold_o_idx; this_o_idx; this_o_idx = next_o_idx)
{
object_type *o_ptr;
/* Get the object */
o_ptr = &o_list[this_o_idx];
/* Get the next object */
next_o_idx = o_ptr->next_o_idx;
/* Done */
if (this_o_idx == o_idx)
{
/* No previous */
if (prev_o_idx == 0)
{
/* Remove from list */
m_ptr->hold_o_idx = next_o_idx;
}
/* Real previous */
else
{
object_type *i_ptr;
/* Previous object */
i_ptr = &o_list[prev_o_idx];
/* Remove from list */
i_ptr->next_o_idx = next_o_idx;
}
/* Forget next pointer */
o_ptr->next_o_idx = 0;
/* Done */
break;
}
/* Save prev_o_idx */
prev_o_idx = this_o_idx;
}
}
/* Dungeon */
else
{
int y = j_ptr->iy;
int x = j_ptr->ix;
int Depth = j_ptr->dun_depth;
cave_type *c_ptr = &cave[Depth][y][x];
int i;
/* Object is gone */
c_ptr->o_idx = 0;
/* No one can see it anymore */
for (i = 1; i < NumPlayers + 1; i++)
Players[i]->obj_vis[c_ptr->o_idx] = FALSE;
}
}
static void object_wipe(object_type* o_ptr)
{
/* Wipe the object */
WIPE(o_ptr, object_type);
}
/*
* Delete a dungeon object
*/
void delete_object_idx(int o_idx)
{
object_type *j_ptr;
/* Excise */
excise_object_idx(o_idx);
/* Object */
j_ptr = &o_list[o_idx];
/* Dungeon floor */
if (!j_ptr->held_m_idx)
{
int y, x, Depth;
/* Location */
y = j_ptr->iy;
x = j_ptr->ix;
Depth = j_ptr->dun_depth;
/* Visual update */
everyone_lite_spot(Depth, y, x);
}
/* Wipe the object */
object_wipe(j_ptr);
}
/*
* Deletes object from given location
*/
void delete_object(int Depth, int y, int x)
{
cave_type *c_ptr;
/* Paranoia */
if (!in_bounds(Depth, y, x)) return;
/* Paranoia -- make sure the level has been allocated */
if (!cave[Depth])
{
printf("Error : tried to delete object on unallocated level %d\n",Depth);
return;
}
/* Find where it was */
c_ptr = &cave[Depth][y][x];
/* Delete the object */
if (c_ptr->o_idx) delete_object_idx(c_ptr->o_idx);
}
/*
* Move an object from index i1 to index i2 in the object list
*/
static void compact_objects_aux(int i1, int i2)
{
int i, Ind;
object_type *o_ptr;
/* Do nothing */
if (i1 == i2) return;
/* Repair objects */
for (i = 1; i < o_max; i++)
{
/* Get the object */
o_ptr = &o_list[i];
/* Skip "dead" objects */
if (!o_ptr->k_idx) continue;
/* Repair "next" pointers */
if (o_ptr->next_o_idx == i1)
{
/* Repair */
o_ptr->next_o_idx = i2;
}
}
/* Get the object */
o_ptr = &o_list[i1];
/* Monster */
if (o_ptr->held_m_idx)
{
monster_type *m_ptr;
/* Get the monster */
m_ptr = &m_list[o_ptr->held_m_idx];
/* Repair monster */
if (m_ptr->hold_o_idx == i1)
{
/* Repair */
m_ptr->hold_o_idx = i2;
}
}
/* Dungeon */
else
{
int y, x, Depth;
/* Get location */
y = o_ptr->iy;
x = o_ptr->ix;
Depth = o_ptr->dun_depth;
/* Repair grid */
if (cave[Depth] && (cave[Depth][y][x].o_idx == i1))
{
/* Repair */
cave[Depth][y][x].o_idx = i2;
}
}
/* Copy the visibility flags for each player */
for (Ind = 1; Ind < NumPlayers + 1; Ind++)
Players[Ind]->obj_vis[i2] = Players[Ind]->obj_vis[i1];
/* Hack -- move object */
COPY(&o_list[i2], &o_list[i1], object_type);
/* Hack -- wipe hole */
object_wipe(o_ptr);
}
/*
* Compact and reorder the object list
*
* This function can be very dangerous, use with caution!
*
* When compacting objects, we first destroy gold, on the basis that by the
* time item compaction becomes an issue, the player really won't care.
* We also nuke items marked as squelch.
*
* When compacting other objects, we base the saving throw on a combination of
* object level, distance from player, and current "desperation".
*
* After compacting, we "reorder" the objects into a more compact order, and we
* reset the allocation info, and the "live" array.
*/
void compact_objects(int size)
{
int i, y, x, cnt;
int cur_lev, cur_val, chance;
/* Reorder objects when not passed a size */
if (!size)
{
/* Excise dead objects (backwards!) */
for (i = o_max - 1; i >= 1; i--)
{
object_type *o_ptr = &o_list[i];
/* Skip real objects */
if (o_ptr->k_idx) continue;
/* Move last object into open hole */
compact_objects_aux(o_max - 1, i);
/* Compress "o_max" */
o_max--;
}
/* Reset "o_nxt" */
o_nxt = o_max;
/* Reset "o_top" */
o_top = 0;
/* Collect "live" objects */
for (i = 0; i < o_max; i++)
{
/* Collect indexes */
o_fast[o_top++] = i;
}
return;
}
/* Message */
s_printf("Compacting objects...\n");
/*** Try destroying objects ***/
/* First do gold */
for (i = 1; (i < o_max) && (size); i++)
{
object_type *o_ptr = &o_list[i];
/* Nuke gold */
if (o_ptr->tval == TV_GOLD)
{
delete_object_idx(i);
size--;
}
}
/* Compact at least 'size' objects */
for (cnt = 1; size; cnt++)
{
/* Get more vicious each iteration */
cur_lev = 5 * cnt;
/* Destroy more valuable items each iteration */
cur_val = 500 * (cnt - 1);
/* Examine the objects */
for (i = 1; (i < o_max) && (size); i++)
{
object_type *o_ptr = &o_list[i];
object_kind *k_ptr = &k_info[o_ptr->k_idx];
/* Skip dead objects */
if (!o_ptr->k_idx) continue;
/* Hack -- High level objects start out "immune" */
if (k_ptr->level > cur_lev) continue;
/* Valuable objects start out "immune" */
if (object_value(0, o_ptr) > cur_val) continue;
/* Saving throw */
chance = 90;
/* Monster */
if (o_ptr->held_m_idx)
{
monster_type *m_ptr;
/* Get the monster */
m_ptr = &m_list[o_ptr->held_m_idx];
/* Monsters protect their objects */
if (magik(90)) continue;
}
/* Dungeon */
else
{
/* Get the location */
y = o_ptr->iy;
x = o_ptr->ix;
/* Hack -- only compact items in houses in emergencies */
if (!o_ptr->dun_depth && (cave[0][y][x].info & CAVE_ICKY))
{
/* Grant immunity except in emergencies */
if (cnt < 1000) chance = 100;
}
}
/* Hack -- only compact artifacts in emergencies */
if (artifact_p(o_ptr) && (cnt < 1000)) chance = 100;
/* Apply the saving throw */
if (magik(chance)) continue;
/* Delete the object */
delete_object_idx(i);
size--;
}
}
/* Reorder objects */
compact_objects(0);
}
and this is missing in inven_carry()
Code: Select all
/* Structure copy to insert the new item */
p_ptr->inventory[i] = (*o_ptr);
/* Get the new object */
j_ptr = &p_ptr->inventory[i];
/* Forget monster */
j_ptr->held_m_idx = 0;
/* Forget location */
j_ptr->iy = j_ptr->ix = j_ptr->dun_depth = 0;
save.c
-------
Code: Select all
static void wr_item(object_type *o_ptr)
{
...
/* Held by monster index */
write_int("held_m_idx", o_ptr->held_m_idx);
end_section("item");
...
}
This could explain the (nothing)s you get...