예제 #1
0
    private static bool AttachClass()
    {
        unit u = GetFilterUnit();

        if (GetUnitAbilityLevel(u, FourCC("Aloc")) > 0)
        {
            return(false);
        }
        if (Indexer.ContainsKey(GetHandleId(u)))
        {
            return(false);
        }

        if (CustomTypes.ContainsKey(GetUnitTypeId(u)))
        {
            Indexer[GetHandleId(u)] = (NoxUnit)Activator.CreateInstance(CustomTypes[GetUnitTypeId(u)], u);
        }
        else if (IsUnitType(u, UNIT_TYPE_HERO))
        {
            Indexer[GetHandleId(u)] = new NoxHero(u);
        }
        else
        {
            Indexer[GetHandleId(u)] = new NoxUnit(u);
        }
        u = null;
        return(false);
    }
예제 #2
0
 public Status ApplyStatus(NoxUnit source, NoxUnit target, int level, float duration, int initialStacks = 1, int bonusLevel = 0, float bonusDuration = 0, int bonusStacks = 1)
 {
     if (!target.ContainsStatus(Id))
     {
         // create new status and add it to unit
         return(target.AddStatus(Id, new Status(Id, this, source, target, level, duration)));
     }
     return(target.GetStatus(Id).Reapply(bonusDuration, bonusLevel, bonusStacks));
 }
예제 #3
0
 /// <summary>
 /// Ensure all damage goes through this.
 /// </summary>
 /// <param name="target"></param>
 /// <param name="damage"></param>
 public void Damage(NoxUnit target, float damage)
 {
     DamageEngineIgnore = true;
     UnitDamageTarget(this, target, damage, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNIVERSAL, null);
     DamageEngineIgnore = false;
     if (IsUnitDeadBJ(target))
     {
         AwaitRemoval(target, this);                      // weird bug BECAUSE WC3REFUNDED SHIT HI-HI
     }
 }
예제 #4
0
        //public Status ApplyStatus(NoxUnit source, NoxUnit target, int level, float duration, int bonusLevel = 0, float bonusDuration = 0, )
        //{
        //    if (!target.ContainsStatus(Id))
        //        // create new status and add it to unit
        //        return target.AddStatus(Id, new Status(Id, this, source, target, level, duration));
        //    return target.GetStatus(Id).Reapply(bonusDuration, bonusLevel, 0);
        //}

//        [Obsolete]
//#pragma warning disable CS0809 // Obsolete member overrides non-obsolete member
        public override Status ApplyStatus(NoxUnit source, NoxUnit target, int level, float duration, int bonusLevel = 0, float bonusDuration = 0)
//#pragma warning restore CS0809 // Obsolete member overrides non-obsolete member
        {
            if (!target.ContainsStatus(Id))
            {
                // create new status and add it to unit
                return(target.AddStatus(Id, new Status(Id, this, source, target, level, duration)));
            }
            return(target.GetStatus(Id).Reapply(bonusDuration, bonusLevel, 0));
        }
예제 #5
0
 public void RegisterOnHit(NoxUnit whatUnit)
 {
     if (whatUnit.ContainsOnHit(Id))
     {
         whatUnit.GetOnHit(Id).Count++;
     }
     else
     {
         whatUnit.AddOnHit(Id, new OnHit(this));
     }
 }
예제 #6
0
 public void UnregisterOnHit(NoxUnit whatUnit)
 {
     if (whatUnit.ContainsOnHit(Id))
     {
         OnHit hit = whatUnit.GetOnHit(Id);
         hit.Count--;
         if (hit.Count == 0)
         {
             whatUnit.RemoveOnHit(Id);
         }
     }
 }
예제 #7
0
파일: OnHit.cs 프로젝트: AzuStar/NoxRaven
 /// <summary>
 /// Reverse the source and target to make it AmHit.
 /// </summary>
 /// <param name="source"></param>
 /// <param name="target"></param>
 public void ApplyOnHit(NoxUnit source, NoxUnit target, float damage, float processedDamage)
 {
     if (GetRandomReal(0, 1) < source.TriggerChance * Type.Chance)
     {
         if (!Type.Epic)
         {
             for (int i = 0; i < Count; i++)
             {
                 Type.Callback.Invoke(source, target, damage, processedDamage, this);
             }
         }
         else
         {
             Type.Callback.Invoke(source, target, damage, processedDamage, this);
         }
     }
 }
