Spell BlinkBJ

Sgqvur

FullOfUltimateTruthsAndEt ernalPrinciples, i.e shi
BlinkBJ is a jass version of the Warden's ability Blink. BlinkBJ tries to mimic as much as possible the behavior of Blink. In a zealous attempt to make it as close as possible to the original it also "inherits" a flaw. The flaw is that Blink doesn't check if the target position is in the playable map area, BlinkBJ doesn't do either but it can easily be added =).

BlinkBJ requires SimError

Code:
Credits to Vexorian, DioD, Cohadar and Alexander244. 
http://www.wc3c.net/showthread.php?t=96955

globals
    sound SimError_Sound = null
    real SIMERROR_DEFAULT_DURATION = 2.00
endglobals

function SimError takes player p, string msg, real duration returns nothing
    if (GetLocalPlayer() == p) then
        call ClearTextMessages()
        call DisplayTimedTextToPlayer(p, 0.51, 0.96, duration, "|cffffcc00\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" + msg + "|r")
        call StartSound(SimError_Sound)
    endif
endfunction

function InitTrig_SimError takes nothing returns nothing
    set SimError_Sound = CreateSoundFromLabel("InterfaceError", false, false, false, 10, 10)
endfunction


Code:
globals

    constant integer BLINKBJ_RAWCODE = 'ABBJ'
    constant string  BLINKBJ_DEFAULT_EFFECT_CASTER_LOCATION = "Abilities\\Spells\\NightElf\\Blink\\BlinkCaster.mdl"
    constant string  BLINKBJ_DEFAULT_EFFECT_TARGET_POINT_LOCATION = "Abilities\\Spells\\NightElf\\Blink\\BlinkTarget.mdl"

    constant integer BLINKBJ_ERROR_TERRAIN_IS_MASKED = 10
    constant string  BLINKBJ_ERROR_TERRAIN_IS_MASKED_MESSAGE = "Must explore there first."
    
    constant integer BLINKBJ_ERROR_WITHIN_MINIMUM_RANGE = 20
    constant string  BLINKBJ_ERROR_WITHIN_MINIMUM_RANGE_MESSAGE = "Target is inside minimum range."
    
    constant integer BLINKBJ_ERROR_INVALID_TARGET_POINT = 30
    constant string  BLINKBJ_ERROR_INVALID_TARGET_POINT_MESSAGE = "Unable to target there."
    
    constant integer BLINKBJ_ERROR_CASTER_DISABLED_MOVEMENT = 40
    constant string  BLINKBJ_ERROR_CASTER_DISABLED_MOVEMENT_MESSAGE = "Caster movement has been disabled."

    constant integer BLINKBJ_SUCCESS = 1

endglobals

//function UnitResetAbilityCooldown takes unit u, integer abilityid returns nothing
//    local integer level = GetUnitAbilityLevel(u, abilityid)
//    call UnitRemoveAbility(u, abilityid)
//    call UnitAddAbility(u, abilityid)
//    call SetUnitAbilityLevel(u, abilityid, level)
//endfunction

function BlinkBJClearSideEffects takes unit u returns nothing
    call IssueImmediateOrder(u, "stop")
    call TriggerSleepAction(0.0)
    call SetUnitAnimation(u, "stand")
endfunction

