Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Isekai #76955

Draft
wants to merge 53 commits into
base: master
Choose a base branch
from
Draft

Isekai #76955

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
59aec51
initial barebones implementation of world swapping
bombasticSlacks Sep 27, 2024
95fb82a
added debug text input for subworld type; subworlds now in /maps/worl…
Blueflowerss Sep 27, 2024
98427fc
fixed visibility cache crash
Blueflowerss Sep 27, 2024
8f2709b
Update example_eocs.json
Blueflowerss Sep 27, 2024
54a154d
add attribution
bombasticSlacks Sep 27, 2024
cf6f563
typing 'default' into the world_test EOC returns you to main world
Blueflowerss Sep 29, 2024
ff1c110
update EOC to mention the 'default' option
Blueflowerss Sep 29, 2024
76c1db3
changed 'map_prefix' to 'world_prefix' where appropriate. Began some …
Blueflowerss Sep 29, 2024
a582962
moved 'world_prefix' to 'map.h'
Blueflowerss Sep 29, 2024
819924b
made overmap save it's data to /worlds subdirectory if world_prefix i…
Blueflowerss Sep 29, 2024
8486320
monsters are now preserved between worlds
Blueflowerss Sep 30, 2024
8070dd1
added map memory to things that are saved
Blueflowerss Sep 30, 2024
b1731ef
add a check to stop teleports in other worlds from causing a world swap
Blueflowerss Oct 1, 2024
e5b1ac0
add mention of the EOC change in EFFECT_ON_CONDITION.md
Blueflowerss Oct 1, 2024
c212a44
hacky way of preventing toilet related mapgen
Blueflowerss Oct 2, 2024
7c29f3c
add a seperate bool variable from 'new_game', 'swapping_worlds'. Also…
Blueflowerss Oct 2, 2024
21e725a
savefile now stores the world_prefix the player was on
Blueflowerss Oct 2, 2024
db65c37
moved world swap functions over to new 'multiworld.h/cpp' files and f…
Blueflowerss Oct 3, 2024
d67883f
don't teleport player to saved in world before the game has even loaded
Blueflowerss Oct 3, 2024
eae7354
add 'u_in_world' and add an example usage to 'EOC_world_swap'
Blueflowerss Oct 3, 2024
3ae7dc9
made u_teleport display a succesful message if either the teleport or…
Blueflowerss Oct 3, 2024
c69b356
Update src/condition.cpp
Blueflowerss Oct 3, 2024
825852a
Update src/condition.cpp
Blueflowerss Oct 3, 2024
c1f158e
Update src/do_turn.cpp
Blueflowerss Oct 3, 2024
1cf392d
Update src/mapbuffer.cpp
Blueflowerss Oct 3, 2024
87a26d1
Update src/mapbuffer.cpp
Blueflowerss Oct 3, 2024
12a4955
Update src/mapbuffer.cpp
Blueflowerss Oct 3, 2024
40a1f11
Update src/multiworld.cpp
Blueflowerss Oct 3, 2024
394590b
Update src/multiworld.cpp
Blueflowerss Oct 3, 2024
b1e80ab
Update src/multiworld.cpp
Blueflowerss Oct 3, 2024
aa8bd2a
Update src/multiworld.cpp
Blueflowerss Oct 3, 2024
bcb62ad
Delete sta1xwkz
Blueflowerss Oct 3, 2024
408e25e
Apply suggestions from code review
Blueflowerss Oct 3, 2024
5d8705a
resolve merge conflict
Blueflowerss Oct 3, 2024
1fc4d80
bump savegame version number on test
Blueflowerss Oct 3, 2024
6551f23
apply clang tidy suggestions
Blueflowerss Oct 4, 2024
e1b4c95
Update src/multiworld.cpp
Blueflowerss Oct 4, 2024
d437340
applied more clang-tidy suggestions
Blueflowerss Oct 4, 2024
2c41b83
Apply suggestions from code review
Blueflowerss Oct 4, 2024
5a76beb
Update src/multiworld.h
Blueflowerss Oct 4, 2024
6ef8653
remove pointless comment
Blueflowerss Oct 4, 2024
4bb4dd6
Update multiworld.h
Blueflowerss Oct 4, 2024
4237c91
Update multiworld.h again
Blueflowerss Oct 4, 2024
41d2c74
Update multiworld.cpp
Blueflowerss Oct 4, 2024
2c63b77
Update multiworld.h final
Blueflowerss Oct 4, 2024
d4c8a0a
Apply suggestions from code review
Blueflowerss Oct 4, 2024
434ebd1
add code optimization
Blueflowerss Oct 5, 2024
2005baf
remove redundant declarations
Blueflowerss Oct 7, 2024
f4eed94
Update EFFECT_ON_CONDITION.md
Blueflowerss Oct 7, 2024
d02519d
Update multiworld.h
Blueflowerss Oct 7, 2024
e23ae45
Fold multiworld code into game class
kevingranade Oct 10, 2024
f9fb4a3
Move dimension path handling to path info proper.
kevingranade Oct 10, 2024
745ea20
Bugfixes
kevingranade Oct 10, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions data/json/effects_on_condition/example_eocs.json
Original file line number Diff line number Diff line change
Expand Up @@ -522,5 +522,31 @@
{ "math": [ "ITEM_POWER_PERC", "=", "n_val('power_percentage')" ] },
{ "u_message": "<global_val:ITEM_POWER> / <global_val:ITEM_POWER_MAX> (<global_val:ITEM_POWER_PERC>%)" }
]
},
{
"type": "effect_on_condition",
"id": "EOC_dimension_swap_test",
"//": "shifts the character to a new dimension",
"global": true,
"effect": [
{
"set_string_var": "",
"string_input": {
"title": { "i18n": true, "str": "teleport to dimension named:" },
"description": { "i18n": true, "str": "'default' returns you to main dimension" },
"width": 30
},
"target_var": { "u_val": "destination_dimension" }
},
{ "u_location_variable": { "u_val": "tele_test" }, "x_adjust": 0, "y_adjust": 0 },
{
"u_teleport": { "u_val": "tele_test" },
"dimension_prefix": { "u_val": "destination_dimension" },
"fail_message": "your body doesn't move",
"success_message": "This place feels different."
},
{ "u_message": { "u_val": "destination_dimension" } },
{ "if": { "u_in_dimension": "" }, "then": { "u_message": "home sweet home" } }
]
}
]
1 change: 1 addition & 0 deletions doc/EFFECT_ON_CONDITION.md
Original file line number Diff line number Diff line change
Expand Up @@ -3802,6 +3802,7 @@ You or NPC is teleported to `target_var` coordinates
| "success_message" | optional | string or [variable object](#variable-object) | message, that would be printed, if teleportation was successful |
| "fail_message" | optional | string or [variable object](#variable-object) | message, that would be printed, if teleportation was failed, like if coordinates contained creature or impassable obstacle (like wall) |
| "force" | optional | boolean | default false; if true, teleportation can't fail - any creature, that stand on target coordinates, would be brutally telefragged, and if impassable obstacle occur, the closest point would be picked instead |
| "dimension_prefix" | optional | string | default ""; if a value is specified, will teleport the player to a dimension named after the prefix. Currently very WIP |

##### Valid talkers:

Expand Down
9 changes: 9 additions & 0 deletions src/condition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -835,6 +835,14 @@ conditional_t::func f_is_wearing( const JsonObject &jo, std::string_view member,
};
}

conditional_t::func f_in_dimension( const JsonObject &jo, std::string_view member )
{
str_or_var dimension_prefix = get_str_or_var( jo.get_member( member ), member, true );
return [dimension_prefix]( dialogue const & d ) {
return ( g->get_dimension_prefix() == dimension_prefix.evaluate( d ) );
};
}

conditional_t::func f_has_item( const JsonObject &jo, std::string_view member, bool is_npc )
{
str_or_var item_id = get_str_or_var( jo.get_member( member ), member, true );
Expand Down Expand Up @@ -2515,6 +2523,7 @@ parsers = {
{"u_has_perception", "npc_has_perception", jarg::member | jarg::array, &conditional_fun::f_has_perception },
{"u_has_part_temp", "npc_has_part_temp", jarg::member | jarg::array, &conditional_fun::f_has_part_temp },
{"u_is_wearing", "npc_is_wearing", jarg::member, &conditional_fun::f_is_wearing },
{"u_in_dimension", jarg::member, &conditional_fun::f_in_dimension },
{"u_has_item", "npc_has_item", jarg::member, &conditional_fun::f_has_item },
{"u_has_item_with_flag", "npc_has_item_with_flag", jarg::member, &conditional_fun::f_has_item_with_flag },
{"u_has_items", "npc_has_items", jarg::member, &conditional_fun::f_has_items },
Expand Down
5 changes: 4 additions & 1 deletion src/do_turn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,10 @@ bool do_turn()
g->gamemode->per_turn();
calendar::turn += 1_turns;
}

//used for dimension swapping
if( g->swapping_dimensions ) {
g->swapping_dimensions = false;
}
play_music( music::get_music_id_string() );

// starting a new turn, clear out temperature cache
Expand Down
65 changes: 64 additions & 1 deletion src/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5379,7 +5379,7 @@ bool game::revive_corpse( const tripoint &p, item &it, int radius )
}
// If this is not here, the game may attempt to spawn a monster before the map exists,
// leading to it querying for furniture, and crashing.
if( g->new_game ) {
if( g->new_game || g->swapping_dimensions ) {
return false;
}
if( it.has_flag( flag_FIELD_DRESS ) || it.has_flag( flag_FIELD_DRESS_FAILED ) ||
Expand Down Expand Up @@ -12325,6 +12325,55 @@ void game::vertical_move( int movez, bool force, bool peeking )
cata_event_dispatch::avatar_moves( old_abs_pos.raw(), u, m );
}

bool game::travel_to_dimension( const std::string &new_prefix )
{
map &here = get_map();
avatar &player = get_avatar();
unload_npcs();
for( monster &critter : all_monsters() ) {
despawn_monster( critter );
}
if( player.in_vehicle ) {
here.unboard_vehicle( player.pos_bub() );
}
// Make sure we don't mess up savedata if for some reason maps can't be saved
if( !save_maps() ) {
return false;
}
for( int z = -OVERMAP_DEPTH; z <= OVERMAP_HEIGHT; z++ ) {
here.clear_vehicle_list( z );
}
here.rebuild_vehicle_level_caches();
// Inputting an empty string to the text input EOC fails
// so i'm using 'default' as empty/main dimension
if( new_prefix != "default" ) {
dimension_prefix = new_prefix;
} else {
dimension_prefix.clear();
}
MAPBUFFER.clear();
// FIXME hack to prevent crashes from temperature checks
// This returns to false in 'on_turn()' so it should be fine?
swapping_dimensions = true;
// In theory if we skipped the next two lines we'd have an exact copy of the overmap
// from the past dimension, only with differences noticeable in the local map.
overmap_buffer.clear();
// load/create new overmap
overmap_buffer.get( point_abs_om{} );
// Loads submaps and invalidate related caches
here.load( tripoint_abs_sm( here.get_abs_sub() ), false );
here.access_cache( here.get_abs_sub().z() ).map_memory_cache_dec.reset();
here.access_cache( here.get_abs_sub().z() ).map_memory_cache_ter.reset();
here.invalidate_visibility_cache();
load_npcs();
// Handle static monsters
here.spawn_monsters( true, true );
update_overmap_seen();
// Update weather now as it could be different on the new location
get_weather().nextweather = calendar::turn;
return true;
}

void game::start_hauling( const tripoint &pos )
{
std::vector<item_location> candidate_items = m.get_haulable_items( pos );
Expand Down Expand Up @@ -13291,6 +13340,20 @@ cata_path PATH_INFO::world_base_save_path_path()
return world_generator->active_world->folder_path_path();
}

cata_path PATH_INFO::current_dimension_save_path_path()
{
std::string dimension_prefix = g->get_dimension_prefix();
if( !dimension_prefix.empty() ) {
return PATH_INFO::world_base_save_path_path() / "dimensions" / dimension_prefix;
}
return PATH_INFO::world_base_save_path_path();
}

cata_path PATH_INFO::current_dimension_player_save_path_path()
{
return PATH_INFO::current_dimension_save_path_path() / base64_encode( get_avatar().get_save_id() );
}

void game::shift_destination_preview( const point &delta )
{
for( tripoint_bub_ms &p : destination_preview ) {
Expand Down
18 changes: 18 additions & 0 deletions src/game.h
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,18 @@
* If peeking == true, forbids some exotic movement options
*/
void vertical_move( int z, bool force, bool peeking = false );
/**
* Moves the player to an alternate dimension.
* The prefix identifies the dimension and its properties.
*/
bool travel_to_dimension( const std::string &prefix );
/**
* Retrieve the identifier of the current dimension.
* TODO: this should be a dereferencable id that gives properties of the dimension.
*/
std::string get_dimension_prefix() {
return dimension_prefix;
}
void start_hauling( const tripoint &pos );
/** Returns the other end of the stairs (if any). May query, affect u etc.
* @param pos Disable queries and msgs if not the same position as player.
Expand Down Expand Up @@ -1314,6 +1326,12 @@
const tripoint &examp,
climbing_aid_id aid,
bool deploy_affordance = false );
//currently used as a hacky workaround for dimension swapping
bool swapping_dimensions = false; // NOLINT (cata-serialize)
private:
// Stores the currently occupoed dimension.
// TODO: should be an id instead of a string.
std::string dimension_prefix;

Check failure on line 1334 in src/game.h

View workflow job for this annotation

GitHub Actions / build (src)

Function 'serialize' appears to be a serialization function for class 'game' but does not mention field 'dimension_prefix'. [cata-serialize,-warnings-as-errors]
};

// Returns temperature modifier from direct heat radiation of nearby sources
Expand Down
2 changes: 1 addition & 1 deletion src/item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12845,7 +12845,7 @@ bool item::process_temperature_rot( float insulation, const tripoint &pos, map &

units::temperature_delta temp_mod;
// Toilets and vending machines will try to get the heat radiation and convection during mapgen and segfault.
if( !g->new_game ) {
if( !g->new_game && !g->swapping_dimensions ) {
temp_mod = get_heat_radiation( pos );
temp_mod += get_convection_temperature( pos );
temp_mod += here.get_temperature_mod( pos );
Expand Down
2 changes: 1 addition & 1 deletion src/map_memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ static constexpr int MM_SIZE = MAPSIZE * 2;

static cata_path find_mm_dir()
{
return PATH_INFO::player_base_save_path_path() + ".mm1";
return PATH_INFO::current_dimension_player_save_path_path() + ".mm1";
}

static cata_path find_region_path( const cata_path &dirname, const tripoint &p )
Expand Down
12 changes: 5 additions & 7 deletions src/mapbuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@

class game;
// NOLINTNEXTLINE(cata-static-declarations)
extern std::unique_ptr<game> g;
// NOLINTNEXTLINE(cata-static-declarations)
extern const int savegame_version;

static cata_path find_quad_path( const cata_path &dirname, const tripoint_abs_omt &om_addr )
Expand All @@ -40,9 +38,10 @@ static cata_path find_quad_path( const cata_path &dirname, const tripoint_abs_om
static cata_path find_dirname( const tripoint_abs_omt &om_addr )
{
const tripoint_abs_seg segment_addr = project_to<coords::seg>( om_addr );
return PATH_INFO::world_base_save_path_path() / "maps" / string_format( "%d.%d.%d",
segment_addr.x(),
segment_addr.y(), segment_addr.z() );
std::string segment = string_format( "%d.%d.%d",
segment_addr.x(),
segment_addr.y(), segment_addr.z() );
return PATH_INFO::current_dimension_save_path_path() / "maps" / segment;
}

mapbuffer MAPBUFFER;
Expand Down Expand Up @@ -136,8 +135,7 @@ bool mapbuffer::submap_exists( const tripoint_abs_sm &p )

void mapbuffer::save( bool delete_after_save )
{
assure_dir_exist( PATH_INFO::world_base_save_path() + "/maps" );

assure_dir_exist( PATH_INFO::current_dimension_save_path_path() / "maps" );
int num_saved_submaps = 0;
int num_total_submaps = submaps.size();

Expand Down
19 changes: 17 additions & 2 deletions src/npctalk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6715,13 +6715,28 @@ talk_effect_fun_t::func f_teleport( const JsonObject &jo, std::string_view membe
} else {
success_message.str_val = translation();
}
str_or_var dimension_prefix;
if( jo.has_member( "dimension_prefix" ) ) {
dimension_prefix = get_str_or_var( jo.get_member( "dimension_prefix" ),
"dimension_prefix", false, "" );
} else {
dimension_prefix.str_val = "";
}
bool force = jo.get_bool( "force", false );
return [is_npc, target_var, fail_message, success_message, force]( dialogue const & d ) {
return [is_npc, target_var, fail_message, success_message, force,
dimension_prefix]( dialogue const & d ) {
tripoint_abs_ms target_pos = get_tripoint_from_var( target_var, d, is_npc );
Creature *teleporter = d.actor( is_npc )->get_creature();
if( teleporter ) {
std::string prefix = dimension_prefix.evaluate( d );
bool successful_dimension_swap = false;
// Make sure we don't cause a dimension swap on every
// short/long range teleport outside the default dimension
if( !prefix.empty() && prefix != g->get_dimension_prefix() ) {
successful_dimension_swap = g->travel_to_dimension( prefix );
}
if( teleport::teleport_to_point( *teleporter, get_map().bub_from_abs( target_pos ), true, false,
false, force ) ) {
false, force ) || successful_dimension_swap ) {
teleporter->add_msg_if_player( success_message.evaluate( d ) );
} else {
teleporter->add_msg_if_player( fail_message.evaluate( d ) );
Expand Down
3 changes: 2 additions & 1 deletion src/overmapbuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ int camp_reference::get_distance_from_bounds() const

cata_path overmapbuffer::terrain_filename( const point_abs_om &p )
{
return PATH_INFO::world_base_save_path_path() / string_format( "o.%d.%d", p.x(), p.y() );
return PATH_INFO::current_dimension_save_path_path() / string_format( "o.%d.%d", p.x(), p.y() );
}

cata_path overmapbuffer::player_filename( const point_abs_om &p )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also add dimension stuff here

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aha, thanks, I missed that the "player" part was all "seen" data, need to wrap up the last of those.

Expand Down Expand Up @@ -305,6 +305,7 @@ overmap *overmapbuffer::get_existing( const point_abs_om &p )
// checked in a previous call of this function).
return nullptr;
}
assure_dir_exist( PATH_INFO::current_dimension_save_path_path() );
if( file_exist( terrain_filename( p ) ) ) {
// File exists, load it normally (the get function
// indirectly call overmap::open to do so).
Expand Down
2 changes: 2 additions & 0 deletions src/path_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ cata_path user_keybindings();
cata_path user_moddir_path();
cata_path user_sound();
cata_path world_base_save_path_path();
cata_path current_dimension_save_path_path();
cata_path current_dimension_player_save_path_path();

void set_datadir( const std::string &datadir );
void set_config_dir( const std::string &config_dir );
Expand Down
7 changes: 6 additions & 1 deletion src/savegame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ extern std::map<std::string, std::list<input_event>> quick_shortcuts_map;
* Changes that break backwards compatibility should bump this number, so the game can
* load a legacy format loader.
*/
const int savegame_version = 34;
const int savegame_version = 35;

/*
* This is a global set by detected version header in .sav, maps.txt, or overmap.
Expand Down Expand Up @@ -98,6 +98,7 @@ void game::serialize( std::ostream &fout )
json.member( "calendar_start", calendar::start_of_cataclysm );
json.member( "game_start", calendar::start_of_game );
json.member( "initial_season", static_cast<int>( calendar::initial_season ) );
json.member( "dimension_prefix", g->get_dimension_prefix() );
json.member( "auto_travel_mode", auto_travel_mode );
json.member( "run_mode", static_cast<int>( safe_mode ) );
json.member( "mostseen", mostseen );
Expand Down Expand Up @@ -220,6 +221,10 @@ void game::unserialize( std::istream &fin, const cata_path &path )
calendar::initial_season = static_cast<season_type>( data.get_int( "initial_season",
static_cast<int>( SPRING ) ) );

std::string loaded_dimension_prefix;
if( data.read( "dimension_prefix", loaded_dimension_prefix ) ) {
dimension_prefix = loaded_dimension_prefix;
}
data.read( "auto_travel_mode", auto_travel_mode );
data.read( "run_mode", tmprun );
data.read( "mostseen", mostseen );
Expand Down
2 changes: 1 addition & 1 deletion src/weather.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -965,7 +965,7 @@ units::temperature weather_manager::get_temperature( const tripoint &location )
//underground temperature = average New England temperature = 43F/6C
units::temperature temp = location.z < 0 ? AVERAGE_ANNUAL_TEMPERATURE : temperature;

if( !g->new_game ) {
if( !g->new_game && !g->swapping_dimensions ) {
units::temperature_delta temp_mod;
temp_mod = get_heat_radiation( location );
temp_mod += get_convection_temperature( location );
Expand Down
2 changes: 1 addition & 1 deletion tests/submap_load_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -851,7 +851,7 @@ static JsonValue submap_fd_pre_migration = json_loader::from_string( submap_fd_p
static void load_from_jsin( submap &sm, const JsonValue &jsin )
{
// Ensure that the JSON is up to date for our savegame version
REQUIRE( savegame_version == 34 );
REQUIRE( savegame_version == 35 );
int version = 0;
JsonObject sm_json = jsin.get_object();
if( sm_json.has_member( "version" ) ) {
Expand Down
Loading