HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Dark Lightning [OLY] Code Development

09-22-2008, 08:51 PM#1
Flame_Phoenix
Ok guys, this is another one of my spell for the spell Olympics. Although I am totally sure I can't win against Anitarf nor Griffen (my freaking Nemesis) I still think this is a spell people should see and I believe some of you may even like it.
The code is well commented, and I feel a system can be explored from the code. Unlike many other spells, I prepared this code for the user, this means the user is not limited only to the SETUP part, I also want the user to enter the code's core so he can also learn from my code and mainly make even better lightning spells. This is mainly why my code has many methods and why it is so divided, so people can actually use an easy and efficient "Divide and Conquer" strategy. This makes sections of the code easier to change.
I would really like to see this spell approved, it is my first working lightning spell, and it passed nearly through hell to make it work for Olympics.
I just feel bad I actually delivered a not perfect version of this spell... The Math formula is not what I exactly pretended, but it was what I could do with the time I had.
Please enjoy and be nice on comments, I put a lot of effort into making this spell for you, the user.

Credits:
This time I feel forced to tell explicitly the people who helped me making this spell. Note that without them this spell would have not been possible to make. Thx to Anitarf and Pyrogasm, both of them wasted many hours seeing my code, I can never thank them enough for what they did. I would also like to thank Daelin for his outdated, but useful math formulas and to Deaod as well.

Description:
A JESP spell that allows the user to create lightning spells with any model he desires. In this sample, the caster sends a dark projectile which will damage enemy units and heal the caster by the amount of damage they received. If an enemy unit dies due this ability, it will return as an Undead to aid the caster, unless it is a summon or a hero.

Click image for larger version

Name:	Dark Lightning.jpg
Views:	201
Size:	231.8 KB
ID:	37390

Requirements:
- Jass NewGen Pack (uses vJASS)
- TimerUtils

History:
Hidden information:

History
Versions 1.0, 1.2, 1.3, 1.4:
- This versions all had different approaches to try solving the same problem "How to make a lightning spell ?" but they all proved either to be inefficient or to fail
- Yes, I actually remade from zero the spell 3 times (without counting with version 1.0)

Version 1.5:
- First release to the spell Olympics
- Math formula improved
- Removed a useless timer
- Cleaned and commented the code

Version 1.6:
- The Math formula for damage reduction was still, wrong, so now it is corrected and now most things work as they should

Version 1.7:
- Code optimizations
- Fixed a glitch with the dummy unit, now it actually dies

Version 1.8:
- Made the function Targets easier to use
- Now the code has its own algorithm and re uses groups
- Added new function SetProjectile
- Many other minor code fixes and updates were done
- Added Anitarf to the credits

Version 1.9
- Changed the model of the missile to make it look better and now it works with flying units by changing its flying height properly
- Now the missile always faces the direction of the victim
- Improved the map and the terrain
- Changed the algorithm for picking units, now he picks close units to the target
- Now the effects appear on the units
- Now I also preload the units missile and the dummy

Version 2.0
- Now the abilities for the dummy unit are also preloaded
- Replaced SetUnitPosition with SetUnitX and SetUnitY, now the spell is faster!


Version 2.1
- Replaced some variables in order to make the preloading of the dummy unit faster.
- Cleaned the code and deleted old comments and code fragments as well as eliminated the "data = this" laziness

Version 2.2
- Now the code really works well with 1 single timer. Thx Pyrogasm and Anitarf!
- This spell would have not been possible without the people on the credits, Anitarf, Daelin, Deaod and Pyrogasm, thx to you all!


