Fix crates and barrels "stealing" the items from other containers when they are pushed over them

Fix stone blocks disappearing when pushed
This commit is contained in:
2015-06-06 23:23:45 -04:00
parent 58fbf3b287
commit 722f670e3d
14 changed files with 62 additions and 46 deletions

View File

@@ -1603,7 +1603,7 @@ void initiate_outdoor_combat(short i) {
for(m = 0; m < 6; m++)
for(n = 0; n < 24; n++)
if(univ.party[m].main_status != eMainStatus::ALIVE && univ.party[m].items[n].variety != eItemType::NO_ITEM) {
place_item(univ.party[m].items[n],to_place,true);
place_item(univ.party[m].items[n],to_place);
univ.party[m].items[n].variety = eItemType::NO_ITEM;
}

View File

@@ -197,7 +197,6 @@ void adjust_window_mode() {
void plop_fancy_startup() {
sf::Texture pict_to_draw;
sf::Event event;
short i,j;
rectangle whole_window,from_rect;
rectangle logo_from = {0,0,350,350};

View File

@@ -204,20 +204,12 @@ void drop_item(short pc_num,short item_num,location where_drop) {
take_given_item = false;
item_store.charges = how_many;
}
if(is_container(loc))
item_store.contained = true;
if(!place_item(item_store,loc,false)) {
add_string_to_buf("Drop: Too many items on ground");
item_store.contained = false;
}
else {
if(item_store.contained)
if(place_item(item_store,loc,true))
add_string_to_buf("Drop: Item put away");
else add_string_to_buf("Drop: OK");
univ.party[pc_num].items[item_num].charges -= how_many;
if(take_given_item)
univ.party[pc_num].take_item(item_num);
}
break;
default: //should never be reached
break;
@@ -229,26 +221,29 @@ void drop_item(short pc_num,short item_num,location where_drop) {
draw_terrain(0);
}
bool place_item(cItem item,location where,bool forced,bool contained) {
bool place_item(cItem item,location where,bool contained) {
short i;
(void) forced;
if(contained && !is_container(where))
contained = false;
bool is_pushable_ctr = contained && (univ.town.is_barrel(where.x,where.y) || univ.town.is_crate(where.x,where.y));
for(i = 0; i < univ.town.items.size(); i++)
if(univ.town.items[i].variety == eItemType::NO_ITEM) {
univ.town.items[i] = item;
univ.town.items[i].item_loc = where;
univ.town.items[i].contained = contained;
univ.town.items[i].held = is_pushable_ctr;
reset_item_max();
return true;
return univ.town.items[i].contained;
}
univ.town.items.push_back(item);
univ.town.items.back().item_loc = where;
univ.town.items.back().contained = contained;
univ.town.items.back().held = is_pushable_ctr;
reset_item_max();
return true;
return univ.town.items.back().contained;
}
void give_thing(short pc_num, short item_num) {
@@ -762,7 +757,7 @@ void place_glands(location where,mon_num_t m_type) {
if((monst.corpse_item >= 0) && (monst.corpse_item < 400) && (get_ran(1,1,100) < monst.corpse_item_chance)) {
store_i = get_stored_item(monst.corpse_item);
place_item(store_i,where,false);
place_item(store_i,where);
}
}
@@ -835,7 +830,7 @@ void place_treasure(location where,short level,short loot,short mode) {
r1 = get_ran(1,1,9);
if(((loot > 1) && (r1 < 7)) || ((loot == 1) && (r1 < 5)) || (mode == 1)
|| ((r1 < 6) && (univ.party.get_level() < 30)) || (loot > 2) )
place_item(new_item,where,false);
place_item(new_item,where);
}
for(j = 0; j < 5; j++) {
r1 = get_ran(1,1,100);
@@ -891,7 +886,7 @@ void place_treasure(location where,short level,short loot,short mode) {
if((univ.party[i].main_status == eMainStatus::ALIVE)
&& get_ran(1,1,100) < id_odds[univ.party[i].skill(eSkill::ITEM_LORE)])
new_item.ident = true;
place_item(new_item,where,false);
place_item(new_item,where);
}
}
}

View File

@@ -10,7 +10,7 @@ void give_food(short amount,bool print_result);
short take_food(short amount,bool print_result);
void equip_item(short pc_num,short item_num);
void drop_item(short pc_num,short item_num,location where_drop);
bool place_item(cItem item,location where,bool forced,bool contained = false);
bool place_item(cItem item,location where,bool try_contained = false);
void give_thing(short pc_num, short item_num);
short dist_from_party(location where);
void set_item_flag(cItem *item);

View File

@@ -869,7 +869,7 @@ void monst_inflict_fields(short which_monst) {
for(k = 0; k < univ.town.items.size(); k++)
if(univ.town.items[k].variety != eItemType::NO_ITEM && univ.town.items[k].contained
&& (univ.town.items[k].item_loc == where_check))
univ.town.items[k].contained = false;
univ.town.items[k].contained = univ.town.items[k].held = false;
univ.town.set_crate(where_check.x,where_check.y,false);
univ.town.set_barrel(where_check.x,where_check.y,false);
if(univ.town.is_fire_barr(where_check.x,where_check.y)) {
@@ -986,7 +986,7 @@ bool monst_check_special_terrain(location where_check,short mode,short which_mon
univ.town.set_crate(to_loc.x,to_loc.y, true);
for(i = 0; i < univ.town.items.size(); i++)
if(univ.town.items[i].variety != eItemType::NO_ITEM && univ.town.items[i].item_loc == where_check
&& (univ.town.items[i].contained))
&& univ.town.items[i].contained && univ.town.items[i].held)
univ.town.items[i].item_loc = to_loc;
}
}
@@ -1000,7 +1000,7 @@ bool monst_check_special_terrain(location where_check,short mode,short which_mon
univ.town.set_barrel(to_loc.x,to_loc.y,true);
for(i = 0; i < univ.town.items.size(); i++)
if(univ.town.items[i].variety != eItemType::NO_ITEM && univ.town.items[i].item_loc == where_check
&& (univ.town.items[i].contained))
&& univ.town.items[i].contained && univ.town.items[i].held)
univ.town.items[i].item_loc = to_loc;
}

View File

@@ -118,7 +118,7 @@ char last_light_mask[13][13];
void apply_unseen_mask() {
rectangle base_rect = {9,9,53,45},to_rect,big_to = {13,13,337,265};
short i,j,k,l;
short i,j;
bool need_bother = false;
if(PSD[SDF_NO_FRILLS] > 0 || fog_lifted)

View File

@@ -2200,7 +2200,7 @@ void do_alchemy() {
store_i.graphic_num += get_ran(1,0,2);
if(!univ.party[pc_num].give_item(store_i,false)) {
add_string_to_buf("No room in inventory. Potion placed on floor.", 2);
place_item(store_i,univ.town.p_loc,true);
place_item(store_i,univ.town.p_loc);
}
else add_string_to_buf("Alchemy: Successful.");
}
@@ -2618,7 +2618,7 @@ void kill_pc(cPlayer& which_pc,eMainStatus type) {
if(overall_mode != MODE_OUTDOORS)
for(i = 0; i < 24; i++)
if(which_pc.items[i].variety != eItemType::NO_ITEM) {
dummy = place_item(which_pc.items[i],item_loc,true);
dummy = place_item(which_pc.items[i],item_loc);
which_pc.items[i].variety = eItemType::NO_ITEM;
}
if(type == eMainStatus::DEAD || type == eMainStatus::DUST)

View File

@@ -266,7 +266,7 @@ bool check_special_terrain(location where_check,eSpecCtx mode,cPlayer& which_pc,
univ.town.set_crate(to_loc.x,to_loc.y,true);
for(i = 0; i < univ.town.items.size(); i++)
if(univ.town.items[i].variety != eItemType::NO_ITEM && univ.town.items[i].item_loc == where_check
&& (univ.town.items[i].contained))
&& univ.town.items[i].contained && univ.town.items[i].held)
univ.town.items[i].item_loc = to_loc;
}
if(univ.town.is_barrel(where_check.x,where_check.y)) {
@@ -277,7 +277,7 @@ bool check_special_terrain(location where_check,eSpecCtx mode,cPlayer& which_pc,
univ.town.set_barrel(to_loc.x,to_loc.y,true);
for(i = 0; i < univ.town.items.size(); i++)
if(univ.town.items[i].variety != eItemType::NO_ITEM && univ.town.items[i].item_loc == where_check
&& (univ.town.items[i].contained))
&& univ.town.items[i].contained && univ.town.items[i].held)
univ.town.items[i].item_loc = to_loc;
}
if(univ.town.is_block(where_check.x,where_check.y)) {
@@ -285,7 +285,7 @@ bool check_special_terrain(location where_check,eSpecCtx mode,cPlayer& which_pc,
to_loc = push_loc(from_loc,where_check);
univ.town.set_block(where_check.x,where_check.y,false);
if(to_loc.x > 0)
univ.town.set_block(to_loc.x,to_loc.y,false);
univ.town.set_block(to_loc.x,to_loc.y,true);
}
}
@@ -1223,7 +1223,7 @@ bool use_space(location where) {
univ.town.set_crate(to_loc.x,to_loc.y,true);
for(i = 0; i < univ.town.items.size(); i++)
if(univ.town.items[i].variety != eItemType::NO_ITEM && univ.town.items[i].item_loc == where
&& (univ.town.items[i].contained))
&& univ.town.items[i].contained && univ.town.items[i].held)
univ.town.items[i].item_loc = to_loc;
}
if(univ.town.is_barrel(where.x,where.y)) {
@@ -1237,7 +1237,7 @@ bool use_space(location where) {
univ.town.set_barrel(to_loc.x,to_loc.y,true);
for(i = 0; i < univ.town.items.size(); i++)
if(univ.town.items[i].variety != eItemType::NO_ITEM && univ.town.items[i].item_loc == where
&& (univ.town.items[i].contained))
&& univ.town.items[i].contained && univ.town.items[i].held)
univ.town.items[i].item_loc = to_loc;
}
if(univ.town.is_block(where.x,where.y)) {
@@ -1743,9 +1743,9 @@ void push_things() {
hit_party(get_ran(1, 1, 6), eDamageType::WEAPON);
}
for(k = 0; k < univ.town.items.size(); k++)
if(univ.town.items[k].variety != eItemType::NO_ITEM && univ.town.items[k].contained
if(univ.town.items[k].variety != eItemType::NO_ITEM && univ.town.items[k].held
&& (univ.town.items[k].item_loc == univ.town.p_loc))
univ.town.items[k].contained = false;
univ.town.items[k].contained = univ.town.items[k].held = false;
redraw = true;
}
}
@@ -1781,9 +1781,9 @@ void push_things() {
damage_pc(univ.party[i],get_ran(1, 1, 6), eDamageType::WEAPON,eRace::UNKNOWN,0);
}
for(k = 0; k < univ.town.items.size(); k++)
if(univ.town.items[k].variety != eItemType::NO_ITEM && univ.town.items[k].contained
if(univ.town.items[k].variety != eItemType::NO_ITEM && univ.town.items[k].held
&& (univ.town.items[k].item_loc == univ.party[i].combat_pos))
univ.town.items[k].contained = false;
univ.town.items[k].contained = univ.town.items[k].held = false;
redraw = true;
}
}
@@ -4022,7 +4022,7 @@ void townmode_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
break;
case eSpecType::TOWN_PLACE_ITEM:
store_i = get_stored_item(spec.ex2a);
place_item(store_i,l,true,spec.ex2b);
place_item(store_i,l,spec.ex2b);
break;
case eSpecType::TOWN_SPLIT_PARTY:
if(which_mode == eSpecCtx::TALK)
@@ -4358,8 +4358,11 @@ void rect_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
if(univ.town.items[k].variety != eItemType::NO_ITEM && univ.town.items[k].item_loc == l) {
univ.town.items[k].item_loc.x = spec.sd1;
univ.town.items[k].item_loc.y = spec.sd2;
if(i && spec.m3)
univ.town.items[k].contained = true;
if(i && spec.m3) {
univ.town.items[k].contained = is_container(univ.town.items[k].item_loc);
if(univ.town.is_crate(spec.sd1,spec.sd2) || univ.town.is_barrel(spec.sd1,spec.sd2))
univ.town.items[k].held = true;
}
}
break;
case eSpecType::RECT_DESTROY_ITEMS:

View File

@@ -446,6 +446,9 @@ void start_town_mode(short which_town, short entry_dir) {
else
univ.town.items[j].property = univ.town->preset_items[i].property;
univ.town.items[j].contained = univ.town->preset_items[i].contained;
int x = univ.town.items[j].item_loc.x, y = univ.town.items[j].item_loc.y;
if(univ.town.items[j].contained && (univ.town.is_barrel(x,y) || univ.town.is_crate(x,y)))
univ.town.items[j].held = true;
univ.town.items[j].is_special = i + 1;
}
@@ -508,7 +511,7 @@ void start_town_mode(short which_town, short entry_dir) {
continue;
for(n = 0; n < 24; n++)
if(univ.party[m].items[n].variety != eItemType::NO_ITEM) {
place_item(univ.party[m].items[n],univ.town.p_loc,true);
place_item(univ.party[m].items[n],univ.town.p_loc);
univ.party[m].items[n].variety = eItemType::NO_ITEM;
}
}

View File

@@ -96,7 +96,7 @@ cItem::cItem(){
item_loc.x = 0;
item_loc.y = 0;
treas_class = 0;
ident = property = magic = contained = false;
ident = property = magic = contained = held = false;
cursed = concealed = enchanted = unsellable = false;
}
@@ -923,7 +923,7 @@ void cItem::append(legacy::item_record_type& old){
contained = old.item_properties & 8;
cursed = old.item_properties & 16;
concealed = old.item_properties & 32;
enchanted = false;
enchanted = held = false;
unsellable = old.item_properties & 16;
// Set missile, if needed
if(variety == eItemType::ARROW || variety == eItemType::BOLTS) {
@@ -1273,6 +1273,7 @@ void cItem::writeTo(std::ostream& file, std::string prefix) const {
if(property) file << prefix << "PROPERTY\n";
if(magic) file << prefix << "MAGIC\n";
if(contained) file << prefix << "CONTAINED\n";
if(held) file << prefix << "HELD\n";
if(cursed) file << prefix << "CURSED\n";
if(concealed) file << prefix << "CONCEALED\n";
if(enchanted) file << prefix << "ENCHANTED\n";
@@ -1309,6 +1310,7 @@ void cItem::readFrom(std::istream& sin){
else if(cur == "PROPERTY") property = true;
else if(cur == "MAGIC") magic = true;
else if(cur == "CONTAINED") contained = true;
else if(cur == "HELD") held = true;
else if(cur == "CURSED") cursed = true;
else if(cur == "CONCEALED") concealed = true;
else if(cur == "ENCHANTED") enchanted = true;

View File

@@ -43,7 +43,7 @@ public:
std::string full_name;
std::string name;
unsigned int treas_class;
bool ident, property, magic, contained, cursed, concealed, enchanted, unsellable;
bool ident, property, magic, contained, held, cursed, concealed, enchanted, unsellable;
std::string desc;
unsigned char rec_treas_class() const;
short item_weight() const;

View File

@@ -454,6 +454,7 @@ bool cPlayer::give_item(cItem item, bool do_print, bool allow_overload) {
else {
item.property = false;
item.contained = false;
item.held = false;
items[free_space] = item;
if(do_print && print_result) {

View File

@@ -1946,6 +1946,8 @@ bool place_item(location spot_hit,short which_item,bool property,bool always,sho
}
town->preset_items.push_back({spot_hit, which_item, scenario.scen_items[which_item]});
town->preset_items.back().contained = container_there(spot_hit);
town->preset_items.back().property = property;
town->preset_items.back().always_there = always;
return true;
}

View File

@@ -266,6 +266,17 @@ bool load_party_v1(fs::path file_to_load, cUniverse& univ, bool town_restore, bo
univ.append(town_maps);
univ.append(o_maps);
univ.town.append(sfx, misc_i);
// Check items in crates/barrels
for(int i = 0; i < univ.town->max_dim(); i++) {
for(int j = 0; j < univ.town->max_dim(); j++) {
if(univ.town.is_barrel(i,j) || univ.town.is_crate(i,j)) {
for(cItem item : univ.town.items) {
if(item.item_loc == loc(i,j) && item.contained)
item.held = true;
}
}
}
}
}
return true;