function BlinkBJ takes string effect_caster_loc, string effect_target_point_loc, real min_range, real max_travel_range, unit hero_nakamura, real target_pointx, real target_pointy, string hotkey returns integer
    local player hero_owner = GetOwningPlayer(hero_nakamura)
    local real casterx = GetUnitX(hero_nakamura)
    local real castery = GetUnitY(hero_nakamura)
    local real dx
    local real dy
    local real range
    local real angle
    local real blinkendx
    local real blinkendy
    local boolean hero_is_invul
    
    if IsMaskedToPlayer(target_pointx, target_pointy, hero_owner) then
        call BlinkBJClearSideEffects(hero_nakamura)
        call ForceUIKey(hotkey)
        call SimError(hero_owner, BLINKBJ_ERROR_TERRAIN_IS_MASKED_MESSAGE, SIMERROR_DEFAULT_DURATION)
        
        return BLINKBJ_ERROR_TERRAIN_IS_MASKED
    endif
    
    set dx = target_pointx - casterx 
    set dy = target_pointy - castery 
    set range = SquareRoot(dx * dx + dy * dy)
    set angle = Atan2(dy, dx)
    
    if range < min_range then
        call BlinkBJClearSideEffects(hero_nakamura)
        call ForceUIKey(hotkey)
        call SimError(hero_owner, BLINKBJ_ERROR_WITHIN_MINIMUM_RANGE_MESSAGE, SIMERROR_DEFAULT_DURATION)
        
        return BLINKBJ_ERROR_WITHIN_MINIMUM_RANGE
        
    elseif range >= max_travel_range then
        set dx = casterx + max_travel_range * Cos(angle)
        set dy = castery + max_travel_range * Sin(angle)
    else
        set dx = casterx + range * Cos(angle)
        set dy = castery + range * Sin(angle)
    endif

    set blinkendx = dx
    set blinkendy = dy
    
    if IsMaskedToPlayer(blinkendx, blinkendy, hero_owner) then
        call BlinkBJClearSideEffects(hero_nakamura)
        call ForceUIKey(hotkey)
        call SimError(hero_owner, BLINKBJ_ERROR_INVALID_TARGET_POINT_MESSAGE, SIMERROR_DEFAULT_DURATION)
        
        return BLINKBJ_ERROR_INVALID_TARGET_POINT
    endif
    
    // ensnare, roots etc.
    if GetUnitMoveSpeed(hero_nakamura) <= 0.0 then
        call BlinkBJClearSideEffects(hero_nakamura)
        call ForceUIKey(hotkey)
        call SimError(hero_owner, BLINKBJ_ERROR_CASTER_DISABLED_MOVEMENT_MESSAGE, SIMERROR_DEFAULT_DURATION)
        
        return BLINKBJ_ERROR_CASTER_DISABLED_MOVEMENT
    endif
    
    call DestroyEffect(AddSpecialEffect(effect_caster_loc, casterx, castery))
    call SetUnitX(hero_nakamura, blinkendx)
    call SetUnitY(hero_nakamura, blinkendy)
    call DestroyEffect(AddSpecialEffect(effect_target_point_loc, GetUnitX(hero_nakamura), GetUnitY(hero_nakamura)))

    set hero_is_invul = (GetUnitAbilityLevel(hero_nakamura, 'Avul') >= 1)
    if not hero_is_invul then
        // Add spell ivul to avoid projectiles(storm bolt, death coil etc.)
        call UnitAddAbility(hero_nakamura, 'Avul')
    endif

    // keep the ivul for some fraction of second
    // why 0.4? felt like a nice magic number what can I say it's my favorite number 4 div by 10 =)
    call TriggerSleepAction(0.4)

    if not hero_is_invul then
        // remove invul from hero to prevent imba
        call UnitRemoveAbility(hero_nakamura, 'Avul')
    endif
    
    return BLINKBJ_SUCCESS
endfunction

function BlinkBJ_Action takes nothing returns nothing
    local unit caster = GetTriggerUnit()
    local integer level = GetUnitAbilityLevel(caster, BLINKBJ_RAWCODE)
    local real min_range = 200
    local real max_travel_range = (1000 + ((level - 1) * 75)) * 0.75 // 3/4
    
    // http://world-editor-tutorials.thehelper.net/formula.php
    // 50 / 10 / 10
    //local real mana_cost = 20 * level * level - 100 * level + 130
    
    local location loc = GetSpellTargetLoc()
    local real target_pointx = GetLocationX(loc)
    local real target_pointy = GetLocationY(loc)
    
    call BlinkBJ(BLINKBJ_DEFAULT_EFFECT_CASTER_LOCATION, BLINKBJ_DEFAULT_EFFECT_TARGET_POINT_LOCATION, min_range, max_travel_range, caster, target_pointx, target_pointy, "B")

    call RemoveLocation(loc)
    set loc = null
