Skip to content

Commit

Permalink
- Reldens - Skills
Browse files Browse the repository at this point in the history
- Merge pull request #13 from damian-pastorini/v0.18.0
  • Loading branch information
damian-pastorini authored Jun 15, 2023
2 parents 23390a5 + 8c59f93 commit 82e15e4
Show file tree
Hide file tree
Showing 14 changed files with 3,946 additions and 28 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,3 @@
/ts-node*
/v8-compile-cache*
/dev
package-lock.json
15 changes: 14 additions & 1 deletion lib/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,18 @@ module.exports = {
ACTION_SKILL_BEFORE_RUN_LOGIC: actionPref+'Brl',
ACTION_SKILL_AFTER_RUN_LOGIC: actionPref+'Arl',
ACTION_SKILL_PHYSICAL_ATTACK_HIT: actionPref+'Pah',
ACTION_SKILL_PHYSICAL_EFFECT_HIT: actionPref+'Peh'
ACTION_SKILL_PHYSICAL_EFFECT_HIT: actionPref+'Peh',
SKILL_STATES: {
PHYSICAL_SKILL_INVALID_TARGET: 'physicalSkillInvalidTarget',
PHYSICAL_SKILL_RUN_LOGIC: 'physicalSkillRunLogic',
OUT_OF_RANGE: 'outOfRange',
CAN_NOT_ACTIVATE: 'canNotActivate',
DODGED: 'dodged',
APPLYING_DAMAGE: 'applyingDamage',
APPLIED_DAMAGE: 'appliedDamage',
APPLIED_CRITICAL_DAMAGE: 'appliedCriticalDamage',
APPLYING_EFFECTS: 'applyingEffects',
APPLIED_EFFECTS: 'appliedEffects',
EXECUTE_PHYSICAL_ATTACK: 'executePhysicalAttack'
}
};
10 changes: 4 additions & 6 deletions lib/server/sender.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ class Sender
if(nextLevelExp > 0){
messageData.ne = nextLevelExp;
}
// @NOTE: we could send just this.currentLabel but better check if there's an specific one for this level
// and don't send extra information we already have on the client.
// @NOTE: we could send just this.currentLabel but better check if there's a specific one for this level and
// don't send extra information we already have on the client.
if(classPath.labelsByLevel[classPath.currentLevel]){
messageData.nl = classPath.labelsByLevel[classPath.currentLevel];
}
Expand Down Expand Up @@ -121,9 +121,7 @@ class Sender

