Feast 2.0!
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

136 lines
6.5 KiB

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