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

BotL - Coding & Systems

Status
Not open for further replies.
Level 16
Joined
Jul 31, 2012
Messages
2,217
yes, i know, i made globals: Unit and Grp >> most used locals>> and global variables for spell constants"
KB3D is the best thing, really, not that i am the leader of it, but seriously it save like 80% of coding time!

Oh and i created a custom version with more features of the KB3D JUST for BotL xDD
 
Level 16
Joined
Jul 31, 2012
Messages
2,217
Malhorne, chobibo, i need 2 systems for the BotL but since i guess it needs Table to make, which i don't know how to use yet, you guys are the ones

so the 2 systems are easy:
DPS (stackable)
TimedStatBonus (gives bonus stat then removes it after time)

the kind of funtion:

DPS:
JASS:
function ApplyDPS takes unit target, unit source, real amount, real timeout returns nothing
//Damage Type is SPELL, Attack Type is MAGIC
TimedStatBonus:
JASS:
function AddTimedStatBonus takes unit hero, integer amount, integer statType, real timeout returns nothing
 
Level 18
Joined
Sep 14, 2012
Messages
3,413
JASS:
library DoT
    globals
        private constant real FPS = 0.0312500
    endglobals
    
    struct DoT extends array
        private unit caster
        private unit target
        private real interval
        private real during
        private real dmg
        private real temp
        private static integer instanceCount
        private thistype prev
        private thistype next
        private static timer period
        
        private static method iterate takes nothing returns nothing
            local thistype this = thistype(0)
            local integer i
            loop
                set this = this.next
                exitwhen this == 0
                set this.temp = this.temp + FPS
                if this.temp > this.interval then
                    call UnitDamageTarget(this.caster, this.target, this.dmg, true, false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, null)
                    set this.temp = this.temp-this.interval
                endif
                set this.during = this.during - FPS
                if this.during < 0 then
                    call this.destroy()
                endif
            endloop
        endmethod
        
        static method add takes unit cast, unit targ, real dur, real inter, real dm returns nothing
            local thistype this
            
            if thistype(0).prev == 0 then
                set instanceCount = instanceCount + 1
                set this = instanceCount
            else
                set this = thistype(0).prev
                set thistype(0).prev = thistype(0).prev.prev
            endif
            
            if thistype(0).next == 0 then
                call TimerStart(period, FPS, true, function thistype.iterate)
            else
                set thistype(0).next.prev = this
            endif
            
            set this.next = thistype(0).next
            set thistype(0).next = this
            set this.prev = thistype(0)
            
            set this.caster = cast
            set this.target = targ
            set this.interval = inter
            set this.during = dur
            set this.dmg = dm
            set this.temp = 0
        endmethod

        private method destroy takes nothing returns nothing
            if this.next != 0 then
            set this.next.prev = this.prev
        endif
            
        set this.prev.next = this.next
        set this.prev = thistype(0).prev
        set thistype(0).prev = this
        
        if thistype(0).next == 0 then
            call PauseTimer(period)
        endif

        set this.caster = null
        set this.target = null
        endmethod
        
        private static method onInit takes nothing returns nothing
            set instanceCount = 0
            set period = CreateTimer()
        endmethod
    endstruct
endlibrary
 
Level 18
Joined
Sep 14, 2012
Messages
3,413
JASS:
library TimedStats

    globals
        private constant real FPS = 0.0312500
    endglobals
    
    //1 : Strength
    //2 : Agility
    //3 : Intelligence
    struct TimedStats extends array
        private unit targ
        private real temp
        private integer amount
        private integer type
        private thistype prev
        private thistype next
        private static timer period
        private static integer count
        private static HandleTable tab
        
        private static method periodic takes nothing returns nothing
            local thistype this = thistype(0)
            loop
                set this = this.next
                exitwhen this == 0 
                set this.temp = this.temp -FPS
                if this.temp < 0 then
                    if this.type==1 then
                        call SetHeroStr(this.targ, GetHeroStr(this.targ, false)-this.amount, false)
                    elseif this.type==2 then
                        call SetHeroAgi(this.targ, GetHeroAgi(this.targ, false)-this.amount, false)
                    elseif this.type==3 then
                        call SetHeroInt(this.targ, GetHeroInt(this.targ, false)-this.amount, false)
                    debug else
                        debug call BJDebugMsg("You entered the wrong number for the stats thingy")
                    endif
                    call this.destroy()
                endif
            endloop
        endmethod
        
        static method AddTimedStatBonus takes unit targ, integer i, integer stats, real time returns nothing
            local thistype this
            if thistype(0).prev == 0 then
                set this = thistype(0).prev
                set thistype(0).prev = thistype(0).prev.prev
            else
                set count = count + 1
                set this = count
            endif
            if thistype(0).next == 0 then
                call TimerStart(period, FPS, true, function thistype.periodic)
            else
                set thistype(0).next.prev = this
            endif
            set this.next = thistype(0).next
            set thistype(0).next = this
            set this.prev = thistype(0)
            set this.targ = targ
            set this.amount = i
            set this.type = stats
            set this.temp = time
            if i==1 then
                call SetHeroStr(targ, GetHeroStr(targ, false)+amount, false)
            elseif i==2 then
                call SetHeroAgi(targ, GetHeroAgi(targ, false)+amount, false)
            elseif i==3 then
                call SetHeroInt(targ, GetHeroInt(targ, false)+amount, false)
            debug else
                debug call BJDebugMsg("You're giving wrong number for the stats thingy")
            endif
        endmethod
        
        private method destroy takes nothing returns nothing
                if this.next != 0 then
                    set this.next.prev = this.prev
                endif
                set this.prev.next = this.next
                set this.prev = thistype(0).prev
                set thistype(0).prev = this
                if thistype(0).next == 0 then
                    call PauseTimer(period)
                endif
                set this.targ = null
        endmethod
        
        private static method onInit takes nothing returns nothing
            set count = 0
            set period = CreateTimer()
            set tab = HandleTable.create()
        endmethod
    endstruct
