Is this MUI? (SpellSystem)

Vestras

Retired
Reaction score
248
Well, I'm making a spell system, like Vexorian's CasterSystem, just simpler, not so messed up, well, I want to know if the method I'm using with dummy casters is MUI. (I use bj_ghoul[...].)

JASS:
// !!!! START OF SS--SPELLSYSTEM CONFIG !!!! \\
constant function ss_dummy takes nothing returns integer
    // Raw code of the dummy unit
    return 'e000'
endfunction

constant function ss_heightenabler takes nothing returns integer
    // Raw code of Medivh's Raven Form ability
    return 'Amrf'
endfunction

constant function ss_integer takes nothing returns integer
    // Just a random integer, the more random the better
    return 6594
endfunction

constant function ss_player takes nothing returns integer
    // The player which should own all dummy units
    return 15
endfunction

// !!!! START OF SS--sscache FUNCTION !!!! \\
function ss takes nothing returns gamecache
    if udg_sscache == null then
        call FlushGameCache(InitGameCache("data.ss"))
        set udg_sscache = InitGameCache("data.ss")
    endif
 return udg_sscache
endfunction

// !!!! START OF SS--SPECIFIC FUNCTIONS !!!! \\
function EnemyFilter takes nothing returns boolean
    local integer i = GetStoredInteger(ss(), "ss", "enemy_playerid")
    return IsUnitEnemy(GetFilterUnit(), Player(i)) == true
endfunction

function AllyFilter takes nothing returns boolean
    local integer i = GetStoredInteger(ss(), "ss", "ally_playerid")
    return IsUnitAlly(GetFilterUnit(), Player(i)) == true
endfunction

constant function H2I takes handle h returns integer
    return h
    return 0
endfunction

constant function I2U takes integer i returns unit
    return i
    return null
endfunction

// !!!! START OF SS--CASTER MODULE !!!! \\
function create takes real x, real y returns unit
    set bj_ghoul[ss_integer()] = CreateUnit(Player(ss_player()), ss_dummy(), x, y, 0)
    return bj_ghoul[ss_integer()]
endfunction

function castXY takes integer abilityid, integer level, string orderstring, real tx, real ty returns nothing
    call UnitAddAbility(bj_ghoul[ss_integer()], abilityid)
    call SetUnitAbilityLevel(bj_ghoul[ss_integer()], abilityid, level)
    call IssuePointOrder(bj_ghoul[ss_integer()], orderstring, tx, ty)
endfunction

function castLoc takes integer abilityid, integer level, string orderstring, location l returns nothing
    call UnitAddAbility(bj_ghoul[ss_integer()], abilityid)
    call SetUnitAbilityLevel(bj_ghoul[ss_integer()], abilityid, level)
    call IssuePointOrderLoc(bj_ghoul[ss_integer()], orderstring, l)
endfunction

function castTarget takes integer abilityid, integer level, string orderstring, unit target returns nothing
    call UnitAddAbility(bj_ghoul[ss_integer()], abilityid)
    call SetUnitAbilityLevel(bj_ghoul[ss_integer()], abilityid, level)
    call IssueTargetOrder(bj_ghoul[ss_integer()], orderstring, target)
endfunction

function castInstant takes integer abilityid, integer level, string orderstring returns nothing
    call UnitAddAbility(bj_ghoul[ss_integer()], abilityid)
    call SetUnitAbilityLevel(bj_ghoul[ss_integer()], abilityid, level)
    call IssueImmediateOrder(bj_ghoul[ss_integer()], orderstring)
endfunction

function castAOE takes integer abilityid, integer level, real timed, string orderstring, real x, real y, real radius returns nothing
    local group g = CreateGroup()
    local unit s
        call GroupEnumUnitsInRange(g, x, y, radius, null)
        call UnitAddAbility(bj_ghoul[ss_integer()], abilityid)
        call SetUnitAbilityLevel(bj_ghoul[ss_integer()], abilityid, level)
        call UnitApplyTimedLife(bj_ghoul[ss_integer()], 'BTLF', timed)
        loop
            set s = FirstOfGroup(g)
            exitwhen s == null
                call IssueTargetOrder(bj_ghoul[ss_integer()], orderstring, s)
        endloop
    call DestroyGroup(g)
    set s = null
    set g = null
endfunction