Collapse JASS:
//===========================================================================
//A JESP spell that allows the user to create lightning spells with any model
//he desires. In this sample, the caster sends a dark projectile which will 
//damage enemy units and heal the caster by the amount of damage they received.
//If an enemy unit dies due this ability, it will return as an Undead to aid 
//the caster, unless it is a summon or a hero.
//
//Requires TimerUtils
//
//@author Flame_Phoenix 
//
//@credits
//- Deaod, for all hi help in the code, with math formulas and advices
//- Anitarf, for math formulas and advices for efficiency
//- Pyrogasm, for giving me the algorithm for making the spell with 1 timer only
//- Daelin, for the math formulas on his outdated spells 
//
//@version 2.2
//===========================================================================
scope DarkLightning initializer Init
//===========================================================================
//=============================SETUP START===================================
//===========================================================================
   globals
        private constant integer AID = 'A000'   //rw of teh ability
        private constant real SPEED = 700.  //speed of the missile
        private constant integer MISSILE_ID = 'h000'    //rw of the missile
        private constant integer DUM_ID = 'h001'    //rw of the dummy unit
        private constant integer DUM_AB = 'A001'    //Ability of the dumy unit (animated dead)
        private constant string DUM_ORDER = "animatedead"   //string order of the dummy unit
        private constant real TIMER_CICLE = 0.03    //cicles of the timer
        private constant string DRAIN_EFFECT = "Abilities\\Spells\\Demon\\DarkPortal\\DarkPortalTarget.mdl"
        private constant string BLOOD_EFFECT = "Objects\\Spawnmodels\\Orc\\Orcblood\\BattrollBlood.mdl"
    endglobals
    
    private function Range takes integer level returns real
    //If there is more than one Target, a next target will be picked in a 500
    //AOE from the first
        return 500. + (level * 0)   
    endfunction
    
    private function Damage takes integer level returns real
    //Damage each Target will take
        return 100. * level
    endfunction
    
    private function Reduction takes integer level returns real
    //Damage reduction per Target
        return 0.15 + (level * 0)
    endfunction
    
    private function TargetsNumber takes integer level returns integer
    //The number of targets
        return 4 + (level * 1)
    endfunction
    
    private function Targets takes unit caster, unit target returns boolean
    //"caster" is the caster of the spell, and "target" is the target being evauated
        return IsUnitEnemy(target, GetOwningPlayer(caster)) and (IsUnitType(target, UNIT_TYPE_STRUCTURE) == false) and (IsUnitType(target, UNIT_TYPE_MAGIC_IMMUNE) == false) and (GetWidgetLife(target) > 0.405)
    endfunction
    
//===========================================================================
//=============================SETUP END=====================================
//===========================================================================

    globals
        private group g
        private boolexpr b
        private unit tmpCaster = null
        private timer t
        private integer instancesCount
    endglobals
    
