Favor lowered. It should require actual work to maintain. Fixed a bug with pets.
This commit is contained in:
149
README.md
149
README.md
@@ -1,150 +1,3 @@
|
||||
# Draugnorak
|
||||
|
||||
A survival audio game built with NVGT. Explore, gather, craft, and defend your base as day and night cycle.
|
||||
|
||||
## Installation
|
||||
- Unzip the file for your operating system.
|
||||
- On Linux and Mac, make sure the draugnorak executable is marked executable.
|
||||
``` bash
|
||||
chmod +x draugnorak
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
- Move with Left/Right, jump with Up.
|
||||
- Hold Shift, /, or Z for 1 second to search the current area.
|
||||
- Craft basic tools in the base with C.
|
||||
- Set snares and build fires to survive.
|
||||
|
||||
Some of the first things you will want are a stone knife, spear, stone axe, and firepit.
|
||||
## Controls
|
||||
- **Left/Right**: Move.
|
||||
- **Up**: Jump, climb trees, start rope climbs when prompted.
|
||||
- **Down**: Climb down trees or descend rope climbs when prompted.
|
||||
- **Shift, /, or Z (hold)**: Search area (1-second hold, 1-second delay).
|
||||
- **Control (hold/release)**: Attack with equipped weapon. Sling uses a charge window.
|
||||
- **A**: Action menu (place snare, feed fire, burn incense).
|
||||
- **C**: Crafting menu (base only).
|
||||
- **I**: Inventory.
|
||||
- **E**: Equipment.
|
||||
- **P**: Character info.
|
||||
- **B**: Base info (base only).
|
||||
- **Q**: Quests menu (base only).
|
||||
- **S**: Altar menu (base only).
|
||||
- **Tab**: Adventure menu (outside base, once per day).
|
||||
- **H**: Health.
|
||||
- **T**: Time.
|
||||
- **X**: Coordinates + terrain.
|
||||
- **1-0**: Quick slots (equip bound items).
|
||||
- **Backspace**: Pause/Resume.
|
||||
- **Escape**: Exit game (or close menus).
|
||||
|
||||
### History Shortcuts
|
||||
- **\\**: Repeat most recent notification.
|
||||
- **[ / ]**: Previous/next notification.
|
||||
- **, / .**: Previous/next speech history message.
|
||||
|
||||
## Menus
|
||||
- **Up/Down**: Move selection.
|
||||
- **Enter**: Confirm.
|
||||
- **Escape**: Close.
|
||||
- **Tab (in most menus)**: Perform “max” actions (craft all, deposit all, etc.).
|
||||
|
||||
## Gathering and Resources
|
||||
- **Grass/Forest/Deep Forest**: Sticks and vines (search).
|
||||
- **Gravel/Stone**: Stones (search).
|
||||
- **Streams/Water edges**: Reeds and clay (search).
|
||||
- **World drops**: Found on the ground after hunting; search picks them up.
|
||||
- **Trees**:
|
||||
- Search near trees for sticks/vines.
|
||||
- Use an axe to chop down a tree for logs (and extra sticks/vines).
|
||||
- Trees regrow over time.
|
||||
- You can climb trees (Up) and climb down (Down).
|
||||
|
||||
## Crafting (Base Only)
|
||||
Crafting is only available in the base (C).
|
||||
|
||||
### Categories
|
||||
- **Weapons**: Spear, Sling, Bow
|
||||
- **Tools**: Knife, Snare, Stone Axe, Fishing Pole, Rope, Quiver, Canoe, Reed Basket, Clay Pot
|
||||
- **Materials**: Butcher Game, Smoke Fish, Bowstring, Arrows, Incense
|
||||
- **Clothing**: Skin gear, Moccasins, Pouch, Backpack
|
||||
- **Buildings**: Firepit, Fire, Herb Garden, Storage, Pasture, Stable, Altar
|
||||
- **Barricade**: Reinforcement options
|
||||
- **Runes**: Unlocks later
|
||||
|
||||
## Combat and Hunting
|
||||
- Equip weapons in the Equipment menu (E) or bind them to quick slots.
|
||||
- **Spear**: 1-tile range.
|
||||
- **Axe**: Melee; also chops trees.
|
||||
- **Sling**: Ranged (uses stones). Hold Control to charge; release on the “in-range” audio cue.
|
||||
- **Bow**: Ranged (uses arrows). Hold Control to draw; release to fire. Damage scales with draw time (0–10).
|
||||
- Enemies include zombies (night), bandits (invasions), and boars (daytime).
|
||||
- **25% chance** to recover a fired arrow as a world drop.
|
||||
- If your base has an altar, each undead kill grants **+0.2 favor**.
|
||||
|
||||
## Base and Survival
|
||||
- **Passive healing** in the base when below max health.
|
||||
- **Herb Garden** increases healing speed (base only, one per base).
|
||||
- **Fires** require a nearby firepit and need fuel (sticks, vines, logs).
|
||||
- **Barricade** starts at 100 health, capped at 500; reinforces via Crafting > Barricade.
|
||||
- **Storage** enables base inventory management and helps attract residents.
|
||||
- **Residents** (if recruited) consume meat, help defend, repair the barricade, and collect resources.
|
||||
|
||||
## Residents and Automation
|
||||
Residents can automate survival tasks, defend your base, and process resources. To get the most out of them, ensure you have the necessary tools and facilities in your base storage.
|
||||
|
||||
### Recruitment and Care
|
||||
- **Recruitment**: Residents join automatically after invasions. If you have **Storage** built, the likelihood for survivors to become residents increases. **1–2 survivors** can join at a time, up to a maximum of **4 residents**.
|
||||
- **Food**: Each resident consumes **1 unit of food every 8 hours** (3 per day).
|
||||
- Priority: Meat > Smoked Fish > Basket of Fruits and Nuts.
|
||||
- If no food is available, residents will go hungry and stop working.
|
||||
- **Blessing**: The "Blessing of the Resident" (from the Altar) doubles their efficiency and reduces tool breakage for a short time.
|
||||
|
||||
### Activities and Requirements
|
||||
Residents automatically perform these tasks if the requirements are met in your base storage.
|
||||
|
||||
| Activity | Requires (in Storage) | Details |
|
||||
| :--- | :--- | :--- |
|
||||
| **Defense (Melee)** | **Spear** | Deals damage to attackers. Spears may break. |
|
||||
| **Defense (Ranged - Bow)** | **Bow** + **Arrows** | Preferred ranged defense. Consumes arrows. Bows have a chance to break. |
|
||||
| **Defense (Ranged - Sling)** | **Sling** + **Stones** | Attacks enemies from a distance. Consumes stones. Slings have a chance to break. |
|
||||
| **Repairs** | N/A | Repairs the **Barricade** during the day. |
|
||||
| **Gathering** | **Reed Basket** | Collects Sticks, Vines, Stones, and Logs. |
|
||||
| **Foraging** | **Reed Basket** | Occurs at 6 AM and 12 PM. Produces **Basket of Fruits and Nuts**. |
|
||||
| **Fishing** | **Fishing Pole** | Daytime only. Requires a nearby stream. Catches **Raw Fish**. |
|
||||
| **Smoking Fish** | **Raw Fish** + **Sticks** | Requires a **burning fire**. Converts fish to **Smoked Fish**. |
|
||||
| **Butchering** | **Knife** + **Game** | Requires a **burning fire**. Processes Small Game or Boar Carcasses into Meat, Skins, etc. |
|
||||
| **Snare Check** | **Placed Snares** | Checks active snares, retrieves **Small Game**, and resets the snare. |
|
||||
|
||||
> **Note**: Tools (Spears, Slings, Bows, Baskets, Knives, Fishing Poles) have a chance to break when used by residents. Keep a stock of spares!
|
||||
|
||||
## Time, Weather, and Events
|
||||
- **1 real minute = 1 in-game hour**.
|
||||
- Day/night ambience crossfades around sunrise/sunset.
|
||||
- Weather transitions between clear, windy, rainy, and stormy.
|
||||
- **Invasions** can begin after day 2 and expand the map eastward.
|
||||
- Expansions can be normal biomes or mountain ranges.
|
||||
|
||||
## Mountains and Rope Climbing
|
||||
- Mountains have elevation; steep slopes require a rope.
|
||||
- When prompted, press Up to climb up or Down to climb down.
|
||||
- Moving left/right during a rope climb cancels and causes a fall.
|
||||
- Falling from height can cause damage.
|
||||
|
||||
## Quests, Adventures, and Runes
|
||||
- **Quests** become available in the base once you have an altar and enough favor.
|
||||
- **Adventures** are accessed with Tab outside the base (once per day).
|
||||
- The mountain adventure features the **Unicorn boss**.
|
||||
- Defeating the Unicorn unlocks the **Rune of Swiftness**.
|
||||
- Runes are engraved in the base (Crafting > Runes) and require a knife, clay, and favor.
|
||||
|
||||
## Inventory and Storage
|
||||
- Personal inventory stacks are capped at 9.
|
||||
- Skin pouches add +2 stack capacity, backpacks add +9.
|
||||
- Arrows require quivers. Each quiver adds capacity for 12 arrows.
|
||||
- Bowstrings are crafted from **sinew at a fire** and used to craft bows.
|
||||
- Storage is separate and accessed in the base (Inventory menu when storage exists).
|
||||
|
||||
## Saving and Loading
|
||||
- The game auto-saves daily at 6 AM (in-game time).
|
||||
- Load from the main menu. Starting a new game prompts if a save exists.
|
||||
See files/instructions.md for how to play.
|
||||
|
||||
@@ -1,162 +1,191 @@
|
||||
# Draugnorak
|
||||
|
||||
A survival audio game built with NVGT. Explore, gather, craft, and defend your base as day and night cycle.
|
||||
A survival audio game built with NVGT
|
||||
Explore gather craft defend your base through the day and night cycle
|
||||
|
||||
## Installation
|
||||
- Unzip the file for your operating system.
|
||||
- On Linux and Mac, make sure the draugnorak executable is marked executable.
|
||||
- Unzip the file for your operating system
|
||||
- On Linux and Mac mark the draugnorak executable as executable
|
||||
|
||||
``` bash
|
||||
```bash
|
||||
chmod +x draugnorak
|
||||
```
|
||||
|
||||
|
||||
## Quick Start
|
||||
- Move with Left/Right, jump with Up.
|
||||
- Hold Shift, /, or Z for 1 second to search the current area.
|
||||
- Craft basic tools in the base with C.
|
||||
- Set snares and build fires to survive.
|
||||
|
||||
Some of the first things you will want are a stone knife, spear, stone axe, and firepit.
|
||||
- Move with Left or Right
|
||||
- Jump with Up
|
||||
- Hold Shift or slash or Z for 2 seconds to start a search results come after 1 second delay
|
||||
- Craft basic tools in the base with C
|
||||
- Set snares and build fires to survive
|
||||
|
||||
Some of the first things you will want are a stone knife a spear a stone axe and a firepit
|
||||
|
||||
## Controls
|
||||
- **Left/Right**: Move.
|
||||
- **Up**: Jump, climb trees, start rope climbs when prompted.
|
||||
- **Down**: Climb down trees or descend rope climbs when prompted.
|
||||
- **Shift, /, or Z (hold)**: Search area (1-second hold, 1-second delay).
|
||||
- **Control (hold/release)**: Attack with equipped weapon. Bow and sling use a charge window.
|
||||
- **A**: Action menu (place snare, feed fire, burn incense). Also check fire, fishing pole, or snare if in range.
|
||||
- **C**: Crafting menu (base only).
|
||||
- **I**: Inventory.
|
||||
- **E**: Equipment.
|
||||
- **P**: Character info.
|
||||
- **B**: Base info (base only).
|
||||
- **Q**: Quests menu (base only).
|
||||
- **S**: Altar menu (base only).
|
||||
- **Tab**: Adventure menu (outside base, once per day).
|
||||
- **H**: Health.
|
||||
- **T**: Time.
|
||||
- **X**: Coordinates + terrain.
|
||||
- **1-0**: Quick slots (equip bound items).
|
||||
- **Backspace**: Pause/Resume.
|
||||
- **Escape**: Exit game (or close menus).
|
||||
|
||||
- **Left or Right** move
|
||||
- **Up** jump climb trees start rope climbs when prompted
|
||||
- **Down** climb down trees descend rope climbs when prompted
|
||||
- **Shift or slash or Z hold** search area
|
||||
- **Control hold then release** attack with equipped weapon bow and sling use a charge window
|
||||
- **Space** call your pet send it out or call it back
|
||||
- **A** action menu place snare feed fire burn incense also check fire fishing pole or snare if in range
|
||||
- **C** crafting menu base only
|
||||
- **I** inventory
|
||||
- **E** equipment
|
||||
- **P** character info
|
||||
- **B** base info base only
|
||||
- **Q** quests menu base only
|
||||
- **S** altar menu base only
|
||||
- **F** fylgja menu once unlocked
|
||||
- **Tab** adventure menu outside base once per day
|
||||
- **H** health
|
||||
- **T** time
|
||||
- **X** coordinates and terrain
|
||||
- **1 to 0** quick slots press in Equipment to bind an item to equip or in Inventory to bind a count check
|
||||
- **Backspace** pause or resume
|
||||
- **Escape** exit game or close menus
|
||||
|
||||
### History Shortcuts
|
||||
- **\\**: Repeat most recent notification.
|
||||
- **[ / ]**: Previous/next notification.
|
||||
- **, / .**: Previous/next speech history message.
|
||||
|
||||
- **Backslash** repeat most recent notification
|
||||
- **Left bracket** previous notification
|
||||
- **Right bracket** next notification
|
||||
- **Comma** previous speech history message
|
||||
- **Period** next speech history message
|
||||
|
||||
## Menus
|
||||
- **Up/Down**: Move selection.
|
||||
- **Enter**: Confirm.
|
||||
- **Escape**: Close.
|
||||
- **Tab (in most menus)**: Perform “max” actions (craft all, deposit all, etc.).
|
||||
|
||||
- **Up or Down** move selection
|
||||
- **Enter** confirm
|
||||
- **Escape** close
|
||||
- **Tab in most menus** perform max actions craft all deposit all and similar
|
||||
|
||||
## Gathering and Resources
|
||||
- **Grass/Forest/Deep Forest**: Sticks and vines (search).
|
||||
- **Gravel/Stone**: Stones (search).
|
||||
- **Streams/Water edges**: Reeds and clay (search).
|
||||
- **World drops**: Found on the ground after hunting; search picks them up e.g. goose, turkey, and recoverable arrows.
|
||||
- **Trees**:
|
||||
- Search near trees for sticks/vines.
|
||||
- Use an axe to chop down a tree for logs (and extra sticks/vines).
|
||||
- Trees regrow over time.
|
||||
- You can climb trees (Up) and climb down (Down).
|
||||
- **Grass Forest Deep Forest** sticks and vines search
|
||||
- **Gravel Stone** stones search
|
||||
- **Streams and water edges** reeds and clay search
|
||||
- **Snow** found in high mountains currently yields no resources
|
||||
- **World drops** found on the ground after hunting search picks them up such as goose turkey and recoverable arrows
|
||||
- **Trees** search near trees for sticks and vines
|
||||
- **Trees** use an axe to chop a tree for logs and extra sticks and vines
|
||||
- **Trees** regrow over time
|
||||
- **Trees** you can climb Up and climb down with Down
|
||||
|
||||
## Crafting (Base Only)
|
||||
Crafting is only available in the base (C).
|
||||
## Crafting Base Only
|
||||
Crafting is only available in the base with C
|
||||
|
||||
### Categories
|
||||
- **Weapons**: Spear, Sling, Bow
|
||||
- **Tools**: Knife, Snare, Stone Axe, Fishing Pole, Rope, Quiver, Canoe, Reed Basket, Clay Pot
|
||||
- **Materials**: Butcher Game, Smoke Fish, Bowstring, Arrows, Incense
|
||||
- **Clothing**: Skin gear, Moccasins, Pouch, Backpack
|
||||
- **Buildings**: Firepit, Fire, Herb Garden, Storage, Pasture, Stable, Altar
|
||||
- **Barricade**: Reinforcement options
|
||||
- **Runes**: Unlocks later
|
||||
|
||||
- **Weapons** spear sling bow
|
||||
- **Tools** knife snare stone axe fishing pole rope quiver canoe reed basket clay pot
|
||||
- **Materials** butcher game smoke fish bowstring arrows incense
|
||||
- **Clothing** skin gear moccasins pouch backpack
|
||||
- **Buildings** firepit fire herb garden storage pasture stable altar
|
||||
- **Barricade** reinforcement options
|
||||
- **Runes** engrave equipment after unlocking runes in adventures
|
||||
|
||||
## Combat and Hunting
|
||||
- Equip weapons in the Equipment menu (E) or bind them to quick slots.
|
||||
- **Spear**: 1-tile range.
|
||||
- **Axe**: Melee; also chops trees.
|
||||
- **Sling**: Ranged (uses stones). Hold Control to charge; release on the “in-range” audio cue.
|
||||
- **Bow**: Ranged (uses arrows). Hold Control to draw; release to fire. Damage scales with draw time (0–10).
|
||||
- Enemies include zombies (night), bandits (invasions), and boars (daytime).
|
||||
- **25% chance** to recover a fired arrow as a world drop.
|
||||
- If your base has an altar, each undead kill grants **+0.2 favor**.
|
||||
|
||||
- Equip weapons in the Equipment menu or bind them to quick slots
|
||||
- **Spear** 1 tile range
|
||||
- **Axe** melee also chops trees
|
||||
- **Sling** ranged uses stones hold Control to charge release on the in range audio cue
|
||||
- **Bow** ranged uses arrows hold Control to draw release to fire damage scales with draw time 0 to 10
|
||||
- Enemies include zombies at night bandits during invasions and boars during daytime
|
||||
- **25 percent chance** to recover a fired arrow as a world drop
|
||||
- If your base has an altar each undead kill grants 0.2 favor
|
||||
|
||||
## Base and Survival
|
||||
- **Passive healing** in the base when below max health.
|
||||
- **Herb Garden** increases healing speed (base only, one per base).
|
||||
- **Fires** require a nearby firepit and need fuel (sticks, vines, logs).
|
||||
- **Barricade** starts at 100 health, capped at 500; reinforces via Crafting > Barricade.
|
||||
- **Storage** enables base inventory management and helps attract residents.
|
||||
- **Residents** (if recruited) consume meat, help defend, repair the barricade, and collect resources.
|
||||
|
||||
- Passive healing in the base when below max health
|
||||
- Herb Garden increases healing speed base only one per base
|
||||
- Fires require a nearby firepit and need fuel sticks vines logs
|
||||
- Barricade starts at 40 health capped at 500 reinforces via Crafting Barricade
|
||||
- Storage enables base inventory management and helps attract residents
|
||||
- Residents if recruited consume meat help defend repair the barricade and collect resources
|
||||
|
||||
## Residents and Automation
|
||||
Residents can automate survival tasks, defend your base, and process resources. To get the most out of them, ensure you have the necessary tools and facilities in your base storage.
|
||||
|
||||
Residents can automate survival tasks defend your base and process resources
|
||||
To get the most out of them ensure you have the necessary tools and facilities in your base storage
|
||||
|
||||
### Recruitment and Care
|
||||
- **Recruitment**: Residents join automatically after invasions. If you have **Storage** built, the likelihood for survivors to become residents increases. **1–2 survivors** can join at a time, up to a maximum of **4 residents**. Beware the vampyr, it will eat your residents.
|
||||
- **Food**: Each resident consumes **1 unit of food every 8 hours** (3 per day).
|
||||
- Priority: Meat > Smoked Fish > Basket of Fruits and Nuts.
|
||||
- If no food is available, residents will go hungry and stop working.
|
||||
- **Blessing**: The "Blessing of the Resident" (from the Altar) doubles their efficiency and reduces tool breakage for a short time.
|
||||
|
||||
- **Recruitment** residents can join after invasions end if your barricade is standing storage increases the chance 1 to 2 survivors can join at a time up to a maximum of 4 residents beware the vampyr it will eat your residents
|
||||
- **Food** each resident consumes 1 unit of food every 8 hours 3 per day
|
||||
- **Food priority** meat then smoked fish then basket of fruits and nuts
|
||||
- **Hunger** if no food is available residents go hungry and stop working
|
||||
- **Blessing** the Blessing of the Resident from the altar doubles efficiency and reduces tool breakage for a short time
|
||||
|
||||
### Activities and Requirements
|
||||
Residents automatically perform these tasks if the requirements are met in your base storage.
|
||||
- **Defense melee** requires spear deals damage to attackers spears can break
|
||||
- **Defense ranged bow** requires bow and arrows preferred ranged defense consumes arrows bows can break
|
||||
- **Defense ranged sling** requires sling and stones attacks from a distance consumes stones slings can break
|
||||
- **Repairs** no tools required repairs the barricade during the day
|
||||
- **Gathering** requires reed basket collects sticks vines stones and logs
|
||||
- **Foraging** requires reed basket occurs during daytime and scales with resident count produces basket of fruits and nuts
|
||||
- **Fishing** requires fishing pole daytime only requires a nearby stream catches raw fish
|
||||
- **Smoking fish** requires raw fish and sticks requires a burning fire converts fish to smoked fish
|
||||
- **Butchering** requires knife and game requires a burning fire processes small game or boar carcasses into meat skins and more
|
||||
- **Snare check** requires placed snares checks active snares retrieves small game and resets the snare
|
||||
|
||||
| Activity | Requires (in Storage) | Details |
|
||||
| :--- | :--- | :--- |
|
||||
| **Defense (Melee)** | **Spear** | Deals damage to attackers. Spears may break. |
|
||||
| **Defense (Ranged - Bow)** | **Bow** + **Arrows** | Preferred ranged defense. Consumes arrows. Bows have a chance to break. |
|
||||
| **Defense (Ranged - Sling)** | **Sling** + **Stones** | Attacks enemies from a distance. Consumes stones. Slings have a chance to break. |
|
||||
| **Repairs** | N/A | Repairs the **Barricade** during the day. |
|
||||
| **Gathering** | **Reed Basket** | Collects Sticks, Vines, Stones, and Logs. |
|
||||
| **Foraging** | **Reed Basket** | Occurs at 6 AM and 12 PM. Produces **Basket of Fruits and Nuts**. |
|
||||
| **Fishing** | **Fishing Pole** | Daytime only. Requires a nearby stream. Catches **Raw Fish**. |
|
||||
| **Smoking Fish** | **Raw Fish** + **Sticks** | Requires a **burning fire**. Converts fish to **Smoked Fish**. |
|
||||
| **Butchering** | **Knife** + **Game** | Requires a **burning fire**. Processes Small Game or Boar Carcasses into Meat, Skins, etc. |
|
||||
| **Snare Check** | **Placed Snares** | Checks active snares, retrieves **Small Game**, and resets the snare. |
|
||||
Tools used by residents can break keep a stock of spares
|
||||
|
||||
> **Note**: Tools (Spears, Slings, Bows, Baskets, Knives, Fishing Poles) have a chance to break when used by residents. Keep a stock of spares!
|
||||
## Pets
|
||||
Pets are optional companions that can fight and retrieve drops
|
||||
|
||||
## Time, Weather, and Events
|
||||
- **1 real minute = 1 in-game hour**.
|
||||
- Day/night ambience crossfades around sunrise/sunset.
|
||||
- Weather transitions between clear, windy, rainy, and stormy.
|
||||
- **Invasions** can begin after day 2 and expand the map eastward.
|
||||
- Expansions can be normal biomes or mountain ranges.
|
||||
### Getting a pet
|
||||
- Pets can appear after a quest score of 10 or more
|
||||
- Pets can appear after adventure victories with a small chance
|
||||
- Reaching the top of a tree can attract a hawk with a small chance
|
||||
- You need food to accept a pet offer
|
||||
|
||||
### Calling and status
|
||||
- **Space** call your pet
|
||||
- If your pet is out Space calls it back
|
||||
- If your pet is with you Space sends it out and costs 1 loyalty
|
||||
- If your pet is knocked out Space reports remaining recovery time
|
||||
- Press H to hear pet health and loyalty when you have a pet
|
||||
|
||||
### Loyalty and feeding
|
||||
- Loyalty starts at 5 and max is 10
|
||||
- If no food is available loyalty drops by 2 each hour
|
||||
- Every 8 hours your pet eats 1 food and gains 2 loyalty if food is available
|
||||
- Food can be meat smoked fish raw fish or basket of fruits and nuts
|
||||
- Food is taken from your inventory first then storage
|
||||
- If loyalty reaches 0 your pet leaves
|
||||
|
||||
### Help in the field
|
||||
- When out your pet attacks bandits undead and boars within range
|
||||
- Each successful hit costs the pet 1 health
|
||||
- If health reaches 0 the pet is knocked out for 3 hours and then recovers
|
||||
- When out your pet can retrieve world drops like small game boar carcasses and arrows
|
||||
- If you cannot carry the item the pet keeps it and it is lost
|
||||
|
||||
### Random finds
|
||||
- If loyalty is at least 5 your pet can bring back sticks vines stones or clay
|
||||
|
||||
## Time Weather and Events
|
||||
- 1 real minute equals 1 in game hour
|
||||
- Day night ambience crossfades around sunrise and sunset
|
||||
- Weather transitions between clear windy rainy and stormy
|
||||
- Invasions begin on or after day 2 and expand the map east
|
||||
- Expansions can be normal biomes or mountain ranges
|
||||
|
||||
## Mountains and Rope Climbing
|
||||
- Mountains have elevation; steep slopes require a rope.
|
||||
- When prompted, press Up to climb up or Down to climb down.
|
||||
- Moving left/right during a rope climb cancels and causes a fall.
|
||||
- Falling from height can cause damage.
|
||||
- Mountains have elevation steep slopes require a rope
|
||||
- When prompted press Up to climb up or Down to climb down
|
||||
- Moving left or right during a rope climb cancels and causes a fall
|
||||
- Falling from height can cause damage
|
||||
|
||||
## Quests, Adventures, and Runes
|
||||
- **Quests** become available in the base once you have an altar and enough favor.
|
||||
- **Adventures** are accessed with Tab outside the base (once per day).
|
||||
- The mountain adventure features the **Unicorn boss**.
|
||||
- Defeating the Unicorn unlocks the **Rune of Swiftness**.
|
||||
- Runes are engraved in the base (Crafting > Runes) and require a knife, clay, and favor.
|
||||
## Quests Adventures and Runes
|
||||
- Quests become available in the base once you have an altar and enough favor
|
||||
- Adventures are accessed with Tab outside the base once per day
|
||||
- The mountain adventure features the Unicorn boss unlocking the Rune of Swiftness
|
||||
- The forest adventure features the Bandit Hideout unlocking the Rune of Destruction
|
||||
- Fylgja unlocks after 9 wins in its adventure press F to activate once per day for example Unicorn Charge
|
||||
- Runes are engraved in the base Crafting Runes and require a knife clay and favor
|
||||
|
||||
## Inventory and Storage
|
||||
- Personal inventory stacks are capped at 9.
|
||||
- Skin pouches add +2 stack capacity, backpacks add +9.
|
||||
- Arrows require quivers. Each quiver adds capacity for 12 arrows.
|
||||
- Bowstrings are crafted from **sinew at a fire** and used to craft bows.
|
||||
- Storage is separate and accessed in the base (Inventory menu when storage exists).
|
||||
- Personal inventory stacks are capped at 9
|
||||
- Skin pouches add 2 stack capacity backpacks add 9
|
||||
- Arrows require quivers each quiver adds capacity for 12 arrows
|
||||
- Bowstrings are crafted from sinew at a fire and used to craft bows
|
||||
- Storage is separate and accessed in the base Inventory menu when storage exists
|
||||
|
||||
## Saving and Loading
|
||||
- The game auto-saves daily at 6 AM (in-game time).
|
||||
- Load from the main menu. Starting a new game prompts if a save exists.
|
||||
- The game auto saves daily at 6 AM in game time
|
||||
- Load from the main menu starting a new game prompts if a save exists
|
||||
- In the Load Game menu press Delete to remove the selected save (confirmation required)
|
||||
|
||||
@@ -11,9 +11,9 @@ const int BANDIT_HIDEOUT_BASE_SPAWN_RANGE = 10;
|
||||
const int BANDIT_HIDEOUT_START_SPAWN_RANGE = 10;
|
||||
const int BANDIT_HIDEOUT_BARRICADE_HP_PER_DAY = 34;
|
||||
const int BANDIT_HIDEOUT_BARRICADE_HP_MAX = 500;
|
||||
const double BANDIT_HIDEOUT_FAVOR_PER_KILL = 0.2;
|
||||
const double BANDIT_HIDEOUT_BASE_FAVOR = 3.0;
|
||||
const double BANDIT_HIDEOUT_FAVOR_MAX = 10.0;
|
||||
const double BANDIT_HIDEOUT_FAVOR_PER_KILL = 0.08;
|
||||
const double BANDIT_HIDEOUT_BASE_FAVOR = 0.30;
|
||||
const double BANDIT_HIDEOUT_FAVOR_MAX = 1.0;
|
||||
|
||||
class HideoutBandit {
|
||||
int position;
|
||||
|
||||
@@ -653,7 +653,7 @@ void give_unicorn_rewards() {
|
||||
speak_with_history("Victory!", true);
|
||||
|
||||
// Calculate rewards
|
||||
int favor_reward = 4 + random(1, 4); // 4 + 1d4 = 5-8 favor
|
||||
double favor_reward = double(random(7, 10)) / 10.0; // 0.7-1.0 favor
|
||||
favor += favor_reward;
|
||||
int scrolls_added = add_to_stack(get_personal_count(ITEM_HEAL_SCROLL), 1);
|
||||
add_personal_count(ITEM_HEAL_SCROLL, scrolls_added);
|
||||
@@ -667,7 +667,7 @@ void give_unicorn_rewards() {
|
||||
string[] rewards;
|
||||
rewards.insert_last("=== Victory Rewards ===");
|
||||
rewards.insert_last("");
|
||||
rewards.insert_last("The gods are pleased with your victory! " + favor_reward + " favor awarded.");
|
||||
rewards.insert_last("The gods are pleased with your victory! " + format_favor(favor_reward) + " favor awarded.");
|
||||
rewards.insert_last("Heal Scrolls: +" + scrolls_added + ".");
|
||||
rewards.insert_last("");
|
||||
if (new_rune) {
|
||||
|
||||
@@ -442,7 +442,14 @@ int add_to_stack(int current, int amount) {
|
||||
|
||||
string format_favor(double value) {
|
||||
if (value < 0) value = 0;
|
||||
return "" + int(value);
|
||||
int scaled = int((value * 100.0) + 0.5);
|
||||
int wholePart = scaled / 100;
|
||||
int fractionalPart = scaled % 100;
|
||||
|
||||
if (fractionalPart <= 0) return "" + wholePart;
|
||||
if (fractionalPart < 10) return wholePart + ".0" + fractionalPart;
|
||||
if (fractionalPart % 10 == 0) return wholePart + "." + (fractionalPart / 10);
|
||||
return wholePart + "." + fractionalPart;
|
||||
}
|
||||
|
||||
string get_equipped_weapon_name() {
|
||||
|
||||
@@ -110,6 +110,14 @@ bool sort_string_case_insensitive_sounds(const string &in a, const string &in b)
|
||||
return a.lower() < b.lower();
|
||||
}
|
||||
|
||||
void append_unique_case_insensitive(string[]@ items, const string&in value) {
|
||||
string lowerValue = value.lower();
|
||||
for (uint i = 0; i < items.length(); i++) {
|
||||
if (items[i].lower() == lowerValue) return;
|
||||
}
|
||||
items.insert_last(value);
|
||||
}
|
||||
|
||||
string collapse_spaces(const string&in text) {
|
||||
string result = text;
|
||||
while (result.find_first(" ") > -1) {
|
||||
@@ -159,13 +167,13 @@ void add_doc_entries(string[]@ labels, string[]@ paths, int[]@ types) {
|
||||
string[]@ mdFiles = find_files("files/*.md");
|
||||
if (@mdFiles !is null) {
|
||||
for (uint i = 0; i < mdFiles.length(); i++) {
|
||||
docFiles.insert_last(mdFiles[i]);
|
||||
append_unique_case_insensitive(docFiles, mdFiles[i]);
|
||||
}
|
||||
}
|
||||
string[]@ mdCapsFiles = find_files("files/*.MD");
|
||||
if (@mdCapsFiles !is null) {
|
||||
for (uint i = 0; i < mdCapsFiles.length(); i++) {
|
||||
docFiles.insert_last(mdCapsFiles[i]);
|
||||
append_unique_case_insensitive(docFiles, mdCapsFiles[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
// Altar/sacrifice menu system
|
||||
// Functions for sacrificing items at the altar
|
||||
|
||||
string format_altar_favor(double value) {
|
||||
if (value < 0) value = 0;
|
||||
return "" + int(value);
|
||||
}
|
||||
|
||||
void check_altar_menu(int player_x) {
|
||||
if (!key_pressed(KEY_S)) return;
|
||||
|
||||
@@ -43,7 +48,7 @@ void sacrifice_item(int item_type) {
|
||||
cleanup_equipment_after_inventory_change();
|
||||
double favor_gain = get_item_favor_value(item_type);
|
||||
favor += favor_gain;
|
||||
speak_with_history("Sacrificed 1 " + get_item_label_singular(item_type) + ". Favor +" + format_favor(favor_gain) + ". Total " + format_favor(favor) + ".", true);
|
||||
speak_with_history("Sacrificed 1 " + get_item_label_singular(item_type) + ". Favor +" + format_altar_favor(favor_gain) + ". Total " + format_altar_favor(favor) + ".", true);
|
||||
}
|
||||
|
||||
void sacrifice_item_max(int item_type) {
|
||||
@@ -71,11 +76,11 @@ void sacrifice_item_max(int item_type) {
|
||||
double total_favor = favor_per_item * available;
|
||||
favor += total_favor;
|
||||
|
||||
speak_with_history("Sacrificed " + available + " " + get_item_label(item_type) + ". Favor +" + format_favor(total_favor) + ". Total " + format_favor(favor) + ".", true);
|
||||
speak_with_history("Sacrificed " + available + " " + get_item_label(item_type) + ". Favor +" + format_altar_favor(total_favor) + ". Total " + format_altar_favor(favor) + ".", true);
|
||||
}
|
||||
|
||||
void run_altar_menu() {
|
||||
speak_with_history("Altar. Favor " + format_favor(favor) + ".", true);
|
||||
speak_with_history("Altar. Favor " + format_altar_favor(favor) + ".", true);
|
||||
|
||||
int selection = 0;
|
||||
string[] options;
|
||||
|
||||
@@ -404,8 +404,10 @@ void check_pet_call_key() {
|
||||
petOut = true;
|
||||
petPosition = get_pet_listener_pos();
|
||||
petPositionValid = true;
|
||||
if (file_exists("sounds/pets/call_pet.ogg")) {
|
||||
p.play_stationary("sounds/pets/call_pet.ogg", false);
|
||||
if (file_exists("sounds/action/call_pet.ogg")) {
|
||||
/* But I can feel it, black water washes over me.
|
||||
As it soothes I call to you with my control. */
|
||||
p.play_stationary("sounds/action/call_pet.ogg", false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -661,7 +663,7 @@ bool try_pet_pickup_small_game(const string&in gameType, string &out message) {
|
||||
}
|
||||
add_personal_count(ITEM_SMALL_GAME, 1);
|
||||
personal_small_game_types.insert_last(gameType);
|
||||
message = "Your " + get_pet_display_name() + " retrieved " + gameType + ". A " + get_pet_display_name() + " returns to you.";
|
||||
message = "Your " + get_pet_display_name() + " retrieved " + gameType + ".";
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -681,7 +683,7 @@ bool try_pet_pickup_world_drop(WorldDrop@ drop, string &out message) {
|
||||
return true;
|
||||
}
|
||||
add_personal_count(ITEM_ARROWS, 1);
|
||||
message = "Your " + get_pet_display_name() + " retrieved an arrow. A " + get_pet_display_name() + " returns to you.";
|
||||
message = "Your " + get_pet_display_name() + " retrieved an arrow.";
|
||||
return true;
|
||||
}
|
||||
if (drop.type == "boar carcass") {
|
||||
@@ -690,7 +692,7 @@ bool try_pet_pickup_world_drop(WorldDrop@ drop, string &out message) {
|
||||
return true;
|
||||
}
|
||||
add_personal_count(ITEM_BOAR_CARCASSES, 1);
|
||||
message = "Your " + get_pet_display_name() + " retrieved a boar carcass. A " + get_pet_display_name() + " returns to you.";
|
||||
message = "Your " + get_pet_display_name() + " retrieved a boar carcass.";
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -868,6 +870,11 @@ void handle_pet_hourly_update(int hour) {
|
||||
}
|
||||
}
|
||||
|
||||
if (petKnockoutHoursRemaining <= 0 && petHealth > 0 && petHealth < PET_HEALTH_MAX) {
|
||||
petHealth += 1;
|
||||
if (petHealth > PET_HEALTH_MAX) petHealth = PET_HEALTH_MAX;
|
||||
}
|
||||
|
||||
if (!has_pet_food_available()) {
|
||||
adjust_pet_loyalty(-PET_LOYALTY_HUNGER_LOSS);
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ string get_quest_description(int quest_type) {
|
||||
|
||||
int get_quest_chance_from_favor() {
|
||||
int chance = int(favor * QUEST_CHANCE_PER_FAVOR);
|
||||
if (chance < QUEST_MIN_CHANCE && favor > 1.0) chance = QUEST_MIN_CHANCE;
|
||||
if (chance < QUEST_MIN_CHANCE && favor >= 1.0) chance = QUEST_MIN_CHANCE;
|
||||
if (chance > 100) chance = 100;
|
||||
return chance;
|
||||
}
|
||||
@@ -66,7 +66,7 @@ void add_quest(int quest_type) {
|
||||
|
||||
void attempt_daily_quest() {
|
||||
if (quest_roll_done_today) return;
|
||||
if (favor <= 1.0) return;
|
||||
if (favor < 1.0) return;
|
||||
if (world_altars.length() == 0) return;
|
||||
if (quest_queue.length() >= QUEST_MAX_ACTIVE) return;
|
||||
|
||||
@@ -105,6 +105,7 @@ string get_quest_favor_phrase(int score) {
|
||||
void apply_quest_reward(int score) {
|
||||
double favor_gain = score * QUEST_FAVOR_PER_POINT;
|
||||
if (favor_gain < 0) favor_gain = 0;
|
||||
if (favor_gain > 1.0) favor_gain = 1.0;
|
||||
favor += favor_gain;
|
||||
|
||||
// Determine quantity based on score
|
||||
@@ -142,6 +143,7 @@ void apply_quest_reward(int score) {
|
||||
|
||||
string message = "Quest Complete!\n\nRewards:\n";
|
||||
message += get_quest_favor_phrase(score) + "\n";
|
||||
message += "Favor: +" + format_favor(favor_gain) + "\n";
|
||||
|
||||
if (added_amount > 0) {
|
||||
message += get_item_display_name(reward_item) + ": +" + added_amount + "\n";
|
||||
|
||||
@@ -414,47 +414,85 @@ bool setup_new_character() {
|
||||
}
|
||||
|
||||
bool select_save_file(string &out filename) {
|
||||
string[] files = get_save_files();
|
||||
if (files.length() == 0) return false;
|
||||
|
||||
string[] options;
|
||||
for (uint i = 0; i < files.length(); i++) {
|
||||
string displayName;
|
||||
int sex = SEX_MALE;
|
||||
int day = 1;
|
||||
if (!read_save_metadata(files[i], displayName, sex, day)) {
|
||||
displayName = strip_save_extension(files[i]);
|
||||
options.insert_last(displayName);
|
||||
} else {
|
||||
string sex_label = (sex == SEX_FEMALE) ? "female" : "male";
|
||||
options.insert_last(displayName + ", " + sex_label + ", day " + day);
|
||||
}
|
||||
}
|
||||
|
||||
int selection = 0;
|
||||
speak_with_history("Load game. Select character.", true);
|
||||
speak_with_history(options[selection], true);
|
||||
|
||||
while (true) {
|
||||
wait(5);
|
||||
if (key_pressed(KEY_DOWN)) {
|
||||
play_menu_move_sound();
|
||||
selection++;
|
||||
if (selection >= options.length()) selection = 0;
|
||||
speak_with_history(options[selection], true);
|
||||
string[] files = get_save_files();
|
||||
if (files.length() == 0) return false;
|
||||
|
||||
string[] options;
|
||||
string[] displayNames;
|
||||
int[] sexValues;
|
||||
int[] dayValues;
|
||||
bool[] hasMetadata;
|
||||
for (uint i = 0; i < files.length(); i++) {
|
||||
string displayName;
|
||||
int sex = SEX_MALE;
|
||||
int day = 1;
|
||||
bool gotMeta = read_save_metadata(files[i], displayName, sex, day);
|
||||
if (!gotMeta) {
|
||||
displayName = strip_save_extension(files[i]);
|
||||
options.insert_last(displayName);
|
||||
} else {
|
||||
string sex_label = (sex == SEX_FEMALE) ? "female" : "male";
|
||||
options.insert_last(displayName + ", " + sex_label + ", day " + day);
|
||||
}
|
||||
displayNames.insert_last(displayName);
|
||||
sexValues.insert_last(sex);
|
||||
dayValues.insert_last(day);
|
||||
hasMetadata.insert_last(gotMeta);
|
||||
}
|
||||
if (key_pressed(KEY_UP)) {
|
||||
play_menu_move_sound();
|
||||
selection--;
|
||||
if (selection < 0) selection = int(options.length()) - 1;
|
||||
speak_with_history(options[selection], true);
|
||||
|
||||
int selection = 0;
|
||||
speak_with_history("Load game. Select character. Press delete to remove a save.", true);
|
||||
speak_with_history(options[selection], true);
|
||||
|
||||
bool refreshList = false;
|
||||
while (true) {
|
||||
wait(5);
|
||||
if (key_pressed(KEY_DOWN)) {
|
||||
play_menu_move_sound();
|
||||
selection++;
|
||||
if (selection >= options.length()) selection = 0;
|
||||
speak_with_history(options[selection], true);
|
||||
}
|
||||
if (key_pressed(KEY_UP)) {
|
||||
play_menu_move_sound();
|
||||
selection--;
|
||||
if (selection < 0) selection = int(options.length()) - 1;
|
||||
speak_with_history(options[selection], true);
|
||||
}
|
||||
if (key_pressed(KEY_RETURN)) {
|
||||
play_menu_select_sound();
|
||||
filename = files[selection];
|
||||
return true;
|
||||
}
|
||||
if (key_pressed(KEY_DELETE)) {
|
||||
string prompt = "Are you sure you want to delete the character " + displayNames[selection];
|
||||
if (hasMetadata[selection]) {
|
||||
string sex_label = (sexValues[selection] == SEX_FEMALE) ? "female" : "male";
|
||||
prompt += " gender " + sex_label + " days " + dayValues[selection] + "?";
|
||||
} else {
|
||||
prompt += "?";
|
||||
}
|
||||
int confirm = ui_question("", prompt);
|
||||
if (confirm == 1) {
|
||||
if (file_delete(files[selection])) {
|
||||
speak_with_history("Save deleted.", true);
|
||||
refreshList = true;
|
||||
break;
|
||||
} else {
|
||||
ui_info_box("Draugnorak", "Delete Save", "Unable to delete save.");
|
||||
speak_with_history(options[selection], true);
|
||||
}
|
||||
} else {
|
||||
speak_with_history(options[selection], true);
|
||||
}
|
||||
}
|
||||
if (key_pressed(KEY_ESCAPE)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (key_pressed(KEY_RETURN)) {
|
||||
play_menu_select_sound();
|
||||
filename = files[selection];
|
||||
return true;
|
||||
}
|
||||
if (key_pressed(KEY_ESCAPE)) {
|
||||
|
||||
if (!refreshList) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -894,7 +894,8 @@ string get_time_string() {
|
||||
} else if (weather_state == WEATHER_STORMY) {
|
||||
conditions.insert_last("Storming");
|
||||
}
|
||||
if (!is_daytime) {
|
||||
bool can_see_night_sky = (weather_state == WEATHER_CLEAR || weather_state == WEATHER_WINDY);
|
||||
if (!is_daytime && can_see_night_sky) {
|
||||
conditions.insert_last("Moon and stars");
|
||||
}
|
||||
if (conditions.length() > 0) {
|
||||
|
||||
Reference in New Issue
Block a user