public void EventForActives(string eventId, EffectData effect = null, RelayVar relayVar = null) { List <PokemonCharacter> actives = new List <PokemonCharacter>(); if (effect == null && effectInEvent != null) { effect = effectInEvent; } foreach (Team t in teams) { foreach (PokemonCharacter p in t.pokemons) { if (p.pokemonData.isActive) { actives.Add(p); } } } actives.Sort(ComparePokeSpeed); foreach (PokemonCharacter poke in actives) { RunEvent(eventId, poke.targetScript, null, effect, relayVar); } }
public bool Boost(Globals.BoostsTable boost, TargetableElement target = null, BattleElement source = null, EffectData effect = null) { bool success = false; if (this.currentEvent != null) { if (target == null) { target = this.currentEvent.target; } if (source == null) { source = this.currentEvent.source; } if (effect == null) { effect = this.effectInEvent; } } if (target == null || !(target.sourceElement is PokemonCharacter) || ((PokemonCharacter)target.sourceElement).pokemonData.hp <= 0) { return(false); } if (!((PokemonCharacter)target.sourceElement).pokemonData.isActive) { return(false); } //if (this.gen > 5 && !target.side.foe.pokemonLeft) return false; RelayVar relayVar = new RelayVar(boosts: boost); boost = RunEvent("Boost", target, source, effect, relayVar).boosts; string[] boostedNames = boost.GetBoostedNames(); foreach (string boostName in boostedNames) { int boostBy = ((PokemonCharacter)target.sourceElement).pokemonData.BoostBy(boostName, boost.GetBoostValue(boostName)); if (boostBy != 0) { success = true; relayVar = new RelayVar(integerValue: boostBy); RunEvent("AfterEachBoost", target, source, effect, relayVar); } } relayVar = new RelayVar(boosts: boost); RunEvent("AfterBoost", target, source, effect, relayVar); return(success); }
public int Heal(int damage, TargetableElement target, BattleElement source, EffectData effect) { if (this.currentEvent != null) { if (target == null) { target = this.currentEvent.target; } if (source == null) { source = this.currentEvent.source; } if (effect == null) { effect = this.effectInEvent; } } if (damage < 1) { damage = 1; } RelayVar relayVar = new RelayVar(integerValue: damage); relayVar = RunEvent("TryHeal", target, source, effect, relayVar); damage = relayVar.integerValue; if (relayVar.getEndEvent()) { return(0); } if (!(target.sourceElement is PokemonCharacter)) { return(0); } Pokemon pokeData = ((PokemonCharacter)target.sourceElement).pokemonData; if (pokeData.hp <= 0 || !pokeData.isActive || pokeData.hp >= pokeData.maxhp) { return(0); } int finalDamage = pokeData.Heal(damage); relayVar = new RelayVar(integerValue: finalDamage); RunEvent("Heal", target, source, effect, relayVar); return(finalDamage); }
public int Damage(int damage, TargetableElement target = null, BattleElement source = null, EffectData effect = null, bool instafaint = false) { if (currentEvent != null) { if (target == null) { target = currentEvent.target; } if (source == null) { source = currentEvent.source; } if (effect == null) { effect = effectInEvent; } } if (target == null || !(target.sourceElement is PokemonCharacter)) { return(0); } Pokemon poke = ((PokemonCharacter)target.sourceElement).pokemonData; if (poke.hp <= 0) { return(0); } if (damage <= 0) { return(0); } //// Struggle recoil is not affected by effects if (effect.id != "struggle-recoil") { if (effect.effectType == Globals.EffectTypes.Weather && poke.HasStatusImmunity(effect.id)) { return(0); } RelayVar relayVar = new RelayVar(integerValue: damage); damage = RunEvent("Damage", target, source, effect, relayVar).integerValue; if (damage <= 0) { return(0); } } damage = poke.Damage(damage, source, effect); if (source is PokemonCharacter && effect != null && effect.effectType == Globals.EffectTypes.Move) { ((PokemonCharacter)source).pokemonData.lastDamage = damage; } if (effect != null && effect.drain != null && source is PokemonCharacter) { //this.heal(Math.ceil(damage * effect.drain[0] / effect.drain[1]), source, target, 'drain'); Heal(Mathf.CeilToInt(damage * effect.drain[0] / effect.drain[1]), target, source, GetPureEffect("drain")); } if (!instafaint && poke.hp > 0) { RelayVar relayVar = new RelayVar(integerValue: damage); damage = RunEvent("AfterDamage", target, source, effect, relayVar).integerValue; } return(damage); }
public RelayVar RunEvent(string eventId, TargetableElement target = null, BattleElement source = null, EffectData effect = null, RelayVar relayVar = null, bool onEffect = false, bool fastExit = false) { if (eventDepth >= 8) { Debug.LogError("STACK LIMIT EXCEEDED"); } //Get relevant effects and sort them List <EventStatus> statuses = getRelevantEffects(target, eventId, source); statuses.Sort(ComparePriority); if (relayVar == null) { relayVar = new RelayVar(); } //Current event we are dealing with Event parentEvent = currentEvent; currentEvent = new Event(id: eventId, target: target, source: source, effect: effect); eventDepth++; /*Add the callback for our effect to the beginning if oneffect is true*/ if (onEffect && effect.eventMethods.HasCallback("on" + eventId)) { statuses.Insert(0, new EventStatus(status: effect, callback: "on" + eventId, thing: target)); } /* * for (int i = 0; i < statuses.Count; ++i) * { * Debug.Log(statuses[i].callback + " " + statuses[i].status); * } */ /*Lets begin*/ foreach (EventStatus currentStatus in statuses) { EffectData currentEffect = currentStatus.status; TargetableElement thing = currentStatus.thing; Pokemon pokeThing = (thing.sourceElement is PokemonCharacter) ? ((PokemonCharacter)thing.sourceElement).pokemonData : null; /*CurrentEffect has no callback with currentStatus.callback*/ if (!currentEffect.eventMethods.HasCallback(currentStatus.callback)) { continue; } //Status of target has changed, call it off if (currentEffect.effectType == Globals.EffectTypes.Status && pokeThing != null && pokeThing.statusId != currentEffect.id) { continue; } //Suppressed by Mold Breaker, Teravolt, Turboblaze, if (currentEffect.effectType == Globals.EffectTypes.Ability && !((AbilityData)currentEffect).isUnbreakable && SuppressingAttackEvents(source) && thing != null && thing != GetPokemonSource(source)) { if (MiscData.AttackingEvents.Contains(eventId)) { continue; } if (eventId == "Damage" && effect != null && effect.effectType == Globals.EffectTypes.Move) { continue; } } /*Suppressed by Embargo, Klutz or Magic Room*/ if (currentEffect.effectType == Globals.EffectTypes.Item && pokeThing != null && pokeThing.IgnoringItem() && eventId != "Start" && eventId != "TakeItem" && eventId != "SwitchIn") { continue; } /*Suppressed by Gastro Acid, ...*/ else if (currentEffect.effectType == Globals.EffectTypes.Ability && pokeThing != null && pokeThing.IgnoringAbility() && eventId != "End") { continue; } /*Suppressed by Air Lock, Cloud Nine*/ if ((currentEffect.effectType == Globals.EffectTypes.Weather || eventId == "Weather") && SuppressingWeather() && eventId != "Residual" && eventId != "End") { continue; } //Storing last event info EffectData parentEffect = effectInEvent; EffectData parentEffectData = effectDataInEvent; TargetableElement parentTarget = targetInEvent; effectInEvent = currentEffect; effectDataInEvent = currentStatus.statusData; targetInEvent = thing; /*Calling Callback*/ relayVar = currentEffect.eventMethods.StartCallback(currentStatus.callback, this, relayVar, target, source, effect); /*Recovering last event info*/ effectInEvent = parentEffect; effectDataInEvent = parentEffectData; targetInEvent = parentTarget; if (relayVar.getEndEvent()) { break; //ENDING EVENT } } eventDepth--; currentEvent = parentEvent; return(relayVar); }
public RelayVar SingleEvent(string eventId, EffectData effect, EffectData effectData = null, TargetableElement target = null, BattleElement source = null, EffectData sourceEffect = null, RelayVar relayVar = null) { if (eventDepth >= 8) { Debug.LogError("STACK LIMIT EXCEEDED"); } if (relayVar == null) { relayVar = new RelayVar(); } /*Effect has no callback with eventId*/ if (!effect.eventMethods.HasCallback("on" + eventId)) { return(relayVar); } Pokemon pokeTarget = (target == null || !(target.sourceElement is PokemonCharacter)) ? null : ((PokemonCharacter)target.sourceElement).pokemonData; //Status of target has changed, call it off if (effect.effectType == Globals.EffectTypes.Status && pokeTarget != null && pokeTarget.statusId != effect.id) { return(relayVar); } /*Suppressed by Embargo, Klutz or Magic Room*/ if (effect.effectType == Globals.EffectTypes.Item && pokeTarget != null && pokeTarget.IgnoringItem() && eventId != "Start" && eventId != "TakeItem" && eventId != "Primal") { return(relayVar); } /*Suppressed by Gastro Acid, ...*/ if (effect.effectType == Globals.EffectTypes.Ability && pokeTarget != null && pokeTarget.IgnoringAbility() && eventId != "End") { return(relayVar); } /*Suppressed by Air Lock, Cloud Nine*/ if (effect.effectType == Globals.EffectTypes.Weather && SuppressingWeather() && eventId != "Start" && eventId != "Residual" && eventId != "End") { return(relayVar); } /*Setting the current event we are dealing with*/ EffectData parentEffect = effectInEvent; EffectData parentEffectData = effectDataInEvent; TargetableElement parentTarget = targetInEvent; Event parentEvent = currentEvent; effectInEvent = effect; effectDataInEvent = effectData; targetInEvent = target; currentEvent = new Event(id: eventId, target: target, source: source, effect: sourceEffect); eventDepth++; /*Calling Callcack*/ relayVar = effect.eventMethods.StartCallback("on" + eventId, this, relayVar, target, source, effect); /*Recovering last event info*/ eventDepth--; effectInEvent = parentEffect; effectDataInEvent = parentEffectData; targetInEvent = parentTarget; currentEvent = parentEvent; return(relayVar); }
public int ModifyDamage(int baseDamage, Pokemon pokemon, Pokemon target, ActiveMove activeMove) { Globals.Type type = activeMove.activeData.moveData.type; baseDamage += 2; RelayVar relayVar; //MultiTarget should go here but not needed //Weather modifier relayVar = new RelayVar(integerValue: baseDamage); relayVar = RunEvent("WeatherModifyDamage", pokemon.targetData, target.myPokemon, activeMove.activeData.moveData, relayVar); baseDamage = relayVar.integerValue; Debug.Log("Weather modifier: " + baseDamage); //crit if (activeMove.activeData.crit) { baseDamage = Mathf.FloorToInt(baseDamage * 1.5f); } Debug.Log("Crit modifier: " + baseDamage); //Not a modifier baseDamage = RandomScript.Randomizer(baseDamage); Debug.Log("Random modifier: " + baseDamage); //STAB if (pokemon.HasType(type)) { baseDamage = Mathf.FloorToInt(baseDamage * ((activeMove.activeData.stab != -1) ? activeMove.activeData.stab : 1.5f)); } Debug.Log("STAB modifier: " + baseDamage); //Types activeMove.activeData.typeMod = Mathf.Clamp(target.RunEffectiveness(activeMove), -6, 6); if (activeMove.activeData.typeMod > 0) { for (int i = 0; i < activeMove.activeData.typeMod; i++) { baseDamage *= 2; } } if (activeMove.activeData.typeMod < 0) { for (int i = 0; i > activeMove.activeData.typeMod; i--) { baseDamage = Mathf.FloorToInt(baseDamage / 2f); } } Debug.Log("Types modifier: " + baseDamage); //Burn Status if (pokemon.statusId == "brn" && activeMove.activeData.moveData.category == Globals.MoveCategory.Physical && !pokemon.HasAbilityActive(new string[] { "guts" })) { if (activeMove.id != "facade") { baseDamage = Mathf.FloorToInt(baseDamage * 0.5f); } } Debug.Log("Burn modifier: " + baseDamage); // Final modifier. Modifiers that modify damage after min damage check, such as Life Orb. relayVar = new RelayVar(integerValue: baseDamage); relayVar = RunEvent("ModifyDamage", pokemon.targetData, target.myPokemon, activeMove.activeData.moveData, relayVar); baseDamage = relayVar.integerValue; Debug.Log("other modifier: " + baseDamage); //Z breaking protect if (activeMove.activeData.zPowered && activeMove.activeData.zBrokeProtect) { baseDamage = Mathf.FloorToInt(baseDamage * 0.25f); } Debug.Log("z break protect modifier: " + baseDamage); if (baseDamage < 1) { baseDamage = 1; } return(Mathf.FloorToInt(baseDamage)); }
//I think it will be used for direct damages public int GetDamage(Pokemon pokemon, Pokemon target, ActiveMove activeMove, int directDamage = -1)//movedata comes from active move?? //DirectDamage for confusion and stuff { MoveData moveData = activeMove.activeData.moveData; RelayVar relayVar; if (moveData == null && directDamage == -1) { return(-1); //No moveData and no directDamage } if (directDamage != -1) { moveData = new MoveData(basePower: directDamage, type: Globals.Type.Unknown, category: Globals.MoveCategory.Physical, willCrit: false); } //if not ignoreImmunity return false (do it before? /*RETURN DIRECT DAMAGE*/ if (moveData.ohko != Globals.OHKO.Null) { return(target.maxhp); //Fissure, Sheer cold } if (moveData.eventMethods.damageCallback != null) //mirro coat, naturesmaddnes, hyper fang... { relayVar = new RelayVar(); moveData.eventMethods.StartCallback("damageCallback", this, relayVar, target.targetData, pokemon.myPokemon, null); return(relayVar.integerValue); } if (moveData.damageByLevel) { return(pokemon.level); //nightshade, seismic toss } if (moveData.damage != -1) { return(moveData.damage); //Dragon rage, sonic boom } /*USING BASE POWER*/ //Category Globals.MoveCategory category = (moveData.category == Globals.MoveCategory.Null) ? Globals.MoveCategory.Physical : moveData.category; if (moveData.defensiveCategory != Globals.MoveCategory.Null) { category = moveData.defensiveCategory; } //BasePower int basePower = moveData.basePower; if (moveData.eventMethods.basePowerCallback != null) { relayVar = new RelayVar(); moveData.eventMethods.StartCallback("basePowerCallback", this, relayVar, target.targetData, pokemon.myPokemon, moveData); basePower = relayVar.integerValue; } if (basePower < 0) { return(-1); //Return -1 means no dealing damage } basePower = Mathf.Max(1, basePower); //Min value will be 1 Debug.Log("Power after basePowerCallback: " + basePower); //CritRatio int[] critMultiplier = { 0, 24, 8, 2, 1 }; relayVar = new RelayVar(integerValue: moveData.critRatio); relayVar = RunEvent("ModifyCritRatio", pokemon.targetData, target.myPokemon, moveData, relayVar); int critRatio = Mathf.Clamp(relayVar.integerValue, 0, 4); //Set crit activeMove.activeData.crit = moveData.willCrit; if (!activeMove.activeData.crit) { activeMove.activeData.crit = RandomScript.RandomChance(1, critMultiplier[critRatio]); } if (activeMove.activeData.crit) { relayVar = new RelayVar(booleanValue: activeMove.activeData.crit); relayVar = RunEvent("CriticalHit", target.targetData, null, moveData); activeMove.activeData.crit = relayVar.booleanValue; } //Happens after crit calculation relayVar = new RelayVar(integerValue: basePower); relayVar = RunEvent("BasePower", pokemon.targetData, target.myPokemon, moveData, relayVar, true); if (relayVar.getEndEvent() && relayVar.integerValue != -1) { return(-1); } basePower = Mathf.Max(1, relayVar.integerValue); Debug.Log("Power after basepower: " + basePower); //Starting? int level = pokemon.level; Pokemon attacker = pokemon; Pokemon defender = target; string attackStat = (category == Globals.MoveCategory.Physical) ? "Atk" : "SpA"; string defenseStat = (category == Globals.MoveCategory.Physical) ? "Def" : "SpD"; //statTable int attack; int defense; int atkBoosts = (moveData.useTargetOffensive) ? defender.boosts.GetBoostValue(attackStat) : attacker.boosts.GetBoostValue(attackStat); int defBoosts = (moveData.useSourceDefensive) ? attacker.boosts.GetBoostValue(defenseStat) : defender.boosts.GetBoostValue(defenseStat); bool ignoreNegativeOffensive = moveData.ignoreNegativeOffensive; bool ignorePositiveDefensive = moveData.ignorePositiveDefensive; if (activeMove.activeData.crit) { ignoreNegativeOffensive = true; ignorePositiveDefensive = true; } bool ignoreOffensive = moveData.ignoreOffensive || (ignoreNegativeOffensive && atkBoosts < 0); bool ignoreDefensive = moveData.ignoreDefensive || (ignorePositiveDefensive && defBoosts > 0); if (ignoreOffensive) { //this.debug('Negating (sp)atk boost/penalty.'); atkBoosts = 0; } if (ignoreDefensive) { //this.debug('Negating (sp)def boost/penalty.'); defBoosts = 0; } if (moveData.useTargetOffensive) { attack = defender.CalculateStat(attackStat, atkBoosts); } else { attack = attacker.CalculateStat(attackStat, atkBoosts); } if (moveData.useSourceDefensive) { defense = attacker.CalculateStat(defenseStat, defBoosts); } else { defense = defender.CalculateStat(defenseStat, defBoosts); } Debug.Log("attack: " + attack + " defense: " + defense); //Apply stat modifiers relayVar = new RelayVar(integerValue: attack); relayVar = RunEvent("Modify" + attackStat, attacker.targetData, defender.myPokemon, moveData, relayVar); attack = relayVar.integerValue; relayVar = new RelayVar(integerValue: defense); relayVar = RunEvent("Modify" + defenseStat, defender.targetData, attacker.myPokemon, moveData, relayVar); defense = relayVar.integerValue; Debug.Log("After modifiers attack: " + attack + " defense: " + defense); //int(int(int(2 * L / 5 + 2) * A * P / D) / 50); int baseDamage = Mathf.FloorToInt(Mathf.FloorToInt(Mathf.FloorToInt(2f * level / 5f + 2f) * basePower * attack / defense) / 50f); Debug.Log("baseDamage: " + baseDamage); // Calculate damage modifiers separately (order differs between generations) return(ModifyDamage(baseDamage, pokemon, target, activeMove)); }