//This method just executes the ability without checking if it can public int DoPerformAbility(int ability, Unit target, Vector3 targetPosition) { var ab = abilities[ability]; Common.CombatMessage.AbilityError error; var handle = server.ScriptInterface.PerformAbility(ab.Ability, this, target, targetPosition, out error); ab.Handle = handle; if (error != Common.CombatMessage.AbilityError.NoError) { server.CombatLogWrite(this, target, new Common.CombatMessage.AbilityFail { AbilityName = ab.Ability.Name, Error = error }); return -1; } ab.Cooldown = ab.Ability.RealCooldown(Stats); DecreaseStat(Common.UnitStats.Mana, ab.Ability.RealManaCost(Stats)); server.CombatLogWrite(this, target, new Common.CombatMessage.AbilityStart { Handle = handle, AbilityName = ab.Ability.Name }); ActiveAbilities[handle] = ab.Ability; server.ScriptInterface.PerformAbilityDoneCallbacks[handle] = () => AbilityDone(handle); if (ab.Ability.ChannelingTime > 0) ChangeState(new Channeling(this, ab.Ability, handle, ab.Ability.ChannelingTime)); return handle; }
public void InteractWith(Unit unit) { }
/// <summary> /// This is when a user clicks an object /// </summary> /// <param name="interacter">Avatar who performed the click</param> public void Interact(Unit interacter) { lastInteracter = interacter; }
public void Hit(Unit perpetrator, Unit mediator, int handle, Common.Resource activityObject, Common.CombatMessage.Activity activity, float damage) { if (IsDeleted || IsDead || UnitClass.Invulnerable || IsInvulnerable) return; Common.CombatMessage.DamageType damageType = Common.CombatMessage.DamageType.Hit; var ab = activityObject as Common.Classes.Ability; if (activity == Common.CombatMessage.Activity.Ability) { //Weapon attack stats if (ab.IsBaseAttack) { //Add: Weapon Damage damage += perpetrator.Stats.GetStat(Common.UnitStats.AttackDamage); if (server.Random.NextDouble() < perpetrator.Stats.CritChance) { damage *= 2; damageType = Common.CombatMessage.DamageType.Crit; } if (server.Random.NextDouble() > perpetrator.Stats.HitChance) { damage = 0; damageType = Common.CombatMessage.DamageType.Miss; } if (server.Random.NextDouble() < Stats.EvadeChance) { damage = 0; damageType = Common.CombatMessage.DamageType.Miss; } } //Armor damage reduction damage *= server.Map.ArmorTypeDamageReduction[UnitClass.ArmorType][ab.DamageType]; damage *= (1 - Stats.ArmorDamageReduction); //Unit damage reduction damage *= (1 - DamageReduction[ab.DamageType]); } if (damage > 0) { List<int> toRemove = new List<int>(); foreach (int i in shields.Keys) { if (shields[i] > damage) { shields[i] -= damage; damage = 0; break; } else { damage -= shields[i]; toRemove.Add(i); } } foreach (int i in toRemove) { RemoveShield(i); RemoveBuff(i); } server.ScriptInterface.InEventUnitHit(this, perpetrator, damage, ab != null ? ab.IsBaseAttack : false); DecreaseStat(Common.UnitStats.HitPoints, damage); } if (perpetrator is Avatar) server.GameStats.IncreaseStat(perpetrator.Id, Common.GameStats.PlayerStats.PlayerStat.Damage, damage); if (this is Avatar) server.GameStats.IncreaseStat(Id, Common.GameStats.PlayerStats.PlayerStat.DamageTaken, damage); server.CombatLogWrite(perpetrator, this, new Common.CombatMessage.Damage { ActivitySource = activity, Handle = handle, HitPoints = damage, DamageType = damageType, MediatorID = mediator != null ? mediator.Id : null }); if (Stats.GetStat(Common.UnitStats.HitPoints) <= 0) Kill(perpetrator); }
public float Heal(Unit healer, Unit mediator, int handle, Common.Resource activityObject, Common.CombatMessage.Activity activity, float hitpoints, Common.CombatMessage.HealType healType) { if (IsDead || UnitClass.IsBuilding) return 0; float hp = GetStat(Common.UnitStats.HitPoints); float maxHP = GetStat(Common.UnitStats.MaxHitPoints); if (hp + hitpoints > maxHP) hitpoints = maxHP - hp; IncreaseStat(Common.UnitStats.HitPoints, hitpoints); if (healer is Avatar) server.GameStats.IncreaseStat(healer.Id, Common.GameStats.PlayerStats.PlayerStat.HealingDone, hitpoints); server.ScriptInterface.InEventUnitHealed(this, healer, hitpoints, healType); server.CombatLogWrite(healer, this, new Common.CombatMessage.Heal { ActivitySource = activity, Handle = handle, Hitpoints = hitpoints, MediatorID = mediator != null ? mediator.Id : null, HealType = healType }); return hitpoints; }
public int ApplyBuff(Common.Classes.Buff buff, Unit caster) { if (buff.IsDebuff && IsImmuneToDebuffs) return -1; if (buff.IsUnique) { List<int> toRemove = new List<int>(); foreach (int i in ActiveBuffs.Keys) { // this comparison might need to be redone when further decisions have been made // about how buffs will be applied if (ActiveBuffs[i].Name == buff.Name) { toRemove.Add(i); } } foreach (int i in toRemove) RemoveBuff(i); } int handle = server.ScriptInterface.ApplyBuff(buff, caster, this); server.ScriptInterface.BuffDoneCallbacks[handle] = () => { server.CombatLogWrite(caster, this, new Common.CombatMessage.RemoveBuff { Handle = handle }); ActiveBuffs.Remove(handle); }; server.CombatLogWrite(caster, this, new Common.CombatMessage.ApplyBuff { Handle = handle, BuffName = buff.Name }); ActiveBuffs.Add(handle, buff); return handle; }
public override void Kill(Unit perpetrator) { base.Kill(perpetrator); server.GameStats.IncreaseStat(Id, Common.GameStats.PlayerStats.PlayerStat.Deaths, 1); if (perpetrator is Avatar) server.GameStats.IncreaseStat(perpetrator.Id, Common.GameStats.PlayerStats.PlayerStat.Kills, 1); deathTimeout = server.Timeout(10, () => { Teleport(Player.Team.StartPosition); ChangeState(new Normal(this)); }); }
public Dead(Unit unit) : base(unit) { }
public Channeling(Unit unit, Common.Classes.Ability ability, int channelingHandle, float timeout) : base(unit) { this.ability = ability; this.channelingHandle = channelingHandle; this.timeout = timeout; }
public override int PerformAbility(int ability, Unit target, Vector3 targetPosition) { return -1; }
public Uncontrollable(Unit unit) : base(unit) { }
public Normal(Unit unit) : base(unit) { }
public virtual int PerformAbility(int ability, Unit target, Vector3 targetPosition) { return unit.DoPerformAbility(ability, target, targetPosition); }
protected IState(Unit unit) { this.unit = unit; }
public virtual void Kill(Unit perpetrator) { if (IsDead) return; if (perpetrator.Team != Team) { IEnumerable<Object> ie = server.VicinityManager.InPublishRange(this); List<Unit> grantExperience = new List<Unit>(); List<Unit> bounteers = new List<Unit>(); foreach (Object o in ie) { if (o.Team == perpetrator.Team && o is Unit) { Unit u = (Unit)o; if (u.UnitClass.Leveling && u.IsLeveling && !u.IsDead && !u.IsDeleted) grantExperience.Add(u); if(u is Avatar) bounteers.Add(u); } } // some experience is lost here due to integer rounding (by intention) int exp = grantExperience.Count > 0 ? Stats.ExperienceEmitted / grantExperience.Count : 0; if (!(perpetrator is Avatar)) exp /= 2; if (exp > 0) { foreach (Unit u in grantExperience) u.IncreaseStat(Common.UnitStats.Experience, exp); } int gold; if(perpetrator is Avatar) { gold = Stats.GoldEmitted; ((Avatar)perpetrator).IncreaseStat(Common.UnitStats.Money, gold); } else { gold = bounteers.Count > 0 ? Stats.GoldEmitted / bounteers.Count : 0; foreach(var b in bounteers) b.IncreaseStat(Common.UnitStats.Money, gold); } server.CombatLogWrite(perpetrator, this, new Common.CombatMessage.Killed { Bounty = gold }); } ChangeState(new Dead(this)); server.ScriptInterface.InEventUnitKilled(this, perpetrator); }
public void NextTarget() { List<Object> ivr = new List<Object>(server.VicinityManager.InVisibleRange(this)); int lastIndex = -1; if (Target != null) for (int i = 0; i < ivr.Count; i++) if (ivr[i] == Target) lastIndex = i; for(int i=0; i < ivr.Count; i++) { var obj = ivr[(i + lastIndex + 1) % ivr.Count]; if (obj is Unit && ((Unit)obj).Team != Team) { Target = (Unit)obj; return; } } }
public CombatState(Unit unit) : base(unit) { }