Feast 2.0!
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 
 

150 строки
4.1 KiB

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