• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Mini-Contest - Hive Member

Status
Not open for further replies.

contest.....png

Enhance the created hero, based on your team submission!


The goal of this Mini Contest is to continue the submissions of our Team Contest - Hive Member. It is not possible to join if you did not entry said contest, and so creating a new hero from scratch is not allowed, too.

Theme Criteria

The goal is completing the hero, making it a round thing. Very important is that it's not required to make extreme changes in already submitted work, but more to optimize it, to add something new and up achieve an overall good synergy. For example, if the current icons are already good as they are, then you don't have to change them - but if you realize the icons don't match anymore with maybe new icons, then you should change them accordingly. What is important in the end is the result of the hero, not mainly the pure progress/changes from old to new submission.

Though there are some technical requirements of course, to ensure it is a complete hero. There must exist:
  • 1 model with appropriated animations.
  • 4 spells - they must be recognized as custom spells, but the ObjectEditor is also very welcome to be used as tool. It's not required to be purely coded spells.
  • Icons. As many icons as you need for your hero, or spells. Important is that all icons are exclusively created for the hero.
As side note:
Even you don't perfectly make all animations, or don't get done all wanted spells, or icons, you are still very welcome to participate and to present your changes!

Team Criteria

  • Teams stay the same, defined here.
  • It's not allowed to add, or to change a team member.
  • If a team member does not participate in this Mini Contest, he will be excluded from results team of course, meaning also not gaining reputation.

Rules


Rules pretty much apply from old contest, but with some adjustments:

  • 1 WIP team-post is enough. Though the WIP post should slightly cover all planned changes that have to be done. For example, talk a bit about new spell concepts, or planned visual changes.
    If prefered, all team members can of course post WIPs them selves, too, without relying on one team WIP.
  • Giving critiques is still prefered given inside teams, but now also giving tips to other teams is allowed unless it doesn't mean making their technical work. Basically feedback is allowed by anyone.
  • You still should post your assets in the respective Resource Section, but the threads there won't be locked.
  • The test map's name should be: "[Mini Contest]" + <team> + "-" + <hero name>

Prizes
  • First Place: 12 reputation points
  • Remaining entries: 6 reputation points
  • Judge: 6 reputation points

Judging / Results
  • free judge #1
  • free judge #2
PM me if you're interested.



Creativity and Concept
Are the chosen concepts interesting and maybe even somewhat unique, or are they boring and make no sense?/10

Synergy
How well do created assets work together? Do the spells feel weirdly mixed? Do the icons match the spells, and does the model look good when making spells? etc../20

Balance
Is the hero overpowered, or maybe too weak? Does he only make sense in a very specific scenario, or could it be used more widely?/20

Technical note
Do the animations look good/bad? Are the spells badly designed? Are the icons simply copy & pastes? etc../20

/70
  • Judgement: 60%
  • Poll: 40%
FinalScore = (40*Reached_Poll_Percentage) + (60*Reached_Judge_Percentage)


Deadline

The Mini Contest shall begin on 2nd March 2018 and conclude on 31 March 2018 GMT (day is included). There won't be any extensions.


 
Last edited:

Kyrbi0

Arena Moderator
Level 45
Joined
Jul 29, 2008
Messages
9,502
Love it! Not just the idea (follow-up Contest, a Hero Contest, using & improving on old Contest stuff), but the willingness to execute it. : )

I'll talk with my team, but you can be sure that at least I'll be entering. : D

;;; )))
 
Last edited:

Kyrbi0

Arena Moderator
Level 45
Joined
Jul 29, 2008
Messages
9,502
Hmm.. why don't we try having a new team contest instead of improving the previous?
I'm not feeling it for this one
We can do both... This one is sufficiently "lite" to not strain people too much, methinks.

~~

Speaking of which, just as a note, I'm a little concerned about work-load/reward distribution for this one. I was concerned for the main Contest, but now the tables are turned; instead of being weighted too heavily towards the artists (especially the Modeler most of all), this Contest weighs much more heavily on the Coder than on either of the Artists (Icon-er is close, though).

It's true the Modeler could entirely remake the model, or the Icon-er totally re-do all icons... But the baseline expectations for this Contest are now expecting a lot more from the Coder than from the other two.

Now, we didn't change the rewards for the last Contest (i.e. giving more to the Artists who did more & less to the Coders who did less), and so I don't know that we should change anything here. (even though it affects me more greatly this time around, for several reasons I'm not gonna campaign against it).


Really what I bring this is up for is to point out that, in any given Team Contest, we really oughta take a careful look at what is being required of whom, adjust those requirements as equitably as possible, and challenge/reward people appropriately. : )

~~~

Giving critiques is still prefered given inside teams, but now also giving tips to other teams is allowed unless it doesn't mean making their technical work. Basically feedback is allowed by anyone.
Very glad to see this. : )

I've got thoughts on the Criteria but, another day. Don't worry about it.
 
