Name | Type | is_array | initial_value |
//TESH.scrollpos=0
//TESH.alwaysfold=0
library ListModule
//===========================================================================
// Information:
//==============
//
// This library provides the List module, which allows you to easily create
// a linked list of all of the allocated instances of a struct-type. Iterating
// through a linked list is about 12% faster than iteratating through an array
// in JASS. There is no faster method to iterate through a list of structs than
// the method used by this module. Aside from the marginal speed gain, the best
// use of this library is to hide some ugly low-level code from your structs.
// Rather than manually building and maintaining a list of struct instances,
// just implement the List module, and your code will become much prettier.
//
//===========================================================================
// How to use the List module:
//=============================
//
// Using the List module is pretty simple. First, implement it in your
// struct (preferably at the top to avoid unnecessary TriggerEvaluate calls).
// In the struct's create method, you must call listAdd(). In the onDestroy
// method, you must also call listRemove(). An example is shown below:
/*
struct Example
implement List
static method create takes nothing returns Example
local Example this = allocate()
call listAdd() //This method adds the instance to the list.
return this
endmethod
method onDestroy takes nothing returns nothing
call listRemove() //This method removes the instance from the list.
endmethod
endstruct
*/
// The requirement to call listAdd() and listRemove() will be done away
// with once JassHelper supports module onDestroy and module onCreate, but
// for now, it is not too much of a burden.
//
// Once this is done, your struct will gain all of the methods detailed
// in the API section. Below is an example of how to iterate through the list
// of allocated structs of the implementing struct-type:
/*
function IterationExample takes nothing returns nothing
local Example e = Example.first
loop
exitwhen e == 0
//Do something with e here.
set e = e.next
endloop
//Use .last and .prev instead to iterate backwards.
endmethod
*/
//
//===========================================================================
// List module API:
//==================
//
// (readonly)(static) first -> thistype
// This member contains the first instance of thistype in the list.
//
// (readonly)(static) last -> thistype
// This member contains the last instance of thistype in the list.
//
// (readonly)(static) count -> integer
// This member contains the number of allocated structs of thistype.
//
// (readonly) next -> thistype
// This member contains the next instance of thistype in the list.
//
// (readonly) prev -> thistype
// This member contains the previous instance of thistype in the list.
//
// listAdd()
// This method adds this instance to the list of structs of thistype.
// This should be called on each instance after it is allocated (within
// the create method).
//
// listRemove()
// This method removes this instance from the list of structs of thistype.
// This should be called on each instance before it is destroyed (within
// the onDestroy method).
//
// (static) listDestroy()
// This method destroys all the structs of thistype within the list.
//
//===========================================================================
module List
private static boolean destroying = false
private boolean inlist = false
readonly static integer count = 0
readonly thistype next = 0
readonly thistype prev = 0
static method operator first takes nothing returns thistype
return thistype(0).next
endmethod
static method operator last takes nothing returns thistype
return thistype(0).prev
endmethod
method listRemove takes nothing returns nothing
if not inlist then
return
endif
set inlist = false
set prev.next = next
set next.prev = prev
set count = count - 1
endmethod
method listAdd takes nothing returns nothing
if inlist or destroying then
return
endif
set inlist = true
set last.next = this
set prev = last
set thistype(0).prev = this
set count = count + 1
endmethod
static method listDestroy takes nothing returns nothing
local thistype this = last
set destroying = true
loop
exitwhen this == 0
call destroy()
set this = prev
endloop
set destroying = false
endmethod
endmodule
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library IllusionSystem requires ListModule
/****************************************************************************************
System coded by Robbepop.
Please give credits if you use it in your map! ;-)
Requires:
- List Module
- One object data ability. (just copy and paste)
- One global dummy unit. (... if you don't already have one)
- vJass knowledge. (The system's coding is possible with Gui, too.)
This system allows you to create variable illusions with just one object of an ability.
See in the 'test' trigger how to do so.
Via the global variable 'lastCreatedIllusion' you have access to the illsion you have
lastly created with this system and are able to perform several actions.
This is also shown in the 'test' trigger.
There are some variable factors for illusions.
However, due to the wc3 mechanics not too many ...
You can scale the duration of an illusion,
the damage factor and the hit factor.
There are 3 possible values for the damage factor, 1.0, 2.0 or 3.0 to decide if your
illusion shell takes damage as normal (1.0) or with a factor of 2.0 or 3.0.
Possible values for the hit factor are 0, 0.1, 0.2, 0.3 ... 0.9 and 1.0.
This is the value which decides how much attack damage your illusion will deal.
To create illusion without a timed life just use a negative duration as parameter e.g. -1.
Im sorry that there are not more options and possibilities but I hope this system allows
illusions which are variable enough to make this system useful for you. =)
*******************************************************************************************/
globals
private constant integer DUMMY_ID = 'n000' //Configure this to your dummy's id.
private constant integer ILLU_ABIL = 'A000' //Change this value to your copy's id.
unit lastCreatedIllusion
endglobals
struct Illusion
implement List
private unit Dummy
private real IlluDuration
private method destroy takes nothing returns nothing
//Var Clearing
call KillUnit(.Dummy)
set .Dummy = null
//List Modul
call .listRemove()
//Deallocate
call .deallocate()
endmethod
static method create takes unit target, real dmgfactor, real hitfactor, real dur returns thistype
//Var Init
local thistype this = 0
//Check for possible values:
if dmgfactor >= 1. and dmgfactor <= 3. and hitfactor >= 0. and hitfactor <= 1. then
//Var Setting
set this = thistype.allocate()
//List Modul
call .listAdd()
//Var Setting
set .Dummy = CreateUnit(GetOwningPlayer(target), DUMMY_ID, GetUnitX(target), GetUnitY(target), 0)
set .IlluDuration = dur
//Create Illusion
call UnitAddAbility(.Dummy, ILLU_ABIL)
call SetUnitAbilityLevel(.Dummy, ILLU_ABIL, R2I((dmgfactor * 11) + (hitfactor * 10) - 10))
call IssueTargetOrderById(.Dummy, 852274, target)
//Error: forbidden values:
else
debug call BJDebugMsg("|cffff0000Error:|r Used forbidden values to create an illusion!")
endif
//Return
return this
endmethod
private static method GetDummyId takes unit check returns thistype
local thistype this = thistype.first
loop
exitwhen this == 0
if check == .Dummy then
return this
endif
set this = this.next
endloop
return 0
endmethod
private static method main takes nothing returns nothing
//Var Init
local unit dummy = GetSummoningUnit()
local thistype this = GetDummyId(dummy)
//Check for true illusion:
if this > 0 then
//Var Setting
set lastCreatedIllusion = GetTriggerUnit()
//Set Illu Duration
if .IlluDuration >= 0 then
call UnitApplyTimedLife(lastCreatedIllusion, 'Blil', .IlluDuration)
endif
//Remove Dummy
call this.destroy()
endif
//Clear
set dummy = null
endmethod
private static method onSummoning takes nothing returns boolean
if IsUnitIllusion(GetTriggerUnit()) then
call thistype.main()
endif
return false
endmethod
private static method onInit takes nothing returns nothing
//Var Init
local trigger t
//Trigger Init
set t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SUMMON)
call TriggerAddCondition(t, Condition(function thistype.onSummoning))
//Ability Init
set bj_lastCreatedUnit = CreateUnit(Player(12), DUMMY_ID, 0, 0, 0)
call UnitAddAbility(bj_lastCreatedUnit, ILLU_ABIL)
call RemoveUnit(bj_lastCreatedUnit)
//Clear
set t = null
endmethod
endstruct
/****************************************************************************************
You can use these two functions to create an illusion with just one line of code in
vJass and to get the last created illusion with this system. Note: illusions created
from other sources won't get saved as a 'lastCreatedIllusion'!
****************************************************************************************/
function GetLastCreatedIllusion takes nothing returns unit
return lastCreatedIllusion
endfunction
function CreateIllusion takes unit target, real d, real h, real dur returns Illusion
local Illusion illu = Illusion.create(target, d, h, dur)
return illu
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope Windwalk initializer init
private function condition takes nothing returns boolean
return GetSpellAbilityId() == 'AOwk'
endfunction
private function main takes nothing returns nothing
//Create an Illusion
call CreateIllusion(GetTriggerUnit(), 3., 1., 5.)
//Do something with your created illusion!
call SelectUnit(lastCreatedIllusion, true)
endfunction
private function init takes nothing returns nothing
set gg_trg_test = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(gg_trg_test, EVENT_PLAYER_UNIT_SPELL_FINISH)
call TriggerAddCondition(gg_trg_test, Condition(function condition))
call TriggerAddAction(gg_trg_test, function main)
endfunction
endscope