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

[WIP] Adds ability for weather to spawn monsters, and a new weather type, Mist, which uses it. #41067

Closed
wants to merge 28 commits into from
Closed
Show file tree
Hide file tree
Changes from 27 commits
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
14 changes: 13 additions & 1 deletion data/json/effects.json
Original file line number Diff line number Diff line change
Expand Up @@ -1967,7 +1967,19 @@
},
{
"type": "effect_type",
"id": "recently_coughed"
"id": "disrupted_sleep",
"max_duration": "72 h"
},
{
"type": "effect_type",
"id": "nightmares",
"max_duration": "72 h"
},
{
"type": "effect_type",
"id": "incorporeal",
"name": [ "Incorporeal" ],
"desc": [ "You have as much substance as mist does." ]
},
{
"type": "effect_type",
Expand Down
5 changes: 5 additions & 0 deletions data/json/monster_factions.json
Original file line number Diff line number Diff line change
Expand Up @@ -201,5 +201,10 @@
"type": "MONSTER_FACTION",
"name": "triffid",
"base_faction": "plant"
},
{
"type": "MONSTER_FACTION",
"name": "mist",
"neutral": [ "animal", "insect", "blob", "zombie", "zombie_aquatic", "plant", "bot", "blob", "nether", "jabberwock" ]
}
]
84 changes: 84 additions & 0 deletions data/json/monsters/mist.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
[
{
"id": "mon_mist_wraith",
"type": "MONSTER",
"name": { "str": "Mist wraith" },
"description": "A wispy figure slightly more solid than the mist surrounding it. Its form is constantly shifting and never distinct.",
"default_faction": "mist",
"species": [ "MIST" ],
"volume": "62500 ml",
"weight": "0 g",
"hp": 1,
"speed": 110,
"symbol": "X",
"color": "white",
"aggression": 100,
"morale": 100,
"dodge": 8,
"special_attacks": [ [ "DISSIPATE_DRAIN", 1 ] ],
"death_function": [ "DISSIPATE" ],
"flags": [ "FLIES", "NO_BREATHE", "SEES", "HEARS" ]
},
{
"id": "mon_mist_spectre",
"type": "MONSTER",
"name": { "str": "Mist spectre" },
"description": "A menacing figure slightly more solid than the mist surrounding it. Its shape brings back painful memories.",
"default_faction": "mist",
"bodytype": "human",
"species": [ "MIST" ],
"volume": "62500 ml",
"weight": "0 g",
"hp": 1,
"speed": 110,
"symbol": "U",
"color": "white",
"aggression": 100,
"morale": 100,
"dodge": 9,
"special_attacks": [ [ "DISSIPATE_NIGHTMARES", 1 ], [ "DISSIPATE_FORCE_SCREAM", 1 ] ],
"death_function": [ "DISSIPATE" ],
"flags": [ "FLIES", "NO_BREATHE", "SEES", "HEARS" ]
},
{
"id": "mon_mist_phantom",
"type": "MONSTER",
"name": { "str": "Mist phantom" },
"description": "A hollow figure no more solid than the mist surrounding it.",
"default_faction": "mist",
"bodytype": "human",
"species": [ "MIST" ],
"volume": "62500 ml",
"weight": "0 g",
"hp": 1,
"speed": 110,
"symbol": "W",
"color": "white",
"aggression": 100,
"morale": 100,
"dodge": 10,
"special_attacks": [ [ "DISSIPATE_INCORPOREAL", 1 ] ],
"death_function": [ "DISSIPATE" ],
"flags": [ "FLIES", "NO_BREATHE", "SEES", "HEARS" ]
},
{
"id": "mon_mist_bag",
"type": "MONSTER",
"name": { "str": "Mist bag" },
"description": "A bag seemingly made of mist, it appears to be on the edge of bursting.",
"default_faction": "mist",
"bodytype": "human",
"species": [ "MIST" ],
"volume": "62500 ml",
"weight": "0 g",
"hp": 1,
"speed": 70,
"symbol": "B",
"color": "white",
"aggression": 100,
"morale": 100,
"special_attacks": [ [ "DISSIPATE", 1 ] ],
"death_function": [ "RELEASE_MIST" ],
"flags": [ "FLIES", "NO_BREATHE", "SEES", "HEARS" ]
}
]
10 changes: 10 additions & 0 deletions data/json/morale_types.json
Original file line number Diff line number Diff line change
Expand Up @@ -383,5 +383,15 @@
"id": "morale_perm_debug",
"type": "morale_type",
"text": "Debug Morale"
},
{
"id": "morale_traumatic_memory",
"type": "morale_type",
"text": "Relived a traumatic memory"
},
{
"id": "morale_nightmare",
"type": "morale_type",
"text": "Had a vivid nightmare"
}
]
46 changes: 45 additions & 1 deletion data/json/regional_map_settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -916,7 +916,51 @@
"base_acid": 0.0,
"base_wind": 3.4,
"base_wind_distrib_peaks": 80,
"base_wind_season_variation": 50
"base_wind_season_variation": 50,
"mist": {
Copy link
Member

Choose a reason for hiding this comment

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

This should be generalized to an array of localized weather objects with jsonized properties and effects.

"mist_active": true,
"mist_scaling": 1.0,
"mist_frequency": 7,
"mist_length": 8,
Copy link
Member

Choose a reason for hiding this comment

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

Duration should be randomized between a [ min, max ] pair rather than fixed randomization around a value.

"mist_increases_per": 10,
"mist_thick_threshold": 10,
"mist_stifling_threshold": 20
},
"weather_spawn": [
Copy link
Member

Choose a reason for hiding this comment

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

Spawns should be part of the weather objects.

{
"index": 14,
"hallucinations": true,
"spawns": [ "mon_mist_wraith" ],
"time_between_spawns": 60,
"chance_to_spawn": 75,
"max_spawns": 2,
"max_radius": 8,
"min_radius": 5,
"message": "You feel the mist react to you and shapes form."
},
{
"index": 15,
"hallucinations": true,
"spawns": [ "mon_mist_wraith", "mon_mist_spectre" ],
"time_between_spawns": 50,
"chance_to_spawn": 75,
"max_spawns": 2,
"max_radius": 6,
"min_radius": 4,
"message": "The mist reacts to you and nightmarish shapes form."
},
{
"index": 16,
"hallucinations": true,
"spawns": [ "mon_mist_wraith", "mon_mist_spectre", "mon_mist_phantom" ],
"time_between_spawns": 40,
"chance_to_spawn": 75,
"max_spawns": 3,
"max_radius": 4,
"min_radius": 3,
"message": "The mist reflects your darkest thoughts and shapes form."
}
]
},
"overmap_feature_flag_settings": { "clear_blacklist": false, "blacklist": [ ], "clear_whitelist": false, "whitelist": [ ] }
}
Expand Down
53 changes: 53 additions & 0 deletions data/json/snippets/mist.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
[
{
"type": "snippet",
"category": "mist_increase_intensity",
"text": [ "The mist thickens.", "The mist feels slightly stronger and more alive." ]
},
{
"type": "snippet",
"category": "mist_arrives",
"text": [
"You blink and there is dense mist as far as you can see, which is much less than it used to be.",
"In an instant a thick mist descends upon the world, far too fast to be natural. Or are you finally losing it?."
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
"In an instant a thick mist descends upon the world, far too fast to be natural. Or are you finally losing it?."
"In an instant a thick mist descends upon the world, far too fast to be natural."

I think the 'losing it' bit inserts too much of the character's thoughts

]
},
{
"type": "snippet",
"category": "mist_leaves",
"text": [ "The mist evaporates like it was never there.", "In a heartbeat the mist is gone." ]
},
{
"type": "snippet",
"category": "mist_shouts",
"text": [
"I'm sorry mommy!",
"Please stop sir, that hurts!",
"Why? I tried my best!",
"No, please get up, please be ok!",
"Why would you lie about THAT?",
"I never loved you!",
"I only ever tolerated you!",
"That's why I never trusted you!",
"It's not fair!",
"Enjoy the funeral, you sicko!",
"Help!",
"Cmon I can still be fun, there's no need for that!",
"I can do better, I promise, please!",
"I'm going to kill that son of a bitch!",
"That's no excuse!"
]
Copy link
Member

Choose a reason for hiding this comment

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

Consider importing other snippets here, to make the mist more confusing. eg.

"<im_leaving_you>",
"<ill_kill_you>",
"<ill_die>",
"<wait>",
"<drop_it>",
"<hands_up>",
"<fuck_you>",
"<general_danger_h>",
"<kill_npc>",
"<kill_npc_h>",
"<speech_warning>"

This is a batch of generally concerning-sounding snippets that NPCs say, and if the mist often sounds like NPCs it will be really disorienting.

},
{
"type": "snippet",
"category": "nightmares",
"text": [
"You awaken from a nightmare about being eaten alive while your friends applaud.",
"You awaken from a nightmare about being naked in a the arctic tundra and freezing to death.",
"You awaken from a nightmare about an unseen predator slowly killing you.",
"You awaken from a nightmare about killing those you love with your bare hands.",
"You awaken from a nightmare about being finally judged for your ill deeds.",
"You awaken from a nightmare about the cataclysm not having happened and being stuck in an office job."
]
}
]
5 changes: 5 additions & 0 deletions data/json/species.json
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,11 @@
"id": "HUMAN",
"description": "a human"
},
{
"type": "SPECIES",
"id": "MIST",
"description": "a slightly solid shape in the mist"
},
{
"type": "SPECIES",
"id": "UNKNOWN"
Expand Down
73 changes: 72 additions & 1 deletion doc/REGION_SETTINGS.md
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,8 @@ The **weather** section defines the base weather attributes used for the region.
| `base_wind` | Base wind for the region in mph units. Roughly the yearly average. |
| `base_wind_distrib_peaks` | How high the wind peaks can go. Higher values produce windier days. |
| `base_wind_season_variation` | How the wind varies with season. Lower values produce more variation |

| `mist` | Section defining mist, if this is missing mist is disabled
| `weather_spawn` | Section defining if monsters will spawn in weather |
### Example

```json
Expand All @@ -512,6 +513,76 @@ The **weather** section defines the base weather attributes used for the region.
}
```

## Mist

The **mist** section defines the base mist attributes used for the region.

### Fields

| Identifier | Description |
| ------------------------------ | --------------------------------------------------------------------- |
| `mist_active` | bool defining if the mist is enabled |
| `mist_scaling` | float that affects how fast the mist grows more powerful with each appearance, at 0 the mist will not grow stronger each time |
| `mist_frequency` | the average number of days between mist appearances, the actual value is random between .5 and 1.5 this value minus scaling effects |
| `mist_length` | the average number of hours the mist will last, the actual value is random between .7 and 1.3 this plus mist scaling effects |
| `mist_increases_per` | the number of times the mist will increase its intensity per instance |
| `mist_thick_threshold` | the intensity at which the mist will become thick instead of regular |

### Example

```json
{
"mist": {
"mist_active": true,
"mist_scaling": 1.5,
"mist_frequency": 3,
"mist_length": 12,
"mist_increases_per": 10,
"mist_thick_threshold": 10,
"mist_stifling_threshold": 20
},
}
```


## Weather Spawn

The **weather_spawn** section defines creatures that will spawn in weather.

### Fields

| Identifier | Description |
| ------------------------------ | --------------------------------------------------------------------- |
| `index` | the index of the weather in the enum weather_type found in weather.h |
| `hallucinations` | bool determining whether the weather should spawn hallucinations for nearby creatures, if true this will be treated as another spawn |
| `spawns` | an array of the monster_ids of every monster you want to spawn, one will be chosen at random every spawn |
| `time_between_spawns` | the number of seconds between monster spawns |
| `chance_to_spawn` | the percent chance a monster will spawn for each spawn attempt in max_spawns |
| `max_spawns` | the maximum number of monsters/hallucinations that will spawn |
| `max_radius` | the maximum distance monsters/hallucinations will spawn from the target |
| `min_radius` | the closest distance monsters/hallucinations will spawn to the target |
| `message` | Message to be displayed if at least one non hallucination spawns |

### Example

```json
{
"weather_spawn": [
{
"index": 14,
"hallucinations": true,
"spawns": [ "mon_mist_wraith" ],
"seconds_between_spawns": 60,
"chance_to_spawn": 75,
"max_spawns": 2,
"max_radius": 8,
"min_radius": 4,
"message": "You feel the mist react to you and shapes form."
}
]
}
```

## Overmap Feature Flag Settings

The **overmap_feature_flag_settings** section defines operations that operate on the flags assigned to overmap features.
Expand Down
4 changes: 3 additions & 1 deletion src/activity_item_handling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ static const activity_id ACT_TIDY_UP( "ACT_TIDY_UP" );
static const activity_id ACT_VEHICLE( "ACT_VEHICLE" );
static const activity_id ACT_VEHICLE_DECONSTRUCTION( "ACT_VEHICLE_DECONSTRUCTION" );
static const activity_id ACT_VEHICLE_REPAIR( "ACT_VEHICLE_REPAIR" );

static const efftype_id effect_incorporeal( "incorporeal" );
static const efftype_id effect_pet( "pet" );
static const efftype_id effect_nausea( "nausea" );

Expand Down Expand Up @@ -2188,7 +2190,7 @@ static bool mine_activity( player &p, const tripoint &src_loc )
( itm.type->can_use( "JACKHAMMER" ) && itm.ammo_sufficient() );
} );
if( mining_inv.empty() || p.is_mounted() || p.is_underwater() || g->m.veh_at( src_loc ) ||
!g->m.has_flag( "MINEABLE", src_loc ) ) {
!g->m.has_flag( "MINEABLE", src_loc ) || p.has_effect( effect_incorporeal ) ) {
return false;
}
item *chosen_item = nullptr;
Expand Down
6 changes: 6 additions & 0 deletions src/animation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,7 @@ void game::draw_weather( const weather_printable &w )
static const std::string weather_acid_drop {"weather_acid_drop"};
static const std::string weather_rain_drop {"weather_rain_drop"};
static const std::string weather_snowflake {"weather_snowflake"};
static const std::string weather_mist {"weather_mist"};

std::string weather_name;
switch( w.wtype ) {
Expand All @@ -704,6 +705,11 @@ void game::draw_weather( const weather_printable &w )
case WEATHER_SNOWSTORM:
weather_name = weather_snowflake;
break;
case WEATHER_MIST:
case WEATHER_THICK_MIST:
case WEATHER_STIFLING_MIST:
weather_name = weather_mist;
break;
default:
break;
}
Expand Down
Loading