//===========================================================================
    private function AceptedTargets takes nothing returns boolean
        return Targets(tmpCaster, GetFilterUnit())
    endfunction
    
    private struct SpellData 
        unit caster     //our caster !
        unit vic    //the current victim
        integer level   //the level of the ability
        group picked   //saves all targeted units so far, so they don't get picked again
        unit missile    //the missile
        real wait   //tells us how much time we must wait
        integer targNum   //Current number of the target
        real lastDamage //this tells us the last amount of damage a unit received. NOTE: this is NOT the damage a unit is taking.
        boolean done
        
        static method create takes unit caster, unit vic returns SpellData
            local SpellData data = SpellData.allocate()
            
            //setting variables
            set data.caster = caster
            set data.vic = vic
            set data.level = GetUnitAbilityLevel(caster, AID)
            set data.missile = CreateUnit(GetOwningPlayer(caster),  MISSILE_ID, GetUnitX(caster), GetUnitY(caster), 0)  
            set data.wait = 0.
            set data.targNum = 0
            set data.done = false
            
            //we recycle the group 
            if data.picked == null then
                set data.picked = CreateGroup()
            endif
            
            //here we add the caster to the picked group, just in case
            call GroupAddUnit(data.picked, data.vic)
            
            return data
        endmethod
        
        method SetProjectile takes nothing returns nothing
            local real a = GetUnitX(.missile) - GetUnitX(.vic)
            local real b = GetUnitY(.missile) - GetUnitY(.vic)
            local real d = SquareRoot(a*a + b*b) //the distance between "a" and "b"
            
            set .wait = d / SPEED
            
            //we adapt the fly height of the missile to the height of the target!
            call SetUnitFlyHeight(.missile, GetUnitFlyHeight(.vic), (GetUnitFlyHeight(.missile) - GetUnitFlyHeight(.vic)) / .wait)
        endmethod
        
        method TargetEffect takes nothing returns nothing 
            local unit dum
        
            //the hp the enemies will lose and that the caster will win
            if (.targNum == 0) then
                set .lastDamage = Damage(.level)
            else
                set .lastDamage = .lastDamage - (.lastDamage * Reduction(.level))
            endif
            
            //here we damage the bad guy ! Die you bastard !!!!
            //we also created the effects for both targets and caster
            call UnitDamageTarget(.caster, .vic, .lastDamage, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, null)
            call DestroyEffect(AddSpecialEffectTarget(DRAIN_EFFECT, .vic, "origin"))
            call DestroyEffect(AddSpecialEffectTarget(BLOOD_EFFECT, .caster, "origin"))
            
            //Heal the caster
            call SetWidgetLife(.caster, GetWidgetLife(.caster) + .lastDamage)
            
            if (GetWidgetLife(.vic) < 0.405)  and (IsUnitType(.vic, UNIT_TYPE_HERO) == false) and (IsUnitType(.vic, UNIT_TYPE_SUMMONED) == false) then
                set dum = CreateUnit(GetOwningPlayer(.caster), DUM_ID, GetUnitX(.vic), GetUnitY(.vic), 0)
                call UnitAddAbility(dum, DUM_AB)
                call SetUnitAbilityLevel(dum, DUM_AB, .level)
                call IssueImmediateOrder(dum, DUM_ORDER)
                call UnitApplyTimedLife(dum, 'BTLF', 1.)
            endif
            
            set dum = null
        endmethod
        
        method NextTarget takes nothing returns unit
            local unit f = null
            local unit ret = null
            
            //the position of the current target
            local real cX = GetUnitX(.vic)
            local real cY = GetUnitY(.vic)
            
            //the position of our new target
            local real nX
            local real nY
            
            //by saving the minimal distance, this will help us choose
            //the closest new target to our current target
            local real minDist = Range(.level)
            
            local real d //this will be a temporary variable for the distances we will calculate
            
            //here we pick all units near the last target
            set tmpCaster = .caster
            call GroupEnumUnitsInRange(g, GetUnitX(.vic), GetUnitY(.vic), Range(.level), b)
            
            loop
                set f = FirstOfGroup(g)
                exitwhen(f == null)
                call GroupRemoveUnit(g, f)
                if (IsUnitInGroup(f, .picked) == false) then
                    set nX = GetUnitX(f)
                    set nY = GetUnitY(f)
                    
                    //now we calculate the distance between f and our current target
                    set d = SquareRoot((nX - cX)*(nX - cX) + (nY - cY)*(nY - cY))
                    
                    //if this new distance is the smallest, then we update our target
                    if (d < minDist) then
                        set minDist = d
                        set ret = f
                    endif
                endif
            endloop
            return ret
        endmethod
        
        method ChainEffect takes nothing returns nothing
            //we add the victim to the victims groups, so we won't pick it twice
            call GroupAddUnit(.picked, .vic)
            
            //here we call the function responsable for the bad things we do to the bad guys xD
            call .TargetEffect()
            
            //now we increase the counter to know how many units we hit           
            set .targNum = .targNum + 1

            //if the number of our current target is lower than the maximum amount
            //of targets we can hit, we continue, else we end everything
            if (.targNum < TargetsNumber(.level)) then 
                
                //pick new target !
                set .vic = .NextTarget()
                
                //if the new unit is not null, we repeat this step, else we end
                if (.vic != null) then
                   call .SetProjectile()
                else
                    set .done = true
                endif
            else
                set .done = true
            endif
        endmethod
        
        method MoveMissile takes nothing returns nothing
            local real x1 = GetUnitX(.missile)
            local real x2 = GetUnitX(.vic)
            local real y1 = GetUnitY(.missile)
            local real y2 = GetUnitY(.vic)
            
            local real dx = TIMER_CICLE * (x2 - x1) / .wait  
            local real dy = TIMER_CICLE * (y2 - y1) / .wait
         
            call SetUnitX(.missile, x1 + dx)
            call SetUnitY(.missile, y1 + dy)
            
           //here we set the facing of the missile
            call SetUnitFacing(.missile, bj_RADTODEG * Atan2(y2 - y1, x2 - x1))
            
            set .wait = .wait - TIMER_CICLE
            
            //this is when the missile gets to the unit
            if .wait < TIMER_CICLE then
                
                call SetUnitX(.missile, x2)
                call SetUnitY(.missile, y2)
            
                //This runs the ChainEffect function again!
                call .ChainEffect()
            endif
        endmethod
        
        method onDestroy takes nothing returns nothing
            //we clear the gorup so we can use it later
            call GroupClear(.picked)

            //we destroy the projectile
            call ShowUnit(.missile, false)
            call KillUnit(.missile)
        endmethod
    endstruct
    
    globals
        private SpellData array datas
    endglobals
    
    private function Periodic takes nothing returns nothing
        local integer currentIndex = 0
        local SpellData currentInstance
        
        
        loop
            set currentInstance = datas[currentIndex]
            call currentInstance.MoveMissile() 
            
            //if our instance is done, we decrement the number of total instances
            //and then we check if there are any more instances being run
            if (currentInstance.done) then
                set instancesCount = instancesCount - 1
                
                //if there are, then we update our instance to the next of the array
                //and we correct the index
                if (instancesCount > 0) then
                    set datas[currentIndex] = datas[instancesCount]
                    set currentIndex = currentIndex - 1
                //else we just release the timer
                else
                    call ReleaseTimer(t)
                endif
                
                //now before we leave current instance for good, we destroy it!
                call currentInstance.destroy()
            
            endif
                
            set currentIndex = currentIndex + 1
            exitwhen currentIndex >= instancesCount
            
        endloop
    endfunction 