endfunction

//===========================================================================
function BlinkBJ_Condition takes nothing returns boolean
    return GetSpellAbilityId() == BLINKBJ_RAWCODE
endfunction

function InitTrig_BlinkBJ takes nothing returns nothing
    local trigger t = CreateTrigger()
    
    call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_CAST)
    call TriggerAddCondition(t, Condition(function BlinkBJ_Condition))
    call TriggerAddAction(t, function BlinkBJ_Action)
endfunction
 

Attachments

luorax

Invasion in Duskwood
I haven't checked the whole script, cuz it's too late and I've to go school tomorrow, but here's something:

PHP:
    local location loc = GetSpellTargetLoc()
    local real target_pointx = GetLocationX(loc)
    local real target_pointy = GetLocationY(loc)
==

PHP:
    local real target_pointx = GetSpellTargetX()
    local real target_pointy = GetSpellTargetY()
 

tooltiperror

Super Moderator
I haven't checked the whole script, cuz it's too late and I've to go school tomorrow, but here's something:

PHP:
    local location loc = GetSpellTargetLoc()
    local real target_pointx = GetLocationX(loc)
    local real target_pointy = GetLocationY(loc)
==

PHP:
    local real target_pointx = GetSpellTargetX()
    local real target_pointy = GetSpellTargetY()
Incorrect, that's bugged.

Name has an incorrect convention. BJ = Blizzard JASS.

Spell also unneccesary. If it can be done with object editor, then do so.
 

Romek

Super Moderator
Staff member
Why would you submit what is essentially a spell that's in the game by default?
 

Sgqvur

FullOfUltimateTruthsAndEt ernalPrinciples, i.e shi
>Spell also unneccesary. If it can be done with object editor, then do so.

Now where's the fun in that?

>Why would you submit what is essentially a spell that's in the game by default?

Warcraft III TFT has many spells "by default" that's true.
But they are all "static". You can't change their behavior while playing. You do some OE stuff and that's it while triggered spells doesn't suffer from that kinda problem.

You can call me an "imaginationless" copycat as much as you like =).

>Name has an incorrect convention. BJ = Blizzard JASS.

I reject your conventions and substitute my own.
 

tooltiperror

Super Moderator
The natives give incorrect information. If a spell targets at (50,30) and you use GetSpellTargetX(), it may return something such as 55. Not sure exact coordinates that would be effected, but GetSpellTargetX/Y return incorrect numbers.

EDIT: Post a link to SimError, and put everything inside a scope/library, make functions private, and such.
 

BlackRose

