Spell Contagious Disease

The_Kingpin

Member (Who are you and why should I care?)
Reaction score
41
Contagious Disease - Follows JESP Standard

scrn.jpg

My first spell :).
This is a single-unit target spell that gives a unit a disease. The disease damages the unit every second that the disease lasts. The disease can spread to other units that come close to a diseased unit.

This spell is virtually MUI (Up to 8190 instances). It is coded in vJass, which means Jass NewGen Pack v3g or higher is required.

Code
JASS:
//Contagious Disease
//Configuration
//
//
//Edit the variables below to suit your needs.
                                                                                                    library ContagiousDisease
                                                                                                        globals
        //This is the id if the Disease ability.
        private integer Ability = 'A000'
        
        //This is the id of the ability that shows the buff.
        private integer BuffAbility = 'A001'
        
        //This is how many seconds the disease effect will last.
        private real Duration = 30
        
        //This the maximum radius a unit must be in to contract the disease.
        private real Range = 225
        
                                                                                                        endglobals
                                                                                                        private function Conditions takes unit Target, unit Caster returns boolean
        
        //These are the conditions that must be met for the disease to spread.
        return IsUnitEnemy(Caster,GetOwningPlayer(Target)) == true and IsUnitType(Target,UNIT_TYPE_GROUND) == true and IsUnitType(Target,UNIT_TYPE_MECHANICAL) == false
        //The variable "Caster" is the original source of the disease,
        //and "Target" is the unit that the disease will be spread to.
        
                                                                                                        
                                                                                                        endfunction
        
                                                                                                        private function Damage takes integer l returns real
                                                                                                            local real array Level
        //This is the damage dealt each second per level.
        //If there are more than three levels, continue the list.
        set Level[1]=4
        set Level[2]=6
        set Level[3]=8
        //set Level[4]=12
        //and so on.
                                                                                                            return Level[l]
                                                                                                        endfunction
//End Configuration.
//The following is the code necessary for the spell to function properly.
//Do not edit it unless you are sure of what you are doing.
//
//
//

    globals
        private integer array Data
    endglobals
    
    private function H2I takes handle h returns integer 
        return h
        return 0
    endfunction
    
    private function StoreStruct takes handle h, integer str returns nothing
        set Data[H2I(h)-0x100000]=str 
    endfunction
    
    private function RecallStruct takes handle h returns integer
        return Data[H2I(h)-0x100000] 
    endfunction
    
    struct ContagiousDisease
        unit Unit = null
        unit Caster = null
        real Damage = 0
        integer Level = 1
        trigger Duration = CreateTrigger()
        trigger Period = CreateTrigger()
        trigger Enum = CreateTrigger()
        
        
        static method InRange takes nothing returns boolean
            local ContagiousDisease this
            local ContagiousDisease that = ContagiousDisease(RecallStruct(GetTriggeringTrigger()))
            if RecallStruct(GetTriggerUnit()) == 0 and Conditions(that.Caster,GetTriggerUnit()) then
                set this = ContagiousDisease.create(GetTriggerUnit(),that.Caster,that.Level)
            endif
            return false
        endmethod
        
        static method TimeUp takes nothing returns boolean
            local ContagiousDisease this = ContagiousDisease(RecallStruct(GetTriggeringTrigger()))
            call this.destroy()
            return false
        endmethod
        
        static method PeriodFunc takes nothing returns boolean
            local ContagiousDisease this = ContagiousDisease(RecallStruct(GetTriggeringTrigger()))
            if GetUnitState(this.Unit,UNIT_STATE_LIFE) > 0 then
                call UnitDamageTarget(this.Caster,this.Unit,this.Damage,false,false,ATTACK_TYPE_CHAOS,DAMAGE_TYPE_DISEASE,WEAPON_TYPE_WHOKNOWS)
            else
                call this.destroy() 
            endif
            return false
        endmethod
        
        
        private method onDestroy takes nothing returns nothing
            call DestroyTrigger(this.Period)
            call DestroyTrigger(this.Duration)
            call DestroyTrigger(this.Enum)
            call UnitRemoveAbility(this.Unit,BuffAbility)
            call StoreStruct(this.Unit,0)
        endmethod
            
        
        static method create takes unit Unit, unit Caster, integer Level returns ContagiousDisease
            local ContagiousDisease this
            if RecallStruct(Unit) == 0 then
                set this = ContagiousDisease.allocate()
                set this.Unit = Unit 
                set this.Caster = Caster
                set this.Damage = Damage(Level)
                set this.Level = Level
                call TriggerRegisterTimerEvent(this.Period,1,true)
                call TriggerAddCondition(this.Period,Condition(function ContagiousDisease.PeriodFunc))
                call TriggerRegisterTimerEvent(this.Duration,Duration,false)
                call TriggerAddCondition(this.Duration,Condition(function ContagiousDisease.TimeUp))
                call TriggerRegisterUnitInRange(this.Enum,this.Unit,Range,null)
                call TriggerAddCondition(this.Enum,Condition(function ContagiousDisease.InRange))
                call StoreStruct(this.Unit,this)
                call StoreStruct(this.Duration,this)
                call StoreStruct(this.Period,this)
                call StoreStruct(this.Enum,this)
                call UnitAddAbility(this.Unit,BuffAbility)
                return this
            endif
            return 0
        endmethod
    endstruct

