Spellpack Wraith's Spellpack

Flare

Stops copies me!
Reaction score
662
JASS:
function TimerCallback takes nothing returns boolean
  local Knock data = TT_GetData ()
  local real x = GetUnitX (data.target)
  local real y = GetUnitY (data.target)
//TT_PERIOD is being used here, so that we have a single timer interval figure for any TT spells
  set x = x + data.cos * TT_PERIOD * SLIDE_SPEED
  set y = y + data.sin * TT_PERIOD * SLIDE_SPEED
  call SetUnitPosition (data.target, x, y)
  set data.distance = data.distance - TT_PERIOD * SLIDE_SPEED
  if data.distance <= 0 then
    call data.destroy ()
    //any other cleanup
    return true
  endif
  return false
endfunction

function SpellActions takes nothing returns nothing
  local Knock data = Knock.create ()
  local real x1
  local real y1
  local real x2
  local real y2
  local real angle
  set data.caster = GetTriggerUnit ()
  set data.target = GetSpellTargetUnit ()
  set x1 = GetUnitX (data.caster)
  set y1 = GetUnitY (data.caster)
  set x2 = GetUnitX (data.target)
  set y2 = GetUnitY (data.target)
  set angle = Atan2 (y2 - y1, x2 - x1)
  set data.distance = MAX_DISTANCE
  set data.cos = Cos (angle)
  set data.sin = Sin (angle)
  call TT_Start (function TimerCallback, data)
endfunction


That should knock the unit back, at the angle between caster and target at spellcast, and prevent the target from issuing any orders

Obviously, events and whatever other functions you have should be added in, I have no intention of adding those into the code above since they don't need any changes
 

wraithseeker

Tired.
Reaction score
122
It works fine, thanks I will give credit

I got something puzzled over here, my maths grade is bad

JASS:
 set angle = Atan2 (y2 - y1, x2 - x1)


What does it do exactly? What is Atan2?

Y2 - Y1 gets you the distance between them?
Same as above but X ?

JASS:
call EnumDestructablesInCircleBJ(100,GetUnitLoc(data.target),KillTree)


Cannot convert integer to code ?
 

Larcenist

REP: Respect, Envy, Prosperity?
Reaction score
211
> What does it do exactly? What is Atan2?

Atan2 is a variation of the tan^-1 function.

> Y2 - Y1 gets you the distance between them?

Distance in measure units between Y2 and Y1 (obviously on the Y-axis).

> Cannot convert integer to code ?

Should probably be:

JASS:
call EnumDestructablesInCircleBJ(100,GetUnitLoc(data.target),function KillTree)


Also you have a point leak there (GetUnitLoc(data.target)).
 

wraithseeker

Tired.
Reaction score
122
My bad! I always forget to put the function silly me + REP

I added some extra stuffs and plan to add more when I get back to school tomorrow, tell me when does this lag and bug like hell?

JASS:
<div class="bbCodeSpoiler">
	<button type="button" class="bbCodeSpoiler-button button" data-xf-click="toggle" data-xf-init="tooltip" title="Click to reveal or hide spoiler"><span class="button-text">

		<span>Spoiler</span>
	</span></button>
	<div class="bbCodeSpoiler-content">
		<div class="bbCodeBlock bbCodeBlock--spoiler">
			<div class="bbCodeBlock-content">scope Stunbolt initializer Init

globals
private constant integer SPELL = &#039;BOLT&#039; // raw code of dummy spell 
private constant real MAX_DISTANCE = 700
private constant real SLIDE_SPEED = 700
private constant string EFFECT = &quot;Abilities\\Spells\\Orc\\WarStomp\\WarStompCaster.mdl&quot;
private constant boolean KillTrees = true
private constant string BLOOD = &quot;Objects\\Spawnmodels\\Human\\HumanLargeDeathExplode\\HumanLargeDeathExplode.mdl&quot;
endglobals

// do not touch below this point//