Forum User
Does this simulate dodging missiles as well?
Does this cap the Blink range to 3/4 if you target outside the maximum Blink distance (as it does normally, although I don't know why you would want that to happen :p)?
 

tooltiperror

Super Moderator
Code:
scope Blink initializer onInit // Requires SimError, GTrigger

	globals
		private constant integer BLINKBJ_RAWCODE = 'ABBJ'
		private constant string  BLINKBJ_DEFAULT_EFFECT_CASTER_LOCATION = "Abilities\\Spells\\NightElf\\Blink\\BlinkCaster.mdl"
		private constant string  BLINKBJ_DEFAULT_EFFECT_TARGET_POINT_LOCATION = "Abilities\\Spells\\NightElf\\Blink\\BlinkTarget.mdl"
		private constant integer BLINKBJ_ERROR_TERRAIN_IS_MASKED = 10
		private constant string  BLINKBJ_ERROR_TERRAIN_IS_MASKED_MESSAGE = "Must explore there first."  
		private constant integer BLINKBJ_ERROR_WITHIN_MINIMUM_RANGE = 20
		private constant string  BLINKBJ_ERROR_WITHIN_MINIMUM_RANGE_MESSAGE = "Target is inside minimum range."    
		private constant integer BLINKBJ_ERROR_INVALID_TARGET_POINT = 30
		private constant string  BLINKBJ_ERROR_INVALID_TARGET_POINT_MESSAGE = "Unable to target there."
		private constant integer BLINKBJ_SUCCESS = 1
	endglobals

	private function UnitResetAbilityCooldown takes unit u, integer abilityid returns nothing
		local integer level = GetUnitAbilityLevel(u, abilityid)
		call UnitRemoveAbility(u, abilityid)
		call UnitAddAbility(u, abilityid)
		call SetUnitAbilityLevel(u, abilityid, level)
	endfunction

	private function BlinkBJClearSideEffects takes unit u returns nothing
		call IssueImmediateOrder(u, "stop")
		call TriggerSleepAction(0.0)
		call SetUnitAnimation(u, "stand")
	endfunction

	private function BlinkBJ takes integer rawcode, string effect_caster_loc, string effect_target_point_loc, real min_range, real max_travel_range, real mana_cost, unit hero_nakamura, real target_pointx, real target_pointy, string hotkey returns integer
		local player hero_owner = GetOwningPlayer(hero_nakamura)
		local real casterx = GetUnitX(hero_nakamura)
		local real castery = GetUnitY(hero_nakamura)
		local real dx
		local real dy
		local real range
		local real angle
		local real blinkendx	
		local real blinkendy
		if IsMaskedToPlayer(target_pointx, target_pointy, hero_owner) then
			call SetUnitState(hero_nakamura, UNIT_STATE_MANA, mana_cost + GetUnitState(hero_nakamura, UNIT_STATE_MANA))
			call UnitResetAbilityCooldown(hero_nakamura, rawcode)	
			call BlinkBJClearSideEffects(hero_nakamura)
			call ForceUIKey(hotkey)
			call SimError(hero_owner, BLINKBJ_ERROR_TERRAIN_IS_MASKED_MESSAGE, 10.0)
			return BLINKBJ_ERROR_TERRAIN_IS_MASKED
		endif
		set dx = target_pointx - casterx 
		set dy = target_pointy - castery 
		set range = SquareRoot(dx * dx + dy * dy)
		set angle = Atan2(dy, dx)
		if range < min_range then
			call SetUnitState(hero_nakamura, UNIT_STATE_MANA, mana_cost + GetUnitState(hero_nakamura, UNIT_STATE_MANA))
			call UnitResetAbilityCooldown(hero_nakamura, rawcode)
			call BlinkBJClearSideEffects(hero_nakamura)
			call ForceUIKey(hotkey)
			call SimError(hero_owner, BLINKBJ_ERROR_WITHIN_MINIMUM_RANGE_MESSAGE, 10.0)
			return BLINKBJ_ERROR_WITHIN_MINIMUM_RANGE
		elseif range >= max_travel_range then
			set dx = casterx + max_travel_range * Cos(angle)
			set dy = castery + max_travel_range * Sin(angle)
		else
			set dx = casterx + range * Cos(angle)
			set dy = castery + range * Sin(angle)
		endif
		set blinkendx = dx
		set blinkendy = dy
		if IsMaskedToPlayer(blinkendx, blinkendy, hero_owner) then
			call SetUnitState(hero_nakamura, UNIT_STATE_MANA, mana_cost + GetUnitState(hero_nakamura, UNIT_STATE_MANA))
			call UnitResetAbilityCooldown(hero_nakamura, rawcode)
			call BlinkBJClearSideEffects(hero_nakamura)
			call ForceUIKey(hotkey)	
			call SimError(hero_owner, BLINKBJ_ERROR_INVALID_TARGET_POINT_MESSAGE, 10.0)
			return BLINKBJ_ERROR_INVALID_TARGET_POINT
		endif
		call DestroyEffect(AddSpecialEffect(effect_caster_loc, casterx, castery))
		call BlinkBJClearSideEffects(hero_nakamura)
		call SetUnitPosition(hero_nakamura, blinkendx, blinkendy)
		call DestroyEffect(AddSpecialEffect(effect_target_point_loc, GetUnitX(hero_nakamura), GetUnitY(hero_nakamura)))
		return BLINKBJ_SUCCESS
	endfunction
	
	private function Actions takes nothing returns boolean
		local unit caster = GetTriggerUnit()
		local integer level = GetUnitAbilityLevel(caster, BLINKBJ_RAWCODE)
		local real min_range = 200
		local real max_travel_range = 1000 + ((level - 1) * 75)
		// http://world-editor-tutorials.thehelper.net/formula.php
		// 50 / 10 / 10
		local real mana_cost = 20 * level * level - 100 * level + 130
		local location loc = GetSpellTargetLoc()
		local real target_pointx = GetLocationX(loc)
		local real target_pointy = GetLocationY(loc)
		call BlinkBJ(BLINKBJ_RAWCODE, BLINKBJ_DEFAULT_EFFECT_CASTER_LOCATION, BLINKBJ_DEFAULT_EFFECT_TARGET_POINT_LOCATION, min_range, max_travel_range, mana_cost, caster, target_pointx, target_pointy, "B")
		call RemoveLocation(loc)
		set loc = null
		return false
	endfunction
	
	private function onInit takes nothing returns nothing
		call TriggerAddCondition(GT_RegisterStartsEffectEvent(CreateTrigger(),BLINKBJ_RAWCODE),Condition(function Actions))
	endfunction

endscope
I put your code in a scope, added some scope, and used GTrigger Event to register the spell instead of the ugly method you were doing. I also put it into a boolexpr and updated it to look like modern vJASS.

1) Use a struct instead of locals, they're somewhere around 0.00001 seconds faster, and OOP is more manageable if this is a 'template'.
2) Remove your BLINKBJ prefixes. Again, we're not in the midst of discovering JASS2.
3) Inline some of your functions? They're just as bad as using a BJ in some places (BlinkBJClearSideEffects)
4) Do you really insist on using an improper term because you can't be half assed to show some dedicated to getting something improved?
 

