Not exactly, here's a better example:
This is a cne that adds a new movetopos task as a subtask of the current task every time the target goes out of combat range. Here's the code where this cne is added to the killtarget task:
So if you want your task to be added a subtask, your module needs to have two parts. One part is the new task itself...this would look like any of the other tasks and require the same functions/members (task:Create(), task:Init(), task_complete_eval(), etc). The other part is what we'll call the "loader". This part consists of a cne that adds your task as a subtask of the main task you want to extend (grind, fish, gather, etc), and a function that is registered for the "Module.Initalize" event that adds your loader cne to the process or process_overwatch element list. Here's where things get a little tricky. You need to add your cne to the list of cnes that get processed by the task you want to extend, but the tasks are instanced and there's no way to get a reference to the task itself unless you know at runtime that it's in the current queue. The function in the line you referenced above:
inheritsFrom uses lua table properties to create a pseudo object-oriented environment...it will add the functions from the table passed as a parameter (ffxiv_task_grind in the example above) to the new table (newinst) but it will not add the other table values (the "data members", if you want to think of it like other object oriented languages). So in the :Create() functions, you'll notice we always initialize the appropriate data members after calling inheritsFrom to create the new task instance we're going to return. So after that overlong explanation, the problem is that you need to add your cne to the process_elements or overwatch_elements of a task instance that you have no way to reference at runtime.
You could override the task:Create() function or the task:Init() function as you mentioned, but that's a bit of an ugly solution since it means that your code will be broken the second we change either of those functions (and the Init() functions change often as we add/remove cnes for fixes). So instead what I've just done is modify the framework so that it will also check the cnes in the process_elements and over_elements list of the superClass for the current task (if one exists). What that means is that you can add your cne to ffxiv_task_grind.process_elements() like so:
Note that only the immediate superClass of the current task will be checked (its not recursive all the way to the lowest base class). So if you have
and you add a new cne element to task0.process_elements, it won't be checked by task3:Process(). Only the process_elements list of the immediate superClass (task2) will be checked.
I'll have to do some quick testing after the update is finished and push it if it works but what should happen is that your cne will be checked after the cnes on the current task instance are checked and your task will be added as a subtask if the evaluation function returns true and the priority is the highest among all the cne eval functions that returned true. This is a long winded explanation, but this is some of the more complex stuff in the framework and we haven't had time to document it more thoroughly yet. Hopefully that gives you a little better idea of how to go about adding a new task without modifying the core lua?
Code:
---------------------------------------------------------------------------------------------
--ADD_MOVETOTARGET: If (current target distance > combat range) Then (add movetotarget task)
--Adds a MoveToTarget task
---------------------------------------------------------------------------------------------
c_movetotarget = inheritsFrom( ml_cause )
e_movetotarget = inheritsFrom( ml_effect )
function c_movetotarget:evaluate()
if ( ml_task_hub.CurrentTask().targetid ~= nil and ml_task_hub.CurrentTask().targetid ~= 0 ) then
local target = EntityList:Get(ml_task_hub.CurrentTask().targetid)
if (target ~= nil and target ~= 0 and target.alive) then
return not InCombatRange(target.id)
end
end
return false
end
function e_movetotarget:execute()
ml_debug( "Moving within combat range of target" )
local target = EntityList:Get(ml_task_hub.CurrentTask().targetid)
if (target ~= nil and target.pos ~= nil) then
local newTask = ffxiv_task_movetopos:Create()
newTask.pos = target.pos
newTask.targetid = target.id
newTask.useFollowMovement = true
ml_task_hub:CurrentTask():AddSubTask(newTask)
end
end
This is a cne that adds a new movetopos task as a subtask of the current task every time the target goes out of combat range. Here's the code where this cne is added to the killtarget task:
Code:
--Process() cnes
local ke_moveToTarget = ml_element:create( "MoveToTarget", c_movetotarget, e_movetotarget, 10 )
self:add( ke_moveToTarget, self.process_elements)
So if you want your task to be added a subtask, your module needs to have two parts. One part is the new task itself...this would look like any of the other tasks and require the same functions/members (task:Create(), task:Init(), task_complete_eval(), etc). The other part is what we'll call the "loader". This part consists of a cne that adds your task as a subtask of the main task you want to extend (grind, fish, gather, etc), and a function that is registered for the "Module.Initalize" event that adds your loader cne to the process or process_overwatch element list. Here's where things get a little tricky. You need to add your cne to the list of cnes that get processed by the task you want to extend, but the tasks are instanced and there's no way to get a reference to the task itself unless you know at runtime that it's in the current queue. The function in the line you referenced above:
Code:
local newinst = inheritsFrom(ffxiv_task_grind)
inheritsFrom uses lua table properties to create a pseudo object-oriented environment...it will add the functions from the table passed as a parameter (ffxiv_task_grind in the example above) to the new table (newinst) but it will not add the other table values (the "data members", if you want to think of it like other object oriented languages). So in the :Create() functions, you'll notice we always initialize the appropriate data members after calling inheritsFrom to create the new task instance we're going to return. So after that overlong explanation, the problem is that you need to add your cne to the process_elements or overwatch_elements of a task instance that you have no way to reference at runtime.
You could override the task:Create() function or the task:Init() function as you mentioned, but that's a bit of an ugly solution since it means that your code will be broken the second we change either of those functions (and the Init() functions change often as we add/remove cnes for fixes). So instead what I've just done is modify the framework so that it will also check the cnes in the process_elements and over_elements list of the superClass for the current task (if one exists). What that means is that you can add your cne to ffxiv_task_grind.process_elements() like so:
Code:
myModule.HandleInit()
local ke_loadmytask = ml_element:create( "LoadMyTask", c_loadmytask, e_loadmytask, 20 )
ffxiv_task_grind:add( ke_loadmytask, ffxiv_task_grind.process_elements)
end
Note that only the immediate superClass of the current task will be checked (its not recursive all the way to the lowest base class). So if you have
Code:
task1 = inheritsFrom(task0)
task2 = inheritsFrom(task1)
task3 = inheritsFrom(task2)
I'll have to do some quick testing after the update is finished and push it if it works but what should happen is that your cne will be checked after the cnes on the current task instance are checked and your task will be added as a subtask if the evaluation function returns true and the priority is the highest among all the cne eval functions that returned true. This is a long winded explanation, but this is some of the more complex stuff in the framework and we haven't had time to document it more thoroughly yet. Hopefully that gives you a little better idea of how to go about adding a new task without modifying the core lua?