job board checkpoint

This commit is contained in:
evilchili 2023-09-01 18:41:19 -07:00
parent 0d2662a2b6
commit 4bf15b8b4f
4 changed files with 112 additions and 5 deletions

View File

@ -1,12 +1,29 @@
import random import random
import collections import collections
from pathlib import Path
from rolltable.tables import RollTable
from npc.generator.base import generate_npc from npc.generator.base import generate_npc
Crime = collections.namedtuple('Crime', ['name', 'min_bounty', 'max_bounty']) Crime = collections.namedtuple('Crime', ['name', 'min_bounty', 'max_bounty'])
def generate_location(frequency='default'):
source = Path("sources/locations.yaml")
rt = RollTable([source.read_text()], hide_rolls=True, frequency=frequency)
return random.choice(rt.rows[1:])[1]
def nearest(value, step=50):
if value < step:
return step
remainder = value % step
if remainder > int(step / 2):
return value - remainder + step
return value - remainder
class BaseJob: class BaseJob:
""" """
The base class for random odd jobs. The base class for random odd jobs.
@ -22,7 +39,7 @@ class BaseJob:
self._name = name self._name = name
self._details = details self._details = details
self._reward = reward self._reward = reward
self._contact = contact self._contact = contact or generate_npc()
self._location = location self._location = location
@property @property
@ -87,8 +104,7 @@ class Bounty(BaseJob):
self._dead_or_alive = ' or '.join(dead_or_alive) self._dead_or_alive = ' or '.join(dead_or_alive)
if not self._reward: if not self._reward:
# need to round to the nearest 10 < 100, nearest 100 otherwise reward = nearest(random.randint(self.crime.min_bounty, self.crime.max_bounty))
reward = round(random.randint(self.crime.min_bounty, self.crime.max_bounty), 5)
self._reward = f"{reward} Gold Pieces" self._reward = f"{reward} Gold Pieces"
if not self._name: if not self._name:
@ -117,6 +133,48 @@ class Bounty(BaseJob):
return self._target return self._target
class Determinant(BaseJob):
"""
Hiring the services of a Determinant to resolve a dispute.
"""
def __init__(self, **kwargs):
super().__init__(**kwargs)
class Escort(BaseJob):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self._contact = generate_npc()
self._location = generate_location('settlements')
self._destination = generate_location('default')
self._reward = f"{nearest(random.randint(5, 20), step=5)} GP/day"
self._name = (
f"Accompany {self.contact} from {self.location} to "
f"{self._destination}. {self.reward}"
)
class Foraging(BaseJob):
def __init__(self, **kwargs):
super().__init__(**kwargs)
source = Path("sources/flora.yaml")
rt = RollTable([source.read_text()], hide_rolls=True)
# [ rarity, name, descr, val ]
self._ingredient = random.choice(rt.rows)
self._amount = nearest(random.randint(0, 300), step=25)
value = self._amount * int(self._ingredient[3].split(' ')[0])
bonus = nearest(random.randint(0, 200))
self._reward = f"{value} GP + {bonus} GP Bonus"
self._name = f"{self.reward} for {self._amount} {self._ingredient[1]}"
self._contact = "Andok"
self._location = "Andok's Apothecary, Tano's Edge"
classes = BaseJob.__subclasses__() classes = BaseJob.__subclasses__()
job_types = [c.__name__ for c in classes] job_types = [c.__name__ for c in classes]
@ -126,4 +184,5 @@ def generate_job():
if __name__ == '__main__': if __name__ == '__main__':
print(Bounty()) for i in range(10):
print(Escort())

View File

@ -142,7 +142,7 @@ Weird:
- A jet black conical mushroom. The soil around it turns jet black. Said to grant visions when ingested. - A jet black conical mushroom. The soil around it turns jet black. Said to grant visions when ingested.
- 5 GP - 5 GP
- Rolling Cactus: - Rolling Cactus:
- A globular cactus that rolls and bounces freely in the wind. 1 gallon of water can be harvested from 10 cacti. - A globular cactus that rolls and bounces freely in the wind.
- 5 GP - 5 GP
- Orc's Fart: - Orc's Fart:
- A large succulent up to 4ft in height, which continually produces a pungent gas, swelling the bulb. When the bulb is forced open, a toxic cloud 20ft in diameter is expelled. DC 13 CON save or 1d4 poison dmg. - A large succulent up to 4ft in height, which continually produces a pungent gas, swelling the bulb. When the bulb is forced open, a toxic cloud 20ft in diameter is expelled. DC 13 CON save or 1d4 poison dmg.

View File

@ -0,0 +1,27 @@
# locations
metadata:
headers:
- Name
frequencies:
default:
Settlements: 0.5
Sahwat: 0.5
settlements:
Settlements: 1.0
Sahwat: 0.0
sahwat:
Settlements: 0.0
Sahwat: 1.0
Settlements:
- Tano's Edge
- The Heap
- Gazakh Noch
- Poshni Koth
Sahwat:
- Blooming Wastes
- Dust River Canyon
- Gopher Gulch
- Calamity Ridge
- The Haunted Hills
- Bone City
- The Undersands

View File

@ -0,0 +1,21 @@
import pytest
from site_tools import jobs
@pytest.mark.parametrize('value, step, expected', [
(0, 50, 50),
(49, 50, 50),
(51, 50, 50),
(99, 50, 100),
(100, 50, 100),
(101, 50, 100),
(124, 50, 100),
(125, 50, 100),
(126, 50, 150),
(150, 50, 150),
(151, 50, 150),
(199, 50, 200)
])
def test_nearest(value, step, expected):
assert jobs.nearest(value, step=step) == expected