//***************************************************************************************************
//* ========================
//* Inferno Grenade ver.1.00
//* ========================
//* Made by Shdow89
//*
//*
//* How to implement:
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//* 1. Copy the spell "Inferno Grenade" to your map.
//*
//* 2. Copy dummy unit "Main Grenade" and "Child Grenade" to your map
//*
//* 3, Make a global variable of type hashtable and name it Hash2
//*
//* 4. Copy this trigger and the entire costu script section to your map
//*
//* 5. Go down through constants, change rawcodes of the spell and dummy units.
//*
//* Choosable/Effects:
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//* Go down through constant function and change to what you like. Units affected are:
//* Enemy Units, Non-Magic immune, Non-Structures and living. This can be changed in the
//* costum script section of the map.
//* Change the models to "Main Grenade" and "Child Grenade" dummy units to grenade type
//* you like.
//*
//* Editor's Word:
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//* My fourth JASS[JESP] spell. It's currently a beta version, so post some feedback. Post if you
//* found any bugs, improvement ideas, etc. Everything is wellcome.
//*
//* Spells Action:
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//* The caster lobs an inferno grenade at a target point. When the Grenade reaches it's point
//* it will deal damage to nearby enemy units and split itself into small flames, that fly to
//* random location, dealing damage to nearby units when they reach their location.
//* Small flames deal half the main grenade damage.
//*
//* Credits:
//* ¯¯¯¯¯¯¯¯
//* Shadow1500 for his Jump Parabola.
//* The_Reborn_Devil for pointing out the mistakes.
//*
//*
//*************************************************************************************************
constant function Inferno_GrenadeID takes nothing returns integer
return 'A001' //Inferno Grenade ability rawcode. Change to yours!
endfunction
constant function Storm_CrowI2D takes nothing returns integer
return 'Arav'//Strom Crow ability rawcode. If you haven't touch this spell in your map, don't change it. If you did, change it to your rawcode.
endfunction
constant function Gr_Explode_SFX takes nothing returns string
return "Objects\\Spawnmodels\\Other\\NeutralBuildingExplosion\\NeutralBuildingExplosion.mdl" //!! Main Grenade death special effect.
endfunction
constant function Gr_Explode_Child_SFX takes nothing returns string
return "Abilities\\Spells\\Other\\Doom\\DoomDeath.mdl"//!! Child Grenade death SFX.
endfunction
constant function Affected_Unit_SFX takes nothing returns string
return "Objects\\Spawnmodels\\Human\\FragmentationShards\\FragBoomSpawn.mdl" //!! SFX For enemy units that receive damage by the blast.
endfunction
constant function Grenade_DummyID takes nothing returns integer
return 'h001' // Main Grenade dummy unit rawcode. Change to yours.
endfunction
constant function Grenade_ChildDummy_ID takes nothing returns integer
return 'h003' // Child Grenade dummy unit rawcode. Change to yours.
endfunction
constant function Grenade_Moving_Speed takes nothing returns real
return 15.0 // Grenade moving speed, both main and child
endfunction
constant function Greande_Max_Height takes nothing returns real
return 500.0 // Main Grenade max height reached. Consider this as a missile arc.
endfunction
constant function Grenade_Radius takes nothing returns real
return 300.0 // Main Grenade damage radius
endfunction
constant function Child_Grenade_Radius takes nothing returns real
return 200.0 // Child Grenade damage radius
endfunction
constant function Damage_Grenade takes integer i returns real
return 50.00*i // Damage dealt by main grenade. Half of this is dealt with child grenades.
endfunction
constant function Child_Grenade_Height takes nothing returns real
return 200.0 // Child Grenade max reached height.
endfunction
constant function Gr_Timer_Loop takes nothing returns real
return 0.03 // How fast timer repets itself. I don't advise touching this, if you are unsure.
endfunction
constant function Child_Grenade_Number takes nothing returns integer
return 8 // How many small grenades(flames) are spawned.
endfunction
//Done with Constants. Don't touch anything below, if you are unsure.
//==================Shadow1500's Parabola======================================================================================
function JumpParabola2 takes real dist, real maxdist,real maxheight returns real
local real t = (dist*2)/maxdist-1
return (-t*t+1)*maxheight
endfunction
//========================================================================================================
//Condition Trigger
function Trig_Inferno_Grenade_Conditions takes nothing returns boolean
return GetSpellAbilityId() == Inferno_GrenadeID()
endfunction
//==================MOVING GRENADE(S)==================================================================================
function Child_Grenade_Move takes nothing returns nothing
local timer t2 = GetExpiredTimer()
local unit timmy = LoadUnitHandle(udg_Hash2, GetHandleId(t2), 10)
local unit damager = LoadUnitHandle(udg_Hash2, GetHandleId(t2), 15)
//Settings for jump, move, and my empty wallet.
local real mX = LoadReal(udg_Hash2, GetHandleId(t2), 11)
local real mY = LoadReal(udg_Hash2, GetHandleId(t2), 12)
local real mHeight = Child_Grenade_Height()
local real mDist = LoadReal(udg_Hash2, GetHandleId(t2), 13)
local real curDist = SquareRoot((GetUnitX(timmy) - mX)*(GetUnitX(timmy) - mX)+(GetUnitY(timmy) - mY)*(GetUnitY(timmy)- mY))
local real tweety = JumpParabola2(curDist, mDist, mHeight)
local real angle = GetUnitFacing(timmy)/(180.0/bj_PI)
local real marchX = GetUnitX(timmy) + Grenade_Moving_Speed() * Cos(angle)
local real marchY = GetUnitY(timmy) + Grenade_Moving_Speed() * Sin(angle)
if curDist <= Grenade_Moving_Speed() then
call PauseTimer(t2)
call DestroyTimer(t2)
call FlushChildHashtable(udg_Hash2, GetHandleId(t2))
set t2 = null
call DestroyEffect(AddSpecialEffect(Gr_Explode_Child_SFX(), GetUnitX(timmy), GetUnitY(timmy)))
call DamageEnemiesArea(damager,Child_Grenade_Radius(),GetUnitX(timmy),GetUnitY(timmy),Damage_Grenade(GetUnitAbilityLevel(damager,Inferno_GrenadeID()))/2,true,false,ATTACK_TYPE_MAGIC,DAMAGE_TYPE_MAGIC,WEAPON_TYPE_WHOKNOWS,Affected_Unit_SFX())
call RemoveUnit(timmy)
set timmy = null
set damager = null
else
call SetUnitPosition(timmy, marchX, marchY)
call SetUnitFlyHeight(timmy, tweety, 0)
set damager = null
set timmy = null
set t2 = null
endif
endfunction
//==============MAIN GRENADE MOVE===========================================================================================
function Grenade_Fly takes nothing returns nothing
local timer t = GetExpiredTimer()
local timer t2 = null
local unit dummy = LoadUnitHandle(udg_Hash2, GetHandleId(t), 1)
local unit damager = LoadUnitHandle(udg_Hash2, GetHandleId(t), 5)
local real x = LoadReal(udg_Hash2, GetHandleId(t), 2)
local real y = LoadReal(udg_Hash2, GetHandleId(t), 3)
//..................Settings for Child Grenades.................................................
local unit n_child = null
local integer count = 0
local integer n_angle = 0
local real n_dist = 0.00
local real mX = 0.0
local real mY = 0.0
//.............................................................................................
//Setting values for the jump parabola and grenade move.
local real maxHeight = Greande_Max_Height() //Unit max Height achived, configurable in constants.
local real maxDist = LoadReal(udg_Hash2, GetHandleId(t), 4) //Loaded distance between start location and target location.
local real cur_dist = SquareRoot((GetUnitX(dummy) - x)*(GetUnitX(dummy) - x)+(GetUnitY(dummy) - y)*(GetUnitY(dummy)-y))//Current distance between target location and dummy unit.
local real fly = JumpParabola2(cur_dist, maxDist, maxHeight)//Using Shadow1500 jump parabola
local real angle = Atan2(y - GetUnitY(dummy), x - GetUnitX(dummy))//Moving angle
local real moveX = GetUnitX(dummy) + Grenade_Moving_Speed() * Cos(angle)//PolarProjectionX
local real moveY = GetUnitY(dummy) + Grenade_Moving_Speed() * Sin(angle)//PolarProjectionY
if cur_dist <= Grenade_Moving_Speed() then
call PauseTimer(t)
call DestroyTimer(t)
call FlushChildHashtable(udg_Hash2, GetHandleId(t))
set t = null
call DestroyEffect(AddSpecialEffect(Gr_Explode_SFX(), GetUnitX(dummy), GetUnitY(dummy)))
call DamageEnemiesArea(damager,Grenade_Radius(),GetUnitX(dummy),GetUnitY(dummy),Damage_Grenade(GetUnitAbilityLevel(damager,Inferno_GrenadeID())),true,false,ATTACK_TYPE_MAGIC,DAMAGE_TYPE_MAGIC,WEAPON_TYPE_WHOKNOWS,Affected_Unit_SFX())
//Child grenades main preset actions
set n_angle = 360/Child_Grenade_Number()
loop
set count = count + 1
exitwhen count > Child_Grenade_Number()
set t2 = CreateTimer()
set n_child = CreateUnit(GetOwningPlayer(dummy),Grenade_ChildDummy_ID(), GetUnitX(dummy) + 5.0 * Cos(I2R(n_angle*count)), GetUnitY(dummy) + 5.0 * Sin(I2R(n_angle*count)), I2R(n_angle*count))
call UnitAddAbility(n_child, Storm_CrowI2D())
call UnitRemoveAbility(n_child, Storm_CrowI2D())
set n_dist = GetRandomReal(200.0, 600.0)
set mX = GetUnitX(n_child) + n_dist * Cos(GetUnitFacing(n_child)/(180.0/bj_PI))
set mY = GetUnitY(n_child) + n_dist * Sin(GetUnitFacing(n_child)/(180.0/bj_PI))
call SaveUnitHandle(udg_Hash2, GetHandleId(t2), 10, n_child)
call SaveReal(udg_Hash2, GetHandleId(t2), 11, mX)
call SaveReal(udg_Hash2, GetHandleId(t2), 12, mY)
call SaveReal(udg_Hash2, GetHandleId(t2), 13, n_dist)
call SaveUnitHandle(udg_Hash2, GetHandleId(t2), 15, damager)
call TimerStart(t2, Gr_Timer_Loop(), true, function Child_Grenade_Move)
set t2 = null
endloop
call RemoveUnit(dummy)
set t2 = null
set n_child = null
set damager = null
set dummy = null
else
call SetUnitPosition(dummy, moveX, moveY)
call SetUnitFlyHeight(dummy, fly, 0)
set dummy = null
set damager = null
set t2 = null
set t = null
endif
endfunction
//=================================ACTION TRIGGER======================================================================================================
function Trig_Inferno_Grenade_Actions takes nothing returns nothing
local timer t = CreateTimer()
local unit cast = GetTriggerUnit()
local real x = GetSpellTargetX()
local real y = GetSpellTargetY()
local real angle = Atan2(y - GetUnitY(cast), x - GetUnitX(cast))
local unit dummy = CreateUnit(GetOwningPlayer(cast), Grenade_DummyID(), GetUnitX(cast)+20.0*Cos(angle), GetUnitY(cast)+20.0*Sin(angle), angle)
local real maxDist = SquareRoot((x - GetUnitX(dummy))*(x - GetUnitX(dummy))+(y - GetUnitY(dummy))*(y - GetUnitY(dummy)))
call UnitAddAbility(dummy, Storm_CrowI2D())
call UnitRemoveAbility(dummy, Storm_CrowI2D())
call SaveUnitHandle(udg_Hash2, GetHandleId(t), 1, dummy)
call SaveReal(udg_Hash2, GetHandleId(t), 2, x)
call SaveReal(udg_Hash2, GetHandleId(t), 3, y)
call SaveReal(udg_Hash2, GetHandleId(t), 4, maxDist)
call SaveUnitHandle(udg_Hash2, GetHandleId(t), 5, cast)
call TimerStart(t, Gr_Timer_Loop(), true, function Grenade_Fly)
set cast = null
set t = null
endfunction
//==================INIT TRIGGER=======================================================================================
function InitTrig_Inferno_Grenade takes nothing returns nothing
local trigger trig = CreateTrigger()
local integer guza
set guza = 0
loop
call TriggerRegisterPlayerUnitEvent(trig, Player(guza), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
set guza = guza + 1
exitwhen guza == 16
endloop
call TriggerAddCondition(trig, Condition(function Trig_Inferno_Grenade_Conditions))
call TriggerAddAction(trig, function Trig_Inferno_Grenade_Actions)
call Preload(Gr_Explode_SFX())
call Preload(Gr_Explode_Child_SFX())
call Preload(Affected_Unit_SFX())
call PreloadStart()
set udg_Hash2 = InitHashtable()
set trig = null
endfunction