예제 #8
0
    // ****************
    // * Unit Methods *
    // ****************
    private void DamageHandler()
    {
        if (DamageEngineIgnore)
        {
            return;
        }
        if (GetEventDamage() < 1)
        {
            return;
        }
        NoxUnit source = Cast(GetEventDamageSource());

        BlzSetEventDamage(0);
        // ~this is the target
        //if (!Ranged) // later
        float dmg = source.WeaponDamage();

        source.DealPhysicalDamage(this, dmg, true, true, false, Ranged);
    }
예제 #9
0
    /// <summary>
    /// Do not call RemoveUnit on indexed unit or permaleak.
    /// </summary>
    /// <param name="u"></param>
    private static void AwaitRemoval(NoxUnit u, NoxUnit killer)
    {
        if (!Indexer.ContainsKey(GetHandleId(u)))
        {
            return;                                       // this is a very weird thing to happen, but will happen for Neutrals so yeah
        }
        if (u.Corpse)
        {
            return;
        }
        KillEvent @event = new KillEvent()
        {
            EventInfo = new NoxRaven.Events.Metas.KillMeta()
            {
                Killer = killer,
                Dying  = u
            }
        };

        killer.OnKill(@event);
        u.OnDeath(@event);

        foreach (Status st in u.Statuses.Values)
        {
            st.Remove();
        }
        u.Statuses.Clear();// just in case

        if (GetUnitAbilityLevel(u, FourCC("Aloc")) > 0)
        {
            return;                                             // wat
        }
        if (IsUnitType(u, UNIT_TYPE_HERO))
        {
            return;                                // always leak heroes
        }
        u.Corpse = true;

        Utils.DelayedInvoke(KeepCorpsesFor, () => { u.Remove(); }); // ah shiet, change to let resurrections
        //ue = null;
    }
예제 #10
0
 /// <summary>
 /// Permanent status.
 /// </summary>
 /// <param name="id"></param>
 /// <param name="type"></param>
 /// <param name="source"></param>
 /// <param name="target"></param>
 /// <param name="level"></param>
 /// <param name="duration"></param>
 /// <param name="stacking"></param>
 /// <param name="periodic"></param>
 private Status(int id, TimedType type, NoxUnit source, NoxUnit target, int level, int initialStacks, int stacksLim, float duration, float periodicTimeout, bool stacking, bool periodic, bool permanent = false)
 {
     //if(type.DataType != null)
     //Data = Activator.CreateInstance(type.DataType);
     Id       = id;
     Type     = type;
     Source   = source;
     Target   = target;
     Level    = level;
     Stacking = stacking;
     Periodic = periodic;
     //Permanent = permanent;
     PeriodicTimeout = periodicTimeout;
     StacksLim       = stacksLim;
     Duration        = duration;
     t = CreateTimer();
     if (periodic)
     {
         PeriodicTicks = 0;
         TimeRemain    = duration;
         TimerStart(t, PeriodicTimeout, false, PeriodicTimerRestart);
     }
     else
     {
         TimerStart(t, duration, false, Remove);
     }
     if (stacking)
     {
         Stacks = initialStacks;
     }
     if (Type.Apply != null)
     {
         Type.Apply.Invoke(this);
     }
     if (Type.Effectpath != null && Type.Attachment != null)
     {
         SpecialEffect = AddSpecialEffectTarget(Type.Effectpath, target._Self, Type.Attachment);
     }
 }
예제 #11
0
 public bool ContainsOnHit(NoxUnit whatUnit)
 {
     return(whatUnit.ContainsOnHit(Id));
 }
