[SNIPPET] Force Attack
Requirements:
AIDS
JassNewGenPack
Snippet - Force Attack v1.02
Forces a unit to attack another unit for a set duration.
Forces a unit to attack another unit for a set duration.
Requirements:
AIDS
JassNewGenPack
JASS:
//+---------------------------------------------------------------+
//| F O R C E A T T A C K v 1 . 0 2 |
//| B Y B L A C K R O S E |
//+---------------------------------------------------------------+
// --------------------------------------------------------
// Requirements:
// - JassNewGen
// - AIDS Jesus4Lyf
// - KeyTimers2 Jesus4Lyf
// --------------------------------------------------------
// DESCRIPTION:
// A simple snippet that forces a unit to attack another unit for a set duration.
// HOW TO IMPORT:
// Copy this trigger and AIDS into your map and done! Make sure you have NewGen.
// FUNCTION
// call ForceAttack( attackingUnit, targetedUnit, duration, effectpath, attachpath )
//+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
//| CHANGELOG |
//+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
//| v1.02: |
//| - Using hashtable to pass data then KT2 |
//| - NO DYNAMIC TRIGGERS! |
//+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
//| v1.01: |
//| - Fixed those problems, HOORAY! |
//| - Prettier document? |
//+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
//| v1.00: |
//| - Initial release. |
//+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
library ForceAttack initializer OnInit requires AIDS//, KT
globals
private group GROUP = CreateGroup()
private trigger TRIGGER = CreateTrigger()
private hashtable HASHTABLE = InitHashtable()
private timer TIMER = CreateTimer()
private unit ATTACKER
private unit TARGET
endglobals
private struct FAData extends array
//! runtextmacro AIDS()
unit attacker
unit target
real duration
trigger trig
effect SFX
player ap
player tp
timer Timerz
// Locust no?
private static method AIDS_filter takes unit u returns boolean
return GetUnitAbilityLevel(u,039;Aloc039;) ==0
endmethod
static method MoveTarget takes nothing returns nothing
call IssuePointOrder( ATTACKER, "move", GetUnitX( TARGET ), GetUnitY( TARGET ) )
call PauseTimer( TIMER )
endmethod
static method AttackTarget takes nothing returns nothing
local thistype d
local boolean b = false
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 1. If the event triggering this was ATTACKED.
// 2. Then we check if the attacked unit was not current target, and
// attacker is in the attacking GROUP.
// 3. We disable this trigger, order a commmand, if target is not seen
// then we move it. Otherwise attack, if attack set some boolean to true to prevent
// below from ordering another attack.
//
if GetTriggerEventId() == EVENT_PLAYER_UNIT_ATTACKED then
set d = thistype[GetAttacker()]
if GetTriggerUnit() != d.target and IsUnitInGroup( d.attacker, GROUP ) then
call DisableTrigger( TRIGGER )
//call IssueTargetOrder( d.attacker, "attack", d.target )
if IsUnitVisible( d.target, d.ap ) == false then
debug call BJDebugMsg( "Attacked - Cannot see, so unit is now moving to target location" )
set ATTACKER = d.attacker
set TARGET = d.target
call TimerStart( TIMER, 0.00, false, function FAData.MoveTarget )
//call IssuePointOrder( d.attacker, "move", GetUnitX( d.target ), GetUnitY( d.target ) )
else
debug call BJDebugMsg( "Attacked - ATTACK COMMAND." )
call IssueTargetOrder( d.attacker, "attack", d.target )
set b = true
endif
call EnableTrigger( TRIGGER )
endif
endif
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 1. If the event was either of a command.
// 2. We check if the ordered unit was in the group.
// 3. If so, disable this trigger. Do the same as above.
//
if ( GetTriggerEventId() == EVENT_PLAYER_UNIT_ISSUED_ORDER ) or /*
*/ ( GetTriggerEventId() == EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER ) or /*
*/ ( GetTriggerEventId() == EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER ) then
set d = thistype[GetOrderedUnit()]
if IsUnitInGroup( d.attacker, GROUP ) then
call DisableTrigger( TRIGGER )
//call IssueTargetOrder( d.attacker, "attack", d.target )
if IsUnitVisible( d.target, d.ap ) == false then
debug call BJDebugMsg( "Order - Cannot see, so unit is now moving to target location" )
set ATTACKER = d.attacker
set TARGET = d.target
call TimerStart( TIMER, 0.00, false, function FAData.MoveTarget )
//call IssuePointOrder( d.attacker, "move", GetUnitX( d.target ), GetUnitY( d.target ) )
elseif b == false then
debug call BJDebugMsg( "Order - Order attack command." )
call IssueTargetOrder( d.attacker, "attack", d.target )
endif
call EnableTrigger( TRIGGER )
endif
endif
endmethod
static method EndAttack takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer id = GetHandleId(t)
local unit attacker = LoadUnitHandle( HASHTABLE, id, 2 )
debug call BJDebugMsg( "Attack ended" )
call DestroyEffect( LoadEffectHandle( HASHTABLE, id, 1 ) )
call GroupRemoveUnit( GROUP, attacker )
call IssueImmediateOrder( attacker, "stop" )
call FlushChildHashtable( HASHTABLE, id )
call PauseTimer( t )
call DestroyTimer( t )
set t = null
set attacker = null
endmethod
endstruct
function ForceAttack takes unit attacker, unit target, real duration, string path, string where returns nothing
local FAData d = FAData[attacker]
local integer id
if IsUnitInGroup( attacker, GROUP ) then
debug call BJDebugMsg( "Unit is already being forced to attack a target." )
return
endif
set d.attacker = attacker
set d.target = target
set d.duration = duration
set d.Timerz = CreateTimer()
call GroupAddUnit( GROUP, d.attacker )
set d.ap = GetOwningPlayer( d.attacker )
set d.tp = GetOwningPlayer( d.target )
set d.SFX = AddSpecialEffectTarget( path, d.attacker, where )
if IsUnitVisible( d.target, d.ap ) then
call IssueTargetOrder( d.attacker, "attack", d.target )
else
call IssuePointOrder( d.attacker, "move", GetUnitX( d.target ), GetUnitY( d.target ) )
endif
set id = GetHandleId( d.Timerz )
call SaveEffectHandle( HASHTABLE, id, 1, d.SFX )
call SaveUnitHandle( HASHTABLE, id, 2, d.attacker )
call TimerStart( d.Timerz, d.duration, false, function FAData.EndAttack )
endfunction
private function OnInit takes nothing returns nothing
call TriggerRegisterAnyUnitEventBJ( TRIGGER, EVENT_PLAYER_UNIT_ATTACKED )
call TriggerRegisterAnyUnitEventBJ( TRIGGER, EVENT_PLAYER_UNIT_ISSUED_ORDER )
call TriggerRegisterAnyUnitEventBJ( TRIGGER, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER )
call TriggerRegisterAnyUnitEventBJ( TRIGGER, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER )
call TriggerAddAction( TRIGGER, function FAData.AttackTarget )
endfunction
endlibrary