endlibrary

I made no test at all you need to do this :p


Ah wait ...
You want this to refresh the timeout each time it happens ?
 
Level 18
Joined
Sep 14, 2012
Messages
3,413
Holy shit made a mistake in DoT :
JASS:
library DoT
    globals
        private constant real FPS = 0.100
    endglobals
    
    struct DoT extends array
        private unit caster
        private unit target
        private real interval   
        private real during
        private real dmg
        private real temp
        private static integer instanceCount
        private thistype prev
        private thistype next
        private static timer period
        
        private static method iterate takes nothing returns nothing
            local thistype this = thistype(0)
            loop
                set this = this.next
                exitwhen this == 0
                set this.temp = this.temp + FPS
                if this.temp > this.interval then
                    call UnitDamageTarget(this.caster, this.target, this.dmg, true, false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, null)
                    set this.temp = this.temp-this.interval
                endif
                set this.during = this.during - FPS
                if this.during < 0 then
                    call this.destroy()
                endif
            endloop
        endmethod
        
        static method add takes unit cast, unit targ, real dur, real inter, real dm returns nothing
            local thistype this
            
            if thistype(0).prev == 0 then
                set instanceCount = instanceCount + 1
                set this = instanceCount
            else
                set this = thistype(0).prev
                set thistype(0).prev = thistype(0).prev.prev
            endif
            
            if thistype(0).next == 0 then
                call TimerStart(period, FPS, true, function thistype.iterate)
            else
                set thistype(0).next.prev = this
            endif
            
            set this.next = thistype(0).next
            set thistype(0).next = this
            set this.prev = thistype(0)
            
            set this.caster = cast
            set this.target = targ
            set this.interval = inter
            set this.during = dur
            set this.dmg = dm
            set this.temp = 0
        endmethod

        private method destroy takes nothing returns nothing
            if this.next != 0 then
            set this.next.prev = this.prev
        endif
            
        set this.prev.next = this.next
        set this.prev = thistype(0).prev
        set thistype(0).prev = this
        
        if thistype(0).next == 0 then
            call PauseTimer(period)
        endif

        set this.caster = null
        set this.target = null
        endmethod
        
        private static method onInit takes nothing returns nothing
            set instanceCount = 0
            set period = CreateTimer()
        endmethod
    endstruct
endlibrary
 
Level 22
Joined
Sep 24, 2005
Messages
4,821
Oh, the circularly linked list? It's cool! But it's rather pointless now that I know globals need nulling, the supposed advantage over Knuth shuffle (thanks to Nestharus for this piece of info) is negligible. I'm no longer a speed freak, so...

Anyways, congratulations to you for having written your linked list iteration in vjass haha xD.

Add a debug allocator dude, it sucks to not know if that one is failing, and believe me, fuckups happen all the time, speed isn't an issue in object allocation, since your not going to allocate en masse. The list iteration is good though. Oh and don't use a real for an iterator countdown, use an integer, calculate the numbers of iteration the DoT requires to damage the unit. The unit must also be damaged on cast so you should decrement the iteration counter by one when starting the DoT. A 1/32 period isn't good for a DoT period, try 1/10, the precision is pointless.

Oh and sorry for my rumblings, I'm just happy today that old people are coming back to modding.
 
Status
Not open for further replies.
Top