@RED BARON , I saw your post, yes, and I'm sorry for it. Timing is I think always a bit problematic, and if you as one person say already next month is bad timing then I thought it might be wasted time and situation trying to wait for all. Though, maybe we can let the thread open a bit longer and move it elsewhere, not to archive straight, so you can add something later, too. : )

Really nice that you wanna use the chance (those who already stated it).

For sharing workload - I was told by @Murlocologist that the modeler can spend much time for perfecting animations, and that it can be a very big task. I think here the modeler can work on such things, when he before focused more on how the model statically looks. Coding itself can be very wide, I know from myself. You can do 4 spells very quick, if you do the bare minimum, and use standard procedures and tequniques that you're already used to. But if you create new concepts you might face difficult problems that take time to solve, and then coding one spell might take a good while, too. Making icons will probably depend much though on other team guys, too, as it might be hard to create some new icons without having any other input like a new spell. But I hope team will arrange.

I've got thoughts on the Criteria
I might well think it might be improved a bit. I intuitilvly wrote some frame which I though differs a bit from most technical criteria from before, but it might be I didn't cover up all wanted points. It's also wanted always, not too overload given criteria, but if some feedback is given we for sure might improve them a bit, and lastly then for further contests, too. :)
 
Level 35
Joined
Oct 9, 2006
Messages
6,392
@RED BARON , I saw your post, yes, and I'm sorry for it. Timing is I think always a bit problematic, and if you as one person say already next month is bad timing then I thought it might be wasted time and situation trying to wait for all. Though, maybe we can let the thread open a bit longer and move it elsewhere, not to archive straight, so you can add something later, too. : )

Really nice that you wanna use the chance (those who already stated it).

For sharing workload

No worries :smile: But keeping it open or perhaps just allowing a post to be added to it, so there is context could be fine. Stil I dunno about the rest of the group, so might be pointless.

As for workload: It really depends on the person and effort. Creating more spells for the hero also requires creating more icons. If the model is already done, I'd say that the modeler has the least amount of work. But everything can be improved and something can be made as a bare minimum, so heck its hard as hell to judge.

Well, instead of making new icons, those who drew them could do textures this time to compensate workload of other members.

Yea, texture work was for our group planned to be something I worked on (given warp it never really came true, but hey).
 
Didn't realize there was a mini-contest.
By reading the purpose of the mini-contest, all I can say is:

@MyPad said:
Heh heh heh.... :mwahaha:

All I have to do now is to enable some triggers, and help out in creating the new icons with @Darkfang.

EDIT:

Some WIP:
upload_2018-3-3_16-35-37.png


upload_2018-3-3_16-36-1.png


upload_2018-3-3_16-36-43.png