예제 #12
0
    /// <summary>
    /// Damage parsers that takes care of all calculations. Damage parser calculates outgoing damage from the unit.
    /// </summary>
    /// <param name="target">Whos is the target</param>
    /// <param name="damage"></param>
    /// <param name="triggerOnHit">Does it apply on-hit effects?</param>
    /// <param name="triggerCrit">Can it crit?</param>
    public void DealPhysicalDamage(NoxUnit target, float damage, bool triggerOnHit, bool triggerCrit, bool isSpell, bool isRanged)
    {
        if (damage < 0)
        {
            return;
        }
        location loc   = Location(GetUnitX(target) + GetRandomReal(0, 5), GetUnitY(target) + GetRandomReal(0, 5));
        float    pars  = damage;
        float    critC = CritChance;
        float    critD = CritDamage;

        // maths
        pars *= (1 - Math.Min(target.DamageReduction, 1));
        float armor = BlzGetUnitArmor(target);

        if (armor < 0)
        {
            pars *= (1.71f - Pow(1f - ARMOR_CONST, -armor)); // war3 real armor reduction is 1.71-pow(xxx) - why? - no idea
        }
        else
        {
            pars *= 1 / (1 + armor * ARMOR_CONST * (1 - ArmorPenetration));  // Inverse armor reduction function, got by solving: Armor * CONST / (1 + ARMOR * CONST)
        }
        //Event Pars
        DamageEvent parsThroughUnit = new DamageEvent()
        {
            EventInfo = new DamageMeta()
            {
                Source       = this,
                Target       = target,
                Damage       = damage,
                TriggerOnHit = triggerOnHit,
                TriggerCrit  = triggerCrit,
                IsSpell      = isSpell,
                IsRanged     = isRanged
            },

            ProcessedDamage = pars,
            CritChance      = critC,
            CritDamage      = critD
        };

        OnDealPhysicalDamage.Invoke(parsThroughUnit);
        target.OnRecievePhysicalDamage.Invoke(parsThroughUnit);
        pars  = parsThroughUnit.ProcessedDamage;
        critC = parsThroughUnit.CritChance;
        critD = parsThroughUnit.CritDamage;
        // The logic

        if (triggerCrit && GetRandomReal(0, 1) < critC)
        {
            pars *= critD;

            Utils.TextDirectionRandom(Utils.NotateNumber(R2I(pars)), loc, 8.5f, 255, 0, 0, 0, 1.3f, GetOwningPlayer(this));
            Utils.TextDirectionRandom(Utils.NotateNumber(R2I(pars)), loc, 8.5f, 255, 0, 0, 0, 1.3f, GetOwningPlayer(target));
        }
        else
        {
            Utils.TextDirectionRandom(Utils.NotateNumber(R2I(pars)), loc, 6.9f, 255, 0, 0, 0, 0.8f, GetOwningPlayer(this));
            Utils.TextDirectionRandom(Utils.NotateNumber(R2I(pars)), loc, 6.9f, 255, 0, 0, 0, 0.8f, GetOwningPlayer(target));
        }

        Damage(target, pars);

        if (isSpell)
        {
            Heal(pars * SpellVamp);
        }
        else
        {
            Heal(pars * Lifesteal);
        }
        // Now that's done
        // Onhits
        if (triggerOnHit)
        {
            List <OnHit> onhits = new List <OnHit>(OnHits.Values);
            foreach (OnHit onhit in onhits)
            {
                onhit.ApplyOnHit(this, target, damage, pars);
            }
            //ApplyAmHits(source);
        }

        // cleanup
        RemoveLocation(loc);
        loc = null;
    }
예제 #13
0
 /// <summary>
 /// Periodic Timed Stacking Status
 /// </summary>
 internal Status(int id, TimedType type, NoxUnit source, NoxUnit target, int level, float duration, float peridoticTimeout, int initialStacks, int stacksLim)
     : this(id, type, source, target, level, initialStacks, stacksLim, duration, peridoticTimeout, false, true)
 {
 }
예제 #14
0
 /// <summary>
 /// Periodic Timed Status
 /// </summary>
 internal Status(int id, TimedType type, NoxUnit source, NoxUnit target, int level, float duration, float periodicTimeout)
     : this(id, type, source, target, level, 0, 0, duration, periodicTimeout, false, true)
 {
 }
