Pārlūkot izejas kodu

Rearrange town, add goo monster, give everyone AI

Control is now determined by whether or not something is viewed
in third person.
master
Fen Dweller pirms 4 gadiem
vecāks
revīzija
5fe4205711
11 mainītis faili ar 126 papildinājumiem un 55 dzēšanām
  1. +9
    -2
      src/App.vue
  2. +1
    -1
      src/components/Combat.vue
  3. +1
    -3
      src/components/Statblock.vue
  4. +14
    -0
      src/game/ai.ts
  5. +4
    -2
      src/game/creature.ts
  6. +0
    -4
      src/game/creatures.ts
  7. +1
    -2
      src/game/creatures/characters/inazuma.ts
  8. +39
    -0
      src/game/creatures/monsters/slime.ts
  9. +3
    -0
      src/game/creatures/player.ts
  10. +35
    -39
      src/game/maps/town.ts
  11. +19
    -2
      src/game/vore.ts

+ 9
- 2
src/App.vue Parādīt failu

@@ -4,6 +4,7 @@
<div id="main-area"> <div id="main-area">
<transition name="component-fade" mode='out-in'> <transition name="component-fade" mode='out-in'>
<component <component
@control="control"
@profile="profile" @profile="profile"
@exit="$data.profileSubject = null" @exit="$data.profileSubject = null"
@give-in="gameOver()" @give-in="gameOver()"
@@ -23,7 +24,6 @@ import Header from '@/components/Header.vue'
import Combat from '@/components/Combat.vue' import Combat from '@/components/Combat.vue'
import Explore from '@/components/Explore.vue' import Explore from '@/components/Explore.vue'
import Profile from '@/components/Profile.vue' import Profile from '@/components/Profile.vue'
import * as Creatures from '@/game/creatures'
import * as Items from '@/game/items' import * as Items from '@/game/items'
import { Creature } from '@/game/creature' import { Creature } from '@/game/creature'
import { ProperNoun, TheyPronouns, FemalePronouns, MalePronouns, ImproperNoun, POV } from '@/game/language' import { ProperNoun, TheyPronouns, FemalePronouns, MalePronouns, ImproperNoun, POV } from '@/game/language'
@@ -33,6 +33,7 @@ import { LogLine, nilLog } from '@/game/interface'
import { InstantKillEffect } from '@/game/combat/effects' import { InstantKillEffect } from '@/game/combat/effects'
import moment from 'moment' import moment from 'moment'
import { Town } from '@/game/maps/town' import { Town } from '@/game/maps/town'
import Player from './game/creatures/player'


