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:
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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};
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
|
||||
}
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
@@ -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:
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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) {
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user