예제 #15
0
        ///// <summary>
        ///// Permanent Status
        ///// </summary>
        //internal Status(int id, StatusType type, NoxUnit source, NoxUnit target, int level)
        //    : this(id, type, source, target, level, 0, 0, 0, 0, false, false, true) { }

        ///// <summary>
        ///// Permanent Stacking
        ///// </summary>
        //internal Status(int id, StatusType type, NoxUnit source, NoxUnit target, int level, int initialStacks, int stacksLim)
        //    : this(id, type, source, target, level, initialStacks, stacksLim, 0, 0, true, false, true) { }

        ///// <summary>
        ///// Permanent Periodic
        ///// </summary>
        ///// <param name="id"></param>
        ///// <param name="type"></param>
        ///// <param name="source"></param>
        ///// <param name="target"></param>
        ///// <param name="level"></param>
        //internal Status(int id, StatusType type, NoxUnit source, NoxUnit target, int level)
        //    : this(id, type, source, target, level, 0, 0, 0, 0, false, true, true) { }

        /// <summary>
        /// Timed Status
        /// </summary>
        internal Status(int id, TimedType type, NoxUnit source, NoxUnit target, int level, float duration)
            : this(id, type, source, target, level, 0, 0, duration, 0, false, false)
        {
        }
예제 #16
0
 public OnHit GetOnHit(NoxUnit whatUnit)
 {
     return(whatUnit.GetOnHit(Id));
 }
예제 #17
0
 public Status GetStatus(NoxUnit unit) => unit.GetStatus(Id);
예제 #18
0
        /// <summary>
        /// Run when all static data is initialized.<br />
        /// Types taht need to be initialized before running: UnitEntity Custom Classes, Players, Items
        /// </summary>
        public static void RunAfterExtensionsReady()
        {
            int abilid = FourCC("AD00");

            for (int i = 0; i < NoxUnit.Abilities_BonusDamage.Length; i++)
            {
                NoxUnit.Abilities_BonusDamage[i] = abilid;
                if ((i + 1) % 10 == 0)
                {
                    abilid += 246;
                }
                abilid++;
            }
            abilid = FourCC("AR00");
            for (int i = 0; i < NoxUnit.Abilities_BonusArmor.Length; i++)
            {
                NoxUnit.Abilities_BonusArmor[i] = abilid;
                if ((i + 1) % 10 == 0)
                {
                    abilid += 246;
                }
                abilid++;
            }
            abilid = FourCC("CR00");
            for (int i = 0; i < NoxUnit.Abilities_Corruption.Length; i++)
            {
                NoxUnit.Abilities_Corruption[i] = abilid;
                if ((i + 1) % 10 == 0)
                {
                    abilid += 246;
                }
                abilid++;
            }
            abilid = FourCC("ST00");
            for (int i = 0; i < NoxHero.Abilities_Strength.Length; i++)
            {
                NoxHero.Abilities_Strength[i] = abilid;
                if ((i + 1) % 10 == 0)
                {
                    abilid += 246;
                }
                abilid++;
            }
            abilid = FourCC("AG00");
            for (int i = 0; i < NoxHero.Abilities_Agility.Length; i++)
            {
                NoxHero.Abilities_Agility[i] = abilid;
                if ((i + 1) % 10 == 0)
                {
                    abilid += 246;
                }
                abilid++;
            }
            abilid = FourCC("IN00");
            for (int i = 0; i < NoxHero.Abilities_Intelligence.Length; i++)
            {
                NoxHero.Abilities_Intelligence[i] = abilid;
                if ((i + 1) % 10 == 0)
                {
                    abilid += 246;
                }
                abilid++;
            }
            NoxUnit.InitUnitLogic();
            NoxItem.InitItemLogic();
            NoxAbility.InitAbilityLogic();
            TimerStart(CreateTimer(), 1800, true, GCRoutine);
        }
예제 #19
0
 public void Kill(NoxUnit whoToKill)
 {
     Kill(whoToKill);
     AwaitRemoval(this, whoToKill);
 }