BlackRose

Forum User
Incorrect, that's bugged.
Not sure exact coordinates that would be effected, but GetSpellTargetX/Y return incorrect numbers.
stupid stupid :mad::mad::mad::mad:

Code:
function GetSpellTargetCoords_OnEffectResponse takes nothing returns nothing
    local location  loc     = GetSpellTargetLoc()
    local boolean   xmatch  = false
    local boolean   ymatch  = false
    
    local real      tarx    = GetSpellTargetX()
    local real      tary    = GetSpellTargetY()
    
    local real      tarxloc = GetLocationX( loc )
    local real      taryloc = GetLocationY( loc )
    
    call ClearTextMessages()
    call BJDebugMsg( "Target X (X):" + R2S( tarx ) )
    call BJDebugMsg( "Target X (Loc): " + R2S( tarxloc ) )
    call BJDebugMsg( "-------------------------------------------" )
    call BJDebugMsg( "Target Y (Y):" + R2S( tary ) )
    call BJDebugMsg( "Target Y (Loc): " + R2S( taryloc ) )
    
    if tarx == tarxloc then
        set xmatch = true
    endif
    
    if tary == taryloc then
        set ymatch = true
    endif
    
    if xmatch and ymatch then
        call BJDebugMsg( "|cff00FF00Happy New Years! GetSpellTargetLoc() and GetSpellTargetX/Y() are sane!" )
    else
        if not xmatch then
            call BJDebugMsg( "|cffFF0000The x values did not match!" )
        elseif not ymatch then
            call BJDebugMsg( "|cffFF0000The y values did not match!" )
        elseif not xmatch and not ymatch then
            call BJDebugMsg( "|cffFF0000The x values and y values did not match!" )
        endif
    endif
    
    call RemoveLocation( loc )
    set loc = null