struct Knock
unit target
unit caster
real x1
real y1
real cos
real sin
real DISTANCE
real angle
endstruct

private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == SPELL
endfunction

private function KillTree takes nothing returns nothing
call KillDestructable(GetEnumDestructable())
endfunction

private function Ally takes nothing returns boolean
    return IsUnitAlly(GetFilterUnit(),GetOwningPlayer(GetTriggerUnit())) == true
endfunction

private function Damage takes nothing returns nothing
local real t1 = GetUnitX(GetEnumUnit())
local real t2 = GetUnitY(GetEnumUnit())
call UnitDamageTarget(GetEnumUnit(),GetTriggerUnit(),30,true,false,ATTACK_TYPE_HERO, DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
call DestroyEffect(AddSpecialEffect(BLOOD,t1,t2))
endfunction

private function Knockback takes nothing returns boolean
  local Knock data = TT_GetData()
  local real x = GetUnitX(data.target)
  local real y = GetUnitY(data.target)
  local location area = GetUnitLoc(data.target)
  local group g = GetUnitsInRangeOfLocMatching(200,area,Condition(function Ally))
  call ForGroup(g,function Damage)
//TT_PERIOD is being used here, so that we have a single timer interval figure for any TT spells
  set x = x + data.cos * TT_PERIOD * SLIDE_SPEED
  set y = y + data.sin * TT_PERIOD * SLIDE_SPEED
  if KillTrees == true then
  call EnumDestructablesInCircleBJ(200,area,function KillTree)
  endif
  call DestroyEffect(AddSpecialEffect(EFFECT,x,y))
  call SetUnitPosition (data.target, x, y)
  set data.DISTANCE = data.DISTANCE - TT_PERIOD * SLIDE_SPEED
  if data.DISTANCE &lt;= 0 then
    call data.destroy ()
    call RemoveLocation(area)
    return true
  endif
  return false
endfunction

private function Actions takes nothing returns nothing
  local Knock data = Knock.create ()
  local real x1
  local real y1
  local real x2
  local real y2
  local real angle
  set data.caster = GetTriggerUnit ()
  set data.target = GetSpellTargetUnit ()
  set x1 = GetUnitX (data.caster)
  set y1 = GetUnitY (data.caster)
  set x2 = GetUnitX (data.target)
  set y2 = GetUnitY (data.target)
  set angle = Atan2 (y2 - y1, x2 - x1)
  set data.DISTANCE = MAX_DISTANCE
  set data.cos = Cos (angle)
  set data.sin = Sin (angle)
  call TT_Start (function Knockback, data)
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 Conditions))
call TriggerAddAction(t, function Actions)
endfunction

endscope</div>
		</div>
	</div>
</div>

Added damage effect and tree part, all works execpt the damage part, can anyone tell me what's wrong?

The damage part never occurs at all because I can see no blood.
 

Flare

Stops copies me!
Reaction score
662
The timer callback doesn't maintain the reference to GetTriggerUnit, and since you're GroupEnum stuff is in your timer callback, it won't work

Alternative
JASS:
globals
  private group G = CreateGroup ()
  private boolexpr FilterFunc //In your Init func, set this variable to:
//Condition (function GroupFunc)
  private Knock gdata
//You may want a different name, I just generally label global struct data with a g <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite7" alt=":p" title="Stick Out Tongue    :p" loading="lazy" data-shortname=":p" />
endglobals

private function GroupFunc takes nothing returns boolean
  local Knock a = gdata
//shorter var name for struct members, it&#039;s not a requirement though
  local unit u = GetEnumUnit ()
  if IsUnitEnemy (u, GetOwningPlayer (data.caster)) and IsUnitType (u, UNIT_TYPE_DEAD) == false and OtherConditions then
//OtherConditions would be anything like a structure/mechanical check, ethereal check, that sorta stuff - again, can be removed
    call UnitDamagetarget (a.caster, u, damage, attack, ranged, attackType, damageType, weaponType)
    call DestroyEffect (AddSpecialEffect (modelPath, GetUnitX (u), GetUnitY (u)))
  endif
