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.
 
 
 
 
 

176 wiersze
5.3 KiB

  1. import { StatusEffect, Damage, DamageType, Action, Condition, Vigor } from '../combat'
  2. import { DynText, LiveText, ToBe, Verb } from '../language'
  3. import { Creature } from "../creature"
  4. import { LogLine, LogEntry, LogLines, FAElem, nilLog } from '../interface'
  5. export class InstantKillEffect extends StatusEffect {
  6. constructor () {
  7. super('Instant Kill', 'Instant kill!', 'fas fa-skull')
  8. }
  9. onApply (creature: Creature) {
  10. creature.vigors.Health = 0
  11. creature.removeEffect(this)
  12. return new LogLines(
  13. new LogLine(
  14. `${creature.name.capital} ${creature.name.conjugate(new ToBe())} killed instantly! `,
  15. new FAElem('fas fa-skull')
  16. ),
  17. creature.takeDamage(new Damage())
  18. )
  19. }
  20. }
  21. export class StunEffect extends StatusEffect {
  22. constructor (private duration: number) {
  23. super('Stun', 'Cannot act!', 'fas fa-sun')
  24. this.desc = new DynText('Stunned for your next ', new LiveText(this, x => x.duration), ' actions!')
  25. }
  26. get topLeft () {
  27. return this.duration.toString()
  28. }
  29. onApply (creature: Creature) {
  30. return new LogLine(`${creature.name.capital} ${creature.name.conjugate(new ToBe())} is stunned!`)
  31. }
  32. onRemove (creature: Creature) {
  33. return new LogLine(`${creature.name.capital} ${creature.name.conjugate(new ToBe())} no longer stunned.`)
  34. }
  35. preTurn (creature: Creature): { prevented: boolean; log: LogEntry } {
  36. if (--this.duration <= 0) {
  37. return {
  38. prevented: true,
  39. log: new LogLines(
  40. `${creature.name.capital} ${creature.name.conjugate(new ToBe())} stunned! ${creature.pronouns.capital.subjective} can't move.`,
  41. creature.removeEffect(this)
  42. )
  43. }
  44. } else {
  45. return {
  46. prevented: true,
  47. log: new LogLines(
  48. `${creature.name.capital} ${creature.name.conjugate(new ToBe())} stunned! ${creature.pronouns.capital.subjective} can't move!`
  49. )
  50. }
  51. }
  52. }
  53. }
  54. export class DamageTypeResistanceEffect extends StatusEffect {
  55. constructor (private damageTypes: DamageType[], private amount: number) {
  56. super('Resistance', 'Block ' + ((1 - amount) * 100).toFixed() + '% of these damage types: ' + damageTypes.join(", "), 'fas fa-shield-alt')
  57. }
  58. onApply (creature: Creature) {
  59. return new LogLine(`${creature.name.capital} ${creature.name.conjugate(new Verb('gain'))} a shield!`)
  60. }
  61. onRemove (creature: Creature) {
  62. return new LogLine(`${creature.name.capital} ${creature.name.conjugate(new Verb('lose'))} ${creature.pronouns.possessive} shield!`)
  63. }
  64. modResistance (type: DamageType, factor: number) {
  65. if (this.damageTypes.includes(type)) {
  66. return factor * this.amount
  67. } else {
  68. return factor
  69. }
  70. }
  71. }
  72. export class PredatorCounterEffect extends StatusEffect {
  73. constructor (private devour: Action, private chance: number) {
  74. super('Predatory Counter', 'Eat them back', 'fas fa-redo')
  75. this.desc = new DynText(new LiveText(this, x => (x.chance * 100).toFixed(0)), '% chance to devour your attackers')
  76. }
  77. preAttack (creature: Creature, attacker: Creature) {
  78. if (this.devour.allowed(creature, attacker) && Math.random() < this.chance) {
  79. return {
  80. prevented: true,
  81. log: new LogLines(
  82. `${creature.name.capital} ${creature.name.conjugate(new Verb('surprise'))} ${attacker.name.objective} and ${creature.name.conjugate(new Verb('try', 'tries'))} to devour ${attacker.pronouns.objective}!`,
  83. this.devour.execute(creature, attacker)
  84. )
  85. }
  86. } else {
  87. return { prevented: false, log: nilLog }
  88. }
  89. }
  90. }
  91. export class UntouchableEffect extends StatusEffect {
  92. constructor () {
  93. super('Untouchable', 'Cannot be attacked', 'fas fa-times')
  94. }
  95. preAttack (creature: Creature, attacker: Creature) {
  96. return {
  97. prevented: true,
  98. log: new LogLine(`${creature.name.capital} cannot be attacked.`)
  99. }
  100. }
  101. }
  102. export class DazzlingEffect extends StatusEffect {
  103. constructor (private conditions: Condition[]) {
  104. super('Dazzling', 'Stuns enemies who try to affect this creature', 'fas fa-spinner')
  105. }
  106. preReceiveAction (creature: Creature, attacker: Creature) {
  107. if (this.conditions.every(cond => cond.allowed(creature, attacker))) {
  108. attacker.applyEffect(new StunEffect(1))
  109. return {
  110. prevented: true,
  111. log: new LogLine(`${attacker.name.capital} can't act against ${creature.name.objective}!`)
  112. }
  113. } else {
  114. return {
  115. prevented: false,
  116. log: nilLog
  117. }
  118. }
  119. }
  120. }
  121. export class SurrenderEffect extends StatusEffect {
  122. constructor () {
  123. super('Surrendered', 'This creature has given up, and will fail most tests', 'fas fa-flag')
  124. }
  125. onApply (creature: Creature): LogEntry {
  126. creature.takeDamage(
  127. new Damage(
  128. { amount: creature.vigors.Resolve, target: Vigor.Resolve, type: DamageType.Pure }
  129. )
  130. )
  131. return new LogLine(
  132. `${creature.name.capital} ${creature.name.conjugate(new Verb('surrender'))}!`
  133. )
  134. }
  135. failTest (creature: Creature, opponent: Creature): { failed: boolean; log: LogEntry } {
  136. return {
  137. failed: true,
  138. log: nilLog
  139. }
  140. }
  141. }
  142. export class SizeEffect extends StatusEffect {
  143. constructor (private change: number) {
  144. super('Size-Shifted', 'This creature has changed in size', 'fas fa-ruler')
  145. }
  146. onApply (creature: Creature): LogLine {
  147. return new LogLine(`Smol`)
  148. }
  149. scale (scale: number): number {
  150. return scale * this.change
  151. }
  152. }