598 lines
18 KiB
Lua
598 lines
18 KiB
Lua
local logicEntity =
|
|
{
|
|
BaseClass = "WorldObject",
|
|
Name="LogicEntity",
|
|
InEventUI = false,
|
|
|
|
Parameters = {},
|
|
ApplicableActions = {},
|
|
Events = {},
|
|
Conditions = {},
|
|
TextContexts = {},
|
|
TextParameters = {},
|
|
LiveParameters = {},
|
|
|
|
DisplayerProperties = "R2::CDisplayerLua",
|
|
DisplayerPropertiesParams = "logicEntityPropertySheetDisplayer",
|
|
PermanentTreeIcon = "r2ed_icon_permanent_macro_components.tga",
|
|
TreeIcon = "r2ed_icon_macro_components.tga",
|
|
SelectBarType = i18n.get("uiR2EDMacroComponents"):toUtf8(),
|
|
|
|
Prop =
|
|
{
|
|
{Name="Behavior", Type="LogicEntityBehavior"},
|
|
},
|
|
|
|
---------------------------------------------------------------------------------------------------------
|
|
-- from base class
|
|
getContextualTreeIcon = function(this)
|
|
if this:getParentAct():isBaseAct() then
|
|
return this:getPermanentTreeIcon()
|
|
end
|
|
return ""
|
|
end,
|
|
|
|
getSelectBarIcon = function(this)
|
|
return r2.Classes.BaseClass.getContextualTreeIcon(this)
|
|
end,
|
|
|
|
---------------------------------------------------------------------------------------------------------
|
|
-- from base class
|
|
getPermanentStatutIcon = function(this)
|
|
|
|
if not this:isBotObject() and this:getParentAct():isBaseAct() then
|
|
return "r2ed_permanent_pins.tga"
|
|
else
|
|
return ""
|
|
end
|
|
end ,
|
|
|
|
--------------------------------------------------------------------------------------------
|
|
-- Get the currently selected sequence, or nil if there's no available sequence
|
|
getSelectedSequenceIndex = function(this)
|
|
local activities = this:getBehavior().Activities
|
|
if activities.Size == 0 then return nil end
|
|
local index = defaulting(this.User.SelectedSequence, 0)
|
|
if index >= activities.Size then
|
|
index = activities.Size - 1
|
|
end
|
|
return index
|
|
end,
|
|
--------------------------------------------------------------------------------------------
|
|
-- from WorldObject
|
|
canChangeDisplayMode = function(this)
|
|
return true
|
|
end,
|
|
---------------------------------------------------------------------------------------------------------
|
|
-- get the "Category" for this logic entity (Category entry found in the palette)
|
|
getCategory = function(this)
|
|
return this.Category
|
|
end,
|
|
---------------------------------------------------------------------------------------------------------
|
|
-- get the "Sub-Category" for this logic entity (Category entry found in the palette)
|
|
getSubCategory = function(this)
|
|
return this.SubCategory
|
|
end,
|
|
--------------------------------------------------------------------------------------------
|
|
isNextSelectable = function(this)
|
|
return true
|
|
end,
|
|
--------------------------------------------------------------------------------------------
|
|
-- return the behavior object, depending on wether this npc is grouped or not
|
|
getBehavior = function(this)
|
|
if this:isKindOf("NpcGrpFeature") then
|
|
return this.Components[0].Behavior
|
|
elseif this:isGrouped() and this.ParentInstance:isKindOf("NpcGrpFeature") then
|
|
return this.ParentInstance.Components[0].Behavior
|
|
else
|
|
return this.Behavior
|
|
end
|
|
end,
|
|
--------------------------------------------------------------------------------------------
|
|
-- check if that npc is part of a group
|
|
isGrouped = function(this)
|
|
if this.User.Grouped == true then return true end
|
|
if this.ParentInstance then
|
|
return this.ParentInstance:isKindOf("NpcGrpFeature")
|
|
end
|
|
return false
|
|
end,
|
|
|
|
|
|
-- get list of command for display in the toolbar
|
|
getAvailableCommands = function(this, dest)
|
|
r2.Classes.WorldObject.getAvailableCommands(this, dest)
|
|
if not this:isBotObject() and not this:isKindOf("Act") then
|
|
table.insert(dest, this:buildCommand(this.editActions, "edit_actions", "uiR2EDEditEventsTriggers", "r2ed_edit_events.tga", false))
|
|
|
|
if not this:getParentAct():isBaseAct() then
|
|
table.insert(dest, this:buildCommand(this.togglePermanentCurrentAct, "permanent_content", "uimR2EDMenuPermanentContent", "r2ed_permanent_content.tga", true))
|
|
else
|
|
table.insert(dest, this:buildCommand(this.togglePermanentCurrentAct, "current_content", "uimR2EDMenuCurrentActContent", "r2ed_current_act_content.tga", true))
|
|
end
|
|
end
|
|
end,
|
|
|
|
--
|
|
togglePermanentCurrentAct = function(this, noNewAction)
|
|
|
|
local newAct
|
|
local actionName=""
|
|
if this:getParentAct():isBaseAct() then
|
|
newAct = r2:getCurrentAct()
|
|
actionName = "uiR2EDCurrentActEntityAction"
|
|
else
|
|
newAct = r2.Scenario:getBaseAct()
|
|
actionName = "uiR2EDPermanentEntityAction"
|
|
end
|
|
|
|
local parent = newAct.Features[0]
|
|
local attr = "Components"
|
|
local instance = this
|
|
if not this:isInDefaultFeature() then
|
|
parent = newAct
|
|
attr = "Features"
|
|
end
|
|
|
|
if this:isGrouped() or this:isKindOf("Creature") then
|
|
instance = this.ParentInstance
|
|
end
|
|
|
|
if noNewAction~=false then
|
|
r2.requestNewAction(i18n.get(actionName))
|
|
end
|
|
r2.requestMoveNode(instance.InstanceId, "", -1, parent.InstanceId, attr, -1)
|
|
end,
|
|
|
|
--
|
|
onPostCreate = function(this)
|
|
if this.User.DisplayProp and this.User.DisplayProp == 1 then
|
|
r2:setSelectedInstanceId(this.InstanceId)
|
|
r2:showProperties(this)
|
|
this.User.DisplayProp = nil
|
|
end
|
|
end,
|
|
--
|
|
editActions = function(this)
|
|
|
|
r2.events:openEditor()
|
|
end,
|
|
--------------------------------------------------------------------------------------------
|
|
-- Test if this entity is a bot object
|
|
isBotObject = function(this)
|
|
return false
|
|
end,
|
|
--------------------------------------------------------------------------------------------
|
|
-- Test if thisentity is a plant
|
|
isPlant = function(this)
|
|
return false
|
|
end,
|
|
--------------------------------------------------------------------------------------------
|
|
-- from base class
|
|
onPostHrcMove = function (this)
|
|
-- if no more in a group, then mark as 'ungrouped'
|
|
local grouped = false
|
|
if this.ParentInstance then
|
|
grouped = this.ParentInstance:isKindOf("NpcGrpFeature")
|
|
end
|
|
this.User.Grouped = grouped
|
|
-- force update of the available options
|
|
--if this == r2:getSelectedInstance() then
|
|
r2.ContextualCommands:update()
|
|
--end
|
|
end,
|
|
|
|
getAiCost = function(this)
|
|
if this.User.GhostDuplicate then return 0 end
|
|
return r2.getAiCost(this)
|
|
end,
|
|
|
|
getStaticObjectCost = function(this)
|
|
return r2.getStaticObjectCost(this)
|
|
end,
|
|
|
|
hasScenarioCost = function(this)
|
|
return true;
|
|
end,
|
|
|
|
createProtected = function(this)
|
|
|
|
if not r2:checkAiQuota() then return end
|
|
|
|
if this.create then
|
|
this.create()
|
|
end
|
|
end,
|
|
|
|
--
|
|
getApplicableActions = function(this)
|
|
return r2.Classes[this.Class].ApplicableActions
|
|
end,
|
|
|
|
----------------------------------------------------------------------------
|
|
-- add a line to the event sub menu
|
|
initEventTypeMenu = function(this, subMenu, eventCategory)
|
|
|
|
local class = r2.Classes[this.Class]
|
|
local eventsTable = {}
|
|
if eventCategory=="ApplicableActions" then
|
|
eventsTable = this:getApplicableActions()
|
|
else
|
|
eventsTable = class[eventCategory]
|
|
end
|
|
|
|
for k, eventType in pairs(eventsTable) do
|
|
local endRequest = (r2.events.eventTypeWithValue[eventType]==nil)
|
|
|
|
if not r2.getLogicAttribute(this.Class, eventCategory, eventType) then
|
|
debugInfo("Error: '"..eventCategory.. "' '" ..eventType .. "' is not defined for class'"..this.Class.."'")
|
|
assert(r2.getLogicAttribute(this.Class, eventCategory, eventType))
|
|
end
|
|
|
|
local uc_eventType = ucstring()
|
|
local menuTitle = r2.getLogicAttribute(this.Class, eventCategory, eventType)
|
|
|
|
local addLine = true
|
|
if r2.events.memberManagement and this:isKindOf("Npc") and this:isGrouped() and menuTitle.groupIndependant~=true then
|
|
addLine = false
|
|
end
|
|
|
|
if addLine then
|
|
uc_eventType:fromUtf8(menuTitle.menu)
|
|
subMenu:addLine(uc_eventType, "lua",
|
|
"r2.events:setEventType('".. eventType .."','" .. tostring(endRequest) .. "','" .. eventCategory .. "')", eventType)
|
|
end
|
|
end
|
|
|
|
if table.getn(class[eventCategory])==0 then
|
|
subMenu:addLine(i18n.get("uiR2EdNoSelelection"), "", "", "")
|
|
end
|
|
end,
|
|
}
|
|
|
|
|
|
function logicEntity:getLogicTranslations()
|
|
local logicTranslations = {
|
|
["ApplicableActions"] = {
|
|
["activate"] = { menu=i18n.get( "uiR2AA0Activate" ):toUtf8(),
|
|
text=i18n.get( "uiR2AA1Activate" ):toUtf8()},
|
|
["deactivate"] = { menu=i18n.get( "uiR2AA0Deactivate" ):toUtf8(),
|
|
text=i18n.get( "uiR2AA1Deactivate" ):toUtf8()},
|
|
["trigger"] = { menu=i18n.get( "uiR2AA0Trigger" ):toUtf8(),
|
|
text=i18n.get( "uiR2AA1Trigger" ):toUtf8()},
|
|
},
|
|
["Events"] = {
|
|
["activation"] = { menu=i18n.get( "uiR2Event0Activation" ):toUtf8(),
|
|
text=i18n.get( "uiR2Event1Activation" ):toUtf8()},
|
|
["deactivation"] = { menu=i18n.get( "uiR2Event0Deactivation" ):toUtf8(),
|
|
text=i18n.get( "uiR2Event1Deactivation" ):toUtf8()},
|
|
["trigger"] = { menu=i18n.get( "uiR2Event0Trigger" ):toUtf8(),
|
|
text=i18n.get( "uiR2Event1Trigger" ):toUtf8()},
|
|
},
|
|
["Conditions"] = {
|
|
["is active"] = { menu=i18n.get( "uiR2Test0Active" ):toUtf8(),
|
|
text=i18n.get( "uiR2Test1Active" ):toUtf8()},
|
|
["is inactive"] = { menu=i18n.get( "uiR2Test0Inactive" ):toUtf8(),
|
|
text=i18n.get( "uiR2Test1Inactive" ):toUtf8()},
|
|
}
|
|
}
|
|
return logicTranslations
|
|
end
|
|
|
|
-----------------------------------------
|
|
--- register the curent Feature to menu
|
|
|
|
--function logicEntity.initLogicEntitiesMenu(this, logicEntityMenu)
|
|
--
|
|
-- if this.InEventUI == true then
|
|
-- local name = i18n.get("uiR2ED" .. this.Name)
|
|
-- local tableInstances = r2.Scenario:getAllInstancesByType(this.Name)
|
|
-- if table.getn(tableInstances) > 0 then
|
|
-- logicEntityMenu:addLine(name, "lua", "", this.Name)
|
|
-- end
|
|
-- end
|
|
--end
|
|
|
|
----------------------------------------------------------------------------
|
|
-- add a line to the event sub menu
|
|
--function logicEntity.initLogicEntitiesInstancesMenu(this, subMenu, calledFunction)
|
|
--
|
|
-- local entitiesTable = r2.Scenario:getAllInstancesByType(this.Name)
|
|
-- for key, entity in pairs(entitiesTable) do
|
|
-- local uc_name = ucstring()
|
|
-- uc_name:fromUtf8(entity.Name)
|
|
-- subMenu:addLine(uc_name, "lua", calledFunction.."('".. entity.InstanceId .."')", entity.InstanceId)
|
|
-- end
|
|
--
|
|
-- if table.getn(entitiesTable)==0 then
|
|
-- subMenu:addLine(i18n.get("uiR2EdNoSelelection"), "", "", "")
|
|
-- end
|
|
--end
|
|
|
|
-----------------------------------------
|
|
--- register the curent Feature to menu
|
|
|
|
function logicEntity.initLogicEntitiesMenu(this, logicEntityMenu)
|
|
--debugInfo("####5")
|
|
if this.InEventUI == true then
|
|
local name = i18n.get("uiR2ED" .. this.Name)
|
|
--local startTime = nltime.getPreciseLocalTime()
|
|
local enumerator = r2:enumInstances(this.Name)
|
|
--local endTime = nltime.getPreciseLocalTime()
|
|
--debugInfo(string.format("time for enumInstances is %f", endTime - startTime))
|
|
startTime = endTime
|
|
if enumerator:next() then
|
|
logicEntityMenu:addLine(name, "lua", "", this.Name)
|
|
end
|
|
--endTime = nltime.getPreciseLocalTime()
|
|
--debugInfo(string.format("time for next is %f", endTime - startTime))
|
|
end
|
|
end
|
|
|
|
------------------------------------------------------------------------------
|
|
---- add a line to the event sub menu
|
|
function logicEntity.initLogicEntitiesInstancesMenu(this, subMenu, calledFunction)
|
|
local enumerator = r2:enumInstances(this.Name)
|
|
local found = false
|
|
while 1 do
|
|
local entity = enumerator:next()
|
|
if not entity then break end
|
|
found= true
|
|
local uc_name = ucstring()
|
|
uc_name:fromUtf8(entity.Name)
|
|
subMenu:addLine(uc_name, "lua", calledFunction.."('".. entity.InstanceId .."')", entity.InstanceId)
|
|
end
|
|
if not found then
|
|
subMenu:addLine(i18n.get("uiR2EdNoSelelection"), "", "", "")
|
|
end
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
r2.registerComponent(logicEntity)
|
|
|
|
---------------------------------------------------
|
|
--useful to represent a mission
|
|
--an empty group, an active state, a inactive state
|
|
--and a finished state. Use the createPseudoGroup
|
|
--function to directly add these in the context
|
|
--local pseudoGroup=
|
|
--{
|
|
-- BaseClass="BaseClass",
|
|
-- Name="PseudoGroup",
|
|
-- Prop=
|
|
-- {
|
|
-- {Name="RtGroup",Type="RtNpcGrp"},
|
|
-- {Name="InactiveState",Type="RtAiState"},
|
|
-- {Name="ActiveState",Type="RtAiState"},
|
|
-- {Name="FinishedState",Type="RtAiState"},
|
|
-- }
|
|
--}
|
|
--r2.registerComponent(pseudoGroup)
|
|
|
|
--insert a new text in the textManager, after it has been translated
|
|
local insertTextRt = function(text,context)
|
|
local rtEntry = r2.newComponent("RtEntryText")
|
|
rtEntry.Text = text
|
|
debugInfo(colorTag(128,128,0).."insertion : "..text.." "..rtEntry.Id)
|
|
table.insert(context.RtScenario.Texts.Texts,rtEntry)
|
|
debugInfo(colorTag(128,128,0).."new size : "..table.getn(context.RtScenario.Texts.Texts))
|
|
return rtEntry.Id
|
|
end
|
|
|
|
----------------------------------------------
|
|
----create a psudo group to translate missions
|
|
----insert the elements in the context
|
|
--r2.createPseudoGroup = function(context)
|
|
-- local PseudoGroup = r2.newComponent("PseudoGroup")
|
|
-- local group = PseudoGroup.RtGroup
|
|
-- group.Name = group.Id
|
|
--
|
|
-- table.insert(context.RtAct.NpcGrps, group)
|
|
--
|
|
-- do
|
|
-- local state
|
|
--
|
|
-- state= PseudoGroup.InactiveState
|
|
-- state.Name = state.Id
|
|
-- table.insert(context.RtAct.AiStates,state)
|
|
-- table.insert(state.Children,group.Id)
|
|
--
|
|
-- state= PseudoGroup.ActiveState
|
|
-- state.Name = state.Id
|
|
-- table.insert(context.RtAct.AiStates,state)
|
|
--
|
|
--
|
|
-- state= PseudoGroup.FinishedState
|
|
-- state.Name = state.Id
|
|
-- table.insert(context.RtAct.AiStates,state)
|
|
--
|
|
-- end
|
|
-- return PseudoGroup
|
|
--end
|
|
--
|
|
--
|
|
--
|
|
local feature = {}
|
|
|
|
--
|
|
--local logicTexts ={
|
|
-- BaseClass="BaseClass",
|
|
-- Name="LogicTexts",
|
|
-- Prop=
|
|
-- {
|
|
-- {Name="Spontaneous",Type="Table"},
|
|
-- {Name="Interrogated",Type="Table"},
|
|
-- },
|
|
--}
|
|
--
|
|
--local LogicTextsTranslator = function(this,context,logicEntity)
|
|
-- local addTriggeredAction = r2.Features["ActivitySequence"].addTriggeredAction
|
|
-- local action
|
|
-- local index
|
|
-- local counter =context.Counter
|
|
--
|
|
-- if logicEntity == nil
|
|
-- then
|
|
-- debugInfo("logic entity nil!!")
|
|
-- end
|
|
--
|
|
-- if context.RtGroups == nil
|
|
-- then
|
|
-- debugInfo("context.RtGroups nil!!")
|
|
-- end
|
|
--
|
|
-- if context.RtGroups[logicEntity.NpcGrpId] == nil
|
|
-- then
|
|
-- debugInfo("context.RtGroups[logicEntity.NpcGrpId] nil!!")
|
|
-- end
|
|
--
|
|
-- for k,v in pairs(this.Spontaneous)
|
|
-- do
|
|
-- if k ~= "Keys"
|
|
-- then
|
|
-- --get the "npc_say" action
|
|
-- action = Translator.LogicEntityTranslator(v,context,logicEntity)
|
|
-- --add this action to the triggerable actions of the npc group which give the mission
|
|
-- index = addTriggeredAction(context,context.RtGroups[logicEntity.NpcGrpId].Name,action)
|
|
--
|
|
-- local name = context.RtGroups[logicEntity.NpcGrpId].Name
|
|
--
|
|
-- --create an action to trigg the action to the npc group
|
|
-- action = Actions.createAction("modify_variable",name..":v3 = "..index)
|
|
--
|
|
-- --then, add the action to the correct state/event
|
|
--
|
|
-- if k=="Activated"
|
|
-- then
|
|
-- r2.Utils.addReaction(counter.ActiveState,"start_of_state",action)
|
|
-- end
|
|
--
|
|
-- if k=="Deactivated"
|
|
-- then
|
|
-- r2.Utils.addReaction(counter.InactiveState,"start_of_state",action)
|
|
-- end
|
|
--
|
|
-- if k=="Progresses"
|
|
-- then
|
|
-- r2.Utils.addReaction(counter.ActiveState,"user_event_0",action)
|
|
-- end
|
|
-- end
|
|
-- end
|
|
--
|
|
-- for k,v in pairs(this.Interrogated)
|
|
-- do
|
|
-- if k ~= "Keys"
|
|
-- then
|
|
-- --get the "npc_say" action
|
|
-- action = r2.Translator.LogicEntityTranslator(v,context)
|
|
-- --add this action to the triggerable actions of the npc group which give the mission
|
|
-- index = addTriggeredAction(context,context.RtGroups[logicEntity.NpcGrpId].Name,action)
|
|
-- local name = context.RtGroups[logicEntity.NpcGrpId].Name
|
|
-- --create an action to trigg the action to the npc group
|
|
-- action = Actions.createAction("modify_variable",name..":v3 = "..index)
|
|
--
|
|
-- --TODO insert the action in the correct state/event ...
|
|
-- end
|
|
-- end
|
|
--
|
|
--end
|
|
--
|
|
--r2.registerComponent(logicTexts)
|
|
--
|
|
--
|
|
--r2.registerComponent(varText)
|
|
---------------------------------------------------------
|
|
--This component is linked to a BaseCounter.It's used in
|
|
--the ParametrableText component to represent the value
|
|
--of the variable
|
|
--local var =
|
|
--{
|
|
-- BaseClass="BaseClass",
|
|
-- Name="TextParam",
|
|
-- Prop=
|
|
-- {
|
|
-- {Name="BaseCounterId",Type="String"}
|
|
-- }
|
|
--}
|
|
--r2.registerComponent(var)
|
|
--
|
|
|
|
----------------------------------------------------
|
|
--this component represents a text with parameters.
|
|
--It's a table of strings and/or TextParam elements.
|
|
--It allows to build sentences with variables.
|
|
--The Translator build a sentence with the strings
|
|
-- and parameters, and returns a "npc_say" action.
|
|
--see the UnitTest.testCounter() function.
|
|
--local paramText =
|
|
--{
|
|
-- BaseClass="BaseClass",
|
|
-- Name="ParametrableText",
|
|
-- Prop=
|
|
-- {
|
|
-- --components are : "TextParam" objects or strings
|
|
-- {Name="Components",Type="Table"},
|
|
-- {Name="Npc",Type="String"}
|
|
-- }
|
|
--
|
|
--}
|
|
--r2.registerComponent(paramText)
|
|
--
|
|
--
|
|
--local ParamTextTranslator = function(this,context)
|
|
-- local text=""
|
|
-- local param=""
|
|
-- for k,v in pairs(this.Components)
|
|
-- do
|
|
-- if k~="Keys"
|
|
-- then
|
|
-- if type(v) == "string"
|
|
-- then
|
|
-- text = text..v
|
|
-- else
|
|
-- if v.Class == "TextParam"
|
|
-- then
|
|
-- local id = v.BaseCounterId
|
|
-- local baseCounter = context.Components[id]
|
|
-- local counterName = context.CounterNames[id]
|
|
-- param = r2.Utils.concat(param,counterName)
|
|
-- text = text.."$d "..baseCounter.Object.." "
|
|
-- end
|
|
-- end
|
|
--
|
|
-- end
|
|
-- end
|
|
-- local action = r2.newComponent("RtNpcEventHandlerAction")
|
|
-- action.Action = "npc_say"
|
|
-- local who = r2.Utils.getNpcParam(this.Npc,context)
|
|
-- action.Parameters = who.."\n"..insertTextRt(text,context).."\n"..param
|
|
-- return action
|
|
--end
|
|
--
|
|
-- Obsolette?
|
|
--Translator.LogicEntityTranslator = function(logicEntity,context,ParentLogicEntity)
|
|
-- local class = logicEntity.Class
|
|
-- if class == "VarText"
|
|
-- then
|
|
-- return VarTextTranslator(logicEntity,context,ParentLogicEntity)
|
|
-- end
|
|
-- if class == "Counter"
|
|
-- then
|
|
-- return CounterTranslator(logicEntity,context,ParentLogicEntity)
|
|
-- end
|
|
-- if class == "LogicTexts"
|
|
-- then
|
|
-- return LogicTextsTranslator(logicEntity,context,ParentLogicEntity)
|
|
-- end
|
|
-- if class == "BaseCounter"
|
|
-- then
|
|
-- return BaseCounterTranslator(logicEntity,context,ParentLogicEntity)
|
|
-- end
|
|
-- if class == "ParametrableText"
|
|
-- then
|
|
-- return ParamTextTranslator(logicEntity,context)
|
|
-- end
|
|
--end
|