├── .gitignore ├── src ├── ducks │ ├── index.js │ └── mission.js ├── reducer.js ├── store │ ├── index.js │ ├── prod.js │ └── dev.js ├── views │ ├── root │ │ ├── index.js │ │ ├── prod.js │ │ └── dev.js │ ├── lengthSelector.js │ ├── locationSelector.js │ ├── app.js │ ├── locationTips.js │ ├── locationCurios.js │ └── missionProvisions.js ├── index.js ├── components │ ├── capitalize.js │ ├── devtools.js │ └── torchRadioGroup.js └── data │ ├── tips.js │ ├── provisions.js │ └── curios.js ├── images.sketch ├── public ├── logo.png ├── cursor.png ├── cursor_link.png ├── icons │ ├── coin.png │ ├── redCross.png │ ├── curios │ │ ├── sack.png │ │ ├── crate.png │ │ ├── sconce.png │ │ ├── bookshelf.png │ │ ├── fish_idol.png │ │ ├── old_tree.png │ │ ├── bas_relief.png │ │ ├── bone_altar.png │ │ ├── dinner_cart.png │ │ ├── eerie_coral.png │ │ ├── iron_maiden.png │ │ ├── sarcophagus.png │ │ ├── alchemy_table.png │ │ ├── altar_of_light.png │ │ ├── ancient_coffin.png │ │ ├── beast_carcass.png │ │ ├── decorative_urn.png │ │ ├── discarded_pack.png │ │ ├── eldritch_alter.png │ │ ├── giant_oyster.png │ │ ├── heirloom_chest.png │ │ ├── holy_fountain.png │ │ ├── left_luggage.png │ │ ├── pile_of_bones.png │ │ ├── rack_of_blades.png │ │ ├── shallow_grave.png │ │ ├── stack_of_books.png │ │ ├── suit_of_armor.png │ │ ├── travelers_tent.png │ │ ├── ancient_artifact.png │ │ ├── confession_booth.png │ │ ├── eerie_spiderweb.png │ │ ├── moonshine_barrel.png │ │ ├── pile_of_scrolls.png │ │ ├── shamblers_altar.png │ │ ├── ships_figurehead.png │ │ ├── troubling_effigy.png │ │ ├── ancestors_knapsack.png │ │ ├── brackish_tidepool.png │ │ ├── giant_fish_carcass.png │ │ ├── locked_sarcophagus.png │ │ ├── mummified_remains.png │ │ ├── occult_scrawlings.png │ │ ├── pristine_fountain.png │ │ ├── sacrificial_stone.png │ │ ├── unlocked_strongbox.png │ │ ├── bernacle_crusted_chest.png │ │ ├── locked_display_cabinet.png │ │ └── makeshift_dining_table.png │ └── provisions │ │ ├── Food.gif │ │ ├── Food.png │ │ ├── Torch.png │ │ ├── Bandage.png │ │ ├── Food_0.png │ │ ├── Food_1.png │ │ ├── Food_2.png │ │ ├── Food_3.png │ │ ├── Shovel.png │ │ ├── Antivenom.png │ │ ├── Dog_Treats.png │ │ ├── Firewood.png │ │ ├── Holy_Water.png │ │ ├── Skeleton_Key.png │ │ └── Medicinal_Herbs.png ├── checkbox_sprite.png ├── fonts │ ├── 3073CA_0_0.eot │ ├── 3073CA_0_0.ttf │ ├── 3073CA_0_0.woff │ ├── 3073CA_1_0.eot │ ├── 3073CA_1_0.ttf │ ├── 3073CA_1_0.woff │ ├── 3073CA_0_0.woff2 │ └── 3073CA_1_0.woff2 ├── provisions_background.png ├── index.html └── style.css ├── screenshots.png ├── .babelrc ├── README.md ├── webpack.config.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | public/bundle.js 2 | public/bundle.js.map 3 | node_modules 4 | -------------------------------------------------------------------------------- /src/ducks/index.js: -------------------------------------------------------------------------------- 1 | export function selector(state) { 2 | return state; 3 | } 4 | -------------------------------------------------------------------------------- /images.sketch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/images.sketch -------------------------------------------------------------------------------- /public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/logo.png -------------------------------------------------------------------------------- /screenshots.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/screenshots.png -------------------------------------------------------------------------------- /public/cursor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/cursor.png -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "presets": ["es2015", "react"], 4 | "plugins": ["transform-object-rest-spread"] 5 | } 6 | -------------------------------------------------------------------------------- /public/cursor_link.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/cursor_link.png -------------------------------------------------------------------------------- /public/icons/coin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/coin.png -------------------------------------------------------------------------------- /public/icons/redCross.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/redCross.png -------------------------------------------------------------------------------- /public/checkbox_sprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/checkbox_sprite.png -------------------------------------------------------------------------------- /public/fonts/3073CA_0_0.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/fonts/3073CA_0_0.eot -------------------------------------------------------------------------------- /public/fonts/3073CA_0_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/fonts/3073CA_0_0.ttf -------------------------------------------------------------------------------- /public/fonts/3073CA_0_0.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/fonts/3073CA_0_0.woff -------------------------------------------------------------------------------- /public/fonts/3073CA_1_0.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/fonts/3073CA_1_0.eot -------------------------------------------------------------------------------- /public/fonts/3073CA_1_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/fonts/3073CA_1_0.ttf -------------------------------------------------------------------------------- /public/fonts/3073CA_1_0.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/fonts/3073CA_1_0.woff -------------------------------------------------------------------------------- /public/icons/curios/sack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/sack.png -------------------------------------------------------------------------------- /public/fonts/3073CA_0_0.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/fonts/3073CA_0_0.woff2 -------------------------------------------------------------------------------- /public/fonts/3073CA_1_0.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/fonts/3073CA_1_0.woff2 -------------------------------------------------------------------------------- /public/icons/curios/crate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/crate.png -------------------------------------------------------------------------------- /public/icons/curios/sconce.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/sconce.png -------------------------------------------------------------------------------- /public/icons/curios/bookshelf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/bookshelf.png -------------------------------------------------------------------------------- /public/icons/curios/fish_idol.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/fish_idol.png -------------------------------------------------------------------------------- /public/icons/curios/old_tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/old_tree.png -------------------------------------------------------------------------------- /public/icons/provisions/Food.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/provisions/Food.gif -------------------------------------------------------------------------------- /public/icons/provisions/Food.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/provisions/Food.png -------------------------------------------------------------------------------- /public/icons/provisions/Torch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/provisions/Torch.png -------------------------------------------------------------------------------- /public/provisions_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/provisions_background.png -------------------------------------------------------------------------------- /public/icons/curios/bas_relief.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/bas_relief.png -------------------------------------------------------------------------------- /public/icons/curios/bone_altar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/bone_altar.png -------------------------------------------------------------------------------- /public/icons/curios/dinner_cart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/dinner_cart.png -------------------------------------------------------------------------------- /public/icons/curios/eerie_coral.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/eerie_coral.png -------------------------------------------------------------------------------- /public/icons/curios/iron_maiden.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/iron_maiden.png -------------------------------------------------------------------------------- /public/icons/curios/sarcophagus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/sarcophagus.png -------------------------------------------------------------------------------- /public/icons/provisions/Bandage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/provisions/Bandage.png -------------------------------------------------------------------------------- /public/icons/provisions/Food_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/provisions/Food_0.png -------------------------------------------------------------------------------- /public/icons/provisions/Food_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/provisions/Food_1.png -------------------------------------------------------------------------------- /public/icons/provisions/Food_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/provisions/Food_2.png -------------------------------------------------------------------------------- /public/icons/provisions/Food_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/provisions/Food_3.png -------------------------------------------------------------------------------- /public/icons/provisions/Shovel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/provisions/Shovel.png -------------------------------------------------------------------------------- /public/icons/curios/alchemy_table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/alchemy_table.png -------------------------------------------------------------------------------- /public/icons/curios/altar_of_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/altar_of_light.png -------------------------------------------------------------------------------- /public/icons/curios/ancient_coffin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/ancient_coffin.png -------------------------------------------------------------------------------- /public/icons/curios/beast_carcass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/beast_carcass.png -------------------------------------------------------------------------------- /public/icons/curios/decorative_urn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/decorative_urn.png -------------------------------------------------------------------------------- /public/icons/curios/discarded_pack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/discarded_pack.png -------------------------------------------------------------------------------- /public/icons/curios/eldritch_alter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/eldritch_alter.png -------------------------------------------------------------------------------- /public/icons/curios/giant_oyster.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/giant_oyster.png -------------------------------------------------------------------------------- /public/icons/curios/heirloom_chest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/heirloom_chest.png -------------------------------------------------------------------------------- /public/icons/curios/holy_fountain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/holy_fountain.png -------------------------------------------------------------------------------- /public/icons/curios/left_luggage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/left_luggage.png -------------------------------------------------------------------------------- /public/icons/curios/pile_of_bones.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/pile_of_bones.png -------------------------------------------------------------------------------- /public/icons/curios/rack_of_blades.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/rack_of_blades.png -------------------------------------------------------------------------------- /public/icons/curios/shallow_grave.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/shallow_grave.png -------------------------------------------------------------------------------- /public/icons/curios/stack_of_books.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/stack_of_books.png -------------------------------------------------------------------------------- /public/icons/curios/suit_of_armor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/suit_of_armor.png -------------------------------------------------------------------------------- /public/icons/curios/travelers_tent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/travelers_tent.png -------------------------------------------------------------------------------- /public/icons/provisions/Antivenom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/provisions/Antivenom.png -------------------------------------------------------------------------------- /public/icons/provisions/Dog_Treats.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/provisions/Dog_Treats.png -------------------------------------------------------------------------------- /public/icons/provisions/Firewood.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/provisions/Firewood.png -------------------------------------------------------------------------------- /public/icons/provisions/Holy_Water.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/provisions/Holy_Water.png -------------------------------------------------------------------------------- /public/icons/curios/ancient_artifact.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/ancient_artifact.png -------------------------------------------------------------------------------- /public/icons/curios/confession_booth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/confession_booth.png -------------------------------------------------------------------------------- /public/icons/curios/eerie_spiderweb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/eerie_spiderweb.png -------------------------------------------------------------------------------- /public/icons/curios/moonshine_barrel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/moonshine_barrel.png -------------------------------------------------------------------------------- /public/icons/curios/pile_of_scrolls.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/pile_of_scrolls.png -------------------------------------------------------------------------------- /public/icons/curios/shamblers_altar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/shamblers_altar.png -------------------------------------------------------------------------------- /public/icons/curios/ships_figurehead.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/ships_figurehead.png -------------------------------------------------------------------------------- /public/icons/curios/troubling_effigy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/troubling_effigy.png -------------------------------------------------------------------------------- /public/icons/provisions/Skeleton_Key.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/provisions/Skeleton_Key.png -------------------------------------------------------------------------------- /public/icons/curios/ancestors_knapsack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/ancestors_knapsack.png -------------------------------------------------------------------------------- /public/icons/curios/brackish_tidepool.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/brackish_tidepool.png -------------------------------------------------------------------------------- /public/icons/curios/giant_fish_carcass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/giant_fish_carcass.png -------------------------------------------------------------------------------- /public/icons/curios/locked_sarcophagus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/locked_sarcophagus.png -------------------------------------------------------------------------------- /public/icons/curios/mummified_remains.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/mummified_remains.png -------------------------------------------------------------------------------- /public/icons/curios/occult_scrawlings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/occult_scrawlings.png -------------------------------------------------------------------------------- /public/icons/curios/pristine_fountain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/pristine_fountain.png -------------------------------------------------------------------------------- /public/icons/curios/sacrificial_stone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/sacrificial_stone.png -------------------------------------------------------------------------------- /public/icons/curios/unlocked_strongbox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/unlocked_strongbox.png -------------------------------------------------------------------------------- /public/icons/provisions/Medicinal_Herbs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/provisions/Medicinal_Herbs.png -------------------------------------------------------------------------------- /public/icons/curios/bernacle_crusted_chest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/bernacle_crusted_chest.png -------------------------------------------------------------------------------- /public/icons/curios/locked_display_cabinet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/locked_display_cabinet.png -------------------------------------------------------------------------------- /public/icons/curios/makeshift_dining_table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnaudRinquin/darkest-companion/HEAD/public/icons/curios/makeshift_dining_table.png -------------------------------------------------------------------------------- /src/reducer.js: -------------------------------------------------------------------------------- 1 | import { combineReducers } from 'redux'; 2 | import mission from './ducks/mission'; 3 | 4 | export default combineReducers({ 5 | mission, 6 | }); 7 | -------------------------------------------------------------------------------- /src/store/index.js: -------------------------------------------------------------------------------- 1 | if (process.env.NODE_ENV === 'production') { 2 | module.exports = require('./prod'); 3 | } else { 4 | module.exports = require('./dev'); 5 | } 6 | -------------------------------------------------------------------------------- /src/views/root/index.js: -------------------------------------------------------------------------------- 1 | if (process.env.NODE_ENV === 'production') { 2 | module.exports = require('./prod'); 3 | } else { 4 | module.exports = require('./dev'); 5 | } 6 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render } from 'react-dom'; 3 | import Root from './views/root'; 4 | import store from './store'; 5 | 6 | render(, document.getElementById('app-root')); 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Darkest Companion 2 | 3 | A [Darkest Dungeon](http://www.darkestdungeon.com/) curios and provisions helper 4 | 5 | ![screenshots](./screenshots.png) 6 | 7 | # Build and run 8 | 9 | ```bash 10 | npm install && npm run build 11 | ``` 12 | 13 | In dev mode 14 | 15 | ```bash 16 | npm run dev 17 | ``` 18 | -------------------------------------------------------------------------------- /src/components/capitalize.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export function capitalize(text) { 4 | const [firstLetter, ...rest] = text; 5 | return `${firstLetter.toUpperCase()}${rest.join('')}`; 6 | } 7 | 8 | export default function Capitalize({text}) { 9 | return {capitalize(text)} 10 | } 11 | -------------------------------------------------------------------------------- /src/components/devtools.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createDevTools } from 'redux-devtools'; 3 | import LogMonitor from 'redux-devtools-log-monitor'; 4 | import DockMonitor from 'redux-devtools-dock-monitor'; 5 | 6 | export default createDevTools( 7 | 8 | 9 | 10 | ); 11 | -------------------------------------------------------------------------------- /src/views/root/prod.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { Provider } from 'react-redux'; 3 | import App from '../app'; 4 | import store from '../../store'; 5 | 6 | export default class Root extends Component { 7 | render() { 8 | const { store } = this.props; 9 | return ( 10 | 11 | 12 | 13 | ); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/views/root/dev.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { Provider } from 'react-redux'; 3 | import App from '../app'; 4 | import DevTools from '../../components/devtools'; 5 | 6 | export default class Root extends Component { 7 | render() { 8 | const { store } = this.props; 9 | return ( 10 | 11 |
12 | 13 | 14 |
15 |
16 | ); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/store/prod.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | import { createStore, applyMiddleware, compose } from 'redux'; 3 | import { persistStore, autoRehydrate } from 'redux-persist' 4 | import thunk from 'redux-thunk'; 5 | import reducer from '../reducer'; 6 | 7 | export function createNewStore() { 8 | const store = createStore(reducer, compose( 9 | applyMiddleware(thunk), 10 | autoRehydrate() 11 | )); 12 | 13 | persistStore(store); 14 | 15 | return store; 16 | } 17 | 18 | export default createNewStore(); 19 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Darkest Companion 6 | 7 | 8 | 9 | 10 | 11 |
12 |
13 | 14 |
15 |
16 |
17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/views/lengthSelector.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { connect } from 'react-redux'; 3 | import { TorchRadioGroup } from '../components/torchRadioGroup'; 4 | import { LENGTHS, selectLength, getSelectedLength } from '../ducks/mission'; 5 | 6 | export function LengthSelector({selectedLength, selectLength}) { 7 | return
8 |

Length

9 | 10 |
11 | } 12 | 13 | export default connect(getSelectedLength, { selectLength })(LengthSelector); 14 | -------------------------------------------------------------------------------- /src/views/locationSelector.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { connect } from 'react-redux'; 3 | import { TorchRadioGroup } from '../components/torchRadioGroup'; 4 | import { LOCATIONS, selectLocation, getSelectedLocation } from '../ducks/mission'; 5 | 6 | export function LocationSelector({selectedLocation, selectLocation}) { 7 | return
8 |

Location

9 | 10 |
11 | } 12 | 13 | export default connect(getSelectedLocation, { selectLocation })(LocationSelector); 14 | -------------------------------------------------------------------------------- /src/store/dev.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | import { createStore, applyMiddleware, compose } from 'redux'; 3 | import { persistStore, autoRehydrate } from 'redux-persist'; 4 | import thunk from 'redux-thunk'; 5 | import reducer from '../reducer'; 6 | import devtools from '../components/devtools'; 7 | 8 | export function createNewStore(initialState) { 9 | const store = createStore( 10 | reducer, 11 | compose( 12 | applyMiddleware(thunk), 13 | autoRehydrate(), 14 | devtools.instrument() 15 | ) 16 | ) 17 | 18 | if (module.hot) { 19 | module.hot.accept('../reducer', () => 20 | store.replaceReducer(require('../reducer')).default 21 | ); 22 | } 23 | 24 | persistStore(store); 25 | 26 | return store; 27 | }; 28 | 29 | export default createNewStore(); 30 | -------------------------------------------------------------------------------- /src/components/torchRadioGroup.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import RadioGroup from 'react-radio-group'; 3 | import Capitalize from '../components/capitalize'; 4 | 5 | const renderOption = (Radio, option) => { 6 | return 13 | } 14 | 15 | const renderOptions = (options) => (Radio) => { 16 | return
{options.map(renderOption.bind(null, Radio))}
17 | } 18 | 19 | export function TorchRadioGroup({selectedValue, onChange, name, options}) { 20 | return
21 | 22 | {renderOptions(options)} 23 | 24 |
25 | } 26 | -------------------------------------------------------------------------------- /src/views/app.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import LocationSelector from './locationSelector'; 3 | import LengthSelector from './lengthSelector'; 4 | import MissionProvisions from './missionProvisions'; 5 | import LocationCurios from './locationCurios'; 6 | import LocationTips from './locationTips'; 7 | 8 | export default function App() { 9 | return
10 |
11 |
12 | 13 | 14 |
15 | 16 | 17 |
18 | 19 |
20 | Game content, images and materials are trademarks and copyrights of Red Hook Studios, creators of the (awesome) Darkest Dungeon game. 21 |
22 |
23 | } 24 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | var webpack = require('webpack'); 2 | var path = require('path'); 3 | 4 | module.exports = { 5 | entry: [ 6 | './src/index.js' 7 | ], 8 | devtool: process.env.WEBPACK_DEVTOOL || 'source-map', 9 | output: { 10 | path: path.join(__dirname, 'public'), 11 | filename: 'bundle.js' 12 | }, 13 | resolve: { 14 | extensions: ['', '.js', '.jsx'] 15 | }, 16 | module: { 17 | loaders: [ 18 | { 19 | test: /\.jsx?$/, 20 | exclude: /(node_modules|bower_components)/, 21 | loaders: process.env.NODE_ENV !== 'production' ? ['react-hot', 'babel'] : ['babel'], 22 | } 23 | ] 24 | }, 25 | devServer: { 26 | contentBase: "./public", 27 | noInfo: true, 28 | hot: true, 29 | inline: true 30 | }, 31 | plugins: [ 32 | new webpack.NoErrorsPlugin(), 33 | new webpack.DefinePlugin({ 34 | 'process.env': { 35 | 'NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'dev') 36 | } 37 | }) 38 | ] 39 | }; 40 | 41 | if (process.env.NODE_ENV !== 'production') { 42 | module.exports.entry.push('webpack-dev-server/client?http://0.0.0.0:8080'); 43 | module.exports.entry.push('webpack/hot/only-dev-server'); 44 | } 45 | -------------------------------------------------------------------------------- /src/views/locationTips.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { connect } from 'react-redux'; 3 | import { getSelectedLocation } from '../ducks/mission'; 4 | import { getTipsForLocation } from '../data/tips'; 5 | import Capitalize from '../components/capitalize'; 6 | 7 | function renderTip(tip, index) { 8 | return
9 |
{tip.label}
10 |
{tip.details}
11 |
12 | } 13 | 14 | function renderTipsCategory(category, tips) { 15 | if (!tips.length) { 16 | return null; 17 | } 18 | return
19 |
20 |
21 | 22 |
23 |
24 | {tips.map(renderTip)} 25 |
26 |
27 |
28 | } 29 | 30 | const tipCategories = ['effective', 'ineffective', 'dangers']; 31 | 32 | export function LocationTips({selectedLocation}) { 33 | const tips = getTipsForLocation(selectedLocation); 34 | 35 | return
36 |

Tips

37 |
38 | {tipCategories.map(category => renderTipsCategory(category, tips[category]))} 39 |
40 |
41 | } 42 | 43 | export default connect(getSelectedLocation)(LocationTips); 44 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "darkest-companion", 3 | "version": "0.0.0", 4 | "description": "Darkest Dungeon curios and provisions companion", 5 | "main": "index.js", 6 | "dependencies": { 7 | "react": "^0.14.7", 8 | "react-dom": "^0.14.7", 9 | "react-radio-group": "^2.2.0", 10 | "react-redux": "^4.4.0", 11 | "redux": "^3.3.1", 12 | "redux-persist": "^1.5.6", 13 | "redux-thunk": "^1.0.3", 14 | "reselect": "^2.0.3" 15 | }, 16 | "devDependencies": { 17 | "babel-core": "^6.5.2", 18 | "babel-loader": "^6.2.3", 19 | "babel-plugin-transform-object-rest-spread": "^6.5.0", 20 | "babel-preset-es2015": "^6.5.0", 21 | "babel-preset-react": "^6.5.0", 22 | "react-hot-loader": "^1.3.0", 23 | "redux-devtools": "^3.1.1", 24 | "redux-devtools-dock-monitor": "^1.1.0", 25 | "redux-devtools-log-monitor": "^1.0.4", 26 | "webpack": "^1.12.13", 27 | "webpack-dev-server": "^1.14.1" 28 | }, 29 | "scripts": { 30 | "build": "NODE_ENV=production webpack --progress --profile --colors", 31 | "dev": "webpack-dev-server --progress --profile --colors --hot", 32 | "prepublish": "git branch -D gh-pages && git checkout -b gh-pages", 33 | "publish": "npm run build && cp -r public/* ./ && git add . && git commit -m 'Publish github pages'", 34 | "postpublish": "git push -f origin gh-pages && git checkout master" 35 | }, 36 | "repository": { 37 | "type": "git", 38 | "url": "git+https://github.com/arnaudrinquin/darkest-companion.git" 39 | }, 40 | "keywords": [ 41 | "darkest-dungeon" 42 | ], 43 | "author": "Arnaud Rinquin", 44 | "license": "MIT", 45 | "bugs": { 46 | "url": "https://github.com/arnaudrinquin/darkest-companion/issues" 47 | }, 48 | "homepage": "https://github.com/arnaudrinquin/darkest-companion#readme" 49 | } 50 | -------------------------------------------------------------------------------- /src/ducks/mission.js: -------------------------------------------------------------------------------- 1 | import { selector } from '.'; 2 | import { createSelector } from 'reselect' 3 | 4 | export function selectLocation(location) { 5 | return { 6 | type: 'SELECT_LOCATION', 7 | payload: location, 8 | } 9 | } 10 | 11 | export function selectLength(length) { 12 | return { 13 | type: 'SELECT_LENGTH', 14 | payload: length, 15 | } 16 | } 17 | 18 | export const LOCATIONS = [ 19 | 'ruins', 20 | 'warrens', 21 | 'weald', 22 | 'cove', 23 | ]; 24 | 25 | export const LENGTHS = [ 26 | 'short', 27 | 'medium', 28 | 'long' 29 | ]; 30 | 31 | const initialState = { 32 | selectedLocation: LOCATIONS[0], 33 | selectedLength: LENGTHS[0], 34 | }; 35 | 36 | export default function missionReducer(state = initialState, { type, payload }) { 37 | switch (type) { 38 | case 'SELECT_LOCATION': 39 | if (LOCATIONS.indexOf(payload) === -1) { 40 | throw new Error(`Invalid location selected: ${payload}`); 41 | } 42 | 43 | return { 44 | ...state, 45 | selectedLocation: payload, 46 | }; 47 | case 'SELECT_LENGTH': 48 | if (LENGTHS.indexOf(payload) === -1) { 49 | throw new Error(`Invalid length selected: ${payload}`); 50 | } 51 | 52 | return { 53 | ...state, 54 | selectedLength: payload, 55 | }; 56 | default: 57 | return state; 58 | } 59 | } 60 | 61 | export const getMission = createSelector( 62 | selector, 63 | ({mission}) => mission 64 | ) 65 | 66 | export const getSelectedLocation = createSelector( 67 | getMission, 68 | ({selectedLocation}) => ({ selectedLocation }) 69 | ) 70 | 71 | export const getSelectedLength = createSelector( 72 | getMission, 73 | ({selectedLength}) => ({ selectedLength }) 74 | ) 75 | 76 | export const getSelectedLocationAndLength = createSelector( 77 | getSelectedLocation, 78 | getSelectedLength, 79 | ({selectedLocation}, {selectedLength}) => ({selectedLocation, selectedLength}) 80 | ) 81 | -------------------------------------------------------------------------------- /src/views/locationCurios.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { connect } from 'react-redux'; 3 | import { getSelectedLocation } from '../ducks/mission'; 4 | import { getCuriosForLocation } from '../data/curios'; 5 | 6 | function renderOutcome(outcome, index) { 7 | let amount; 8 | let chances; 9 | if (outcome.amount) { 10 | amount =  x{outcome.amount} 11 | } 12 | 13 | if (outcome.chances !== 100) { 14 | chances = {outcome.chances}% 15 | } 16 | 17 | 18 | return
19 | {chances} 20 | {outcome.type.label} 21 | {amount} 22 |
23 | } 24 | 25 | function renderCurioOption(option, index) { 26 | return
27 |
28 |
29 | {option.activator.label} 30 |
31 |
32 | {option.outcomes.map(renderOutcome)} 33 |
34 |
35 |
36 | } 37 | 38 | function renderCurio(curio, index) { 39 | 40 | let icon; 41 | 42 | if (curio.icon) { 43 | icon = {curio.label}/ 44 | } 45 | 46 | return
47 |
48 |
{curio.name}
49 | {icon} 50 | {/*
{curio.description}
*/} 51 |
52 | {curio.options.map(renderCurioOption)} 53 |
54 | } 55 | 56 | export function LocationCurios({selectedLocation}) { 57 | const curios = getCuriosForLocation(selectedLocation); 58 | 59 | return
60 |

Curios

61 | {curios.map(renderCurio)} 62 |
63 | } 64 | 65 | export default connect(getSelectedLocation)(LocationCurios); 66 | -------------------------------------------------------------------------------- /src/views/missionProvisions.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { connect } from 'react-redux'; 3 | import { getSelectedLocationAndLength } from '../ducks/mission'; 4 | import { getMissionProvisions } from '../data/provisions'; 5 | 6 | const types = [ 7 | 'firewood', 8 | 'food', 9 | 'shovels', 10 | 'antivenoms', 11 | 'bandages', 12 | 'herbs', 13 | 'keys', 14 | 'holyWaters', 15 | 'torches', 16 | ]; 17 | 18 | function stacks(quantity, stackSize) { 19 | const stacks = []; 20 | const rest = quantity % stackSize; 21 | for(let i = stackSize ; i < quantity ; i += stackSize) { 22 | stacks.push(stackSize); 23 | } 24 | if (rest) { 25 | stacks.push(rest); 26 | } else { 27 | stacks.push(stackSize); 28 | } 29 | return stacks; 30 | } 31 | 32 | function renderProvisionStack(provision, quantity, index) { 33 | return
34 | {provision.label}/ 35 |
{quantity > 1 ? quantity : ''}
36 |
37 | } 38 | 39 | function renderProvisionStacks(provision) { 40 | return stacks(provision.quantity, provision.stack) 41 | .map(renderProvisionStack.bind(null, provision)); 42 | } 43 | 44 | export function MissionProvisions({selectedLocation, selectedLength}) { 45 | const provisions = getMissionProvisions(selectedLocation, selectedLength); 46 | 47 | return
48 |

Provisions

49 |
50 | {types.reduce((rendered, type) => { 51 | 52 | const provision = provisions[type]; 53 | 54 | if (!provision.quantity) return rendered; 55 | 56 | return [ 57 | ...rendered, 58 | ...renderProvisionStacks(provision), 59 | ] 60 | }, [])} 61 |
62 |
63 | Total Cost: 64 |   65 | 66 |   67 | {provisions.totalCost.toLocaleString()} 68 |
69 |
70 | } 71 | 72 | export default connect(getSelectedLocationAndLength)(MissionProvisions); 73 | -------------------------------------------------------------------------------- /src/data/tips.js: -------------------------------------------------------------------------------- 1 | const tips = { 2 | ruins: { 3 | effective: [ 4 | { 5 | label: 'Blight', 6 | details: 'low resist', 7 | }, 8 | { 9 | label: 'Crusader', 10 | details: 'extra DMG vs. Unholy', 11 | }, 12 | { 13 | label: 'Direct damage', 14 | details: 'Few high PROT enemies', 15 | }, 16 | ], 17 | ineffective: [ 18 | { 19 | label: 'Bleeds', 20 | details: 'high resist', 21 | }, 22 | ], 23 | dangers: [ 24 | { 25 | label: 'Bone spearman', 26 | details: 'at low ranks', 27 | }, 28 | { 29 | label: 'Stress dealers', 30 | details: 'Bone Courtier, Cultist Acolyte and Madman', 31 | }, 32 | { 33 | label: 'Books and bookshelves', 34 | details: 'High risk of bad outcome', 35 | }, 36 | ] 37 | }, 38 | warrens: { 39 | effective: [ 40 | { 41 | label: 'Bleed', 42 | details: 'low resist', 43 | }, 44 | { 45 | label: 'Houndmaster', 46 | details: 'extra DMG vs. Beast', 47 | }, 48 | { 49 | label: 'Scouting', 50 | details: 'Specific map layouts', 51 | }, 52 | ], 53 | ineffective: [ 54 | { 55 | label: 'Blight', 56 | details: 'high resist', 57 | }, 58 | ], 59 | dangers: [ 60 | { 61 | label: 'Swinetaur', 62 | details: 'especially in the back rows', 63 | }, 64 | { 65 | label: 'Swine chopper', 66 | details: 'High bleed, hard to kill', 67 | } 68 | ] 69 | }, 70 | weald: { 71 | effective: [ 72 | { 73 | label: 'Bandages', 74 | details: 'Many curios + enemies inflicting bleeds', 75 | }, 76 | { 77 | label: 'Antivenom', 78 | details: 'Many curios + enemies inflicting blights', 79 | }, 80 | { 81 | label: 'Shovels', 82 | details: 'More walls', 83 | }, 84 | { 85 | label: 'Holy waters', 86 | details: 'Curios affecting quirks and stress positively', 87 | }, 88 | ], 89 | ineffective: [], 90 | dangers: [ 91 | { 92 | label: 'Crone', 93 | details: 'in the front rows', 94 | }, 95 | { 96 | label: 'Ectoplasm', 97 | details: 'can summon others', 98 | }, 99 | { 100 | label: 'Rabid Gnasher', 101 | details: 'Fast + deals bleeds and diseases', 102 | }, 103 | ] 104 | }, 105 | cove: { 106 | effective: [ 107 | { 108 | label: 'Medicinal herbs', 109 | details: 'Curio, traps, debuff interactions', 110 | }, 111 | { 112 | label: 'Shovels', 113 | details: 'Curio interactions', 114 | }, 115 | { 116 | label: 'Bandages', 117 | details: 'Many bleed dealing enemies', 118 | }, 119 | { 120 | label: 'Blight', 121 | details: 'Low blight resistance + high PROT', 122 | }, 123 | { 124 | label: 'Prot debuff', 125 | details: 'Ennemies with high PROT', 126 | }, 127 | { 128 | label: 'Occultist', 129 | details: 'Ennemies mostly Eldritch', 130 | }, 131 | ], 132 | ineffective: [ 133 | { 134 | label: 'Bleed', 135 | details: 'High bleed resistance', 136 | } 137 | ], 138 | dangers: [ 139 | { 140 | label: 'Pelagic Groupers', 141 | details: 'Deals lot of damages', 142 | }, 143 | { 144 | label: 'Thrall', 145 | details: 'Explodes and deals a lot of damages if left alive', 146 | }, 147 | ] 148 | }, 149 | } 150 | 151 | export function getTipsForLocation(location) { 152 | return tips[location]; 153 | } 154 | -------------------------------------------------------------------------------- /public/style.css: -------------------------------------------------------------------------------- 1 | @font-face {font-family: 'DwarvenAxeBB';src: url('./fonts/3073CA_0_0.eot');src: url('./fonts/3073CA_0_0.eot?#iefix') format('embedded-opentype'),url('./fonts/3073CA_0_0.woff2') format('woff2'),url('./fonts/3073CA_0_0.woff') format('woff'),url('./fonts/3073CA_0_0.ttf') format('truetype');} 2 | @font-face {font-family: 'DwarvenAxeBB-Italic';src: url('./fonts/3073CA_1_0.eot');src: url('./fonts/3073CA_1_0.eot?#iefix') format('embedded-opentype'),url('./fonts/3073CA_1_0.woff2') format('woff2'),url('./fonts/3073CA_1_0.woff') format('woff'),url('./fonts/3073CA_1_0.ttf') format('truetype');} 3 | 4 | /* 5 | 6 | grey: #5D5A50 7 | yellow: #C9B569 8 | */ 9 | 10 | body { 11 | background: #2F2F2F; 12 | color: #A0A0A0; 13 | font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; 14 | padding: 5px; 15 | cursor: url(./cursor.png), auto; 16 | } 17 | 18 | h1 { 19 | color: #C9B569; 20 | font-size: 30px; 21 | font-family: 'DwarvenAxeBB'; 22 | font-weight: normal; 23 | padding: 0; 24 | margin: 10px 0 5px 0; 25 | } 26 | 27 | .location-selector, .length-selector, .level-provisions { 28 | width: 320px; /* = 8 * 40 */ 29 | margin-bottom: 20px; 30 | } 31 | 32 | .torch-radio-group > div { 33 | display: flex; 34 | justify-content: space-around; 35 | } 36 | 37 | .torch-radio { 38 | flex: 0 1 auto; 39 | cursor: url(./cursor_link.png), auto; 40 | } 41 | 42 | .torch-radio > input { 43 | visibility: hidden; 44 | position: absolute; 45 | } 46 | 47 | .torch-radio > .torch-radio-icon { 48 | display: inline-block; 49 | vertical-align: middle; 50 | width: 38px; 51 | height: 56px; 52 | text-align: center; 53 | background: url('./checkbox_sprite.png') no-repeat -38px 0; 54 | } 55 | 56 | .torch-radio > input:checked + .torch-radio-icon { 57 | background-position : 0 0; 58 | } 59 | 60 | .torch-radio > input:checked ~ .torch-radio-label { 61 | color: #C9B569; 62 | } 63 | 64 | .copyrights { 65 | text-align: center; 66 | font-size: 12px; 67 | } 68 | 69 | .copyrights a:visited, .copyrights a { 70 | color: #C9B569; 71 | cursor: url(./cursor_link.png), auto; 72 | } 73 | 74 | .provisions-list { 75 | display: flex; 76 | flex-wrap: wrap; 77 | width: 320px; 78 | height: 160px; 79 | background: url('./provisions_background.png') no-repeat 0 0; 80 | } 81 | 82 | .provision-item { 83 | position: relative; 84 | height: 80px; 85 | } 86 | 87 | .provision-quantity { 88 | position: absolute; 89 | top: 4px; 90 | left: 6px; 91 | font-size: 18px; 92 | color: #C9B569; 93 | font-family: 'DwarvenAxeBB'; 94 | } 95 | 96 | .provision-icon { 97 | width: 40px; 98 | } 99 | 100 | .provisions-total { 101 | text-align: center; 102 | margin: 5px; 103 | font-family: 'DwarvenAxeBB'; 104 | font-size: 24px; 105 | } 106 | 107 | .provisions-total-label { 108 | color: #C9B569; 109 | } 110 | 111 | .selectorsAndProvisions { 112 | display: flex; 113 | flex-wrap: wrap; 114 | justify-content: space-around; 115 | } 116 | 117 | .centered { 118 | text-align: center; 119 | } 120 | 121 | #logo { 122 | max-width: 300px; 123 | } 124 | 125 | .curio { 126 | display: flex; 127 | flex-wrap: wrap; 128 | margin: 10px 0 30px 0; 129 | align-items: center; 130 | } 131 | 132 | .curio-cell { 133 | flex: 0 1 auto; 134 | width: 160px; 135 | margin: 5px 0; 136 | } 137 | 138 | .curio-activator { 139 | width: 40px; 140 | margin: 0 5px; 141 | } 142 | 143 | .curio-cell-container { 144 | display: flex; 145 | align-items: center; 146 | } 147 | 148 | .curio-cell-item { 149 | flex: 0 1 auto; 150 | } 151 | 152 | .curio-icon { 153 | max-width: 120px; 154 | } 155 | 156 | .curio-description { 157 | text-align: center; 158 | font-size: 18px; 159 | } 160 | 161 | .curio-name { 162 | color: #C9B569; 163 | margin-bottom: 10px; 164 | } 165 | .curio-with { 166 | color: #C9B569; 167 | } 168 | 169 | .curio-outcome { 170 | padding-left: 5px; 171 | padding-top: 5px; 172 | font-size: 14px; 173 | } 174 | 175 | .curio-outcome-chances { 176 | margin-right: 5px; 177 | } 178 | 179 | .location-tips { 180 | width: 500px; 181 | } 182 | 183 | .tips-category-list { 184 | display: flex; 185 | flex-wrap: wrap; 186 | justify-content: flex-start; 187 | } 188 | 189 | .tips-category-item { 190 | margin: 10px 5px; 191 | width: 150px; 192 | } 193 | 194 | .tips-category { 195 | font-size: 30px; 196 | font-family: 'DwarvenAxeBB'; 197 | } 198 | 199 | .tips-category-effective { 200 | color: green; 201 | } 202 | 203 | .tips-category-ineffective { 204 | color: orange; 205 | } 206 | 207 | .tips-category-dangers { 208 | color: red; 209 | } 210 | 211 | .tips-label { 212 | color: #C9B569; 213 | } 214 | 215 | .tips-list-item { 216 | margin: 8px 0; 217 | } 218 | 219 | .tips-details { 220 | padding-left: 5px; 221 | font-size: 12px; 222 | } 223 | -------------------------------------------------------------------------------- /src/data/provisions.js: -------------------------------------------------------------------------------- 1 | // Data from @damp 2 | // https://docs.google.com/spreadsheets/d/1e9VBtUO0tY2l58DSUb_JHnULDuAhziqnOCQH1VS4GtY/edit#gid=61256338 3 | const iconPath = `./icons/provisions/` 4 | 5 | const provisions = { 6 | firewood: { 7 | label: 'Firewood', 8 | icon: _ => `${iconPath}Firewood.png`, 9 | cost: 0, 10 | stack: 1, 11 | }, 12 | food: { 13 | label: 'Food', 14 | icon: quantity => { 15 | if (quantity < 6) { 16 | return `${iconPath}Food_1.png`; 17 | } else if (quantity < 12) { 18 | return `${iconPath}Food_2.png`; 19 | } else { 20 | return `${iconPath}Food_3.png`; 21 | } 22 | }, 23 | cost: 75, 24 | stack: 12, 25 | }, 26 | shovels: { 27 | label: 'Shovels', 28 | icon: _ => `${iconPath}Shovel.png`, 29 | cost: 250, 30 | stack: 4, 31 | }, 32 | antivenoms: { 33 | label: 'Antivenoms', 34 | icon: _ => `${iconPath}Antivenom.png`, 35 | cost: 150, 36 | stack: 6, 37 | }, 38 | bandages: { 39 | label: 'Bandages', 40 | icon: _ => `${iconPath}Bandage.png`, 41 | cost: 150, 42 | stack: 6, 43 | }, 44 | herbs: { 45 | label: 'Medicinal Herbs', 46 | icon: _ => `${iconPath}Medicinal_Herbs.png`, 47 | cost: 200, 48 | stack: 6, 49 | }, 50 | keys: { 51 | label: 'Skeleton Keys', 52 | icon: _ => `${iconPath}Skeleton_Key.png`, 53 | cost: 200, 54 | stack: 6, 55 | }, 56 | holyWaters: { 57 | label: 'Holy Waters', 58 | icon: _ => `${iconPath}Holy_Water.png`, 59 | cost: 150, 60 | stack: 6, 61 | }, 62 | torches: { 63 | label: 'Torches', 64 | icon: _ => `${iconPath}Torch.png`, 65 | cost: 75, 66 | stack: 8, 67 | }, 68 | } 69 | 70 | const baseProvisions = { 71 | short: { 72 | firewood: 0, 73 | food: 12, 74 | torches: 8, 75 | shovels: 2 76 | }, 77 | medium: { 78 | firewood: 1, 79 | food: 18, 80 | torches: 13, 81 | shovels: 3 82 | }, 83 | long: { 84 | firewood: 2, 85 | food: 20, 86 | torches: 16, 87 | shovels: 4 88 | } 89 | } 90 | 91 | const DATA = { 92 | ruins: { 93 | short: { 94 | ...baseProvisions.short, 95 | herbs:1, 96 | holyWaters: 2, 97 | bandages: 1, 98 | antivenoms: 0, 99 | keys: 1, 100 | }, 101 | medium: { 102 | ...baseProvisions.medium, 103 | herbs: 2, 104 | holyWaters: 3, 105 | bandages: 2, 106 | antivenoms: 0, 107 | keys: 2, 108 | }, 109 | long: { 110 | ...baseProvisions.long, 111 | herbs: 3, 112 | holyWaters: 4, 113 | bandages: 3, 114 | antivenoms: 0, 115 | keys: 3, 116 | } 117 | }, 118 | warrens: { 119 | short: { 120 | ...baseProvisions.short, 121 | torches: 10, 122 | herbs:3, 123 | holyWaters: 2, 124 | bandages: 1, 125 | antivenoms: 0, 126 | keys: 2, 127 | }, 128 | medium: { 129 | ...baseProvisions.medium, 130 | torches: 16, 131 | herbs: 4, 132 | holyWaters: 3, 133 | bandages: 2, 134 | antivenoms: 1, 135 | keys: 3, 136 | }, 137 | long: { 138 | ...baseProvisions.long, 139 | torches: 20, 140 | herbs: 5, 141 | holyWaters: 4, 142 | bandages: 3, 143 | antivenoms: 1, 144 | keys: 3, 145 | } 146 | }, 147 | weald: { 148 | short: { 149 | ...baseProvisions.short, 150 | shovels: 3, 151 | herbs:1, 152 | holyWaters: 1, 153 | bandages: 2, 154 | antivenoms: 2, 155 | keys: 1, 156 | }, 157 | medium: { 158 | ...baseProvisions.medium, 159 | shovels: 5, 160 | herbs: 2, 161 | holyWaters: 2, 162 | bandages: 3, 163 | antivenoms: 3, 164 | keys: 2, 165 | }, 166 | long: { 167 | ...baseProvisions.long, 168 | shovels: 6, 169 | herbs: 2, 170 | holyWaters: 3, 171 | bandages: 4, 172 | antivenoms: 4, 173 | keys: 2, 174 | } 175 | }, 176 | cove: { 177 | short: { 178 | ...baseProvisions.short, 179 | shovels: 3, 180 | herbs:2, 181 | holyWaters: 0, 182 | bandages: 2, 183 | antivenoms: 0, 184 | keys: 1, 185 | }, 186 | medium: { 187 | ...baseProvisions.medium, 188 | shovels: 5, 189 | herbs: 3, 190 | holyWaters: 1, 191 | bandages: 4, 192 | antivenoms: 0, 193 | keys: 2, 194 | }, 195 | long: { 196 | ...baseProvisions.long, 197 | shovels: 6, 198 | herbs: 4, 199 | holyWaters: 1, 200 | bandages: 6, 201 | antivenoms: 0, 202 | keys: 3, 203 | } 204 | }, 205 | } 206 | 207 | export function getMissionProvisions(location, length) { 208 | const quantities = DATA[location][length]; 209 | return Object.keys(quantities).reduce((result, type) => { 210 | const quantity = quantities[type]; 211 | const subCost = provisions[type].cost * quantity; 212 | return { 213 | ...result, 214 | totalCost: result.totalCost + subCost, 215 | [type]: { 216 | quantity, 217 | ...provisions[type], 218 | subCost, 219 | } 220 | }; 221 | }, { totalCost: 0 }); 222 | } 223 | -------------------------------------------------------------------------------- /src/data/curios.js: -------------------------------------------------------------------------------- 1 | 2 | function concatBuffEffects(effects = []) { 3 | return effects.map(function effectToString({type, amount, percent}){ 4 | return `${amount}${percent ? '%' : ''} ${type}`; 5 | }).join(', '); 6 | } 7 | 8 | const outcomeTypes = { 9 | nothing: { 10 | label: 'Nothing', 11 | }, 12 | scouting: { 13 | label: 'Scouting', 14 | }, 15 | torch: { 16 | label: 'Torch', 17 | }, 18 | heirlooms: { 19 | label: 'Heirlooms', 20 | }, 21 | anyLoot: { 22 | label: 'Any loot', 23 | }, 24 | food: { 25 | label: 'Food', 26 | }, 27 | gainPositiveQuirk(type = 'random') { 28 | return { 29 | label: `Gain ${type} positive quirk`, 30 | } 31 | }, 32 | gainNegativeQuirk(type = 'random') { 33 | return { 34 | label: `Gain ${type} negative quirk`, 35 | } 36 | }, 37 | purgeNegativeQuirk: { 38 | label: 'Purge a negative quirk', 39 | }, 40 | negativeQuirkOrDisease: { 41 | label: 'Gain a negative quirk or disease', 42 | }, 43 | goldGemsSupplies: { 44 | label: 'Gold, gems or supplies', 45 | }, 46 | goldGemsHeirlooms: { 47 | label: 'Gold, gems or heirlooms', 48 | }, 49 | goldHeirlooms: { 50 | label: 'Gold or heirlooms', 51 | }, 52 | goldSuppliesHeirlooms: { 53 | label: 'Gold, supplies or heirloooms', 54 | }, 55 | goldGems: { 56 | label: 'Gold or gems', 57 | }, 58 | goldTrinket: { 59 | label: 'Gold or trinket', 60 | }, 61 | goldFoodTrinket: { 62 | label: 'Gold, food or trinket', 63 | }, 64 | goldFoodSupply: { 65 | label: 'Gold, food or supplies', 66 | }, 67 | goldGemsTrinket: { 68 | label: 'Gold, gems or trinket', 69 | }, 70 | goldGemsFood: { 71 | label: 'Gold, gems or food', 72 | }, 73 | gemsHerlooms: { 74 | label: 'Gems or herlooms', 75 | }, 76 | goldGemsHeirloomsSupplies: { 77 | label: 'Gold, gems, heirlooms or supplies', 78 | }, 79 | specialTrinketOrPuzzlingTrapezohdron: { 80 | label: 'Special trinket or Puzzling Trapezohedron', 81 | }, 82 | addStress(amount) { 83 | return { 84 | label: `Stress +${amount}`, 85 | } 86 | }, 87 | removeStress(amount) { 88 | return { 89 | label: `Stress heal ${amount}`, 90 | } 91 | }, 92 | setLight(to) { 93 | return { 94 | label: `Set light to ${to}`, 95 | } 96 | }, 97 | decreaseLight(by) { 98 | return { 99 | label: `Decrease light by ${by}` 100 | } 101 | }, 102 | bleed: { 103 | label: 'Bleed', 104 | }, 105 | blight: { 106 | label: 'Blight', 107 | }, 108 | buff(effects, untilCamp) { 109 | return { 110 | label: `Buff ${concatBuffEffects(effects)}${untilCamp ? ' until camp' : ''}`, 111 | } 112 | }, 113 | debuff(effects, untilCamp) { 114 | return { 115 | label: `Debuff ${concatBuffEffects(effects)}${untilCamp ? ' until camp' : ''}`, 116 | } 117 | }, 118 | disease(diseaseName = 'random') { 119 | return { 120 | label: `${diseaseName} disease`, 121 | } 122 | }, 123 | healStressEffectAndHP(stressHeal, hpHeal) { 124 | return { 125 | label: `Heal ${stressHeal} stress, cure status effect, heal ${hpHeal} HP` 126 | } 127 | }, 128 | summonShambler: { 129 | label: 'Summon Shambler', 130 | }, 131 | buffDMGAndAccAndCRTAndCureStatusEffect(dmg, acc, crt) { 132 | return { 133 | label: `Buff +${dmg}% DMG, +${acc} ACC, +${crt}% CRT, Cure Status Effects`, 134 | } 135 | } 136 | } 137 | 138 | const provisionsIconPath = './icons/provisions/' 139 | const activators = { 140 | nothing: { 141 | label: 'Nothing', 142 | icon: './icons/redCross.png', 143 | }, 144 | antivenom: { 145 | label: 'Antivenom', 146 | icon: `${provisionsIconPath}/Antivenom.png`, 147 | }, 148 | bandage: { 149 | label: 'Bandage', 150 | icon: `${provisionsIconPath}/Bandage.png`, 151 | }, 152 | dogTreats: { 153 | label: 'Dog Treats', 154 | icon: `${provisionsIconPath}/Dog_Treats.png`, 155 | }, 156 | holyWater: { 157 | label: 'Holy Water', 158 | icon: `${provisionsIconPath}/Holy_Water.png`, 159 | }, 160 | medicinalHerb: { 161 | label: 'Medicinal Herb', 162 | icon: `${provisionsIconPath}/Medicinal_Herbs.png`, 163 | }, 164 | shovel: { 165 | label: 'Shovel', 166 | icon: `${provisionsIconPath}/Shovel.png`, 167 | }, 168 | skeletonKey: { 169 | label: 'Skeleton Key', 170 | icon: `${provisionsIconPath}/Skeleton_Key.png`, 171 | }, 172 | torch: { 173 | label: 'Torch', 174 | icon: `${provisionsIconPath}/Torch.png`, 175 | }, 176 | } 177 | 178 | const iconPath = './icons/curios/'; 179 | 180 | const universalCurios = [ 181 | { 182 | name: 'Ancient Artifact', 183 | icon: `${iconPath}ancient_artifact.png`, 184 | options: [ 185 | { 186 | activator: activators.nothing, 187 | outcomes: [ 188 | { 189 | chances: 100, 190 | type: outcomeTypes.goldGems, 191 | amount: 2.5, 192 | }, 193 | ], 194 | }, 195 | { 196 | activator: activators.skeletonKey, 197 | outcomes: [ 198 | { 199 | chances: 100, 200 | type: outcomeTypes.specialTrinketOrPuzzlingTrapezohdron, 201 | amount: 3, 202 | }, 203 | ], 204 | }, 205 | ], 206 | }, 207 | { 208 | name: 'Crate', 209 | icon: `${iconPath}crate.png`, 210 | options: [ 211 | { 212 | activator: activators.nothing, 213 | outcomes: [ 214 | { 215 | chances: 75, 216 | type: outcomeTypes.heirlooms, 217 | }, 218 | { 219 | chances: 25, 220 | type: outcomeTypes.nothing, 221 | }, 222 | ], 223 | }, 224 | ], 225 | }, 226 | { 227 | name: 'Discarded Pack', 228 | icon: `${iconPath}discarded_pack.png`, 229 | options: [ 230 | { 231 | activator: activators.nothing, 232 | outcomes: [ 233 | { 234 | chances: 60, 235 | type: outcomeTypes.goldGemsSupplies, 236 | amount: 1.5, 237 | }, 238 | { 239 | chances: 20, 240 | type: outcomeTypes.scouting, 241 | }, 242 | { 243 | chances: 20, 244 | type: outcomeTypes.nothing, 245 | }, 246 | ], 247 | }, 248 | ], 249 | }, 250 | { 251 | name: 'Eldritch Altar', 252 | icon: `${iconPath}eldritch_alter.png`, 253 | description: 'A weird and unnatural statuette that appears to be an item of unholy worship.', 254 | options: [ 255 | { 256 | activator: activators.nothing, 257 | outcomes: [ 258 | { 259 | chances: 50, 260 | type: outcomeTypes.addStress(50) 261 | }, 262 | { 263 | chances: 33, 264 | type: outcomeTypes.gainPositiveQuirk(), 265 | }, 266 | { 267 | chances: 16, 268 | type: outcomeTypes.gainNegativeQuirk(), 269 | }, 270 | { 271 | chances: 16, 272 | type: outcomeTypes.nothing, 273 | }, 274 | ], 275 | }, 276 | { 277 | activator: activators.holyWater, 278 | outcomes: [ 279 | { 280 | chances: 100, 281 | type: outcomeTypes.purgeNegativeQuirk, 282 | }, 283 | ], 284 | }, 285 | ], 286 | }, 287 | { 288 | name: 'Heirloom Chest', 289 | icon: `${iconPath}heirloom_chest.png`, 290 | description: 'A chest with your family\'s sigil.', 291 | options: [ 292 | { 293 | activator: activators.nothing, 294 | outcomes: [ 295 | { 296 | chances: 75, 297 | type: outcomeTypes.goldGems, 298 | amount: 2, 299 | }, 300 | { 301 | chances: 12.5, 302 | type: outcomeTypes.bleed, 303 | }, 304 | { 305 | chances: 12.5, 306 | type: outcomeTypes.blight, 307 | }, 308 | ], 309 | }, 310 | { 311 | activator: activators.skeletonKey, 312 | outcomes: [ 313 | { 314 | chances: 100, 315 | type: outcomeTypes.heirlooms, 316 | amount: 3 317 | }, 318 | ], 319 | }, 320 | { 321 | activator: activators.antivenom, 322 | outcomes: [ 323 | { 324 | chances: 100, 325 | type: outcomeTypes.heirlooms, 326 | amount: 3 327 | }, 328 | ], 329 | }, 330 | ], 331 | }, 332 | { 333 | name: 'Sack', 334 | icon: `${iconPath}sack.png`, 335 | options: [ 336 | { 337 | activator: activators.nothing, 338 | outcomes: [ 339 | { 340 | chances: 75, 341 | type: outcomeTypes.goldGems, 342 | }, 343 | { 344 | chances: 25, 345 | type: outcomeTypes.nothing, 346 | }, 347 | ], 348 | }, 349 | ], 350 | }, 351 | { 352 | name: 'Sconce', 353 | icon: `${iconPath}sconce.png`, 354 | options: [ 355 | { 356 | activator: activators.nothing, 357 | outcomes: [ 358 | { 359 | chances: 100, 360 | type: outcomeTypes.torch, 361 | }, 362 | ], 363 | }, 364 | ], 365 | }, 366 | { 367 | name: 'Shambler\'s Altar', 368 | icon: `${iconPath}shamblers_altar.png`, 369 | description: 'It says: "The sacrifice of fire is the gate to ruin! Place a torch if you crave the void!"', 370 | options: [ 371 | { 372 | activator: activators.nothing, 373 | outcomes: [ 374 | { 375 | chances: 100, 376 | type: outcomeTypes.nothing, 377 | }, 378 | ], 379 | }, 380 | { 381 | activator: activators.torch, 382 | outcomes: [ 383 | { 384 | chances: 100, 385 | type: outcomeTypes.summonShambler, 386 | }, 387 | ], 388 | }, 389 | ], 390 | }, 391 | { 392 | name: 'Unlocked Strongbox', 393 | icon: `${iconPath}unlocked_strongbox.png`, 394 | description: 'A long-forgotten strongbox sits on the cold stone floor, its contents unknown.', 395 | options: [ 396 | { 397 | activator: activators.nothing, 398 | outcomes: [ 399 | { 400 | chances: 75, 401 | type: outcomeTypes.anyLoot, 402 | amount: 2, 403 | }, 404 | { 405 | chances: 25, 406 | type: outcomeTypes.blight, 407 | }, 408 | ], 409 | }, 410 | ], 411 | }, 412 | ]; 413 | 414 | const curiosPerLocation = { 415 | 'ruins': [ 416 | ...universalCurios, 417 | { 418 | name: 'Alchemy Table', 419 | icon: `${iconPath}alchemy_table.png`, 420 | description: 'A partially intact set of experimental equipment.', 421 | options: [ 422 | { 423 | activator: activators.nothing, 424 | outcomes: [ 425 | { 426 | chances: 50, 427 | type: outcomeTypes.blight, 428 | }, 429 | { 430 | chances: 25, 431 | type: outcomeTypes.goldGems 432 | }, 433 | { 434 | chances: 25, 435 | type: outcomeTypes.nothing 436 | }, 437 | ], 438 | }, 439 | { 440 | activator: activators.torch, 441 | outcomes: [ 442 | { 443 | chances: 100, 444 | type: outcomeTypes.setLight(100), 445 | }, 446 | ], 447 | }, 448 | { 449 | activator: activators.medicinalHerb, 450 | outcomes: [ 451 | { 452 | chances: 100, 453 | type: outcomeTypes.goldGems, 454 | amount: 2, 455 | }, 456 | ], 457 | }, 458 | ], 459 | }, 460 | { 461 | name: 'Altar of Light', 462 | icon: `${iconPath}altar_of_light.png`, 463 | description: 'A small holy altar seems out of place against the backdrop of corruption.', 464 | options: [ 465 | { 466 | activator: activators.nothing, 467 | outcomes: [ 468 | { 469 | chances: 100, 470 | type: outcomeTypes.buff([{ 471 | type: 'DMG', 472 | amount: 20, 473 | }], true), 474 | }, 475 | ], 476 | }, 477 | { 478 | activator: activators.holyWater, 479 | outcomes: [ 480 | { 481 | chances: 100, 482 | type: outcomeTypes.buff([{ 483 | type: 'DMG', 484 | amount: 30, 485 | }], true), 486 | }, 487 | ], 488 | }, 489 | ], 490 | }, 491 | { 492 | name: 'Bookshelf', 493 | icon: `${iconPath}bookshelf.png`, 494 | description: 'A bookshelf full of old, leather-bound books.', 495 | options: [ 496 | { 497 | activator: activators.nothing, 498 | outcomes: [ 499 | { 500 | chances: 25, 501 | type: outcomeTypes.scouting, 502 | }, 503 | { 504 | chances: 25, 505 | type: outcomeTypes.addStress(50), 506 | }, 507 | { 508 | chances: 16, 509 | type: outcomeTypes.gainPositiveQuirk(), 510 | }, 511 | { 512 | chances: 8, 513 | type: outcomeTypes.negativeQuirkOrDisease, 514 | }, 515 | { 516 | chances: 25, 517 | type: outcomeTypes.nothing, 518 | } 519 | ] 520 | } 521 | ] 522 | }, 523 | { 524 | name: 'Confession Booth', 525 | icon: `${iconPath}confession_booth.png`, 526 | description: 'A forsaken confession booth. It hasn\'t been used in years.', 527 | options: [ 528 | { 529 | activator: activators.nothing, 530 | outcomes: [ 531 | { 532 | chances: 50, 533 | type: outcomeTypes.addStress(20), 534 | }, 535 | { 536 | chances: 25, 537 | type: outcomeTypes.goldTrinket, 538 | }, 539 | { 540 | chances: 25, 541 | type: outcomeTypes.purgeNegativeQuirk, 542 | }, 543 | ] 544 | }, 545 | { 546 | activator: activators.holyWater, 547 | outcomes: [ 548 | { 549 | chances: 100, 550 | type: outcomeTypes.removeStress(30), 551 | }, 552 | ] 553 | }, 554 | ] 555 | }, 556 | { 557 | name: 'Decorative Urn', 558 | icon: `${iconPath}decorative_urn.png`, 559 | description: 'An urn holds ashes of the departed.', 560 | options: [ 561 | { 562 | activator: activators.nothing, 563 | outcomes: [ 564 | { 565 | chances: 44, 566 | type: outcomeTypes.goldTrinket, 567 | amount: 2, 568 | }, 569 | { 570 | chances: 22, 571 | type: outcomeTypes.blight, 572 | }, 573 | { 574 | chances: 7, 575 | type: outcomeTypes.disease('Creeping Cough'), 576 | }, 577 | { 578 | chances: 3, 579 | type: outcomeTypes.disease(), 580 | }, 581 | { 582 | chances: 22, 583 | type: outcomeTypes.nothing, 584 | }, 585 | ] 586 | }, 587 | { 588 | activator: activators.holyWater, 589 | outcomes: [ 590 | { 591 | chances: 100, 592 | type: outcomeTypes.goldTrinket, 593 | amount: 2, 594 | }, 595 | ] 596 | }, 597 | { 598 | activator: activators.shovel, 599 | outcomes: [ 600 | { 601 | chances: 100, 602 | type: outcomeTypes.gainNegativeQuirk('Guilty Conscience'), 603 | }, 604 | ] 605 | }, 606 | ] 607 | }, 608 | { 609 | name: 'Holy Fountain', 610 | icon: `${iconPath}holy_fountain.png`, 611 | description: 'An ornate fountain of holy purport.', 612 | options: [ 613 | { 614 | activator: activators.nothing, 615 | outcomes: [ 616 | { 617 | chances: 50, 618 | type: outcomeTypes.healStressEffectAndHP(10, 5), 619 | }, 620 | { 621 | chances: 50, 622 | type: outcomeTypes.goldGems, 623 | }, 624 | ] 625 | }, 626 | { 627 | activator: activators.holyWater, 628 | outcomes: [ 629 | { 630 | chances: 100, 631 | type: outcomeTypes.healStressEffectAndHP(20, 12), 632 | }, 633 | ] 634 | } 635 | ] 636 | }, 637 | { 638 | name: 'Iron Maiden', 639 | icon: `${iconPath}iron_maiden.png`, 640 | description: 'A rusty iron maiden stands against the wall, clasped shut.', 641 | options: [ 642 | { 643 | activator: activators.nothing, 644 | outcomes: [ 645 | { 646 | chances: 40, 647 | type: outcomeTypes.anyLoot, 648 | amount: 2, 649 | }, 650 | { 651 | chances: 20, 652 | type: outcomeTypes.gainNegativeQuirk('Claustrophobia'), 653 | }, 654 | { 655 | chances: 13, 656 | type: outcomeTypes.disease('Tetanus'), 657 | }, 658 | { 659 | chances: 6, 660 | type: outcomeTypes.disease(), 661 | }, 662 | { 663 | chances: 20, 664 | type: outcomeTypes.nothing, 665 | }, 666 | ] 667 | }, 668 | { 669 | activator: activators.medicinalHerb, 670 | outcomes: [ 671 | { 672 | chances: 100, 673 | type: outcomeTypes.anyLoot, 674 | }, 675 | ] 676 | } 677 | ] 678 | }, 679 | { 680 | name: 'Locked Display Cabinet', 681 | icon: `${iconPath}locked_display_cabinet.png`, 682 | description: 'There could be valuables left inside, but this cabinet is locked.', 683 | options: [ 684 | { 685 | activator: activators.nothing, 686 | outcomes: [ 687 | { 688 | chances: 50, 689 | type: outcomeTypes.bleed, 690 | amount: 2, 691 | }, 692 | { 693 | chances: 50, 694 | type: outcomeTypes.blight, 695 | }, 696 | ] 697 | }, 698 | { 699 | activator: activators.skeletonKey, 700 | outcomes: [ 701 | { 702 | chances: 100, 703 | type: outcomeTypes.goldGemsHeirlooms, 704 | amount: 2.5, 705 | }, 706 | ] 707 | }, 708 | { 709 | activator: activators.shovel, 710 | outcomes: [ 711 | { 712 | chances: 100, 713 | type: outcomeTypes.goldGemsHeirlooms, 714 | amount: 2, 715 | }, 716 | ] 717 | } 718 | ] 719 | }, 720 | { 721 | name: 'Locked Sarcophagus', 722 | icon: `${iconPath}locked_sarcophagus.png`, 723 | description: 'An ornate sarcophagus. It\'s locked.', 724 | options: [ 725 | { 726 | activator: activators.nothing, 727 | outcomes: [ 728 | { 729 | chances: 50, 730 | type: outcomeTypes.bleed, 731 | amount: 2, 732 | }, 733 | { 734 | chances: 50, 735 | type: outcomeTypes.blight, 736 | }, 737 | ] 738 | }, 739 | { 740 | activator: activators.skeletonKey, 741 | outcomes: [ 742 | { 743 | chances: 100, 744 | type: outcomeTypes.goldGemsHeirlooms, 745 | amount: 1.5, 746 | }, 747 | ] 748 | }, 749 | { 750 | activator: activators.shovel, 751 | outcomes: [ 752 | { 753 | chances: 100, 754 | type: outcomeTypes.goldGemsHeirlooms, 755 | }, 756 | ] 757 | } 758 | ] 759 | }, 760 | { 761 | name: 'Sarcophagus', 762 | icon: `${iconPath}sarcophagus.png`, 763 | description: 'An ornate sarcophagus. It is slightly ajar.', 764 | options: [ 765 | { 766 | activator: activators.nothing, 767 | outcomes: [ 768 | { 769 | chances: 60, 770 | type: outcomeTypes.goldHeirlooms, 771 | amount: 2, 772 | }, 773 | { 774 | chances: 20, 775 | type: outcomeTypes.gainNegativeQuirk('Thanatophobia'), 776 | }, 777 | { 778 | chances: 20, 779 | type: outcomeTypes.nothing, 780 | }, 781 | ] 782 | }, 783 | ] 784 | }, 785 | { 786 | name: 'Stack of books', 787 | icon: `${iconPath}stack_of_books.png`, 788 | description: 'A stack of literary treasures in an unlikely location.', 789 | options: [ 790 | { 791 | activator: activators.nothing, 792 | outcomes: [ 793 | { 794 | chances: 26, 795 | type: outcomeTypes.addStress(25), 796 | amount: 2, 797 | }, 798 | { 799 | chances: 26, 800 | type: outcomeTypes.gainPositiveQuirk(), 801 | }, 802 | { 803 | chances: 13, 804 | type: outcomeTypes.gainNegativeQuirk(), 805 | }, 806 | { 807 | chances: 13, 808 | type: outcomeTypes.decreaseLight(25), 809 | }, 810 | { 811 | chances: 20, 812 | type: outcomeTypes.nothing, 813 | }, 814 | ], 815 | }, 816 | { 817 | activator: activators.torch, 818 | outcomes: [ 819 | { 820 | chances: 100, 821 | type: outcomeTypes.addStress(100), 822 | }, 823 | ], 824 | }, 825 | ] 826 | }, 827 | { 828 | name: 'Suit of Armor', 829 | icon: `${iconPath}suit_of_armor.png`, 830 | description: 'An antique suit of armor stands amidst the ruins.', 831 | options: [ 832 | { 833 | activator: activators.nothing, 834 | outcomes: [ 835 | { 836 | chances: 75, 837 | type: outcomeTypes.buff([{ 838 | type: 'DODGE', 839 | amount: 10 840 | }, 841 | { 842 | type: 'PROT', 843 | amount: 10, 844 | percent: true, 845 | }], true), 846 | }, 847 | { 848 | chances: 12.5, 849 | type: outcomeTypes.gainPositiveQuirk('Ruins Adventurer'), 850 | }, 851 | { 852 | chances: 12.5, 853 | type: outcomeTypes.gainPositiveQuirk('Ruins Tactician'), 854 | }, 855 | ], 856 | }, 857 | ] 858 | }, 859 | ], 860 | 'warrens': [ 861 | ...universalCurios, 862 | { 863 | name: 'Bone Altar', 864 | icon: `${iconPath}bone_altar.png`, 865 | description: 'A dark altar with skulls prominently on display. A strange power can be felt in its presence.', 866 | options: [ 867 | { 868 | activator: activators.nothing, 869 | outcomes: [ 870 | { 871 | chances: 100, 872 | type: outcomeTypes.buffDMGAndAccAndCRTAndCureStatusEffect(15, 10, 5), 873 | amount: 2, 874 | }, 875 | ], 876 | }, 877 | ] 878 | }, 879 | { 880 | name: 'Dinner Cart', 881 | icon: `${iconPath}dinner_cart.png`, 882 | description: 'A cart of human remains. It looks much like a feeding trough. Disgusting.', 883 | options: [ 884 | { 885 | activator: activators.nothing, 886 | outcomes: [ 887 | { 888 | chances: 25, 889 | type: outcomeTypes.goldFoodTrinket, 890 | amount: 1, 891 | }, 892 | { 893 | chances: 25, 894 | type: outcomeTypes.blight, 895 | }, 896 | { 897 | chances: 25, 898 | type: outcomeTypes.disease(), 899 | }, 900 | { 901 | chances: 25, 902 | type: outcomeTypes.nothing, 903 | }, 904 | ], 905 | }, 906 | { 907 | activator: activators.medicinalHerb, 908 | outcomes: [ 909 | { 910 | chances: 100, 911 | type: outcomeTypes.goldFoodTrinket, 912 | amount: 2, 913 | }, 914 | ], 915 | }, 916 | ] 917 | }, 918 | { 919 | name: 'Makeshift dining table', 920 | icon: `${iconPath}makeshift_dining_table.png`, 921 | description: 'An oddly assembled dining table. There might still be food scraps around.', 922 | options: [ 923 | { 924 | activator: activators.nothing, 925 | outcomes: [ 926 | { 927 | chances: 25, 928 | type: outcomeTypes.goldFoodTrinket, 929 | amount: 1, 930 | }, 931 | { 932 | chances: 25, 933 | type: outcomeTypes.blight, 934 | }, 935 | { 936 | chances: 25, 937 | type: outcomeTypes.disease(), 938 | }, 939 | { 940 | chances: 25, 941 | type: outcomeTypes.nothing, 942 | }, 943 | ], 944 | }, 945 | { 946 | activator: activators.medicinalHerb, 947 | outcomes: [ 948 | { 949 | chances: 100, 950 | type: outcomeTypes.goldFoodTrinket, 951 | amount: 2, 952 | }, 953 | ], 954 | }, 955 | ] 956 | }, 957 | { 958 | name: 'Moonshine Barrel', 959 | icon: `${iconPath}moonshine_barrel.png`, 960 | description: 'A barrel that reeks of powerful liquors.', 961 | options: [ 962 | { 963 | activator: activators.nothing, 964 | outcomes: [ 965 | { 966 | chances: 33.3, 967 | type: outcomeTypes.goldFoodSupply, 968 | amount: 1, 969 | }, 970 | { 971 | chances: 33.3, 972 | type: outcomeTypes.blight, 973 | }, 974 | { 975 | chances: 11.1, 976 | type: outcomeTypes.disease('Alcoholism'), 977 | }, 978 | { 979 | chances: 22.2, 980 | type: outcomeTypes.nothing, 981 | }, 982 | ], 983 | }, 984 | { 985 | activator: activators.medicinalHerb, 986 | outcomes: [ 987 | { 988 | chances: 100, 989 | type: outcomeTypes.buff([{ 990 | type: 'DMG', 991 | amount: 30, 992 | percent: true, 993 | }], true), 994 | }, 995 | ], 996 | }, 997 | ] 998 | }, 999 | { 1000 | name: 'Occult Scrawlings', 1001 | icon: `${iconPath}occult_scrawlings.png`, 1002 | description: 'Scrawlings written on what looks like stretched and tanned human flesh...', 1003 | options: [ 1004 | { 1005 | activator: activators.nothing, 1006 | outcomes: [ 1007 | { 1008 | chances: 33.3, 1009 | type: outcomeTypes.gainPositiveQuirk(), 1010 | amount: 1, 1011 | }, 1012 | { 1013 | chances: 25, 1014 | type: outcomeTypes.addStress(25), 1015 | }, 1016 | { 1017 | chances: 17.6, 1018 | type: outcomeTypes.gainNegativeQuirk(), 1019 | }, 1020 | { 1021 | chances: 25, 1022 | type: outcomeTypes.nothing, 1023 | }, 1024 | ], 1025 | }, 1026 | { 1027 | activator: activators.holyWater, 1028 | outcomes: [ 1029 | { 1030 | chances: 100, 1031 | type: outcomeTypes.debuff([{ 1032 | type: 'DODGE', 1033 | amount: 20, 1034 | }]), 1035 | }, 1036 | ], 1037 | }, 1038 | ] 1039 | }, 1040 | { 1041 | name: 'Pile of Bones', 1042 | icon: `${iconPath}pile_of_bones.png`, 1043 | description: 'All that\'s left of a previous adventurer, perhaps.', 1044 | options: [ 1045 | { 1046 | activator: activators.nothing, 1047 | outcomes: [ 1048 | { 1049 | chances: 25, 1050 | type: outcomeTypes.anyLoot, 1051 | amount: 2, 1052 | }, 1053 | { 1054 | chances: 25, 1055 | type: outcomeTypes.disease(), 1056 | }, 1057 | { 1058 | chances: 25, 1059 | type: outcomeTypes.gainNegativeQuirk('Bloodthirsty'), 1060 | }, 1061 | { 1062 | chances: 25, 1063 | type: outcomeTypes.nothing, 1064 | }, 1065 | ], 1066 | }, 1067 | { 1068 | activator: activators.holyWater, 1069 | outcomes: [ 1070 | { 1071 | chances: 100, 1072 | type: outcomeTypes.anyLoot, 1073 | amount: 2, 1074 | }, 1075 | ], 1076 | }, 1077 | ] 1078 | }, 1079 | { 1080 | name: 'Pile of Scrolls', 1081 | icon: `${iconPath}pile_of_scrolls.png`, 1082 | description: 'A bunch of scrolls. The cursive is sloppy and difficult to read.', 1083 | options: [ 1084 | { 1085 | activator: activators.nothing, 1086 | outcomes: [ 1087 | { 1088 | chances: 33.3, 1089 | type: outcomeTypes.scouting 1090 | }, 1091 | { 1092 | chances: 16.7, 1093 | type: outcomeTypes.addStress(15), 1094 | }, 1095 | { 1096 | chances: 11.1, 1097 | type: outcomeTypes.gainPositiveQuirk(), 1098 | }, 1099 | { 1100 | chances: 5.6, 1101 | type: outcomeTypes.gainNegativeQuirk(), 1102 | }, 1103 | { 1104 | chances: 33.3, 1105 | type: outcomeTypes.nothing, 1106 | }, 1107 | ], 1108 | }, 1109 | { 1110 | activator: activators.torch, 1111 | outcomes: [ 1112 | { 1113 | chances: 100, 1114 | type: outcomeTypes.purgeNegativeQuirk, 1115 | }, 1116 | ], 1117 | }, 1118 | ] 1119 | }, 1120 | { 1121 | name: 'Rack of Blades', 1122 | icon: `${iconPath}rack_of_blades.png`, 1123 | description: 'A rack of dulled, rusty knives. They are covered in fresh blood.', 1124 | options: [ 1125 | { 1126 | activator: activators.nothing, 1127 | outcomes: [ 1128 | { 1129 | chances: 40, 1130 | type: outcomeTypes.goldGemsFood 1131 | }, 1132 | { 1133 | chances: 40, 1134 | type: outcomeTypes.bleed, 1135 | }, 1136 | { 1137 | chances: 20, 1138 | type: outcomeTypes.nothing, 1139 | }, 1140 | ], 1141 | }, 1142 | { 1143 | activator: activators.bandage, 1144 | outcomes: [ 1145 | { 1146 | chances: 100, 1147 | type: outcomeTypes.goldGemsFood, 1148 | amount: 1.5, 1149 | }, 1150 | ], 1151 | }, 1152 | ] 1153 | }, 1154 | { 1155 | name: 'Sacrifial Stone', 1156 | icon: `${iconPath}sacrificial_stone.png`, 1157 | description: 'A stone used for ancient, barbaric rituals.', 1158 | options: [ 1159 | { 1160 | activator: activators.nothing, 1161 | outcomes: [ 1162 | { 1163 | chances: 50, 1164 | type: outcomeTypes.addStress(50), 1165 | }, 1166 | { 1167 | chances: 25, 1168 | type: outcomeTypes.purgeNegativeQuirk, 1169 | }, 1170 | { 1171 | chances: 12.5, 1172 | type: outcomeTypes.gainPositiveQuirk('Warrens Explorer'), 1173 | }, 1174 | { 1175 | chances: 12.5, 1176 | type: outcomeTypes.gainPositiveQuirk('Warrens Explorer'), 1177 | }, 1178 | ], 1179 | }, 1180 | ], 1181 | }, 1182 | { 1183 | name: 'Stack of Books', 1184 | icon: `${iconPath}stack_of_books.png`, 1185 | description: 'A stack of literary treasures in an unlikely location.', 1186 | options: [ 1187 | { 1188 | activator: activators.nothing, 1189 | outcomes: [ 1190 | { 1191 | chances: 26.7, 1192 | type: outcomeTypes.addStress(25), 1193 | }, 1194 | { 1195 | chances: 26.7, 1196 | type: outcomeTypes.gainPositiveQuirk(), 1197 | }, 1198 | { 1199 | chances: 13.3, 1200 | type: outcomeTypes.gainNegativeQuirk(), 1201 | }, 1202 | { 1203 | chances: 13.3, 1204 | type: outcomeTypes.decreaseLight(25), 1205 | }, 1206 | { 1207 | chances: 20, 1208 | type: outcomeTypes.nothing, 1209 | }, 1210 | ], 1211 | }, 1212 | { 1213 | activator: activators.torch, 1214 | outcomes: [ 1215 | { 1216 | chances: 100, 1217 | type: outcomeTypes.addStress(100), 1218 | }, 1219 | ], 1220 | }, 1221 | ], 1222 | }, 1223 | ], 1224 | 'weald': [ 1225 | ...universalCurios, 1226 | { 1227 | name: 'Ancient Coffin', 1228 | icon: `${iconPath}ancient_coffin.png`, 1229 | description: 'An old coffin. It is slightly ajar.', 1230 | options: [ 1231 | { 1232 | activator: activators.nothing, 1233 | outcomes: [ 1234 | { 1235 | chances: 50, 1236 | type: outcomeTypes.goldHeirlooms, 1237 | amount: 2, 1238 | }, 1239 | { 1240 | chances: 8.3, 1241 | type: outcomeTypes.gainPositiveQuirk('Weald Adventurer'), 1242 | }, 1243 | { 1244 | chances: 8.3, 1245 | type: outcomeTypes.gainPositiveQuirk('Weald Adventurer'), 1246 | }, 1247 | { 1248 | chances: 33.3, 1249 | type: outcomeTypes.nothing, 1250 | }, 1251 | ], 1252 | }, 1253 | ], 1254 | }, 1255 | { 1256 | name: 'Beast Carcass', 1257 | icon: `${iconPath}beast_carcass.png`, 1258 | description: 'Something has recently mutilated this creature...', 1259 | options: [ 1260 | { 1261 | activator: activators.nothing, 1262 | outcomes: [ 1263 | { 1264 | chances: 42.9, 1265 | type: outcomeTypes.food, 1266 | }, 1267 | { 1268 | chances: 28.6, 1269 | type: outcomeTypes.disease('Rabies'), 1270 | }, 1271 | { 1272 | chances: 14.3, 1273 | type: outcomeTypes.gainNegativeQuirk('Zoophobia'), 1274 | }, 1275 | { 1276 | chances: 14.3, 1277 | type: outcomeTypes.nothing, 1278 | }, 1279 | ], 1280 | }, 1281 | { 1282 | activator: activators.medicinalHerb, 1283 | outcomes: [ 1284 | { 1285 | chances: 100, 1286 | type: outcomeTypes.food, 1287 | amount: 2 1288 | }, 1289 | ], 1290 | }, 1291 | ], 1292 | }, 1293 | { 1294 | name: 'Eerie Spiderweb', 1295 | icon: `${iconPath}eerie_spiderweb.png`, 1296 | description: 'A spiderweb with a strange glow to it. There might be something behind it.', 1297 | options: [ 1298 | { 1299 | activator: activators.nothing, 1300 | outcomes: [ 1301 | { 1302 | chances: 40, 1303 | type: outcomeTypes.goldGemsTrinket, 1304 | }, 1305 | { 1306 | chances: 10, 1307 | type: outcomeTypes.gainNegativeQuirk('Slow Reflexes'), 1308 | }, 1309 | { 1310 | chances: 10, 1311 | type: outcomeTypes.gainNegativeQuirk('Slowdraw'), 1312 | }, 1313 | { 1314 | chances: 40, 1315 | type: outcomeTypes.nothing, 1316 | }, 1317 | ], 1318 | }, 1319 | { 1320 | activator: activators.bandage, 1321 | outcomes: [ 1322 | { 1323 | chances: 100, 1324 | type: outcomeTypes.goldGemsTrinket, 1325 | amount: 1.5 1326 | }, 1327 | ], 1328 | }, 1329 | ], 1330 | }, 1331 | { 1332 | name: 'Left Luggage', 1333 | icon: `${iconPath}left_luggage.png`, 1334 | description: 'Someone dropped this recently. Probably on the run. It has a lock on it.', 1335 | options: [ 1336 | { 1337 | activator: activators.nothing, 1338 | outcomes: [ 1339 | { 1340 | chances: 50, 1341 | type: outcomeTypes.anyLoot, 1342 | }, 1343 | { 1344 | chances: 50, 1345 | type: outcomeTypes.blight, 1346 | }, 1347 | ], 1348 | }, 1349 | { 1350 | activator: activators.skeletonKey, 1351 | outcomes: [ 1352 | { 1353 | chances: 100, 1354 | type: outcomeTypes.anyLoot, 1355 | amount: 3 1356 | }, 1357 | ], 1358 | }, 1359 | { 1360 | activator: activators.antivenom, 1361 | outcomes: [ 1362 | { 1363 | chances: 100, 1364 | type: outcomeTypes.anyLoot, 1365 | amount: 3 1366 | }, 1367 | ], 1368 | }, 1369 | ], 1370 | }, 1371 | { 1372 | name: 'Mummified Remains', 1373 | icon: `${iconPath}mummified_remains.png`, 1374 | description: 'Ancient remains. The body looks well preserved.', 1375 | options: [ 1376 | { 1377 | activator: activators.nothing, 1378 | outcomes: [ 1379 | { 1380 | chances: 40, 1381 | type: outcomeTypes.goldTrinket, 1382 | }, 1383 | { 1384 | chances: 40, 1385 | type: outcomeTypes.blight, 1386 | }, 1387 | { 1388 | chances: 20, 1389 | type: outcomeTypes.nothing, 1390 | }, 1391 | ], 1392 | }, 1393 | { 1394 | activator: activators.bandage, 1395 | outcomes: [ 1396 | { 1397 | chances: 100, 1398 | type: outcomeTypes.goldTrinket, 1399 | amount: 2 1400 | }, 1401 | ], 1402 | }, 1403 | ], 1404 | }, 1405 | { 1406 | name: 'Old Tree', 1407 | icon: `${iconPath}old_tree.png`, 1408 | description: 'This tree has a huge hole in the trunk. Perhaps there\'s something inside...', 1409 | options: [ 1410 | { 1411 | activator: activators.nothing, 1412 | outcomes: [ 1413 | { 1414 | chances: 50, 1415 | type: outcomeTypes.anyLoot, 1416 | amount: 2, 1417 | }, 1418 | { 1419 | chances: 25, 1420 | type: outcomeTypes.blight, 1421 | }, 1422 | { 1423 | chances: 25, 1424 | type: outcomeTypes.nothing, 1425 | }, 1426 | ], 1427 | }, 1428 | { 1429 | activator: activators.antivenom, 1430 | outcomes: [ 1431 | { 1432 | chances: 100, 1433 | type: outcomeTypes.anyLoot, 1434 | amount: 3, 1435 | }, 1436 | ], 1437 | }, 1438 | ], 1439 | }, 1440 | { 1441 | name: 'Pristine Fountain', 1442 | icon: `${iconPath}pristine_fountain.png`, 1443 | description: 'A beautiful fountain. It looks unaffected by the surrounding chaos.', 1444 | options: [ 1445 | { 1446 | activator: activators.nothing, 1447 | outcomes: [ 1448 | { 1449 | chances: 100, 1450 | type: outcomeTypes.removeStress(20), 1451 | }, 1452 | ], 1453 | }, 1454 | { 1455 | activator: activators.holyWater, 1456 | outcomes: [ 1457 | { 1458 | chances: 100, 1459 | type: outcomeTypes.removeStress(30), 1460 | }, 1461 | ], 1462 | }, 1463 | ], 1464 | }, 1465 | { 1466 | name: 'Shallow Grave', 1467 | icon: `${iconPath}shallow_grave.png`, 1468 | description: 'A grave, dug in haste.', 1469 | options: [ 1470 | { 1471 | activator: activators.nothing, 1472 | outcomes: [ 1473 | { 1474 | chances: 50, 1475 | type: outcomeTypes.blight, 1476 | }, 1477 | { 1478 | chances: 50, 1479 | type: outcomeTypes.disease(), 1480 | }, 1481 | ], 1482 | }, 1483 | { 1484 | activator: activators.shovel, 1485 | outcomes: [ 1486 | { 1487 | chances: 100, 1488 | type: outcomeTypes.gemsHerlooms, 1489 | amount: 3, 1490 | }, 1491 | ], 1492 | }, 1493 | ], 1494 | }, 1495 | { 1496 | name: 'Traveler\'s Tent', 1497 | icon: `${iconPath}travelers_tent.png`, 1498 | description: 'Someone has camped here recently.', 1499 | options: [ 1500 | { 1501 | activator: activators.nothing, 1502 | outcomes: [ 1503 | { 1504 | chances: 37.5, 1505 | type: outcomeTypes.goldSuppliesHeirlooms, 1506 | amount: 2, 1507 | }, 1508 | { 1509 | chances: 37.5, 1510 | type: outcomeTypes.scouting, 1511 | }, 1512 | { 1513 | chances: 12.5, 1514 | type: outcomeTypes.addStress(25), 1515 | }, 1516 | { 1517 | chances: 12.5, 1518 | type: outcomeTypes.nothing, 1519 | }, 1520 | ], 1521 | }, 1522 | ], 1523 | }, 1524 | { 1525 | name: 'Troubling Effigy', 1526 | icon: `${iconPath}troubling_effigy.png`, 1527 | description: 'An unsettling effigy erected in service to a mysterious god.', 1528 | options: [ 1529 | { 1530 | activator: activators.nothing, 1531 | outcomes: [ 1532 | { 1533 | chances: 18.7, 1534 | type: outcomeTypes.gainPositiveQuirk(), 1535 | }, 1536 | { 1537 | chances: 18.7, 1538 | type: outcomeTypes.gainNegativeQuirk(), 1539 | }, 1540 | { 1541 | chances: 18.7, 1542 | type: outcomeTypes.bleed, 1543 | }, 1544 | { 1545 | chances: 9.4, 1546 | type: outcomeTypes.blight, 1547 | }, 1548 | { 1549 | chances: 9.4, 1550 | type: outcomeTypes.addStress(15), 1551 | }, 1552 | { 1553 | chances: 25, 1554 | type: outcomeTypes.nothing, 1555 | }, 1556 | ], 1557 | }, 1558 | { 1559 | activator: activators.holyWater, 1560 | outcomes: [ 1561 | { 1562 | chances: 100, 1563 | type: outcomeTypes.gainPositiveQuirk(), 1564 | }, 1565 | ], 1566 | }, 1567 | ], 1568 | }, 1569 | ], 1570 | 'cove': [ 1571 | ...universalCurios, 1572 | { 1573 | name: 'Barnacle Crusted Chest', 1574 | icon: `${iconPath}bernacle_crusted_chest.png`, 1575 | description: 'A treasure chest blanketed in barnacles.', 1576 | options: [ 1577 | { 1578 | activator: activators.nothing, 1579 | outcomes: [ 1580 | { 1581 | chances: 50, 1582 | type: outcomeTypes.goldGemsHeirloomsSupplies, 1583 | amount: 2, 1584 | }, 1585 | { 1586 | chances: 25, 1587 | type: outcomeTypes.bleed, 1588 | }, 1589 | { 1590 | chances: 25, 1591 | type: outcomeTypes.nothing, 1592 | }, 1593 | ], 1594 | }, 1595 | { 1596 | activator: activators.shovel, 1597 | outcomes: [ 1598 | { 1599 | chances: 100, 1600 | type: outcomeTypes.anyLoot, 1601 | amount: 3, 1602 | }, 1603 | ], 1604 | }, 1605 | ], 1606 | }, 1607 | { 1608 | name: 'Bas-Relief', 1609 | icon: `${iconPath}bas_relief.png`, 1610 | description: 'A puzzingly ancient sculpture of dizzying implication...', 1611 | options: [ 1612 | { 1613 | activator: activators.nothing, 1614 | outcomes: [ 1615 | { 1616 | chances: 66.7, 1617 | type: outcomeTypes.gainPositiveQuirk(), 1618 | }, 1619 | { 1620 | chances: 25, 1621 | type: outcomeTypes.gainNegativeQuirk(), 1622 | }, 1623 | { 1624 | chances: 8.3, 1625 | type: outcomeTypes.disease(), 1626 | }, 1627 | ], 1628 | }, 1629 | { 1630 | activator: activators.shovel, 1631 | outcomes: [ 1632 | { 1633 | chances: 100, 1634 | type: outcomeTypes.addStress(100), 1635 | }, 1636 | ], 1637 | }, 1638 | ], 1639 | }, 1640 | { 1641 | name: 'Brackish Tidepool', 1642 | icon: `${iconPath}brackish_tidepool.png`, 1643 | description: 'A pool of water cupped in smooth stone. Its color looks sightly off...', 1644 | options: [ 1645 | { 1646 | activator: activators.nothing, 1647 | outcomes: [ 1648 | { 1649 | chances: 75, 1650 | type: outcomeTypes.buff([{ 1651 | type: 'Bleed, Blight, Disease and Debuff resist', 1652 | amount: 33, 1653 | percent: true, 1654 | }], true), 1655 | }, 1656 | { 1657 | chances: 25, 1658 | type: outcomeTypes.disease(), 1659 | }, 1660 | ], 1661 | }, 1662 | { 1663 | activator: activators.antivenom, 1664 | outcomes: [ 1665 | { 1666 | chances: 100, 1667 | type: outcomeTypes.healStressEffectAndHP(5, 5), 1668 | }, 1669 | ], 1670 | }, 1671 | ], 1672 | }, 1673 | { 1674 | name: 'Eerie Coral', 1675 | icon: `${iconPath}eerie_coral.png`, 1676 | description: 'There is something odd about this coral.', 1677 | options: [ 1678 | { 1679 | activator: activators.nothing, 1680 | outcomes: [ 1681 | { 1682 | chances: 50, 1683 | type: outcomeTypes.removeStress(10), 1684 | }, 1685 | { 1686 | chances: 25, 1687 | type: outcomeTypes.addStress(25), 1688 | }, 1689 | { 1690 | chances: 25, 1691 | type: outcomeTypes.nothing, 1692 | }, 1693 | ], 1694 | }, 1695 | { 1696 | activator: activators.medicinalHerb, 1697 | outcomes: [ 1698 | { 1699 | chances: 100, 1700 | type: outcomeTypes.purgeNegativeQuirk, 1701 | }, 1702 | ], 1703 | }, 1704 | ], 1705 | }, 1706 | { 1707 | name: 'Fish Idol', 1708 | icon: `${iconPath}fish_idol.png`, 1709 | description: 'A strange presence is felt near this statue of worship.', 1710 | options: [ 1711 | { 1712 | activator: activators.nothing, 1713 | outcomes: [ 1714 | { 1715 | chances: 50, 1716 | type: outcomeTypes.debuff( 1717 | [ 1718 | { 1719 | type: 'DMG', 1720 | amount: -25, 1721 | percent: true, 1722 | }, 1723 | { 1724 | type: 'ACC', 1725 | amount: -10, 1726 | }, 1727 | ], true), 1728 | }, 1729 | { 1730 | chances: 50, 1731 | type: outcomeTypes.debuff( 1732 | [ 1733 | { 1734 | type: 'DODGE', 1735 | amount: -12, 1736 | }, 1737 | { 1738 | type: 'Marked', 1739 | amount: '3 round', 1740 | }, 1741 | ], true), 1742 | }, 1743 | ], 1744 | }, 1745 | { 1746 | activator: activators.holyWater, 1747 | outcomes: [ 1748 | { 1749 | chances: 50, 1750 | type: outcomeTypes.buff( 1751 | [ 1752 | { 1753 | type: 'DMG', 1754 | amount: 18, 1755 | percent: true, 1756 | }, 1757 | ], true), 1758 | }, 1759 | { 1760 | chances: 50, 1761 | type: outcomeTypes.buff( 1762 | [ 1763 | { 1764 | type: 'DMG', 1765 | amount: 10, 1766 | percent: true, 1767 | }, 1768 | { 1769 | type: 'ACC', 1770 | amount: 5, 1771 | }, 1772 | ], true), 1773 | }, 1774 | ], 1775 | }, 1776 | ], 1777 | }, 1778 | { 1779 | name: 'Giant Fish Carcass', 1780 | icon: `${iconPath}giant_fish_carcass.png`, 1781 | description: 'A stuffed sea creature has washed ashore. Wonder that it ate...', 1782 | options: [ 1783 | { 1784 | activator: activators.nothing, 1785 | outcomes: [ 1786 | { 1787 | chances: 16.7, 1788 | type: outcomeTypes.goldGemsSupplies, 1789 | }, 1790 | { 1791 | chances: 16.7, 1792 | type: outcomeTypes.disease('The Red Plague'), 1793 | }, 1794 | { 1795 | chances: 11.1, 1796 | type: outcomeTypes.blight, 1797 | }, 1798 | { 1799 | chances: 5.5, 1800 | type: outcomeTypes.bleed, 1801 | }, 1802 | { 1803 | chances: 50, 1804 | type: outcomeTypes.nothing, 1805 | }, 1806 | ], 1807 | }, 1808 | { 1809 | activator: activators.medicinalHerb, 1810 | outcomes: [ 1811 | { 1812 | chances: 100, 1813 | type: outcomeTypes.anyLoot, 1814 | amount: 3, 1815 | }, 1816 | ], 1817 | }, 1818 | ], 1819 | }, 1820 | { 1821 | name: 'Giant Oyster', 1822 | icon: `${iconPath}giant_oyster.png`, 1823 | description: 'A live oyster. Who knows what value it hides...', 1824 | options: [ 1825 | { 1826 | activator: activators.nothing, 1827 | outcomes: [ 1828 | { 1829 | chances: 40, 1830 | type: outcomeTypes.goldTrinket, 1831 | amount: 2, 1832 | }, 1833 | { 1834 | chances: 40, 1835 | type: outcomeTypes.bleed, 1836 | }, 1837 | { 1838 | chances: 20, 1839 | type: outcomeTypes.nothing, 1840 | }, 1841 | ], 1842 | }, 1843 | { 1844 | activator: activators.shovel, 1845 | outcomes: [ 1846 | { 1847 | chances: 100, 1848 | type: outcomeTypes.goldTrinket, 1849 | amount: 3, 1850 | }, 1851 | ], 1852 | }, 1853 | { 1854 | activator: activators.dogTreats, 1855 | outcomes: [ 1856 | { 1857 | chances: 100, 1858 | type: outcomeTypes.buff([{ 1859 | type: 'DODGE', 1860 | amount: 25, 1861 | }]), 1862 | }, 1863 | ], 1864 | }, 1865 | ], 1866 | }, 1867 | { 1868 | name: 'Ship\'s Figurehead', 1869 | icon: `${iconPath}ships_figurehead.png`, 1870 | description: 'The figurehead emits a marvelous aura.', 1871 | options: [ 1872 | { 1873 | activator: activators.nothing, 1874 | outcomes: [ 1875 | { 1876 | chances: 66.7, 1877 | type: outcomeTypes.buff([{ 1878 | type: 'SPD', 1879 | amount: 20, 1880 | percent: true, 1881 | }], true), 1882 | }, 1883 | { 1884 | chances: 33.3, 1885 | type: outcomeTypes.removeStress(30), 1886 | }, 1887 | ], 1888 | }, 1889 | ], 1890 | }, 1891 | ], 1892 | } 1893 | 1894 | export function getCuriosForLocation(location) { 1895 | return curiosPerLocation[location]; 1896 | } 1897 | --------------------------------------------------------------------------------