瀏覽代碼

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 4 年之前
父節點
當前提交
5fe4205711
共有 11 個檔案被更改,包括 126 行新增55 行删除
  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 查看文件

@@ -4,6 +4,7 @@
<div id="main-area">
<transition name="component-fade" mode='out-in'>
<component
@control="control"
@profile="profile"
@exit="$data.profileSubject = null"
@give-in="gameOver()"
@@ -23,7 +24,6 @@ import Header from '@/components/Header.vue'
import Combat from '@/components/Combat.vue'
import Explore from '@/components/Explore.vue'
import Profile from '@/components/Profile.vue'
import * as Creatures from '@/game/creatures'
import * as Items from '@/game/items'
import { Creature } from '@/game/creature'
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 moment from 'moment'
import { Town } from '@/game/maps/town'
import Player from './game/creatures/player'

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

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

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



+ 1
- 1
src/components/Combat.vue 查看文件

@@ -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) {
this.executedLeft(this.encounter.currentMove.ai.decide(this.encounter.currentMove, this.encounter))
} else {


+ 1
- 3
src/components/Statblock.vue 查看文件

@@ -57,9 +57,7 @@
</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>
</div>
</div>


+ 14
- 0
src/game/ai.ts 查看文件

@@ -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
*/


+ 4
- 2
src/game/creature.ts 查看文件

@@ -4,7 +4,7 @@ import { LogEntry, LogLines, LogLine } from '@/game/interface'
import { VoreContainer, VoreType, Container } from '@/game/vore'
import { Item, EquipmentSlot, Equipment, ItemKind, Currency } from '@/game/items'
import { PassAction } from '@/game/combat/actions'
import { AI } from '@/game/ai'
import { AI, RandomAI } from '@/game/ai'
import { Entity, Resistances } from '@/game/entity'
import { Perk } from '@/game/combat/perks'
import { VoreRelay } from '@/game/events'
@@ -60,7 +60,7 @@ export class Creature extends Entity {
side: Side;
title = "Lv. 1 Creature";
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) {
super(name, kind, pronouns)
@@ -76,6 +76,8 @@ export class Creature extends Entity {
/* eslint-disable-next-line */
const self = this

this.ai = new RandomAI(this)

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


+ 0
- 4
src/game/creatures.ts 查看文件

@@ -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 查看文件

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

this.addVoreContainer(stomach)

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

+ 39
- 0
src/game/creatures/monsters/slime.ts 查看文件

@@ -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 查看文件

@@ -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 { AttackAction } from '@/game/combat/actions'
import { RavenousPerk, BellyBulwakPerk, FlauntPerk } from '@/game/combat/perks'
import { VoreAI } from "../ai"

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

this.perspective = POV.Second

this.ai = new VoreAI(this)
}
}

+ 35
- 39
src/game/maps/town.ts 查看文件

@@ -1,7 +1,6 @@
import { Place, Choice, Direction, World } from '@/game/world'
import { ProperNoun, ImproperNoun, MalePronouns, FemalePronouns, TheyPronouns } from '@/game/language'
import { Encounter, Stat, Damage, DamageType, Vigor, Side } from '@/game/combat'
import * as Creatures from '@/game/creatures'
import * as Items from '@/game/items'
import { LogLine, nilLog, LogLines } from '@/game/interface'
import { Creature } from '@/game/creature'
@@ -10,9 +9,12 @@ import { InstantDigestionEffect, SurrenderEffect } from '@/game/combat/effects'
import moment from 'moment'
import { VoreAI } from '@/game/ai'
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[] {
const fighter = new Creatures.Human(new ProperNoun("Redgar"), MalePronouns, {
const fighter = new Human(new ProperNoun("Redgar"), MalePronouns, {
stats: {
Toughness: 20,
Power: 20,
@@ -24,7 +26,7 @@ function makeParty (): Creature[] {
})
fighter.title = "Lv. 6 Fighter"
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: {
Toughness: 10,
Power: 15,
@@ -36,7 +38,7 @@ function makeParty (): Creature[] {
})
rogue.title = "Lv. 5 Rogue"
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: {
Toughness: 10,
Power: 10,
@@ -48,7 +50,7 @@ function makeParty (): Creature[] {
})
wizard.title = "Lv. 6 Wizard"
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: {
Toughness: 15,
Power: 15,
@@ -75,26 +77,6 @@ export const Town = (): Place => {
"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(
new ImproperNoun('alley'),
"A spooky alley"
@@ -123,7 +105,7 @@ export const Town = (): Place => {
const bossEncounters = [
new Encounter(
{ 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(
"Eat someone",
"Slurp",
(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())
const options = executor.validActions(snack).filter(action => action instanceof DevourAction)
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(
"Fight someone",
"Ow",
(world) => {
const enemy = new Creatures.Human(new ProperNoun("Nerd"), TheyPronouns)
const enemy = new Human(new ProperNoun("Nerd"), TheyPronouns)
enemy.side = Side.Monsters
enemy.ai = new VoreAI(enemy)
enemy.equip(new Items.Sword(), Items.EquipmentSlot.MainHand)
@@ -210,12 +192,12 @@ export const Town = (): Place => {
)
)

westAve.choices.push(
square.choices.push(
new Choice(
"Recruit someone",
"Not ow",
(world) => {
const ally = new Creatures.Human(new ProperNoun("Ally"), TheyPronouns)
const ally = new Human(new ProperNoun("Ally"), TheyPronouns)
ally.side = Side.Heroes
ally.ai = new VoreAI(ally)
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(
new Choice(
"Add money",
@@ -352,14 +353,9 @@ export const Town = (): Place => {

home.biconnect(Direction.South, debug)
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)
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
}

+ 19
- 2
src/game/vore.ts 查看文件

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

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

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 {
fluidName = new Noun("cum")



Loading…
取消
儲存