Code WIP (Actually finished)
JASS:
library OvermindSpellOne initializer Init requires /*

    *   ---------------
    */  RealGroup,   /*
    *   ---------------
    *       -   Allows outsourcing of dynamic data attachment.
    *
    *   ---------------
    */  TextTag,     /*
    *   ---------------
    *       -   A library requirement for displaying game information related to the spell.
    *
    *   ------------------
    */  TimerUtils,    /*
    *   ------------------
    *       -   An abstraction library for timers. It allows requesting of to-be recycled timers,
    *           in an O[1] fashion.
    *
    *   ---------------------
    */  AllocationAndLinks /*
    *   ---------------------
    *       -   Updated allocator module that considers the new maximum count of array instances.
    *
    */

    scope OvermindSpellUno

        globals
            /*
                A flag that basically allows debugging of functions
            */
            private constant boolean ALLOW_DEBUG = false
        endglobals
       
        /*
            Configurable functions:
           
                These are the functions which are okay to modify:
                    RAW_ID(integer request)
                   
                    DATA(integer request, integer level)
                   
                    MDL_FILE(integer request)
                   
                SPELL_DM(int req)
                    -   A separate function that stores certain rawcodes to be used in the scope
                        By default, it returns 0. (not a float)
               
                DATA(int req, int lev)
                    -   The most versatile function, this function can essentially serve as 
                        the softcoded Object Editor fields which can be tinkered with.
                        Defaults to 0f.
                       
                        Some requests indicate a default value for a requested instance. In
                        that case, if you need to modify, you can do so. However, those
                        that are not defined as defaulting to a certain value will not work
                        with your modifications.
                       
                    -   This is somewhat considered as a magic numbers' function.
                       
                MDL_FILE(int req)
                    -   Another versatile function, this function stores the appropriate strings
                        to be used later on.
                        Defaults to "".
        */
       
        //  Spell raw code
        private constant function SPELL_ID takes nothing returns integer
            return 'A000'
        endfunction
       
        private constant function RAW_ID takes integer request returns integer
            if request == 0 then
                //  The illusion ability to be used
                return '0000'
            elseif request == 1 then
                //  The illusion's timed buff
                return 'B001'
            endif
            return 0
        endfunction

        private constant function DATA takes integer request, integer level returns real
            if request == 0 then
                //  Returns damage dealt per tick in puddle
                if level == 1 then
                    return 25.
                elseif level == 2 then
                    return 35.
                elseif level == 3 then
                    return 50.
                endif
               
            elseif request == 1 then
                //  Returns damage dealt on puddle evaporation
                if level == 1 then
                    return 50.
                elseif level == 2 then
                    return 70.
                elseif level == 3 then
                    return 90.
                endif
               
            elseif request == 2 then
                //  Returns the tick rate of the puddle.
                //  Defaults to 1.
                return 1.
               
            elseif request == 3 then
                //  Returns the duration of the illusion
                if level == 1 then
                    return 10.
                elseif level == 2 then
                    return 15.
                elseif level == 3 then
                    return 20.
                endif
           
            elseif request == 4 then
                //  Returns damage received by the illusion
                if level == 1 then
                    return 1.25
                elseif level == 2 then
                    return 1.25
                elseif level == 3 then
                    return 1.25
                endif
           
            elseif request == 5 then
                //  Returns the speed of the bile projectile
                //  Defaults to 700.
                return 700.
           
            elseif request == 6 then
                //  Returns the tick rate of the movement
                //  Also functions as the transition rate of visibility.
                return 1/50.
           
            elseif request == 7 then
                //  Returns the duration of transition of visibility.
                return 1.5
               
            elseif request == 8 then
                //  Returns the range check for damaging nearby units
                //  Defaults to 250.
                return 250.
            endif
            return 0.
        endfunction
       
        private constant function MDL_FILE takes integer request returns string
            if request == 0 then
                //  Returns the model string of the projectile
                return "Abilities\\Weapons\\ChimaeraAcidMissile\\ChimaeraAcidMissile.mdl"
            elseif request == 1 then
                //  Returns the puddle model
                //  For now, it defaults to the above string
                return MDL_FILE(0)
            endif       
            return ""
        endfunction
       
        /*
            Spell code:
           
                This section deals with the actual mechanics of the spell. It is not recommended
            to modify the spell code other than inserting debug messages.
           
                The class is named Data since the class is encapsulated and does not need a detailed
            name.
           
                class Data implements AllocLinkBundle
                        - Importing the coder's own allocation and linked list bundle
               
                    private static code exec_code
                        - A variable generated to prevent a trigger evaluation and duplication of functions
                       
                    private static timer EVAL
                        - A timer specifically for handling the list in the class.
                          Should not be destroyed.
                         
                    private static boolean EVAL_ACT
                        - A flag to determine if the timer is running or not.
                       
                    private integer flag
                        - A flag to determine the current phase of the spell.
                       
                    private unit dummy
                        - Stores a newly-created dummy unit for effect purposes.
                       
                    private effect missile_fx
                        - Only used for the dummy unit as a projectile
                          model.
                                               
                    private effect missile_fx2
                    private effect missile_fx3
                        - Reserved as pool model. Change MDL_FILE(1) to the model file of your choice.

                    readonly unit unit
                        - The actual casting unit.
                       
                    readonly unit illusion
                        - The current illusion unit.
                       
                    readonly unit target
                        - The target of the ability.
                       
                    readonly integer level
                        - An integer storing the spell level of the casting unit. (SPELL_ID()
                   
                    readonly RealGroup reals
                        - A variable that allows dynamic mapping of variables as they are requested.
                          For more info, see Essential Libraries/Real Group
               
                class functions
                   
                    -function destroy()
                        -> Does exactly what it is defined, destroying and clearing the instance.
                       
                    -static function get_illu(unit id) returns Data
                        -> Searches for the illusion that dealt damage.
                    -static function get(unit id) returns Data
                        -> Searches for the caster.
                       
                    -static function create(unit u) returns Data
                        -> Creates an instance mapped to the unit.
                       
                    -private static function onManipulateDamage()
                        -> Search illusion, and apply necessary handler changes.
                       
                    -private static function onSummon()
                        -> Detects a summon event by the dummy.
                       
                    -
        */
       
        //! runtextmacro link_module("search", "private")
       
        private struct Data extends array
            implement AllocLinkBundle
           
            private static code exec_code = null
           
            private static timer EVAL = null
            private static boolean EVAL_ACT = false
           
            private integer flag
            private integer flag_data
           
            private real fade
           
            private unit dummy
            private effect missile_fx
            private effect missile_fx2
            private effect missile_fx3
           
            readonly unit unit
            readonly unit illusion
            readonly unit target
           
            readonly integer level
           
            readonly RealGroup reals
           
            private method destroy takes nothing returns nothing
                call reals.destroy()
               
                set unit = null
                set target = null
               
                set dummy = null
               
                set reals = 0
                set level = 0
               
                set flag = 0
                set fade = 0
                set flag_data = 0
               
                call pop()
                call deallocate()
            endmethod
           
           
            //! runtextmacro search_list("", "get_illu", "unit", "next", "illusion == id")

            //! runtextmacro search_list("", "get", "unit", "next", "unit == id")
           
            static method create takes unit u, unit targ returns thistype
                local thistype this = get(u)
               
                if this == 0 then
                    set this = allocate()
                    set unit = u
                    set target = targ
                    set level = GetUnitAbilityLevel(u, SPELL_ID())
                   
                    set fade = DATA(7, 0)
                    set flag = 1
                    set flag_data = 255
                                   
                    call IssueImmediateOrderById(unit, 851972)
                    call PauseUnit(unit, true)
                   
                    set reals = RealGroup.create()
                    set reals.value = DATA(3, level)
                   
                    call reals.add(GetUnitX(unit))
                    call reals.add(GetUnitY(unit))
                   
                    call push()
                   
                    if not EVAL_ACT then
                        call TimerStart(EVAL, DATA(6, 0), true, exec_code)
                        set EVAL_ACT = true
                    endif
                endif
                return this
            endmethod
           
            private static unit damaged = null
            private static thistype damaged_this = 0
           
            private static method onManipulateDamage takes nothing returns nothing
                local thistype this
               
                if damaged != Damage.target then
                    set this = get_illu(Damage.target)
                    set damaged_this = this
                    set damaged = Damage.target
                else
                    set this = damaged_this
                endif
               
                if this != 0 then
                    set Damage.amount = Damage.amount * DATA(4, level)
                endif
            endmethod
           
            implement DoubleLink_search
           
            private unit summoned
            private unit summoned_illu
           
            private thistype summoned_this
            private static thistype summoned_count = 0
           
            private static method onSummon takes nothing returns nothing
                local thistype this = thistype(0).search_next.summoned_this
               
                call DestroyTrigger(GetTriggeringTrigger())
                set thistype(0).search_next.summoned = GetSummonedUnit()
               
                call UnitRemoveAbility(thistype(0).search_next.summoned_illu, RAW_ID(0))
                call RecycleDummy(thistype(0).search_next.summoned_illu)
                       
                call SelectUnit(unit, false)
               
                call ShowUnit(unit, false)
                call SetUnitInvulnerable(unit, true)
               
                call SetUnitX(thistype(0).search_next.summoned, GetUnitX(unit))
                call SetUnitY(thistype(0).search_next.summoned, GetUnitY(unit))
               
                call PauseUnit(thistype(0).search_next.summoned, true)
                   
                if GetLocalPlayer() == GetOwningPlayer(unit) then
                    call SelectUnit(thistype(0).search_next.summoned, true)
                endif
               
                set illusion = thistype(0).search_next.summoned
               
                call UnitApplyTimedLife(illusion, 'BTLF', DATA(3, level) - 0.5)
               
                set summoned_count = summoned_count - 1
               
                set thistype(0).search_next.summoned = null
                set thistype(0).search_next.summoned_illu = null
               
                set thistype(0).search_next.summoned_this = 0
               
                call thistype(0).search_next.search_pop()
            endmethod
           
            private method timer_onTick_enum takes integer i, integer i2 returns nothing
                local player p = GetOwningPlayer(unit)
                call GroupEnumUnitsInRange(ENUM_GROUP, reals[i].value, reals[i + 1].value, DATA(8, level), null)
                //! runtextmacro FoG_start()
                    if IsUnitEnemy(enum_unit, p) and UnitAlive(enum_unit) then
                        call UnitDamageTarget(unit, enum_unit, DATA(i2, level), true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_UNIVERSAL, null)
                    endif
                //! runtextmacro FoG_end()
                set p = null
            endmethod
           
            private static method timer_onTick takes nothing returns nothing
                local thistype this = GetTimerData(GetExpiredTimer())
                local integer i = 1
               
                set reals.value = reals.value - DATA(2, level)
                if reals.value <= 0 or not UnitAlive(illusion) then
                    call ReleaseTimer(GetExpiredTimer())
                    set i = i + 2
                    loop
                        exitwhen i >= reals.number_count
                   
                        call DestroyEffect(AddSpecialEffect(MDL_FILE(0), reals[i].value, reals[i + 1].value))
                        call timer_onTick_enum(i, 1)
                   
                        set i = i + 2
                    endloop
                    set fade = 1.5
                    set flag = 4
                   
                    call UnitDamageTarget(unit, illusion, 0, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNIVERSAL, null)
                    call KillUnit(illusion)
               
                    set illusion = null
                   
                    call PauseUnit(unit, false)
                   
                    call ShowUnit(unit, true)
                    call SetUnitInvulnerable(unit, false)
                   
                    call SetUnitX(unit, reals[3].value)
                    call SetUnitY(unit, reals[4].value)               
                   
                    call SelectUnit(unit, true)
               
                    call DestroyEffect(missile_fx2)
                    call DestroyEffect(missile_fx3)
                   
                    set missile_fx2 = null
                    set missile_fx3 = null
                else
                    loop
                        exitwhen i >= reals.number_count
                       
                        call DestroyEffect(AddSpecialEffect(MDL_FILE(0), reals[i].value, reals[i + 1].value))
                        call timer_onTick_enum(i, 0)
                       
                        set i = i + 2
                    endloop
                endif
            endmethod
           
            private method actions takes nothing returns nothing
                local trigger detector
               
                local unit illu
               
                local real r
               
                local real r1
                local real r2
                local real r3
                local real r4
               
                if flag == 1 then
                    set flag_data = Math.int_max(R2I(flag_data - (flag_data - 0)/fade*DATA(6, 0)), 0)
                    call SetUnitVertexColor(unit, 255, 255, 255, flag_data)
                   
                    set fade = fade - DATA(6, 0)
                   
                    call DestroyEffect(AddSpecialEffect(MDL_FILE(0), reals[1].value, reals[2].value))
                   
                    if fade <= 0 then
                        set illu = GetRecycledDummyAnyAngle(GetUnitX(unit), GetUnitY(unit), GetUnitFlyHeight(unit))
                        set summoned_count = summoned_count + 1
                        call summoned_count.search_push()
                       
                        set summoned_count.summoned_illu = illu
                       
                        call UnitAddAbility(illu, RAW_ID(0))
                        call SetUnitOwner(illu, GetOwningPlayer(unit), true)
                       
                        set detector = CreateTrigger()
                        call TriggerRegisterUnitEvent(detector, illu, EVENT_UNIT_SUMMON)
                        call TriggerAddCondition(detector, function thistype.onSummon)
                       
                        set detector = null
                       
                        set summoned_count.summoned_this = this
                        call IssueTargetOrderById(illu, 852274, unit)
                       
                        set illu = null
                       
                        set fade = 0.5
                       
                        set flag = 2
                        set flag_data = 0
                       
                        set summoned_count.summoned = null
                       
                        set missile_fx2 = AddSpecialEffect(MDL_FILE(1), GetUnitX(unit), GetUnitY(unit))
                        call TimerStart(NewTimerEx(this), DATA(2, 0), true, function thistype.timer_onTick)
                    endif
                   
                elseif flag == 2 then
               
                    if fade == 0.5 then
                        set illu = illusion
                       
                        call SetUnitAnimation(illu, "attack")
                        call QueueUnitAnimation(illu, "stand")
                       
                        set illu = null
                    elseif fade <= 0 then
                        set illu = illusion
                       
                        call PauseUnit(illu, false)
                       
                        set illu = GetRecycledDummy(reals[1].real, reals[2].real, GetUnitFlyHeight(illu), Math.radA(reals[1].real, reals[2].real, GetUnitX(target), GetUnitY(target)))
                        set missile_fx = AddSpecialEffectTarget(MDL_FILE(0), illu, "origin")
                       
                        set dummy = illu
                       
                        set flag = 3
                        set fade = 0
                       
                        set illu = null
                        return
                    endif
                   
                    set fade = fade - DATA(6, 0)

                elseif flag == 3 then
               
                    set illu = dummy
                   
                    set r1 = GetUnitX(target)
                    set r2 = GetUnitY(target)
                   
                    set r3 = GetUnitX(illu)
                    set r4 = GetUnitY(illu)
                   
                    set r = Math.rad(GetUnitX(illu), GetUnitY(illu), r1, r2)
                   
                    if Math.dist(GetUnitX(illu), GetUnitY(illu), r1, r2) <= DATA(5, level)*DATA(6, 0) then
                        call reals.add(r1)
                        call reals.add(r2)

                        call SetUnitX(illu, reals[3].real)
                        call SetUnitY(illu, reals[4].real)
                       
                        call DestroyEffect(missile_fx)
                        set missile_fx = null
                       
                        call DummyAddRecycleTimer(illu, 1.)
                        set flag = 0
                       
                        set missile_fx3 = AddSpecialEffect(MDL_FILE(1), reals[3].real, reals[4].real)
                    else
                        call SetUnitX(illu, GetUnitX(illu) + DATA(5, level)*DATA(6, 0)*Cos(r))
                        call SetUnitY(illu, GetUnitY(illu) + DATA(5, level)*DATA(6, 0)*Sin(r))
                       
                        call SetUnitFacing(illu, r*bj_RADTODEG)                   
                    endif
                   
                    set illu = null
               
                elseif flag == 4 then
                   
                    set flag_data = (R2I(flag_data - (flag_data - 255)/fade*DATA(6, 0)))
                    call SetUnitVertexColor(unit, 255, 255, 255, flag_data)
                   
                    set fade = fade - DATA(6, 0)
                   
                    call DestroyEffect(AddSpecialEffect(MDL_FILE(0), reals[3].value, reals[4].value))
                   
                    if fade <= 0 then
                        set flag_data = 255
                        call SetUnitVertexColor(unit, 255, 255, 255, flag_data)
                       
                        call destroy()
                    endif
                endif
            endmethod
           
            private static method timer_onLoop takes nothing returns nothing
                local thistype this = thistype(0).next
                local integer i = 0
                loop
                    exitwhen this == 0
                   
                    //  On timer loop
                    call actions()
                   
                    set this = next
                    set i = i + 1
                endloop
                if i == 0 then
                    call PauseTimer(EVAL)
                    set EVAL_ACT = false
                endif
            endmethod
           
            private static method onInit takes nothing returns nothing
                set EVAL = CreateTimer()
               
                set exec_code = function thistype.timer_onLoop
               
                call Damage.registerModifier(function thistype.onManipulateDamage)
            endmethod
        endstruct
       
        private function OnSpellEffect takes nothing returns nothing
            if GetSpellAbilityId() == SPELL_ID() then
                call Data.create(GetTriggerUnit(), GetSpellTargetUnit())
            endif
        endfunction
       
        public function Init takes nothing returns nothing
            local trigger t = CreateTrigger()
           
            call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
            call TriggerAddCondition(t, function OnSpellEffect)
           
            set t = null
        endfunction
    endscope

    scope OvermindSpellTwo
       
        private constant function SPELL_ID takes nothing returns integer
            return 'A001'
        endfunction
       
        private constant function RAW_ID takes integer request returns integer
            if request == 0 then
                return '1000'
            endif
            return 0
        endfunction
       
        private constant function DATA takes integer request, integer level returns real
            if request == 0 then
                //  Returns the amount of damage absorbed as life-force
                if level == 1 then
                    return 0.06
                elseif level == 2 then
                    return 0.08
                elseif level == 3 then
                    return 0.10
                endif
            elseif request == 1 then
                //  Returns a flag for allowing Manabreak
                //  If return type is not zero, flag is true; else false.
                if level == 1 then
                    return 0.
                elseif level == 2 then
                    return 0.
                elseif level == 3 then
                    return 0.
                endif
            elseif request == 2 then
                //  Returns ratio of manabreak based on damage dealt.
                //  Depends on the above flag in order to work.
                if level == 1 then
                    return 0.5
                elseif level == 2 then
                    return 1.25
                elseif level == 3 then
                    return 2.
                endif
            elseif request == 3 then
                //  Returns the number of stacks stored.
                //  Has a maximum of 64 stacks.
                //  Negative value will allow instantaneous restoration of mana per blow.
                if level == 1 then
                    return 8.
                elseif level == 2 then
                    return 14.
                elseif level == 3 then
                    return 20.
                endif
            elseif request == 4 then
                //  Returns the ratio of damage dealt based on stored stacks.
                if level == 1 then
                    return 0.5
                elseif level == 2 then
                    return 1.25
                elseif level == 3 then
                    return 2.
                endif
            elseif request == 5 then
                //  Returns a flag for allowing Manaburst
                //  If return type is not zero, the flag is true; else false.
                if level == 1 then
                    return 0.
                elseif level == 2 then
                    return 1.
                elseif level == 3 then
                    return 1.
                endif
            elseif request == 6 then
                //  Returns the Area of effect for Manaburst.
                if level == 1 then
                    return 200.
                elseif level == 2 then
                    return 200.
                elseif level == 3 then
                    return 200.
                endif
            elseif request == 7 then
                //  Returns the flag for considering unit's max mana
                //  If return type is zero; flag is true; else false
                if level == 1 then
                    return 0.
                elseif level == 2 then
                    return 0.
                elseif level == 3 then
                    return 1.
                endif
            elseif request == 8 then
                //  Results into the maximum number of stacks.
                //  Cannot be modified via assigning of level.
                return 64.
            endif
            return 0.
        endfunction
       
        private constant function MDL_FILE takes integer request returns string
            if request == 0 then
                return "Objects\\Spawnmodels\\NightElf\\NECancelDeath\\NECancelDeath.mdl"
            elseif request == 1 then
                return "Abilities\\Spells\\Human\\Feedback\\ArcaneTowerAttack.mdl"
            elseif request == 2 then
                return "Abilities\\Spells\\Human\\Polymorph\\PolyMorphDoneGround.mdl"
            endif
            return ""
        endfunction
       
        private struct Data extends array
            implement AllocLinkBundle
           
            readonly unit unit

            readonly integer count
            readonly integer level
           
            readonly real amount
           
            //  See AllocationAndLinks for the textmacro implementation
            //! runtextmacro search_list("", "get", "unit", "next", "unit == id")
           
            static method create takes unit u returns thistype
                local thistype this = get(u)
           
                if this == 0 then
                    set this = allocate()
                    set unit = u
                   
                    call push()
                endif
               
                set level = GetUnitAbilityLevel(unit, SPELL_ID())
               
                if DATA(3, level) <= 0 then
                    call UnitRemoveAbility(unit, RAW_ID(0))
                else
                    call UnitAddAbility(unit, RAW_ID(0))
                    call SetUnitAbilityLevel(unit, RAW_ID(0), level)
                endif
                return this
            endmethod
           
            private method erupt_damage takes nothing returns nothing
                local player p = GetOwningPlayer(unit)
               
                call CreateTextTagBJ(p, GetUnitX(unit) - 40, GetUnitY(unit), 70, 0, 255, 255, I2S(R2I(amount*DATA(4, level))))
                set vj_lastCreatedTextTag.duration = 3.5
                set vj_lastCreatedTextTag.fade = 2.75
                set vj_lastCreatedTextTag.height = 13
               
                call GroupEnumUnitsInRange(ENUM_GROUP, GetUnitX(unit), GetUnitY(unit), DATA(6, level), null)
                //! runtextmacro FoG_start()
                    if IsUnitEnemy(enum_unit, p) and UnitAlive(enum_unit) then
                        call DestroyEffect(AddSpecialEffectTarget(MDL_FILE(2), enum_unit, "chest"))
                        call UnitDamageTarget(unit, enum_unit, amount*DATA(4, level), true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNIVERSAL, null)
                    endif
                //! runtextmacro FoG_end()
                set p = null
            endmethod
           
            static method erupt takes unit u returns nothing
                local thistype this = get(u)
               
                if this == 0 then
                    debug call stdLib.throwError("Error; data was not initialized.")
                    debug return
                    set this = create(u)
                endif
               
                if amount == 0 then
                    call stdLib.throwError("Amount to be restored is zero.")
                    call IssueImmediateOrderById(unit, 851972)
                    call UnitRemoveAbility(unit, RAW_ID(0))
                    call UnitAddAbility(unit, RAW_ID(0))
                    return
                endif
               
                if DATA(3, level) > 0 then
                    call DestroyEffect(AddSpecialEffectTarget(MDL_FILE(0), unit, "chest"))
                    call SetUnitMana(unit, GetUnitMana(unit) + amount)
                   
                    if DATA(5, level) != 0 then
                        call erupt_damage()
                    endif
                   
                    set amount = 0.
                    set count = 0
                endif
            endmethod
           
            private static method onDamage takes nothing returns nothing
                local thistype this = get(Damage.source)
                local trigger t = GetTriggeringTrigger()
               
                if this == 0 and GetUnitAbilityLevel(Damage.source, SPELL_ID()) != 0 then
                    set this = create(Damage.source)
                endif
               
                if IsUnitEnemy(Damage.target, GetOwningPlayer(Damage.source)) and this != 0 then
                    //  If the number of stacks is infinite
                    if DATA(3, level) > 0 then
                        //  Stores the maximum amount of life force
                        if count < Math.real_min(DATA(3, level), DATA(8, 0)) then
                            set amount = amount + Damage.amount*DATA(0, level)
                            set count = count + 1
                        //  Keeping the debug stuff just in case it breaks.
                        endif
                    else
                        //  Sets unit's mana (acts as a wrapper)
                        call SetUnitMana(unit, GetUnitMana(unit) + Damage.amount*DATA(0, level))
                    endif
                   
                    if DATA(1, level) != 0 then
                        if (DATA(7, level) == 0) or (DATA(7, level) != 0 and GetUnitMaxMana(Damage.target) != 0.) then
                            //  Disables the current trigger which fires on Damage event.
                            call DisableTrigger(t)
                       
                            //  Apply special effect
                            call DestroyEffect(AddSpecialEffectTarget(MDL_FILE(1), Damage.target, "chest"))
                            call UnitDamageTarget(unit, Damage.target, Damage.amount*DATA(0, level)*DATA(2, level), true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNIVERSAL, null)
                           
                            call EnableTrigger(t)
                        endif
                    endif
                endif
                set t = null
            endmethod
           
            private static method onInit takes nothing returns nothing
                local trigger t = CreateTrigger()
               
                call Damage.registerTrigger(t)
                call TriggerAddCondition(t, function thistype.onDamage)
               
                set t = null
            endmethod
        endstruct
       
        private function OnHeroLevel takes nothing returns nothing
            if GetTriggerEventId() == EVENT_PLAYER_HERO_SKILL then
                if GetLearnedSkill() == SPELL_ID() then
                    call Data.create(GetTriggerUnit())
                endif
            elseif GetTriggerEventId() == EVENT_PLAYER_UNIT_SPELL_EFFECT then
                if GetSpellAbilityId() == RAW_ID(0) then
                    call Data.erupt(GetTriggerUnit())
                endif
            endif
        endfunction
       
        public function Init takes nothing returns nothing
            local trigger t = CreateTrigger()
           
            call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_HERO_SKILL)
            call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
            call TriggerAddCondition(t, function OnHeroLevel)
           
            set t = null
        endfunction
    endscope

    private function Init takes nothing returns nothing
        call OvermindSpellUno_Init()
        call OvermindSpellTwo_Init()
    endfunction