//===========================================================================    
    private function Conditions takes nothing returns boolean
        if GetSpellAbilityId() == AID then
            
            //if there are no instances of the spell then it means the timer does not
            //exist, so we create it and start it!
            if instancesCount == 0 then
                set t = NewTimer()
                call TimerStart(t, TIMER_CICLE, true, function Periodic)
            endif
            
            set datas[instancesCount] = SpellData.create(GetTriggerUnit(), GetSpellTargetUnit())
            call datas[instancesCount].SetProjectile()
            set instancesCount = instancesCount + 1
        
        endif

        return false
    endfunction
//===========================================================================
    private function Init takes nothing returns nothing
        local trigger LightningTrg = CreateTrigger(  )
        call TriggerRegisterAnyUnitEventBJ( LightningTrg, EVENT_PLAYER_UNIT_SPELL_EFFECT )
        call TriggerAddCondition( LightningTrg, Condition( function Conditions ) )
        
        set LightningTrg = null
        
        //setting globals
        set b = Condition(function AceptedTargets)
        set g = CreateGroup()
        set instancesCount = 0
        
        //Preload the effects
        call Preload(DRAIN_EFFECT)
        call Preload(BLOOD_EFFECT)
        
        //preloading units and spells
        set bj_lastCreatedUnit = CreateUnit(Player(0), DUM_ID, 0, 0, 0)
        call UnitAddAbility(bj_lastCreatedUnit, DUM_AB)
        call KillUnit(bj_lastCreatedUnit)
        
        call KillUnit(CreateUnit(Player(0), MISSILE_ID, 0, 0, 0))
    endfunction
endscope
Attached Images
File type: jpgDark Lightning.jpg (231.8 KB)
Attached Files
File type: w3xDark Lightning 2.2.w3x (39.2 KB)
09-24-2008, 01:00 PM#2
Anitarf
In the SpellData struct, why do you create&destroy the group when you could reuse it?

The struct SpellData doesn't really need the targMaxNum member since you can always get that value based on the spell's level.

The ChainEffect function should take a SpellData parameter, instead of getting it from the expired timer again.