function castGroup takes integer abilityid, integer level, real timed, string orderstring, real x, real y, group g returns nothing
    local unit s
        call UnitAddAbility(bj_ghoul[ss_integer()], abilityid)
        call SetUnitAbilityLevel(bj_ghoul[ss_integer()], abilityid, level)
        call UnitApplyTimedLife(bj_ghoul[ss_integer()], 'BTLF', timed)
        loop
            set s = FirstOfGroup(g)
            exitwhen s == null
                call IssueTargetOrder(bj_ghoul[ss_integer()], orderstring, s)
        endloop
    set s = null
endfunction

function removeDummy takes nothing returns nothing
    call RemoveUnit(bj_ghoul[ss_integer()])
endfunction

function removeDummyTimed takes real time returns nothing
    call UnitApplyTimedLife(bj_ghoul[ss_integer()], 'BTLF', time)
endfunction

function createAndCastXY takes integer abilityid, integer level, real timed, string orderstring, real x, real y, real tx, real ty returns unit
    set bj_ghoul[ss_integer()] = CreateUnit(Player(ss_player()), ss_dummy(), x, y, 0)
        call UnitAddAbility(bj_ghoul[ss_integer()], abilityid)
        call SetUnitAbilityLevel(bj_ghoul[ss_integer()], abilityid, level)
        call IssuePointOrder(bj_ghoul[ss_integer()], orderstring, tx, ty)
        call UnitApplyTimedLife(bj_ghoul[ss_integer()], 'BTLF', timed)
    return bj_ghoul[ss_integer()]
endfunction

function createAndCastLoc takes integer abilityid, integer level, real timed, string orderstring, real x, real y, location l returns unit
    set bj_ghoul[ss_integer()] = CreateUnit(Player(ss_player()), ss_dummy(), x, y, 0)
        call UnitAddAbility(bj_ghoul[ss_integer()], abilityid)
        call SetUnitAbilityLevel(bj_ghoul[ss_integer()], abilityid, level)
        call IssuePointOrderLoc(bj_ghoul[ss_integer()], orderstring, l)
        call UnitApplyTimedLife(bj_ghoul[ss_integer()], 'BTLF', timed)
    return bj_ghoul[ss_integer()]
endfunction

function createAndCastTarget takes integer abilityid, integer level, real timed, string orderstring, real x, real y, unit target returns unit
    set bj_ghoul[ss_integer()] = CreateUnit(Player(ss_player()), ss_dummy(), x, y, 0)
        call UnitAddAbility(bj_ghoul[ss_integer()], abilityid)
        call SetUnitAbilityLevel(bj_ghoul[ss_integer()], abilityid, level)
        call IssueTargetOrder(bj_ghoul[ss_integer()], orderstring, target)
        call UnitApplyTimedLife(bj_ghoul[ss_integer()], 'BTLF', timed)
    return bj_ghoul[ss_integer()]
endfunction

function createAndCastInstant takes integer abilityid, integer level, real timed, string orderstring, real x, real y returns unit
    set bj_ghoul[ss_integer()] = CreateUnit(Player(ss_player()), ss_dummy(), x, y, 0)
        call UnitAddAbility(bj_ghoul[ss_integer()], abilityid)
        call SetUnitAbilityLevel(bj_ghoul[ss_integer()], abilityid, level)
        call IssueImmediateOrder(bj_ghoul[ss_integer()], orderstring)
        call UnitApplyTimedLife(bj_ghoul[ss_integer()], 'BTLF', timed)
    return bj_ghoul[ss_integer()]
endfunction

function AOE_Callback takes nothing returns nothing
    local string orderstring = GetStoredString(ss(), "ss", "aoe_order")
    local integer abilityid = GetStoredInteger(ss(), "ss", "aoe_id")
    local integer level = GetStoredInteger(ss(), "ss", "aoe_lvl")
    local real timed = GetStoredReal(ss(), "ss", "aoe_time")
    local real x = GetStoredReal(ss(), "ss", "aoe_x")
    local real y = GetStoredReal(ss(), "ss", "aoe_y")
        set bj_ghoul[ss_integer()] = CreateUnit(Player(ss_player()), ss_dummy(), x, y, 0)
        call UnitAddAbility(bj_ghoul[ss_integer()], abilityid)
        call SetUnitAbilityLevel(bj_ghoul[ss_integer()], abilityid, level)
        call IssueTargetOrder(bj_ghoul[ss_integer()], orderstring, GetEnumUnit())
        call UnitApplyTimedLife(bj_ghoul[ss_integer()], 'BTLF', timed)
endfunction