endfunction

//===========================================================================
function InitTrig_GetSpellTargetCoords takes nothing returns nothing
    set gg_trg_GetSpellTargetCoords = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( gg_trg_GetSpellTargetCoords, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddAction( gg_trg_GetSpellTargetCoords, function GetSpellTargetCoords_OnEffectResponse )
endfunction
Where is your evidence that GetSpellTargetX/Y is inaccurate, tooltiperror?
 

Sgqvur

FullOfUltimateTruthsAndEt ernalPrinciples, i.e shi
>1) Use a struct instead of locals, they're somewhere around 0.00001 seconds faster, and OOP is more manageable if this is a 'template'.

Nah I prefer gigantic function calls and this is not a template it's a "mimicy" of Blink.

>2) Remove your BLINKBJ prefixes. Again, we're not in the midst of discovering JASS2.
Well that's funny it's like BLINKBJ prefix reminds you of the infamous udg_ prefix.

>3) Inline some of your functions? They're just as bad as using a BJ in some places (BlinkBJClearSideEffects)

What does that suppose to mean?

>4) Do you really insist on using an improper term because you can't be half assed to show some dedicated to getting something improved?

Improved? Do you really think that adding scope, using struct/OOP, removing prefixes and inlining(3 lines of code) actually improve anything in this case?

And where is my white space and new lines in your "improved" script?(aka hard to read)

>I also put it into a boolexpr and updated it to look like modern vJASS.

It uses TriggerSleepAction(0) so it will crash the thread?

I think this might be added as well:
Code:
call Preload(BLINKBJ_DEFAULT_EFFECT_CASTER_LOCATION)
call preload(BLINKBJ_DEFAULT_EFFECT_TARGET_POINT_LOCATION)
 

Darthfett

Aerospace/Cybersecurity Software Engineer
I put your code in a scope, added some scope, and used GTrigger Event to register the spell instead of the ugly method you were doing. I also put it into a boolexpr and updated it to look like modern vJASS.
Nothing wrong with using the method he was using. IMO, yours requires much more 'decrypting'.

1) Use a struct instead of locals, they're somewhere around 0.00001 seconds faster, and OOP is more manageable if this is a 'template'.
I didn't see any mention of this being a template. A few functions is much nicer to non-vJASS users, and since there are no callbacks or time delays (except that TSA, which is just fine for this case). At the most, it would be the increased efficiency of a global over a local, which is shown to be less and less the more globals you have.


2) Remove your BLINKBJ prefixes. Again, we're not in the midst of discovering JASS2.
I'm going to agree with tooltip on this one. BJ stands for 'Blizzard JASS', and since you're using globals blocks (requires vJASS), you may as well use the scope/library feature to add some scope.

3) Inline some of your functions? They're just as bad as using a BJ in some places (BlinkBJClearSideEffects)
Using BJ's isn't always a bad thing. In this case, it becomes clear that the three actions go together, and what their purpose is. Efficiency isn't everything.

4) Do you really insist on using an improper term because you can't be half assed to show some dedicated to getting something improved?
What, exactly, is this referring to?
 

Sgqvur

FullOfUltimateTruthsAndEt ernalPrinciples, i.e shi
This doesn't also dodge incoming projectiles/spells
Yes thanks for pointing that out. (Guess I did some pretty poor testing =) )
Added a fix in the first post and updated the map.

It uses even more TSA now xD
 

jrhetf4xb