If you're so keen on modularization, then why didn't you make this code a seperate function, since you use it twice?
Collapse JASS:
                set a = GetUnitX(data.missile) - GetUnitX(data.vic)
                set b = GetUnitY(data.missile) - GetUnitY(data.vic)
                set d = SquareRoot(a*a + b*b) //the distance between "a" and "b"
                set data.wait = d / SPEED
                
                //start moving the damn missile
                call SetTimerData(data.t, integer(data))
                call TimerStart(data.t, TIMER_CICLE, true, function MoveMissile)

Why do functions TargetEffect and NextTarget take an integer parameter, why can't they just take a SpellData parameter?

Why do you have the hp local variable in the function TargetEffect? You could just use data.lastDamage instead of it.

You don't give an expiration timer to your dummy casters, also, shouldn't you check if the victim was a summoned unit or a hero before creating them?

I think the calibration function for targets would look better if instead of using GetFilterUnit() it took parameters caster and target, it would look cleaner this way.

This spell could benefit a lot from using xe.
09-24-2008, 09:04 PM#3
Flame_Phoenix
Quote:
In the SpellData struct, why do you create&destroy the group when you could reuse it?
Because I don't know how to do it. For me, a code that reuses a group is not enough, I must also be able to understand it. I can always use NewGroup from CSSafety if you really want me to.

Quote:
The struct SpellData doesn't really need the targMaxNum member since you can always get that value based on the spell's level.
You are correct, I am fixing it right now.

Quote:
The ChainEffect function should take a SpellData parameter, instead of getting it from the expired timer again.
What are you talking about ? About which function ? How ? I am clueless, please explain this idea better.

Quote:
If you're so keen on modularization, then why didn't you make this code a seperate function, since you use it twice?
I guess I could create a function called StartProjectile or something that would take care of that, but I don't think that 6 lines justify the weight of calling another function. Besides that piece of code is well commented and it is really easy to change and understand, there is no real need.
However if you really want me to do it, I will do it. Main reason is that I didn't have time to change it, and now I really can't find a strong reason to do it =P

Quote:
Why do functions TargetEffect and NextTarget take an integer parameter, why can't they just take a SpellData parameter?
They do take a SpellData parameter (I mean they take the pointer that points to the structure) so I really don't see the big problem here ...
However (once again) if I really need to change this to see my spell approved you know I will...

Quote:
Why do you have the hp local variable in the function TargetEffect? You could just use data.lastDamage instead of it.
Again you are correct. This issue is fixed now =)
Quote:

You don't give an expiration timer to your dummy casters, also, shouldn't you check if the victim was a summoned unit or a hero before creating them?
LOL.. I can't believe I actually forgot to kill the dummy ... fixed =P
Well, that would be just complicating the spell... nothing will really change, I will create a dummy unit for nothing, so what ? ...
Bah, Anyway, I know that if I don't change this you are going to be mad at me or just think I am lazy so, I fixed that too lol...