//Then, we can just return false and keep the group empty - it&#039;s a temporary group usage, so we have no need to store them.
  return false
endfunction

private function TimerCallback takes nothing returns nothing
  local Knock data = TT_GetData ()
  //local declarations and such

//setting the value for the global
  set gdata = data
//native group enumeration function instead of that GetUnitsInRange crap <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite7" alt=":p" title="Stick Out Tongue    :p" loading="lazy" data-shortname=":p" />
  call GroupEnumUnitsInRange (G, groupX, groupY, radius, FilterFunc)
  //other stuff
endfunction


Also, don't forget about configurable values for the attack-type, damage-type (optional, but would be nice), damage, damage and tree-killing radii

JASS:
//
  set data.DISTANCE = data.DISTANCE - TT_PERIOD * SLIDE_SPEED
  if data.DISTANCE &lt;= 0 then
    call data.destroy ()
//Hmmm...
    call RemoveLocation(area)
    return true
  endif

Move that RemoveLocation from there to
JASS:
//
  set data.DISTANCE = data.DISTANCE - TT_PERIOD * SLIDE_SPEED
  call RemoveLocation (area)
  if data.DISTANCE &lt;= 0 then
    call data.destroy ()
    return true
  endif


The way you have it presently, the only time the location gets removed is when the spell ends - you are creating 34 (I think) locations per spell instance, yet only 1 is best destroyed, so you've got 33 leaks
 

wraithseeker

Tired.
Reaction score
122
JASS:
scope Stunbolt initializer Init

globals
private constant integer SPELL = &#039;BOLT&#039; // raw code of dummy spell 
private constant real MAX_DISTANCE = 700
private constant real SLIDE_SPEED = 700
private constant string EFFECT = &quot;Abilities\\Spells\\Orc\\WarStomp\\WarStompCaster.mdl&quot;
private constant boolean KillTrees = true
private constant string BLOOD = &quot;Objects\\Spawnmodels\\Human\\HumanLargeDeathExplode\\HumanLargeDeathExplode.mdl&quot; 
private Knock GROUPDATA
private boolexpr DAMGER
endglobals

// do not touch below this point//

struct Knock
unit target
unit caster
real x1
real y1
real cos
real sin
real DISTANCE
real angle
endstruct

private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == SPELL
endfunction

private function KillTree takes nothing returns nothing
call KillDestructable(GetEnumDestructable())
endfunction

private function Damage takes nothing returns boolean
local Knock g = GROUPDATA
local unit e = GetEnumUnit()
local real t1 = GetUnitX(e)
local real t2 = GetUnitY(e)
if IsUnitAlly(e,GetOwningPlayer(g.caster)) == false then //and IsUnitDeadBJ(e) == false then
call UnitDamageTarget(e,g.caster,30,true,false,ATTACK_TYPE_HERO, DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
call DestroyEffect(AddSpecialEffect(BLOOD,t1,t2))
endif
return false
endfunction

private function Knockback takes nothing returns boolean
  local Knock data = TT_GetData()
  local real x = GetUnitX(data.target)
  local real y = GetUnitY(data.target)
  local location area = GetUnitLoc(data.target)
  local group g = CreateGroup()
  set GROUPDATA = data
  call GroupEnumUnitsInRange(g,GetUnitX(data.target),GetUnitY(data.target),200,DAMGER)
//TT_PERIOD is being used here, so that we have a single timer interval figure for any TT spells
  set x = x + data.cos * TT_PERIOD * SLIDE_SPEED
  set y = y + data.sin * TT_PERIOD * SLIDE_SPEED
  if KillTrees == true then
  call EnumDestructablesInCircleBJ(200,area,function KillTree)
  endif
  call DestroyEffect(AddSpecialEffect(EFFECT,x,y))
  call SetUnitPosition (data.target, x, y)
  set data.DISTANCE = data.DISTANCE - TT_PERIOD * SLIDE_SPEED
  call RemoveLocation(area)
  if data.DISTANCE &lt;= 0 then
    call data.destroy ()
    return true
  endif
  return false
endfunction

private function Actions takes nothing returns nothing
  local Knock data = Knock.create ()
  local real x1
  local real y1
  local real x2
  local real y2
  local real angle
  set data.caster = GetTriggerUnit ()
  set data.target = GetSpellTargetUnit ()
  set x1 = GetUnitX (data.caster)
  set y1 = GetUnitY (data.caster)
  set x2 = GetUnitX (data.target)
  set y2 = GetUnitY (data.target)
  set angle = Atan2 (y2 - y1, x2 - x1)
  set data.DISTANCE = MAX_DISTANCE
  set data.cos = Cos (angle)
  set data.sin = Sin (angle)
  call TT_Start (function Knockback, data)
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 Conditions))
call TriggerAddAction(t, function Actions)
set DAMGER = Filter(function Damage)
endfunction

