skills.ts 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. class Skill extends Initializing implements SkillDefinition{
  2. id:string;
  3. label: 'Label Missing';
  4. hidden: false;
  5. isDifficultyBased:boolean=false;
  6. e2s = Skill.e2sFunction();
  7. s2e = Skill.s2eFunction();
  8. dailyExpLimit:number|((levelAtStartOfDay:number)=>number)=0;
  9. //#region Static
  10. static get(skillId:string):Skill{
  11. const constantData = setup.skills[skillId];
  12. if(!constantData)
  13. return new NullSkill();
  14. let skill = new Skill();
  15. skill.init(constantData);
  16. skill.id = skillId;
  17. return skill;
  18. }
  19. static e2sFunction(factorEvery10Levels=2,factor=100){
  20. return function(n:number){
  21. const base = factorEvery10Levels ** 0.1;
  22. n += factor;
  23. return Math.floor(Math.logBase(n/100,base));
  24. }
  25. }
  26. static s2eFunction(factorEvery10Levels=2,factor=100){
  27. return function(n:number):number{
  28. const base = factorEvery10Levels ** 0.1;
  29. return Math.ceil(Math.pow(base,n) * factor) - factor;
  30. }
  31. }
  32. //#endregion
  33. experience2Skill(experience:number){return this.e2s(experience);}
  34. skill2Experience(skillLevel:number){return this.s2e(skillLevel);}
  35. get dailyExperienceSoftLimit():((levelAtStartOfDay:number)=>number){
  36. if(this.dailyExpLimit){
  37. if(typeof this.dailyExpLimit == "number"){
  38. const number = this.dailyExpLimit;
  39. return (n=>number);
  40. }
  41. return this.dailyExpLimit;
  42. }
  43. return (n=>this.skill2Experience(n + 1) - this.skill2Experience(n));
  44. }
  45. /**
  46. * How much experiences to gain depending on the experience already received today.
  47. * @param {SkillOfCharacter} skillData
  48. * @param {number} requestedExperienceIncrease
  49. * @returns {number}
  50. */
  51. skillGain(skillData: SkillOfCharacter, requestedExperienceIncrease:number):number{
  52. let experienceEffectiveGain = 0;
  53. const todaysStartExperience = skillData.experienceHistory.last();
  54. const todaysStartLevel = this.experience2Skill(todaysStartExperience);
  55. //const experienceRequiredToAdvanceOneLevel = this.skill2Experience(todaysStartLevel + 1) - this.skill2Experience(todaysStartLevel);
  56. const experienceWithoutPenalty = this.dailyExperienceSoftLimit(todaysStartLevel);
  57. let experienceGainedSoFarToday = skillData.experience - todaysStartExperience;
  58. const experienceToGainWithoutPenaltyLeft = Math.max(0,experienceWithoutPenalty - experienceGainedSoFarToday);
  59. const experienceToGainWithoutPenalty = Math.min(requestedExperienceIncrease,experienceToGainWithoutPenaltyLeft);
  60. experienceEffectiveGain += experienceToGainWithoutPenalty;
  61. experienceGainedSoFarToday += experienceToGainWithoutPenalty;
  62. requestedExperienceIncrease -= experienceToGainWithoutPenalty;
  63. const requestedTotalExperienceIncrease = experienceGainedSoFarToday + requestedExperienceIncrease;
  64. const factorOfBeingOverTarget = requestedTotalExperienceIncrease / experienceWithoutPenalty;
  65. const experienceGainWithPenalty = Math.ceil(requestedExperienceIncrease / factorOfBeingOverTarget);
  66. experienceEffectiveGain += experienceGainWithPenalty;
  67. return experienceEffectiveGain;
  68. }
  69. }
  70. class NullSkill extends Skill{
  71. }
  72. setup.Skill = Skill;
  73. setup.skills = {};
  74. setup.skills.agility = {
  75. label: 'Agility',
  76. hidden: true
  77. }
  78. setup.skills.charisma = {
  79. label: 'Charisma',
  80. hidden: true
  81. }
  82. setup.skills.chess = {
  83. label: 'Chess',
  84. e2s: Skill.e2sFunction(2.5),
  85. s2e: Skill.s2eFunction(2.5),
  86. image:'pc/skills/chess.webp'
  87. }
  88. setup.skills.computer = {
  89. label: 'Computer',
  90. image:'pc/skills/computer.webp'
  91. }
  92. setup.skills.dance = {
  93. label: 'Dancing',
  94. image:'pc/skills/dance.webp'
  95. }
  96. setup.skills.gaming = {
  97. label: 'Gaming',
  98. e2s: Skill.e2sFunction(1.5),
  99. s2e: Skill.s2eFunction(1.5),
  100. image:'pc/skills/gaming.webp'
  101. }
  102. setup.skills.gunnery = {
  103. label: 'Shooting (Gun)',
  104. e2s: Skill.e2sFunction(1.5),
  105. s2e: Skill.s2eFunction(1.5),
  106. image:'pc/skills/gunnery.webp'
  107. }
  108. setup.skills.iceskating = {
  109. label: 'Iceskating',
  110. hidden: true
  111. }
  112. setup.skills.inhibition = {
  113. label: 'Inhibition'
  114. }
  115. setup.skills.intelligence = {
  116. label: 'Intelligence',
  117. hidden: true
  118. }
  119. setup.skills.people = {
  120. label: 'People',
  121. hidden: true
  122. }
  123. setup.skills.perception = {
  124. label: 'Perception',
  125. hidden: true
  126. }
  127. setup.skills.persuasion = {
  128. label: 'Persuasion',
  129. hidden: true
  130. }
  131. setup.skills.reaction = {
  132. label: 'Reaction',
  133. hidden: true
  134. }
  135. setup.skills.spirit = {
  136. label: 'Spirit',
  137. hidden: true
  138. }
  139. setup.skills.strength = {
  140. label: 'Strength',
  141. hidden: true
  142. }
  143. setup.skills.vitality = {
  144. label: 'Vitality',
  145. hidden: true
  146. }
  147. setup.skills.webcam = {
  148. label: 'Webcam Girl',
  149. e2s: Skill.e2sFunction(1.5),
  150. s2e: Skill.s2eFunction(1.5)
  151. }