From 722f670e3d43b713c887b46f9200cb68f8280181 Mon Sep 17 00:00:00 2001 From: Celtic Minstrel Date: Sat, 6 Jun 2015 23:23:45 -0400 Subject: [PATCH] Fix crates and barrels "stealing" the items from other containers when they are pushed over them Fix stone blocks disappearing when pushed --- src/boe.actions.cpp | 2 +- src/boe.graphics.cpp | 1 - src/boe.items.cpp | 37 +++++++++++++++-------------------- src/boe.items.h | 2 +- src/boe.monster.cpp | 6 +++--- src/boe.newgraph.cpp | 2 +- src/boe.party.cpp | 4 ++-- src/boe.specials.cpp | 27 +++++++++++++------------ src/boe.town.cpp | 5 ++++- src/classes/item.cpp | 6 ++++-- src/classes/item.h | 2 +- src/classes/pc.cpp | 1 + src/scenedit/scen.actions.cpp | 2 ++ src/tools/fileio_party.cpp | 11 +++++++++++ 14 files changed, 62 insertions(+), 46 deletions(-) diff --git a/src/boe.actions.cpp b/src/boe.actions.cpp index 5ebf1239..f26bdf12 100644 --- a/src/boe.actions.cpp +++ b/src/boe.actions.cpp @@ -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; } diff --git a/src/boe.graphics.cpp b/src/boe.graphics.cpp index bed9cb8c..5c2173ce 100644 --- a/src/boe.graphics.cpp +++ b/src/boe.graphics.cpp @@ -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}; diff --git a/src/boe.items.cpp b/src/boe.items.cpp index adc1dc48..2a3c2fa9 100644 --- a/src/boe.items.cpp +++ b/src/boe.items.cpp @@ -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) - 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); - } + 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); } } } diff --git a/src/boe.items.h b/src/boe.items.h index f2772b24..0ca9117c 100644 --- a/src/boe.items.h +++ b/src/boe.items.h @@ -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); diff --git a/src/boe.monster.cpp b/src/boe.monster.cpp index 005c5236..53477ee9 100644 --- a/src/boe.monster.cpp +++ b/src/boe.monster.cpp @@ -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; } diff --git a/src/boe.newgraph.cpp b/src/boe.newgraph.cpp index de068d94..a63e77cf 100644 --- a/src/boe.newgraph.cpp +++ b/src/boe.newgraph.cpp @@ -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) diff --git a/src/boe.party.cpp b/src/boe.party.cpp index 7495ac37..d6844231 100644 --- a/src/boe.party.cpp +++ b/src/boe.party.cpp @@ -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) diff --git a/src/boe.specials.cpp b/src/boe.specials.cpp index 72ab65a2..0032474e 100644 --- a/src/boe.specials.cpp +++ b/src/boe.specials.cpp @@ -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: diff --git a/src/boe.town.cpp b/src/boe.town.cpp index 8cb29cc6..a9a9fd56 100644 --- a/src/boe.town.cpp +++ b/src/boe.town.cpp @@ -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; } } diff --git a/src/classes/item.cpp b/src/classes/item.cpp index 24ae3875..2b013171 100644 --- a/src/classes/item.cpp +++ b/src/classes/item.cpp @@ -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; diff --git a/src/classes/item.h b/src/classes/item.h index b1dd8300..abb5de7c 100644 --- a/src/classes/item.h +++ b/src/classes/item.h @@ -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; diff --git a/src/classes/pc.cpp b/src/classes/pc.cpp index 2fb5ae7e..ffcd02cc 100644 --- a/src/classes/pc.cpp +++ b/src/classes/pc.cpp @@ -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) { diff --git a/src/scenedit/scen.actions.cpp b/src/scenedit/scen.actions.cpp index c8995c45..d8f705f7 100644 --- a/src/scenedit/scen.actions.cpp +++ b/src/scenedit/scen.actions.cpp @@ -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; } diff --git a/src/tools/fileio_party.cpp b/src/tools/fileio_party.cpp index a0c7d05d..b74b741e 100644 --- a/src/tools/fileio_party.cpp +++ b/src/tools/fileio_party.cpp @@ -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;