No... not some weird attack modifying spell.
Requirements:
- JassNewGenPack
- SimError - Vexorian
- KeyTimers2 - Jesus4Lyf
Glaive Bounce by BlackRose v1.02b
Creates 2 transparent like guards, they then throw a glaive that bounces off them, dishing out damage between enemy units hit by the glaive.

Creates 2 transparent like guards, they then throw a glaive that bounces off them, dishing out damage between enemy units hit by the glaive.
- It is MUI.
- No it will not lag, even on lots of instances.
- Quite amusing.
Requirements:
- JassNewGenPack
- SimError - Vexorian
- KeyTimers2 - Jesus4Lyf
JASS:
Glaive Bounce by BlackRose
---------------------------
Version: 1.02b
Date released: 27th June 2009
Date updated: 4th July 2009
Makes a glaive that bounces between 2 spirits, it keeps deflecting,
damage enemy units in the way.
How to import:
--------------
- Make sure you have JassNewGenPack.
1. Copy GlaiveBounce, SimError, and KT trigger into your map.
2. Copy all objects needed.
3. Make sure to update rawcode.
4. Done!
Version history:
----------------
v1.00: 27th June 2009
- Initial release.
v1.01: 27th June 2009
- Made transparency customizable.
- Guards now play Spell Animation (7) when they delflect Glaive.
v1.01b: 27th June 2009
- Small code update.
v1.01c: 27th June 2009
- Another small update.
v1.02: 28th June 2009
- Code updates.
- Made it so you can see how many bounces there are, <-- Configurable as well.
- Made text appear on enemy units to show how much damage done.
- Fixed something to do with map boundary.
v1.02b: 4th July 2009
- Code update.
- Extra configurables.
Credits:
--------
- Blitz for suggestion playing animation when Glaive reflects.
- emjlr3 for AnimIndexs finding out, though it is not even hard to make.
- Jesus4Lyf for KeyTimers2.
- Vexorian for SimError.
- JassNewGenPack team.
- Made for TheHelper.net AND ClanMapz.com Resources forum, DO NOT REDISTRUBUTE at all.
Contact can be made by PMing me at TheHelper forums, Username: BlackRose
JASS:
scope GlaiveBounce initializer Init
globals
// OBJECT CONFIGURABLES
// ----------------------------------------------------------------------------
private constant integer SPELL_ID = 'A000' // Glaive Bounce rawcode.
private constant integer DUMMY_ID = 'h005' // Glaive rawcode.
private constant integer GUARD_ID = 'e001' // Reflector rawcode.
// You could kill a group of units easy by placing right next to you.
// Allow this?
private constant string MIN_RANGE_MSG = "Target is inside minimum range."
private constant boolean ALLOW_MIN_RANGE = true
private constant boolean RECLICK = true // If point is in min-range, re click?
private constant string SPELL_HOTKEY = "B" // Hotkey.
// OTHER CONFIGURABLES
//----------------------------------------------------------------------------
private constant real TIMER_INTERVAL = 0.03 // Every 0.03 do action.
private constant integer END_TYPE = 1 //<- Set to 0 or 1.
// END_TYPES - How the spell ends, after certain time or after bounces/
// 0 = Time limit.
// 1 = Bounces limit.
// DAMAGE CONFIGURABLES
// ----------------------------------------------------------------------------
private constant attacktype ATK_TYPE = ATTACK_TYPE_NORMAL // Attack type
private constant damagetype DMG_TYPE = DAMAGE_TYPE_MAGIC // Damage type
private constant weapontype WPN_TYPE = null // Weapon type
// COSMETIC CONFIGURABLES
// ----------------------------------------------------------------------------
private constant boolean SHOW_DMG_TT = true // Show damage text above target? True or false.
private constant string DMG_TT_COLOR = "|cffff0000" // Damage text color, right now is RED.
private constant real DMG_TT_SIZE = 10.5 // Text size.
private constant boolean SHOW_BOUNCE_TT = true // Show bounces on Guard?
private constant string BOUNCE_TT_COLOR = "|cff87ceeb" // Color of above? Right now is LIGHT BLUE
private constant real BOUNCE_TT_SIZE = 12 // Text size.
private constant integer ANIMATION = 7 // Animation index of Guard, type -anim in this testmap to find out indexes.
// Credit to emjlr3.
// Colors of Guard, can be edited here OR Object Editor. In Percentage here.
private constant real RED = 100.
private constant real BLUE = 100.
private constant real GREEN = 100.
private constant real TRANSPARENCY = 50. // How much transparency Guard has. Max of 100.
// Effects
private constant string ATH_POINT = "chest" // Where on targets place SFX?
private constant string REFLECT_POINT = "origin" // Where on Guard reflect?
private constant string REFLECT_SFX = "Abilities\\Spells\\Human\\Defend\\DefendCaster.mdx" // Reflect SFX.
private constant string DAMAGE_SFX = "Abilities\\Spells\\Other\\Stampede\\StampedeMissileDeath.mdx" // Damage targets SFX.
endglobals
// AoE of Glaive Damage, right now is 140. But you can set it up whatever.
private function GetAoE takes integer Level returns real
return 140 + ( Level * 0. )
endfunction
// Minimum range you can cast. 400/450/500/550.
private function GetMinRange takes integer Level returns real
return 350 + ( Level * 50. )
endfunction
// Damage. It is level * 20 right now, so its 20/40/60/80
private function GetDamage takes integer Level returns real
return Level * 20.
endfunction
// Speed of the missile moving.
private function GetSpeed takes integer Level returns real
return Level * 30.
endfunction
// How many bounces there are.
private function GetBounces takes integer Level returns real
return Level * 5.
endfunction
// Or how long will the spell last.
private function GetTime takes integer Level returns real
return Level * 2.5
endfunction
//===========================================================================
// Only modify below if you know how to.
//===========================================================================
function QTT takes string Message, real x, real y, real angle, real dur, real size returns nothing
local texttag tt = CreateTextTag()
local real vel = 90 * 0.071 / 128
local real xvel = vel * Cos( angle )
local real yvel = vel * Sin( angle )
call SetTextTagText( tt, Message, size * 0.0023 )
call SetTextTagPos( tt, x, y, 0 )
call SetTextTagPermanent( tt, false )
call SetTextTagVelocity( tt, xvel, yvel )
call SetTextTagFadepoint( tt, dur - 0.50 )
call SetTextTagLifespan( tt, dur )
set tt = null
endfunction
globals
private player TempPlayer
private group TempGroup
private group G = CreateGroup()
private boolexpr UFilter
endglobals
// Conditions.
private function UFilt takes nothing returns boolean
return IsUnitType( GetFilterUnit(), UNIT_TYPE_DEAD ) == false and IsUnitEnemy( GetFilterUnit(), TempPlayer ) and IsUnitInGroup( GetFilterUnit(), TempGroup ) == false
endfunction
private struct xxData
boolean BounceBack = false
unit Caster
unit Missile
unit Guard1
unit Guard2
player Owner
group DamageGroup
real tx
real ty
real MaxTime
real MaxBounces
real Damage
real Speed
real AoE
real Time = 0.00
integer Bounces = 0
method onDestroy takes nothing returns nothing
call KillUnit( .Missile )
call RemoveUnit( .Guard1 )
call RemoveUnit( .Guard2 )
call DestroyGroup( .DamageGroup )
endmethod
static method create takes nothing returns xxData
local xxData d = xxData.allocate()
local integer level
local integer i = 0
local real array x
local real array y
local real cx
local real cy
local location l = GetSpellTargetLoc()
local real Angle
local integer r = R2I(RED * 2.55 )
local integer b = R2I(BLUE * 2.55 )
local integer g = R2I(GREEN * 2.55 )
local integer t = R2I(TRANSPARENCY * 2.55 )
set d.DamageGroup = CreateGroup()
set d.Caster = GetTriggerUnit()
set d.Owner = GetOwningPlayer( d.Caster )
set level = GetUnitAbilityLevel( d.Caster, SPELL_ID )
// Saving func calls.
set d.MaxBounces = GetBounces( level )
set d.MaxTime = GetTime( level )
set d.Damage = GetDamage( level )
set d.Speed = GetSpeed( level )
set d.AoE = GetAoE( level )
set cx = GetUnitX( d.Caster )
set cy = GetUnitY( d.Caster )
set d.tx = GetLocationX( l )
set d.ty = GetLocationY( l )
set Angle = bj_RADTODEG * Atan2( d.ty - cy, d.tx - cx )
set d.Missile = CreateUnit( d.Owner, DUMMY_ID, cx, cy, Angle )
set d.Guard1 = CreateUnit( d.Owner, GUARD_ID, cx, cy, Angle )
set Angle = bj_RADTODEG * Atan2( cy - d.ty, cx - d.tx )
set d.Guard2 = CreateUnit( d.Owner, GUARD_ID, d.tx, d.ty, Angle )
set d.tx = GetUnitX( d.Guard2 )
set d.ty = GetUnitY( d.Guard2 )
call SetUnitVertexColor( d.Guard1, r, b, g, t )
call SetUnitVertexColor( d.Guard2, r, b, g, t )
call RemoveLocation( l )
set l = null
return d
endmethod
endstruct
private function Callback takes nothing returns boolean
local xxData d = KT_GetData()
local real x
local real y
local real nx
local real ny
local real angle
local real dx
local real dy
local unit u
set d.Time = d.Time + TIMER_INTERVAL
debug call BJDebugMsg(R2S( d.Time ) )
set x = GetUnitX( d.Missile )
set y = GetUnitY( d.Missile )
set angle = Atan2( d.ty - y, d.tx - x )
set nx = x + d.Speed * Cos( angle )
set ny = y + d.Speed * Sin( angle )
set dx = d.tx - nx
set dy = d.ty - ny
call SetUnitX( d.Missile, nx )
call SetUnitY( d.Missile, ny )
set TempPlayer = d.Owner
set TempGroup = d.DamageGroup
call GroupEnumUnitsInRange( G, nx, ny, d.AoE, UFilter )
loop
set u = FirstOfGroup( G )
exitwhen u == null
call GroupRemoveUnit( G, u )
call GroupAddUnit( d.DamageGroup, u )
if SHOW_DMG_TT then
call QTT( DMG_TT_COLOR + I2S( R2I( d.Damage ) ) + "|r", GetUnitX( u ), GetUnitY( u ), 90, 1, DMG_TT_SIZE )
endif
call UnitDamageTarget( d.Caster, u, d.Damage, true, false, ATK_TYPE, DMG_TYPE, WPN_TYPE )
call DestroyEffect( AddSpecialEffectTarget( DAMAGE_SFX, u, ATH_POINT ) )
endloop
// GLAIVE BOUNCES BACK
// -------------------------
if ( dx * dx + dy * dy ) < 8100 then
set d.Bounces = d.Bounces + 1
call GroupClear( d.DamageGroup )
if SHOW_BOUNCE_TT and END_TYPE == 1 then
// QuickTaxTag by ME
call QTT( BOUNCE_TT_COLOR + I2S( d.Bounces ) + "|r", d.tx, d.ty, angle, 2, BOUNCE_TT_SIZE )
endif
if d.BounceBack then
call SetUnitAnimationByIndex( d.Guard1, ANIMATION )
call DestroyEffect( AddSpecialEffectTarget( REFLECT_SFX, d.Guard1, REFLECT_POINT ) )
set d.BounceBack = false
set d.tx = GetUnitX( d.Guard2 )
set d.ty = GetUnitY( d.Guard2 )
else
call SetUnitAnimationByIndex( d.Guard2, ANIMATION )
call DestroyEffect( AddSpecialEffectTarget( REFLECT_SFX, d.Guard2, REFLECT_POINT ) )
set d.tx = GetUnitX( d.Guard1 )
set d.ty = GetUnitY( d.Guard1 )
set d.BounceBack = true
endif
endif
if (d.Time >= d.MaxTime and END_TYPE == 0) or (d.Bounces >= d.MaxBounces and END_TYPE == 1) then
if END_TYPE == 0 then
debug call BJDebugMsg( "END_TYPE = 0, timer" )
else
debug call BJDebugMsg("END_TYPE = 1, bounces" )
endif
call d.destroy()
return true
endif
return false
endfunction
private function Cond takes nothing returns boolean
if GetSpellAbilityId() == SPELL_ID then
call KT_Add( function Callback, xxData.create(), TIMER_INTERVAL )
endif
return false
endfunction
//===========================================================================
private function MinCond takes nothing returns boolean
return GetSpellAbilityId() == SPELL_ID
endfunction
private function StopAction takes nothing returns nothing
local location l = GetSpellTargetLoc()
local unit u = GetTriggerUnit()
local real dx = GetLocationX( l ) - GetUnitX( u )
local real dy = GetLocationY( l ) - GetUnitY( u )
if SquareRoot( dx * dx + dy * dy ) < GetMinRange( GetUnitAbilityLevel( u, SPELL_ID ) ) and ALLOW_MIN_RANGE then
call IssueImmediateOrder( u, "stop" )
call SimError( GetOwningPlayer( u ), MIN_RANGE_MSG )
if GetLocalPlayer() == GetOwningPlayer( u ) then
call ForceUIKey( SPELL_HOTKEY )
endif
endif
call RemoveLocation( l )
set l = null
set u = null
endfunction
//==========================================================================
private function Init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( t, Condition( function Cond ) )
set t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_CHANNEL )
call TriggerAddCondition( t, Condition( function MinCond ) )
call TriggerAddAction( t, function StopAction )
set UFilter = Condition( function UFilt )
endfunction
endscope
Attachments
-
33.9 KB Views: 414