Feast 2.0!
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 
 
 

149 Zeilen
7.3 KiB

  1. import { Creature, POV, Entity } from '../entity'
  2. import { Stat, Damage, DamageType, TransferAction, Vigor, StatTest, FeedAction, DigestAction, EatenAction, AttackAction, DamageFormula, ConstantDamageFormula } from '../combat'
  3. import { ProperNoun, TheyPronouns, ImproperNoun, POVPair, FemalePronouns, POVPairArgs } from '../language'
  4. import { VoreType, Stomach, InnerStomach, Container, Bowels } from '../vore'
  5. import { LogLine, LogLines, LogEntry, FAElem, CompositeLog, ImgElem } from '../interface'
  6. import { Wolf } from '../creatures'
  7. class BellyCrushAction extends AttackAction {
  8. successLines = new POVPairArgs<Entity, Entity, { damage: Damage }>([
  9. [[POV.First, POV.Third], (user, target, args) => new CompositeLog(new LogLine(
  10. `You crush on ${target.name} with your belly for `,
  11. args.damage.renderShort()
  12. ), new ImgElem('./media/cafat/images/belly-crush.webp'))],
  13. [[POV.Third, POV.First], (user, target, args) => new CompositeLog(new LogLine(
  14. `${user.name.capital} crushes on you with ${user.pronouns.possessive} belly for `,
  15. args.damage.renderShort()
  16. ), new ImgElem('./media/cafat/images/belly-crush.webp'))],
  17. [[POV.Third, POV.Third], (user, target, args) => new CompositeLog(new LogLine(
  18. `${user.name.capital} crushes on ${target.name} with ${user.pronouns.possessive} belly for `,
  19. args.damage.renderShort()
  20. ), new ImgElem('./media/cafat/images/belly-crush.webp'))]
  21. ])
  22. constructor (_damage: Damage) {
  23. super({
  24. calc (user, target) { return _damage.scale(user.bulk / 25) },
  25. describe (user, target) { return new LogLine('Deal ', _damage.scale(user.bulk / 25).renderShort(), ` with your ${user.bulk} `, new FAElem('fas fa-weight-hanging')) }
  26. })
  27. this.name = 'Belly Crush'
  28. this.desc = 'Use your weight!'
  29. }
  30. describe (user: Creature, target: Creature): LogEntry {
  31. return new LogLine(`Crush ${target.name} under your gut. `, this.damage.describe(user, target))
  32. }
  33. }
  34. class BelchAction extends AttackAction {
  35. successLines = new POVPairArgs<Entity, Entity, { damage: Damage }>([
  36. [[POV.First, POV.Third], (user, target, args) => new CompositeLog(new LogLine(
  37. `You belch on ${target.name} for `,
  38. args.damage.renderShort()
  39. ), new ImgElem('./media/cafat/images/belch.webp'))],
  40. [[POV.Third, POV.First], (user, target, args) => new CompositeLog(new LogLine(
  41. `${user.name.capital} belches on you for `,
  42. args.damage.renderShort()
  43. ), new ImgElem('./media/cafat/images/belch.webp'))],
  44. [[POV.Third, POV.Third], (user, target, args) => new CompositeLog(new LogLine(
  45. `${user.name.capital} belches on ${target.name} for `,
  46. args.damage.renderShort()
  47. ), new ImgElem('./media/cafat/images/belch.webp'))]
  48. ])
  49. constructor (damage: Damage) {
  50. super(new ConstantDamageFormula(damage))
  51. this.name = 'Belch'
  52. this.desc = 'Drain your foe\'s willpower with a solid BELCH'
  53. }
  54. }
  55. class CrushAction extends EatenAction {
  56. lines: POVPair<Entity, Entity> = new POVPair([
  57. [[POV.First, POV.Third], (user, target) => new LogLine(`You crush ${target.name} `, new FAElem('fas fa-skull'))],
  58. [[POV.Third, POV.First], (user, target) => new CompositeLog(new LogLine(`${user.name.capital} crushes you; ${user.pronouns.subjective} ${user.pronouns.isPlural ? 'belch' : 'belches'} as ${user.pronouns.possessive} gut lets out a fatal CRUNCH `, new FAElem('fas fa-skull')), new ImgElem('./media/cafat/images/crunch.webp'))],
  59. [[POV.Third, POV.Third], (user, target) => new LogLine(`${user.name.capital} crushes ${target.name}; ${user.pronouns.subjective} ${user.pronouns.isPlural ? 'belch' : 'belches'} as ${user.pronouns.possessive} gut lets out a fatal CRUNCH `, new FAElem('fas fa-skull'))]
  60. ])
  61. private damage: Damage = new Damage(
  62. { amount: 99, type: DamageType.Crush, target: Vigor.Health }
  63. )
  64. constructor (container: Container) {
  65. super(container, "Crush", "Crush 'em!")
  66. this.desc = "Crush somebody in your gut"
  67. }
  68. execute (user: Creature, target: Creature): LogEntry {
  69. target.takeDamage(this.damage)
  70. return this.lines.run(user, target)
  71. }
  72. describe (user: Creature, target: Creature): LogEntry {
  73. return new LogLine(`Crush ${target.name} in your ${this.container.name} for massive, unavoidable damage.`)
  74. }
  75. }
  76. export class Cafat extends Creature {
  77. constructor () {
  78. super(new ProperNoun('Cafat'), [TheyPronouns, FemalePronouns][Math.floor(Math.random() * 2)], {
  79. [Stat.Toughness]: 30,
  80. [Stat.Power]: 30,
  81. [Stat.Speed]: 15,
  82. [Stat.Willpower]: 25,
  83. [Stat.Charm]: 20
  84. }, new Set([VoreType.Oral, VoreType.Anal]), new Set([VoreType.Oral, VoreType.Anal]), 150)
  85. this.vigors.Health = 200
  86. this.maxVigors.Health = 200
  87. this.vigors.Stamina = 250
  88. this.maxVigors.Stamina = 250
  89. this.vigors.Resolve = 150
  90. this.maxVigors.Resolve = 150
  91. const stomach = new Stomach(this, 100, new Damage(
  92. { amount: 20, type: DamageType.Acid, target: Vigor.Health },
  93. { amount: 10, type: DamageType.Crush, target: Vigor.Stamina },
  94. { amount: 10, type: DamageType.Dominance, target: Vigor.Resolve }
  95. ))
  96. stomach.name = new ImproperNoun("upper stomach", "upper stomachs").all
  97. this.containers.push(stomach)
  98. const lowerStomach = new InnerStomach(this, 100, new Damage(
  99. { amount: 40, type: DamageType.Acid, target: Vigor.Health },
  100. { amount: 20, type: DamageType.Crush, target: Vigor.Stamina },
  101. { amount: 20, type: DamageType.Dominance, target: Vigor.Resolve }
  102. ), stomach)
  103. lowerStomach.name = new ImproperNoun("lower stomach", "lower stomachs").all
  104. stomach.consumeLines = new POVPair([
  105. [[POV.First, POV.Third], (user, target) => new LogLines(`You devour ${target.name}`)],
  106. [[POV.Third, POV.First], (user, target) => new CompositeLog(new LogLines(`${user.name.capital} devours you`), new ImgElem('./media/cafat/images/stomach.webp'))],
  107. [[POV.Third, POV.Third], (user, target) => new LogLines(`${user.name.capital} munches ${target.name.capital}`)]
  108. ])
  109. const crush = new CrushAction(lowerStomach)
  110. lowerStomach.actions.push(crush)
  111. this.containers.push(lowerStomach)
  112. const transfer = new TransferAction(stomach, lowerStomach)
  113. transfer.lines = new POVPairArgs([
  114. [[POV.First, POV.Third], (user, target, args) => new LogLine(`You squeeze ${target.name} from your ${args.from.name} to your ${args.to.name}`)],
  115. [[POV.Third, POV.First], (user, target, args) => new CompositeLog(new LogLine(`You're squeezed from ${user.name}'s ${args.from.name} to ${user.pronouns.possessive} ${args.to.name}`), new ImgElem('./media/cafat/images/lower-stomach.webp'))],
  116. [[POV.Third, POV.Third], (user, target, args) => new LogLine(`${user.name} squeezes ${target.name} from ${user.pronouns.possessive} ${args.from.name} to ${user.pronouns.possessive} ${args.to.name}`)]
  117. ])
  118. this.actions.push(transfer)
  119. this.actions.push(new TransferAction(lowerStomach, stomach))
  120. this.actions.push(new AttackAction(new ConstantDamageFormula(new Damage({ amount: 40, type: DamageType.Crush, target: Vigor.Health }))))
  121. this.actions.push(new BellyCrushAction(new Damage({ amount: 10, type: DamageType.Crush, target: Vigor.Health }, { amount: 10, type: DamageType.Dominance, target: Vigor.Resolve })))
  122. this.actions.push(new BelchAction(new Damage(
  123. { amount: 100, target: Vigor.Resolve, type: DamageType.Acid }
  124. )))
  125. this.otherActions.push(new FeedAction(stomach))
  126. }
  127. }