function createAndCastAOE takes integer abilityid, integer level, real timed, string orderstring, real x, real y, real radius returns nothing
    local group g = CreateGroup()
    local unit s
        call GroupEnumUnitsInRange(g, x, y, radius, null)
        call StoreString(ss(), "ss", "aoe_order", orderstring)
        call StoreInteger(ss(), "ss", "aoe_id", abilityid)
        call StoreInteger(ss(), "ss", "aoe_lvl", level)
        call StoreReal(ss(), "ss", "aoe_time", timed)
        call StoreReal(ss(), "ss", "aoe_x", x)
        call StoreReal(ss(), "ss", "aoe_y", y)
        call ForGroup(g, function AOE_Callback)
    call DestroyGroup(g)
    set s = null
    set g = null
endfunction

function Group_Callback takes nothing returns nothing
    local string orderstring = GetStoredString(ss(), "ss", "grp_order")
    local integer abilityid = GetStoredInteger(ss(), "ss", "grp_id")
    local integer level = GetStoredInteger(ss(), "ss", "grp_lvl")
    local real timed = GetStoredReal(ss(), "ss", "grp_time")
    local real x = GetStoredReal(ss(), "ss", "grp_x")
    local real y = GetStoredReal(ss(), "ss", "grp_y")
        set bj_ghoul[ss_integer()] = CreateUnit(Player(ss_player()), ss_dummy(), x, y, 0)
        call UnitAddAbility(bj_ghoul[ss_integer()], abilityid)
        call SetUnitAbilityLevel(bj_ghoul[ss_integer()], abilityid, level)
        call IssueTargetOrder(bj_ghoul[ss_integer()], orderstring, GetEnumUnit())
        call UnitApplyTimedLife(bj_ghoul[ss_integer()], 'BTLF', timed)
endfunction

function createAndCastGroup takes integer abilityid, integer level, real timed, string orderstring, real x, real y, group g returns nothing
    local unit s
        call StoreString(ss(), "ss", "grp_order", orderstring)
        call StoreInteger(ss(), "ss", "grp_id", abilityid)
        call StoreInteger(ss(), "ss", "grp_lvl", level)
        call StoreReal(ss(), "ss", "grp_time", timed)
        call StoreReal(ss(), "ss", "grp_x", x)
        call StoreReal(ss(), "ss", "grp_y", y)
        call ForGroup(g, function Group_Callback)
    set s = null
endfunction

function SetSourceZ takes real z returns nothing
    call UnitAddAbility(bj_ghoul[ss_integer()], ss_heightenabler())
    call SetUnitFlyHeight(bj_ghoul[ss_integer()], z, 0)
    call UnitRemoveAbility(bj_ghoul[ss_integer()], ss_heightenabler())
endfunction

constant function GetLastCreatedDummy takes nothing returns unit
    return bj_ghoul[ss_integer()]
endfunction

// !!!! START OF SS--DAMAGE MODULE !!!! \\
function DamageUnit takes unit damager, unit target, real damage, boolean armor returns boolean
    if armor == false then
        return UnitDamageTarget(damager, target, damage, false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_UNIVERSAL, null)
    else
        return UnitDamageTarget(damager, target, damage, false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, null)
    endif
    return false
endfunction

function DPE_Callback takes nothing returns nothing
    local boolean armor = GetStoredBoolean(ss(), "ss", "dpe_armor")
    local real damage = GetStoredReal(ss(), "ss", "dpe_damage")
    local unit damager = I2U(GetStoredInteger(ss(), "ss", "dpe_damager"))
        call DamageUnit(null, GetEnumUnit(), damage, armor)
endfunction

function DamagePointEnemies takes unit damager, real x, real y, real radius, real damage, boolean armor returns nothing
    local group g = CreateGroup()
    call StoreInteger(ss(), "ss", "enemy_playerid", GetPlayerId(GetOwningPlayer(damager)))
    call StoreBoolean(ss(), "ss", "dpe_armor", armor)
    call StoreReal(ss(), "ss", "dpe_damage", damage)
    call StoreInteger(ss(), "ss", "dpe_damager", H2I(damager))
        call GroupEnumUnitsInRange(g, x, y, radius, Filter(function EnemyFilter))
        call ForGroup(g, function DPE_Callback)
    call DestroyGroup(g)
    set g = null
endfunction

function DamagePointEnemiesLoc takes unit damager, location l, real radius, real damage, boolean armor returns nothing
    local real x = GetLocationX(l)
    local real y = GetLocationY(l)
        call DamagePointEnemies(damager, x, y, radius, damage, armor)
