sidove
Member
- Reaction score
- 22
Hey i have a spell i want to do and it is called rain of arrows/arrow storm. What it does is a rain of arrows and it should look like this http://3.bp.blogspot.com/_O3F0fH5AG...Q/s400/The+Mummy+3_rain+of+reverse+arrows.png
The problem is that i don't know how to do it, i want the spell to combine with my group system, here is the core
And what the core does is that it makes if the leader does a spell then the companions will do the same spell too, but the system dosen't work on "point and pick" spells, so that's the problem.
Sorry forgot to mention i don't want the companions to have the spell but then the spell system only works... I think it's possibly with like:
Now what i don't know is how to stop this and i want it to be MUI. Please help and thanks in advance
//Sidove
The problem is that i don't know how to do it, i want the spell to combine with my group system, here is the core
JASS:
//TESH.scrollpos=495
//TESH.alwaysfold=0
library Grouping initializer Init uses GroupingParam, Array, String
globals // constants
constant integer FORMATION_DEFAULT = 0
constant integer FORMATION_LINE = 1
constant integer FORMATION_CIRCLE = 2
constant integer ORDER_SMART = 851971
constant integer ORDER_ATTACK = 851983
constant integer ORDER_HOLDPOSITION = 851993
constant integer ORDER_MOVE = 851986
constant integer ORDER_STOP = 851972
constant integer ORDER_PATROL = 851990
constant integer ERROR_INVALID_TYPE = 1
constant integer ERROR_INVALID_UNIT = 2
constant integer ERROR_INVALID_OWNER = 3
constant integer ERROR_SIZE_EXCEEDED = 4
constant integer ERROR_UNIT_IN_OTHER_GROUP = 5
constant integer ERROR_UNDEFINED = 6
constant integer NO_ERROR = 0
constant trigger recruit_trig = CreateTrigger()
constant trigger dismiss_trig = CreateTrigger()
constant trigger newcom_trig = CreateTrigger()
constant trigger target_trig = CreateTrigger()
constant trigger point_trig = CreateTrigger()
constant trigger instant_trig = CreateTrigger()
constant trigger setform_trig = CreateTrigger()
endglobals
private function RecruitCondition takes nothing returns boolean
return GetSpellAbilityId() == GUI_RECRUIT
endfunction
private function DismissCondition takes nothing returns boolean
return GetSpellAbilityId() == GUI_DISMISS
endfunction
private function CommanderCondition takes nothing returns boolean
return GetUnitAbilityLevel(GetTriggerUnit(), GUI_COMMANDER) != 0
endfunction
private function RecruitAction takes nothing returns nothing
local unit u = GetTriggerUnit()
local Group g = GetGroup(u)
local integer errorcode
if (g != 0) then
set errorcode = g.Recruit(GetSpellTargetUnit())
if (errorcode != NO_ERROR) then
if errorcode == ERROR_INVALID_TYPE then
call DisplayTextToPlayer(GetOwningPlayer(u), 0, 0, "Cannot recruit this unit of a different unit-type")
elseif errorcode == ERROR_SIZE_EXCEEDED then
call DisplayTextToPlayer(GetOwningPlayer(u), 0, 0, "Cannot recruit this unit, the group has reached its maximum size")
elseif errorcode == ERROR_UNIT_IN_OTHER_GROUP then
call DisplayTextToPlayer(GetOwningPlayer(u), 0, 0, "Cannot recruit units already recruited in another group")
elseif errorcode == ERROR_INVALID_OWNER then
call DisplayTextToPlayer(GetOwningPlayer(u), 0, 0, "Cannot recruit units you don039;t own")
elseif errorcode == ERROR_UNDEFINED then
call DisplayTextToPlayer(GetOwningPlayer(u), 0, 0, "Warning: undefined error")
endif
endif
endif
set u = null
endfunction
private function DismissAction takes nothing returns nothing
local unit u = GetTriggerUnit()
local Group g = GetGroup(u)
local integer errorcode
if (g != 0) then
set errorcode = g.Dismiss(GetSpellTargetUnit())
if errorcode == ERROR_UNIT_IN_OTHER_GROUP then
call DisplayTextToPlayer(GetOwningPlayer(u), 0, 0, "Can only dismiss units of the same group")
elseif errorcode == ERROR_INVALID_OWNER then
call DisplayTextToPlayer(GetOwningPlayer(u), 0, 0, "Cannot dismiss units you don039;t own")
elseif errorcode == ERROR_UNDEFINED then
call DisplayTextToPlayer(GetOwningPlayer(u), 0, 0, "Warning: undefined error")
endif
endif
set u = null
endfunction
private function PointAction takes nothing returns nothing
local Group g = GetGroup(GetTriggerUnit())
call g.ExecutePointOrder(GetIssuedOrderId(), GetOrderPointX(), GetOrderPointY())
endfunction
private function TargetAction takes nothing returns nothing
local Group g = GetGroup(GetTriggerUnit())
call g.ExecuteTargetOrder(GetIssuedOrderId(), GetOrderTarget())
endfunction
private function InstantAction takes nothing returns nothing
local Group g = GetGroup(GetTriggerUnit())
call g.ExecuteImmediateOrder(GetIssuedOrderId())
endfunction
private function NewCommanderAction takes nothing returns nothing
local Group g = GetGroup(GetDyingUnit())
call g.NewCommander()
endfunction
private function SetFormationAction takes nothing returns nothing
local integer spellid = GetSpellAbilityId()
local Group g = GetGroup(GetTriggerUnit())
if g != null then
if spellid == GUI_SET_FORMATION_DEFAULT then
call g.SetFormation(FORMATION_DEFAULT)
elseif spellid == GUI_SET_FORMATION_CIRCLE then
call g.SetFormation(FORMATION_CIRCLE)
elseif spellid == GUI_SET_FORMATION_LINE then
call g.SetFormation(FORMATION_LINE)
endif
endif
endfunction
private function Init takes nothing returns nothing
// RECRUITING TRIGGER
call TriggerRegisterAnyUnitEventBJ(recruit_trig, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(recruit_trig, Condition(function RecruitCondition))
call TriggerAddAction(recruit_trig, function RecruitAction)
// DISMISSING TRIGGER
call TriggerRegisterAnyUnitEventBJ(dismiss_trig, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(dismiss_trig, Condition(function DismissCondition))
call TriggerAddAction(dismiss_trig, function DismissAction)
// NEW COMMANDER TRIGGER
call TriggerRegisterAnyUnitEventBJ(newcom_trig, EVENT_PLAYER_UNIT_DEATH)
call TriggerAddCondition(newcom_trig, Condition(function CommanderCondition))
call TriggerAddAction(newcom_trig, function NewCommanderAction)
// POINT ORDER TRIGGER
call TriggerRegisterAnyUnitEventBJ(point_trig, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER)
call TriggerAddCondition(point_trig, Condition(function CommanderCondition))
call TriggerAddAction(point_trig, function PointAction)
// TARGET ORDER TRIGGER
call TriggerRegisterAnyUnitEventBJ(target_trig, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER)
call TriggerAddCondition(target_trig, Condition(function CommanderCondition))
call TriggerAddAction(target_trig, function TargetAction)
// INSTANT ORDER TRIGGER
call TriggerRegisterAnyUnitEventBJ(instant_trig, EVENT_PLAYER_UNIT_ISSUED_ORDER)
call TriggerAddCondition(instant_trig, Condition(function CommanderCondition))
call TriggerAddAction(instant_trig, function InstantAction)
// SET FORMATION TRIGGER
call TriggerRegisterAnyUnitEventBJ(setform_trig, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(setform_trig, Condition(function CommanderCondition))
call TriggerAddAction(setform_trig, function SetFormationAction)
endfunction
struct Group
private group units
private unit commander
private real spacing
private integer size // maximum size
private integer formation
private effect commandergfx
private boolean inherit
private boolean recruit
private boolean recruittype
private boolean formations
private static boolean init = true
private static Array defaultorders
private Array orders
method Recruit takes unit u returns integer
if this.recruit then
if GetGroup(u) != 0 then
return ERROR_UNIT_IN_OTHER_GROUP // the recruit is either in another group already or is a commander itself...
elseif CountUnitsInGroup(.units) >= this.size then
return ERROR_SIZE_EXCEEDED // too many units already in group
elseif .recruittype and GetUnitTypeId(u) != GetUnitTypeId(.commander) then
return ERROR_INVALID_TYPE
elseif GetOwningPlayer(u) != GetOwningPlayer(this.commander) then
return ERROR_INVALID_OWNER
endif
call GroupAddUnit(.units, u)
call SetGroup(u, this)
return NO_ERROR
endif
return ERROR_UNDEFINED
endmethod
method Dismiss takes unit u returns integer
if .recruit then
if GetOwningPlayer(u) != GetOwningPlayer(this.commander) then
return ERROR_INVALID_OWNER
elseif not IsUnitInGroup(u, .units) then
return ERROR_UNIT_IN_OTHER_GROUP // unit can't be dismissed
endif
call GroupRemoveUnit(.units, u)
call SetUnitUserData(u, 0)
return NO_ERROR
endif
return ERROR_UNDEFINED
endmethod
private method InitCommander takes unit c returns nothing
// Adds all necessary abilities to the commander
set .commander = c
call SetGroup(.commander, this)
set this.commandergfx = AddSpecialEffectTarget(COMMAND_GFX, .commander, ATTACH_POINT)
call UnitAddAbility(.commander, GUI_COMMANDER)
if .recruit then
call UnitAddAbility(.commander, GUI_RECRUIT)
call UnitAddAbility(.commander, GUI_DISMISS)
endif
if .formations then
call UnitAddAbility(.commander, GUI_SET_FORMATION)
endif
call IssueImmediateOrder(.commander, ORDERSTRING_COMMANDING_ON)
endmethod
private method ClearCommander takes nothing returns nothing
// Clears all commanding abilities from a unit
call SetGroup(.commander, 0)
call DestroyEffect(.commandergfx)
call UnitRemoveAbility(.commander, GUI_COMMANDER)
if .recruit then
call UnitRemoveAbility(.commander, GUI_RECRUIT)
call UnitRemoveAbility(.commander, GUI_DISMISS)
endif
if .formations then
call UnitRemoveAbility(.commander, GUI_SET_FORMATION)
endif
endmethod
private method InitOrders takes string orders returns nothing
local integer i = 0
local integer size = CountOccurancesOfSubstring(orders, ";")
local string order
local integer j = 0
local integer ordersize = StringLength(orders)
if Group.init then
set Group.defaultorders = Array.Create(6)
set Group.defaultorders[0]= ORDER_SMART
set Group.defaultorders[1]= ORDER_ATTACK
set Group.defaultorders[2]= ORDER_HOLDPOSITION
set Group.defaultorders[3]= ORDER_STOP
set Group.defaultorders[4]= ORDER_PATROL
set Group.defaultorders[5] = ORDER_MOVE
endif
if size > 0 then
set this.orders = Array.Create(size)
else
set this.orders = 0
endif
loop
exitwhen i >= size
set order = ""
loop
exitwhen SubString(orders, j, j+1) == ";"
set order = order + SubString(orders, j, j + 1)
set j = j + 1
endloop
set this.orders<i>= OrderId(order)
set i = i + 1
set j = j + 1 // skip ";"
endloop
endmethod
static method Create takes unit commander, group units, integer size, real spacing, boolean inherit, boolean recruit, boolean recruittype, boolean formations, string orders returns Group
local Group g = Group.allocate()
local group unitz = CreateGroup()
local unit u
set g.recruit = recruit
set g.recruittype = recruittype
set g.inherit = inherit
set g.formations = formations
set g.formation = FORMATION_DEFAULT
set g.spacing = spacing
set g.size = size
call g.InitCommander(commander)
if units != null then
set g.units = CreateGroup()
call GroupAddGroup(units, unitz)
call GroupRemoveUnit(unitz, commander) // making sure the commander is not added as a normal unit. Would cause a game crash otherwise
loop
set u = FirstOfGroup(unitz)
exitwhen u == null
call g.Recruit(u)
call GroupRemoveUnit(unitz, u)
endloop
endif
call DestroyGroup(unitz)
call g.InitOrders(orders)
set unitz = null
return g
endmethod
method Clear takes nothing returns nothing
// clears the group
local unit u = FirstOfGroup(.units)
loop
exitwhen u == null
call GroupRemoveUnit(.units, u)
call SetGroup(u, 0)
endloop
call DestroyGroup(.units)
call DestroyEffect(.commandergfx)
set .units = null
if .commander != null then
call .ClearCommander()
set .commander = null
endif
set .commandergfx = null
call this.orders.Destroy()
call .destroy()
endmethod
method NewCommander takes nothing returns boolean
local unit u = FirstOfGroup(.units)
local group g = CreateGroup()
if (u == null) then
call .Clear()
call DestroyGroup(g)
set g = null
return false
elseif .inherit then
call GroupAddGroup(.units, g)
loop
set u = FirstOfGroup(g)
exitwhen u == null
if GetUnitState(u, UNIT_STATE_LIFE) > 0 then
call GroupAddUnit(.units, .commander)
call GroupRemoveUnit(.units, u)
call .ClearCommander()
call .InitCommander(u)
set u = null
call DestroyGroup(g)
set g = null
return true
endif
call GroupRemoveUnit(g, u)
endloop
call DestroyGroup(g)
set g = null
set u = null
call .Clear()
return false
endif
call .Clear()
return false
endmethod
method SetFormation takes integer formation returns nothing
set .formation = formation
call this.ExecutePointOrder(ORDER_MOVE, GetUnitX(.commander), GetUnitY(.commander))
endmethod
private method PointOrderCircle takes integer orderid, real x, real y returns nothing
local group g = CreateGroup()
local unit u
local integer count = CountUnitsInGroup(this.units)
local real angle
local real angleincr
local real dist = this.spacing * count
call GroupAddGroup(.units, g)
if count != 0 then
set angle = 0.0
set angleincr = (6.283184 / count)
loop
set u = FirstOfGroup(g)
exitwhen u == null
call GroupRemoveUnit(g, u)
call IssuePointOrderById(u, orderid, x + dist * Cos(angle), y + dist * Sin(angle))
set angle = angle + angleincr
endloop
endif
call DestroyGroup(g)
set g = null
endmethod
private method PointOrderDefault takes integer orderid, real x, real y returns nothing
local group g = CreateGroup()
local unit u
local integer count = CountUnitsInGroup(this.units)
local integer dim = R2I(0.5 + SquareRoot(count)) // the amount of units on 1 row and 1 collumn
local real space = 6 * this.spacing
local real start_const = (dim * (this.spacing * 2.3333)) // 2.3333 = 7 / 3
local real start_x = x - start_const
local real start_y = y - start_const
local integer i = 0 // x iterator
local integer j = 0 // y iterator
local real rot_angle = Atan2(GetUnitY(this.commander) - y, GetUnitX(this.commander) - x) // in radians, angle between source point and target point
local real angle
local real dist
local real unit_x
local real unit_y
local real temp_x
local real temp_y
call GroupAddGroup(this.units, g)
loop
set u = FirstOfGroup(g)
exitwhen u == null
call GroupRemoveUnit(g, u)
set unit_x = start_x + (i * space)
set unit_y = start_y + (j * space)
set angle = Atan2(y - unit_y, x - unit_x)
set temp_x = (unit_x - x)
set temp_y = (unit_y - y)
set dist = SquareRoot(temp_x * temp_x + temp_y * temp_y)
call IssuePointOrderById(u, orderid, x + dist*Cos(angle+rot_angle), y + dist*Sin(angle+rot_angle))
set i = i + 1
if (i >= dim) then
set j = j + 1
set i = 0
endif
endloop
call DestroyGroup(g)
set g = null
endmethod
private method PointOrderLine takes integer orderid, real x, real y returns nothing
local group g = CreateGroup()
local unit u
local integer count = CountUnitsInGroup(.units)
local real dist = 4 * .spacing
local real angle = Atan2(GetUnitY(.commander) - y, GetUnitX(.commander) - x)
local real cos1 = Cos(angle + 1.570796)
local real cos2 = Cos(angle - 1.570796)
local real sin1 = Sin(angle + 1.570796)
local real sin2 = Sin(angle - 1.570796)
local boolean switch = true
call GroupAddGroup(.units, g)
if count != 0 then
loop
set u = FirstOfGroup(g)
exitwhen u == null
call GroupRemoveUnit(g, u)
if switch then
call IssuePointOrderById(u, orderid, x + dist * cos1, y + dist * sin1)
else
call IssuePointOrderById(u, orderid, x + dist * cos2, y + dist * sin2)
set dist = dist + (this.spacing * 4)
endif
set switch = not switch
endloop
endif
call DestroyGroup(g)
set g = null
set u = null
endmethod
private method IsValidOrder takes integer orderid returns boolean
local integer i = 0
local integer size = 6
loop
exitwhen i >= size
if this.defaultorders<i> == orderid then
return true
endif
set i = i + 1
endloop
if this.orders != 0 then
set i = 0
set size = this.orders.size
loop
exitwhen i >= size
if this.orders<i> == orderid then
return true
endif
set i = i + 1
endloop
endif
return false
endmethod
method ExecutePointOrder takes integer orderid, real x, real y returns nothing
if ((GetUnitAbilityLevel(this.commander, COMMAND_BUFF) > 0) and this.IsValidOrder(orderid)) then
if .formation == FORMATION_DEFAULT then
call .PointOrderDefault(orderid, x, y)
elseif .formation == FORMATION_CIRCLE then
call .PointOrderCircle(orderid, x, y)
elseif .formation == FORMATION_LINE then
call .PointOrderLine(orderid, x, y)
endif
else
endif
endmethod
method ExecuteTargetOrder takes integer orderid, widget target returns nothing
local group g
local unit u
if ((GetUnitAbilityLevel(this.commander, COMMAND_BUFF) > 0) and this.IsValidOrder(orderid)) then
set g = CreateGroup()
call GroupAddGroup(this.units, g)
loop
set u = FirstOfGroup(g)
exitwhen u == null
call IssueTargetOrderById(u, orderid, target)
call GroupRemoveUnit(g, u)
endloop
call DestroyGroup(g)
set g = null
set u = null
endif
endmethod
method ExecuteImmediateOrder takes integer orderid returns nothing
local group g = CreateGroup()
local unit u
if ((GetUnitAbilityLevel(this.commander, COMMAND_BUFF) > 0) and this.IsValidOrder(orderid)) then
set g = CreateGroup()
call GroupAddGroup(this.units, g)
loop
set u = FirstOfGroup(g)
exitwhen u == null
call IssueImmediateOrderById(u, orderid)
call GroupRemoveUnit(g, u)
endloop
call DestroyGroup(g)
set g = null
set u = null
endif
endmethod
endstruct
endlibrary</i></i></i>
And what the core does is that it makes if the leader does a spell then the companions will do the same spell too, but the system dosen't work on "point and pick" spells, so that's the problem.
Sorry forgot to mention i don't want the companions to have the spell but then the spell system only works... I think it's possibly with like:
Trigger:
- Events: A unit starts the effect of an ability
- Conditions: Ability being cast equal to Rain of Arrows
- Actions: Unit Group - Pick every unit in units and do (Actions)
- Loop - Actions
- Unit- Order Picked unit to Attack Ground Target of ability being cast
Now what i don't know is how to stop this and i want it to be MUI. Please help and thanks in advance
//Sidove