~GaLs~
† Ғσſ ŧħə ѕαĸε Φƒ ~Ğ䣚~ †
- Reaction score
- 180
I'm in, once the spell contest had finished.
set x = GetUnitX(stuckUnit)
set y = GetUnitY(stuckUnit)
call SetUnitPosition(stuckUnit, x, y)
// then issue move order again
Uh i know what MUI means, but what does it really stand for?That would be making your tower's abilities MUI.
MUI = Multi Unit Instancable
> How do you make a spell MUI is it possible w/ GUI or only w/ JASS?
It depends very much on your specific situation.
It's usually possible with either, but sometimes it can be very difficult to do in GUI.
scope Lasso
//******************************************************************************************
//*
//* Lasso Tower
//*
//* A tower which can lasso units, initiating a rubber band like effect between it
//* and the target. The lasso snaps at a maximum distance, and all lassoes on a tower
//* can be released at the click of a button.
//*
//* Requires:
//* - This trigger copied to your map
//* - Configuration of the given globals
//*
//******************************************************************************************
globals
// Config. Options:
private integer tower_id = 039;hgtw039; // Tower rawcode
private integer lasso_id = 039;A000039; // Lasso ability rawcode
private integer release_id = 039;A001039; // Release ability rawcode
private string lasso_sfx = "LEAS" // String for desired lightning effect
private string release_sfx = "Abilities\\Spells\\Demon\\DarkPortal\\DarkPortalTarget.mdl" // Effect to create when a lasso breaks or is released
private real damage = 150. // Damage done when a lasso breaks or is released
private real interval = .03 // Speed of periodic timer
private real max_dist = 750. // Maximum distance a creep can be away before the lasso snaps
private real min_dist = 200. // Targets closer then this distance will not be pulled at all
private real max_duration = 15. // Maximum length of time a lasso will remain
private real pull = .03 // Percent of distance targets are pulled back
private real cast_height = 200. // Height to create lasso lightning on caster
private real targ_height = 45. // Height to create lasso lightning on target
private boolean stacking = false // Whether multiple towers can lasso the same creep at once
// Needed Globals:
private Lasso_data array Data
private integer Count = 0
private timer T = CreateTimer()
endglobals
//============================================================================
struct Lasso_data
unit cast
real Xcast
real Ycast
unit targ
lightning lasso
real time = 0.
// Lasso is done for the target
method End takes integer i returns integer
// Destroy lasso
call DestroyLightning(.lasso)
// Update stored structs and counting of them
set Data<i> = Data[Count]
set Count = Count - 1
// Destroy struct
call .destroy()
// Subtract 1 from current loop, so we run through the newly updated Data<i>
return i - 1
endmethod
endstruct
//============================================================================
// Checks to see if a location is pathable or not
private function CheckPathabilityTrickGet takes nothing returns nothing
set bj_rescueChangeColorUnit = bj_rescueChangeColorUnit or (GetEnumItem()!=bj_itemRandomCurrentPick)
endfunction
private function CheckPathabilityTrick takes item p, real x, real y returns boolean
local integer i = 30
local rect r
call SetItemPosition(p,x,y)
if Pow(GetItemX(p)-x,2)+Pow(GetItemY(p)-y,2)<=100 then
return true
endif
set r = Rect(x-i,y-i,x+i,y+i)
set bj_itemRandomCurrentPick = p
set bj_rescueChangeColorUnit = false
call EnumItemsInRect(r,null,function CheckPathabilityTrickGet)
call RemoveRect(r)
set r = null
return bj_rescueChangeColorUnit
endfunction
private function CheckPathability takes real x, real y returns boolean
local item it = CreateItem(039;ciri039;,x,y)
local boolean b = CheckPathabilityTrick(it,x,y)
call SetItemVisible(it,false)
call RemoveItem(it)
set it = null
return b
endfunction
// Distance and angle between coordinates
private function DBPXY takes real x1, real y1, real x2, real y2 returns real
return SquareRoot((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2))
endfunction
private function ABPXY takes real x1, real y1, real x2, real y2 returns real
return Atan2(y2-y1, x2-x1)
endfunction
private function Movement takes nothing returns nothing
local integer i = 1
local Lasso_data d
local real x
local real y
local real ang
local real dist
// Loop through current instances
loop
exitwhen i>Count
set d = Data<i>
// Update duration
set d.time = d.time + interval
// Store targets current coordinates and distance from caster
set x = GetUnitX(d.targ)
set y = GetUnitY( d.targ)
set dist = DBPXY(d.Xcast,d.Ycast,x,y)
if dist>max_dist then
// Lasso is past its max length, create neat effect, damage target, end instance
call DestroyEffect(AddSpecialEffectTarget(release_sfx, d.targ,"chest"))
call UnitDamageTarget(d.cast,d.targ,damage,false,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,null)
set i = d.End(i)
elseif d.time>max_duration or GetWidgetLife( d.cast)<.405 or GetWidgetLife(d.targ)<.405 then
// Lasso duration is up or the caster or target is dead, end instance, deal no damage and create no effect
set i = d.End(i)
else
// Lasso is still in progress, update targets location and lassos location, if possible
set ang = ABPXY(d.Xcast,d.Ycast,x,y)
// Check if there is slack left in the lasso
if dist>min_dist then
// There isn't, woot!
set dist = pull * dist
set x = x - dist * Cos(ang)
set y = y - dist * Sin(ang)
// See if coordinates to move to are pathable, if so, move the target there
if CheckPathability(x,y) then
call SetUnitX(d.targ,x)
call SetUnitY(d.targ,y)
call MoveLightningEx(d.lasso,true,d.Xcast,d.Ycast,cast_height,x,y,targ_height)
else
// Not pathable, update lightning to targets current position
call MoveLightningEx(d.lasso,true,d.Xcast,d.Ycast,cast_height,GetUnitX(d.targ),GetUnitY( d.targ),targ_height)
endif
endif
endif
set i = i + 1
endloop
// If there are no more instances, pause the timer
if Count==0 then
call PauseTimer(T)
endif
endfunction
private function Lasso takes nothing returns nothing
local Lasso_data d = Lasso_data.create()
// Store needed data
set d.cast = GetTriggerUnit()
set d.Xcast = GetUnitX(d.cast)
set d.Ycast = GetUnitY(d.cast)
set d.targ = GetSpellTargetUnit()
// Create our lasso
set d.lasso = AddLightningEx(lasso_sfx,true,d.Xcast,d.Ycast,cast_height,GetUnitX( d.targ),GetUnitY(d.targ),targ_height)
// Increase struct count by 1
set Count = Count + 1
// Store our new struct
set Data[Count] = d
// Start timer if this is the first new struct stored
if Count==1 then
call TimerStart(T,interval,true,function Movement)
endif
endfunction
//============================================================================
private function Release takes nothing returns nothing
local unit u = GetTriggerUnit()
local Lasso_data d
local integer i = 1
// Loop through current instances
loop
exitwhen i>Count
set d = Data<i>
if u==d.cast then
// This instance was started by this tower, end it, deal damage and create the neat effect
call DestroyEffect(AddSpecialEffectTarget(release_sfx,d.targ,"chest"))
call UnitDamageTarget(u,d.targ,damage,false,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,null)
set i = d.End(i)
endif
set i = i + 1
endloop
set u = null
endfunction
//============================================================================
private function SimError takes player ForPlayer, string msg returns nothing
local sound error = CreateSoundFromLabel( "InterfaceError",false,false,false,10,10)
if GetLocalPlayer() == ForPlayer then
call ClearTextMessages()
call DisplayTimedTextToPlayer( ForPlayer, 0.52, -1.00, 2.00, "|cffffcc00"+msg+"|r" )
call StartSound( error )
endif
call KillSoundWhenDone( error)
set error = null
endfunction
// What to do after this cast?
private function Conds takes nothing returns boolean
if GetUnitTypeId(GetTriggerUnit())!=tower_id then
// Incorrect tower type
return false
elseif GetSpellAbilityId()==lasso_id then
// Lets lasso that target!
call Lasso()
elseif GetSpellAbilityId()==release_id then
// Release em up!
call Release()
endif
return false
endfunction
// What if a tower tries to cast on the same creep twice?
// Or two towers try and cast on the same creep at the same time?
private function Stop takes nothing returns boolean
local unit u = GetTriggerUnit()
local unit targ = GetSpellTargetUnit()
local Lasso_data d
local integer i = 1
// Loop through current instances
loop
exitwhen i>Count
set d = Data<i>
if d.cast==u and d.targ==targ then
set i = Count
call UnitRemoveAbility(u,lasso_id)
call UnitAddAbility(u,lasso_id)
call SimError(GetOwningPlayer(u),"This tower already has a lasso attached to that creep.")
elseif not stacking and d.targ==targ then
set i = Count
call UnitRemoveAbility(u,lasso_id)
call UnitAddAbility(u,lasso_id)
call SimError(GetOwningPlayer(u),"This creep has already been lassoed")
endif
set i = i + 1
endloop
set u = null
set targ = null
return false
endfunction
//============================================================================
public function InitTrig takes nothing returns nothing
local trigger trig = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(trig,EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(trig,Condition(function Conds))
set trig = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(trig,EVENT_PLAYER_UNIT_SPELL_CAST)
call TriggerAddCondition(trig,Condition(function Stop))
set trig = null
endfunction
endscope</i></i></i></i></i>
but I don't really want to see a second tower just to increase the damage of the first, or something similar.