Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/map3 #139

Merged
merged 14 commits into from
Feb 13, 2021
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,21 +82,21 @@ Cards can apply "powers". A power is a status effect or aura that usually lasts

As an example, setting `state.player.powers.weak = 5`, indicates that the player should be considered weak for five turns. Powers decrease by one stack per turn.

### The player
### Player

On `state.player` we have you, the player. This object describes the health, powers and the cards you have.

### Dungeon

Every game starts in a dungeon. You fight your way through one or more rooms to reach the end, where you win the game.
Every game starts in a dungeon. You make your way through rooms to reach the end.

There are different types of rooms. Like Monster and Campfire. One day there'll be more like Merchant and Treasure or a "random" room.

Later it'd be cool to have real maps like Slay The Spire, where there are multiple paths to take.

### Monsters

Monsters exist inside the rooms in a dungeon. A monster has some health and a list of "intents" that it will take each turn. These intents are basically the AI. Monsters can do damage, block and apply powers. It's not super flexible, as we're not using actions and cards like the player does. But it is enough for now.
Monsters exist inside the rooms in a dungeon. A monster has health and a list of "intents" that it will take each turn. These intents are basically the AI. Monsters can do damage, block and apply powers. It's not super flexible, as we're not using actions and cards like the player does. But it is enough for now.

## References

Expand Down
20 changes: 9 additions & 11 deletions public/content/dungeon-encounters.js
Original file line number Diff line number Diff line change
@@ -1,48 +1,47 @@
/* eslint-disable no-unused-vars */
import Dungeon, {MonsterRoom, Monster} from '../game/dungeon.js'
import Dungeon from '../game/dungeon.js'
import {MonsterRoom, Monster} from '../game/dungeon-rooms.js'
import {random} from '../game/utils.js'

// Hello. With the imported functions above you can create a dungeon with different rooms and monsters.
// This file contains the example dungeon used in Slay the Web.

export const dungeonWithMap = () => {
return Dungeon({
rows: 7,
columns: 6,
minEncounters: 3,
maxEncounters: 4,
paths: '0235',
width: 6,
height: 7,
minRooms: 3,
maxRooms: 4,
customPaths: '0235',
})
}

// This is the dungeon used in tests. Don't change it without running tests.
export const createTestDungeon = () => {
const dungeon = Dungeon({rows: 3, columns: 1})
const dungeon = Dungeon({width: 1, height: 3})
// The tests rely on the first room having a single monster, second two monsters.
const intents = [{block: 7}, {damage: 10}, {damage: 8}, {}, {damage: 14}]
dungeon.graph[1][0].room = MonsterRoom(Monster({hp: 42, intents}))
dungeon.graph[2][0].room = MonsterRoom(Monster({hp: 24, intents}), Monster({hp: 13, intents}))
return dungeon
}

// Here are some different monsters we use in the game.
export const monsters = {}

monsters['Necromancer'] = MonsterRoom(
Monster({
hp: random(18, 20),
intents: [{damage: 7}, {damage: 11}, {damage: 7}, {block: 9}],
random: 2,
})
)

monsters['monster2'] = MonsterRoom(
Monster({
hp: random(43, 47),
intents: [{vulnerable: 1}, {damage: 10}, {damage: 6}, {}, {weak: 1}],
random: 2,
})
)

monsters['monster3'] = MonsterRoom(
Monster({
hp: random(13, 17),
Expand All @@ -67,7 +66,6 @@ monsters['monster4'] = MonsterRoom(
random: 2,
})
)

monsters['monster5'] = MonsterRoom(
Monster({hp: 70, block: 12, intents: [{block: 5}, {damage: 16}]})
)
Expand Down
4 changes: 2 additions & 2 deletions public/game/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -335,10 +335,10 @@ function move(state, {move}) {
draft.player.powers = {}
draft.player.currentEnergy = 3
draft.player.block = 0
draft.dungeon.x = move.x
draft.dungeon.y = move.y
draft.dungeon.graph[move.y][move.x].didVisit = true
draft.dungeon.pathTaken.push({x: move.x, y: move.y})
draft.dungeon.x = move.x
draft.dungeon.y = move.y
// if (number === state.dungeon.rooms.length - 1) {
// throw new Error('You have reached the end of the dungeon. Congratulations.')
// }
Expand Down
67 changes: 67 additions & 0 deletions public/game/dungeon-rooms.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import {uuid} from './utils.js'
import {shuffle, range} from './utils.js'

export function StartRoom() {
return {
id: uuid(),
type: 'start',
}
}

export function BossRoom() {
return {
id: uuid(),
type: 'boss',
}
}

// A campfire gives our hero the opportunity to rest, remove or upgrade a card.
export function CampfireRoom() {
return {
id: uuid(),
type: 'campfire',
// choices: ['rest', 'remove', 'upgrade'],
}
}

// A monster room has one or more monsters.
export function MonsterRoom(...monsters) {
return {
id: uuid(),
type: 'monster',
monsters,
}
}

// A monster has health, probably some damage and a list of intents.
// Use a list of intents to describe what the monster should do each turn.
// Supported intents: block, damage, vulnerable and weak.
// Intents are cycled through as the monster plays its turn.
export function Monster(props = {}) {
let intents = props.intents

// By setting props.random to a number, all damage intents will be randomized with this range.
if (typeof props.random === 'number') {
intents = props.intents.map((intent) => {
if (intent.damage) {
let newDamage = shuffle(range(5, intent.damage - props.random))[0]
intent.damage = newDamage
}
return intent
})
}

return {
id: uuid(),
currentHealth: props.currentHealth || props.hp || 42,
maxHealth: props.hp || 42,
block: props.block || 0,
powers: props.powers || {},
// A list of "actions" the monster will take each turn.
// Example: [{damage: 6}, {block: 2}, {}, {weak: 2}]
// ... meaning turn 1, deal 6 damage, turn 2 gain 2 block, turn 3 do nothing, turn 4 apply 2 weak
intents: intents || [],
// A counter to keep track of which intent to run next.
nextIntent: 0,
}
}
Loading