ikillforeyou wrote:How did he get the dummy units to follow the ship?
He used a periodic event, which is very laggy indeed. And the unhandled memory leaks don't help either. :)
I'll edit this post with extracted code once I'm done with my WinXP reinstall for a client (approx 30 mins).
EDIT: So here is the promised code:
(Don't read this, because I split it into three smaller parts for easier digesting. Scroll down to find them.)
Code: Select all
//===========================================================================
// Trigger: Weapon Move 1
//===========================================================================
function Trig_Weapon_Move_1_Func001A takes nothing returns nothing
call SetUnitPositionLoc( udg_PlayerShip_Control[GetConvertedPlayerId(GetEnumPlayer())], GetUnitLoc(udg_PlayerShip[GetConvertedPlayerId(GetEnumPlayer())]) )
endfunction
function Trig_Weapon_Move_1_Actions takes nothing returns nothing
call ForForce( GetPlayersAll(), function Trig_Weapon_Move_1_Func001A )
endfunction
//===========================================================================
function InitTrig_Weapon_Move_1 takes nothing returns nothing
set gg_trg_Weapon_Move_1 = CreateTrigger( )
call TriggerRegisterTimerEventPeriodic( gg_trg_Weapon_Move_1, 2.00 )
call TriggerAddAction( gg_trg_Weapon_Move_1, function Trig_Weapon_Move_1_Actions )
endfunction
//===========================================================================
// Trigger: Weapon Move 2
//===========================================================================
function Trig_Weapon_Move_2_Conditions takes nothing returns boolean
if ( not ( GetUnitTypeId(GetAttacker()) == 'u00P' ) ) then
return false
endif
return true
endfunction
function Trig_Weapon_Move_2_Func001A takes nothing returns nothing
call SetUnitPositionLoc( GetEnumUnit(), PolarProjectionBJ(GetUnitLoc(udg_PlayerShip[GetConvertedPlayerId(GetOwningPlayer(GetAttacker()))]), GetRandomReal(0.00, 128.00), GetRandomReal(0.01, 360.00)) )
call IssueTargetOrderBJ( GetEnumUnit(), "attack", udg_PlayerShip_Target[GetConvertedPlayerId(GetOwningPlayer(GetAttacker()))] )
endfunction
function Trig_Weapon_Move_2_Actions takes nothing returns nothing
call ForGroupBJ( udg_PlayerShip_Cannons[GetConvertedPlayerId(GetOwningPlayer(GetAttacker()))], function Trig_Weapon_Move_2_Func001A )
endfunction
//===========================================================================
function InitTrig_Weapon_Move_2 takes nothing returns nothing
set gg_trg_Weapon_Move_2 = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Weapon_Move_2, EVENT_PLAYER_UNIT_ATTACKED )
call TriggerAddCondition( gg_trg_Weapon_Move_2, Condition( function Trig_Weapon_Move_2_Conditions ) )
call TriggerAddAction( gg_trg_Weapon_Move_2, function Trig_Weapon_Move_2_Actions )
endfunction
//===========================================================================
// Trigger: Weapon Move 3
//===========================================================================
function Trig_Weapon_Move_3_Conditions takes nothing returns boolean
if ( not ( IsUnitType(GetAttacker(), UNIT_TYPE_ANCIENT) == true ) ) then
return false
endif
if ( not ( DistanceBetweenPoints(GetUnitLoc(GetAttacker()), GetUnitLoc(udg_PlayerShip[GetConvertedPlayerId(GetOwningPlayer(GetAttacker()))])) > 256.00 ) ) then
return false
endif
return true
endfunction
function Trig_Weapon_Move_3_Actions takes nothing returns nothing
call SetUnitPositionLoc( GetAttacker(), GetUnitLoc(udg_PlayerShip[GetConvertedPlayerId(GetOwningPlayer(GetAttacker()))]) )
endfunction
//===========================================================================
function InitTrig_Weapon_Move_3 takes nothing returns nothing
set gg_trg_Weapon_Move_3 = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Weapon_Move_3, EVENT_PLAYER_UNIT_ATTACKED )
call TriggerAddCondition( gg_trg_Weapon_Move_3, Condition( function Trig_Weapon_Move_3_Conditions ) )
call TriggerAddAction( gg_trg_Weapon_Move_3, function Trig_Weapon_Move_3_Actions )
endfunction
[/size]
So it turns out that he has three triggers, Weapon Move 1, 2 and 3.
Let me explain them one by one:
Weapon Move 1 utilizes a periodic event, occurring every 2 seconds. The trigger action is: Loop through all players, and move every weapon (dummy unit with no model) in the PlayerShip_Control
unit group array to the ship of the player. ("i" is the player number)Code: Select all
//===========================================================================
// Trigger: Weapon Move 1
//===========================================================================
function Trig_Weapon_Move_1_Func001A takes nothing returns nothing
call SetUnitPositionLoc( udg_PlayerShip_Control[GetConvertedPlayerId(GetEnumPlayer())], GetUnitLoc(udg_PlayerShip[GetConvertedPlayerId(GetEnumPlayer())]) )
endfunction
function Trig_Weapon_Move_1_Actions takes nothing returns nothing
call ForForce( GetPlayersAll(), function Trig_Weapon_Move_1_Func001A )
endfunction
//===========================================================================
function InitTrig_Weapon_Move_1 takes nothing returns nothing
set gg_trg_Weapon_Move_1 = CreateTrigger( )
call TriggerRegisterTimerEventPeriodic( gg_trg_Weapon_Move_1, 2.00 )
call TriggerAddAction( gg_trg_Weapon_Move_1, function Trig_Weapon_Move_1_Actions )
endfunction
Weapon Move 2 is not important. It happens when any unit is attacked. This causes a very little lag spike during battles :) 'u00P' is the code for a custom unit called "Control". I'm too lazy to check what it is or what it does, but I think you will know. The trigger only runs if that Control unit is the attacker. The action is basically this: Spread out every cannon under the ship (polar projection by RAND(0,128) pixels towards/facing RAND(0,360) degrees, then issue an attack order against whoever the attacker was/is.)
Code: Select all
//===========================================================================
// Trigger: Weapon Move 2
//===========================================================================
function Trig_Weapon_Move_2_Conditions takes nothing returns boolean
if ( not ( GetUnitTypeId(GetAttacker()) == 'u00P' ) ) then
return false
endif
return true
endfunction
function Trig_Weapon_Move_2_Func001A takes nothing returns nothing
call SetUnitPositionLoc( GetEnumUnit(), PolarProjectionBJ(GetUnitLoc(udg_PlayerShip[GetConvertedPlayerId(GetOwningPlayer(GetAttacker()))]), GetRandomReal(0.00, 128.00), GetRandomReal(0.01, 360.00)) )
call IssueTargetOrderBJ( GetEnumUnit(), "attack", udg_PlayerShip_Target[GetConvertedPlayerId(GetOwningPlayer(GetAttacker()))] )
endfunction
function Trig_Weapon_Move_2_Actions takes nothing returns nothing
call ForGroupBJ( udg_PlayerShip_Cannons[GetConvertedPlayerId(GetOwningPlayer(GetAttacker()))], function Trig_Weapon_Move_2_Func001A )
endfunction
//===========================================================================
function InitTrig_Weapon_Move_2 takes nothing returns nothing
set gg_trg_Weapon_Move_2 = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Weapon_Move_2, EVENT_PLAYER_UNIT_ATTACKED )
call TriggerAddCondition( gg_trg_Weapon_Move_2, Condition( function Trig_Weapon_Move_2_Conditions ) )
call TriggerAddAction( gg_trg_Weapon_Move_2, function Trig_Weapon_Move_2_Actions )
endfunction
Weapon Move 3 is not important either. It checks for Ancient unit type (which probably means "this is a ship" or "this is a dummy weapon") and then if the two whatevers are close enough to each other (within 256 pixels) then moves them on top of each other. (I would like to express my confusion about this trigger:
WTF! Thank you.)
Code: Select all
//===========================================================================
// Trigger: Weapon Move 3
//===========================================================================
function Trig_Weapon_Move_3_Conditions takes nothing returns boolean
if ( not ( IsUnitType(GetAttacker(), UNIT_TYPE_ANCIENT) == true ) ) then
return false
endif
if ( not ( DistanceBetweenPoints(GetUnitLoc(GetAttacker()), GetUnitLoc(udg_PlayerShip[GetConvertedPlayerId(GetOwningPlayer(GetAttacker()))])) > 256.00 ) ) then
return false
endif
return true
endfunction
function Trig_Weapon_Move_3_Actions takes nothing returns nothing
call SetUnitPositionLoc( GetAttacker(), GetUnitLoc(udg_PlayerShip[GetConvertedPlayerId(GetOwningPlayer(GetAttacker()))]) )
endfunction
//===========================================================================
function InitTrig_Weapon_Move_3 takes nothing returns nothing
set gg_trg_Weapon_Move_3 = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Weapon_Move_3, EVENT_PLAYER_UNIT_ATTACKED )
call TriggerAddCondition( gg_trg_Weapon_Move_3, Condition( function Trig_Weapon_Move_3_Conditions ) )
call TriggerAddAction( gg_trg_Weapon_Move_3, function Trig_Weapon_Move_3_Actions )
endfunction
Unprotecting is fun :) I'm glad the JASS code wasn't obfuscated, because that'd have been a nightmare to read. If you have any questions or know what "Control" is, post!
--3ICE