protected virtual bool ReactsAgainst(SkillDef s, StatEffectRecord se) { return(s != this && //don't react against your own application s.character != character && //don't react against your own character's skills s.currentTargetCharacter == character && //only react to skills used against our character reactionSkill && //only react if you're a reaction skill !s.reactionSkill && //don't react against reaction skills s is ActionSkillDef && //only react against targeted skills ReactionTypesMatch(se)); //only react if masks match }
protected virtual bool ReactionTypesMatch(StatEffectRecord se) { string[] reactionTypes = se.effect.target == StatEffectTarget.Applied ? reactionTypesApplied : reactionTypesApplier; StatChange[] reactionStatChanges = se.effect.target == StatEffectTarget.Applied ? reactionStatChangesApplied : reactionStatChangesApplier; return(se.Matches(reactionStatChanges, reactionTypes)); }
protected virtual void SkillApplied(SkillDef s) { //react against each effect currentReactedSkill = s; List <StatEffectRecord> fx = s.lastEffects; bool reacts = false; foreach (StatEffectRecord se in fx) { currentReactedEffect = se; if (ReactsAgainst(s, se)) { reacts = true; break; } } if (reacts) { ClearLastEffects(); currentTargetCharacter = s.character; Target target = (new Target()).Character(s.character); reactionTargetRegion.Owner = this; reactionEffectRegion.Owner = this; PathNode[] reactionTiles = PathNodesForTarget( target, reactionTargetRegion, reactionEffectRegion, character.TilePosition, Quaternion.Euler(0, character.Facing, 0) ); targetCharacters = new List <Character>() { s.character }; SetArgsFromTarget(target, null, ""); targetCharacters = reactionEffectRegion.CharactersForTargetedTiles(reactionTiles); if (targetCharacters.Contains(currentTargetCharacter)) { ApplyPerApplicationEffectsTo( reactionApplicationEffects.effects, new List <Character>() { currentTargetCharacter } ); if (reactionEffects.Length > 0) { ApplyEffectsTo( target, null, reactionEffects, targetCharacters, "reaction.hitType", character.TilePosition ); } map.BroadcastMessage( "SkillApplied", this, SendMessageOptions.DontRequireReceiver ); } } currentReactedSkill = null; currentReactedEffect = null; }
public StatEffectRecord Apply( SkillDef skill, Character character, Character targ ) { Formulae fdb = skill != null ? skill.fdb : (character != null ? character.fdb : (targ != null ? targ.fdb : Formulae.DefaultFormulae)); StatEffectRecord effect=null; Character actualTarget=null; switch(target) { case StatEffectTarget.Applier: actualTarget = character; break; case StatEffectTarget.Applied: actualTarget = targ; break; } if(Formula.NotNullFormula(triggerF)) { if(triggerF.GetValue(fdb, skill, actualTarget) == 0) { return null; } } switch(effectType) { case StatEffectType.Augment: case StatEffectType.Multiply: case StatEffectType.Replace: float modValue = 0; float oldStat = actualTarget.GetBaseStat(statName); float newStat = ModifyStat( oldStat, skill, actualTarget, null, null, ref modValue ); // Debug.Log("base modvalue is "+modValue+", newstat is "+newStat); newStat = actualTarget.SetBaseStat(statName, newStat, respectLimits); if(constrainValueToLimits) { modValue = effectType == StatEffectType.Replace ? newStat : newStat - oldStat; } effect = new StatEffectRecord(this, oldStat, newStat, modValue); Debug.Log("hit "+actualTarget+"("+target+") for "+modValue+", new "+statName+" "+newStat); // Debug.Log("vtype "+value.formulaType+" ltype "+value.lookupType); break; case StatEffectType.ChangeFacing: float oldAngle = actualTarget.Facing; float angle = value.GetValue(fdb, skill, actualTarget); actualTarget.Facing = angle; if(actualTarget.mountedCharacter != null) { actualTarget.mountedCharacter.Facing = angle; } if(actualTarget.mountingCharacter != null) { actualTarget.mountingCharacter.Facing = angle; } Debug.Log("set facing to "+angle); effect = new StatEffectRecord(this, oldAngle, angle, angle); break; case StatEffectType.EndTurn: effect = new StatEffectRecord(this); Debug.Log("end turn"); skill.scheduler.DeactivateAfterSkillApplication(actualTarget, skill); break; case StatEffectType.SpecialMove: { if(specialMoveLine == null) { Debug.LogError("Undefined move line"); } specialMoveLine.Owner = skill; Vector3 start = new Vector3( specialMoveGivenStartX.GetValue(fdb, skill, targ), specialMoveGivenStartY.GetValue(fdb, skill, targ), specialMoveGivenStartZ.GetValue(fdb, skill, targ) ); effect = new StatEffectRecord(this, start); actualTarget.SpecialMove( start, specialMoveAnimateToStart, specialMoveType, specialMoveLine, specialMoveSpeedXY, specialMoveSpeedZ, skill ); break; } case StatEffectType.ApplyStatusEffect: { StatusEffect sfx = (GameObject.Instantiate( statusEffectPrefab, Vector3.zero, Quaternion.identity ) as StatusEffect); sfx.applyingSkill = skill; Debug.Log("apply status effect "+sfx); actualTarget.ApplyStatusEffect(sfx); effect = new StatEffectRecord(this, sfx); break; } case StatEffectType.RemoveStatusEffect: { Debug.Log("remove status effects "+statusEffectRemovalType+" with str "+statusEffectRemovalStrength); StatusEffect[] removed = actualTarget.RemoveStatusEffect( statusEffectRemovalType, statusEffectRemovalStrength ); effect = new StatEffectRecord(this, removed); break; } case StatEffectType.Dismount: { if(dismountMounter && actualTarget.IsMounting) { actualTarget.Dismount(); } if(dismountMounted && actualTarget.IsMounted) { actualTarget.mountingCharacter.Dismount(); } effect = new StatEffectRecord(this); break; } case StatEffectType.AddItem: { Inventory inv = actualTarget.inventory; if(inv == null) { Debug.LogError("No inventory under effect (add)"); } Item involvedItem = item ?? skill.InvolvedItem; if(involvedItem == null) { Debug.LogError("No item in question (add)"); } bool success = inv.InsertItem(involvedItem, -1, 1) == 1; effect = new StatEffectRecord(this, inv, involvedItem, success); break; } case StatEffectType.RemoveItem: { Inventory inv = actualTarget.inventory; if(inv == null) { Debug.LogError("No inventory under effect (remove)"); } Item involvedItem = item ?? skill.InvolvedItem; if(involvedItem == null) { Debug.LogError("No item in question (remove)"); } bool success = inv.RemoveItem(involvedItem, 1) == 1; effect = new StatEffectRecord(this, inv, involvedItem, success); break; } } return effect; }
public StatEffectRecord Apply( SkillDef skill, Character character, Character targ ) { Formulae fdb = skill != null ? skill.fdb : (character != null ? character.fdb : (targ != null ? targ.fdb : Formulae.DefaultFormulae)); StatEffectRecord effect = null; Character actualTarget = null; switch (target) { case StatEffectTarget.Applier: actualTarget = character; break; case StatEffectTarget.Applied: actualTarget = targ; break; } if (Formula.NotNullFormula(triggerF)) { if (triggerF.GetValue(fdb, skill, actualTarget) == 0) { return(null); } } switch (effectType) { case StatEffectType.Augment: case StatEffectType.Multiply: case StatEffectType.Replace: float modValue = 0; float oldStat = actualTarget.GetBaseStat(statName); float newStat = ModifyStat( oldStat, skill, actualTarget, null, null, ref modValue ); // Debug.Log("base modvalue is "+modValue+", newstat is "+newStat); newStat = actualTarget.SetBaseStat(statName, newStat, respectLimits); if (constrainValueToLimits) { modValue = effectType == StatEffectType.Replace ? newStat : newStat - oldStat; } effect = new StatEffectRecord(this, oldStat, newStat, modValue); Debug.Log("hit " + actualTarget + "(" + target + ") for " + modValue + ", new " + statName + " " + newStat); // Debug.Log("vtype "+value.formulaType+" ltype "+value.lookupType); break; case StatEffectType.ChangeFacing: float oldAngle = actualTarget.Facing; float angle = value.GetValue(fdb, skill, actualTarget); actualTarget.Facing = angle; if (actualTarget.mountedCharacter != null) { actualTarget.mountedCharacter.Facing = angle; } if (actualTarget.mountingCharacter != null) { actualTarget.mountingCharacter.Facing = angle; } Debug.Log("set facing to " + angle); effect = new StatEffectRecord(this, oldAngle, angle, angle); break; case StatEffectType.EndTurn: effect = new StatEffectRecord(this); Debug.Log("end turn"); skill.scheduler.DeactivateAfterSkillApplication(actualTarget, skill); break; case StatEffectType.SpecialMove: { if (specialMoveLine == null) { Debug.LogError("Undefined move line"); } specialMoveLine.Owner = skill; Vector3 start = new Vector3( specialMoveGivenStartX.GetValue(fdb, skill, targ), specialMoveGivenStartY.GetValue(fdb, skill, targ), specialMoveGivenStartZ.GetValue(fdb, skill, targ) ); effect = new StatEffectRecord(this, start); actualTarget.SpecialMove( start, specialMoveAnimateToStart, specialMoveType, specialMoveLine, specialMoveSpeedXY, specialMoveSpeedZ, skill ); break; } case StatEffectType.ApplyStatusEffect: { StatusEffect sfx = (GameObject.Instantiate( statusEffectPrefab, Vector3.zero, Quaternion.identity ) as StatusEffect); sfx.applyingSkill = skill; Debug.Log("apply status effect " + sfx); actualTarget.ApplyStatusEffect(sfx); effect = new StatEffectRecord(this, sfx); break; } case StatEffectType.RemoveStatusEffect: { Debug.Log("remove status effects " + statusEffectRemovalType + " with str " + statusEffectRemovalStrength); StatusEffect[] removed = actualTarget.RemoveStatusEffect( statusEffectRemovalType, statusEffectRemovalStrength ); effect = new StatEffectRecord(this, removed); break; } case StatEffectType.Dismount: { if (dismountMounter && actualTarget.IsMounting) { actualTarget.Dismount(); } if (dismountMounted && actualTarget.IsMounted) { actualTarget.mountingCharacter.Dismount(); } effect = new StatEffectRecord(this); break; } case StatEffectType.AddItem: { Inventory inv = actualTarget.inventory; if (inv == null) { Debug.LogError("No inventory under effect (add)"); } Item involvedItem = item ?? skill.InvolvedItem; if (involvedItem == null) { Debug.LogError("No item in question (add)"); } bool success = inv.InsertItem(involvedItem, -1, 1) == 1; effect = new StatEffectRecord(this, inv, involvedItem, success); break; } case StatEffectType.RemoveItem: { Inventory inv = actualTarget.inventory; if (inv == null) { Debug.LogError("No inventory under effect (remove)"); } Item involvedItem = item ?? skill.InvolvedItem; if (involvedItem == null) { Debug.LogError("No item in question (remove)"); } bool success = inv.RemoveItem(involvedItem, 1) == 1; effect = new StatEffectRecord(this, inv, involvedItem, success); break; } } return(effect); }
protected virtual void SkillApplied(SkillDef s) { //react against each effect currentReactedSkill = s; List<StatEffectRecord> fx = s.lastEffects; bool reacts = false; foreach(StatEffectRecord se in fx) { currentReactedEffect = se; if(ReactsAgainst(s, se)) { reacts = true; break; } } if(reacts) { ClearLastEffects(); currentTargetCharacter = s.character; Target target = (new Target()).Character(s.character); reactionTargetRegion.Owner = this; reactionEffectRegion.Owner = this; PathNode[] reactionTiles = PathNodesForTarget( target, reactionTargetRegion, reactionEffectRegion, character.TilePosition, Quaternion.Euler(0,character.Facing,0) ); targetCharacters = new List<Character>(){s.character}; SetArgsFromTarget(target, null, ""); targetCharacters = reactionEffectRegion.CharactersForTargetedTiles(reactionTiles); if(targetCharacters.Contains(currentTargetCharacter)) { ApplyPerApplicationEffectsTo( reactionApplicationEffects.effects, new List<Character>(){currentTargetCharacter} ); if(reactionEffects.Length > 0) { ApplyEffectsTo( target, null, reactionEffects, targetCharacters, "reaction.hitType", character.TilePosition ); } map.BroadcastMessage( "SkillApplied", this, SendMessageOptions.DontRequireReceiver ); } } currentReactedSkill = null; currentReactedEffect = null; }
protected virtual bool ReactsAgainst(SkillDef s, StatEffectRecord se) { return s != this && //don't react against your own application s.character != character && //don't react against your own character's skills s.currentTargetCharacter == character && //only react to skills used against our character reactionSkill && //only react if you're a reaction skill !s.reactionSkill && //don't react against reaction skills s is ActionSkillDef && //only react against targeted skills ReactionTypesMatch(se); //only react if masks match }
protected virtual bool ReactionTypesMatch(StatEffectRecord se) { string[] reactionTypes = se.effect.target == StatEffectTarget.Applied ? reactionTypesApplied : reactionTypesApplier; StatChange[] reactionStatChanges = se.effect.target == StatEffectTarget.Applied ? reactionStatChangesApplied : reactionStatChangesApplier; return se.Matches(reactionStatChanges, reactionTypes); }