async onSkillAttachApplyDamage(skill, target, damage, newValue)
{
let messageData = {
d: damage
};
let messageData = {d: damage};
if(typeof skill.owner.getSkillExtraData === 'function'){
Object.assign(messageData, {extraData: skill.owner.getSkillExtraData({skill, target})});
}
Expand All @@ -137,7 +135,7 @@ class Sender

async runBehaviors(messageData, actionName, behavior, ownerId)
{
// @NOTE: since the sender is a new instance for each SkillsServer but it's listening on a single EventsManager
// @NOTE: since the sender is a new instance for each SkillsServer, but it's listening on a single EventsManager
// which fires the event for every player then we need to check if the current event fired was related to the
// current player.
if(this.classPath.getOwnerId() !== ownerId){
Expand Down
2 changes: 2 additions & 0 deletions lib/server/storage/models-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ class ModelsManager
// This way we will be able to use the get method, save the entity in a variable and call the relations list
// from it.
let skillsModels = await this.getEntity('skill').loadAllWithRelations([
'skill_attack',
'skill_physical_data',
'skill_owner_conditions',
'skill_owner_effects',
'skill_target_effects'
Expand Down
2 changes: 2 additions & 0 deletions lib/server/storage/skills-generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ class SkillsGenerator
}
// force to use the same events manager instance used on the main package:
skillModel.events = events;
this.enrichWithAttackData(skillModel);
this.enrichWithPhysicalData(skillModel);
skillsList[skillModel.key] = {class: skillClass, data: skillModel};
}
return {skillsModels, skillsList};
Expand Down
17 changes: 8 additions & 9 deletions lib/skill.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ class Skill
this.uses = 0;
this.canActivate = sc.get(props, 'canActivate', true);
this.range = sc.get(props, 'range', 0);
this.lastState = '';
this.groups = sc.get(props, 'groups', []);
this.lastAppliedModifiers = {};
// if enabled range will be validated just before execution to get the owner and target realtime positions:
this.rangeAutomaticValidation = sc.get(props, 'rangeAutomaticValidation', false);
// @NOTE: if automatic range validation is enabled the rangePropertyX and rangePropertyY will be required and
Expand All @@ -63,8 +66,6 @@ class Skill
this.ownerConditions = sc.get(props, 'ownerConditions', []);
// owner effects will be applied when the skill is executed:
this.ownerEffects = sc.get(props, 'ownerEffects', []);
// groups:
this.groups = sc.get(props, 'groups', []);
// critical multiplier and critical chance are to specify how and if a skill hit is critical:
this.criticalChance = sc.get(props, 'criticalChance', 0);
this.criticalMultiplier = sc.get(props, 'criticalMultiplier', 1);
Expand All @@ -85,6 +86,7 @@ class Skill
});
// the delay is the time in milliseconds until player can use the skill again:
if(!this.canActivate || this.owner.isCasting){
this.lastState = SkillsConst.SKILL_STATES.CAN_NOT_ACTIVATE;
// @NOTE: player could be running an attack already.
return false;
}
Expand Down Expand Up @@ -190,7 +192,7 @@ class Skill
this.applyModifiers(this.ownerEffects, this.owner, true);
await this.fireEvent(SkillsEvents.SKILL_APPLY_OWNER_EFFECTS, this, target);
}
if(this.castTime > 0){
if(0 < this.castTime){
await this.fireEvent(SkillsEvents.SKILL_BEFORE_CAST, this, target);
this.owner.isCasting = setTimeout(() => {
skillLogicResult = this.finishExecution(target);
Expand Down Expand Up @@ -263,16 +265,12 @@ class Skill
if(this.criticalChance <= 0){
return false;
}
return this.criticalChance < this.randomInteger(1, 100);
}

randomInteger(min, max)
{
return Math.floor(Math.random() * (max - min + 1)) + min;
return this.criticalChance < sc.randomInteger(1, 100);
}

applyModifiers(modifiersObjectList, target, avoidCritical = false)
{
this.lastAppliedModifiers = {};
for(let i of Object.keys(modifiersObjectList)){
let modifier = modifiersObjectList[i];
modifier.target = target;
Expand All @@ -281,6 +279,7 @@ class Skill
newValue = this.applyCriticalValue(newValue);
}
modifier.setOwnerProperty(modifier.propertyKey, newValue);
this.lastAppliedModifiers[modifier.propertyKey] = newValue;
}
}

Expand Down
14 changes: 10 additions & 4 deletions lib/types/attack.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,13 @@ class Attack extends Skill

async runSkillLogic()
{
this.lastState = null;
if(!this.validateRange(this.target)){
// out of range, the owner or the target could moved away
// out of range, the owner or the target could move away
this.lastState = SkillsConst.SKILL_STATES.OUT_OF_RANGE;
return false;
}
this.lastState = SkillsConst.SKILL_STATES.APPLYING_DAMAGE;
return await this.applyDamageTo(this.target);
}

Expand All @@ -64,15 +67,16 @@ class Attack extends Skill
let ownerAim = this.getPropertiesTotal(this.owner, this.aimProperties);
let targetDodge = this.getPropertiesTotal(target, this.dodgeProperties);
if(this.dodgeFullEnabled && targetDodge > (ownerAim * this.dodgeOverAimSuccess)){
this.lastState = SkillsConst.SKILL_STATES.DODGED;
return false;
}
let affectedPropertyValue = this.getAffectedPropertyValue(target);
if(!this.allowEffectBelowZero && 0 < affectedPropertyValue){
if(!this.allowEffectBelowZero && 0 >= affectedPropertyValue){
return false;
}
// dodge proportion:
let dodgeAimDiff = this.getDiffProportion(ownerAim, targetDodge);
let damage = this.applyDirectDamage
let damage = this.applyDirectDamage
? this.hitDamage // 100%
: this.calculateProportionDamage(target, this.hitDamage, targetDodge, ownerAim, dodgeAimDiff);
// critical calculation:
Expand All @@ -81,8 +85,9 @@ class Attack extends Skill
let modifiedValue = (!this.allowEffectBelowZero && affectedPropertyValue < damage)
? 0
: affectedPropertyValue - damage;
await this.fireEvent(SkillsEvents.SKILL_ATTACK_APPLY_DAMAGE, this, target, damage, modifiedValue);
this.setAffectedPropertyValue(target, modifiedValue);
this.lastState = SkillsConst.SKILL_STATES.APPLIED_DAMAGE;
await this.fireEvent(SkillsEvents.SKILL_ATTACK_APPLY_DAMAGE, this, target, damage, modifiedValue);
}

calculateCriticalDamage(damage, targetDodge, ownerAim, dodgeAimDiff)
Expand All @@ -91,6 +96,7 @@ class Attack extends Skill
if(!this.criticalAffected || targetDodge > ownerAim){
return criticalValue;
}
this.lastState = SkillsConst.SKILL_STATES.APPLIED_CRITICAL_DAMAGE;
// calculate dodge proportion over critical damage and remove it from the critical total:
return criticalValue - (Math.floor((criticalValue * dodgeAimDiff / 100)));
}
Expand Down
6 changes: 5 additions & 1 deletion lib/types/effect.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,17 @@ class Effect extends Skill

async runSkillLogic()
{
this.lastState = null;
if(!this.validateRange(this.target)){
// out of range, the owner or the target could moved away
this.lastState = SkillsConst.SKILL_STATES.OUT_OF_RANGE;
// out of range, the owner or the target could move away
return false;
}
this.lastState = SkillsConst.SKILL_STATES.APPLYING_EFFECTS;
// @NOTE: the difference between the normal skills modifiers and the effects are the critical chance applied
// to the modifiers here.
this.applyModifiers(this.targetEffects, this.target);
this.lastState = SkillsConst.SKILL_STATES.APPLIED_EFFECTS;
await this.fireEvent(SkillsEvents.SKILL_EFFECT_TARGET_MODIFIERS, this);
}

Expand Down
1 change: 1 addition & 0 deletions lib/types/physical-attack.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class PhysicalAttack extends Attack
{
super(props);
this.type = SkillsConst.SKILL_TYPE_PHYSICAL_ATTACK;
this.parentType = SkillsConst.SKILL_TYPE_ATTACK;
PhysicalPropertiesValidator.validate(props);
this.magnitude = props.magnitude;
this.objectWidth = props.objectWidth;
Expand Down
1 change: 1 addition & 0 deletions lib/types/physical-effect.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class PhysicalEffect extends Effect
{
super(props);
this.type = SkillsConst.SKILL_TYPE_PHYSICAL_EFFECT;
this.parentType = SkillsConst.SKILL_TYPE_EFFECT;
PhysicalPropertiesValidator.validate(props);
this.magnitude = props.magnitude;
this.objectWidth = props.objectWidth;
Expand Down
2 changes: 1 addition & 1 deletion lib/types/physical-properties-validator.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class PhysicalPropertiesValidator
static validate(props)
{
if(typeof props.owner.executePhysicalSkill !== 'function'){
ErrorManager.error('Missing executePhysicalAttack required method.');
ErrorManager.error('Missing executePhysicalSkill required method.');
}
if(!sc.hasOwn(props, 'magnitude')){
ErrorManager.error('Missing magnitude property.');
Expand Down
9 changes: 8 additions & 1 deletion lib/types/physical-skill-runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,20 @@
*
*/

const SkillsConst = require('@reldens/skills/lib/constants');

class PhysicalSkillRunner
{

static async runSkillLogic(skill)
{
this.lastState = null;
if(!skill.validateRange(skill.target)){
// out of range, the owner or the target could moved away
this.lastState = SkillsConst.SKILL_STATES.OUT_OF_RANGE;
// @NOTE: out of range, the owner or the target could have moved away.
return false;
}
this.lastState = SkillsConst.SKILL_STATES.EXECUTE_PHYSICAL_ATTACK;
await skill.owner.executePhysicalSkill(skill.target, skill);
return false;
}
Expand All @@ -21,11 +26,13 @@ class PhysicalSkillRunner
{
await skill.fireEvent(skillType, skill, target);
if(skill.validateTargetOnHit && target !== skill.target){
this.lastState = SkillsConst.SKILL_STATES.PHYSICAL_SKILL_INVALID_TARGET;
return false;
}
if('function' !== typeof runSkillLogicCallback){
return false;
}
this.lastState = SkillsConst.SKILL_STATES.PHYSICAL_SKILL_RUN_LOGIC;
return await runSkillLogicCallback(target);
}

Expand Down
Loading

0 comments on commit 82e15e4

Please sign in to comment.