ソースを参照

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")



読み込み中…
キャンセル
保存