make pushing crates/barrels/blocks DRY

This commit is contained in:
2025-05-19 19:16:22 -05:00
parent c2352082bf
commit e3b0934d15
4 changed files with 64 additions and 41 deletions

View File

@@ -8,6 +8,7 @@
#include "boe.monster.hpp"
#include "boe.combat.hpp"
#include "boe.text.hpp"
#include "boe.town.hpp"
#include "boe.specials.hpp"
#include "boe.items.hpp"
#include "sounds.hpp"
@@ -703,8 +704,6 @@ bool try_move(short i,location start,short x,short y) {
}
bool combat_move_monster(short which,location destination) {
if(!monst_can_be_there(destination,which))
return false;
else if(!monst_check_special_terrain(destination,2,which))
@@ -798,7 +797,7 @@ bool monster_placid(short m_num) {
}
// This damages a monster by any fields it's in, and destroys any barrels or crates
// it's stiing on.
// it's sitting on.
void monst_inflict_fields(short which_monst) {
short r1;
location where_check;
@@ -993,29 +992,21 @@ static bool monst_check_one_special_terrain(location where_check,short mode,shor
if(monster_placid(which_monst))
can_enter = false;
else {
to_loc = push_loc(from_loc,where_check);
univ.town.set_crate(where_check.x,where_check.y,false);
if(to_loc.x > 0)
univ.town.set_crate(to_loc.x,to_loc.y, true);
for(short 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].held)
univ.town.items[i].item_loc = to_loc;
push_thing(PUSH_CRATE, from_loc, where_check);
}
}
if(univ.town.is_barrel(where_check.x,where_check.y)) {
if(monster_placid(which_monst))
can_enter = false;
else {
to_loc = push_loc(from_loc,where_check);
univ.town.set_barrel(where_check.x,where_check.y,false);
if(to_loc.x > 0)
univ.town.set_barrel(to_loc.x,to_loc.y,true);
for(short 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].held)
univ.town.items[i].item_loc = to_loc;
push_thing(PUSH_BARREL, from_loc, where_check);
}
}
if(univ.town.is_block(where_check.x, where_check.y)){
if(monster_placid(which_monst))
can_enter = false;
else {
push_thing(PUSH_BLOCK, from_loc, where_check);
}
}
if(monster_placid(which_monst) && // monsters don't hop into bed when things are calm

View File

@@ -287,32 +287,15 @@ bool check_special_terrain(location where_check,eSpecCtx mode,cPlayer& which_pc,
}
if(univ.town.is_crate(where_check.x,where_check.y)) {
add_string_to_buf(" You push the crate.");
to_loc = push_loc(from_loc,where_check);
univ.town.set_crate(where_check.x,where_check.y,false);
if(to_loc.x > 0)
univ.town.set_crate(to_loc.x,to_loc.y,true);
for(short 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].held)
univ.town.items[i].item_loc = to_loc;
push_thing(PUSH_CRATE, from_loc, where_check);
}
if(univ.town.is_barrel(where_check.x,where_check.y)) {
add_string_to_buf(" You push the barrel.");
to_loc = push_loc(from_loc,where_check);
univ.town.set_barrel(where_check.x,where_check.y,false);
if(to_loc.x > 0)
univ.town.set_barrel(to_loc.x,to_loc.y,true);
for(short 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].held)
univ.town.items[i].item_loc = to_loc;
push_thing(PUSH_BARREL, from_loc, where_check);
}
if(univ.town.is_block(where_check.x,where_check.y)) {
add_string_to_buf(" You push the stone block.");
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,true);
push_thing(PUSH_BLOCK, from_loc, where_check);
}
}
@@ -1815,7 +1798,6 @@ void push_things() {
return false;
};
// TODO monsters could smash crates and barrels, and crash into blocks
// Push monsters
for(short i = 0; i < univ.town.monst.size(); i++){
cCreature& creature = univ.town.monst[i];
@@ -1825,6 +1807,7 @@ void push_things() {
}else{
check_push(creature.cur_loc);
}
// Monsters destroy crates/barrels in monst_inflict_fields() in boe.monster.cpp
}
}
// Push items

View File

@@ -1600,3 +1600,44 @@ bool quadrant_legal(short i, short j) {
return false;
return true;
}
void push_thing(ePushableThing type, location pusher_loc, location thing_loc) {
location to_loc = push_loc(pusher_loc, thing_loc);
move_thing(type, thing_loc, to_loc);
}
void move_thing(ePushableThing type, location from_loc, location to_loc) {
// Get the thing out of its spot
switch(type){
case PUSH_CRATE:
univ.town.set_crate(from_loc.x, from_loc.y, false);
break;
case PUSH_BARREL:
univ.town.set_barrel(from_loc.x, from_loc.y, false);
break;
case PUSH_BLOCK:
univ.town.set_block(from_loc.x, from_loc.y, false);
break;
}
// If it wasn't deleted, put it in the new spot
if(to_loc.x > 0){
switch(type){
case PUSH_CRATE:
univ.town.set_crate(to_loc.x, to_loc.y, true);
break;
case PUSH_BARREL:
univ.town.set_barrel(to_loc.x, to_loc.y, true);
break;
case PUSH_BLOCK:
univ.town.set_block(to_loc.x, to_loc.y, true);
break;
}
}
// Move items inside crate or barrel
if(type == PUSH_CRATE || type == PUSH_BARREL){
for(short i = 0; i < univ.town.items.size(); i++)
if(univ.town.items[i].variety != eItemType::NO_ITEM && univ.town.items[i].item_loc == from_loc
&& univ.town.items[i].contained && univ.town.items[i].held)
univ.town.items[i].item_loc = to_loc;
}
}

View File

@@ -33,3 +33,11 @@ bool is_door(location destination);
void display_map();
void check_done();
bool quadrant_legal(short i, short j) ;
enum ePushableThing {
PUSH_CRATE,
PUSH_BARREL,
PUSH_BLOCK,
};
void push_thing(ePushableThing type, location pusher_loc, location thing_loc);
void move_thing(ePushableThing type, location from_loc, location to_loc);