@Component({ @Component({
components: { components: {
@@ -74,7 +75,7 @@ export default class App extends Vue {
} }


created () { created () {
const player = new Creatures.Player()
const player = new Player()
player.perspective = POV.Second player.perspective = POV.Second
player.side = Side.Heroes player.side = Side.Heroes
player.equipment[Items.EquipmentSlot.MainHand] = new Items.Sword() player.equipment[Items.EquipmentSlot.MainHand] = new Items.Sword()
@@ -95,6 +96,12 @@ export default class App extends Vue {
profile (subject: Creature) { profile (subject: Creature) {
this.$data.profileSubject = subject this.$data.profileSubject = subject
} }

control (subject: Creature) {
this.$data.world.player.perspective = POV.Third
this.$data.world.player = subject
subject.perspective = POV.Second
}
} }
</script> </script>




+ 1
- 1
src/components/Combat.vue Parādīt failu

@@ -216,7 +216,7 @@ export default class Combat extends Vue {
} }
}) })


if (!(this.encounter.currentMove.ai === null)) {
if (this.encounter.currentMove.perspective === POV.Third) {
if (this.encounter.currentMove.side === Side.Heroes) { if (this.encounter.currentMove.side === Side.Heroes) {
this.executedLeft(this.encounter.currentMove.ai.decide(this.encounter.currentMove, this.encounter)) this.executedLeft(this.encounter.currentMove.ai.decide(this.encounter.currentMove, this.encounter))
} else { } else {


+ 1
- 3
src/components/Statblock.vue Parādīt failu

@@ -57,9 +57,7 @@
</div> </div>
</div> </div>
</div> </div>
<button @click.stop="subject.perspective = POV.First">1st</button>
<button @click.stop="subject.perspective = POV.Second">2nd</button>
<button @click.stop="subject.perspective = POV.Third">3rd</button>
<button @click="$emit('control', subject)">Control</button>
<button class="show-profile" @click="$emit('profile', subject)">Show profile</button> <button class="show-profile" @click="$emit('profile', subject)">Show profile</button>
</div> </div>
</div> </div>


+ 14
- 0
src/game/ai.ts Parādīt failu

@@ -202,6 +202,20 @@ export class FavorEscapedPrey extends Decider {
} }
} }


/**
* The RandomAI just does whatever it wants to
*/
export class RandomAI extends AI {
constructor (owner: Creature) {
super(
[

],
owner
)
}
}

/** /**
* The VoreAI tries to eat opponents, but only if the odds are good enough * The VoreAI tries to eat opponents, but only if the odds are good enough
*/ */


+ 4
- 2
src/game/creature.ts Parādīt failu

@@ -4,7 +4,7 @@ import { LogEntry, LogLines, LogLine } from '@/game/interface'
import { VoreContainer, VoreType, Container } from '@/game/vore' import { VoreContainer, VoreType, Container } from '@/game/vore'
import { Item, EquipmentSlot, Equipment, ItemKind, Currency } from '@/game/items' import { Item, EquipmentSlot, Equipment, ItemKind, Currency } from '@/game/items'
import { PassAction } from '@/game/combat/actions' import { PassAction } from '@/game/combat/actions'
import { AI } from '@/game/ai'
import { AI, RandomAI } from '@/game/ai'
import { Entity, Resistances } from '@/game/entity' import { Entity, Resistances } from '@/game/entity'
import { Perk } from '@/game/combat/perks' import { Perk } from '@/game/combat/perks'
import { VoreRelay } from '@/game/events' import { VoreRelay } from '@/game/events'
@@ -60,7 +60,7 @@ export class Creature extends Entity {
side: Side; side: Side;
title = "Lv. 1 Creature"; title = "Lv. 1 Creature";
equipment: {[key in EquipmentSlot]?: Equipment } = {} equipment: {[key in EquipmentSlot]?: Equipment } = {}
ai: AI|null = null
ai: AI


constructor (name: Noun, kind: Noun, pronouns: Pronoun, public baseStats: Stats, public preyPrefs: Set<VoreType>, public predPrefs: Set<VoreType>, private baseMass: number) { constructor (name: Noun, kind: Noun, pronouns: Pronoun, public baseStats: Stats, public preyPrefs: Set<VoreType>, public predPrefs: Set<VoreType>, private baseMass: number) {
super(name, kind, pronouns) super(name, kind, pronouns)
@@ -76,6 +76,8 @@ export class Creature extends Entity {
/* eslint-disable-next-line */ /* eslint-disable-next-line */
const self = this const self = this


this.ai = new RandomAI(this)

this.voreStats = { this.voreStats = {
get [VoreStat.Bulk] () { get [VoreStat.Bulk] () {
return self.containers.reduce( return self.containers.reduce(


+ 0
- 4
src/game/creatures.ts Parādīt failu

@@ -1,4 +0,0 @@
import Human from '@/game/creatures/human'
import Player from '@/game/creatures/player'
import Inazuma from '@/game/creatures/characters/inazuma'
export { Human, Player, Inazuma }

+ 1
- 2
src/game/creatures/characters/inazuma.ts Parādīt failu

@@ -92,7 +92,6 @@ export default class Inazuma extends Creature {
)) ))


this.addVoreContainer(stomach) this.addVoreContainer(stomach)

this.ai = null
this.ai = new VoreAI(this)
} }
} }

+ 39
- 0
src/game/creatures/monsters/slime.ts Parādīt failu

@@ -0,0 +1,39 @@
import { VoreAI } from '@/game/ai'
import { DamageType, Side, Stat, StatDamageFormula, Vigor } from '@/game/combat'
import { Creature } from '@/game/creature'
import { ImproperNoun, ObjectPronouns } from '@/game/language'
import { anyVore, Goo } from '@/game/vore'

export default class Slime extends Creature {
constructor () {
super(
new ImproperNoun("slime", "slimes"),
new ImproperNoun("slime", "slimes"),
ObjectPronouns,
{
Power: 20,
Toughness: 20,
Agility: 5,
Reflexes: 5,
Charm: 5,
Willpower: 5
},
anyVore,
anyVore,
50
)

const gooContainer = new Goo(
this,
3,
new StatDamageFormula([
{ fraction: 1, stat: Stat.Toughness, type: DamageType.Acid, target: Vigor.Health }
])
)

this.addVoreContainer(gooContainer)

this.side = Side.Monsters
this.ai = new VoreAI(this)
}
}

+ 3
- 0
src/game/creatures/player.ts Parādīt failu

@@ -4,6 +4,7 @@ import { Damage, DamageType, Vigor, ConstantDamageFormula } from '@/game/combat'
import { Stomach, Bowels, anyVore, Cock, Balls, Breasts, InnerBladder, Slit, Womb, biconnectContainers } from '@/game/vore' import { Stomach, Bowels, anyVore, Cock, Balls, Breasts, InnerBladder, Slit, Womb, biconnectContainers } from '@/game/vore'
import { AttackAction } from '@/game/combat/actions' import { AttackAction } from '@/game/combat/actions'
import { RavenousPerk, BellyBulwakPerk, FlauntPerk } from '@/game/combat/perks' import { RavenousPerk, BellyBulwakPerk, FlauntPerk } from '@/game/combat/perks'
import { VoreAI } from "../ai"


export default class Player extends Creature { export default class Player extends Creature {
constructor () { constructor () {
@@ -23,5 +24,7 @@ export default class Player extends Creature {
this.addVoreContainer(stomach) this.addVoreContainer(stomach)


this.perspective = POV.Second this.perspective = POV.Second

this.ai = new VoreAI(this)
} }
} }

+ 35
- 39
src/game/maps/town.ts Parādīt failu

@@ -1,7 +1,6 @@
import { Place, Choice, Direction, World } from '@/game/world' import { Place, Choice, Direction, World } from '@/game/world'
import { ProperNoun, ImproperNoun, MalePronouns, FemalePronouns, TheyPronouns } from '@/game/language' import { ProperNoun, ImproperNoun, MalePronouns, FemalePronouns, TheyPronouns } from '@/game/language'
import { Encounter, Stat, Damage, DamageType, Vigor, Side } from '@/game/combat' import { Encounter, Stat, Damage, DamageType, Vigor, Side } from '@/game/combat'
import * as Creatures from '@/game/creatures'
import * as Items from '@/game/items' import * as Items from '@/game/items'
import { LogLine, nilLog, LogLines } from '@/game/interface' import { LogLine, nilLog, LogLines } from '@/game/interface'
import { Creature } from '@/game/creature' import { Creature } from '@/game/creature'
@@ -10,9 +9,12 @@ import { InstantDigestionEffect, SurrenderEffect } from '@/game/combat/effects'
import moment from 'moment' import moment from 'moment'
import { VoreAI } from '@/game/ai' import { VoreAI } from '@/game/ai'
import { DeliciousPerk } from '@/game/combat/perks' import { DeliciousPerk } from '@/game/combat/perks'
import Inazuma from '../creatures/characters/inazuma'
import Human from '../creatures/human'
import Slime from '../creatures/monsters/slime'


function makeParty (): Creature[] { function makeParty (): Creature[] {
const fighter = new Creatures.Human(new ProperNoun("Redgar"), MalePronouns, {
const fighter = new Human(new ProperNoun("Redgar"), MalePronouns, {
stats: { stats: {
Toughness: 20, Toughness: 20,
Power: 20, Power: 20,
@@ -24,7 +26,7 @@ function makeParty (): Creature[] {
}) })
fighter.title = "Lv. 6 Fighter" fighter.title = "Lv. 6 Fighter"
fighter.equip(new Items.Sword(), Items.EquipmentSlot.MainHand) fighter.equip(new Items.Sword(), Items.EquipmentSlot.MainHand)
const rogue = new Creatures.Human(new ProperNoun('Lidda'), FemalePronouns, {
const rogue = new Human(new ProperNoun('Lidda'), FemalePronouns, {
stats: { stats: {
Toughness: 10, Toughness: 10,
Power: 15, Power: 15,
@@ -36,7 +38,7 @@ function makeParty (): Creature[] {
}) })
rogue.title = "Lv. 5 Rogue" rogue.title = "Lv. 5 Rogue"
rogue.equip(new Items.Dagger(), Items.EquipmentSlot.MainHand) rogue.equip(new Items.Dagger(), Items.EquipmentSlot.MainHand)
const wizard = new Creatures.Human(new ProperNoun('Mialee'), FemalePronouns, {
const wizard = new Human(new ProperNoun('Mialee'), FemalePronouns, {
stats: { stats: {
Toughness: 10, Toughness: 10,
Power: 10, Power: 10,
@@ -48,7 +50,7 @@ function makeParty (): Creature[] {
}) })
wizard.title = "Lv. 6 Wizard" wizard.title = "Lv. 6 Wizard"
wizard.equip(new Items.Wand(), Items.EquipmentSlot.MainHand) wizard.equip(new Items.Wand(), Items.EquipmentSlot.MainHand)
const cleric = new Creatures.Human(new ProperNoun('Jozan'), MalePronouns, {
const cleric = new Human(new ProperNoun('Jozan'), MalePronouns, {
stats: { stats: {
Toughness: 15, Toughness: 15,
Power: 15, Power: 15,
@@ -75,26 +77,6 @@ export const Town = (): Place => {
"Where weird stuff happens" "Where weird stuff happens"
) )


const westAve = new Place(
new ImproperNoun('West Avenue'),
"Streets of Sim City"
)

const northAve = new Place(
new ImproperNoun('North Avenue'),
"Streets of Sim City"
)

const eastAve = new Place(
new ImproperNoun('East Avenue'),
"Streets of Sim City"
)

const southAve = new Place(
new ImproperNoun('South Avenue'),
"Streets of Sim City"
)

const alley = new Place( const alley = new Place(
new ImproperNoun('alley'), new ImproperNoun('alley'),
"A spooky alley" "A spooky alley"
@@ -123,7 +105,7 @@ export const Town = (): Place => {
const bossEncounters = [ const bossEncounters = [
new Encounter( new Encounter(
{ name: "Inazuma", intro: () => nilLog }, { name: "Inazuma", intro: () => nilLog },
makeParty().concat([new Creatures.Inazuma()])
makeParty().concat([new Inazuma()])
) )
] ]


@@ -174,12 +156,12 @@ export const Town = (): Place => {
) )
) )


westAve.choices.push(
square.choices.push(
new Choice( new Choice(
"Eat someone", "Eat someone",
"Slurp", "Slurp",
(world, executor) => { (world, executor) => {
const snack = new Creatures.Human(new ProperNoun(["Snack", "Treat", "Tasty", "Dinner", "Appetizer"][Math.floor(Math.random() * 5)]), [MalePronouns, FemalePronouns, TheyPronouns][Math.floor(Math.random() * 3)])
const snack = new Human(new ProperNoun(["Snack", "Treat", "Tasty", "Dinner", "Appetizer"][Math.floor(Math.random() * 5)]), [MalePronouns, FemalePronouns, TheyPronouns][Math.floor(Math.random() * 3)])
snack.applyEffect(new SurrenderEffect()) snack.applyEffect(new SurrenderEffect())
const options = executor.validActions(snack).filter(action => action instanceof DevourAction) const options = executor.validActions(snack).filter(action => action instanceof DevourAction)
return options[Math.floor(options.length * Math.random())].execute(executor, snack) return options[Math.floor(options.length * Math.random())].execute(executor, snack)
@@ -187,12 +169,12 @@ export const Town = (): Place => {
) )
) )


westAve.choices.push(
square.choices.push(
new Choice( new Choice(
"Fight someone", "Fight someone",
"Ow", "Ow",
(world) => { (world) => {
const enemy = new Creatures.Human(new ProperNoun("Nerd"), TheyPronouns)
const enemy = new Human(new ProperNoun("Nerd"), TheyPronouns)
enemy.side = Side.Monsters enemy.side = Side.Monsters
enemy.ai = new VoreAI(enemy) enemy.ai = new VoreAI(enemy)
enemy.equip(new Items.Sword(), Items.EquipmentSlot.MainHand) enemy.equip(new Items.Sword(), Items.EquipmentSlot.MainHand)
@@ -210,12 +192,12 @@ export const Town = (): Place => {
) )
) )


westAve.choices.push(
square.choices.push(
new Choice( new Choice(
"Recruit someone", "Recruit someone",
"Not ow", "Not ow",
(world) => { (world) => {
const ally = new Creatures.Human(new ProperNoun("Ally"), TheyPronouns)
const ally = new Human(new ProperNoun("Ally"), TheyPronouns)
ally.side = Side.Heroes ally.side = Side.Heroes
ally.ai = new VoreAI(ally) ally.ai = new VoreAI(ally)
ally.equip(new Items.Sword(), Items.EquipmentSlot.MainHand) ally.equip(new Items.Sword(), Items.EquipmentSlot.MainHand)
@@ -339,6 +321,25 @@ export const Town = (): Place => {
) )
) )


woods.choices.push(
new Choice(
"Fight a slime",
"Go fight a slime",
(world, executor) => {
const enemy = new Slime()
const encounter = new Encounter(
{
name: "Fight some tasty nerd",
intro: () => new LogLine(`A slime draws near!`)
},
[world.player, enemy].concat(world.party)
)
world.encounter = encounter
return nilLog
}
)
)

debug.choices.push( debug.choices.push(
new Choice( new Choice(
"Add money", "Add money",
@@ -352,14 +353,9 @@ export const Town = (): Place => {


home.biconnect(Direction.South, debug) home.biconnect(Direction.South, debug)
debug.biconnect(Direction.South, bosses) debug.biconnect(Direction.South, bosses)
home.biconnect(Direction.North, westAve)
westAve.biconnect(Direction.West, westRoad)
westAve.biconnect(Direction.North, alley)
home.biconnect(Direction.North, square)
westRoad.biconnect(Direction.South, woods) westRoad.biconnect(Direction.South, woods)
square.biconnect(Direction.East, eastAve)
square.biconnect(Direction.West, westAve)
square.biconnect(Direction.North, northAve)
square.biconnect(Direction.South, southAve)
square.biconnect(Direction.West, westRoad)


return home return home
} }

+ 19
- 2
src/game/vore.ts Parādīt failu

@@ -13,7 +13,8 @@ export enum VoreType {
Unbirth = "Unbirthing", Unbirth = "Unbirthing",
Breast = "Breast Vore", Breast = "Breast Vore",
Bladder = "Bladder Vore", Bladder = "Bladder Vore",
Tail = "Tail Vore"
Tail = "Tail Vore",
Goo = "Goo Vore"
} }


export const anyVore = new Set([ export const anyVore = new Set([
@@ -23,7 +24,8 @@ export const anyVore = new Set([
VoreType.Unbirth, VoreType.Unbirth,
VoreType.Breast, VoreType.Breast,
VoreType.Bladder, VoreType.Bladder,
VoreType.Tail
VoreType.Tail,
VoreType.Goo
]) ])


export interface Container extends Actionable { export interface Container extends Actionable {
@@ -408,6 +410,21 @@ export class Tail extends NormalVoreContainer {
} }
} }


export class Goo extends NormalVoreContainer {
fluidName = new Noun("goo")
fluidColor = "#66ee66";

constructor (owner: Creature, capacity: number, damage: DamageFormula) {
super(new ImproperNoun('goo', 'goo').all, owner, new Set([VoreType.Goo]), capacity, damage)
}

tickLine (user: Creature, target: Creature, args: { damage: Damage }) {
return new RandomEntry(
new LogLine(`${user.name.capital} ${user.name.conjugate(Words.Clench)} ${target.name.objective} in ${user.pronouns.possessive} ${this.name} for `, args.damage.renderShort(), `.`)
)
}
}

export class Cock extends NormalVoreContainer { export class Cock extends NormalVoreContainer {
fluidName = new Noun("cum") fluidName = new Noun("cum")




Notiek ielāde…
Atcelt
Saglabāt