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.
 
 
 
 
 

161 wiersze
4.5 KiB

  1. import { DamageType, Damage, Combatant, Stats, Action, Vigor, VoreStats, VoreStat, Stat } from './combat'
  2. import { Noun, Pronoun } from './language'
  3. import { LogEntry, LogLine } from './interface'
  4. import { Vore, Container, VoreType } from './vore'
  5. export enum POV {First, Third}
  6. export interface Entity {
  7. name: Noun;
  8. pronouns: Pronoun;
  9. perspective: POV;
  10. }
  11. export interface Mortal extends Entity {
  12. vigors: {[key in Vigor]: number};
  13. maxVigors: {[key in Vigor]: number};
  14. disabled: boolean;
  15. resistances: Map<DamageType, number>;
  16. takeDamage: (damage: Damage) => void;
  17. stats: Stats;
  18. baseStats: Stats;
  19. status: string;
  20. destroy: () => LogEntry;
  21. }
  22. export class Creature extends Vore implements Combatant {
  23. vigors = {
  24. [Vigor.Health]: 100,
  25. [Vigor.Stamina]: 100,
  26. [Vigor.Resolve]: 100
  27. }
  28. maxVigors = {
  29. [Vigor.Health]: 100,
  30. [Vigor.Stamina]: 100,
  31. [Vigor.Resolve]: 100
  32. }
  33. baseStats: Stats
  34. voreStats: VoreStats
  35. get disabled (): boolean {
  36. return Object.values(this.vigors).some(val => val <= 0)
  37. }
  38. resistances: Map<DamageType, number> = new Map()
  39. perspective: POV = POV.Third
  40. containers: Array<Container> = []
  41. actions: Array<Action> = [];
  42. otherActions: Array<Action> = [];
  43. get bulk (): number {
  44. return this.voreStats.Mass + this.containers.reduce((total, conatiner) => { return total + conatiner.contents.reduce((total, prey) => total + prey.voreStats.Bulk, 0) }, 0)
  45. }
  46. containedIn: Container|null = null;
  47. constructor (public name: Noun, public pronouns: Pronoun, public stats: Stats, public preyPrefs: Set<VoreType>, public predPrefs: Set<VoreType>, mass: number) {
  48. super()
  49. const containers = this.containers
  50. this.baseStats = stats
  51. this.voreStats = {
  52. get [VoreStat.Bulk] () {
  53. console.log(containers)
  54. return containers.reduce(
  55. (total: number, container: Container) => {
  56. return total + container.contents.reduce(
  57. (total: number, prey: Vore) => {
  58. return total + prey.voreStats.Bulk
  59. },
  60. 0
  61. ) + container.digested.reduce(
  62. (total: number, prey: Vore) => {
  63. return total + prey.voreStats.Bulk
  64. },
  65. 0
  66. )
  67. },
  68. this.Mass
  69. )
  70. },
  71. [VoreStat.Mass]: mass,
  72. get [VoreStat.PreyCount] () {
  73. return containers.reduce(
  74. (total: number, container: Container) => {
  75. return total + container.contents.reduce(
  76. (total: number, prey: Vore) => {
  77. return total + 1 + prey.voreStats[VoreStat.PreyCount]
  78. },
  79. 0
  80. )
  81. },
  82. 0
  83. )
  84. }
  85. }
  86. }
  87. toString (): string {
  88. return this.name.toString()
  89. }
  90. takeDamage (damage: Damage): LogEntry {
  91. damage.damages.forEach(instance => {
  92. const resistance: number|undefined = this.resistances.get(instance.type)
  93. if (resistance !== undefined) {
  94. if (instance.target in Vigor) {
  95. this.vigors[instance.target as Vigor] -= instance.amount * resistance
  96. } else if (instance.target in Stat) {
  97. this.stats[instance.target as Stat] -= instance.amount * resistance
  98. }
  99. } else {
  100. if (instance.target in Vigor) {
  101. this.vigors[instance.target as Vigor] -= instance.amount
  102. } else if (instance.target in Stat) {
  103. this.stats[instance.target as Stat] -= instance.amount
  104. }
  105. }
  106. })
  107. if (this.vigors.Health <= 0) {
  108. return this.destroy()
  109. } else {
  110. return new LogLine()
  111. }
  112. }
  113. get status (): string {
  114. if (this.vigors[Vigor.Health] <= 0) {
  115. return "Dead"
  116. }
  117. if (this.vigors[Vigor.Stamina] <= 0) {
  118. return "Unconscious"
  119. }
  120. if (this.vigors[Vigor.Resolve] <= 0) {
  121. return "Broken"
  122. }
  123. if (this.containedIn !== null) {
  124. return "Devoured"
  125. }
  126. return "Normal"
  127. }
  128. validActions (target: Creature): Array<Action> {
  129. let choices = this.actions.concat(this.containers.flatMap(container => container.actions)).concat(target.otherActions)
  130. if (this.containedIn !== null) {
  131. choices = choices.concat(this.containedIn.actions)
  132. }
  133. return choices.filter(action => {
  134. return action.allowed(this, target)
  135. })
  136. }
  137. destroy (): LogEntry {
  138. return super.destroy()
  139. }
  140. }