endfunction

function DPA_Callback takes nothing returns nothing
    local boolean armor = GetStoredBoolean(ss(), "ss", "dpa_armor")
    local real damage = GetStoredReal(ss(), "ss", "dpa_damage")
    local unit damager = I2U(GetStoredInteger(ss(), "ss", "dpa_damager"))
        call DamageUnit(null, GetEnumUnit(), damage, armor)
endfunction

function DamagePointAllies takes unit damager, real x, real y, real radius, real damage, boolean armor returns nothing
    local group g = CreateGroup()
    call StoreInteger(ss(), "ss", "ally_playerid", GetPlayerId(GetOwningPlayer(damager)))
    call StoreBoolean(ss(), "ss", "dpa_armor", armor)
    call StoreReal(ss(), "ss", "dpa_damage", damage)
    call StoreInteger(ss(), "ss", "dpa_damager", H2I(damager))
        call GroupEnumUnitsInRange(g, x, y, radius, Filter(function AllyFilter))
        call ForGroup(g, function DPA_Callback)
    call DestroyGroup(g)
    set g = null
endfunction

function DamagePointAlliesLoc takes unit damager, location l, real radius, real damage, boolean armor returns nothing
    local real x = GetLocationX(l)
    local real y = GetLocationY(l)
        call DamagePointAllies(damager, x, y, radius, damage, armor)
endfunction

function DPALL_Callback takes nothing returns nothing
    local boolean armor = GetStoredBoolean(ss(), "ss", "dpall_armor")
    local real damage = GetStoredReal(ss(), "ss", "dpall_damage")
    local unit damager = I2U(GetStoredInteger(ss(), "ss", "dpall_damager"))
        call DamageUnit(null, GetEnumUnit(), damage, armor)
endfunction

function DamagePointAll takes unit damager, real x, real y, real radius, real damage, boolean armor returns nothing
    local group g = CreateGroup()
    call StoreBoolean(ss(), "ss", "dpall_armor", armor)
    call StoreReal(ss(), "ss", "dpall_damage", damage)
    call StoreInteger(ss(), "ss", "dpall_damager", H2I(damager))
        call GroupEnumUnitsInRange(g, x, y, radius, null)
        call ForGroup(g, function DPALL_Callback)
    call DestroyGroup(g)
    set g = null
endfunction

function DamagePointAllLoc takes unit damager, location l, real radius, real damage, boolean armor returns nothing
    local real x = GetLocationX(l)
    local real y = GetLocationY(l)
        call DamagePointAll(damager, x, y, radius, damage, armor)
endfunction

// !!!! START OF SS--SHAPES MODULE !!!! \\
function line takes real x, real y, real tx, real ty, unit c, string fx, integer n, real dmg, real dmgaoe, boolean armor returns nothing
    local integer i = 0
    local real dx = tx - x
    local real dy = ty - y
    local real dist = SquareRoot(dx * dx + dy * dy) / n
    local real angle = Atan2(ty - y, tx - x)
    local real px
    local real py
                
        loop
            set i = i + 1
            exitwhen i > n
                set px = x + (dist * i) * Cos(angle)
                set py = y + (dist * i) * Sin(angle)
                call DestroyEffect(AddSpecialEffect(fx, px, py))
                call DamagePointEnemies(c, px, py, dmgaoe, dmg, armor)
        endloop
endfunction

function circle takes real x, real y, real radius, unit c, string fx, integer n, real dmg, real dmgaoe, boolean armor returns nothing
    local integer i = 0
    local real angle
    local real px
    local real py
            
        set px = x + radius * Cos(0 * bj_DEGTORAD)
        set py = y + radius * Sin(0 * bj_DEGTORAD)
        call DestroyEffect(AddSpecialEffect(fx, px, py))
        call UnitDamagePoint(c, 0, dmgaoe, px, py, dmg, false, true, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, null)
        loop
            set i = i + 1
            exitwhen i > n
                set angle = i * (360 / n)
                set px = x + radius * Cos(angle * bj_DEGTORAD)
                set py = y + radius * Sin(angle * bj_DEGTORAD)
                call DestroyEffect(AddSpecialEffect(fx, px, py))
                call DamagePointEnemies(c, px, py, dmgaoe, dmg, armor)
        endloop
endfunction


