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

NPCs: support faction tagged zones #30150

Merged
merged 5 commits into from
May 12, 2019
Merged
Changes from 1 commit
Commits
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
Prev Previous commit
Next Next commit
mapgen: add commands to place NPC zones
NPC zones can be added by faction id and zone type.
  • Loading branch information
mlangsdorf committed May 11, 2019
commit 34e5236afef0e85d2d1e349709f32cd44f799425
7 changes: 7 additions & 0 deletions doc/MAPGEN.md
Original file line number Diff line number Diff line change
@@ -66,6 +66,7 @@
* 2.5.17 "sealed_item"
* 2.5.18 "graffiti"
* 2.6.19 "translate_ter"
* 2.6.20 "zones"
* 2.6 "rotation"
* 3 update_mapgen
* 3.1 overmap tile specification
@@ -698,6 +699,12 @@ normal mapgen, but it is useful for setting a baseline with update_mapgen.
- "from": (required, string) the terrain id of the terrain to be transformed
- "to": (required, string) the terrain id that the from terrain will transformed into

### 2.5.20 "zones"
Places a zone for an NPC faction. NPCs in the faction will use the zone to influence the AI.
- "type": (required, string) must be one of NPC_RETREAT, NPC_NO_INVESTIGATE, or NPC_INVESTIGATE_ONLY. NPCs will prefer to retreat towards NPC_RETREAT zones. They will not move to the see the source of unseen sounds coming from NPC_NO_INVESTIGATE zones. They will not move to the see the source of unseen sounds coming from outside NPC_INVESTIGATE_ONLY zones.
- "faction": (required, string) the faction id of the NPC faction that will use the zone.
- "name": (optional, string) the name of the zone.

