- Joined
- May 16, 2020
- Messages
- 660
Hi guys,
Unfortunately I know zero JASS, which is why I'm opening a request for something which would be rather simple in GUI. I really need to learn the basics of JASS...
The requests are regarding the attached map and is for adjustments to 3 spells in there:
Black Hole
- Fix: There is an error in the code; the dummy unit's ability doesn't increase with the caster ability level
- I want to update the Black Hole visuals as in the attached image. For this I want to create another dummy unit (the AEO effect), at the same spot where the main Black Hole stands, with the same duration. Is it possible to add a line of code so that I can simply include the "dummy2_id"?
Toss
Is it possible to add the following modification:
- If an enemy is tossed, he takes 20% increased damage (so 20% in addition to the 75*lvl; allies take only 20%)
- If the hero has the ability X, the 20% damage bonus increases to 35% / 50% / 65% for enemies. Allies take still only 20%
Wild Axes
- For some reasons the axes don't always look into the correct direction. Is it possible to fix this?
Thanks!
Unfortunately I know zero JASS, which is why I'm opening a request for something which would be rather simple in GUI. I really need to learn the basics of JASS...
The requests are regarding the attached map and is for adjustments to 3 spells in there:
Black Hole
- Fix: There is an error in the code; the dummy unit's ability doesn't increase with the caster ability level
- I want to update the Black Hole visuals as in the attached image. For this I want to create another dummy unit (the AEO effect), at the same spot where the main Black Hole stands, with the same duration. Is it possible to add a line of code so that I can simply include the "dummy2_id"?
JASS:
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope BlackHole
globals
// Config. Globals:
private constant integer abil_id = 'A002' // Black Hole ability rawcode
private constant integer dummy_id = 'u000' // Black Hole unit rawcode
private constant real pull = 1.75 // Distance pulled/interval
private constant boolean fight = false // Whether units can fight against the pull
private constant string sfx = "Abilities\\Weapons\\AncientProtectorMissile\\AncientProtectorMissile.mdl" // Effect created on pulled units
// Needed Globals:
public trigger Trigger = null // Output trigger will be BlackHole_Trigger, which can be used publically
private group G = CreateGroup()
private player P = null
private real X
private real Y
endglobals
// Config. Functions:
private function Range takes integer lvl returns real
return 400. // Area for pull/lvl
endfunction
// Damage is found on the Black Hole (Dummy) ability
private struct data
unit hole
unit u
player p
integer lvl
real x
real y
endstruct
private function Conditions takes nothing returns boolean
return GetUnitTypeId(GetSummonedUnit())==dummy_id
endfunction
private function Filt takes nothing returns boolean
return GetWidgetLife(GetFilterUnit())>.405 and not IsUnitType(GetFilterUnit(),UNIT_TYPE_STRUCTURE) and IsUnitEnemy(GetFilterUnit(),P)
endfunction
private function Effects takes nothing returns nothing
local real x
local real y
local real ang
set bj_ghoul[25] = GetEnumUnit()
set x = GetUnitX(bj_ghoul[25])
set y = GetUnitY(bj_ghoul[25])
set ang = Atan2(Y-y,X-x)
if fight then
call SetUnitX(bj_ghoul[25],x+pull*Cos(ang))
call SetUnitY(bj_ghoul[25],y+pull*Sin(ang))
else
call SetUnitPosition(bj_ghoul[25],x+pull*Cos(ang),y+pull*Sin(ang))
endif
call DestroyEffect(AddSpecialEffectTarget(sfx,bj_ghoul[25],"origin"))
endfunction
private function Movement takes nothing returns boolean
local data d = TT_GetData()
if GetWidgetLife(d.hole)<.405 then
call d.destroy()
return true
endif
call GroupClear(G)
set P = d.p
set X = d.x
set Y = d.y
call GroupEnumUnitsInRange(G,d.x,d.y,Range(d.lvl),Condition(function Filt))
call ForGroup(G,function Effects)
return false
endfunction
private function Actions takes nothing returns nothing
local data d = data.create()
set d.hole = GetSummonedUnit()
set d.x = GetUnitX(d.hole)
set d.y = GetUnitY(d.hole)
set d.u = GetSummoningUnit()
set d.p = GetOwningPlayer(d.u)
set d.lvl = GetUnitAbilityLevel(d.u,abil_id)
call TT_Start(function Movement,d)
endfunction
//===========================================================================
public function InitTrig takes nothing returns nothing
set Trigger = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( Trigger, EVENT_PLAYER_UNIT_SUMMON )
call TriggerAddCondition( Trigger, Condition( function Conditions ) )
call TriggerAddAction( Trigger, function Actions )
endfunction
endscope
Toss
Is it possible to add the following modification:
- If an enemy is tossed, he takes 20% increased damage (so 20% in addition to the 75*lvl; allies take only 20%)
- If the hero has the ability X, the 20% damage bonus increases to 35% / 50% / 65% for enemies. Allies take still only 20%
JASS:
//TESH.scrollpos=109
//TESH.alwaysfold=0
scope Toss
globals
// Config Globals:
private constant integer abil_id = 'A001' // Toss ability rawcode
private constant integer fly_id = 'Amrf' // Rawcode of ability to use for fly trick, if you have not touched Crow Form, this doesn't need changing
private constant real impact_damage = .20 // Percent of toss damage dealt to tossed unit
private constant real time = 1. // Flight time for tossed unit (seconds)
private constant string fly_sfx = "Abilities\\Spells\\Undead\\Cripple\\CrippleTarget.mdl" // Effect created on target during toss
private constant string end_sfx = "Abilities\\Spells\\Orc\\WarStomp\\WarStompCaster.mdl" // Effect created on target at end of toss
private constant boolean kill_trees = true // Whether trees are destroyed upon target landing
private constant attacktype attack_type = ATTACK_TYPE_NORMAL // Attack type used for damage
private constant damagetype damage_type = DAMAGE_TYPE_DEMOLITION // Damage type used for damage
// Needed Globals:
private group G = CreateGroup()
private unit U = null
private rect R = null
private location L = null
public trigger Trigger = null // Output trigger will be Toss_Trigger, which can be used publically
endglobals
// Config. Functions:
private function Damage takes integer lvl returns real
return 75.*lvl // Damage/lvl
endfunction
private function Area takes integer lvl returns real
return 275. // Area within to grab units and damage units/lvl
endfunction
//========================================================================================
private struct data
unit u
unit targ
player p
real xt
real yt
real xl
real yl
real dist
real ang
real cos
real sin
real speed
real hc
integer lvl
integer count = 1
effect e
static method FiltIsEnemy takes nothing returns boolean
return IsUnitEnemy(GetFilterUnit(), bj_groupEnumOwningPlayer) and GetUnitState(GetFilterUnit(),UNIT_STATE_LIFE)>.405
endmethod
static method DamageGroup takes unit damager, real radius, real x, real y, real amount returns nothing
local unit u
set bj_groupEnumOwningPlayer = GetOwningPlayer(damager)
call GroupClear(G)
call GroupEnumUnitsInRange(G, x, y, radius, Condition(function data.FiltIsEnemy))
loop
set u = FirstOfGroup(G)
exitwhen u == null
call GroupRemoveUnit(G,u)
call UnitDamageTarget(damager,u,amount,false,false,attack_type,damage_type,null)
endloop
endmethod
static method KillTrees_Child takes nothing returns nothing
call KillDestructable(GetEnumDestructable())
endmethod
static method KillTrees takes real x, real y, real radius returns nothing
set R = Rect(x - radius,y - radius,x + radius,y + radius)
call EnumDestructablesInRect(R,null,function data.KillTrees_Child)
call RemoveRect(R)
endmethod
method onDestroy takes nothing returns nothing
call SetUnitFlyHeight(.targ,GetUnitDefaultFlyHeight(.targ),0.)
call PauseUnit(.targ,false)
call SetUnitPathing(.targ,true)
call DestroyEffect(.e)
call UnitDamageTarget(.u,.targ,Damage(.lvl)*impact_damage,false,false,attack_type,damage_type,null)
call DestroyEffect(AddSpecialEffectTarget(end_sfx,.targ,"origin"))
call data.DamageGroup(.u,Area(.lvl),.xl,.yl,Damage(.lvl))
if kill_trees then
call data.KillTrees(.xl,.yl,Area(.lvl))
endif
endmethod
endstruct
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == abil_id
endfunction
private function Filt takes nothing returns boolean
return GetFilterUnit()!=U and GetWidgetLife(GetFilterUnit())>.405 and not IsUnitType(GetFilterUnit(),UNIT_TYPE_STRUCTURE) and not IsUnitType(GetFilterUnit(),UNIT_TYPE_FLYING)
endfunction
private function GetSpeed takes real dist returns real
return dist/(1./TT_PERIOD)
endfunction
private function GetCountConversion takes integer count returns real
return (50./(time/TT_PERIOD))*count
endfunction
private function Movement takes nothing returns boolean
local data d = TT_GetData()
local real conv
local real height
local real speed
local real x
local real y
if d.count<=time/TT_PERIOD then
set conv = GetCountConversion(d.count)
set height = (conv-25.)*(conv-25.)
set speed = d.count*d.speed
set x = d.xt+speed*d.cos
set y = d.yt+speed*d.sin
call SetUnitX(d.targ,x)
call SetUnitY(d.targ,y)
call SetUnitFlyHeight(d.targ,625.-height,0.)
set d.count = d.count + 1
return false
else
call d.destroy()
return true
endif
endfunction
private function Actions takes nothing returns nothing
local data d = data.create()
set d.u = GetTriggerUnit()
set d.p = GetOwningPlayer(d.u)
set d.lvl = GetUnitAbilityLevel(d.u,abil_id)
call GroupClear(G)
set U = d.u
call GroupEnumUnitsInRange(G,GetUnitX(d.u),GetUnitY(d.u),Area(d.lvl),Condition(function Filt))
set d.targ = GroupPickRandomUnit(G)
if d.targ==null then
call d.destroy()
return
endif
set d.xt = GetUnitX(d.targ)
set d.yt = GetUnitY(d.targ)
set L = GetSpellTargetLoc()
set d.xl = GetLocationX(L)
set d.yl = GetLocationY(L)
set d.ang = Atan2(d.yl-d.yt,d.xl-d.xt)
set d.cos = Cos(d.ang)
set d.sin = Sin(d.ang)
set d.dist = SquareRoot((d.xt-d.xl)*(d.xt-d.xl) + (d.yt-d.yl)*(d.yt-d.yl))
set d.speed = GetSpeed(d.dist)
call PauseUnit(d.targ,true)
call SetUnitPathing(d.targ,false)
call UnitAddAbility(d.targ,fly_id)
call UnitRemoveAbility(d.targ,fly_id)
set d.e = AddSpecialEffectTarget(fly_sfx,d.targ,"origin")
call TT_Start(function Movement,d)
call RemoveLocation(L)
endfunction
//===========================================================================
public function InitTrig takes nothing returns nothing
set Trigger = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( Trigger, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( Trigger, Condition( function Conditions ) )
call TriggerAddAction( Trigger, function Actions )
endfunction
endscope
Wild Axes
- For some reasons the axes don't always look into the correct direction. Is it possible to fix this?
JASS:
//TESH.scrollpos=67
//TESH.alwaysfold=0
scope WildAxes
globals
// Config. Globals:
private constant integer abil_id = 'A003' // Wild Axes ability rawcode
private constant integer dummy_id = 'e000' // Wild Axes unit rawcode
private constant real speed = .028 // Speed for axes, this is an arbitrary value, increasing it increases the axes speed, while decreasing it decreases their speed
private constant real width = 375. // Width for bezier curve, larger values give a wider arc, and vice versa
private constant real area = 150. // Area to damage units around axes and destroy trees
private constant string sfx = "Objects\\Spawnmodels\\Human\\HumanBlood\\BloodElfSpellThiefBlood.mdl" // Effect created on hit units
private constant attacktype attack_type = ATTACK_TYPE_NORMAL // Attack type for damage
private constant damagetype damage_type = DAMAGE_TYPE_NORMAL // Damage type for damage
// Needed Globals:
public trigger Trigger = null // Output trigger will be WildAxes_Trigger, which can be used publically
private group G = CreateGroup()
private group TempG = null
private player P = null
private location L = null
private rect R = null
endglobals
// Config. Functions:
private function Damage takes integer lvl returns real
return 50.+(lvl*30.) // Damage/lvl
endfunction
private struct data
unit u
unit axe
player p
group grp
real x
real y
real xl
real yl
real a = 1.
real outx
real outy
real ang
integer lvl
boolean first = true
endstruct
private function Conditions takes nothing returns boolean
return GetSpellAbilityId()==abil_id
endfunction
private function Filt takes nothing returns boolean
return not IsUnitInGroup(GetFilterUnit(),TempG) and GetWidgetLife(GetFilterUnit())>.405 and not IsUnitType(GetFilterUnit(),UNIT_TYPE_STRUCTURE) and IsUnitEnemy(GetFilterUnit(),P)
endfunction
private function Kill_Trees takes nothing returns nothing
call KillDestructable(GetEnumDestructable())
endfunction
private function Effects takes unit u, real x, real y, group grp, integer lvl returns nothing
local unit dum
set R = Rect(x-150.,y-150.,x+150.,y+150.)
call EnumDestructablesInRect(R,null,function Kill_Trees)
call RemoveRect(R)
call GroupClear(G)
set P = GetOwningPlayer(u)
set TempG = grp
call GroupEnumUnitsInRange(G,x,y,area,Condition(function Filt))
loop
set dum = FirstOfGroup(G)
exitwhen dum==null
call GroupRemoveUnit(G,dum)
call UnitDamageTarget(u,dum,Damage(lvl),false,false,attack_type,damage_type,null)
call DestroyEffect(AddSpecialEffectTarget(sfx,dum,"chest"))
call GroupAddUnit(grp,dum)
endloop
endfunction
private function Movement takes nothing returns boolean
local data d = TT_GetData()
local real b = 1.-d.a
call SetUnitX(d.axe,d.x*d.a*d.a+d.outx*2*d.a*b+d.xl*b*b)
call SetUnitY(d.axe,d.y*d.a*d.a+d.outy*2*d.a*b+d.yl*b*b)
call Effects(d.u,GetUnitX(d.axe),GetUnitY(d.axe),d.grp,d.lvl)
if d.first then
set d.a = d.a-speed
else
set d.a = d.a+speed
set d.x = GetUnitX(d.u)
set d.y = GetUnitY(d.u)
endif
if d.a<0. and d.first then
set d.first = false
set d.outx = d.x+width*Cos(Atan2(d.yl-d.y,d.xl-d.x)+d.ang)
set d.outy = d.y+width*Sin(Atan2(d.yl-d.y,d.xl-d.x)+d.ang)
endif
if d.a>1. and d.first==false then
call DestroyGroup(d.grp)
call RemoveUnit(d.axe)
call d.destroy()
return true
endif
return false
endfunction
private function Actions takes nothing returns nothing
local data d1 = data.create()
local data d2 = data.create()
set d1.u = GetTriggerUnit()
set d2.u = d1.u
set d1.x = GetUnitX(d1.u)
set d2.x = d1.x
set d1.y = GetUnitY(d1.u)
set d2.y = d1.y
set d1.p = GetOwningPlayer(d1.u)
set d2.p = d1.p
set d1.axe = CreateUnit(d1.p,dummy_id,d1.x,d1.y,0.)
set d2.axe = CreateUnit(d1.p,dummy_id,d1.x,d1.y,0.)
set d1.grp = CreateGroup()
set d2.grp = CreateGroup()
set d1.lvl = GetUnitAbilityLevel(d1.u,abil_id)
set d2.lvl = d1.lvl
set L = GetSpellTargetLoc()
set d1.xl = GetLocationX(L)
set d2.xl = d1.xl
set d1.yl = GetLocationY(L)
set d2.yl = d1.yl
set d1.outx = d1.x+width*Cos(Atan2(d1.yl-d1.y,d1.xl-d1.x)+45.)
set d1.outy = d1.y+width*Sin(Atan2(d1.yl-d1.y,d1.xl-d1.x)+45.)
set d2.outx = d1.x+width*Cos(Atan2(d1.yl-d1.y,d1.xl-d1.x)-45.)
set d2.outy = d1.y+width*Sin(Atan2(d1.yl-d1.y,d1.xl-d1.x)-45.)
set d1.ang = -45.
set d2.ang = 45.
call TT_Start(function Movement,d1)
call TT_Start(function Movement,d2)
call RemoveLocation(L)
endfunction
//===========================================================================
public function InitTrig takes nothing returns nothing
set Trigger = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( Trigger, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( Trigger, Condition( function Conditions ) )
call TriggerAddAction( Trigger, function Actions )
endfunction
endscope
Thanks!