I don't really know myself...
(It's not done, at all, yet.)
 

Flare

Stops copies me!
Reaction score
662
1) Not fully - the dummy doesn't appear to be going anywhere, so how is it going to cast a spell if the target is 5000 distance from the dummy -AND- if the dummy doesn't have 0 Animation - Backswing Time and Animation - Cast Point, orders issued in quick succession are likely to break stuff

2) Ahm...
JASS:
        call FlushGameCache(InitGameCache("data.ss"))
        set udg_sscache = InitGameCache("data.ss")

IIRC, the extension for cache is .w3v, not any random thing you feel like putting in there

3) Any particular reason why you aren't using vJASS - there isn't any reason not to (since I2H-based functions are known to be unsafe). And please don't say "For non-NewGen users", since downloading NewGen is a small price to pay* for greater safety

*It's not necessarily a bad thing
 

Vestras

Retired
Reaction score
248
1) Cast backswing point is 0. You can decide where to create the dummy yourself, but I'll might add a MoveDummy function. Why isn't it fully MUI?

2) I know, but that can work too.

3) I knew you would say that. :p And yes, there is - there is still people who doesn't use vJASS, so I want those to be able to follow too.
 

Flare

Stops copies me!
Reaction score
662
You can decide where to create the dummy yourself, but I'll might add a MoveDummy function. Why isn't it fully MUI?

Look at the castTargetingType functions - they aren't moving the units at all so if I cast at (1000, 1500) using castXY, then cast at (2000, 500) with castXY, the dummy won't be there to cast, so that would mean it's not fully MUI

And your createDummy function should have a duration argument as well since if you use createDummy, then a createAndCast function, a dummy is left floating around since it isn't destroyed since people may forget to use removeDummy (which is a bit useless) or would find it more convienient to have the dummy be killed automatically

there is still people who doesn't use vJASS, so I want those to be able to follow too.
Read the rest of the sentence
 

Vestras

Retired
Reaction score
248
Oh yeah, I forgot to add SetSourceX and SetSourceY functions, I'll do that.
Okay then...

> Read the rest of the sentence

I did.
 
Reaction score
333
3) I knew you would say that. :p And yes, there is - there is still people who doesn't use vJASS, so I want those to be able to follow too.

And you think that people who do use vJass are still going to want to use this system when it doesn't even come in a library? There are people who still live in huts in certain parts of the world..

Why is the circle function not using radians internally?

JASS:


...

JASS:
GetStoredString(ss(), "ss", "grp_order")


You appear to be using Gamecache to replace globals here.

JASS:
call UnitDamagePoint(c, 0, dmgaoe, px, py, dmg, false, true, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, null)


Just pretend that this function doesn't exist.

JASS:
function line takes real x, real y, real tx, real ty, unit c, string fx, integer n, real dmg, real dmgaoe, boolean armor returns nothing
    local integer i = 0
    local real dx = tx - x
    local real dy = ty - y
    local real dist = SquareRoot(dx * dx + dy * dy) / n
    local real angle = Atan2(ty - y, tx - x)
    local real px
    local real py
                
        loop
            set i = i + 1
            exitwhen i > n
                set px = x + (dist * i) * Cos(angle)
                set py = y + (dist * i) * Sin(angle)
                call DestroyEffect(AddSpecialEffect(fx, px, py))
                call DamagePointEnemies(c, px, py, dmgaoe, dmg, armor)
        endloop
endfunction


You should not be using trigonometry to draw a line between two points.

JASS:
loop
            set s = FirstOfGroup(g)
            exitwhen s == null
                call IssueTargetOrder(bj_ghoul[ss_integer()], orderstring, s)
        endloop


So this is going to loop over the first unit in a group until it hits the op limit.

JASS:
constant function I2U takes integer i returns unit


Not safe (also why is this constant?).

JASS:
function create takes real x, real y returns unit
    set bj_ghoul[ss_integer()] = CreateUnit(Player(ss_player()), ss_dummy(), x, y, 0)
    return bj_ghoul[ss_integer()]
endfunction


It appears this function is never called.
 

Xorifelse

I'd love to elaborate about discussions...........
Reaction score
87
IIRC, the extension for cache is .w3v, not any random thing you feel like putting in there

Oh really? It seems to work fine here,
JASS:

    function init takes nothing returns nothing
        set g = InitGameCache( "handlevars_" + I2S( GetRandomInt( 0, 100000 ) ) )
        call StoreInteger( g, "a", "a", 1 )
        call FlushStoredInteger( g, "a", "a" )
    endfunction


Perhaps its vJass correcting it, but I used a couple of things with it and it works.
 

