From d3b7495649538e7d915c70b7a9da3bd69859964a Mon Sep 17 00:00:00 2001 From: Zlorthishen <79779913+Zlorthishen@users.noreply.github.com> Date: Fri, 15 Nov 2024 20:02:47 -0600 Subject: [PATCH 1/3] initial commit Co-Authored-By: anothersimulacrum <42699974+anothersimulacrum@users.noreply.github.com> --- .../overmap_special/aircraft_carrier.json | 2 +- .../overmap/overmap_special/specials.json | 4 ++-- src/overmap.cpp | 20 ++++++++++++++-- src/overmapbuffer.cpp | 14 +++++++++++ src/overmapbuffer.h | 23 +++++++++++++++++++ src/savegame.cpp | 21 +++++++++++++++++ 6 files changed, 79 insertions(+), 5 deletions(-) diff --git a/data/json/overmap/overmap_special/aircraft_carrier.json b/data/json/overmap/overmap_special/aircraft_carrier.json index ecda177f8f79..daa2697d10fc 100644 --- a/data/json/overmap/overmap_special/aircraft_carrier.json +++ b/data/json/overmap/overmap_special/aircraft_carrier.json @@ -201,6 +201,6 @@ "city_distance": [ -1, 1000 ], "locations": [ "lake_surface" ], "occurrences": [ 75, 100 ], - "flags": [ "CLASSIC", "LAKE", "MAN_MADE", "UNIQUE", "MILITARY", "ELECTRIC_GRID" ] + "flags": [ "CLASSIC", "LAKE", "MAN_MADE", "UNIQUE", "MILITARY", "ELECTRIC_GRID", "GLOBALLY_UNIQUE" ] } ] diff --git a/data/json/overmap/overmap_special/specials.json b/data/json/overmap/overmap_special/specials.json index a8a1369e0300..a4dc8e3fde02 100644 --- a/data/json/overmap/overmap_special/specials.json +++ b/data/json/overmap/overmap_special/specials.json @@ -1796,7 +1796,7 @@ "city_distance": [ 3, -1 ], "city_sizes": [ 4, -1 ], "occurrences": [ 50, 100 ], - "flags": [ "UNIQUE" ] + "flags": [ "ELECTRIC_GRID", "UNIQUE", "GLOBALLY_UNIQUE" ] }, { "type": "overmap_special", @@ -5624,7 +5624,7 @@ "city_distance": [ 5, -1 ], "city_sizes": [ 4, -1 ], "occurrences": [ 10, 100 ], - "flags": [ "MILITARY", "UNIQUE", "ELECTRIC_GRID" ] + "flags": [ "MILITARY", "UNIQUE", "ELECTRIC_GRID", "GLOBALLY_UNIQUE" ] }, { "type": "overmap_special", diff --git a/src/overmap.cpp b/src/overmap.cpp index 07f2c2d8135a..d04cea3bafe3 100644 --- a/src/overmap.cpp +++ b/src/overmap.cpp @@ -5501,6 +5501,11 @@ bool overmap::can_place_special( const overmap_special &special, const tripoint_ return false; } + if (special.has_flag("GLOBALLY_UNIQUE") && + overmap_buffer.contains_unique_special(special.id)) { + return false; + } + const std::vector fixed_terrains = special.required_locations(); return std::all_of( fixed_terrains.begin(), fixed_terrains.end(), @@ -5538,6 +5543,10 @@ std::vector overmap::place_special( assert( can_place_special( special, p, dir, must_be_unexplored ) ); } + if (special.has_flag("GLOBALLY_UNIQUE")) { + overmap_buffer.add_unique_special(special.id); + } + const bool grid = special.has_flag( "ELECTRIC_GRID" ); special_placement_result result = special.place( *this, p, dir ); @@ -5941,10 +5950,17 @@ void overmap::place_specials( overmap_special_batch &enabled_specials ) const float rate = is_true_center && special.has_flag( "ENDGAME" ) ? 1 : zone_ratio[current]; + const bool unique = iter.special_details->has_flag("UNIQUE"); + const bool globally_unique = iter.special_details->has_flag("GLOBALLY_UNIQUE"); + int amount_to_place; - if( special.has_flag( "UNIQUE" ) ) { + if( unique || globally_unique ) { + const overmap_special_id& id = iter.special_details->id; + const overmap_special_placement_constraints& constraints = iter.special_details->get_constraints(); + int chance = roll_remainder( min * rate ); - amount_to_place = x_in_y( chance, max ) ? 1 : 0; + //FINGERS CROSSED EMOGI + amount_to_place = x_in_y(min, max) && (!globally_unique || !overmap_buffer.contains_unique_special(id)) ? 1 : 0; } else { // Number of instances normalized to terrain ratio float real_max = std::max( static_cast( min ), max * rate ); diff --git a/src/overmapbuffer.cpp b/src/overmapbuffer.cpp index 69eeeea1a076..56c29d34853b 100644 --- a/src/overmapbuffer.cpp +++ b/src/overmapbuffer.cpp @@ -208,6 +208,7 @@ void overmapbuffer::clear() { overmaps.clear(); known_non_existing.clear(); + placed_unique_specials.clear(); last_requested_overmap = nullptr; } @@ -947,6 +948,19 @@ bool overmapbuffer::check_overmap_special_type( const overmap_special_id &id, return om_loc.om->check_overmap_special_type( id, om_loc.local ); } +void overmapbuffer::add_unique_special(const overmap_special_id& id) +{ + if (contains_unique_special(id)) { + debugmsg("Unique overmap special placed more than once: %s", id.str()); + } + placed_unique_specials.emplace(id); +} + +bool overmapbuffer::contains_unique_special(const overmap_special_id& id) const +{ + return placed_unique_specials.find(id) != placed_unique_specials.end(); +} + static omt_find_params assign_params( const std::string &type, int const radius, bool must_be_seen, ot_match_type match_type, bool existing_overmaps_only, diff --git a/src/overmapbuffer.h b/src/overmapbuffer.h index a3a242775841..f031902d72f4 100644 --- a/src/overmapbuffer.h +++ b/src/overmapbuffer.h @@ -9,11 +9,13 @@ #include #include #include +#include #include #include #include "coordinates.h" #include "enums.h" +#include "json.h" #include "memory_fast.h" #include "overmap_types.h" #include "point.h" @@ -518,6 +520,9 @@ class overmapbuffer // Cached result of previous call to overmapbuffer::get_existing overmap mutable *last_requested_overmap; + // Set of globally unique overmap specials that have already been placed + std::unordered_set placed_unique_specials; + /** * Get a list of notes in the (loaded) overmaps. * @param z only this specific z-level is search for notes. @@ -551,6 +556,24 @@ class overmapbuffer const tripoint_abs_omt &loc ); bool check_overmap_special_type_existing( const overmap_special_id &id, const tripoint_abs_omt &loc ); + + /** + * Adds the given globally unique overmap special to the list of placed specials. + */ + void add_unique_special(const overmap_special_id& id); + /** + * Returns true if the given globally unique overmap special has already been placed. + */ + bool contains_unique_special(const overmap_special_id& id) const; + /** + * Writes the placed unique specials as a JSON value. + */ + void serialize_placed_unique_specials(JsonOut& json) const; + /** + * Reads placed unique specials from JSON and overwrites the global value. + */ + void deserialize_placed_unique_specials(JsonIn& jsin); + private: /** * Go thorough the monster groups of the overmap and move out-of-bounds diff --git a/src/savegame.cpp b/src/savegame.cpp index 1e4a849697ed..edad0e91ab36 100644 --- a/src/savegame.cpp +++ b/src/savegame.cpp @@ -34,6 +34,7 @@ #include "output.h" #include "overmap.h" #include "overmap_types.h" +#include "overmapbuffer.h" #include "popup.h" #include "regional_settings.h" #include "scent_map.h" @@ -1167,6 +1168,9 @@ void game::unserialize_master( std::istream &fin ) jsin.read( *faction_manager_ptr ); } else if( name == "seed" ) { jsin.read( seed ); + } + else if (name == "placed_unique_specials") { + overmap_buffer.deserialize_placed_unique_specials(jsin); } else if( name == "weather" ) { JsonObject w = jsin.get_object(); w.read( "lightning", get_weather().lightning_active ); @@ -1202,6 +1206,9 @@ void game::serialize_master( std::ostream &fout ) json.member( "active_missions" ); mission::serialize_all( json ); + json.member("placed_unique_specials"); + overmap_buffer.serialize_placed_unique_specials(json); + json.member( "factions", *faction_manager_ptr ); json.member( "seed", seed ); @@ -1283,3 +1290,17 @@ void Creature_tracker::serialize( JsonOut &jsout ) const } jsout.end_array(); } + +void overmapbuffer::serialize_placed_unique_specials(JsonOut& json) const +{ + json.write_as_array(placed_unique_specials); +} + +void overmapbuffer::deserialize_placed_unique_specials(JsonIn& jsin) +{ + placed_unique_specials.clear(); + jsin.start_array(); + while (!jsin.end_array()) { + placed_unique_specials.emplace(jsin.get_string()); + } +} From 332b965176c48242662449e14f152cece30f097d Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Sat, 16 Nov 2024 02:07:31 +0000 Subject: [PATCH 2/3] style(autofix.ci): automated formatting --- src/overmap.cpp | 19 ++++++++++--------- src/overmapbuffer.cpp | 12 ++++++------ src/overmapbuffer.h | 8 ++++---- src/savegame.cpp | 19 +++++++++---------- 4 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/overmap.cpp b/src/overmap.cpp index d04cea3bafe3..a332dece5d65 100644 --- a/src/overmap.cpp +++ b/src/overmap.cpp @@ -5501,8 +5501,8 @@ bool overmap::can_place_special( const overmap_special &special, const tripoint_ return false; } - if (special.has_flag("GLOBALLY_UNIQUE") && - overmap_buffer.contains_unique_special(special.id)) { + if( special.has_flag( "GLOBALLY_UNIQUE" ) && + overmap_buffer.contains_unique_special( special.id ) ) { return false; } @@ -5543,8 +5543,8 @@ std::vector overmap::place_special( assert( can_place_special( special, p, dir, must_be_unexplored ) ); } - if (special.has_flag("GLOBALLY_UNIQUE")) { - overmap_buffer.add_unique_special(special.id); + if( special.has_flag( "GLOBALLY_UNIQUE" ) ) { + overmap_buffer.add_unique_special( special.id ); } const bool grid = special.has_flag( "ELECTRIC_GRID" ); @@ -5950,17 +5950,18 @@ void overmap::place_specials( overmap_special_batch &enabled_specials ) const float rate = is_true_center && special.has_flag( "ENDGAME" ) ? 1 : zone_ratio[current]; - const bool unique = iter.special_details->has_flag("UNIQUE"); - const bool globally_unique = iter.special_details->has_flag("GLOBALLY_UNIQUE"); + const bool unique = iter.special_details->has_flag( "UNIQUE" ); + const bool globally_unique = iter.special_details->has_flag( "GLOBALLY_UNIQUE" ); int amount_to_place; if( unique || globally_unique ) { - const overmap_special_id& id = iter.special_details->id; - const overmap_special_placement_constraints& constraints = iter.special_details->get_constraints(); + const overmap_special_id &id = iter.special_details->id; + const overmap_special_placement_constraints &constraints = iter.special_details->get_constraints(); int chance = roll_remainder( min * rate ); //FINGERS CROSSED EMOGI - amount_to_place = x_in_y(min, max) && (!globally_unique || !overmap_buffer.contains_unique_special(id)) ? 1 : 0; + amount_to_place = x_in_y( min, max ) && ( !globally_unique || + !overmap_buffer.contains_unique_special( id ) ) ? 1 : 0; } else { // Number of instances normalized to terrain ratio float real_max = std::max( static_cast( min ), max * rate ); diff --git a/src/overmapbuffer.cpp b/src/overmapbuffer.cpp index 56c29d34853b..cc09c721fb69 100644 --- a/src/overmapbuffer.cpp +++ b/src/overmapbuffer.cpp @@ -948,17 +948,17 @@ bool overmapbuffer::check_overmap_special_type( const overmap_special_id &id, return om_loc.om->check_overmap_special_type( id, om_loc.local ); } -void overmapbuffer::add_unique_special(const overmap_special_id& id) +void overmapbuffer::add_unique_special( const overmap_special_id &id ) { - if (contains_unique_special(id)) { - debugmsg("Unique overmap special placed more than once: %s", id.str()); + if( contains_unique_special( id ) ) { + debugmsg( "Unique overmap special placed more than once: %s", id.str() ); } - placed_unique_specials.emplace(id); + placed_unique_specials.emplace( id ); } -bool overmapbuffer::contains_unique_special(const overmap_special_id& id) const +bool overmapbuffer::contains_unique_special( const overmap_special_id &id ) const { - return placed_unique_specials.find(id) != placed_unique_specials.end(); + return placed_unique_specials.find( id ) != placed_unique_specials.end(); } static omt_find_params assign_params( diff --git a/src/overmapbuffer.h b/src/overmapbuffer.h index f031902d72f4..dca6dda2abcd 100644 --- a/src/overmapbuffer.h +++ b/src/overmapbuffer.h @@ -560,19 +560,19 @@ class overmapbuffer /** * Adds the given globally unique overmap special to the list of placed specials. */ - void add_unique_special(const overmap_special_id& id); + void add_unique_special( const overmap_special_id &id ); /** * Returns true if the given globally unique overmap special has already been placed. */ - bool contains_unique_special(const overmap_special_id& id) const; + bool contains_unique_special( const overmap_special_id &id ) const; /** * Writes the placed unique specials as a JSON value. */ - void serialize_placed_unique_specials(JsonOut& json) const; + void serialize_placed_unique_specials( JsonOut &json ) const; /** * Reads placed unique specials from JSON and overwrites the global value. */ - void deserialize_placed_unique_specials(JsonIn& jsin); + void deserialize_placed_unique_specials( JsonIn &jsin ); private: /** diff --git a/src/savegame.cpp b/src/savegame.cpp index edad0e91ab36..0bb2f13ceec7 100644 --- a/src/savegame.cpp +++ b/src/savegame.cpp @@ -1168,9 +1168,8 @@ void game::unserialize_master( std::istream &fin ) jsin.read( *faction_manager_ptr ); } else if( name == "seed" ) { jsin.read( seed ); - } - else if (name == "placed_unique_specials") { - overmap_buffer.deserialize_placed_unique_specials(jsin); + } else if( name == "placed_unique_specials" ) { + overmap_buffer.deserialize_placed_unique_specials( jsin ); } else if( name == "weather" ) { JsonObject w = jsin.get_object(); w.read( "lightning", get_weather().lightning_active ); @@ -1206,8 +1205,8 @@ void game::serialize_master( std::ostream &fout ) json.member( "active_missions" ); mission::serialize_all( json ); - json.member("placed_unique_specials"); - overmap_buffer.serialize_placed_unique_specials(json); + json.member( "placed_unique_specials" ); + overmap_buffer.serialize_placed_unique_specials( json ); json.member( "factions", *faction_manager_ptr ); json.member( "seed", seed ); @@ -1291,16 +1290,16 @@ void Creature_tracker::serialize( JsonOut &jsout ) const jsout.end_array(); } -void overmapbuffer::serialize_placed_unique_specials(JsonOut& json) const +void overmapbuffer::serialize_placed_unique_specials( JsonOut &json ) const { - json.write_as_array(placed_unique_specials); + json.write_as_array( placed_unique_specials ); } -void overmapbuffer::deserialize_placed_unique_specials(JsonIn& jsin) +void overmapbuffer::deserialize_placed_unique_specials( JsonIn &jsin ) { placed_unique_specials.clear(); jsin.start_array(); - while (!jsin.end_array()) { - placed_unique_specials.emplace(jsin.get_string()); + while( !jsin.end_array() ) { + placed_unique_specials.emplace( jsin.get_string() ); } } From f122d7affaf0dc9a51cae07fd4e7b1d1c93756fc Mon Sep 17 00:00:00 2001 From: Zlorthishen <79779913+Zlorthishen@users.noreply.github.com> Date: Sat, 16 Nov 2024 09:48:08 -0600 Subject: [PATCH 3/3] Update specials.json --- data/json/overmap/overmap_special/specials.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/json/overmap/overmap_special/specials.json b/data/json/overmap/overmap_special/specials.json index a4dc8e3fde02..912837b5475d 100644 --- a/data/json/overmap/overmap_special/specials.json +++ b/data/json/overmap/overmap_special/specials.json @@ -5624,7 +5624,7 @@ "city_distance": [ 5, -1 ], "city_sizes": [ 4, -1 ], "occurrences": [ 10, 100 ], - "flags": [ "MILITARY", "UNIQUE", "ELECTRIC_GRID", "GLOBALLY_UNIQUE" ] + "flags": [ "MILITARY", "UNIQUE", "ELECTRIC_GRID" ] }, { "type": "overmap_special",