endlibrary
 

Attachments

  • upload_2018-3-3_16-36-20.png
    upload_2018-3-3_16-36-20.png
    1.6 MB · Views: 72
Last edited:
By the way. I wasn't sure how to define new results calculation for this Extra Contest, but I thought including judges might be prefered. I'm lacking of willing people, though, so anyone who knows candidates can feel very welcome to ask them. : )

Judges should not be an expert in each field, of course, that's most likely not possible. Having knowledge in one, or two fields is good enough, as the technical note is not major anyway. What would be more important is to take an overall look at the hero aspects, not too much in technical details.

Thanks. Like 2 judges would be good I guess. But as alternative if we really noone wants we can think about making a poll-only decission.
 
Level 7
Joined
May 30, 2013
Messages
210
Hmm.

How about opening up this contest, allowing different people/teams each submit their own finished version of the hero? (for instance -afair- none of the heroes submitted in the initial contest have full 4 spells)
Ie, we get to see different people's interpretation of each hero.

Just a suggestion.
Sorry for being late too, just saw the thread.
 
Level 7
Joined
May 30, 2013
Messages
210
Well, it wouldn't disallow them to finish their submission themselves, now would it? It'd just mean that we'd have different versions created by different people.
We could call the initial teams' submissions the official finished submission, but isn't the point of a contest to entice as many (new) participants to participate?
Besides, it'd be interest to see different people's interpretation of the heroes .. at the very least, I'd find it interesting :^]
 