Vexorian

Why no custom sig?
Reaction score
187
I got to thank you, you have seriously managed to make the best example possible of why should people stop using normal Jass.

I mean, seriously:

JASS:
function DamagePointAll takes unit damager, real x, real y, real radius, real damage, boolean armor returns nothing
    local group g = CreateGroup() //ouch
    call StoreBoolean(ss(), "ss", "dpall_armor", armor)  // oh my
    call StoreReal(ss(), "ss", "dpall_damage", damage) //
    call StoreInteger(ss(), "ss", "dpall_damager", H2I(damager)) // /!\ 
        call GroupEnumUnitsInRange(g, x, y, radius, null) // -.-
        call ForGroup(g, function DPALL_Callback) // x_x
    call DestroyGroup(g) // :/
    set g = null //The only line in the whole function that is not plain wrong!
endfunction


And the killing blow:

JASS:
constant function ss_integer takes nothing returns integer
    // Just a random integer, the more random the better
    return 6594
endfunction

constant function GetLastCreatedDummy takes nothing returns unit
    return bj_ghoul[ss_integer()]
endfunction


Is this MUI?
It is miles away from being MUI, but believe me, that's the least of your problems right now.

here is still people who doesn't use vJASS, so I want those to be able to follow too.
Demagogy, always a great idea...
 

Vestras

Retired
Reaction score
248
> Vexorian

Wow. Just wow. How can someone be that arrogant? You don't even tell me what's wrong. You know, not everybody is as good at programming as you.

> And you think that people who do use vJass are still going to want to use this system when it doesn't even come in a library? There are people who still live in huts in certain parts of the world..

No.

> Why is the circle function not using radians internally?

Dunno.

> You appear to be using Gamecache to replace globals here.

So?

> Just pretend that this function doesn't exist.

Why?

> You should not be using trigonometry to draw a line between two points.

What is that? :p

> So this is going to loop over the first unit in a group until it hits the op limit.

Where did you find that? I thought I killed all those...

> Not safe (also why is this constant?).

Why not? And it's constant because all it does it returning.

> It appears this function is never called.

It's for the user...
 

Flare

Stops copies me!
Reaction score
662
You don't even tell me what's wrong
First line of his post made it clear enough :p

As regards his example, I believe it'd be:
1) Group recycling, single global group is far better
2) Gamecache instead of globals
3) Read #2
4) I2H
5) Nulling boolexpr argument i.e. leak
6) You could've done the ForGroup stuff within the the group filter (even though you don't even have a filter...)
7) Again, you could've used group recycling/clear a single global group instead
8) Correct :p