Quote:
I think the calibration function for targets would look better if instead of using GetFilterUnit() it took parameters caster and target, it would look cleaner this way.
Afaik Conditions can NOT take parameters. I use a boolexpr "b" and function Targets its it's Condition. Therefore Although it could look cleaner, I currently don't know how to do it. Besides all spells (or most of them) always use GetFilterUnit() and people don't die by using it ... I really don't see the problem.
However, if you know of away that doesn't change the spell's core drastically, I may implement it (as long as it also doesn't reduce efficiency a lot too xD).
And don't use that modular thing as an excuse for your evil reasons, I believe there efficiency and code easy to understand like hell DO have a balance between xD

Quote:
This spell could benefit a lot from using xe.
Let's be honest for a moment my friend. I make no idea how to use xe or mostly of its modules. I would need some one to teach me, and let's face the fact, you don't want to teach me because I am a pain in the ass for you, and I don't have the time to actually learn an implement it decently before forgetting everything and start asking people questions about my own code again.
So, who would teach me ? Vexorian ? Let's be realistic, he wouldn't do it, he hates noobs who can't understand his "easy commented" code...
Pyrogasm ? I haven't see him for ages

I fear this is the price of honesty, but tonight I will sleep with my conscience clean, at least I don't give illusions to people. I will not implement xe, at least not for now.

I updated the code Anitarf, I hope you like it good enough to approve it now.
09-24-2008, 09:36 PM#4
Anitarf
Quote:
Originally Posted by Flame_Phoenix
Because I don't know how to do it. For me, a code that reuses a group is not enough, I must also be able to understand it. I can always use NewGroup from CSSafety if you really want me to.
CSSafety is deprecated, you can't use it anymore.
You understand that structs are just parallel arrays where each index can be a struct, right? Well, when you destroy a struct instance it's index gets released and may be reused the next time you create a struct of that type. Therefore, if you don't destroy a group that is stored in a struct's member when you destroy the struct, that group will still be there when a new struct gets the old struct's index. So it's simple.

Quote:
What are you talking about ? About which function ? How ? I am clueless, please explain this idea better.
Fix this:private function ChainEffect takes nothing returns nothing
Quote:
I guess I could create a function called StartProjectile or something that would take care of that, but I don't think that 6 lines justify the weight of calling another function.
Sure they justify it. You've added function calls to this spell despite not saving any lines with them, and now you're suddenly worried about the weight of a function call. The code isn't even running on a fast periodic timer or anything like that!

Quote:
They do take a SpellData parameter (I mean they take the pointer that points to the structure)
So, they don't really take a SpellData parameter, since them taking a SpellData parameter would look like this: private function TargetEffect takes SpellData data returns nothing
Quote:
Afaik Conditions can NOT take parameters. I use a boolexpr "b" and function Targets its it's Condition. Therefore Although it could look cleaner, I currently don't know how to do it.
You could try calling the calibration function from the Condition.

Quote:
Let's be honest for a moment my friend. I make no idea how to use xe or mostly of its modules. I would need some one to teach me,
You could teach yourself by reading the documentation, or looking at the samples, the xe map has plenty of both. Anyway, this was more of a by-the-way comment, I couldn't demand that you use a specific system even if I wanted to.
09-24-2008, 11:09 PM#5
Pyrogasm
I'm here, lulz.

My advice: read the documentation. xe isn't really that hard to understand and it's DAMN useful.
09-25-2008, 10:33 AM#6
Flame_Phoenix
Quote:
CSSafety is deprecated, you can't use it anymore.
You understand that structs are just parallel arrays where each index can be a struct, right? Well, when you destroy a struct instance it's index gets released and may be reused the next time you create a struct of that type. Therefore, if you don't destroy a group that is stored in a struct's member when you destroy the struct, that group will still be there when a new struct gets the old struct's index. So it's simple.
Ahhh, now I think I can make that for my code, I will try.

Quote:
Fix this:private function ChainEffect takes nothing returns nothing
You don't want me to call this function based on a timer ? How would I do it than ?

Quote:
Sure they justify it. You've added function calls to this spell despite not saving any lines with them, and now you're suddenly worried about the weight of a function call. The code isn't even running on a fast periodic timer or anything like that!
Jesus you are so damn inconvenient when you want to. I will add a new function ..

Quote:
So, they don't really take a SpellData parameter, since them taking a SpellData parameter would look like this: private function TargetEffect takes SpellData data returns nothing
Ok, I will fix this in next version.

Quote:
You could try calling the calibration function from the Condition.
Wouldn't this make things horribly slower !?

Quote:
You could teach yourself by reading the documentation, or looking at the samples, the xe map has plenty of both. Anyway, this was more of a by-the-way comment, I couldn't demand that you use a specific system even if I wanted to.
I don't have time to teach myself, and if I do so, I will need some one to answer all questions that will arise from my learning process.
I may use xe, but for now I just want to see my pending spells approved.
09-25-2008, 11:05 AM#7
Anitarf
Quote:
Originally Posted by Flame_Phoenix
You don't want me to call this function based on a timer ? How would I do it than ?
You would do it the way you're already doing it, what timer are you talking about?
Quote:
Wouldn't this make things horribly slower !?
No, not horribly.
09-25-2008, 08:27 PM#8
Flame_Phoenix
Quote:
You would do it the way you're already doing it, what timer are you talking about?
My bad, that thing is actually a piece of ghost code I forgot to delete (damn my OLY submission must really be bad, poor me =S ).
I am even most surprised this works at all with that !

Quote:
No, not horribly.
HA ! But you can't deny it, it makes the code SLOWER !!!
I find it weird, you guys are also so keen with super efficient spells and codes, and now you want me to make something slower lol.
Anyway, I don't give speed that much importance, and I kinda like the idea, so it's done.

Ok guys, the new version of code is now released.
I corrected everything as asked (except the "xe"thing, but I hope you all understand, I can't do it right now. Maybe later I will transform this into a template, and there I will use that thing).
Please just see my recycle group thing in the structure, I think it works because I remember seeing a code made by Moycak that looks like that, but I am not sure.

Be kind on comments as usual, and I hope now I changed the spell enough to please you.
10-04-2008, 08:58 AM#9
Flame_Phoenix
48 hours passed:

- bumb for justice ! -
10-04-2008, 02:19 PM#10
Captain Griffen
Stop bumping your thread. It will get looked at in due course. The more impatient you are, the more towards the back of the queue you will go.

Now stop being impatient and stop insulting the mods.
10-04-2008, 04:41 PM#11
Flame_Phoenix
Quote:
Stop bumping your thread. It will get looked at in due course. The more impatient you are, the more towards the back of the queue you will go.

Now stop being impatient and stop insulting the mods.

1 - bumb is allowed after 48 hours. If you want to punish me for bumb, you will have to punish Vestras (per example) as well, he also does it and many other people do it.
Besides this is the 1st time I successfully bumb this thread.

2 - I am not impatient. I just noticed mods were forgetting this section due their long time of inactivity. I don't want this to become THW spell submission thread.

3 - I insulted no one here. I only spoke the truth of what I was observing. If you don't like the truth don't blame me, I didn't caused it. Besides, saying the truth was never an insult. Anyway, post deleted, I understand your position as a mod.
10-04-2008, 05:06 PM#12
Captain Griffen
Mods are not forgetting this section, their priorities are just different. This is a busy period for various mods for various reasons. Mods are not "lazy" as you alledge - they put in far more work than can actually be reasonably expected of anyone.
10-04-2008, 09:39 PM#13
Flame_Phoenix
Quote:
they put in far more work than can actually be reasonably expected of anyone.
you don't know everyone, therefore you can't state such a thing. There are people out there who want to learn and be as good mods as Anitarf, Moyack, you or Vexorian, they just need to be given a chance or some one who is willing to train them.
Besides, when you say "mods work very hard", as far as I know, I only see Anitarf working hard, all other mods either seem to disappear for long periods of time or they just don't help much ...
I face I don't know all mods from Wc3c, but if you give a quick look to the spell submissions, you will in fact conclude that it is Anitarf who is doing most of the job .. alone...
You don't even need to go that far, just look at this thread.... who has been the only mod to helping me ?? Take a wild guess - Anitarf.
10-04-2008, 09:43 PM#14
Captain Griffen
I don't think you've quite gotten it, yet, have you? Mods work for the site and its users for free; if you ever actually want this to get reviewed, I'd suggest you stop whining about the staff.
10-04-2008, 09:45 PM#15
Flame_Phoenix
Quote:
Mods work for the site and its users for free
Well, duh...

Allow me to quote myself:
Quote:
you don't know everyone, therefore you can't state such a thing. There are people out there who want to learn and be as good mods as Anitarf, Moyack, you or Vexorian, they just need to be given a chance or some one who is willing to train them.
Which means there are people who also want to do it for free ... Anyway

Quote:
I'd suggest you stop whining about the staff.
I am not complaining, I am merely an observant of the truth and I am just commenting it.

Anyway, I feel this is getting a lot off-topic, I believe both of us should stop now ...