doc/npc: document shop restocking behaviour

This commit is contained in:
andrei 2022-10-29 22:52:52 +03:00
parent 9183becfca
commit d48e91fce1
4 changed files with 26 additions and 2 deletions

View File

@ -1027,15 +1027,21 @@ NPCs in the faction will use the zone to influence the AI.
| Field | Description
| --- | ---
| type | (required, string) Values: `"NPC_RETREAT"`, `"NPC_NO_INVESTIGATE"`, or `"NPC_INVESTIGATE_ONLY"`.
| type | (required, string) Values: `"NPC_RETREAT"`, `"NPC_NO_INVESTIGATE"`, or `"NPC_INVESTIGATE_ONLY"`, or `LOOT_xxx`
| faction | (required, string) the faction id of the NPC faction that will use the zone.
| name | (optional, string) the name of the zone.
| filter | (optional, string) used as filter for `LOOT_CUSTOM`, or as group id for `LOOT_ITEM_GROUP`
The `type` field values affect NPC behavior. NPCs will:
- Prefer to retreat towards `NPC_RETREAT` zones.
- Not move to see the source of unseen sounds coming from `NPC_NO_INVESTIGATE` zones.
- Not move to see the source of unseen sounds coming from outside of `NPC_INVESTIGATE_ONLY` zones.
- Use `LOOT_xxx` zones for their shop (see [NPCs.md#Shop_restocking](NPCs.md#Shop-restocking))
Single-point loot zones that overlap cargo vehicle parts will be placed as vehicle zones.
Zone placements can be debugged in game by turning on debug mode and changing `F`action in the Zones Manager.
### Specify a player spawning location using "zones"

View File

@ -63,6 +63,15 @@ There are a couple of items in the above template that may not be self explanato
- `"rigid"` : (_optional_) By default, item groups will be continually iterated until they reach a certain value or size threshold for the NPC. Rigid groups are instead guaranteed to populate a single time if they can, and will not include duplicate reruns. (Defaults to false)
- `"refusal"` : (_optional_) message to display in UIs (ex: trade UI) when conditions are not met. Defaults to `"<npcname> does not trust you enough"`
##### Shop restocking
NPCs with at least one `shopkeeper_item_group` will (re)stock their shop in nearby loot zones (within `PICKUP_RANGE` = 6 tiles) owned by their faction and will ignore all other items. If there isn't at least one `LOOT_UNSORTED` zone nearby, fallback zones will be automatically placed on all nearby, reachable, unsealed furniture with either the `CONTAINER` flag or a max volume higher than the floor. If there is no suitable furniture around, a 3x3 zone centered on the NPC will be created instead.
Before restocking, items owned by the NPC's faction within these zones will be consumed according to `shopkeeper_consumption_rates`.
The shop restocks every `restock_interval` regardless of interactions with the avatar.
NOTE: do not place items within these loot zones in mapgen definitions as these will be consumed during the first restock. Add them to the item groups instead.
#### NPC
There is a second template required for a new NPC. It looks like this:
Format:

View File

@ -33,6 +33,9 @@ Vehicle prototypes do not currently accept copy-from
{ "x": 0, "y": 1, "items": [ "matchbook", "2x4" ] }, // all items in the list spawn
{ "x": 0, "y": 0, "item_groups": [ "army_uniform", "rare_guns" ] } all item_groups are processed
]
"zones": [
{ "x": -3, "y": 0, "type": "LOOT_AMMO" }
]
```
.* Important! *. Vehicle parts must be defined in the same order you would install them in the game (ie, frames and mount points first). You also cannot break the normal rules of installation (you can't stack non-stackable part flags).
@ -73,3 +76,9 @@ the optional keyword "chance" provides an X in 100 chance that a particular item
If a single item is specified through `"items"`, an itype variant for it can be specified through `"variant"`.
Multiple lines of items may share the same X and Y values.
### Zones list
The zones list contains an arbitrary number of lines. Each line is of the form:
{ "x": X, "y": Y, "type": ZONE_ID }
where ZONE_ID is any valid zone id such as `LOOT_UNSORTED`.
These zones are only placed if the vehicle has a faction owner.

View File

@ -2101,7 +2101,7 @@ int npc::max_willing_to_owe() const
void npc::shop_restock()
{
// NPCs refresh every week, since the last time you checked in
// Shops restock once every restock_interval
time_duration const elapsed =
restock != calendar::turn_zero ? calendar::turn - restock : 0_days;
if( ( restock != calendar::turn_zero ) && ( elapsed < 0_days ) ) {