Feast 2.0!
Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 
 
 

148 wiersze
7.2 KiB

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