(please, correct me if I'm wrong on these :D)

Globals are simpler and (in this case) safer

It can cause desyncs for Mac users I believe

Where did you find that? I thought I killed all those...
JASS:
function castAOE takes integer abilityid, integer level, real timed, string orderstring, real x, real y, real radius returns nothing
    local group g = CreateGroup()
    local unit s
        call GroupEnumUnitsInRange(g, x, y, radius, null)
        call UnitAddAbility(bj_ghoul[ss_integer()], abilityid)
        call SetUnitAbilityLevel(bj_ghoul[ss_integer()], abilityid, level)
        call UnitApplyTimedLife(bj_ghoul[ss_integer()], 'BTLF', timed)
        loop
            set s = FirstOfGroup(g)
            exitwhen s == null
                call IssueTargetOrder(bj_ghoul[ss_integer()], orderstring, s)
        endloop
    call DestroyGroup(g)
    set s = null
    set g = null
endfunction


Why not? And it's constant because all it does it returning.
I2H-based stuff can return the incorrect variable type (there's no guarantee that you're actually going to end up with a unit at the end) which can cause crashes and various bad sh*t
 

Vexorian

Why no custom sig?
Reaction score
187
Wow. Just wow. How can someone be that arrogant?
You can see it that way.
You know, not everybody is as good at programming as you.
Well, perhaps it is true that not everybody is as good at programming as me, but I just think that they should. Sorry, If thinking that way offends you.

You don't even tell me what's wrong
All what I quoted is wrong, besides of the set g=null part, and I have recognized that you are not to blame for the wrong code, normal Jass the problem here, I was serious in my first paragraph this just shows how broken normal Jass is, the fact you have no freedom to declare globals has forced you to code as bad as we all did in the old times, but now, in 2008, the problems with your code are so blatant that they show that it is probably impossible to make decent code without vJass, vJass' main point being global addition.

CreateGroup - GroupEnumWithNullBoolexpr - DestroyGroup
Memory leak. Again, this problem requires you to use globals, so yes, win for vJass.

gamecache
Gamecache use can be justified but you are using it in places where it plain is not justified, like replacing global variables, and that's just wrong, the penalty in speed and requirements really is too big for it to be able to be a good replacement for globals, win for vJass.

Really, there are structs, there's indexing (which requires global declaration freedom) that I2H stuff is an unnecessary risk.

bj_ghoul[ss_integer()]
The mere fact you are using bj_ghoul like that with a constant function that returns a random number, it is all just broken, magic numbers everywhere, you need globals.


--
Are people that would not use vJass worth lowering the quality of your system by this far? I'd say not, specially when considering that the only people that are unable to run vJass are those in non-intel Macs, the two of them.
 

quraji

zap
Reaction score
144
What is with this bj_ghoul[ss_integer()] stuff? Are you serious? I was going to look over your code fully but seeing that (along with the other stuff) is just counter-motivational.

Sometimes (in other threads) you seem to know what you're doing, and other times you seem like you're on your first day of JASS. Do you have multiple people posting from your account or something?

I'm referring in part to this thread here. I haven't actually bothered to look into it much (another attachment system...no thanks), but at first glance I can gather a few things. You have a knowledge of vJass, and it's features (textmacros, global blocks, etc.). And that you can code a reasonably "complex" (in jass terms) system.

And yet, here I gaze upon a miserable mess of failed jass. Very inconsistent.
 

Vestras

Retired
Reaction score
248
> Vexorian

Oh, okay. But really, why is gamecache so bad? Yes, I know its slower and all that stuff, but why? It can't be bad when the code doesn't need speed.

> quraji

What's wrong with my attachment system? I use it, nothing is wrong with it. And yes, there is... some stuff... that I have a hard time understanding.

Well, I guess I got to make this into vJASS. Then I'll just make it methods, then there's no need for attachment systems.
 

Flare

Stops copies me!
Reaction score
662
But really, why is gamecache so bad?
1) It's excessive when 2 or 3 globals do the same thing i.e. why take the time and effort to declare the cache, set it up, assign things, retrieve things and flush it -AND- using I2H (which is known to be bad), when you could easily do
JASS:
set globalUnit = whichUnit
set globalReal = whatDamage
call GroupEnumUnitsInRange (globalGroup, x, y, radius, Condition (function GroupFunc))
//There is no MUI issues there since you can't use a wait in the group filter anyway, and just return false in GroupFunc to keep the group empty at the end of it all

without any significant problems