I understand they can also still finish them selves. My concern was letting others modify their work for very same contes as long as they're still unfinished with the work them selves. I tend against this honestly, and would prefer every team finishes its own submission.

Not sure to seperate between official and unofficial at that point, because if it's for me, then everyone surely can participate "unofficialy" at any contest at any time. If you for example feel interested to take up some work of Delorin Hero and make your variation you always can make it unofficialy, and if you want you can share it in this thread, too.

Finding many participants is one point, but not the only point I would say.
It surely is interesting to see more intepretations, but I would prefer having seen then more initial submissions, instead of basing it on an "in progress" hero of an other team.

I don't find the idea bad in general, to take up something and to create variations, we should keep this in mind for coming events.
 
Level 37
Joined
Jul 22, 2015
Messages
3,485
By the way. I wasn't sure how to define new results calculation for this Extra Contest, but I thought including judges might be prefered. I'm lacking of willing people, though, so anyone who knows candidates can feel very welcome to ask them. : )
I think results should strictly be about concept and synergy. For judges, have you asked @Kam if he was interested? If I remember correctly, Kam was the "concept" judge for Hero Contest #8.
 

Kyrbi0

Arena Moderator
Level 45
Joined
Jul 29, 2008
Messages
9,502
@IcemanBo , quick question; what should we name the maps? I want to avoid filename issues (both on my computer & with the Hive's bundle function), but there's no replacement Rule to the original Contest's Rule of "<team name> - <hero name>.w3x". Should/Can we append "Mini" or "Redux" or something to the name?

I think results should strictly be about concept and synergy. For judges, have you asked @Kam if he was interested? If I remember correctly, Kam was the "concept" judge for Hero Contest #8.
Not 'Creativity/Uniqueness/Originality', or 'Balance'?
 
Should/Can we append "Mini" or "Redux" or something to the name?
Sounds ok, added: "The test map's name should be: "[Mini Contest]" + <team> + "-" + <hero name>"

Yeh, I added "Technical note", because there still can be some points to gain/lose, like for spells if there are tons of leaks, etc. But sure, it's not only goal here.
 

Kyrbi0

Arena Moderator
Level 45
Joined
Jul 29, 2008
Messages
9,502
Well, let's get this thing rolling: I've got a WIP for my re-entry (lol); already started by renaming things, moving them around, and retrofitting the Ultimate spell (Grim Rupture) in a way that will ultimately make my coding even less necessary. xD
upload_2018-3-9_22-51-23.png


(Just messaged my old team-mates to see if they're interested in pitching in, but I'm nearly done & will be submitting anyway)
 

Kyrbi0

Arena Moderator
Level 45
Joined
Jul 29, 2008
Messages
9,502
I mean.. technically true..

But that is not a full entry is it?
Did... You read the Rules carefully?

The only truly *required* elements are the 3 additional spells to "complete" the entry as a hero. Additional icons/textures/models/animations are neat, and will involve your teammates (in case they want in on the reward), but not strictly necessary.

So you can just whip up 3 more spells & call it a day (though of course, take care to read the Criteria; stuff like Balance & Synergy & such will matter this time).
 

Kyrbi0

Arena Moderator
Level 45
Joined
Jul 29, 2008
Messages
9,502
God as much as I want to make time for this, school hit me like a truck right when the contest started. In addition, I still have a lot of mod responsibilities to finish off, and I don't want to look like I'm avoiding them by participating in this contest. Sorry team :*(
Like heck, just throw some standard OE abilities on there; it doesn't have to be coded, just a complete Hero. : )
 
Status
Not open for further replies.
Top