endscope


Anyone mind telling me what's wrong? the effect is created at the centre of the map and the damage part doesn't work.
 

wraithseeker

Tired.
Reaction score
122
Major Update for Knockback

Will the mods approve this?

Something I feel like asking
Maybe you should make a system like submitting spells get a certain REP , models , icons , maps so it kind of motivate people.
 

Flare

Stops copies me!
Reaction score
662
Will the mods approve this?
Remainder of the code has yet to be looked at - don't think I really took a in-depth look at anything other than knockback yet :p A spellpack can't really be approved on the basis of a single component of the pack

Maybe you should make a system like submitting spells get a certain REP , models , icons , maps so it kind of motivate people.
If that's the case, you will just find some people submitting absolute rubbish (to put it nicely) because they are desperate to get some rep. People say the resource, they think "..." and either say it, or skip past it. Then, when people wonder where the rep for submission is, they do it again.
People currently do submit stuff which (IMO) is either sh*te with regard to material (and sometimes everything else) such as this (my post in the thread probably sums up alot of it ^_^), or just plain useless, probably because it's something that cast majority of people already (should) know

Secondly, if people like a resource, they probably will give you rep for it. If they don't like it, they won't (although they may give rep if it's thought you put alot of effort into it, etc).


Something for approval might be a better idea, but to be honest, if the resource is good enough to be approved, it'll get you a reasonable amount of rep (depending on how generous people are feeling :p)
 

wraithseeker

Tired.
Reaction score
122
Updated, knockback.

Sorry, I forgot to post it as my internet screwed up :(

New major update which should be the last verison ever.

Approving this Yet? Flare

If that's the case, you will just find some people submitting absolute rubbish (to put it nicely) because they are desperate to get some rep. People say the resource, they think "..." and either say it, or skip past it. Then, when people wonder where the rep for submission is, they do it again.
People currently do submit stuff which (IMO) is either sh*te with regard to material (and sometimes everything else) such as this (my post in the thread probably sums up alot of it ^_^), or just plain useless, probably because it's something that cast majority of people already (should) know

Submitting decent spells should get REP :p , I don't get much rep nowadays.
 

Flare

Stops copies me!
Reaction score
662
For the Entangling Roots spell, you're leaking the group g (it's not being destroyed, only nulled) and GetSpellTargetLoc as the location parameter for GetUnitsInRangeOfLoc - store it in a variable, use the variable (preferably with a native, I think there is a native GroupEnum function that takes a location), destroy the variable - you've got a similar issue in Dead Will (you're not even nulling the group there)

You should store GetEnumUnit in a variable, rather than calling it multiple times over (same could be done for GetTriggerUnit in the group callback)

Order string should be a configurable, so people don't have to make the ability entangle (they may want something like Mass Banish, then they can just change the dummy ability, and the order string, and voila, Mass Banish)
 

Vestras

Retired
Reaction score
248
target in the first code, CasterLoc in knockback function timer callback and g in the last code.
Also g in the timer callback.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top