# 2.7 "rotation"
Rotates the generated map after all the other mapgen stuff has been done. The value can be a single integer or a range (out of which a value will be randomly chosen). Example:
```JSON
35 changes: 35 additions & 0 deletions src/clzones.cpp
Original file line number Diff line number Diff line change
@@ -803,6 +803,41 @@ void zone_manager::swap( zone_data &a, zone_data &b )
std::swap( a, b );
}

void zone_manager::rotate_zones( map &target_map, const int turns )
{
if( turns == 0 ) {
return;
}
const tripoint a_start = target_map.getabs( tripoint( 0, 0, 0 ) );
const tripoint a_end = target_map.getabs( tripoint( 23, 23, 0 ) );
const point dim( 24, 24 );
for( zone_data &zone : zones ) {
const tripoint z_start = zone.get_start_point();
const tripoint z_end = zone.get_end_point();
if( ( a_start.x <= z_start.x && a_start.y <= z_start.y ) &&
( a_end.x > z_start.x && a_end.y >= z_start.y ) &&
( a_start.x <= z_end.x && a_start.y <= z_end.y ) &&
( a_end.x >= z_end.x && a_end.y >= z_end.y ) ) {
tripoint z_l_start3 = target_map.getlocal( z_start );
tripoint z_l_end3 = target_map.getlocal( z_end );
// don't rotate centered squares
if( z_l_start3.x == z_l_start3.y && z_l_end3.x == z_l_end3.y &&
( z_l_start3.x + z_l_end3.x ) == 23 ) {
continue;
}
point z_l_start = point( z_l_start3.x, z_l_start3.y ).rotate( turns, dim );
point z_l_end = point( z_l_end3.x, z_l_end3.y ).rotate( turns, dim );
point new_z_start = target_map.getabs( z_l_start );
point new_z_end = target_map.getabs( z_l_end );
tripoint first = tripoint( std::min( new_z_start.x, new_z_end.x ),
std::min( new_z_start.y, new_z_end.y ), a_start.z );
tripoint second = tripoint( std::max( new_z_start.x, new_z_end.x ),
std::max( new_z_start.y, new_z_end.y ), a_end.z );
zone.set_position( std::make_pair( first, second ), false );
}
}
}

void zone_manager::start_sort( const std::vector<tripoint> &src_sorted )
{
for( auto &src : src_sorted ) {
2 changes: 2 additions & 0 deletions src/clzones.h
Original file line number Diff line number Diff line change
@@ -21,6 +21,7 @@ class JsonOut;
class JsonObject;
class item;
class faction;
class map;

using faction_id = string_id<faction>;
const faction_id your_fac( "your_followers" );
@@ -318,6 +319,7 @@ class zone_manager
cata::optional<std::string> query_name( const std::string &default_name = "" ) const;
cata::optional<zone_type_id> query_type() const;
void swap( zone_data &a, zone_data &b );
void rotate_zones( map &target_map, const int turns );

void start_sort( const std::vector<tripoint> &src_sorted );
void end_sort();
36 changes: 36 additions & 0 deletions src/mapgen.cpp
Original file line number Diff line number Diff line change
@@ -14,12 +14,14 @@
#include <cmath>

#include "ammo.h"
#include "clzones.h"
#include "computer.h"
#include "coordinate_conversions.h"
#include "coordinates.h"
#include "debug.h"
#include "drawing_primitives.h"
#include "enums.h"
#include "faction.h"
#include "game.h"
#include "item_group.h"
#include "itype.h"
@@ -1646,6 +1648,34 @@ class jmapgen_translate : public jmapgen_piece
dat.m.translate( from, to );
}
};
/**
* Place a zone
*/
class jmapgen_zone : public jmapgen_piece
{
public:
zone_type_id zone_type;
faction_id faction;
std::string name = "";
jmapgen_zone( JsonObject &jsi ) : jmapgen_piece() {
if( jsi.has_string( "faction" ) && jsi.has_string( "type" ) ) {
std::string fac_id = jsi.get_string( "faction" );
faction = faction_id( fac_id );
std::string zone_id = jsi.get_string( "type" );
zone_type = zone_type_id( zone_id );
if( jsi.has_string( "name" ) ) {
name = jsi.get_string( "name" );
}
}
}
void apply( const mapgendata &dat, const jmapgen_int &x, const jmapgen_int &y,
const float /*mdensity*/, mission * /*miss*/ ) const override {
zone_manager &mgr = zone_manager::get_manager();
const tripoint start = dat.m.getabs( tripoint( x.val, y.val, 0 ) );
const tripoint end = dat.m.getabs( tripoint( x.valmax, y.valmax, 0 ) );
mgr.add( name, zone_type, faction, false, true, start, end );
}
};

static void load_weighted_entries( JsonObject &jsi, const std::string &json_key,
weighted_int_list<std::string> &list )
@@ -2148,6 +2178,7 @@ mapgen_palette mapgen_palette::load_internal( JsonObject &jo, const std::string
new_pal.load_place_mapings<jmapgen_liquid_item>( jo, "liquids", format_placings );
new_pal.load_place_mapings<jmapgen_graffiti>( jo, "graffiti", format_placings );
new_pal.load_place_mapings<jmapgen_translate>( jo, "translate", format_placings );
new_pal.load_place_mapings<jmapgen_zone>( jo, "zones", format_placings );

return new_pal;
}
@@ -2326,6 +2357,7 @@ bool mapgen_function_json_base::setup_common( JsonObject jo )
objects.load_objects<jmapgen_nested>( jo, "place_nested" );
objects.load_objects<jmapgen_graffiti>( jo, "place_graffiti" );
objects.load_objects<jmapgen_translate>( jo, "translate_ter" );
objects.load_objects<jmapgen_zone>( jo, "place_zones" );

if( !mapgen_defer::defer ) {
is_ready = true; // skip setup attempts from any additional pointers
@@ -7301,6 +7333,10 @@ void map::rotate( int turns )
}
}
}

// rotate zones
zone_manager &mgr = zone_manager::get_manager();
mgr.rotate_zones( *this, turns );
}

// Hideous function, I admit...