Member
^ Ooook... This is going in the wrong direction.
Avoid using TSA - timers are your friend. There are many cons with TSA so it's just pointless to use it.
Also, what's the problem with just
Code:
function Actions()
{
    SetUnitPosition(...); 
    DestroyEffect(...); 
}
You've made just a BLINK spell with 150 lines of code! No offense but that's just wrong with all those "hacky" ways of resetting cooldown and all that stuff.
Why not interrupt orders when the spell is CAST (hasn't taken effect yet)? You will free your code from all that junk.
You also don't use scope + initializer.
And it's definitely useless as most BJs :(
 

Darthfett

Aerospace/Cybersecurity Software Engineer
Avoid using TSA - timers are your friend. There are many cons with TSA so it's just pointless to use it.
Not entirely, and they're especially useful if you just need to do an 'instant wait' (wait for the game to update some information. For example, items don't update their location until after a short wait after the Unit loses an item event).

Everyone should be able to admit that timers don't always promote an optimal way of coding. Even modern games, in real program languages (sometimes?) use a giant loop to run a game. Why are we so limited to breaking up things over time to several extra functions? Even the fact that we refer to it as a limitation should be enough.

Also, what's the problem with just
Code:
function Actions()
{
    SetUnitPosition(...); 
    DestroyEffect(...); 
}
You've made just a BLINK spell with 150 lines of code!
I'm not going to address this, as I also have the same questions. Why should we use YOUR blink spell over a mere effect + move position? You'll need to include some sort of documentation as to what flaws this overcomes, in order to be looked at for approval.
 

Sgqvur

FullOfUltimateTruthsAndEt ernalPrinciples, i.e shi
>You'll need to include some sort of documentation as to what flaws this overcomes, in order to be looked at for approval.

So you think blizzard's blink has flaws? =)

