• 🏆 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!

Icon/Model/Spell Team Contest - Hive Member[+100 Rep]

Status
Not open for further replies.
I always thought of this guy when I thought about personifying Direfury.

tumblr_owdybv8xGW1w0yro5o2_250.gif
I don't know if it fits, but hell if that dark archon did not destroy its sc2 counterpart in the terms of looks :cgrin: I mean, look at those flares
 

Kyrbi0

Arena Moderator
Level 44
Joined
Jul 29, 2008
Messages
9,487
Well, i just suggest it because i see someone need a modeller while I kinda can do it
:V

There is demand, there is supply xd jkjk

I dont want good concept to just die like that

Eitherway, if im allow to do that great, if not allow, well, thats just make sense anyway
Well, it's not *completely* without precedent... IIRC a similar situation was found in a Contest, and the solution was to simply disregard that user's contributions (in terms of points; i.e. they couldn't get double points by being in two teams). Not sure how that works with the Poll, but...

@IcemanBo ?
 
Level 11
Joined
Dec 19, 2012
Messages
411
Second WIP from me :

Wurst:
package MooseCharge

/*==================================================================================================*
*                                                                                            
*    Spell Description :
*    
*       Not yet ready...
*                                                                                  
*===================================================================================================*
*
*       Import ClosureTimers for :
*           1. uses class CallbackPeriodic          */
import ClosureTimers

/*
*       Import LinkedListModule for :
*           1. Turn class into LinkedList           */
import LinkedListModule

/*
*       Import IsPathWalkable which uses :
*           1. isPathWalkable()                     */
import IsPathWalkable

/*
*       Import ClosureForGroups which uses :
*           1. forUnitsInRect()                     */
import ClosureForGroups

/*
*       Import Assets which uses :
*           1. Abilities.defendCaster              
*           2. Abilities.shockwaveMissle            */
import Assets

/*
*==================================================================================================*
*
*   Import Instructions :
*
*       Not yet ready...
*
*==================================================================================================*
*
*   Configuration :
*
*       Configuration should be done in MooseCharge_config.wurst
*
/*================================================================================================*/





/*============================================Globals=============================================*/
/** Spell id*/
@configurable constant SPELL_ID                 = 'A000'

/** Spell required charging time*/                                
@configurable constant CHARGE_TIME              = 2.0

/** Determine if spell is interruptable while caster is channelling*/
@configurable constant INTERRUPTABLE_CHANNEL    = true

/** Determine if spell is interruptable while caster is charging*/
@configurable constant INTERRUPTABLE_CHARGING   = true

/** Spell duration after completed charging time*/
@configurable constant SPELL_DURATION           = 3.0

/** Unit's charging animation index*/
@configurable constant CHARGE_ANIMATION_INDEX   = 1

/** Unit's charging animation speed*/
@configurable constant CHARGE_ANIMATION_SPEED   = 1.

/** Starting charging speed*/
@configurable constant START_SPEED              = 100.

/** Maximum charging speed*/
@configurable constant MAX_SPEED                = 500.

/** Speed increase per second*/
@configurable constant ACCELERATION             = 25.

/** Speed decrease per second after reached SPELL_DURATION*/
@configurable constant DEACCELERATION           = 50.

/** Determine if deacceleration will still apply after hitting a unit*/
@configurable constant DEACCELERATE_AFTER_HIT   = false

/** Determine if spell will be continued even after hitting a unit*/
@configurable constant CONTINUE_HIT             = true

/** Periodic run time*/
@configurable constant PERIODIC_TIME            = 0.03125

/** Effect that will be displayed when moose started it charging phase*/
@configurable constant EFFECT_CHARGING          = Abilities.shockwaveMissile

/** EFFECT_CHARGING attachment point*/
@configurable constant CHARGE_ATTACH_POINT      = "chest"

/** Effect that will be displayed when hitting non-pathable path*/
@configurable constant EFFECT_HIT_PATH          = Abilities.defendCaster

/** Effect that will be displayed when hitting a unit*/
@configurable constant EFFECT_HIT_UNIT          = Abilities.defendCaster

/** EFFECT_HIT_PATH and EFFECT_HIT_UNIT attachment point*/
@configurable constant HIT_ATTACH_POINT         = "head"

/** Determine the rect hit size of x for detecting hittable unit*/
@configurable constant HIT_SIZE_X               = 128

/** Determine the rect hit size of y for detecting hittable unit*/
@configurable constant HIT_SIZE_Y               = 128

/** Acceleration speed increases per PERIODIC_TIME*/
constant ACCELERATION_PER_TICK                  = ACCELERATION*PERIODIC_TIME

/** Cargo hold ability id*/
constant CARGO_HOLD                             = 'Abun'

/** Half offset of */
constant HALF_X_OFFSET                          = HIT_SIZE_X/2

/** Half offset of */
constant HALF_Y_OFFSET                          = HIT_SIZE_Y/2

/** Function for filtering out unit who shouldn't get damaged*/
@configurable function hittable(unit caster, unit toHit) returns bool
    return not toHit.isType(UNIT_TYPE_STRUCTURE)

/** Function define the circumstances where if occur, channelling will be interrupted*/
@configurable function chanellingInterrupt(unit caster) returns bool
    return false

/** Function define the circumstances where if occur, charging will be interrupted*/
@configurable function chargingInterrupt(unit caster) returns bool
    return false
/*================================================================================================*/





/*=============================================Enums==============================================*/
enum SpellPhase
    Channel
    Charging
    Deaccelerate
/*================================================================================================*/





/*================================================================================================*/
class Charge
    use LinkedListModule

    //----------------------Ordinary Globals----------------------
    private unit        caster

    private real        distPerTick
    private real        curSpeed            = START_SPEED
    private real        timeLeft            = CHARGE_TIME
    //------------------------------------------------------------


    //-----------------------Tuple Globals------------------------
    private vec2        curPos
    private angle       ang
    //------------------------------------------------------------


    //------------------------Enum Globals------------------------
    private SpellPhase  sp                  = Channel
    //------------------------------------------------------------



    //===================Creation/Destroy Functions===================
    construct(unit caster)
        this.caster = caster
            ..setPropWindow(0.)
            ..addAbility(CARGO_HOLD)
            ..setAnimation(CHARGE_ANIMATION_INDEX)
            ..setTimeScale(CHARGE_ANIMATION_SPEED)

        this.curPos = caster.getPos()
      
        if Charge.size == 1
            Charge.cbp.start(PERIODIC_TIME)

    ondestroy
        //remove all applied effects
        this.caster
            ..removeAbility(CARGO_HOLD)
            ..setPropWindow(GetUnitDefaultPropWindow(this.caster))
            ..setTimeScale(1.)
            ..issueImmediateOrder("stop")

        this.caster = null
        Charge.size--

        if Charge.size == 0
            destroy Charge.cbp
    //================================================================



    //=========================Core Functions=========================
    /** Terminate the spell immediately, by definining whether to apply (stun) effect to caster, and apply (dmgAmount) to (target) (damage will be skipped if dmgAmount is 0 or target is null)*/
    private function terminate(bool stun, real dmgAmount, unit target)
        if stun
            //Stun caster

        if target == null
            //Applies effect to caster for hitting non-pathable path
            this.caster.addEffect(EFFECT_HIT_PATH, HIT_ATTACH_POINT)
        else
            //Applies effect to caster for hitting a unit
            this.caster.addEffect(EFFECT_HIT_UNIT, HIT_ATTACH_POINT)
      
            if dmgAmount > 0
                this.caster.damageTarget(target, dmgAmount)

        destroy this

    private static CallbackPeriodic cbp = (CallbackPeriodic cb) ->
    begin
        for instance in Charge
            if instance.sp == SpellPhase.Channel
            //-----------Phase 1 : Channel-----------
                //if charging time is done
                if instance.timeLeft <= 0
                    instance.sp = SpellPhase.Charging
                    instance.timeLeft = SPELL_DURATION
                //if interruptable and defined interrupt condition is true
                else if INTERRUPTABLE_CHANNEL and chanellingInterrupt(instance.caster)
                    destroy instance
            //------------End of Phase 1-------------
            else if instance.sp == SpellPhase.Charging
            //----------Phase 2 : Charging-----------
                //update caster facing angle
                instance.ang = instance.caster.getFacingAngle()

                //if reached maximum charging time
                if instance.timeLeft <= 0
                    instance.sp = SpellPhase.Deaccelerate
                    instance.timeLeft = instance.curSpeed/DEACCELERATION
                else
                    //if charging speed is not maxed
                    if instance.curSpeed < MAX_SPEED
                        instance.curSpeed += ACCELERATION_PER_TICK

                        if instance.curSpeed > MAX_SPEED
                            instance.curSpeed = MAX_SPEED

                        instance.distPerTick = instance.curSpeed*PERIODIC_TIME

                    //get caster next position
                    var nextPos = instance.curPos.polarOffset(instance.ang, instance.distPerTick)

                    //check if linear path from caster to next position is walkable
                    var path = isPathWalkable(instance.curPos, nextPos)

                    //if walkable
                    if path.walkable
                        //create a rect which centered at nextPos with width of HIT_SIZE_X and height of HIT_SIZE_Y
                        let r = Rect(nextPos.x-HALF_X_OFFSET, nextPos.y-HALF_Y_OFFSET, nextPos.x+HALF_X_OFFSET, nextPos.y+HALF_Y_OFFSET)
                      
                        forUnitsInRect(r, (unit u) ->
                        begin
                            if not u == instance.caster
                                if u.isType(UNIT_TYPE_STRUCTURE)
                                    //terminate spell
                                    instance.terminate(true, 1., u)

                                if hittable(instance.caster, u)
                                    //knock back unit
                        end)
                        instance.curPos = nextPos

                        //update caster position
                        instance.caster.setPos(nextPos)

                        //destroy rect
                        RemoveRect(r)
                    //not walkable, terminate spell
                    else
                        instance.terminate(true, 0, null)

                  
            //------------End of Phase 2-------------
            else if instance.sp == SpellPhase.Deaccelerate
            //--------Phase 3 : Deaccelerate---------
            //------------End of Phase 3-------------

            instance.timeLeft -= PERIODIC_TIME
    end
    //================================================================



    //=======================Accessor Functions=======================
    /** Check if unit (u) if it in spell instance*/
    static function contains(unit u) returns bool
        for instance in Charge
            if instance.caster == u
                return true

        return false
    //================================================================

/*================================================================================================*/

function onChannel() returns bool
    let u = GetTriggerUnit()

    if GetSpellAbilityId() == SPELL_ID and not Charge.contains(u)
        new Charge(u)
  
    return false
  
init
    CreateTrigger()
         ..registerAnyUnitEvent(EVENT_PLAYER_UNIT_SPELL_CHANNEL)
         ..addCondition(Condition(function onChannel))


I remember previously there is someone asking why posting spell code as WIP, because it is the easiest way to show your WIP, .gif file may causes thread to load unnecessary long.
 
Second WIP from me :

Wurst:
package MooseCharge

/*==================================================================================================*
*                                                                                           
*    Spell Description :
*   
*       Not yet ready...
*                                                                                 
*===================================================================================================*
*
*       Import ClosureTimers for :
*           1. uses class CallbackPeriodic          */
import ClosureTimers

/*
*       Import LinkedListModule for :
*           1. Turn class into LinkedList           */
import LinkedListModule

/*
*       Import IsPathWalkable which uses :
*           1. isPathWalkable()                     */
import IsPathWalkable

/*
*       Import ClosureForGroups which uses :
*           1. forUnitsInRect()                     */
import ClosureForGroups

/*
*       Import Assets which uses :
*           1. Abilities.defendCaster             
*           2. Abilities.shockwaveMissle            */
import Assets

/*
*==================================================================================================*
*
*   Import Instructions :
*
*       Not yet ready...
*
*==================================================================================================*
*
*   Configuration :
*
*       Configuration should be done in MooseCharge_config.wurst
*
/*================================================================================================*/





/*============================================Globals=============================================*/
/** Spell id*/
@configurable constant SPELL_ID                 = 'A000'

/** Spell required charging time*/                               
@configurable constant CHARGE_TIME              = 2.0

/** Determine if spell is interruptable while caster is channelling*/
@configurable constant INTERRUPTABLE_CHANNEL    = true

/** Determine if spell is interruptable while caster is charging*/
@configurable constant INTERRUPTABLE_CHARGING   = true

/** Spell duration after completed charging time*/
@configurable constant SPELL_DURATION           = 3.0

/** Unit's charging animation index*/
@configurable constant CHARGE_ANIMATION_INDEX   = 1

/** Unit's charging animation speed*/
@configurable constant CHARGE_ANIMATION_SPEED   = 1.

/** Starting charging speed*/
@configurable constant START_SPEED              = 100.

/** Maximum charging speed*/
@configurable constant MAX_SPEED                = 500.

/** Speed increase per second*/
@configurable constant ACCELERATION             = 25.

/** Speed decrease per second after reached SPELL_DURATION*/
@configurable constant DEACCELERATION           = 50.

/** Determine if deacceleration will still apply after hitting a unit*/
@configurable constant DEACCELERATE_AFTER_HIT   = false

/** Determine if spell will be continued even after hitting a unit*/
@configurable constant CONTINUE_HIT             = true

/** Periodic run time*/
@configurable constant PERIODIC_TIME            = 0.03125

/** Effect that will be displayed when moose started it charging phase*/
@configurable constant EFFECT_CHARGING          = Abilities.shockwaveMissile

/** EFFECT_CHARGING attachment point*/
@configurable constant CHARGE_ATTACH_POINT      = "chest"

/** Effect that will be displayed when hitting non-pathable path*/
@configurable constant EFFECT_HIT_PATH          = Abilities.defendCaster

/** Effect that will be displayed when hitting a unit*/
@configurable constant EFFECT_HIT_UNIT          = Abilities.defendCaster

/** EFFECT_HIT_PATH and EFFECT_HIT_UNIT attachment point*/
@configurable constant HIT_ATTACH_POINT         = "head"

/** Determine the rect hit size of x for detecting hittable unit*/
@configurable constant HIT_SIZE_X               = 128

/** Determine the rect hit size of y for detecting hittable unit*/
@configurable constant HIT_SIZE_Y               = 128

/** Acceleration speed increases per PERIODIC_TIME*/
constant ACCELERATION_PER_TICK                  = ACCELERATION*PERIODIC_TIME

/** Cargo hold ability id*/
constant CARGO_HOLD                             = 'Abun'

/** Half offset of */
constant HALF_X_OFFSET                          = HIT_SIZE_X/2

/** Half offset of */
constant HALF_Y_OFFSET                          = HIT_SIZE_Y/2

/** Function for filtering out unit who shouldn't get damaged*/
@configurable function hittable(unit caster, unit toHit) returns bool
    return not toHit.isType(UNIT_TYPE_STRUCTURE)

/** Function define the circumstances where if occur, channelling will be interrupted*/
@configurable function chanellingInterrupt(unit caster) returns bool
    return false

/** Function define the circumstances where if occur, charging will be interrupted*/
@configurable function chargingInterrupt(unit caster) returns bool
    return false
/*================================================================================================*/





/*=============================================Enums==============================================*/
enum SpellPhase
    Channel
    Charging
    Deaccelerate
/*================================================================================================*/





/*================================================================================================*/
class Charge
    use LinkedListModule

    //----------------------Ordinary Globals----------------------
    private unit        caster

    private real        distPerTick
    private real        curSpeed            = START_SPEED
    private real        timeLeft            = CHARGE_TIME
    //------------------------------------------------------------


    //-----------------------Tuple Globals------------------------
    private vec2        curPos
    private angle       ang
    //------------------------------------------------------------


    //------------------------Enum Globals------------------------
    private SpellPhase  sp                  = Channel
    //------------------------------------------------------------



    //===================Creation/Destroy Functions===================
    construct(unit caster)
        this.caster = caster
            ..setPropWindow(0.)
            ..addAbility(CARGO_HOLD)
            ..setAnimation(CHARGE_ANIMATION_INDEX)
            ..setTimeScale(CHARGE_ANIMATION_SPEED)

        this.curPos = caster.getPos()
     
        if Charge.size == 1
            Charge.cbp.start(PERIODIC_TIME)

    ondestroy
        //remove all applied effects
        this.caster
            ..removeAbility(CARGO_HOLD)
            ..setPropWindow(GetUnitDefaultPropWindow(this.caster))
            ..setTimeScale(1.)
            ..issueImmediateOrder("stop")

        this.caster = null
        Charge.size--

        if Charge.size == 0
            destroy Charge.cbp
    //================================================================



    //=========================Core Functions=========================
    /** Terminate the spell immediately, by definining whether to apply (stun) effect to caster, and apply (dmgAmount) to (target) (damage will be skipped if dmgAmount is 0 or target is null)*/
    private function terminate(bool stun, real dmgAmount, unit target)
        if stun
            //Stun caster

        if target == null
            //Applies effect to caster for hitting non-pathable path
            this.caster.addEffect(EFFECT_HIT_PATH, HIT_ATTACH_POINT)
        else
            //Applies effect to caster for hitting a unit
            this.caster.addEffect(EFFECT_HIT_UNIT, HIT_ATTACH_POINT)
     
            if dmgAmount > 0
                this.caster.damageTarget(target, dmgAmount)

        destroy this

    private static CallbackPeriodic cbp = (CallbackPeriodic cb) ->
    begin
        for instance in Charge
            if instance.sp == SpellPhase.Channel
            //-----------Phase 1 : Channel-----------
                //if charging time is done
                if instance.timeLeft <= 0
                    instance.sp = SpellPhase.Charging
                    instance.timeLeft = SPELL_DURATION
                //if interruptable and defined interrupt condition is true
                else if INTERRUPTABLE_CHANNEL and chanellingInterrupt(instance.caster)
                    destroy instance
            //------------End of Phase 1-------------
            else if instance.sp == SpellPhase.Charging
            //----------Phase 2 : Charging-----------
                //update caster facing angle
                instance.ang = instance.caster.getFacingAngle()

                //if reached maximum charging time
                if instance.timeLeft <= 0
                    instance.sp = SpellPhase.Deaccelerate
                    instance.timeLeft = instance.curSpeed/DEACCELERATION
                else
                    //if charging speed is not maxed
                    if instance.curSpeed < MAX_SPEED
                        instance.curSpeed += ACCELERATION_PER_TICK

                        if instance.curSpeed > MAX_SPEED
                            instance.curSpeed = MAX_SPEED

                        instance.distPerTick = instance.curSpeed*PERIODIC_TIME

                    //get caster next position
                    var nextPos = instance.curPos.polarOffset(instance.ang, instance.distPerTick)

                    //check if linear path from caster to next position is walkable
                    var path = isPathWalkable(instance.curPos, nextPos)

                    //if walkable
                    if path.walkable
                        //create a rect which centered at nextPos with width of HIT_SIZE_X and height of HIT_SIZE_Y
                        let r = Rect(nextPos.x-HALF_X_OFFSET, nextPos.y-HALF_Y_OFFSET, nextPos.x+HALF_X_OFFSET, nextPos.y+HALF_Y_OFFSET)
                     
                        forUnitsInRect(r, (unit u) ->
                        begin
                            if not u == instance.caster
                                if u.isType(UNIT_TYPE_STRUCTURE)
                                    //terminate spell
                                    instance.terminate(true, 1., u)

                                if hittable(instance.caster, u)
                                    //knock back unit
                        end)
                        instance.curPos = nextPos

                        //update caster position
                        instance.caster.setPos(nextPos)

                        //destroy rect
                        RemoveRect(r)
                    //not walkable, terminate spell
                    else
                        instance.terminate(true, 0, null)

                 
            //------------End of Phase 2-------------
            else if instance.sp == SpellPhase.Deaccelerate
            //--------Phase 3 : Deaccelerate---------
            //------------End of Phase 3-------------

            instance.timeLeft -= PERIODIC_TIME
    end
    //================================================================



    //=======================Accessor Functions=======================
    /** Check if unit (u) if it in spell instance*/
    static function contains(unit u) returns bool
        for instance in Charge
            if instance.caster == u
                return true

        return false
    //================================================================

/*================================================================================================*/

function onChannel() returns bool
    let u = GetTriggerUnit()

    if GetSpellAbilityId() == SPELL_ID and not Charge.contains(u)
        new Charge(u)
 
    return false
 
init
    CreateTrigger()
         ..registerAnyUnitEvent(EVENT_PLAYER_UNIT_SPELL_CHANNEL)
         ..addCondition(Condition(function onChannel))


I remember previously there is someone asking why posting spell code as WIP, because it is the easiest way to show your WIP, .gif file may causes thread to load unnecessary long.

..dat readability :grin:
 

Kyrbi0

Arena Moderator
Level 44
Joined
Jul 29, 2008
Messages
9,487
I think now's a good time to remind everyone/campaign for something @Cokemonkey11 brought up in a previous (Hero) Contest, and that is "reverse Byzantium" style.

Basically, unless a critical mass of contestants do not agree with something (i.e. any given change in Contest Rules or Criteria), things move ahead as planned/changed.

What that means in this case is none of us need to "agree" with the extension for it to happen; only a certain number disagreeing would stop it.
 
Can spell maker use Unit Indexers?
I would guess so.
The use of enhancing systems is permitted as long as their contribution is not the major aspect of the final entry. Clarification matters on certain libraries/snippets should be discussed with judges in the contest thread, in case of uncertainty.
 
Just a quick "WIP"

  • DJ Config
    • Events
      • Map initialization
    • Conditions
    • Actions
      • -------- Dummy for Channel --------
      • Set DJ_Dummy = No unit-type
      • -------- Channel animation --------
      • Set DJ_ChannelAnim = spell
      • -------- Channel model --------
      • Set DJ_ChannelModel = <Empty String>
      • -------- Explosion model --------
      • Set DJ_ExplosionModel = Objects\Spawnmodels\Undead\UCancelDeath\UCancelDeath.mdl
      • -------- Dummy size increase per second --------
      • Set DJ_DummySizeUp = 1.00
      • -------- Channel time - make sure to set it equal to Follow Through Time in the ability --------
      • Set DJ_ChannelTime[1] = 5.00
      • Set DJ_ChannelTime[2] = 5.00
      • Set DJ_ChannelTime[3] = 5.00
      • -------- Damage charged per second --------
      • Set DJ_DamageCharge[1] = 25.00
      • Set DJ_DamageCharge[2] = 50.00
      • Set DJ_DamageCharge[3] = 100.00
      • -------- Area of Effect at maximum --------
      • Set DJ_AreaEffect[1] = 500.00
      • Set DJ_AreaEffect[2] = 500.00
      • Set DJ_AreaEffect[3] = 500.00
 

Just one suggestion on that first icon would be to define the bucket outline similar to the other two icons? Lookin really good though!
 
Status
Not open for further replies.
Top