khanat-opennel-code/code/ryzom/common/data_common/r2/r2_logic.lua
2017-03-15 20:43:10 +01:00

2637 lines
76 KiB
Lua
Raw Blame History

--
--
Logic = {}
Logic.Activities = {"Follow Route", "Patrol", "Repeat Road", "Deploy", "Wander", "Rest In Zone", "Feed In Zone", "Hunt In Zone", "Guard Zone", "Stand Still", "Stand On Start Point", "Go To Start Point"}
Logic.TimeLimits = {"No Limit", "Until", "Few Sec", "Few Min", "Chat", "Season", "Day", "Month"}
Logic.Seasons = {"Spring", "Summer", "Autumn", "Winter"}
Logic.Days = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}
Logic.Months = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}
Logic.ScriptActions ={"Sit Down", "Stand Up", "Go To Step", "Set Activity", "Stop Actions", "Start Mission"}
Logic.EventModes ={"Once Only", "Repeating"}
Logic.EventTypes ={"Time", "Place", "Entity or Group", "State Machine", "Counter"}
Logic.ConditionTypes ={
{},
{"Any player in zone", "All players in zone", "No players in zone", "Some players in zone"},
{"At Destination", "Enters State", "Leaves State", "Activity Is", "Die", "Is Attacked"},
{},
{"v0_changed", "v3_changed", "Equals", "Lesser", "Greater", ""},
}
Logic.ChatTypes = {"None", "Repeating", "Non Repeating", "Continue"}
Logic.InteractionTypes = {"Give", "Say"}
Logic.Name = "Activity"
Logic.Description = "A feature for describing activities sequences"
Logic.Components = {}
-- ACTION -------------------
Logic.Components.LogicEntityAction =
{
BaseClass ="BaseClass",
Name = "LogicEntityAction",
DisplayerProperties = "R2::CDisplayerLua",
DisplayerPropertiesParams = "logicEntityActionPropertySheetDisplayer",
Prop =
{
{Name ="Name", Type ="String"},
{Name ="Event", Type ="EventType"},
{Name ="Actions", Type ="Table"}, -- "ActionStep" list
{Name ="Conditions", Type ="Table"}, -- "ConditionStep" list
},
getName = function(this)
local logicEntity = this.Parent.Parent.Parent
assert(logicEntity)
if logicEntity:isGrouped() then
logicEntity = logicEntity.ParentInstance
end
local coloredName = (logicEntity.InstanceId == r2.events.filteredLogicEntityId)
local eventType = r2.events.keyWordsColor .. i18n.get("uiR2EdEventTxtPreEvent"):toUtf8() .. " "
if coloredName then
eventType = eventType .. r2.events.filterWordColor
else
eventType = eventType .. r2.events.entityWordColor
end
local name = "No name"
if logicEntity.getName then
name = logicEntity:getName()
elseif logicEntity.Name then
name = logicEntity.Name
end
eventType = eventType .. name .. " "
eventType = eventType .. r2.events.communWordsColor
eventType = eventType ..r2.getLogicAttribute(logicEntity.Class, "Events", this.Event.Type).text
if this.Event.Value~="" then
local instance = r2:getInstanceFromId(this.Event.Value)
assert(instance)
eventType = eventType .. " " .. instance:getShortName()
end
if this.Event.ValueString and this.Event.ValueString ~= "" then
if string.gfind(eventType, "%%1")() then
eventType = string.gsub(eventType, "%%1", "'"..tostring(this.Event.ValueString).."'")
else
eventType = eventType .. " '" .. tostring(this.Event.ValueString).. "'"
end
end
eventType = eventType .. ", "
-- conditions
local conditionsList = ""
for i=0, this.Conditions.Size-1 do
local conditionInst = this.Conditions[i]
if conditionInst.Entity~="" and conditionInst.Condition.Type~="" then
conditionsList = conditionsList .. "\n" .. r2.events.keyWordsColor
..string.upper(i18n.get("uiR2EdEventTxtPreCondition"):toUtf8()).." "
.. r2.events.communWordsColor
local conditionLogicEntity = r2:getInstanceFromId(tostring(conditionInst.Entity))
assert(conditionLogicEntity)
coloredName = (conditionLogicEntity.InstanceId == r2.events.filteredLogicEntityId)
if coloredName then
conditionsList = conditionsList .. r2.events.filterWordColor
else
conditionsList = conditionsList .. r2.events.entityWordColor
end
conditionsList = conditionsList .. conditionLogicEntity.Name .. " "
conditionsList = conditionsList .. r2.events.communWordsColor
conditionsList = conditionsList ..r2.getLogicAttribute(conditionLogicEntity.Class, "Conditions", conditionInst.Condition.Type).text
if conditionInst.Condition.Value~="" then
local instance = r2:getInstanceFromId(conditionInst.Condition.Value)
assert(instance)
conditionsList = conditionsList .. " '" .. instance:getShortName() .."'"
end
conditionsList = conditionsList .. ", "
end
end
-- actions
local actionsList = ""
for i=0, this.Actions.Size-1 do
local actionInst = this.Actions[i]
if actionInst.Entity~="" and actionInst.Action.Type~="" then
actionsList = actionsList .. "\n" .. r2.events.keyWordsColor
..string.upper(i18n.get("uiR2EdEventTxtPreActions"):toUtf8()).." "
.. r2.events.communWordsColor
local actionLogicEntity = r2:getInstanceFromId(tostring(actionInst.Entity))
assert(actionLogicEntity)
coloredName = (actionLogicEntity.InstanceId == r2.events.filteredLogicEntityId)
if coloredName then
actionsList = actionsList .. r2.events.filterWordColor
else
actionsList = actionsList .. r2.events.entityWordColor
end
local name = "No name"
if actionLogicEntity.getName then
name = actionLogicEntity:getName()
elseif actionLogicEntity.Name then
name = actionLogicEntity.Name
end
actionsList = actionsList .. name .. " "
actionsList = actionsList .. r2.events.communWordsColor
actionsList = actionsList ..r2.getLogicAttribute(actionLogicEntity.Class, "ApplicableActions", actionInst.Action.Type).text
if actionInst.Action.Value~="" then
local instance = r2:getInstanceFromId(actionInst.Action.Value)
assert(instance)
actionsList = actionsList .. " '" .. instance:getShortName() .. "'"
end
if actionInst.Action.ValueString and actionInst.Action.ValueString ~= "" then
if string.gfind(actionsList, "%%1")() then
actionsList = string.gsub(actionsList, "%%1", "'"..tostring(actionInst.Action.ValueString).."'")
else
actionsList = actionsList .. " '" .. tostring(actionInst.Action.ValueString).. "'"
end
end
if i~=this.Actions.Size-1 then
actionsList = actionsList .. ","
else
actionsList = actionsList .. "."
end
end
end
if actionsList=="" then
actionsList = "\n..."
end
return eventType .. conditionsList .. actionsList --.. "\n"
end,
getLogicEntityParent = function(this)
local logicEntity = this.Parent.Parent.Parent
if logicEntity:isGrouped() then logicEntity = logicEntity.Parent.Parent end
return logicEntity
end,
-- The act of the event
getLogicAct = function(this)
local currentAct = r2:getCurrentAct()
local baseAct = r2.Scenario:getBaseAct()
local isBaseAct = false
local presentActs = {}
local isCurrentAct = false
local counter = 0
local entity = this:getLogicEntityParent()
if entity and entity.getParentAct then
local act = entity:getParentAct()
if act then
if act==currentAct then
isCurrentAct=true
elseif act==baseAct then
isBaseAct = true
else
presentActs[act.InstanceId] = act.InstanceId
counter = counter+1
end
end
end
local function verifyAct ( container)
local key, value = next(container, nil)
while key do
if value.Action and value.Action.Type == "Start Act" then
else
local entityId = value.Entity
local entity= r2:getInstanceFromId(entityId)
if entity and entity.getParentAct then
local act = entity:getParentAct()
if act then
if act==currentAct then
isCurrentAct=true
elseif act==baseAct then
isBaseAct = true
else
presentActs[act.InstanceId] = act.InstanceId
counter = counter+1
end
end
end
end
key, value = next(container, key)
end
end
verifyAct(this.Actions)
verifyAct(this.Conditions)
if counter>=2 or (counter==1 and isCurrentAct) then
return nil
elseif counter==1 and not isCurrentAct and isBaseAct then
local act = nil
for k, actId in pairs(presentActs) do
act = r2:getInstanceFromId(actId)
break
end
--inspect(act)
return act
else
--inspect(currentAct)
return currentAct
end
end,
----------
-- called upon translation
getLogicActForTranslate = function(this)
local currentAct = this:getLogicEntityParent():getParentAct()
local baseAct = r2.Scenario:getBaseAct()
local entity = this.Event.Entity
if entity and entity.getParentAct then
local act = entity:getParentAct()
if currentAct == nil then
currentAct = act
elseif act ~= currentAct then
if currentAct == baseAct then
currentAct = act
elseif act == baseAct then
-- do nothing
else
return nil
end
end
end
local function verifyAct ( container)
local key, value = next(container, nil)
while key do
if value.Action and value.Action.Type == "Start Act" then
else
local entityId = value.Entity
local entity= r2:getInstanceFromId(entityId)
if entity and entity.getParentAct then
local act = entity:getParentAct()
if act then
if currentAct == nil then
currentAct = act
elseif act ~= currentAct then
if currentAct == baseAct then
currentAct = act
elseif act == baseAct then
-- do nothing
else return false
end
end
end
end
end
key, value = next(container, key)
end
return true
end
if not verifyAct(this.Actions) then return false end
if not verifyAct(this.Conditions) then return false end
return currentAct
end,
--
getLogicActInstanceId = function(this)
--local ok, act = pcall(Logic.Components.LogicEntityAction.getLogicAct, this)
local ok, act = pcall(Logic.Components.LogicEntityAction.getLogicActForTranslate, this)
if not ok or not act then
return r2.RefId("")
end
return act.InstanceId
end,
}
Logic.Components.EventType =
{
BaseClass ="BaseClass",
Name = "EventType",
DisplayerProperties = "R2::CDisplayerLua",
DisplayerPropertiesParams = "eventTypePropertySheetDisplayer",
Prop =
{
{Name ="Type", Type ="String"},
{Name ="Value", Type ="RefId"}, -- if type is end of activity/chat step/sequence, instance id
{Name ="ValueString", Type ="String", DefaultValue="", DefaultInBase=1}, -- if type is emit user event, sub timer...
}
}
local classActionStepVersion = 2
Logic.Components.ActionStep = {
BaseClass ="BaseClass",
Name = "ActionStep",
Version = classActionStepVersion,
DisplayerProperties = "R2::CDisplayerLua",
DisplayerPropertiesParams = "actionStepPropertySheetDisplayer",
Prop =
{
{Name ="Entity", Type ="RefId"}, -- entity target id
{Name ="Action", Type ="ActionType"} -- sequence id
},
updateVersion = function(this, scenarioValue, currentValue )
local patchValue = scenarioValue
if patchValue < 1 then
local invalidActions = {}
invalidActions["desactivate"] = "deactivate"
invalidActions["Desactivate"] = "deactivate"
r2.updateLogicActions(this, invalidActions, "BanditCamp")
patchValue = 1
end
if patchValue < 2 then
local action = this.Action
if action.Type == "Add 10 Seconds" then
r2.requestSetNode(action.InstanceId, "Type", "add seconds")
r2.requestInsertNode(action.InstanceId, "", -1, "ValueString", "10")
end
if action.Type == "Sub 10 seconds" then
r2.requestSetNode(action.InstanceId, "Type", "sub seconds")
r2.requestInsertNode(action.InstanceId, "", -1, "ValueString", "10")
end
if action.Type == "Add 1 minute" then
r2.requestSetNode(action.InstanceId, "Type", "add seconds")
r2.requestInsertNode(action.InstanceId, "", -1, "ValueString", "60")
end
if action.Type == "Sub 1 minute" then
r2.requestSetNode(action.InstanceId, "Type", "sub seconds")
r2.requestInsertNode(action.InstanceId, "", -1, "ValueString", "60")
end
patchValue = 2
end
if patchValue == currentValue then return true end
return false
end,
}
Logic.Components.ActionType =
{
BaseClass ="BaseClass",
Name = "ActionType",
DisplayerProperties = "R2::CDisplayerLua",
DisplayerPropertiesParams = "actionTypePropertySheetDisplayer",
Prop =
{
{Name ="Type", Type ="String"},
{Name ="Value", Type ="RefId"}, -- if type is begin of activity/chat sequence, instance id
{Name ="ValueString", Type ="String", DefaultValue="", DefaultInBase=1}, -- if type is emit user event, sub timer...
}
}
Logic.Components.ConditionStep =
{
BaseClass ="BaseClass",
Name = "ConditionStep",
DisplayerProperties = "R2::CDisplayerLua",
DisplayerPropertiesParams = "conditionStepPropertySheetDisplayer",
Prop =
{
{Name ="Entity", Type ="RefId"}, -- entity id
{Name ="Condition", Type ="ConditionType"}
}
}
Logic.Components.ConditionType =
{
BaseClass ="BaseClass",
Name = "ConditionType",
DisplayerProperties = "R2::CDisplayerLua",
DisplayerPropertiesParams = "conditionTypePropertySheetDisplayer",
Prop =
{
{Name ="Type", Type ="String"},
{Name ="Value", Type ="RefId"}, -- if type is being in activity/chat step/sequence, instance id
}
}
-- REACTION -----------------
Logic.Components.LogicEntityReaction =
{
BaseClass ="BaseClass",
Name = "LogicEntityReaction",
DisplayerProperties = "R2::CDisplayerLua",
DisplayerPropertiesParams = "logicEntityReactionPropertySheetDisplayer",
Prop =
{
{Name ="Name", Type ="String"},
{Name ="LogicEntityAction", Type ="String"}, -- id of associated LogicEntityAction
{Name ="ActionStep", Type ="String"}, -- id of associated ActionStep
}
}
Logic.Components.ChatAction=
{
BaseClass ="BaseClass",
Name ="ChatAction",
DisplayerProperties = "R2::CDisplayerLua",
DisplayerPropertiesParams = "chatActionPropertySheetDisplayer",
Prop =
{
{Name ="Who", Type ="RefId"},
{Name ="WhoNoEntity", Type ="String"},
{Name ="Says", Type ="String"},
{Name ="Emote", Type ="String"},
{Name ="Facing", Type ="RefId"},
-- {Name ="FacingNoEntity", Type ="String"},
}
}
Logic.Components.ChatStep = {
BaseClass ="BaseClass",
Name = "ChatStep",
DisplayerProperties = "R2::CDisplayerLua",
DisplayerPropertiesParams = "chatStepPropertySheetDisplayer",
Prop =
{
{Name ="Actions", Type ="Table"},
{Name ="Time", Type ="Number" },
{Name ="Name", Type ="String" }
},
getName = function(this)
-- after time
local minNb, secNb = r2.dialogs:calculMinSec(this.Time)
local time = ""
if minNb ~= 0 then
time = tostring(minNb)..i18n.get("uiR2EdShortMinutes"):toUtf8()
end
time = time.." " ..tostring(secNb)..i18n.get("uiR2EdShortSeconds"):toUtf8()
local afterTime = "(" ..i18n.get("uiR2EdAfter"):toUtf8().." ".. time..") "
-- says
local whoToWho = ""
local action = this.Actions[0]
local who = action.Who
if who=="" then who=action.WhoNoEntity end
if who and who ~= "" then
if r2:getInstanceFromId(who) then
who=r2:getInstanceFromId(who).Name
else
who = r2.dialogs.whoToWhoTranslation[who]
end
whoToWho = who .. " "
local facing = action.Facing
if facing~="" then
whoToWho = whoToWho ..i18n.get("uiR2EdSaysTo"):toUtf8().. " " .. r2:getInstanceFromId(facing).Name .. " "
end
local emote = action.Emote
if emote~="" and r2.dialogs.fromEmoteIdToName[emote] ~= nil then
whoToWho = whoToWho .."(" .. r2.dialogs.fromEmoteIdToName[emote] .. ") :"
end
end
return afterTime..whoToWho
end,
getShortName = function(this)
-- says
local saysWhat = ""
local action = this.Actions[0]
local who = action.Who
if who ~= "" or WhoNoEntity~="" then
who = r2:getInstanceFromId(who)
if who then
saysWhat = who.Name
elseif action.WhoNoEntity=="_System" then
saysWhat = i18n.get("uiR2EdSystem"):toUtf8()
elseif action.WhoNoEntity=="_DM" then
saysWhat = i18n.get("uiR2EdDonjonMaster"):toUtf8()
end
saysWhat = saysWhat .. " " ..i18n.get("uiR2EdSays"):toUtf8().. " "
local says = action.Says
if says ~= "" then
local inst=r2:getInstanceFromId(says)
if inst then
says = inst.Text
local uc_says = ucstring()
uc_says:fromUtf8(says)
uc_says = uc_says:substr(0, 4)
says = uc_says:toUtf8()
end
end
saysWhat = saysWhat .. says .. "..."
end
return saysWhat
end,
--------------------------------------------------------------------------------------------
-- from 'BaseClass'
getParentTreeNode = function(this)
end,
}
local classChatSequenceVersion = 1
Logic.Components.ChatSequence = {
PropertySheetHeader = r2.getDisplayButtonHeader("r2.dialogs:openEditor()", "uiR2EdEditDialogButton"),
BaseClass = "LogicEntity",
Name = "ChatSequence",
InEventUI = true,
Menu="ui:interface:r2ed_feature_menu",
Version = classChatSequenceVersion,
DisplayerProperties = "R2::CDisplayerLua",
DisplayerPropertiesParams = "chatSequencePropertySheetDisplayer",
DisplayerUI = "R2::CDisplayerLua",
DisplayerUIParams = "defaultUIDisplayer",
DisplayerVisual = "R2::CDisplayerVisualEntity",
Parameters = {},
ApplicableActions = {
"activate", "deactivate", "starts dialog", "stops dialog", "starts chat" , "continues dialog"
},
Events = {
"start of dialog", "end of dialog" ,
"start of chat", "end of chat",
"activation", "deactivation"
},
Conditions = {
"is not in dialog", "is in dialog", "is in chat"
},
TextContexts = {},
TextParameters = {},
LiveParameters = {},
Prop =
{
{Name = "Type", Type="String",DefaultValue = "None", Visible=false},
{Name ="Repeating", Type="Number" ,DefaultValue = "0", Visible=false},
{Name="Components",Type="Table"},
{Name="SubComponents", Type="Table"},
{Name="Name", Type="String", MaxNumChar="32"},
{Name="AutoStart", Type="Number", WidgetStyle="Boolean", DefaultValue="1", Visible=function(this) return this:mustDisplayAutostart() end},
{Name="Active", Type="Number", WidgetStyle="Boolean", DefaultValue = "1"},
},
mustDisplayAutostart = function(this)
if this.Class == "ProximityDialog" then
return false
end
return true
end,
-- it's a feature
getParentTreeNode = function(this)
return this:getFeatureParentTreeNode()
end,
onPostCreate = function(this)
--this:createGhostComponents()
if this.User.DisplayProp and this.User.DisplayProp == 1 then
r2:setSelectedInstanceId(this.InstanceId)
r2:showProperties(this)
this.User.DisplayProp = nil
end
end,
create = function()
--if r2:getLeftQuota() <= 0 then -- ??
-- r2:makeRoomMsg()
-- return
--end
local function posOk(x, y, z)
if r2.mustDisplayInfo("ChatSequence") == 1 then
r2.displayFeatureHelp("ChatSequence")
end
debugInfo(string.format("Validate creation of 'Dialog' at pos (%d, %d, %d)", x, y, z))
r2.dialogs:newSequenceInst(x, y, z)
end
local function posCancel()
debugInfo("Cancel choice 'Dialog' position")
end
local creature = r2.Translator.getDebugCreature("object_component_dialog.creature")
r2:choosePos(creature, posOk, posCancel, "createDialog")
end,
---- get Name ------
getName = function(this)
local name = this.Name
if name == "" then
local index = r2.logicComponents:searchElementIndex(this)
if index >= 0 then
name = i18n.get("uiR2EDDialog"):toUtf8() .. index
end
end
return name
end,
---- get Name ------
getShortName = function(this)
return this:getName()
end,
---------------------------------------------------------------------------------------------------------
editDialogs = function(this)
r2.dialogs:openEditor()
end,
getAvailableCommands = function(this, dest)
r2.Classes.LogicEntity.getAvailableCommands(this, dest)
table.insert(dest, this:buildCommand(this.editDialogs, "edit_dialogs", "uiR2EDEditDialogs", "r2ed_edit_dialog.tga", true))
this:getAvailableDisplayModeCommands(dest)
end,
initEventValuesMenu = function(this, menu, categoryEvent)
for ev=0,menu:getNumLine()-1 do
local eventType = tostring(menu:getLineId(ev))
if r2.events.eventTypeWithValue[eventType] == "Number" then
menu:addSubMenu(ev)
local subMenu = menu:getSubMenu(ev)
local func = ""
for i=0, 9 do
local uc_name = ucstring()
uc_name:fromUtf8( tostring(i) )
func = "r2.events:setEventValue('','" .. categoryEvent .."','".. tostring(i).."')"
subMenu:addLine(uc_name, "lua", func, tostring(i))
end
elseif r2.events.eventTypeWithValue[eventType]=="ChatStep" then
menu:addSubMenu(ev)
local subMenu = menu:getSubMenu(ev)
for c=0, this.Components.Size-1 do
local chat = this.Components[c]
local uc_name = ucstring()
uc_name:fromUtf8(chat:getShortName())
subMenu:addLine(uc_name, "lua",
"r2.events:setEventValue('".. chat.InstanceId .."','" .. categoryEvent .. "')", chat.InstanceId)
end
if this.Components.Size==0 then
subMenu:addLine(i18n.get("uiR2EdNoSelelection"), "", "", "")
end
end
end
end,
getLogicAction = function(this, context, action)
return r2.Translator.getDialogLogicAction(this, context, action)
end,
getLogicEvent = function(this, context, event)
return r2.Translator.getDialogLogicEvent(this, context, event)
end,
getLogicCondition = function(this, context, condition)
return r2.Translator.getDialogLogicCondition(this, context, condition)
end,
pretranslate = function(this, context)
r2.Translator.createAiGroup(this, context)
end,
translate = function(this, context)
r2.Translator.translateFeatureActivation(this, context)
r2.Translator.translateDialog( this, context)
end,
updateVersion = function(this, scenarioValue, currentValue )
local patchValue = scenarioValue
if patchValue < 1 then
local subComponents = {}
r2.requestInsertNode(this.InstanceId, "", -1, "SubComponents", subComponents)
r2.requestInsertNode(this.InstanceId, "", -1, "AutoStart", this.Active)
r2.requestSetNode(this.InstanceId, "Active", 1)
r2.requestSetNode(this.InstanceId, "Base", r2.Translator.getDebugBase("palette.entities.botobjects.dialog"))
patchValue = 1
end
if patchValue == currentValue then return true end
return false
end,
initLogicEntitiesInstancesMenu = function(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
}
local ActivityStepVersion = 1
Logic.Components.ActivityStep = {
BaseClass ="BaseClass",
Name ="ActivityStep",
Version = ActivityStepVersion,
BuildPropertySheet = true,
Menu ="ui:interface:r2ed_feature_menu",
BuildPropertySheet = false,
DisplayerVisualParams =
{
Look = r2.PrimRender.GroupLook,
ArrayName = "Components"
},
DisplayerProperties = "R2::CDisplayerLua",
DisplayerPropertiesParams = "activityStepPropertySheetDisplayer",
Prop =
{
{Name="Activity", Type="String"},
{Name="ActivityZoneId",Type="RefId",Category="ActivityStep"},
{Name="TimeLimit",Type="String",Category="ActivityStep"},
{Name="TimeLimitValue", Type="String",Category="ActivityStep",Category="ActivityStep"},
{Name="RoadCountLimit", Type="String",Category="ActivityStep",Category="ActivityStep", DefaultInBase = 1, DefaultValue = "0"},
{Name="Chat",Type="RefId"},
{Name = "Type", Type="String",DefaultValue = "None"}, --TEMP TEMP TEMP
{Name="EventsIds",Type="Table"},
{Name="Name", Type="String", MaxNumChar="32"}
},
-- get sequencable parent for this activity step
getSequencableParent = function(this)
local currParent = this.Parent
while currParent do
if currParent.InstanceId and currParent:isSequencable() then
return currParent
end
currParent = currParent.Parent
end
return nil
end,
getVerbLookupString = function(this)
local seqParent = this:getSequencableParent()
if seqParent then
return seqParent:getActivityVerbLookupName(this.Activity)
else
return this.Activity
end
end,
-- do lookup from the verb lookup string used to know the display name, and button texture
doLookupFromVerb = function(this, lookupTable)
local lookupString = this:getVerbLookupString()
-- activity type
local value = lookupTable[lookupString]
if not value then
debugInfo(colorTag(255,0,0).."The activity '".. lookupString .."' is not properly registred")
return nil
end
return value
end,
-- get texture for the button displayed in the mini activity view
getMiniButtonTexture = function(this)
local result = this:doLookupFromVerb(r2.miniActivities.activityTextures)
if result then return result end
return "brick_default.tga"
end,
-- get the verb for this activity (rest, feed, patrol etc...)
getVerb = function(this)
local result = this:doLookupFromVerb(r2.activities.activityTypeTranslation)
if result then result = result.trans end
if result then return result end
return ucstring("Activity not registered : " .. lookupString)
end,
-- element name
getName = function(this)
local activityType = this:getVerb() .. " "
if this.ActivityZoneId~= "" then
local place = r2:getInstanceFromId(tostring(this.ActivityZoneId))
if place~=nil then
activityType = activityType.. place.Name .." "
end
end
-- activity time
local activityTime = ""
if this.TimeLimit == "Few Sec" then
local hourNb, minNb, secNb = r2.logicComponents:calculHourMinSec(tonumber(this.TimeLimitValue))
local timeLimitText = i18n.get("uiR2EdFor"):toUtf8() .. " "
if hourNb ~= 0 then timeLimitText = timeLimitText .. hourNb .. i18n.get("uiR2EdShortHours"):toUtf8() .. " " end
if minNb ~= 0 then timeLimitText = timeLimitText .. minNb .. i18n.get("uiR2EdShortMinutes"):toUtf8() .. " " end
timeLimitText = timeLimitText .. secNb .. i18n.get("uiR2EdShortSeconds"):toUtf8()
activityTime = timeLimitText
elseif r2.activities.timeLimitsTranslation[this.TimeLimit] ~= nil then
activityTime = string.lower(r2.activities.timeLimitsTranslation[this.TimeLimit])
end
return activityType..activityTime
end,
-- element name
getShortName = function(this)
-- activity type
local activityType = this:getVerb()
if this.ActivityZoneId~= "" then
local place = r2:getInstanceFromId(tostring(this.ActivityZoneId))
if place~=nil then
activityType = activityType.. " " .. place.Name
end
end
return activityType
end,
updateVersion = function(this, scenarioValue, currentValue )
local patchValue = scenarioValue
if patchValue < 1 then
local activity = this.Activity
if (activity and activity == "Inactive") then
r2.requestSetNode(this.InstanceId, "Activity", "Stand Still")
end
local name = this.Name
patchValue = 1
end
if patchValue == currentValue then return true end
return false
end
}
Logic.Components.ActivitySequence = {
BaseClass="BaseClass",
Name="ActivitySequence",
BuildPropertySheet = true,
Menu ="ui:interface:r2ed_feature_menu",
--DisplayerUI = "R2::CDisplayerLua",
--DisplayerUIParams = "defaultUIDisplayer",
BuildPropertySheet = false,
DisplayerVisual = "R2::CDisplayerVisualActivitySequence",
DisplayerProperties = "R2::CDisplayerLua",
DisplayerPropertiesParams = "activitySequencePropertySheetDisplayer",
Prop =
{
--{Name ="InstanceId", Type ="String"},
{Name ="Repeating", Type ="Number" , DefaultValue = "1"},
{Name ="Components", Type ="Table"},
{Name ="Name", Type ="String"}
},
---- get Name ------
getName = function(this)
local name = this.Name
if name == "" then
local index = r2.logicComponents:searchElementIndex(this)
if index >= 0 then
name = i18n.get("uiR2EdSeq"):toUtf8() .. index
end
end
return name
end,
---- get Name ------
getShortName = function(this)
return this:getName()
end,
-- get ActiveLogicEntity parent
getActiveLogicEntityParent = function(this)
-- ActiveLogicEntity.Behavior.Activities
local activeLogicEntity = this.Parent.Parent.Parent
-- NpcGrpFeature.Components
--if activeLogicEntity:isGrouped() then activeLogicEntity = activeLogicEntity.Parent.Parent end
return activeLogicEntity
end,
}
--this function must be called when we delete a ChatAction,
--to unregister the text
onDeleteChatAction = function(chatAction)
if chatAction.User.DeleteInProgress == true then return end
chatAction.User.DeleteInProgress = true
if chatAction.Says ~= nil and chatAction.Says ~= ""
then
debugInfo("onDeleteChatAction")
r2.unregisterTextFromId(chatAction.Says)
end
end
--counts the states created, to ensure states names uniqueness
--timer used to time the sequences steps
Logic.activityStepTimer = "t0"
Logic.activityStepTimerId = 0
--timer used to time the chat steps
Logic.chatTimer = "t1"
Logic.chatTimerId = 1
--timer used inside activities
Logic.activityInternalTimer = "t2"
Logic.activityInternalTimerId = 2
--variable used to know which action of the current chat sequence
--must be played
Logic.chatStepVar = "v1"
--variable used to know which chat sequence is currently played
Logic.chatSequenceVar = "v0"
--variable used to know which activity sequence is currently played
Logic.activityStepVar = "v2"
--variable used to know which interrupt action must be executed
Logic.triggerEventVar = "v3"
Logic.EndOfActivitySequenceEvent = 9
Logic.EndOfChatSequenceEvent = 8
--switch_action which hold all chat sequences
Logic.DialogAction = nil
--switch action holding chat sequences transitions
Logic.DialogAction2 = nil
--switch_action which hold all sequence steps
Logic.SequenceAction = nil
Logic.ActionStepCounter =0
Logic.ChatSequenceCounter = 0
--used to know the names of all the states generated
--to translate this activity
Logic.StatesByName = ""
--timer_triggered event, triggered
--each time we must enter a new chat step
Logic.DialogEvent = nil
Logic.DialogEvent2 = nil
--timer_triggered event, triggered
--each time we must enter a new sequence step
Logic.SequenceEvent = nil
--hold the states used in the current activity.
--all the states are created at the start of the translation,
--before translating the events and actions.
Logic.States = {}
--hold the states used in all the activities
--of the group
Logic.ActivitiesStates ={}
--the activity which is currently being translated.
Logic.CurrentActivity = nil
----------------------------------------------------
--to be called once for each sequence of each group
--complete the AiActivity field of the first state of this sequence
--and create the actions to go to the first step
Logic.initGroupActivitiesTranslation = function(context, hlComponent, sequence, first, activityIndex, aiActivity, rtGrp)
assert(context and hlComponent and sequence and activityIndex and aiActivity and rtGrp)
--get the states of this activity
local activityStates = Logic.ActivitiesStates[ tostring(sequence.InstanceId) ]
assert(sequence.Class == "ActivitySequence")
if not activityStates then
if hlComponent then
printWarning("Error while translating '" .. hlComponent.Name .. "' activities in sequence " .. sequence.Name)
-- pretranslate sequence.InstanceId errors instanceId not added in currentAct.ActivitiesId ?
return nil
end
end
--get the initial state of this activity
local aiState = activityStates[sequence.InstanceId][1]
Logic.StatesByName = ""
for k, v in pairs(activityStates)
do
if v.Class ~= "RtAiState"
then
local k1, v1 = next( v, nil)
while k1 do
Logic.StatesByName = r2.Utils.concat(Logic.StatesByName, v1.Name)
k1, v1 = next(v, k1)
end
else
Logic.StatesByName = r2.Utils.concat(Logic.StatesByName, v.Name)
end
end
aiState.AiActivity = aiActivity
assert(aiState.AiActivity)
local event = r2.Translator.createEvent("start_of_state", aiState.Name, rtGrp.Name)
-- local event = r2.Translator.createEvent("group_spawned", aiState.Name, rtGrp.Name)
table.insert(context.RtAct.Events, event)
if first == true
then
table.insert(aiState.Children, rtGrp.Id)
end
local speed = ""
if hlComponent.Speed and hlComponent.Speed == "run" then speed = "()addProfileParameter(\"running\");\n" end
local code = "currentActivitySequenceVar = " .. tostring(activityIndex -1 ) ..";\n"
.. "oldActivitySequenceVar = currentActivitySequenceVar;\n"
.. "RoadCountLimit=0;\n"
.. "oldActivityStepVar = -1;\n"
.. "oldActivityStepVar2 = 0;\n"
.. Logic.activityStepVar .." = 0;\n"
.. speed
.."alive = 0;\n"
.."(alive)isAlived();\n"
.. "if (alive == 1)\n{\n"
.. "\t()setTimer(30, " .. Logic.activityStepTimerId .. ");\n"
.. "\tinit = 1;\n"
.. "}\n"
-- Fauna activities
local action = r2.Translator.createAction("code", code)
action.Name = "startActivitySequence"
table.insert(context.RtAct.Actions, action)
table.insert(event.ActionsId, action.Id)
do
local event = r2.Translator.createEvent("group_spawned", aiState.Name, rtGrp.Name)
local action = r2.Translator.createAction("code", "if (init != 1)\n{\n\t()setTimer(30, " .. Logic.activityStepTimerId .. ");\n}\n")
table.insert(context.RtAct.Events, event)
table.insert(context.RtAct.Actions, action)
table.insert(event.ActionsId, action.Id)
end
local leader = hlComponent
if hlComponent:isKindOf("NpcGrpFeature") then
if hlComponent.Components.Size ~= 0 then
leader = hlComponent.Components[0]
else
leader = nil
end
end
end
--insert an activity step at the specified position
Logic.insertActivityStep = function(sequence, step, pos)
local n = table.getn(sequence.Components)
if n < pos
then
table.insert(sequence.Components, step)
else
table.insert(sequence.Components, pos, step)
end
end
--insert a chat step at the specified position
Logic.insertChatStep = function(chatSequence, chatStep, pos)
local n = table.getn(chatSequence.Components)
if n < pos
then
table.insert(chatSequence.Components, chatStep)
else
table.insert(chatSequence.Components, pos)
end
end
Logic.createInteraction = function(action, parameter)
local index = Logic.find(Logic.InteractionTypes, action)
local interaction
if index == nil or parameter == nil
then
-- debugInfo(colorTag(255,0,0).."unknown interaction : " .. action .." !")
return nil
end
interaction = r2.newComponent("Interaction")
interaction.Type = action
interaction.Parameter = parameter
return interaction
end
Logic.createActivityStep = function(activity, timeLimit, zoneId, time)
local activityStep = nil
if activity == nil or timeLimit == nil
then
return nil
end
--checking activity type and time limit type
if Logic.find(Logic.Activities, activity)~= nil and Logic.find(Logic.TimeLimits, timeLimit)~= nil
then
--checking activity parameter
if ( (activity ~= "Stand Still") and (activity ~= "Inactive") and (zoneId == nil) )
then
--this activity need a zone, and no zone id is given
-- debugInfo(colorTag(255,0,0).."activity <" .. activity .."> need a zone id!")
return nil
end
--checking time parameter
--if time parameter needed, check its presence
if timeLimit~="No Limit" and timeLimit~="Chat" and time == nil
then
--this activity needs a time limit and no limit is given
-- debugInfo(colorTag(255,0,0).."Time limit <" .. timeLimit .."> need a time limit parameter!")
return nil
end
--check season validity
if (timeLimit == "Season") and (Logic.find(Logic.Seasons, time) == nil)
then
-- debugInfo(colorTag(255,0,0).."Unknown season: " .. time)
return nil
end
--check day validity
if (timeLimit == "Day") and (Logic.find(Logic.Days, time) == nil)
then
debugInfo(colorTag(255,0,0).."Uknown week day: " .. time)
return nil
end
if (timeLimit == "Month") and (Logic.find(Logic.Months, time)== nil)
then
-- debugInfo(colorTag(255,0,0,0).."Uknown month: " .. time)
return nil
end
activityStep = r2.newComponent("ActivityStep")
activityStep.Activity = activity
activityStep.TimeLimit = timeLimit
activityStep.ActivityZoneId = zoneId
activityStep.TimeLimitValue = time
else
-- debugInfo(colorTag(255,0,0).."Unknown activity !")
end
return activityStep
end
Logic.createState = function()
local aiState = r2.newComponent("RtAiState")
aiState.Name = aiState.Id
Logic.StatesByName = Logic.StatesByName .."\n" .. aiState.Name
return aiState
end
--create the AiStates necessay to translate this step
Logic.createStepStates = function(step, context)
local states = {}
local state = Logic.createState()
table.insert(states, state)
table.insert(context.RtAct.AiStates, state)
if step.Activity == "Patrol"
then
local state = Logic.createState()
table.insert(states, state)
table.insert(context.RtAct.AiStates, state)
end
return states
end
--assign a zone or a road to an AiState
--if invert is true, invert the road
Logic.assignZone = function(rtAiState, zone, invert)
assert( zone and type(zone) == "userdata")
local points = zone.Points
assert( points ~= nil)
local size = points.Size + 1
rtAiState.Pts = {}
local i =0
local j
local k, v = next(points, nil)
while k ~= nil
do
assert(v ~= nil)
i = i +1
if invert == true
then
j = size - i
else
j = i
end
rtAiState.Pts[j]={}
rtAiState.Pts[j].x = r2.getWorldPos(v).x
rtAiState.Pts[j].y = r2.getWorldPos(v).y
rtAiState.Pts[j].z = r2.getWorldPos(v).z
k, v = next(points, k)
end
end
--create all the states used in this activity Sequence
Logic.createActivityStates = function(context, sequence)
assert( sequence ~= nil)
local activityStates ={}
--activity's initial stat, aiStopStatee
-- init state
local aiStartState = r2.newComponent("RtAiState")
aiStartState.Name = aiStartState.Id
Logic.StatesByName = aiStartState.Name
aiStartState.AiMovement = "idle" -- "stand_on_start_point"
table.insert(context.RtAct.AiStates, aiStartState)
-- end state
local aiStopState = r2.newComponent("RtAiState")
aiStopState.Name = aiStopState.Id
--Logic.StatesByName = aiStopState.Name
aiStopState.AiMovement = "idle" -- "stand_on_start_point"
table.insert(context.RtAct.AiStates, aiStopState)
activityStates[sequence.InstanceId]= { aiStartState, aiStopState}
if (sequence.Components == nil) then assert(nil) end
--creation of the states of the step
local k, v = next(sequence.Components, nil)
while k do
local states = Logic.createStepStates(v, context)
activityStates[v.InstanceId]= states
k, v = next(sequence.Components, k)
end
Logic.ActivitiesStates[sequence.InstanceId] = activityStates
end
Logic.translateActivitySequence = function(context, hlComponent, activitySequence, sequenceId, rtNpcGrp)
assert(rtNpcGrp ~= nil)
if context.Real == false
then
return
end
Logic.ActionStepCounter = 0
Logic.ChatSequenceCounter = 0
--Logic.States = {}
Logic.CurrentActivity = activitySequence
local ok = false
local nbSteps = activitySequence.Components.Size
local aiState
local action
local event
local sequence = activitySequence
if sequence.Components.Size ==0
then
return
end
Logic.initSequence(context, rtNpcGrp)
if Logic.ActivitiesStates[sequence.InstanceId] then
Logic.States = Logic.ActivitiesStates[sequence.InstanceId]
else
Logic.States = ""
end
local i =1
local k, activityStep = next(sequence.Components, nil)
while k do
--translate step
Logic.translateActivityStep(context, hlComponent, activitySequence, activityStep, i, rtNpcGrp)
i = i + 1
k, activityStep = next(sequence.Components, k)
end
--create actions to repeat the sequence
if sequence.Repeating == 1
then
local code =
"//sequence will repeat"..
"oldChatSequenceVar = " .. Logic.chatSequenceVar .. ";\n" ..
"RoadCountLimit=0;\n" ..
"oldActivityStepVar = " .. Logic.activityStepVar .. ";\n" ..
"oldActivityStepVar2 = " .. Logic.activityStepVar .. " + 1" .. ";\n" ..
"v2=0;\n" ..
"()setTimer(1, " ..Logic.activityStepTimerId .. ");\n"
-- .. "()setEvent(" .. Logic.EndOfActivitySequenceEvent ..");\n"
local action = r2.Translator.createAction("code", code)
action.Name = "repeat_sequence"
table.insert(Logic.SequenceAction.Children, action)
else
local backupState =
"//sequence will not repeat"..
"oldChatSequenceVar = " .. Logic.chatSequenceVar .. ";\n" ..
"RoadCountLimit=0;\n"..
"oldActivityStepVar = " .. Logic.activityStepVar .. ";\n" ..
"oldActivityStepVar2 = " .. Logic.activityStepVar .. " + 1" .. ";\n"
local stateName = Logic.ActivitiesStates[sequence.InstanceId][sequence.InstanceId][2].Id
local setNextActivityState = "()postNextState(\"" .. r2.getNamespace() .. stateName .."\");\n"
local action = r2.Translator.createAction("code", backupState
-- .."()setEvent(" .. Logic.EndOfActivitySequenceEvent ..");\n"
..setNextActivityState)
action.Name = "end_of_activity_sequence"
table.insert(Logic.SequenceAction.Children, action)
end
Logic.SequenceEvent.StatesByName = Logic.StatesByName
Logic.DialogEvent = nil
Logic.SequenceEvent = nil
end
Logic._obsolete_TranslateScriptAction = function(context, step, nextTime)
local actionType = Logic.getAction(step)
assert(actionType~= nil)
-- debugInfo(colorTag(0,255,0).. actionType)
if actionType == "stop_actions"
then
local action = r2.Translator.createAction("set_timer_" ..Logic.chatTimer, "0")
return action
end
if actionType == "start_mission"
then
local counterMission = context.Components[step.Parameter]
local action = r2.Translator.createAction("trigger_event_1", context.RtCounters[counterMission.InstanceId].RtGroup.Name)
-- debugInfo("action created!!")
return action
end
if 0==1 and actionType == "go_to_step"
then
--TODO
local param = tonumber(step.Parameter)
debugInfo("param = " .. param)
if (param < 1) or (Logic.CurrentActivity.Components[param]== nil)
then
-- debugInfo(colorTag(255,0,0).."Impossible to go to step " .. param .." !")
return nil
end
debugInfo(context.Feature.Class)
return Logic.selectActivityStep(param)
end
if actionType == "set_activity"
then
local group = nil
local param
local rtGroup
if step.Who ~= "" and step.Who ~= nil
then
group = step.Who
rtGroup = r2.Translator.getRtGroup(context, group)
end
param = tonumber(step.Parameter)
-- debugInfo("param = " .. param)
local action
if group ~= nil
then
action = r2.Translator.createAction("begin_state", Logic.getActivityInitialStateName(group, param, context))
assert(action ~= nil)
local index = Logic.addTriggeredAction(context, context.RtGroups[group].Name, action)
action = r2.Translator.createAction("modify_variable", rtGroup.Name ..":" ..Logic.triggerEventVar .." = " .. index)
action.Name ="set_activity"
else
action = r2.Translator.createAction("begin_state", Logic.getActivityInitialStateName(context.Group.Name, param, context))
assert(action ~= nil)
end
return action
end
local action = r2.Translator.createAction(actionType)
assert(action ~= nil)
return action
end
Logic.translateChatAction = function(context, chatSequenceNumber, chatStepNumber, chatSequence, chatStep, chatAction, rtMAction)
local getRtId = r2.Features["TextManager"].getRtId
if chatAction.Class == "ChatAction"
then
local who = r2.Utils.getNpcParam( tostring( chatAction.Who), context)
-- create say action
if not who then
local whoInstance = r2:getInstanceFromId( tostring(chatAction.Who) )
local chatSequenceInstance = r2:getInstanceFromId(chatSequence.InstanceId)
local whoName = ""
if whoInstance then whoName = "(" .. whoInstance.Name ..")" end
if false then
printWarning( "Error in ChatStep '" .. chatStep:getName()
.. "' of the ChatSequence '" .. chatSequence:getName() .. "'"
.. " the field Who '" .. chatAction.Who .."' is invalid " )
end
return nil
end
if chatAction.Says ~= "" and chatAction.Says ~= nil
then
local param = getRtId(context, tostring(chatAction.Says))
if param then
action = r2.Translator.createAction("npc_say", param, who);
-- action = r2.newComponent("RtNpcEventHandlerAction")
-- action.Action = "npc_say"
-- action.Parameters = who .."\n" .. param
table.insert(rtMAction.Children, action)
else
debugInfo(colorTag(255,255,0).."WRN: Text " .. chatAction.Says .. " error")
end
end
-- create emot action
if tostring(chatAction.Emote) ~= "" and chatAction.Emote ~= nil
then
action = r2.newComponent("RtNpcEventHandlerAction")
action.Action = "emot"
action.Parameters = tostring(chatAction.Emote).."\n" .. who
table.insert(rtMAction.Children, action)
end
-- create facing action
if tostring(chatAction.Facing) ~= "" and chatAction.Facing ~= nil
then
local facing = r2.Utils.getNpcParam(tostring(chatAction.Facing), context)
if facing then
action = r2.newComponent("RtNpcEventHandlerAction")
action.Action = "facing"
action.Parameters = facing .."\n" .. who
table.insert(rtMAction.Children, action)
else
printWarning("Can not find npc")
end
end
else
printWarning( chatAction.Class .. " not implemented yet")
end
end
Logic.translateChatStep = function(context, chatSequenceNumber, chatSequence, chatStepNumber, chatStep, rtActionSwitchChatStep)
assert(chatStep)
assert(chatStep.Class == "ChatStep")
if chatStep.Actions.Size > 0 then
local rtMAction = r2.Translator.createAction("multi_actions")
table.insert(rtActionSwitchChatStep.Children, rtMAction)
local k, chatAction = next(chatStep.Actions, nil)
while k do
Logic.translateChatAction(context, chatSequenceNumber, chatStepNumber, chatSequence, chatStep, chatAction, rtMAction)
local oldChatAction = chatAction
-- next wait
do
if (chatStepNumber < chatSequence.Components.Size and chatSequence.Components[chatStepNumber ]) then
local action = r2.Translator.createAction("code",
"oldChatStepVar = " .. tostring(chatStepNumber)..";\n" ..
Logic.chatStepVar .." = " .. tostring(chatStepNumber+1)..";\n" ..
"()setTimer(" .. tostring(1+chatSequence.Components[chatStepNumber].Time*10) .. ", " .. Logic.chatTimerId .. ");\n");
action.Name = "next"
table.insert(rtMAction.Children, action)
else
local action = r2.Translator.createAction("code",
"oldChatStepVar = " .. tostring(chatStepNumber)..";\n" ..
Logic.chatStepVar .." = " .. tostring(chatStepNumber+1)..";\n" ..
"()setEvent(" ..Logic.EndOfChatSequenceEvent ..");\n" ..
"if (repeatSequence == 1)\n{\n " .. Logic.chatSequenceVar .."=" ..Logic.chatSequenceVar ..";\n" ..
"}\n")
action.Name = "end_of_chat_sequence"
table.insert(rtMAction.Children, action)
end
end
k, chatAction = next(chatStep.Actions, k)
end
else
local action = r2.Translator.createAction("null_action")
action.Name = "empty_chat_step_" .. chatStepNumber
table.insert(rtActionSwitchChatStep.Children, action)
end
end
Logic.translateChatSequence = function (context, chatSequenceNumber, chatSequence, rtSwitchChatSequence)
assert(chatSequence)
assert(chatSequence.Class == "ChatSequence")
if chatSequence.Components.Size > 0 then
local rtActionSwitchChatStep = r2.Translator.createAction("switch_actions", Logic.chatStepVar)
rtActionSwitchChatStep.Name = "switch_chat_step"
table.insert(rtSwitchChatSequence.Children, rtActionSwitchChatStep)
local chatStepNumber = 0
-- initial wait
do
local action = r2.Translator.createAction("code", "oldChatStepVar = 0;\n"
.. Logic.chatStepVar .." = 1;\n()setTimer(" .. tostring( tonumber(chatSequence.Components[0].Time)*10 + 1) .. ", " .. Logic.chatTimerId ..");\n");
action.Name = "initial_wait"
table.insert(rtActionSwitchChatStep.Children, action)
end
local k, chatStep = next(chatSequence.Components, nil)
while k do
chatStepNumber = chatStepNumber + 1
Logic.translateChatStep(context, chatSequenceNumber, chatSequence, chatStepNumber, chatStep, rtActionSwitchChatStep)
k, chatStep = next(chatSequence.Components, k)
end
else
local action = r2.Translator.createAction("null_action")
action.Name = "empty_chat_sequence_" .. chatSequenceNumber
table.insert(rtSwitchChatSequence.Children, action)
end
end
Logic.translateChatSequences = function (context, hlComponent, behavior, rtNpcGrp)
assert(behavior.ChatSequences)
if behavior.ChatSequences.Size > 0 then
assert(rtNpcGrp)
do
local event = r2.Translator.createEvent("variable_" ..Logic.chatSequenceVar .."_changed", "", rtNpcGrp.Name)
event.Name = "activity_sequence_changed"
table.insert(context.RtAct.Events, event)
local rtInitChatStep = r2.Translator.createAction("code", "oldChatStepVar = -1;\n" .. Logic.chatStepVar .." = 0;\n()setTimer(1, " ..Logic.chatTimerId .. ");\n")
rtInitChatStep.Name = "init_chat_step"
table.insert(context.RtAct.Actions, rtInitChatStep)
table.insert(event.ActionsId, rtInitChatStep.Id)
end
local event = r2.Translator.createEvent("timer_" ..Logic.chatTimer .."_triggered", "", rtNpcGrp.Name)
event.Name = "dialog_event"
table.insert(context.RtAct.Events, event)
local rtSwitchChatSequence = r2.Translator.createAction("switch_actions", Logic.chatSequenceVar)
rtSwitchChatSequence.Name = "switch_chat_sequence"
table.insert(context.RtAct.Actions, rtSwitchChatSequence)
table.insert(event.ActionsId, rtSwitchChatSequence.Id)
local chatSequenceNumber = 0
local k, chatSequence = next(behavior.ChatSequences, nil)
while k do
context.Feature = nil
chatSequenceNumber = chatSequenceNumber + 1
Logic.translateChatSequence(context, chatSequenceNumber, chatSequence, rtSwitchChatSequence)
k, chatSequence = next(behavior.ChatSequences, k)
end
end
end
function Logic.isWanderActivity(activity)
return activity == "Wander" or activity == "Go To Zone" or activity == "Rest In Zone" or activity == "Feed In Zone"
or activity == "Hunt In Zone" or activity == "Guard Zone"
end
-------------------------------------------------
--create a transition to go to step number stepNb
--set a timer to go to next step
--select the step
--goto the step's state
Logic.createTransition = function(context, hlComponent, activitySequence, activityStep, activityStepIndex, stepAction)
local findChatSequenceIdByInstanceId = function (chat)
local parent = chat.ParentInstance.ChatSequences
assert(parent)
local nbSequence = 0
local k, sequence = next(parent, nil)
while k do
if tostring(sequence.InstanceId) == tostring(chat.InstanceId) then return nbSequence end
nbSequence = nbSequence + 1
k, sequence = next(parent, k)
end
return -1
end
assert(activityStep)
local chat = nil
if activityStep.Chat ~= "" then
chat = r2:getInstanceFromId( tostring(activityStep.Chat) )
end
local code = ""
local backupState = ""
local setChatSequence = ""
local setNextActivity = ""
local setNextActivityTimer = ""
local setNextActivityState = ""
backupState =
"oldChatSequenceVar = " .. Logic.chatSequenceVar .. ";\n" ..
"RoadCountLimit=0;\n"..
"oldActivityStepVar = " .. Logic.activityStepVar .. ";\n" ..
"oldActivityStepVar2 = " .. Logic.activityStepVar.. " + 1;\n"
if chat~= nil then
local id = findChatSequenceIdByInstanceId( chat )
assert(id ~= -1 )
setChatSequence = Logic.chatSequenceVar .. " = " .. tostring( id ) .. ";\n"
if (activityStep.Type == "Repeating") then
setChatSequence = setChatSequence .. "repeatSequence = 1;\n"
else
setChatSequence = setChatSequence .. "repeatSequence = 0;\n"
end
end
-- next activity
setNextActivity = Logic.activityStepVar .. " = " .. activityStepIndex ..";\n"
-- next activity timer
local param = Logic.getTimeLimit(activityStep)
if param ~= nil then
if Logic.isWanderActivity(activityStep.Activity) then
-- The time limite is use by the activity
else
setNextActivityTimer = "()setTimer(" .. param ..", " ..Logic.activityStepTimerId .. ");\n"
end
end
local states = Logic.States[activityStep.InstanceId]
local stateName = states[1].Name
-- next activity state
setNextActivityState = "()postNextState(\"" .. r2.getNamespace() .. stateName .."\");\n"
local action = r2.Translator.createAction("code", backupState .. setChatSequence .. setNextActivity .. setNextActivityTimer .. setNextActivityState)
action.Name = "process_activity_step" .. activityStepIndex
if stepAction then
local tmpAction = r2.Translator.createAction("multi_actions")
table.insert(tmpAction.Children, action)
table.insert(tmpAction.Children, stepAction)
action = tmpAction
end
action.Name = "process_activity_step" .. activityStepIndex
return action
end
------------------------------------------
--cr<63>e une action qui permet de
--s<>lectionner une s<>quence de chat
Logic.selectDialog = function(dialogNb, rtNpcGrp)
local action
local prefix = ""
if (rtNpcGrp ~= nil) then
prefix = r2.getNamespace() .. rtNpcGrp .. "."
end
action = r2.Translator.createAction("code",
prefix .."oldChatSequenceVar =" .. prefix..Logic.chatSequenceVar ..";\n" ..
prefix .. Logic.chatSequenceVar .." = " ..(dialogNb-1)..";\n")
action.Name = "select_dialog"
return action
end
--create the actions and events necessary to choose
--the dialog while running sequence
Logic.initDialog = function(context)
local event = r2.Translator.createEvent("variable_" ..Logic.chatSequenceVar .."_changed", "all_sequence_states", context.Group.Name)
event.Name = "change_dialog_event"
Logic.DialogEvent2 = event
local action
local mAction = r2.Translator.createAction("multi_actions")
action = r2.Translator.createAction("code", "oldChatStepVar = " .. Logic.chatStepVar ..";\n" .. Logic.chatStepVar .." = 0;\n")
action.Name = "reset_dialog"
table.insert(mAction.Children, action)
action = r2.Translator.createAction("switch_actions", Logic.chatSequenceVar)
action.Name = "init_dialog_timer"
table.insert(mAction.Children, action)
Logic.DialogAction2 = action
table.insert(context.RtAct.Events, event)
table.insert(context.RtAct.Actions, mAction)
table.insert(event.ActionsId, mAction.Id)
event = r2.Translator.createEvent("timer_" ..Logic.chatTimer .."_triggered", "all_sequence_states", context.Group.Name)
event.Name = "dialog_event"
Logic.DialogEvent = event
table.insert(context.RtAct.Events, event)
Logic.DialogAction = r2.Translator.createAction("switch_actions", Logic.chatSequenceVar)
table.insert(context.RtAct.Actions, Logic.DialogAction)
table.insert(event.ActionsId, Logic.DialogAction.Id)
end
Logic.initSequence = function(context, rtNpcGrp)
assert(context)
assert(rtNpcGrp)
event = r2.Translator.createEvent("timer_" ..Logic.activityStepTimer .."_triggered", "all_sequence_states", rtNpcGrp.Name)
event.Name = "sequence_event"
Logic.SequenceEvent = event
table.insert(context.RtAct.Events, event)
Logic.SequenceAction = r2.Translator.createAction("switch_actions", Logic.activityStepVar)
table.insert(context.RtAct.Actions, Logic.SequenceAction)
table.insert(event.ActionsId, Logic.SequenceAction.Id)
end
-- ust to implement translateEvents used to implement event created for implementing
Logic.translateEvent = function( context, hlComponent, activitySequence, activityStep, activityStepIndex, event, rtNpcGrp, statesByName)
local chat = nil
-- context, groups, states, actionToAdd)
local eventType, eventParam = Logic.getEvent(event)
local eventHandler = nil
if context.Events[event.InstanceId] == nil
then
eventHandler = r2.Translator.createEvent(eventType, states, groups)
assert(eventHandler ~= nil)
local stepAction = Logic.translateChatStep(context, event.Action, nil)
if actionToAdd ~= nil
then
table.insert(stepAction.Children, actionToAdd)
end
assert(stepAction ~= nil)
table.insert(context.RtAct.Actions, stepAction)
table.insert(eventHandler.ActionsId, stepAction.Id)
context.Events[event.InstanceId] = eventHandler
else
eventHandler = context.Events[event.InstanceId]
if string.find(eventHandler.StatesByName, states) == nil
then
eventHandler.StatesByName = eventHandler.StatesByName .. "\n" .. states
end
if string.find(eventHandler.GroupsByName, groups) == nil
then
eventHandler.GroupsByName = eventHandler.GroupsByName .. "\n" .. groups
end
end
return eventHandler
end
-- translateEvents
Logic.translateEvents = function(context, hlComponent, activitySequence, activityStep, activityStepIndex, rtNpcGrp, statesByName)
local activityStep
local last = nil
if activityStepIndex == activitySequence.Components.Size then
last = true
end
local k, eventId = next(step.EventsIds, nil)
do
local eventHandler = r2:getInstanceFromId(eventId)
assert(eventHandler ~= nil)
local action = nil
if eventHandler.Condition.Type == "At Destination" then
if step.Activity == "Follow Route" and last ~= true then
action = Logic.selectActivityStep(activityStepIndex + 1)
end
end
--the event returned here is a RtNpcEventHandler
event = translateEvent(context, groups, states, action)
assert(event ~= nil)
table.insert(context.RtAct.Events, event)
k, eventId = next(step.EventsIds, k)
end
end
--translate an activity step
Logic.translateActivityStep = function(context, hlComponent, activitySequence, activityStep, activityStepIndex, rtNpcGrp)
--translate this activity activityStep's events
assert(rtNpcGrp)
local aiState
local aiState2
local statesByName
local groupsByName = rtNpcGrp.Name
local zone = nil
local chat = nil
local aiScriptDebug = false
local activityStep = activityStep
if activityStep.Chat ~= "" then
chat = r2:getInstanceFromId(activityStep.Chat)
if not chat then
printErr("translation error: in the activitySequence " .. activitySequence.Name .. " in component " .. hlComponent.Name .. ": " .. " the chat sequence associated to this activity sequence can not be found")
return nil
end
end
local states = Logic.States[activityStep.InstanceId]
--states creation
aiState = states[1] -- 1 is first ( a lua object not a instance )
--setting state AiMovement
aiState.AiMovement = Logic.getAiMovement(activityStep.Activity)
assert(aiState.AiMovement ~= "")
--setting state zone or road
local positionalActivity= {["Patrol"] = "road",
["Wander"] = "zone",
["Repeat Road"] = "road",
["Follow Route"] = "road",
["Rest In Zone"] = "zone",
["Feed In Zone"] = "zone",
["Hunt In Zone"] = "zone",
["Guard Zone"] = "zone",
["Go To Zone"] = "zone",
}
if positionalActivity[activityStep.Activity] then
local zone = r2:getInstanceFromId(activityStep.ActivityZoneId)
if zone == nil then
aiState = states[1]
aiState.AiMovement = "idle"
return aiState
else
if positionalActivity[activityStep.Activity] == "zone" then
if table.getn(zone.Points) < 3 then
aiState = states[1]
aiState.AiMovement = "idle"
return aiState
end
else
if table.getn(zone.Points) < 2 then
aiState = states[1]
aiState.AiMovement = "idle"
return aiState
end
end
end
end
if activityStep.Activity == "Patrol" then
local zone = r2:getInstanceFromId(activityStep.ActivityZoneId)
if (zone == nil)
then
printErr("translation error: in the activitySequence " .. activitySequence.Name .. " in component " .. hlComponent.Name .. ": " .. " the zone associated to the action can not be found")
return nil
end
--un etat aller, un etat retour
aiState2 = states[2]
aiState2.AiMovement = "follow_route"
Logic.assignZone(aiState, zone, false)
Logic.assignZone(aiState2, zone, true)
statesByName = aiState.Name .."\n" .. aiState2.Name
elseif activityStep.Activity == "Repeat Road" or activityStep.Activity == "Follow Route" or activityStep.Activity == "Wander"
or activityStep.Activity == "Rest In Zone" or activityStep.Activity == "Feed In Zone" or activityStep.Activity == "Hunt In Zone"
or activityStep.Activity == "Guard Zone" or activityStep.Activity == "Go To Zone" then
local zone = r2:getInstanceFromId(activityStep.ActivityZoneId)
if (zone == nil) then
printErr("translation error: in the activitySequence " .. activitySequence.Name .. " in component " .. hlComponent.Name .. ": " .. " the zone associated to the action can not be found")
return nil
end
Logic.assignZone(aiState, zone, false)
statesByName = aiState.Name
else
statesByName = aiState.Name
end
if activityStep.Activity == "Repeat Road" then
local action
local event
--when at end of the road, ...
event = r2.Translator.createEvent("destination_reached_all", statesByName, groupsByName)
table.insert(context.RtAct.Events, event)
--return to the start of the road
local repeatCount = activityStep.RoadCountLimit
if not repeatCount then repeatCount = 2 end
action = r2.Translator.createAction("next_road", groupsByName, aiState.Name, activityStepIndex , repeatCount)
table.insert(context.RtAct.Actions, action)
table.insert(event.ActionsId, action.Id)
elseif activityStep.Activity == "Patrol" then
local action
local event
local repeatCount = activityStep.RoadCountLimit
if not repeatCount then repeatCount = 2 end
event = r2.Translator.createEvent("destination_reached_all", aiState.Name, groupsByName)
table.insert(context.RtAct.Events, event)
action = r2.Translator.createAction("next_road", groupsByName, aiState2.Name, activityStepIndex, repeatCount)
action.Name = "return"
table.insert(context.RtAct.Actions, action)
table.insert(event.ActionsId, action.Id)
event = r2.Translator.createEvent("destination_reached_all", aiState2.Name, groupsByName)
table.insert(context.RtAct.Events, event)
action = r2.Translator.createAction("next_road", groupsByName, aiState.Name, activityStepIndex , repeatCount)
action.Name = "go"
table.insert(context.RtAct.Actions, action)
table.insert(event.ActionsId, action.Id)
elseif activityStep.Activity == "Follow Route" or activityStep.Activity == "Go To Start Point" or activityStep.Activity == "Go To Zone" then
local action
local event
event = r2.Translator.createEvent("destination_reached_all", aiState.Name, groupsByName)
table.insert(context.RtAct.Events, event)
action = Logic.selectActivityStep(activityStepIndex + 1)
table.insert(context.RtAct.Actions, action)
table.insert(event.ActionsId, action.Id)
elseif activityStep.Activity == "Rest In Zone" then
local wanderTime = 100
local restTime = 300
r2.Translator.createActivityInZone(context, aiState.Name, groupsByName, "Rest", Logic.activityInternalTimerId, wanderTime, restTime, aiScriptDebug)
elseif activityStep.Activity == "Feed In Zone" then
local wanderTime = 50
local feedTime = 150
r2.Translator.createActivityInZone(context, aiState.Name, groupsByName, "Eat", Logic.activityInternalTimerId, wanderTime, feedTime, aiScriptDebug)
elseif activityStep.Activity == "Hunt In Zone" then
local wanderTime = 100
local alertTime = 25
local eatTime = 80
r2.Translator.createHuntActivityInZone(context, aiState.Name, groupsByName, Logic.activityInternalTimerId, wanderTime, alertTime, eatTime, aiScriptDebug)
elseif activityStep.Activity == "Guard Zone" then
r2.Translator.createSimpleActivityInZone(context, aiState.Name, groupsByName, "Alert", false, aiScriptDebug)
end
if Logic.isWanderActivity(activityStep.Activity) and activityStep.TimeLimit == "Few Sec" then
local event = r2.Translator.createEvent("destination_reached_all", aiState.Name, groupsByName)
table.insert(context.RtAct.Events, event)
local number = tonumber(activityStep.TimeLimitValue)
if number == nil then
number = 0
end
local action = r2.Translator.createAction("wander_destination_reached", groupsByName, aiState.Name, activityStepIndex, number)
table.insert(context.RtAct.Actions, action)
table.insert(event.ActionsId, action.Id)
end
local stepAction = nil
if activityStep.Activity == "Stand Up" then
stepAction = r2.Translator.createAction("stand_up", rtNpcGrp.Id )
elseif activityStep.Activity == "Sit Down" then
stepAction = r2.Translator.createAction("sit_down", rtNpcGrp.Id )
end
-- translate event create by activitySequence (eg patrol)
if activityStep.EventsIds.Size ~= 0
then
Logic.translateEvents(context, hlComponent, activitySequence, activityStep, activityStepIndex, rtNpcGrp, statesByName)
end
--go to next activityStep
local action = Logic.createTransition(context, hlComponent, activitySequence, activityStep, activityStepIndex, stepAction)
table.insert(Logic.SequenceAction.Children, action)
-- if ActivityStep.TimeLimit == "Chat" creates a eventhandler to go to next state
if activityStep.TimeLimit == "Chat" then
local action
local condition
local event
local number = Logic.findChatSequenceIdByInstanceId(hlComponent, chat.InstanceId)
if (number == nil or number == -1) then
printWarning("Error in translation: in component '" .. hlComponent.Name .. " the chat sequence selected as time limit of Activity Step " .. activityStepIndex .. " does not exist.")
end
event = r2.Translator.createEvent("user_event_8", aiState.Name, rtNpcGrp.Id)
table.insert(context.RtAct.Events, event)
condition = r2.Translator.createAction("condition_if", "v0 == "..tostring(number-1))
table.insert(context.RtAct.Actions, condition)
action = Logic.selectActivityStep(activityStepIndex + 1)
table.insert(condition.Children, action)
table.insert(event.ActionsId, condition.Id)
end
assert(State ~= "")
return aiState
end
---------------------------------------------------------------------------------------
--helpers functions--
---------------------------------------------------------------------------------------
Logic.getAiMovement = function(activity)
assert(activity and type(activity) == "string")
if (activity == "Follow Route") or (activity == "Patrol") or (activity == "Repeat Road") then
return "follow_route"
elseif activity == "Deploy" then
return "stand_on_vertices"
elseif activity == "Wander" or activity == "Go To Zone" or activity == "Rest In Zone" or activity == "Feed In Zone"
or activity == "Hunt In Zone" or activity == "Guard Zone" then
return "wander"
elseif activity == "Stand Still" or activity == "Inactive" or activity == "Stand Up" or activity == "Sit Down" then
return "idle"
elseif activity == "Stand On Start Point" or activity == "Go To Start Point" then
return "stand_on_start_point"
end
printWarning("Undef activity '"..activity.."'")
assert(nil)
return ""
end
Logic.getAction = function(action)
local action_type = action.Action
if action_type == "Sit Down"
then
return "sit_down"
end
if action_type == "Stand Up"
then
return "stand_up"
end
if action_type == "Go To Step"
then
if action.Parameter == nil or action.Parameter == ""
then
return nil
end
return "go_to_step"
end
if action_type == "Set Activity"
then
if action.Parameter == nil or action.Parameter == ""
then
return nil
end
return "set_activity"
end
if action_type == "Stop Actions"
then
return "stop_actions"
end
if action_type == "Start Mission"
then
return "start_mission"
end
return nil
end
Logic.getEvent = function(Event)
local i = Logic.find(Logic.EventTypes, Event.Condition.SourceType)
--Time event type
if i == 0
then
end
--place event type
if i == 1
then
end
--entity event type
if i == 2
then
if Event.Condition.Type == "At Destination"
then
return "destination_reached_all"
end
if Event.Condition.Type == "Is Attacked"
then
return "group_under_attack"
end
if Event.Condition.Type == "Enters State"
then
return "start_of_state"
end
if Event.Condition.Type == "Leaves State"
then
return "end_of_state"
end
if Event.Condition.Type == "Activity Is"
then
end
end
--State Machine event type
if i == 3
then
end
--Counter event type
if i == 4
then
local counterName = Event.Parameter
local param
if counterName == nil
then
end
if string.find(Event.Condition.Type, "v%d_changed") ~= nil
then
return "variable_" ..Event.Condition.Type
end
if Event.Condition.Type == "Equals"
then
param = " = "
else
if Event.Condition.Type == "Lesser"
then
param = " < "
else
if Event.Condition.Type == "Greater"
then
param = " > "
else
param = nil
end
end
end
if param == nil
then
return nil
end
param = param ..Event.Condition.ConditionParameter
return "variable_changed", param
end
end
Logic.checkEvent = function(eventMode, sourceType, sourceId, conditionType, parameter)
local eventTypeInd = Logic.find(Logic.EventTypes, sourceType)
local conditionTypeInd
if eventTypeInd == nil
then
return false
end
--{"Time", "Place", "Entity or Group", "State Machine", "Counter"}
conditionTypeInd = Logic.find(Logic.ConditionTypes[eventTypeInd], conditionType)
if eventTypeInd == nil
then
return false
end
--Time event type
if eventTypeInd == 0
then
end
--Place event type
if eventTypeInd == 1
then
end
--Entity or Group event type
if eventTypeInd == 2
then
if parameter == nil or parameter == ""
then
if conditionType == "At Destination" or conditionType == "Is Attacked"
then
return true
else
return false
end
else
if conditionType == "Enters State" or conditionType == "Leaves State"
then
return true
else
return false
end
end
end
--State Machine event type
if eventTypeInd == 3
then
end
--Counter event type
if eventTypeInd == 4
then
if string.find(conditionType, "v%d_changed") ~= nil
then
return true
end
if conditionType == "Lesser" or conditionType == "Greater" or conditionType == "Equals"
then
return true
end
end
return false
end
Logic.fillCondition = function(condition, sourceType, sourceId, conditionType, conditionParameter)
condition.SourceType = sourceType
condition.SourceId = sourceId
condition.Type = conditionType
condition.ConditionParameter = conditionParameter
end
Logic.fillEvent = function(event, eventMode, sourceType, sourceId, conditionType, conditionParameter)
if Logic.checkEvent(eventMode, sourceType, sourceId, conditionType, conditionParameter) == false
then
assert(0)
return false
end
Logic.fillCondition(event.Condition, sourceType, sourceId, conditionType, conditionParameter)
event.EventMode = eventMode
return true
end
-----------------------------------------
--genere le parametre de l'action set_timer
Logic.getTimeLimit = function(step)
local param = ""
if step.TimeLimit == "Few Sec" then
local limit = tonumber(step.TimeLimitValue)
if limit == nil then
limit = 0
end
limit = 1 + limit * 10
param = tostring( limit )
return param
end
return nil
end
Logic.getActivityInitialStateName = function(groupId, activityNb, context)
local group = context.Components[groupId]
local activity = group.Components[1].Behavior.Activities[activityNb]
if activity == nil
then
return nil
end
local activityStates = Logic.ActivitiesStates[activity.InstanceId]
return activityStates[activity.InstanceId][0].Name
end
--return the states used to represent this step activity
Logic.getActivityStepStates = function(activity, stepNb)
local activityStates = Logic.ActivitiesStates[activity.InstanceId]
local states = activityStates[activity.Components[stepNb].InstanceId]
return states
end
Logic.find = function(array, elem)
local i = 0
for k, v in pairs(array)
do
if k ~="Keys"
then
if elem == v
then
return i
end
i = i + 1
end
end
return nil
end
Logic.findChatSequenceIdByInstanceIdImpl = function(instance, instanceId)
local behvior = instance:getBehavior()
local k, sequence = next(behvior.ChatSequences, nil)
local nbSequence = 0
while k do
nbSequence = nbSequence + 1
if tostring(sequence.InstanceId) == instanceId then return nbSequence end
k, sequence = next(behvior.ChatSequences, k)
end
return -1
end
Logic.findChatSequenceIdByInstanceId = function(target, instanceId)
local instance =target
return Logic.findChatSequenceIdByInstanceIdImpl(instance, instanceId)
end
-- target -> hlNpc or hlNpcGrp
Logic.findChatStepIdByInstanceId = function(target, instanceId)
assert( type(target) == "userdata")
local nbSequence = 0
local nbStep = 0
local instance = target
assert(instance ~= nil)
local behavior = instance:getBehavior()
assert(behavior ~= nil)
local k2, sequence = next(behavior.ChatSequences, nil)
while k2 do
nbSequence = nbSequence + 1
nbStep = 0
local k, step = next(sequence.Components, nil)
while k do
nbStep = nbStep +1
if tostring(step.InstanceId) == instanceId then return {nbStep, nbSequence} end
k, step = next(sequence.Components, k)
end
k2, sequence = next(behavior.ChatSequences, k2)
end
assert(0)
return {-1, -1}
end
-- target is a NpcGrp or a Npc or a CustomNpc
Logic.findActivitySequenceIdByInstanceId = function(target, instanceId)
assert( type(target) == "userdata")
local nbSequence = 0
local behavior = nil
behavior = target:getBehavior()
if behavior == nil then
debugInfo("Error: try to find activity Sequence on an unknown entity of type " .. target.Class )
assert(nil)
end
local npc = behavior.ParentInstance
local grp = behavior.ParentInstance.ParentInstance
if not npc:isGrouped() then grp = nil end
local k, sequence = next(behavior.Activities, nil)
while (k ~= nil) do
nbSequence = nbSequence + 1
if sequence.InstanceId == instanceId then
if grp then return {nbSequence, grp} end
if npc then return {nbSequence, npc} end
assert(nil)
end
k, sequence = next(behavior.Activities, k)
end
return {-1, nil}
end
Logic.findActivityStepIdByInstanceId = function(target, instanceId)
assert( type(target) == "userdata")
local nbSequence = 0
local nbStep = 0
local comp = target
local behavior = comp:getBehavior()
local k, sequence = next(behavior.Activities, nil)
while k do
if tostring(sequence.InstanceId) == instanceId then
assert(nil) -- use findActivityStep instead of findactivitySequence
end
nbSequence = nbSequence + 1
nbStep = 0
local k2, step = next(sequence.Components, nil)
while (k2) do
nbStep = nbStep +1
if tostring(step.InstanceId) == instanceId then return {nbStep, nbSequence} end
k2, step = next(sequence.Components, k2)
end
k, sequence = next(behavior.Activities, k)
end
return {-1, -1}
end
Logic.selectActivityStep = function(stepNb)
local action
stepNb = stepNb - 1
action = r2.Translator.createAction("code",
Logic.activityStepVar .. " = " .. stepNb ..";\n"
.. "()setTimer(1, " ..Logic.activityStepTimerId .. ");\n")
action.Name = "select_activity_step " .. stepNb
return action
end
----------------------------------------------------------------------------
-- add a line to the event menu
local component = Logic.Components.ChatSequence
----------------------------------------------------------------------------
-- add a line to the event menu
function component:getLogicTranslations()
local logicTranslations = {
["ApplicableActions"] = {
["starts dialog"] = { menu=i18n.get( "uiR2AA0ChatSeqStart" ):toUtf8(),
text=i18n.get( "uiR2AA1ChatSeqStart" ):toUtf8()},
["stops dialog"] = { menu=i18n.get( "uiR2AA0ChatSeqStop" ):toUtf8(),
text=i18n.get( "uiR2AA1ChatSeqStop" ):toUtf8()},
["starts chat"] = { menu=i18n.get( "uiR2AA0ChatStepStart" ):toUtf8(),
text=i18n.get( "uiR2AA1ChatStepStart" ):toUtf8()},
["continues dialog"] = { menu=i18n.get( "uiR2AA0ChatStepContinue" ):toUtf8(),
text=i18n.get( "uiR2AA1ChatStepContinue" ):toUtf8()},
},
["Events"] = {
["start of dialog"] = { menu=i18n.get( "uiR2Event0ChatSeqStart" ):toUtf8(),
text=i18n.get( "uiR2Event1ChatSeqStart" ):toUtf8()},
["end of dialog"] = { menu=i18n.get( "uiR2Event0ChatSeqEnd" ):toUtf8(),
text=i18n.get( "uiR2Event1ChatSeqEnd" ):toUtf8()},
["start of chat"] = { menu=i18n.get( "uiR2Event0ChatStepStart" ):toUtf8(),
text=i18n.get( "uiR2Event1ChatStepStart" ):toUtf8()},
["end of chat"] = { menu=i18n.get( "uiR2Event0ChatStepEnd" ):toUtf8(),
text=i18n.get( "uiR2Event1ChatStepEnd" ):toUtf8()},
},
["Conditions"] = {
["is in dialog"] = { menu=i18n.get( "uiR2Test0ChatSeq" ):toUtf8(),
text=i18n.get( "uiR2Test1ChatSeq" ):toUtf8()},
["is not in dialog"] = { menu=i18n.get( "uiR2Test0ChatNotSeq" ):toUtf8(),
text=i18n.get( "uiR2Test1ChatNotSeq" ):toUtf8()},
["is in chat"] = { menu=i18n.get( "uiR2Test0ChatStep" ):toUtf8(),
text=i18n.get( "uiR2Test1ChatStep" ):toUtf8()},
}
}
return logicTranslations
end
r2.Features["ActivitySequence"] = Logic