The only flaw in blizzard's blink is that it doesn't check if it was tried to be casted outside of the playable map area (BlinkBJ can easily be made to do that but it doesn't I wrote why in my first post)

>Also, what's the problem with just
Code:
call SetUnitPosition(...)
call DestroyEffect(...)
but this is not blink! This is imba teleport with eyecandy

>Why not interrupt orders when the spell is CAST (hasn't taken effect yet)? You will free your code from all that junk.

Blink/BlinkBJ checks minimum area, if terrain is masked and if target point is in masked terrain
and "throws" different error messages. (What I mean by "if target point is in masked terrain" is that you can have 512 units of visible/fogged terrain (i.e not masked) then a "hole" of masked terrain for example 256 units and then agian 512 units of not masked terrain. Your hero is in one of the not masked areas and tries to teleport to the masked area(i.e) by clicking on the other not masked area because you can try to blink in any area that is not masked(Blink has 9999 cast range) you would think that you can trick blizzard but no the error "Unable to target there." is shown instead.)

BlinkBJ for the outside of playable map check could throw again "Unable to target there." or even a different error message ("Invalid target or whatever")

>You've made just a BLINK spell with 150 lines of code! No offense but that's just wrong with all those "hacky" ways of resetting cooldown and all that stuff.

How do you reset cooldown?
And what hacky stuff?

>You also don't use scope + initializer.
I use initializer it's called InitTrig_... this functions is called by ~InitCustomTriggers which is called by main.
I "scoped" my globals as well.

>And it's definitely useless as most BJs
Why thank you!


BlinkBJ tries to do all the "hard work" by itself and makes Blink not
.
All the "junk" script is needed to make it that way. (not static means that while ingame minimal range/max blink range/effects could change based on level/stats/items/TOD/etc.)
 

tooltiperror

Super Moderator
Ignore all the good points why don't you? Namely mine and Darthfett's posts. And half the battle is making code readable. BLINKBJ prefixes and ugly code do not make that easy.

Also, libraries are far more portable and less confusing than InitTrigs. Some users also import their code into their map header, which they can not do with this spell.

There is also no reason to use this over Object Editor blink. Name one scenario in which I should use this spell.
 

Sgqvur

FullOfUltimateTruthsAndEt ernalPrinciples, i.e shi
>Name one scenario in which I should use this spell.

I grow tired answering this again and again.

If you use Blizzard's Blink you lose outside of map checking.
If you use Blizzard's Blink you set some values in the OE and they are used while playing the game.

If you use BlinkBJ you gain everything Blizzard's have and the potential of map bounds checking.
If you use BlinkBJ you can boost/improve/change/manipulate the way it works while playing the game just by changing it's parameters.

Edit:

>Ignore all the good points why don't you?
I didn't!

>And half the battle is making code readable.
??

>BLINKBJ prefixes and ugly code do not make that easy.
I strive for readable script/easy to understand not "super model" script.

>Also, libraries are far more portable and less confusing than InitTrigs.
If it wasn't for gobals/structs I would stick with st8 Jass2.
I am just really lazy to reimport blizzard.j/common.j and use their globals block every time I want to change some global. Also the struct's dot syntax is something I can not throw away either cause I like it so much =).

>Some users also import their code into their map header, which they can not do with this spell.

Which spell can? And also the BlinkBJ function can be added there which is infact the core of the spell.
 

tooltiperror

Super Moderator
If you use BlinkBJ you gain everything Blizzard's have and the potential of map bounds checking.
Add a trigger when blink is casted and order the unit to stop if it is outside of map bounds.

If you use BlinkBJ you can boost/improve/change/manipulate the way it works while playing the game just by changing it's parameters.
You can copy paste the blink ability and change it in game, or even do something clever with ability levels for units.

This spell is useless. Look at spells in the spell section, and see how yours compares in quality.

And change the name.
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • The Helper The Helper:
    Friday Yay!
  • mgarcia mgarcia:
    did you guys catch Carl's interview? https://www.youtube.com/watch?v=kuHiMXABkGs
  • mgarcia mgarcia:
    he's the one that informed me about the DVD's working!
  • mgarcia mgarcia:
    he also mentioned the progress on the controllers!
  • The Helper The Helper:
    I did actually it was cool to see the NUON mention
  • The Helper The Helper:
    https://discord.com/channels/985377399338332202/985377399950696481 you can still use this chat too we are two fisted now :)
  • thewrongvine thewrongvine:
    costs me $80 to fill gas tank sad face
  • Ghan Ghan:
    Oof
  • The Helper The Helper:
    Yeah that gas is some expensive stuff :)
  • The Helper The Helper:
    ghan does not have to worry about it he has a tesla and I have a small tank so it does not cost me usually more than 50
  • The Helper The Helper:
    fyi Ghan we are getting an error trying to access stats or world editor tutorials Error 526 Ray ID: 72128c6bf99f6707 • 2022-06-26 02:35:15 UTCInvalid SSL certificate
  • Ghan Ghan:
    An artifact of switching to Cloudflare... the Let's Encrypt certs can't autorenew through Cloudflare.
  • Ghan Ghan:
    I got the forum updated before things expired but there were some other casualties.
  • Ghan Ghan:
    Everything should be fixed now....
  • The Helper The Helper:
    Thank you Ghan!
  • The Helper The Helper:
    Happy Monday!
  • The Helper The Helper:
    new NUON forum mod cubanral!
    +1
  • The Helper The Helper:
  • tom_mai78101 tom_mai78101:
    Started learning how to make tools-assisted speedruns, so I'm lately busy.
  • tom_mai78101 tom_mai78101:
    Here's my current project.
    +3
  • O Old Mountain Shadow:
    that was pretty good!
  • jonas jonas:
    really cool! I saw the game before but always thought it's just a half as good double dragon. Now I realize it actually has a lot of depth!
  • The Helper The Helper:
    I just saw a bunch of running and jumping past all the enemies look like it was scripted as he said I guess I should have watched the whole thing. I only got a couple of minutes in. You should post that video in the forum Tom
  • Darthfett Darthfett:
    "Hi in the chat!"
    +2
  • tom_mai78101 tom_mai78101:
    Currently busy with making the run even better, so I'll post that new one once I'm done. Right now, I had to modify the emulator itself, the tools that makes this video, and some RAM address disassembling / reverse-engineering to get the right values, and such.
    +1

    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