Cataclysm-DDA/tests/gates_test.cpp

232 lines
8.0 KiB
C++

#include "avatar.h"
#include "avatar_action.h"
#include "cata_catch.h"
#include "coordinates.h"
#include "gates.h"
#include "map.h"
#include "mapdata.h"
#include "map_helpers.h"
#include "player_helpers.h"
#include "sounds.h"
#include "type_id.h"
TEST_CASE( "doors should be able to open and close", "[gates]" )
{
map &here = get_map();
clear_map();
tripoint pos = get_avatar().pos() + point_east;
WHEN( "the door is unlocked" ) {
// create closed door on tile next to player
REQUIRE( here.ter_set( pos, t_door_c ) );
REQUIRE( here.ter( pos ).obj().id == t_door_c->id );
THEN( "the door should be able to open and close" ) {
CHECK( here.open_door( get_avatar(), pos, true, false ) );
CHECK( here.ter( pos ).obj().id == t_door_o->id );
CHECK( here.close_door( pos, true, false ) );
CHECK( here.ter( pos ).obj().id == t_door_c->id );
}
}
WHEN( "the door is locked" ) {
// create locked door on tile next to player
REQUIRE( here.ter_set( pos, t_door_locked ) );
REQUIRE( here.ter( pos ).obj().id == t_door_locked->id );
THEN( "the door should not be able to open" ) {
CHECK_FALSE( here.close_door( pos, true, false ) );
CHECK( here.ter( pos ).obj().id == t_door_locked->id );
}
}
}
TEST_CASE( "windows should be able to open and close", "[gates]" )
{
map &here = get_map();
clear_map();
tripoint pos = get_avatar().pos() + point_east;
// create closed window on tile next to player
REQUIRE( here.ter_set( pos, t_window_no_curtains ) );
REQUIRE( here.ter( pos ).obj().id == t_window_no_curtains->id );
WHEN( "the window is opened from the inside" ) {
THEN( "the window should be able to open" ) {
CHECK( here.open_door( get_avatar(), pos, true, false ) );
CHECK( here.ter( pos ).obj().id == t_window_no_curtains_open->id );
}
}
WHEN( "the window is opened from the outside" ) {
THEN( "the window should not be able to open" ) {
CHECK_FALSE( here.close_door( pos, false, false ) );
CHECK( here.ter( pos ).obj().id == t_window_no_curtains->id );
}
}
}
// Note that it is not intended for all doors and windows to make swish sound,
// some doors and windows might make other types of sounds in the future
// TODO: update test case when door and window sounds become defined in JSON.
TEST_CASE( "doors and windows should make whoosh sound", "[gates]" )
{
map &here = get_map();
clear_map();
clear_avatar();
sounds::reset_sounds();
tripoint pos = get_avatar().pos() + point_east;
WHEN( "the door is opened" ) {
REQUIRE( here.ter_set( pos, t_door_c ) );
REQUIRE( here.ter( pos ).obj().id == t_door_c->id );
// make sure there is no sounds before action
REQUIRE( sounds::get_monster_sounds().first.empty() );
REQUIRE( here.open_door( get_avatar(), pos, true, false ) );
REQUIRE( here.ter( pos ).obj().id == t_door_o->id );
THEN( "the door should make a swish sound" ) {
CHECK_FALSE( sounds::get_monster_sounds().first.empty() );
}
}
WHEN( "the door is closed" ) {
REQUIRE( here.ter_set( pos, t_door_o ) );
REQUIRE( here.ter( pos ).obj().id == t_door_o->id );
// make sure there is no sounds before action
REQUIRE( sounds::get_monster_sounds().first.empty() );
REQUIRE( here.close_door( pos, true, false ) );
REQUIRE( here.ter( pos ).obj().id == t_door_c->id );
THEN( "the door should make a swish sound" ) {
CHECK_FALSE( sounds::get_monster_sounds().first.empty() );
}
}
WHEN( "the window is opened" ) {
REQUIRE( here.ter_set( pos, t_window_no_curtains ) );
REQUIRE( here.ter( pos ).obj().id == t_window_no_curtains->id );
// make sure there is no sounds before action
REQUIRE( sounds::get_monster_sounds().first.empty() );
REQUIRE( here.open_door( get_avatar(), pos, true, false ) );
REQUIRE( here.ter( pos ).obj().id == t_window_no_curtains_open->id );
THEN( "the window should make a swish sound" ) {
CHECK_FALSE( sounds::get_monster_sounds().first.empty() );
}
}
WHEN( "the window is closed" ) {
REQUIRE( here.ter_set( pos, t_window_no_curtains_open ) );
REQUIRE( here.ter( pos ).obj().id == t_window_no_curtains_open->id );
// make sure there is no sounds before action
REQUIRE( sounds::get_monster_sounds().first.empty() );
REQUIRE( here.close_door( pos, true, false ) );
REQUIRE( here.ter( pos ).obj().id == t_window_no_curtains->id );
THEN( "the window should make a swish sound" ) {
CHECK_FALSE( sounds::get_monster_sounds().first.empty() );
}
}
}
TEST_CASE( "character should lose moves when opening or closing doors or windows", "[gates]" )
{
avatar &they = get_avatar();
map &here = get_map();
clear_avatar();
clear_map();
tripoint pos = get_avatar().pos() + point_east;
// the movement cost for opening and closing gates
// remember to update this if changing value in code
const int open_move_cost = 100;
// set move value to 0 so we know how many
// move points were spent opening and closing gates
they.moves = 0;
WHEN( "avatar opens door" ) {
REQUIRE( here.ter_set( pos, t_door_c ) );
REQUIRE( here.ter( pos ).obj().id == t_door_c->id );
REQUIRE( avatar_action::move( they, here, tripoint_east ) );
THEN( "avatar should spend move points" ) {
CHECK( they.moves == -open_move_cost );
}
}
WHEN( "avatar fails to open locked door" ) {
REQUIRE( here.ter_set( pos, t_door_locked ) );
REQUIRE( here.ter( pos ).obj().id == t_door_locked->id );
REQUIRE_FALSE( avatar_action::move( they, here, tripoint_east ) );
THEN( "avatar should not spend move points" ) {
CHECK( they.moves == 0 );
}
}
GIVEN( "that avatar is outdoors" ) {
REQUIRE( here.is_outside( pos ) );
WHEN( "avatar fails to open window" ) {
REQUIRE( here.ter_set( pos, t_window_no_curtains ) );
REQUIRE( here.ter( pos ).obj().id == t_window_no_curtains->id );
REQUIRE_FALSE( avatar_action::move( they, here, tripoint_east ) );
THEN( "avatar should spend move points" ) {
CHECK( they.moves == 0 );
}
}
}
GIVEN( "that avatar is indoors" ) {
ter_id ter_flat_roof = ter_id( "t_flat_roof" );
ter_id ter_concrete_floor = ter_id( "t_thconc_floor" );
ter_id ter_concrete_wall = ter_id( "t_concrete_wall" );
// enclose the player in single tile room surrounded with
// concrete floor and roof to test opening windows from indoors
const std::vector<tripoint> room_walls{
pos + point_south_east,
pos + point_south,
pos + point_south_west,
pos + point_west,
pos + point_north_west,
pos + point_north,
pos + point_north_east
};
for( tripoint point : room_walls ) {
REQUIRE( here.ter_set( point, ter_concrete_wall ) );
}
REQUIRE( here.ter_set( pos, ter_concrete_floor ) );
REQUIRE( here.ter_set( pos + tripoint_above, ter_flat_roof ) );
// mark map cache as dirty and rebuild it so that map starts
// recognizing that tile player is standing on is indoors
here.set_outside_cache_dirty( pos.z );
here.build_outside_cache( pos.z );
REQUIRE_FALSE( here.is_outside( pos ) );
WHEN( "avatar opens window" ) {
REQUIRE( here.ter_set( pos, t_window_no_curtains ) );
REQUIRE( here.ter( pos ).obj().id == t_window_no_curtains->id );
REQUIRE( avatar_action::move( they, here, tripoint_east ) );
THEN( "avatar should spend move points" ) {
CHECK( they.moves == -open_move_cost );
}
}
}
}