function Trig_Contagious_Disease_Actions takes nothing returns nothing
    call ContagiousDisease.create(GetSpellTargetUnit(),GetTriggerUnit(),GetUnitAbilityLevel(GetTriggerUnit(),Ability))
endfunction

function Trig_Contagious_Disease_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == Ability
endfunction

//===========================================================================
function InitTrig_Contagious_Disease takes nothing returns nothing
    set gg_trg_Contagious_Disease = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ(gg_trg_Contagious_Disease,EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(gg_trg_Contagious_Disease, Condition(function Trig_Contagious_Disease_Conditions))
    call TriggerAddAction( gg_trg_Contagious_Disease, function Trig_Contagious_Disease_Actions )
endfunction
endlibrary

Download: View attachment Spell-ContagiousDisease.w3x

Jass NewGen Pack v3g: Download Link

Credits 2 Tinki3 for the Demo Map Template.

If you use this in your map, credit is appreciated, but not required.
After all, how can I own a wall of text?

Comments and Constructive criticism are gladly accepted.
 

~GaLs~

† Ғσſ ŧħə ѕαĸε Φƒ ~Ğ䣚~ †
Reaction score
180
Did you missed out a part of your code??
I see endlibrary but i don't see any library around.
 

The_Kingpin

Member (Who are you and why should I care?)
Reaction score
41
No. Scroll way to the right.

I moved those out of sight as to make configuring it less confusing.

BTW your avatar is lulz.
 

phyrex1an

Staff Member and irregular helper
Reaction score
447
I moved those out of sight as to make configuring it less confusing.
Lol, great idea :p

A few comments:

1. Usually when you have a 'per level' array config as you have in function Damage you add a default value just to make sure that it doesn't end the thread when given an invalid level.
JASS:

        set Level[l]=1 // Default
        set Level[1]=4
        set Level[2]=6
        set Level[3]=8


2. In method InRange you have a lot of conditions that fit better in a config function. What if I wanted to make fire (affects mechanical) that spread instead of a disease?

3. You use a lot of H2I for units, I suggest that you check out Cohadars PUI
 

The_Kingpin

Member (Who are you and why should I care?)
Reaction score
41
Hmm... I don't fully understand what you mean with the default value thing.

And I'm using an attachment system based on PandaMine's HSAS. Fast enough at around 93 executions every millisecond.

And yes, I will see if I can put in a config option for the condition.
 

phyrex1an

Staff Member and irregular helper
Reaction score
447
Hmm... I don't fully understand what you mean with the default value thing.
With your version:
JASS:
call Damage(4) // Thread crash, nothing below this line will be executed


With default value
JASS:
call Damage(4) // returns 1 (default)

Only reason it's there is to prevent people from making stupid fatal mistakes like adding an extra level to an ability without changing the config for the spell.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top