Then I'll just make it methods
Doesn't need to be methods - not much point giving people access to a struct if they don't need a struct (standard functions with arguments can work just as well as methods with arguments (or pre-designated members), and there is no problems regarding things like destroying struct instances, and it allows a certain amount of GUI-friendliness since they won't need to understand struct usage to understand a function call)

then there's no need for attachment systems.
Methods don't mean you won't need an attachment system (even though, this system is likely to never need an attachment system going by the current code)
 

Xorifelse

I'd love to elaborate about discussions...........
Reaction score
87
He is not saying that the game cache is bad, he is saying the way you use it is bad.
You can use vJass to create this code in, however using handlevars should be a great improvement aswell.

I suspect you know how to use the handlevars system, but why don't you use it?
JASS:
call StoreBoolean(ss(), "ss", "dpall_armor", armor)
call StoreReal(ss(), "ss", "dpall_damage", damage)
call StoreInteger(ss(), "ss", "dpall_damager", H2I(damager))


You have a unit, why don't you store the boolean, real and the integer in that unit?
Instead you try and create some sort of a private "globals" ( default game cache ), which is slower then normal globals, and isn't MUI.

Secondly there are a lot of bugs in your code and a lot of callbacks not to mention leaks.
For example, i recommend you should use..:

loop
set u = FirstOfGroup( g )
call GroupRemoveUnit( g, u ) // Why are you creating an infinite loop by not adding this?
exitwhen u == null

....

endloop

Looping through a group this way is in most occasions better and faster the ForGroup()
It doesn't create a BoolExpr leak and most of the times you have the local variables at hand, so you don't need to use handlevars or soemthing else.
For example ( createAndCastAOE, AOE_Callback )

Yes, your code is scripted horribly.. the whole point of using jass is to make your code much more efficient, not having to use LOCATIONS...
Avoid useing locations, there are some occations you will need them but not for their basic functionality.

Thirtly, what did you expect from us, pasting a half working inefficient "system", I certainly don't hope you want to have lies told to you of us saying "Man thats a great system, Ima use it right away!"
 

Flare

Stops copies me!
Reaction score
662
Looping through a group this way is in most occasions better and faster the ForGroup()
It doesn't create a BoolExpr leak

Neither does
JASS:
GroupEnumUnitsInRange (g, x, y, radius, Condition (function FilterFunc))
call ForGroup (g, function GroupFunc) //Even though a ForGroup isn't really necessary if you do the group handling within FilterFunc

which is the 'normal'* method (even though I don't think that's exactly what Vestras is doing with the code at the moment)

*I think :p

Thirtly, what did you expect from us, pasting a half working inefficient "system", I certainly don't hope you want to have lies told to you of us saying "Man thats a great system, Ima use it right away!"
Well, he only asked if it was MUI, there wasn't any mention of "How efficient/complete is this?" even though it's fairly obvious that Vestras was informed of those things as well ^^
 
Reaction score
333
Oh, okay. But really, why is gamecache so bad? Yes, I know its slower and all that stuff, but why? It can't be bad when the code doesn't need speed.

How do you know that your code doesn't require "speed" (or merely the absence of slowness in this case)? If it's a system, then people could be using it in any number of ways. "It doesn't matter how slow, ugly and unreadable my code is, as long as it still works" is not good reasoning.

But speed isn't the main problem with using gamecache as a globals replacement. Look at your code... If it doesn't strike you as fundamentally and conceptually wrong that you are using gamecache and the return bug to substitute for something like a global unit variable, then you should stop trying to make systems and this applies to a lot of other stuff as well..

Throughout this thread and others, people have been trying to give advice and your response is often to just deny it because you do not understand why it has been given. You shouldn't approach advice with the intention of ignoring it. If you don't understand why I2H is unsafe, or why gamecache should not be used in lieu of globals, or why it is better to use a filter function in GroupEnum than a ForGroup then you should simply be willing to accept this advice on the basis that the people offering it are probably more experienced than yourself.

What's wrong with my attachment system? I use it, nothing is wrong with it. And yes, there is... some stuff... that I have a hard time understanding.

He didn't say anything was wrong with it, he was just comparing the two.

For example, i recommend you should use..:

loop
set u = FirstOfGroup( g )
call GroupRemoveUnit( g, u ) // Why are you creating an infinite loop by not adding this?
exitwhen u == null

....

endloop

Looping through a group this way is in most occasions better and faster the ForGroup()
It doesn't create a BoolExpr leak and most of the times you have the local variables at hand, so you don't need to use handlevars or soemthing else.

ForGroup does not create a leak (it is the GroupEnum with null boolexpr that does) and you only need to use globals to pass data to callbacks. In most cases neither FirstOfGroup loops nor ForGroups need to be used. Put the group actions into a GroupEnum filter function instead.
 

Viikuna

No Marlo no game.
Reaction score
265
ForGroup does not create a leak (it is the GroupEnum with null boolexpr that does) and you only need to use globals to pass data to callbacks. In most cases neither FirstOfGroup loops nor ForGroups need to be used. Put the group actions into a GroupEnum filter function instead.

I just realized how great this actually is :D
 

Vestras

Retired
Reaction score
248
> How do you know that your code doesn't require "speed" (or merely the absence of slowness in this case)? If it's a system, then people could be using it in any number of ways. "It doesn't matter how slow, ugly and unreadable my code is, as long as it still works" is not good reasoning.

But speed isn't the main problem with using gamecache as a globals replacement. Look at your code... If it doesn't strike you as fundamentally and conceptually wrong that you are using gamecache and the return bug to substitute for something like a global unit variable, then you should stop trying to make systems and this applies to a lot of other stuff as well..

Throughout this thread and others, people have been trying to give advice and your response is often to just deny it because you do not understand why it has been given. You shouldn't approach advice with the intention of ignoring it. If you don't understand why I2H is unsafe, or why gamecache should not be used in lieu of globals, or why it is better to use a filter function in GroupEnum than a ForGroup then you should simply be willing to accept this advice on the basis that the people offering it are probably more experienced than yourself.

Uhm, I don't, it was just for example. (I know that dummy casters require as much speed as possible, because they are really slow them selves.)

Well, yeah, but I didn't actually knew that it could up, or why. I thought "well, it works, then it's fine".

What are you referring to? Maybe that's just my nature?
 
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