Resolve "Toggle Free Look with Hotkey"
[ryzomcore.git] / ryzom / common / data_common / r2 / r2_translator.lua
blobe1c4701ba49ae6c0c4dbfea28213fe78055e7a3f
3 if r2.Translator == nil
4 then
5 r2.Translator={}
6 end
8 local Translator = r2.Translator
10 Translator.PredatorEnemyFaction = "Player|guard|bandit|herbivore|karavan";
12 -- Namespace global
13 function printMsg(str)
14 messageBox(str)
15 debugInfo(colorTag(255,255,0)..str)
16 local ucStringMsg = ucstring()
17 ucStringMsg:fromUtf8(str)
18 displaySystemInfo(ucStringMsg, "BC")
19 messageBox(str)
20 end
22 function printError( str)
23 local msg = "Translation WRN:"
24 debugInfo(colorTag(255,0,0)..msg..str)
25 -- local ucStringMsg = ucstring()
26 -- ucStringMsg:fromUtf8(str)
27 -- displaySystemInfo(ucStringMsg, "BC")
28 --messageBox(str)
29 assert(nil)
30 end
32 r2.Translator.MultilineBc = {}
34 function Translator.updateEachSecond()
35 if table.getn( Translator.MultilineBc ) > 0 then
36 local msg=table.remove(Translator.MultilineBc, 1)
37 if msg then
38 local ucStringMsg = ucstring()
39 ucStringMsg:fromUtf8(msg)
40 displaySystemInfo(ucStringMsg, "BC")
41 end
42 end
43 end
45 function printMsgML(str)
46 local strs = r2.split(str, "\n")
47 for k,v in pairs(strs) do
48 table.insert(Translator.MultilineBc, v)
49 end
50 end
51 --local devMode = false
52 local devMode = config.R2EDExtendedDebug
53 local dataDevMode = false
55 function printWarning( str)
56 local msg = "Translation Error:"..str
57 debugInfo(colorTag(255,0,0)..msg)
58 -- msg will be displayed when client is back to edition
60 -- Just report the last error
61 if (r2.LastTranslationErrorMsg == nil) then
62 r2.LastTranslationErrorMsg = str
63 local ucStringMsg = ucstring("Translation Error")
64 -- ucStringMsg:fromUtf8(r2.LastTranslationErrorMsg)
65 displaySystemInfo(ucStringMsg, "BC")
66 messageBox(str)
67 end
68 if devMode then
69 assert(nil)
70 else
71 error(str) -- force to exit current translation
72 end
73 end
75 function BOMB_IF(condition, str)
76 if ( not condition) then
77 printWarning(str)
78 end
79 end
81 -- Namespace r2
82 function r2:getScenarioId()
83 local str = r2:getNamespace()
84 str = string.gsub(str, "r2_", "")
85 str = string.gsub(str, "_", "")
86 local sessionId = tonumber(str)
87 return sessionId
88 end
91 function r2:getActId(actIn)
92 assert(actIn)
93 local index = -1
94 local actId, act = next(r2.Scenario.Acts)
95 while actId do
96 index = index + 1
97 if (tostring(act.InstanceId) == tostring(actIn.InstanceId)) then return index end
98 actId, act = next(r2.Scenario.Acts, actId)
101 assert(nil)
102 return -1
106 -- Namespace Translator
107 function Translator.getRtGroup(context, instanceId)
108 assert(context.RtAct)
109 assert( context ~= nil and type(context)=="table")
110 assert( instanceId ~= nil and type(instanceId) == "string")
112 if context.RtGroups[instanceId]==nil
113 then
114 context.RtGroups[instanceId] = r2.newComponent("RtNpcGrp")
115 context.RtGroups[instanceId].Name = context.RtGroups[instanceId].Id
116 table.insert(context.RtAct.NpcGrps, context.RtGroups[instanceId])
118 return context.RtGroups[instanceId]
121 function Translator.getRtStatesNames(context, instanceId)
122 local rtNpcGrp = Translator.getRtGroup(context, instanceId)
124 local statesNames = context.GroupStatesName[rtNpcGrp.Name]
125 return statesNames
128 r2.doTranslateFeatures = function(scenario)
129 return Translator.doTranslateFeatures(scenario.InstanceId)
132 r2.translateFeature = function(context)
133 local component = context.Feature
134 if (component == nil) then return end
136 if component.translate ~= nil then
137 component:translate(context)
142 r2.translateFeatures = function(scenario)
144 local rtScenario = r2.doTranslateFeatures(scenario)
145 r2.requestUpdateRtScenario(rtScenario)
150 -- creat a context (mainly RtComponent)
151 Translator.createContext = function(scenario)
152 local context = {}
153 context.Scenario = scenario
154 context.RtScenario = r2.newComponent("RtScenario")
155 context.TextTranslateId={}
156 context.Feature=scenario -- obsloete to remove
157 context.GroupStatesName = {}
158 context.GroupTriggeredActions = {}
159 context.Events = {}
160 context.ActivityStates = {}
161 context.RtGrps={}
162 context.RtGroups={}
163 context.CounterNames={}
164 context.RtCounters = {}
165 --context.EasterEggUniqId = {} -- RtGrpId to uniqId
166 context.ActIdToRtAct = {}
167 context.InteractingSceneryObjects = {}
168 return context
171 -- return the equipment of a rtNpc by looking at the visual properties of an hlNpc
172 Translator.translateEquipment = function(hlNpc)
173 local instanceId = hlNpc.InstanceId
174 local equipment = ""
175 local instance = r2:getInstanceFromId(instanceId)
177 if instance:isKindOf("NpcCustom") then
178 equipment = equipment..r2.getVisualPropertiesFromInstanceId(instanceId);
181 if equipment == nil then
182 equipment = ""
185 local isFauna = hlNpc.IsFauna
186 if isFauna ~= nil and isFauna == 1 then
187 -- Npc with default name use default translation system name
188 local basename = hlNpc.Base
189 if basename then basename = r2.PaletteIdToTranslation[ basename ] end
190 if basename == nil or basename ~= hlNpc.Name then
191 equipment = equipment .. "FAUNA_BOT_USE_BOTNAME\n"
194 return equipment
197 -- get an rtNpc aiActivity from an hlNpc eg "civil" -> "normal"
198 Translator.getAiActivity = function(hlNpc)
199 assert(hlNpc and type(hlNpc) == "userdata")
200 local aiActivity = hlNpc.AiActivity
201 local profile = hlNpc.Profile
202 local str = "no_change"
204 if profile then return "" end
206 if profile ~= nil then
207 if profile == "bandit" then str = "bandit" end
208 if profile == "guard" then str = "guard" end
209 if profile == "civil" then str = "normal" end
210 elseif aiActivity ~= nil then
211 str = aiActivity
214 return str;
217 -- get rtNpc from hlNpc
218 Translator.translateNpc = function(hlNpc, context)
220 local function findInTable(instanceId)
221 for k, v in pairs(context.InteractingSceneryObjects) do
222 if v == instanceId then return true end
224 return false
228 assert(hlNpc and type(hlNpc) == "userdata")
229 local RtNpc = r2.newComponent("RtNpc")
232 RtNpc.Name = hlNpc.Name
235 RtNpc.SheetClient = hlNpc.SheetClient
238 RtNpc.Sheet = hlNpc.Sheet
239 if RtNpc.Sheet == nil then RtNpc.Sheet = "" end
243 if hlNpc:isBotObject() and context and context.InteractingSceneryObjects
244 and findInTable(hlNpc.InstanceId) then
245 RtNpc.IsStuck = 0
246 RtNpc.Sheet = "object_chest_wisdom_std_sel.creature"
247 else
248 RtNpc.IsStuck = hlNpc.IsStuck
251 RtNpc.Pt = r2.getWorldPos(hlNpc)
252 RtNpc.Angle = hlNpc.Angle
253 RtNpc.Equipment = Translator.translateEquipment(hlNpc)
255 local animProp = 0
256 if not hlNpc:getParentAct():isBaseAct() then
257 animProp = animProp + 1 -- TODO test if default feature
260 if hlNpc.IsBotObject ~= 1 then
261 animProp = animProp + 2 -- Living Creature
264 if hlNpc.IsBotObject ~= 1 and hlNpc.IsPlant ~= 1 then
265 animProp = animProp + 4 -- Controlable creature
268 if hlNpc.IsBotObject ~= 1 and hlNpc.IsNpc == 1 then
269 animProp = animProp + 8 -- Creature that talk
271 RtNpc.DmProperty = animProp
272 return RtNpc
275 -- Behavior: the behavior of the npc (or the leader of an group)
276 -- translate the activitySequences of an npc/group
277 Translator.translateActivities = function (context, hlComponent, behavior, rtNpcGrp, aiActivity)
279 assert(context)
280 assert(hlComponent)
281 assert(behavior)
282 assert(rtNpcGrp)
283 assert(aiActivity)
285 local initFun = Logic.initGroupActivitiesTranslation
286 local translateActivitySequence = Logic.translateActivitySequence
287 --all the states names of all the sequences of this group
288 local statesNames=""
289 local first = true
290 --for each group's activity
291 local activityIndex = 1
293 local firstState =""
294 --creation of the group's initial state
296 local leader = hlComponent
297 if hlComponent:isKindOf("NpcGrpFeature") then
298 if table.getn(hlComponent.Components) >= 0 then
299 leader = hlComponent.Components[0]
300 else
301 leader = nil
305 if table.getn(behavior.Activities) == 0 then
310 -- create initial and only state
311 local aiState = r2.newComponent("RtAiState")
312 statesNames = aiState.Id
313 r2.Utils.setState(context, behavior, aiState)
314 aiState.Name = hlComponent.InstanceId..".init"
315 aiState.AiActivity = aiActivity
316 table.insert(context.RtAct.AiStates, aiState)
317 table.insert(aiState.Children, rtNpcGrp.Id)
318 firstState = aiState.Id
321 else
323 local k, v = next(behavior.Activities, nil)
324 while k do
326 if (v.Class == "ActivitySequence") then
327 initFun(context, hlComponent, v, first, activityIndex, aiActivity, rtNpcGrp)
329 if first then
330 firstState = Logic.StatesByName
332 --translate the activity
333 translateActivitySequence(context, hlComponent, v, activityIndex, rtNpcGrp)
334 statesNames = statesNames..Logic.StatesByName.."\n"
335 activityIndex = activityIndex + 1
336 first = false
337 else
338 error("Error while translating '" .. hlComponent.Name .. "' its " .. tostring(nbActivity) .." ActiviySequence contains an element of type " .. v.Class)
340 k, v = next(behavior.Activities, k)
346 if leader and not leader:isBotObject() then
347 local category = leader.SubCategory
348 local aggro = leader.Aggro
349 if not category then
350 category = leader.Category
353 if category then
354 local event = r2.Translator.createEvent("start_of_state", firstState, rtNpcGrp.Id)
355 table.insert(context.RtAct.Events, event)
356 local action = r2.Translator.createAction("bot_init", rtNpcGrp.Id, category, aggro, leader.BotAttackable, leader.PlayerAttackable)
357 table.insert(context.RtAct.Actions, action)
358 table.insert(event.ActionsId, action.Id)
362 context.GroupStatesName[rtNpcGrp.Name] = statesNames
368 function Translator.initializeFactions(context, leader, rtGrp, aiStateName )
369 if leader and not leader:isBotObject() then
370 local category = leader.SubCategory
371 local aggro = leader.Aggro
372 if not category then
373 category = leader.Category
376 if category then
377 local event = r2.Translator.createEvent("start_of_state", aiStateName, rtGrp.Id)
378 table.insert(context.RtAct.Events, event)
379 local action = r2.Translator.createAction("faction_init", rtGrp.Id, category, aggro, leader.BotAttackable, leader.PlayerAttackable)
380 table.insert(context.RtAct.Actions, action)
381 table.insert(event.ActionsId, action.Id)
386 -- translate an eventHandler defined in the behavior of an npc / group
387 -- used to implement translateEventHandlers
388 Translator.translateEventHandler = function(context, hlNpc, eventHandler, rtNpcGrp)
390 local getName = function(object, optionalName)
391 if optionalName and object.optionalName then return "'"..object.optionalName.."'" end
392 if object.Name then return "'"..object.Name.."'" end
393 if object.InstanceId then return "("..object.InstanceId..")" end
394 return "??"
397 local event = nil
398 local firstCondition = nil
399 local lastCondition = nil
401 local target = nil
404 target = hlNpc
406 if not target then
407 printWarning("Error in component '" .. eventHandler.Name.."'")
410 if tostring(eventHandler.Event.Type) == "" then return nil end
412 if not target.getLogicEvent then
413 local eventName = eventHandler.Name
414 printWarning("The component '" .. target.Name .. "' seem to not be able to handle events '")
418 event, firstCondition, lastCondition = target.getLogicEvent(target, context, eventHandler)
421 if not event then
422 printWarning("Error in '".. target.Name.. "' the Event Handler '".. eventHandler:getName() .. "' don't seem to work because the event '"..eventHandler.Event.Type.."' don't seem to be implemented." )
428 local kCondition, condition = next(eventHandler.Conditions, nil)
429 while kCondition do
432 local conditionEntity = r2:getInstanceFromId(condition.Entity)
433 if condition.Condition.Type ~= "" and conditionEntity then
434 assert(conditionEntity)
435 local firstCondition2, lastCondition2 = conditionEntity:getLogicCondition(context, condition)
437 if not firstCondition2 or not lastCondition2 then
438 printWarning("Unknown Condition '".. condition.Condition.Type .. "' in EventHandler ".. eventHandler:getName().." in component " .. getName(target))
439 return nil
444 if not firstCondition then
445 firstCondition = firstCondition2
446 lastCondition = lastCondition2
447 else
448 table.insert(lastCondition.Children, firstCondition2)
449 lastCondition = lastCondition2
453 kCondition, condition = next(eventHandler.Conditions, kCondition)
457 local firstAction = nil
458 local lastAction = nil
460 if eventHandler.Actions.Size > 0 then
462 local multiAction = nil
463 if eventHandler.Actions.Size > 1 then
464 multiAction = Translator.createAction("multi_actions")
467 local kAction, action = next(eventHandler.Actions, nil)
468 while kAction do
469 local actionEntity = r2:getInstanceFromId(action.Entity)
471 if action.Action.Type ~= "" and actionEntity then
472 local firstAction2, lastAction2 = actionEntity:getLogicAction(context, action)
474 if not firstAction2 or not lastAction2 then
475 printWarning("Unknown Action '".. action.Action.Type .. "' in EventHandler ".. eventHandler:getName().." in component " .. getName(target))
478 if multiAction then
479 table.insert(multiAction.Children, firstAction2)
480 else
481 firstAction = firstAction2
485 kAction, action = next(eventHandler.Actions, kAction)
488 if eventHandler.Actions.Size > 1 then
489 firstAction = multiAction
493 -- if there is actions then the first executed npc_event_handler_action are the dynamic_if from [firstCondition, lastCondition]
494 if lastCondition then
495 table.insert(lastCondition.Children, firstAction)
496 firstAction = firstCondition
499 if event and firstAction then
501 local actInstanceId = eventHandler:getLogicActInstanceId()
503 if (tostring(actInstanceId) == "") then
504 debugInfo("Invalid Multi act action:"..eventHandler:getName())
505 return
510 local rtAct2 = context.ActIdToRtAct[actInstanceId]
511 local rtAct = context.RtAct
512 if rtAct2 ~= rtAct then
513 local baseAct = context.Scenario:getBaseAct()
514 local index = context.Scenario:getActIndex(actInstanceId)
515 if index == -1 then
516 printWarning("Invalid Scenario")
518 local rtNpcGrpBase = r2.Translator.getRtGroup(context, baseAct.InstanceId)
520 local action = Translator.createAction("test_act", rtNpcGrpBase.Id , index)
521 table.insert(action.Children, firstAction)
522 firstAction = action
525 -- insert a npc_event_handler
526 table.insert(rtAct.Events, event) -- TODO use eventHandler->
528 -- insert a npc_event_handler_action
529 table.insert(event.ActionsId, firstAction.Id)
530 table.insert(rtAct.Actions, firstAction)
535 -- translates eventHandlers of a npc/group (eventHandlers are defined in beahvior)
536 Translator.translateEventHandlers = function(context, hlNpc, eventHandlers, rtNpcGrp)
537 assert(rtNpcGrp)
538 assert(context)
539 if (eventHandlers ~= nil) then
540 local k, v = next (eventHandlers, nil)
541 while k do
542 local caller = nil
543 if devMode then
544 caller = function (...) local arg = {...} arg[1](arg[2], arg[3], arg[4], arg[5]) return true end
546 else
547 caller = pcall
549 if not caller(Translator.translateEventHandler, context, hlNpc, v, rtNpcGrp) then
550 local eventType = v.Event.Type
551 if eventType == nil then eventType = "" end
552 local componentName = hlNpc.Name
553 if componentName == nil then componentName = "" end
554 printWarning("Error in event handler '"..eventType.."' In component "..componentName)
556 k, v = next (eventHandlers, k)
557 end
565 -- translate a scenario
566 -- scenarioInstanceId the instanceId of the scenario that will be translated to rtData
567 -- returns rtScenario or nil
568 Translator.doTranslateFeatures = function(scenarioInstanceId)
569 local ok
570 local result
572 r2.LastTranslationErrorMsg = nil
573 ok, result = pcall(Translator.doTranslateFeaturesProtected, scenarioInstanceId)
574 if not ok then
575 printWarning(result)
578 return result
581 function Translator.initStartingActIndex(startingAct)
582 local startingAct = r2.Scenario.User.SelectedActInstanceId
584 local acts = r2.Scenario.Acts
587 local actId, act = next(acts, nil)
588 local actIndex = 0
589 while (actId ~= nil)
591 if startingAct and tostring(act.InstanceId) == startingAct then
592 r2.setStartingActIndex(actIndex )
593 else
594 r2.setStartingActIndex(1)
596 actIndex = actIndex + 1
597 actId, act = next(acts, actId)
600 Translator.doTranslateFeaturesProtected = function(scenarioInstanceId)
601 local scenario = r2:getInstanceFromId(scenarioInstanceId)
602 assert(scenario) -- something is broken elsewhere
603 assert( r2.Features ~= nil )
604 local acts = scenario.Acts
605 local context = Translator.createContext(scenario)
606 local cost = 0
607 local rtScenario = context.RtScenario
608 -----------------------------
609 --elements counting
610 local maxSecondaryActCost = 0
611 local baseActCost = 0
612 local first=true
617 -- Recursive method that call a specific function (ie createGhostComponent, pretranslate) on a component
618 -- and every components it contains. Each component level is treated, so that the function needs to be called
619 -- only once on the toplevel feature.
621 local function recursiveFunctionCall(f,components, param)
622 if (components == nil) then
623 return
625 local k, v = next(components, nil)
626 while k do
627 if v[f] then
628 v[f](v, param)
630 if v.Components then
631 recursiveFunctionCall(f, v.Components, param)
633 if v.SubComponents then
634 recursiveFunctionCall(f, v.SubComponents, param)
637 k, v = next(components, k)
641 local function recursiveTranslate(components, context)
642 if (components == nil) then
643 return
645 local k, v = next(components, nil)
646 while k do
647 context.Feature= v
648 r2.translateFeature(context)
649 if v.Components then
650 recursiveTranslate(v.Components, context)
652 if v.SubComponents then
653 recursiveTranslate(v.SubComponents, context)
655 k, v = next(components, k)
659 local function recursivePretranslate2(components, context)
660 if (components == nil) then
661 return
663 local k, v = next(components, nil)
664 while k do
665 context.Feature= v
666 if v.pretranslate2 then v.pretranslate2(v, context) end
668 if v.Components then
669 recursivePretranslate2(v.Components, context)
671 if v.SubComponents then
672 recursivePretranslate2(v.SubComponents, context)
674 k, v = next(components, k)
679 -- Management of items (Copy from Edition Data to Rt Data)
681 local plotItemId, plotItem = next(scenario.PlotItems, nil)
682 while plotItemId do
684 assert(type(plotItem.SheetId) == "number")
685 assert(type(plotItem.Name) == "string")
686 assert(type(plotItem.Desc) == "string")
687 assert(type(plotItem.Comment) == "string")
689 assert(string.len(plotItem.Name) < 256)
690 assert(string.len(plotItem.Desc) < 256)
691 assert(string.len(plotItem.Comment) < 256)
693 local rtPlotItem = r2.newComponent("RtPlotItem")
694 rtPlotItem.SheetId = plotItem.SheetId
696 rtPlotItem.Description = plotItem.Desc
698 rtPlotItem.Name = plotItem.Name
699 rtPlotItem.Comment = plotItem.Comment
700 table.insert(rtScenario.PlotItems, rtPlotItem)
701 plotItemId, plotItem = next(scenario.PlotItems, plotItemId)
707 -- ghost
709 local actId, act = next(acts, nil)
710 while (actId ~= nil) do
711 local features = act.Features
712 recursiveFunctionCall("createGhostComponents", features, act)
714 actId, act = next(acts, actId)
718 -- pre Translation
721 local actId, act = next(acts, nil)
722 while (actId ~= nil) do
724 local rtAct = r2.newComponent("RtAct")
725 if act.WeatherValue ~=nil and act.ManualWeather == 1 then
726 rtAct.WeatherValue = 1 + act.WeatherValue
727 else
728 rtAct.WeatherValue = 0
730 rtAct.ActDescription = ""
731 rtAct.PreActDescription = ""
733 if act.ShortDescription then
734 rtAct.ActDescription = act.ShortDescription
736 if act.PreActDescription then
737 rtAct.PreActDescription = act.PreActDescription
741 context.RtAct = rtAct
743 context.ActIdToRtAct[act.InstanceId] = rtAct
745 context.Act = act
746 context.RtAct = rtAct
747 local features = act.Features
749 act:pretranslate(context)
750 recursiveFunctionCall("pretranslate", features, context)
754 actId, act = next(acts, actId)
758 -----------------------------
759 --texts translation
760 context.Feature = scenario.Texts
761 r2.Features["TextManager"].Translator(context)
763 --for each act
765 local actId, act = next(acts, nil)
766 while (actId ~= nil) do
767 cost= 0
768 -- debugInfo("Act:: "..act.InstanceId)
770 local rtAct = context.ActIdToRtAct[act.InstanceId]
771 context.RtAct = rtAct
772 context.Act = act
773 table.insert(rtScenario.Acts, rtAct)
776 local activitiesIds = act:getActivitiesIds()
777 --creating states for all the activities of all the groups in this act
778 local k, v = next(activitiesIds, nil)
779 while k do
780 local sequence = r2:getInstanceFromId(v)
781 if sequence and sequence.Components
782 then
783 Logic.createActivityStates(context, sequence)
785 k, v = next(activitiesIds, k)
788 actId, act = next(acts, actId)
791 -- translate activities
794 local actId, act = next(acts, nil)
795 while (actId ~= nil) do
796 local rtAct = context.ActIdToRtAct[act.InstanceId]
797 context.RtAct = rtAct
798 context.Act = act
800 local features = act.Features
801 recursivePretranslate2(features, context)
804 actId, act = next(acts, actId)
808 local first = true
810 actId, act = next(acts, nil)
811 while (actId ~= nil) do
812 local rtAct = context.ActIdToRtAct[act.InstanceId]
813 context.RtAct = rtAct
814 context.Act = act
817 local features = act.Features
820 assert(features ~= nil or actId == "Keys")
822 recursiveTranslate(features, context)
824 context.Feature = act
825 act:translate(context);
826 -- scenario
827 if first then
828 first = false
829 context.Feature = scenario
830 scenario:translate(context);
833 actId, act = next(acts, actId)
839 -- Location Id
840 local locationId, location = next(scenario.Locations)
841 local locationIndex = 0
842 local locationMap = {}
844 locationMap[""] = 0
846 while locationId do
847 local rtLocation =r2.newComponent("RtLocation")
848 rtLocation.Island = location.IslandName
849 rtLocation.EntryPoint = location.EntryPoint
850 local enumToInt = {Automatic=0, Spring=1, Summer=2, Autumn=3, Winter=4}
851 rtLocation.Season = enumToInt[ location.Season ]
852 locationMap[location.InstanceId] = locationIndex
854 table.insert(rtScenario.Locations, rtLocation)
855 locationIndex = locationIndex + 1
856 locationId, location = next(scenario.Locations, locationId)
859 local startingAct = r2.Scenario.User.SelectedActInstanceId
862 -- Act Name, position
863 local actId, act = next(acts, nil)
864 local actIndex = 0
865 while (actId ~= nil)
868 local rtAct = context.ActIdToRtAct[act.InstanceId]
869 rtAct.Name = act.Name
871 rtAct.LocationId = locationMap[ act.LocationId ]
873 if startingAct and tostring(act.InstanceId) == startingAct then
874 r2.setStartingActIndex(actIndex )
875 else
876 r2.setStartingActIndex(1)
878 actIndex = actIndex + 1
879 actId, act = next(acts, actId)
881 -- Ring accss
882 if ( r2.getMustVerifyRingAccessWhileLoadingAnimation()) then
884 local ok, level, err = r2.RingAccess.verifyScenario()
885 r2.updateScenarioAck(ok, level, err.What)
888 local ok, err = r2.RingAccess.verifyRtScenario(rtScenario)
889 if not ok then
890 printWarning(err.What)
894 -- inspect(rtScenario)
895 return rtScenario
898 -- Returns a RtNpcEventHandlerAction if the action is allowed
899 --first parameter: action type
900 Translator.createAction = function(...)
901 local arg = {...}
902 local debug=config.R2EDExtendedDebug
903 local function header(toto)
905 if debug then
906 return "print(\"<"..toto..">\");\n"
908 return "//"..toto
911 local function footer(toto)
913 if debug then
914 return "print(\"</"..toto..">\");\n"
916 return ""
920 local action = r2.newComponent("RtNpcEventHandlerAction")
921 local actionType = arg[1]
922 action.Action = actionType
923 action.Name = actionType
925 if actionType == "test_act" then
926 assert(type(arg[2])=="string")
927 assert(type(arg[3])=="number")
928 local rtGrpId = arg[2] -- scenario
929 local actId = arg[3] -- actId
931 local prefix = ""
932 if rtGrpId and rtGrpId ~= "" then
933 prefix = r2:getNamespace() .. rtGrpId.."."
936 action.Action = "dynamic_if"
937 action.Parameters = prefix.."CurrentAct == "..tostring(actId)
938 return action
941 if actionType == "wander_destination_reached" then
942 assert(type(arg[2])=="string")
943 assert(type(arg[3])=="string")
944 assert(type(arg[4])=="number")
945 assert(type(arg[5])=="number")
947 local rtGrpId = arg[2]
948 local states = arg[3]
949 local nextStep = arg[4]
950 local time = arg[5]
952 local prefix = ""
953 if rtGrpId and rtGrpId ~= "" then
954 prefix = r2:getNamespace() .. rtGrpId.."."
957 action.Action = "code"
959 action.Parameters =
960 "v2 = ".. nextStep..";\n" ..
961 "()setTimer("..1+ 10*time..", 0);\n"
964 return action
966 if actionType == "next_road" then
967 assert(type(arg[2])=="string")
968 assert(type(arg[3])=="string")
969 assert(type(arg[4])=="number")
970 assert(type(arg[5])=="string")
972 action.Action = "code"
974 local paramCount = tonumber(arg[5])
975 if paramCount == nil then
976 paramCount = "0"
978 paramCount = tostring(paramCount)
980 action.Parameters =
981 [[//next_road
982 if ( ParamRepeatCount == 0 || ParamGroup.RoadCountLimit < ParamRepeatCount - 1) {
983 if ( ParamRepeatCount != 0) { ParamGroup.RoadCountLimit = ParamGroup.RoadCountLimit + 1; }
984 ()ParamGroup.postNextState("ParamState");
985 } else {
986 ParamGroup.RoadCountLimit = 0;
987 ParamGroup.v2 = ParamActivityIndex;
988 ()ParamGroup.setTimer(1, 0);
992 action.Parameters = string.gsub(action.Parameters, "ParamGroup", r2:getNamespace() .. tostring(arg[2]))
993 action.Parameters = string.gsub(action.Parameters, "ParamState", r2:getNamespace() .. tostring(arg[3]))
994 action.Parameters = string.gsub(action.Parameters, "ParamActivityIndex", tostring(arg[4]))
995 action.Parameters = string.gsub(action.Parameters, "ParamRepeatCount", paramCount)
999 return action
1003 if actionType == "trigger_zone_min_player" then
1004 assert(type(arg[2])=="string")
1005 assert(type(arg[3])=="string")
1006 assert(type(arg[4])=="number")
1007 local rtGrpId = arg[2]
1008 local states = arg[3]
1009 local nbMinPlayer = arg[4]
1012 local prefix = ""
1013 if rtGrpId and rtGrpId ~= "" then
1014 prefix = r2:getNamespace() .. rtGrpId.."."
1017 action.Action = "dynamic_if"
1018 if nbMinPlayer == 0 then
1019 action.Parameters = prefix.."Active == 1 && "..prefix.."NbPlayer == 0"
1020 else
1021 action.Parameters = prefix.."Active == 1 && "..prefix.."NbPlayer >= "..tostring(nbMinPlayer)
1024 return action
1028 if actionType == "on_player_arrived_impl" then
1029 assert(arg[2])
1031 local rtGrpId = arg[2]
1032 local prefix = ""
1033 if rtGrpId and rtGrpId ~= "" then
1034 prefix = r2:getNamespace() .. rtGrpId.."."
1038 action.Parameters = header(actionType)..
1039 "if ( "..prefix.."Active == 1 )\n{\n"..
1040 "\tif ( "..prefix.."Cyclic == 1 )\n"..
1041 "\t{\n"..
1042 "\t\t"..prefix.."Enter = 0 ;\n" ..
1043 "\t\t()"..prefix.."setEvent(1);\n" ..
1044 "\t}\n"..
1045 "\telse if ( "..prefix.."Enter == 1 )\n"..
1046 "\t{\n"..
1047 "\t\t"..prefix.."Enter = 0;\n"..
1048 "\t\t".."()"..prefix.."setEvent(1);\n" ..
1049 "\t}\n" ..
1050 "}\n"..
1051 footer(actionType)
1053 action.Action = "code"
1054 return action
1057 if actionType == "on_player_left_impl" then
1058 assert(arg[2])
1060 local rtGrpId = arg[2]
1061 local prefix = ""
1062 if rtGrpId and rtGrpId ~= "" then
1063 prefix = r2:getNamespace() .. rtGrpId.."."
1067 action.Parameters = header(actionType)..
1068 "if ( "..prefix.."Active == 1 )\n{\n"..
1069 "\tif ( "..prefix.."Cyclic == 1 )\n"..
1070 "\t{\n"..
1071 "\t\t"..prefix.."Leave = 0 ;\n" ..
1072 "\t\t()"..prefix.."setEvent(2);\n" ..
1073 "\t}\n"..
1074 "\telse if ( "..prefix.."Leave == 1 )\n"..
1075 "\t{\n"..
1076 "\t\t"..prefix.."Leave = 0;\n"..
1077 "\t\t".."()"..prefix.."setEvent(2);\n" ..
1078 "\t}\n" ..
1080 ..footer(actionType)
1082 action.Action = "code"
1083 return action
1085 if actionType == "trigger_zone_init" then
1086 assert(arg[2])
1087 assert(arg[3])
1088 assert(arg[4])
1089 local rtGrpId = arg[2]
1090 local auto = arg[3]
1091 local cyclic = arg[4]
1092 local prefix = ""
1093 if rtGrpId and rtGrpId ~= "" then
1094 prefix = r2:getNamespace() .. rtGrpId.."."
1098 action.Parameters = header(actionType)..
1099 "\t"..prefix.."Active = ".. auto .." ;\n" ..
1100 "\t"..prefix.."Leave = ".. auto .." ;\n" ..
1101 "\t"..prefix.."Enter = ".. auto .." ;\n" ..
1102 "\t"..prefix.."Cyclic = "..tostring(cyclic).." ;\n" ..
1103 "if ("..prefix.."Active == 1)\n"..
1104 "{\n"..
1105 "\t()"..prefix.."setEvent(4);\n" ..
1106 "}\n"..
1107 footer(actionType)
1109 action.Action = "code"
1110 return action
1113 if actionType == "trigger_zone_activates" then
1114 assert(arg[2])
1116 local rtGrpId = arg[2]
1117 local prefix = ""
1118 if rtGrpId and rtGrpId ~= "" then
1119 prefix = r2:getNamespace() .. rtGrpId.."."
1123 action.Parameters = header(actionType)..
1124 "if (" ..prefix.."Active == 1)\n"..
1125 "{"..
1126 "\t ()" ..prefix.."setEvent(4);\n"..
1127 "}\n"..
1128 "else\n"..
1129 "{\n"..
1130 "\t"..prefix.."Active = 1 ;\n" ..
1131 "\t"..prefix.."Leave = 1 ;\n" ..
1132 "\t"..prefix.."Enter = 1 ;\n" ..
1133 "()"..prefix.."setEvent(4);\n" ..
1134 "}\n"..
1135 footer(actionType)
1137 action.Action = "code"
1138 return action
1141 if actionType == "trigger_zone_deactivates" then
1142 assert(arg[2])
1144 local rtGrpId = arg[2]
1145 local prefix = ""
1146 if rtGrpId and rtGrpId ~= "" then
1147 prefix = r2:getNamespace() .. rtGrpId.."."
1151 action.Parameters = header(actionType)..
1152 "\t"..prefix.."Active = 0 ;\n" ..
1153 "\t"..prefix.."Leave = 0;\n" ..
1154 "\t"..prefix.."Enter = 0;\n" ..
1155 "()"..prefix.."setEvent(5);\n" ..
1156 footer(actionType)
1158 action.Action = "code"
1159 return action
1162 if actionType == "act_starts" then
1163 assert(arg[2])
1164 assert(arg[3])
1165 assert( type(arg[4]) == "number")
1167 local rtGrpId = arg[2]
1168 local prefix = ""
1169 if rtGrpId and rtGrpId ~= "" then
1170 prefix = r2:getNamespace() .. rtGrpId.."."
1174 local rtGrpId2 = arg[3]
1175 local prefix2=""
1176 if rtGrpId2 and rtGrpId2 ~= "" then
1177 prefix2 = r2:getNamespace() .. rtGrpId2.."."
1181 action.Parameters = header(actionType)..
1182 "()"..prefix.."setTimer(50,0);\n" .. -- act start in 1 second
1183 prefix2.."CurrentAct = " .. tostring( arg[4] ) .. ";\n" ..
1184 "if ( "..prefix2.."v0 == 0 )\n" ..
1185 "{\n"..
1186 "\t()"..prefix2.."setTimer(50,0);\n"..
1187 "\t"..prefix2.."v0 = 0;\n"..
1188 "\t()"..prefix2.."setTimer(150, 1);\n"..
1189 "\t"..prefix2.."ScenarioPoints = 0;\n"..
1190 "}\n"..
1192 footer(actionType)
1194 action.Action = "code"
1195 return action
1198 if actionType == "random_chest_activate" then
1199 local rtGrpId = arg[2]
1200 local prefix = ""
1201 if rtGrpId and rtGrpId ~= "" then
1202 prefix = r2:getNamespace() .. rtGrpId.."."
1204 local eggId =tostring( tonumber(arg[3]))
1205 local actId =tostring( tonumber(arg[4]))
1206 local x = tostring(tonumber(arg[5]))
1207 local y = tostring(tonumber(arg[6]))
1208 local z = tostring(tonumber(arg[7]))
1209 local scenario = tostring( r2:getScenarioId())
1211 local item1Weight = arg[8]
1212 local item1Id = arg[9]
1213 local item1Qty = arg[10]
1214 local item1Str = ""
1215 if item1Id and item1Id ~= "" then
1216 item1Str = tostring(item1Id)..":"..tostring(item1Qty)
1219 local item2Weight = arg[11]
1220 local item2Id = arg[12]
1221 local item2Qty = arg[13]
1222 local item2Str = ""
1223 if item2Id and item2Id ~= "" then
1224 item2Str = tostring(item2Id)..":"..tostring(item2Qty)
1227 local item3Weight = arg[14]
1228 local item3Id = arg[15]
1229 local item3Qty = arg[16]
1230 local item3Str = ""
1231 if item3Id and item3Id ~= "" then
1232 item3Str = tostring(item3Id)..":"..tostring(item3Qty)
1235 local name = arg[17]
1237 local sum12 = tostring(item1Weight + item2Weight)
1238 local sum123 = tostring(item1Weight + item2Weight + item3Weight)
1240 action.Parameters = "//random_chest_activate\n"
1241 .."(" ..prefix.."r)rndm(0,100);\n"
1242 .."if (" ..prefix.. "r > 0 && "..prefix.."r <= "..tostring(item1Weight)..")\n"
1243 .."{\n\t"
1244 .."()"..prefix.."activateEasterEgg(" .. eggId .. ", " .. scenario .."," .. actId .. ", \"" .. item1Str.. "\", " .. x.. ", " .. y.. ", " .. z .. ", 0, \""..r2:getNamespace() .. rtGrpId.."\", \""..name.."\", \"\");\n"
1245 .."}\n"
1246 .."if (" ..prefix.. "r > "..item1Weight.." && "..prefix.."r <= "..sum12..")\n"
1247 .."{\n\t"
1248 .."()"..prefix.."activateEasterEgg(" .. eggId .. ", " .. scenario .."," .. actId .. ", \"" .. item2Str.. "\", " .. x.. ", " .. y.. ", " .. z .. ", 0, \""..r2:getNamespace() .. rtGrpId.."\", \""..name.."\", \"\");\n"
1249 .."}\n"
1250 .."if (" ..prefix.. "r > "..sum12.." && "..prefix.."r <= "..sum123..")\n"
1251 .."{\n\t"
1252 .."()"..prefix.."activateEasterEgg(" .. eggId .. ", " .. scenario .."," .. actId .. ", \"" .. item3Str.. "\", " .. x.. ", " .. y.. ", " .. z .. ", 0, \""..r2:getNamespace() .. rtGrpId.."\", \""..name.."\", \"\");\n"
1253 .."}\n"
1254 .."()"..prefix.."setEvent(4);\n"
1255 action.Action = "code"
1256 return action
1261 if actionType == "easter_egg_activate" then
1262 local rtGrpId = arg[2]
1263 local prefix = ""
1264 if rtGrpId and rtGrpId ~= "" then
1265 prefix = r2:getNamespace() .. rtGrpId.."."
1268 local eggId =tostring( tonumber(arg[3]))
1269 local actId =tostring( tonumber(arg[4]))
1271 local items = tostring(arg[5])
1272 local x = tostring(tonumber(arg[6]))
1273 local y = tostring(tonumber(arg[7]))
1274 local z = tostring(tonumber(arg[8]))
1275 local heading = tostring(tonumber(arg[9]))
1276 local name = tostring(arg[10])
1277 if not name then name = "" end
1278 local look = arg[11]
1279 if not look then look = "" end
1280 local scenario =tostring( r2:getScenarioId())
1284 assert(eggId and scenario and items and x and y and z)
1285 if not heading then heading = tostring(0) end
1287 action.Parameters = "//"..actionType.."\n" ..
1288 "()"..prefix.."activateEasterEgg(" .. eggId .. ", " .. scenario .."," .. actId .. ", \"" .. items.. "\", " .. x.. ", " .. y.. ", " .. z .. "," .. heading .. ", \""..r2:getNamespace() .. rtGrpId.."\", \"".. name .."\", \"".. look .."\");\n"..
1289 "()"..prefix.."setEvent(4);\n"
1290 action.Action = "code"
1291 return action
1294 if actionType == "easter_egg_deactivate" then
1295 local rtGrpId = arg[2]
1296 local prefix = ""
1297 if rtGrpId and rtGrpId ~= "" then
1298 prefix = r2:getNamespace() .. rtGrpId.."."
1301 local eggId =tostring( tonumber(arg[3]))
1302 local actId =tostring( tonumber(arg[4]))
1303 local scenario =tostring( r2:getScenarioId())
1304 assert(eggId and scenario)
1306 action.Parameters = "//"..actionType.."\n" ..
1307 "()"..prefix.."deactivateEasterEgg(" .. eggId .. ", " .. scenario.. "," .. actId..");\n"..
1308 "()"..prefix.."setEvent(5);\n"
1311 action.Action = "code"
1312 return action
1315 if actionType == "dialog_starts" then
1316 local rtGrpId = arg[2]
1317 local prefix = ""
1318 if rtGrpId and rtGrpId ~= "" then
1319 prefix = r2:getNamespace() .. rtGrpId.."."
1321 action.Parameters=
1322 "//"..actionType.."\n" ..
1323 ""..prefix.."start=1;\n" ..
1324 ""..prefix.."v1=0;\n" .. -- intial time before start of dialog is kind of long because we don't want in a start of state that the targeted npc don't exist
1325 "()"..prefix.."setTimer(10, ".. Logic.chatTimerId ..");\n" ..
1326 "()"..prefix.."setEvent(1);" .. "\t//start of dialog\n"
1328 action.Action = "code"
1329 return action
1332 if actionType == "dialog_continues" then
1333 local rtGrpId = arg[2]
1334 local prefix = ""
1335 if rtGrpId and rtGrpId ~= "" then
1336 prefix = r2:getNamespace() .. rtGrpId.."."
1338 action.Parameters=
1339 "//"..actionType.."\n" ..
1340 "if ("..prefix.."break == 1) {\n" ..
1341 "\t()"..prefix.."setTimer(1, ".. Logic.chatTimerId ..");\n" ..
1342 "}\n"
1344 action.Action = "code"
1345 return action
1349 if actionType == "chat_starts" then
1350 local rtGrpId = arg[2]
1351 local prefix = ""
1352 if rtGrpId and rtGrpId ~= "" then
1353 prefix = r2:getNamespace() .. rtGrpId.."."
1355 assert(type(arg[3]) == "number")
1356 local index = tonumber(arg[3])
1357 action.Parameters=
1358 "//"..actionType.."\n" ..
1359 ""..prefix.."start=1;\n" ..
1360 ""..prefix.."v1=".. tostring(index+1)..";\n" ..
1361 "()"..prefix.."setTimer(1, ".. Logic.chatTimerId ..");\n"
1363 action.Action = "code"
1364 return action
1368 if actionType == "dialog_stops" then
1369 local rtGrpId = arg[2]
1370 local prefix = ""
1371 if rtGrpId and rtGrpId ~= "" then
1372 prefix = r2:getNamespace() .. rtGrpId.."."
1374 action.Parameters=
1375 "//"..actionType.."\n" ..
1376 ""..prefix.."start=0;\n" ..
1377 "()"..prefix.."setEvent(2);" .. "\t//end of dialog\n"
1379 action.Action = "code"
1380 return action
1383 if actionType == "dialog_deactivate" then
1384 local rtGrpId = arg[2]
1385 local prefix = ""
1386 if rtGrpId and rtGrpId ~= "" then
1387 prefix = r2:getNamespace() ..rtGrpId.."."
1389 action.Parameters = prefix.."start = 0;\n"
1390 ..prefix.."Active = 0;\n"
1392 action.Action = "code"
1393 return action
1396 if actionType == "dialog_init" then
1397 local rtGrpId = arg[2]
1398 local prefix = ""
1399 if rtGrpId and rtGrpId ~= "" then
1400 prefix = r2:getNamespace() .. rtGrpId.."."
1403 local mustRepeat = tonumber(arg[3])
1404 local autoStart = tonumber(arg[4])
1405 assert(mustRepeat)
1407 action.Parameters=
1408 "//"..actionType.."\n" ..
1409 ""..prefix.."repeat=".. mustRepeat..";\n"..
1410 ""..prefix.."AutoStart=".. autoStart..";\n"
1411 --.."()"..prefix.."setEvent(5); // spawned\n"
1413 action.Action = "code"
1414 return action
1419 if actionType == "chat_step_first" then
1420 local rtGrpId = arg[2]
1421 local prefix = ""
1422 if rtGrpId and rtGrpId ~= "" then
1423 prefix = r2:getNamespace() .. rtGrpId.."."
1426 local initialWait = tonumber(arg[3])
1427 assert(initialWait)
1428 action.Parameters =
1429 "//"..actionType.."\n" ..
1430 prefix .. Logic.chatStepVar .. " = 1;\n" ..
1431 "()"..prefix.."setTimer("..tostring(initialWait*10+1) ..", ".. Logic.chatTimerId ..");\n" ..
1432 "()"..prefix.."setEvent(3);" .. "\t//start of chat\n"
1434 action.Action = "code"
1435 return action
1440 if actionType == "chat_step_last" then
1441 local rtGrpId = arg[2]
1442 local prefix = ""
1443 if rtGrpId and rtGrpId ~= "" then
1444 prefix = r2:getNamespace() .. rtGrpId .. "."
1446 local nbParam = arg[3]
1447 assert(nbParam and type(nbParam) == "number")
1449 action.Parameters =
1450 "//"..actionType.."\n" ..
1451 prefix..Logic.chatStepVar .. "="..tostring(1+nbParam)..";\n" .. --set because of setEvent
1452 "()"..prefix.."setEvent(4);\n" ..
1453 "if ("..prefix.."repeat == 1) {\n" ..
1454 "\t"..prefix.."start=1;\n" ..
1455 "\t"..prefix..Logic.chatStepVar .. "=0;\n" ..
1456 "\t()"..prefix.."setTimer(4, ".. Logic.chatTimerId ..");\n"..
1457 "\t()"..prefix.."setEvent(2);" .. "\t//end of dialog\n" ..
1458 "\t()"..prefix.."setEvent(1);" .. "\t//start of dialog\n" ..
1459 "} else {\n" ..
1460 "\t"..prefix.."start=0;\n" ..
1461 "\t()"..prefix.."setEvent(2);" .. "\t//end of dialog\n" ..
1462 "}\n"
1464 action.Action = "code"
1465 return action
1468 if actionType == "chat_step" then
1469 local rtGrpId = arg[2]
1470 local prefix = ""
1471 if rtGrpId and rtGrpId ~= "" then
1472 prefix = r2:getNamespace() .. rtGrpId.."."
1475 local param = arg[3]
1476 assert(type(param) == "table")
1479 --local m_action = action
1480 --m_action.Action = "multi_actions"
1482 local say =""
1483 local emote=""
1484 local facing=""
1486 local startChat = "()"..prefix.."setTimer(2, 0);\n \n" -- timer 0.4 in on seconde
1487 -- create facing action
1488 if param.Facing ~= "" and param.Facing ~= nil and param.Who ~=nil
1489 then
1490 facing = "//facing\n" ..
1491 "(@group1)"..r2:getNamespace()..param.WhoGrp..".context();\n"
1492 .. "(@group2)"..r2:getNamespace()..param.FacingGrp..".context();\n"
1493 .. "()"..r2:getNamespace()..rtGrpId..".facing(@group1,\""..param.Who.."\", @group2, \"".. param.Facing.."\");\n \n"
1494 startChat = "()"..prefix.."setTimer(10, 0);\n \n" -- timer 0.4 in on seconde
1499 local mustBreak = prefix.."break = "..tostring(param.Break)..";\n"
1500 if param.Break == 0 then
1501 mustBreak = mustBreak..
1502 "()"..prefix.."setTimer(" .. tostring(4+10*tonumber(param.Time)).. ", ".. Logic.chatTimerId ..");\n\n"
1503 else
1504 mustBreak = mustBreak .."\n"
1508 -- local action = r2.newComponent("RtNpcEventHandlerAction")
1509 action.Action = "code"
1510 action.Parameters =
1511 "//"..actionType.." - ChatStep ".. tostring(param.Index).." \n" ..
1512 prefix.."step = " .. tostring(param.Index) ..";\n \n"..
1513 say..facing..emote..
1515 "//set next chat step\n" ..
1516 mustBreak ..
1517 prefix .. Logic.chatStepVar .. " = " .. param.Index .. " + 1;\n \n" ..
1519 startChat..
1520 "()"..prefix.."setTimer(25, 2);\n \n".. -- timer 0.9 in on seconde
1521 "//End of dialog\n"..
1522 "()"..prefix.."setEvent(4);\n \n"
1523 -- table.insert(m_action.Children, action)
1528 return action
1533 if actionType == "chat_step_end" then
1535 local rtGrpId = arg[2]
1536 local prefix = ""
1537 if rtGrpId and rtGrpId ~= "" then
1538 prefix = r2:getNamespace() .. rtGrpId.."."
1541 local param = arg[3]
1542 assert(type(param) == "table")
1544 local baseActRtGrpId = arg[4]
1545 assert(type(baseActRtGrpId) == "string")
1547 if (table.getn(param.Emotes) == 0) then return nil end
1550 local code =
1551 "// lauch emote at end of chat step\n \n" ..
1552 "if ("..prefix.."start == 1)\n" ..
1553 "{\n"..
1554 "\tswitch ( ".. prefix.."step )\n"..
1555 "\t{\n"
1557 local i = 0
1558 local n = table.getn(param.Emotes)
1559 while i ~= n do
1560 i = i +1
1563 if param.WhoNoEntitys[i] == "_System" or param.WhoNoEntitys[i] == "_DM" then
1564 local say = ""
1565 who = "System"
1567 local msg = param.Says[i]
1568 if not msg then msg = "" end
1570 if param.WhoNoEntitys[i] == "_DM" then
1572 say = "\t\t\t" .. "()".. r2:getNamespace() .. baseActRtGrpId .. ".dssMessage( "..tostring(r2:getScenarioId()) .. ", "
1573 .."\"DM\", \"".. who.. "\", \"" .. msg .. "\");\n \n"
1575 else
1576 --avoid to display "system :" when a system msg is broadcasted
1577 who = ""
1578 say = "\t\t\t" .. "()".. r2:getNamespace() .. baseActRtGrpId .. ".dssMessage( "..tostring(r2:getScenarioId()) .. ", "
1579 .."\"SYS\", \"".. who.. "\", \"" .. msg .. "\");\n \n"
1582 code = code ..
1583 "\t\t".. "case "..param.Indexs[i].." :\n" ..
1584 "\t\t".. "{\n" ..
1585 say ..
1586 "\t\t".. "}\n \n"
1588 elseif rtGrpId and param.Whos[i] and param.Whos[i] ~= "" and param.Grps[i] and param.Grps[i] ~= "" then
1589 local say = ""
1590 if param.Says[i] ~= nil and param.Says[i] ~= "" then
1591 say = "\t\t\t" .. "()".. r2:getNamespace() .. rtGrpId .. ".npcSay(@group,\"" .. param.Whos[i] .. "\", \"DSS_" .. tostring(r2:getScenarioId()) .. " " .. param.Says[i] .. "\");\n \n"
1594 local emote = ""
1595 if param.Emotes[i] ~= "" and param.Emotes[i] ~= nil then
1596 local behaviorValue = r2.getEmoteBehaviorFromEmoteId(param.Emotes[i])
1597 emote = "\t\t\t" .. "()"..r2:getNamespace()..rtGrpId..".emote(@group,\""..param.Whos[i].."\", \""..behaviorValue.."\");\n"
1602 code = code ..
1603 "\t\t".. "case "..param.Indexs[i].." :\n" ..
1604 "\t\t".. "{\n" ..
1605 "\t\t\t" .. "(@group)".. r2:getNamespace() .. param.Grps[i] .. ".context();\n \n" ..
1606 say ..
1607 emote ..
1608 "\t\t".. "}\n \n"
1613 code = code .. "\t}\n}"
1616 action.Action = "code"
1617 action.Parameters = code
1619 return action
1623 --BROADCAST
1624 if actionType == "broadcast_msg" then
1625 local baseActRtGrpId = arg[2]
1626 assert(baseActRtGrpId)
1627 assert(type(baseActRtGrpId) == "string")
1629 local msg = arg[3]
1630 assert(msg)
1631 assert(type(msg) == "string")
1633 local who = ""
1635 action.Parameters = "()".. r2:getNamespace() .. baseActRtGrpId .. ".dssMessage( "..tostring(r2:getScenarioId()) .. ", "
1636 .."\"SYS\", \"".. who.. "\", \"" .. msg .. "\");\n"
1638 action.Action = "code"
1639 return action
1642 --QUEST ACTIONS
1643 if actionType == "validate_quest_step" then
1644 local questRtGrpId = arg[2]
1645 local prefix = ""
1646 if questRtGrpId and questRtGrpId ~= "" then
1647 prefix = r2:getNamespace() .. questRtGrpId.."."
1650 local taskRtIds = arg[3]
1651 local nbTasks = table.getn(taskRtIds)
1653 action.Parameters =
1655 if (]] ..prefix.. [[v2 != 0)
1657 switch(]] ..prefix.. [[v2)
1661 --the case (1) never happens : when the quest begins and when the first task is completed, the step index
1662 --is incremented before the action "validate_quest_step"
1664 local i
1665 for i = 2, nbTasks do
1666 action.Parameters = action.Parameters..
1668 case ]] ..tostring(i).. [[ :
1670 if (]]..taskRtIds[i - 1]..[[Active == 1)
1672 ]]..taskRtIds[i - 1]..[[Active = 0;
1673 ()]]..taskRtIds[i - 1]..[[setEvent(5);
1675 ()]] ..taskRtIds[i].. [[setEvent(7);
1676 ]] ..taskRtIds[i].. [[Active = 1;
1677 ()]] ..taskRtIds[i].. [[setEvent(4);
1682 --last task
1683 action.Parameters = action.Parameters..
1685 //default is only used by the last step of the quest
1686 case ]]..tostring(nbTasks + 1) ..[[ :
1688 if (]]..taskRtIds[nbTasks]..[[Active == 1)
1690 ]]..taskRtIds[nbTasks]..[[Active = 0;
1691 ()]]..taskRtIds[nbTasks]..[[setEvent(5);
1693 //if the quest is repeatable
1694 if (]] ..prefix.. [[v1 == 1)
1696 //resetting the index to 1 for first quest step
1697 ]] ..prefix.. [[v2 = 1;
1698 //()]] ..taskRtIds[1].. [[setEvent(7);
1699 ]] ..taskRtIds[1].. [[Active = 1;
1700 ()]] ..taskRtIds[1].. [[setEvent(4);
1702 else
1704 ]] ..prefix.. [[v2 = 0;
1706 ()]] ..prefix.. [[setEvent(8);
1708 } //!switch
1709 } //!if
1712 action.Action = "code"
1714 return action
1719 if actionType == "increment_quest_step_index" then
1720 local currentNamespace = r2:getNamespace()
1722 local questRtGrpId = arg[2]
1723 local prefix = ""
1724 if questRtGrpId and questRtGrpId ~= "" then
1725 prefix = r2:getNamespace() .. questRtGrpId.."."
1728 local currentTaskIndex = arg[3]
1730 action.Parameters = "if ("..prefix.."v2 == " ..tostring(currentTaskIndex)..")\n"
1731 .."{\n"
1732 .."\t "..prefix.."v2 = " ..prefix.."v2 + 1;\n"
1733 .."\t ()" ..prefix.."setEvent(9);\n"
1734 .."}"
1737 action.Action = "code"
1738 return action
1742 if actionType == "request_item" then
1743 local rtGrpId = arg[2]
1744 local prefix = ""
1745 if rtGrpId and rtGrpId ~= "" then
1746 prefix = r2:getNamespace() .. rtGrpId.."."
1749 local grpName = r2:getNamespace() .. rtGrpId
1751 local items = tostring(arg[3])
1752 assert(items)
1754 local phrase = tostring(arg[4])
1755 assert(phrase)
1756 if phrase == "" then phrase = "Ok" end
1757 action.Parameters =
1758 "// request_item\n"
1759 .. "(@groupToNotify)".. grpName ..".context();\n"
1760 .."()receiveMissionItems(\"".. items.."\", \"".. phrase .."\", @groupToNotify);\n"
1763 action.Action = "code"
1764 return action
1769 if actionType == "give_item" then
1770 local rtGrpId = arg[2]
1771 local prefix = ""
1772 if rtGrpId and rtGrpId ~= "" then
1773 prefix = r2:getNamespace() .. rtGrpId.."."
1776 local grpName = r2:getNamespace() .. rtGrpId
1778 local items = tostring(arg[3])
1779 assert(items)
1781 local phrase = tostring(arg[4])
1782 assert(phrase)
1783 if phrase == "" then phrase = "Ok" end
1785 action.Parameters =
1786 "// give_item\n"
1787 .. "(@groupToNotify)".. grpName ..".context();\n"
1788 .."()giveMissionItems(\"".. items.."\", \"".. phrase .."\", @groupToNotify);\n"
1792 action.Action = "code"
1793 return action
1798 if actionType == "give_reward" then
1799 local rtGiverGrpId = arg[2]
1800 local rtGiverName = arg[3]
1801 local rtGiverGrpName = r2:getNamespace()..rtGiverGrpId
1803 local texts = arg[4]
1805 local rewardText = texts["rewardText"]
1806 local rareRewardText = texts["rareRewardText"]
1807 local inventoryFullText = texts["inventoryFullText"]
1808 local notEnoughPointsText = texts["notEnoughPointsText"]
1810 local textsArgs = "\""..rewardText.."\", "
1811 .."\""..rareRewardText.. "\", "
1812 .."\""..inventoryFullText.. "\", "
1813 .."\""..notEnoughPointsText.."\""
1815 action.Parameters = "//Give reward (giver : '".. rtGiverName.."')\n"
1816 .."(@groupToNotify)".. rtGiverGrpName..".context();\n"
1817 .."()giveReward("..textsArgs..", @groupToNotify);\n"
1819 action.Action = "code"
1820 return action
1823 if actionType == "teleport_near" then
1824 local rtGiverGrpId = arg[2]
1825 local rtGiverGrpName = r2:getNamespace()..rtGiverGrpId
1826 local uniqId = arg[3]
1827 local x = arg[4]
1828 local y = arg[5]
1829 local z = arg[6]
1831 action.Parameters = "//teleport Near\n"
1832 .."(@groupToNotify)".. rtGiverGrpName..".context();\n"
1833 .."()teleportNear("..tostring(x)..", "..tostring(y).. ", ".. tostring(z)..", @groupToNotify);\n"
1835 action.Action = "code"
1836 return action
1839 if actionType == "talk_to" then
1840 local rtGrpId = arg[2]
1841 local prefix = ""
1842 if rtGrpId and rtGrpId ~= "" then
1843 prefix = r2:getNamespace() .. rtGrpId.."."
1846 local grpName = r2:getNamespace() .. rtGrpId
1848 local phrase = tostring(arg[3])
1849 assert(phrase)
1851 if phrase == "" then phrase = "Ok" end
1853 action.Parameters =
1854 "// talk_to\n"
1855 .. "(@groupToNotify)".. grpName ..".context();\n"
1856 .."()talkTo(\"".. phrase .."\", @groupToNotify);\n"
1859 action.Action = "code"
1860 return action
1864 if actionType == "set_value" then
1865 local rtGrpId = arg[2]
1866 local prefix = ""
1867 if rtGrpId and rtGrpId ~= "" then
1868 prefix = r2:getNamespace() .. rtGrpId.."."
1871 local variable = tostring(arg[3])
1872 assert(variable)
1873 --local variableLen = string.len(variable)
1874 --assert(variableLen < 8)
1875 --variable = string.lower(variable)
1876 local i = 0;
1878 assert( type(arg[4]) == 'number' or type(arg[4]) == 'string')
1880 local value = arg[4]
1881 action.Parameters = prefix .. variable .. " = " .. value..";\n"
1882 action.Action = "code"
1883 return action
1886 --called each time some scenario points
1887 if actionType == "add_scenario_points" then
1888 --scenario rtId
1889 local rtBaseActId = arg[2]
1890 local points = arg[3]
1891 local prefix = ""
1892 if rtBaseActId and rtBaseActId ~= "" then
1893 prefix = r2:getNamespace()..rtBaseActId.."."
1896 action.Parameters = prefix.."ScenarioPoints = "..prefix.."ScenarioPoints + " ..tostring(points)..";\n"
1898 action.Action = "code"
1899 return action
1903 --called every 30 seconds or so to avoid sending network msg each time some points are added
1904 if actionType == "set_scenario_points" then
1905 local rtScenarioId = tostring( r2:getScenarioId())
1906 local rtBaseActId = arg[2]
1908 local prefix = ""
1909 if rtBaseActId and rtBaseActId ~= "" then
1910 prefix = r2:getNamespace()..rtBaseActId.."."
1913 action.Parameters = "()setScenarioPoints("..rtScenarioId.. ", " ..prefix.."ScenarioPoints);\n"
1914 .."()"..prefix.."setTimer(300,1);\n"
1915 action.Action = "code"
1916 return action
1919 if actionType == "start_scenario_timing" then
1920 local rtScenarioId = tostring( r2:getScenarioId())
1922 action.Parameters = "()startScenarioTiming("..rtScenarioId..");\n"
1923 action.Action = "code"
1924 return action
1927 if actionType == "stop_scenario_timing" then
1928 local rtScenarioId = tostring( r2:getScenarioId())
1930 action.Parameters = "()endScenarioTiming("..rtScenarioId..");\n"
1931 action.Action = "code"
1932 return action
1935 if actionType == "if_value_equal" then
1936 local rtGrpId = arg[2]
1937 local prefix = ""
1938 if rtGrpId and rtGrpId ~= "" then
1939 prefix = r2:getNamespace() .. rtGrpId.."."
1942 local variable = tostring(arg[3])
1943 assert(variable)
1944 local variableLen = string.len(variable)
1945 --variable = string.lower(variable)
1946 local i = 0;
1948 assert( type(arg[4]) == 'number')
1949 local value = arg[4]
1950 action.Parameters = prefix..variable .. " == " .. value
1952 if (arg[5] ~= nil ) then
1953 assert( type(arg[5]) == 'table')
1954 local value = arg[4]
1955 action.Parameters = prefix..variable .. " == " .. value
1956 table.insert(action.Children, arg[5])
1960 action.Action = "dynamic_if"
1962 return action
1965 -- "validate_task" is used when the player completed part of a mission but didn't come back to the mission giver
1966 if actionType == "validate_task" then
1967 local rtGrpId = arg[2]
1968 local prefix = ""
1969 if rtGrpId and rtGrpId ~= "" then
1970 prefix = r2:getNamespace() .. rtGrpId.."."
1973 action.Parameters = "//validateTask \n"
1974 .."if (" ..prefix.."Active == 1 && " ..prefix.."v2 == 1 )\n"
1975 .."{"
1976 .."\n\t" ..prefix.."v2 = 2;\n\t"
1977 .."()" ..prefix.."setEvent(8);\n"
1978 .."}"
1979 action.Action = "code"
1981 return action
1984 -- "complete_mission" is used when the player comes back to the mission giver after having validated the mission.
1985 if actionType == "complete_mission" then
1986 local rtGrpId = arg[2]
1987 local prefix = ""
1988 if rtGrpId and rtGrpId ~= "" then
1989 prefix = r2:getNamespace() .. rtGrpId.."."
1992 action.Parameters = "//complete_mission \n"
1993 .."if (" ..prefix.."Active == 1)\n"
1994 .."{"
1995 .."\n\t" ..prefix.."v2 = 2;\n\t"
1996 .."()" ..prefix.."setEvent(9);\n"
1997 .."}"
1998 action.Action = "code"
2000 return action
2003 if string.find(actionType, "timer_") ~= nil
2004 then
2005 local rtGrpId = arg[2]
2006 local prefix = ""
2007 if rtGrpId and rtGrpId ~= "" then
2008 prefix = r2:getNamespace() .. rtGrpId.."."
2011 local timer = tonumber(arg[3])
2012 assert(0 <= timer and timer <= 3)
2014 if actionType == "timer_trigger" then
2015 action.Parameters = "()"..prefix.."setTimer(4, "..timer..");\n"
2017 elseif actionType == "timer_disable" then
2018 action.Parameters = "()"..prefix.."timerDisable("..timer..");\n"
2019 ..prefix.. "Active = 0;"
2020 elseif actionType == "timer_suspend" then
2021 action.Parameters = "()"..prefix.."timerSuspend("..timer..");\n"
2022 elseif actionType == "timer_resume" then
2023 action.Parameters = "()"..prefix.."timerResume("..timer..");\n"
2024 elseif actionType == "timer_enable" then
2025 printWarning("timerEnable is not implemented in AIS!")
2026 action.Parameters = "()"..prefix.."timerEnable("..timer..");\n" -- !!!NOT IMPLEMENTED IN AIS!!!
2027 elseif actionType == "timer_is_enable" then
2028 action.Parameters = "("..prefix.."is_enable"..")"..prefix.."timerIsEnabled("..timer..");\n"
2029 elseif actionType == "timer_is_suspended" then
2030 action.Parameters = "("..prefix.."is_suspended"..")"..prefix.."timerIsSuspended("..timer..");\n"
2031 elseif actionType == "timer_add" or actionType == "timer_sub" then
2032 local wait = tonumber(arg[4])
2033 assert(wait and 0<= wait)
2034 wait = wait*10 + 4
2035 if actionType == "timer_sub" then
2036 action.Parameters = "()"..prefix.."timerAdd("..timer..", " .. -wait .. ");\n"
2037 else
2038 action.Parameters = "()"..prefix.."timerAdd("..timer..", " .. wait .. ");\n"
2040 elseif actionType == "timer_set" then
2041 local wait = tonumber(arg[4])
2042 assert(wait and 0<= wait)
2043 wait = wait*10 + 4
2044 action.Parameters = "()"..prefix.."setTimer("..wait..", " .. timer .. ");\n"
2045 ..prefix.."Active = 1;\n"
2047 elseif actionType == "timer_set_daytime" then
2048 local hours = tonumber(arg[4])
2049 local minutes = tonumber(arg[5])
2050 assert(hours and 0<= hours and hours <= 23)
2051 assert(minutes and 0<= minutes and minutes <= 60)
2052 action.Parameters = "()"..prefix.."timerSetRyzomDaytime("..timer..", " .. hours .. ", "..minutes..");\n"
2053 else
2054 debugInfo(colorTag(255,0,0).."Unhandeld action '" ..actionType .."'")
2055 assert(nil)
2057 action.Action = "code"
2058 return action
2061 -------------------------------------
2062 -- Counter feature
2063 -------------------------------------
2064 if string.find(actionType, "counter_") ~= nil
2065 then
2066 local rtGrpId = arg[2]
2067 local prefix = ""
2069 if rtGrpId and rtGrpId ~= "" then
2070 prefix = r2:getNamespace() .. rtGrpId.."."
2074 -- Action "Init": initializes the counter by storing the initial counter value in v1
2075 -- and the triggerValue in v2.
2077 if actionType == "counter_init" then
2078 local value = arg[3]
2079 local triggerValue = arg[4]
2080 action.Parameters = prefix.. "v0 = 1;\n"
2081 ..prefix.."v1 = "..value..";\n"
2082 ..prefix.."v2 = "..triggerValue..";\n"
2086 -- Action "increment": checks wether the counter is active or not (var v0 used as a boolean),
2087 -- then increment the counter and enventually checks if the triggerValue (stored in v2) has
2088 -- been reached to trigger a userEvent.
2090 if actionType == "counter_inc" then
2091 action.Name = "counter_inc"
2092 action.Parameters = "if (" ..prefix.. "v0 == 1)\n"
2093 .. "{\n\tif (" ..prefix.. "v1 >= 0)\n"
2094 .. "\t{\n"
2095 .. "\t\t" .. prefix.. "v1 = " ..prefix.. "v1 + 1;\n"
2096 .. "\t\tif (" ..prefix.. "v1 == " ..prefix.."v2)\n"
2097 .. "\t\t{\n"
2098 .. "\t\t\t" .. prefix.. "e=3;\n"
2099 .. "\t\t\t ()" ..prefix.. "setEvent(0);\n"
2100 .. "\t\t}\n"
2101 .."\t}\n}"
2102 --.. "()"..prefix..'debug("v0=");'.."\n"
2103 --.. "()"..prefix..'debug('..prefix..'v0'..');'.."\n"
2104 --.. "()"..prefix..'debug("v1=");'.."\n"
2105 --.. "()"..prefix..'debug('..prefix..'v1'..');'.."\n"
2106 --.. "()"..prefix..'debug("v2=");'.."\n"
2107 --.. "()"..prefix..'debug('..prefix..'v2'..');'.."\n"
2111 -- Action "decrement": works the same as increment (checks if the counter can be decremented)
2113 if actionType == "counter_dec" then
2114 action.Name = "counter_dec"
2115 action.Parameters = "if (" ..prefix.. "v0 == 1)\n"
2116 .. "{\n\tif (" ..prefix.. "v1 > 0)\n"
2117 .. "\t{\n"
2118 .. "\t\t" .. prefix.. "v1 = " ..prefix.. "v1 - 1;\n"
2119 .. "\t\tif (" ..prefix.. "v1 == " ..prefix.. "v2)\n"
2120 .. "\t\t{ \n"
2121 .. "\t\t\t" .. prefix.. "e=3;\n"
2122 .. "\t\t\t()" ..prefix.. "setEvent(0);\n"
2123 .. "\t\t}\n"
2124 .."\t}\n}\n"
2125 .. "()"..prefix..'debug("v0=");'.."\n"
2126 .. "()"..prefix..'debug('..prefix..'v0'..');'.."\n"
2127 .. "()"..prefix..'debug("v1=");'.."\n"
2128 .. "()"..prefix..'debug('..prefix..'v1'..');'.."\n"
2129 .. "()"..prefix..'debug("v2=");'.."\n"
2130 .. "()"..prefix..'debug('..prefix..'v2'..');'.."\n"
2133 if actionType == "counter_enable" then
2134 action.Name = "counter_enable"
2135 action.Parameters = prefix.."v0 = 1;\n"
2138 if actionType == "counter_disable" then
2139 action.Name = "counter_disable"
2140 action.Parameters = prefix.."v0 = 0;\n"
2143 if actionType == "counter_trigger" then
2146 action.Action = "code"
2148 if actionType == "counter_is_enable" then
2149 action.Name = "counter_is_enable"
2150 action.Action = "dynamic_if"
2151 action.Parameters = prefix.. "v0 == 1\n"
2155 return action
2158 -------------------------------------
2159 -- GiveItem Feature
2160 -------------------------------------
2162 if string.find(actionType, "giveItem_") ~= nil
2163 then
2164 local rtGrpId = arg[2]
2165 local prefix = ""
2167 if rtGrpId and rtGrpId ~= "" then
2168 prefix = r2:getNamespace() .. rtGrpId.."."
2171 if actionType == "giveItem_init" then
2172 local qty = arg[3]
2173 --local triggerValue = arg[4]
2174 action.Parameters = prefix.. "v0 = 1;\n"
2175 ..prefix.."v1 = "..qty..";\n"
2176 --..prefix.."v2 = "..triggerValue..";\n"
2179 if actionType == "giveItem_enable" then
2180 action.Name = "giveItem_enable"
2181 action.Parameters = prefix.."v0 = 1;\n"
2184 if actionType == "giveItem_disable" then
2185 action.Name = "giveItem_disable"
2186 action.Parameters = prefix.."v0 = 0;\n"
2189 action.Action = "code"
2191 if actionType == "giveItem_is_enable" then
2192 action.Name = "giveItem_is_enable"
2193 action.Action = "dynamic_if"
2194 action.Parameters = prefix.. "v0 == 1\n"
2197 return action
2201 -------------------------------------
2202 -- RequestItem Feature
2203 -------------------------------------
2205 if string.find(actionType, "requestItem_") ~= nil
2206 then
2207 local rtGrpId = arg[2]
2208 local prefix = ""
2210 if rtGrpId and rtGrpId ~= "" then
2211 prefix = r2:getNamespace() .. rtGrpId.."."
2214 if actionType == "requestItem_init" then
2215 local qty = arg[3]
2216 --local triggerValue = arg[4]
2217 action.Parameters = prefix.. "v0 = 1;\n"
2218 ..prefix.."v1 = "..qty..";\n"
2219 --..prefix.."v2 = "..triggerValue..";\n"
2222 if actionType == "requestItem_enable" then
2223 action.Name = "requestItem_enable"
2224 action.Parameters = prefix.."v0 = 1;\n"
2227 if actionType == "requestItem_disable" then
2228 action.Name = "requestItem_disable"
2229 action.Parameters = prefix.."v0 = 0;\n"
2232 action.Action = "code"
2234 if actionType == "requestItem_is_enable" then
2235 action.Name = "requestItem_is_enable"
2236 action.Action = "dynamic_if"
2237 action.Parameters = prefix.. "v0 == 1\n"
2240 return action
2244 if actionType == "bot_init" then
2245 function indent(s)
2246 s = "\t" .. string.gsub(s, "\n", "\n\t")
2247 return s
2249 local rtGrpId = arg[2]
2250 local prefix = ""
2251 if rtGrpId and rtGrpId ~= "" then
2252 prefix = r2:getNamespace() .. rtGrpId.."."
2256 assert(type(arg[3]) == "string")
2257 assert(type(arg[4]) == "number")
2258 assert(type(arg[5]) == "number")
2259 assert(type(arg[6]) == "number")
2261 local category = tostring(arg[3])
2262 local aggroDist = tonumber(arg[4])
2263 local botAttackable = tonumber(arg[5])
2264 local playerAttackable = tonumber(arg[6])
2267 local action = r2.Translator.createAction("faction_init", rtGrpId, category, aggroDist, botAttackable, playerAttackable)
2268 local code = action.Parameters
2269 code = indent(code)
2270 action.Parameters = "if ("..prefix.."factInit != 1)\n{\n"..code..prefix.."factInit = 1;\n}\n"
2272 return action
2275 if actionType == "faction_init" then
2276 local rtGrpId = arg[2]
2277 local prefix = ""
2278 if rtGrpId and rtGrpId ~= "" then
2279 prefix = r2:getNamespace() .. rtGrpId.."."
2283 assert(type(arg[3]) == "string")
2284 assert(type(arg[4]) == "number")
2285 assert(type(arg[5]) == "number")
2286 assert(type(arg[6]) == "number")
2288 local category = tostring(arg[3])
2289 local aggroDist = tonumber(arg[4])
2290 local botAttackable = tonumber(arg[5])
2291 local playerAttackable = tonumber(arg[6])
2294 local code =""
2296 code = code.."()"..prefix.."setActivity(\"faction\");\n"
2298 if category == "Civil" then
2299 if botAttackable == 1 then
2300 code = code.."()"..prefix.."setFactionProp(\"faction\", \"guard\");\n" -- don't assist
2301 else
2302 code = code.."()"..prefix.."setFactionProp(\"faction\", \"civil\");\n" -- don't assist
2304 code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"\");\n"
2305 code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"\");\n"
2307 elseif category == "Guard" then
2308 if botAttackable == 0 then
2309 code = code.."()"..prefix.."setFactionProp(\"faction\", \"civil\");\n"
2310 code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"Player\");\n"
2311 code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"\");\n"
2313 else
2314 code = code.."()"..prefix.."setFactionProp(\"faction\", \"guard\");\n"
2315 code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"Player|guard\");\n"
2316 code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"bandit|carnivore|kitin\");\n"
2320 elseif category =="Karavan" then
2321 if botAttackable == 0 then
2322 code = code.."()"..prefix.."setFactionProp(\"faction\", \"civil\");\n"
2323 code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"Player\");\n"
2324 code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"\");\n"
2326 else
2327 code = code.."()"..prefix.."setFactionProp(\"faction\", \"karavan\");\n"
2328 code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"Player|karavan\");\n"
2329 code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"bandit|carnivore|kitin|plant|kitinWorker\");\n"
2331 elseif category =="Kami" then
2332 if botAttackable == 0 then
2333 code = code.."()"..prefix.."setFactionProp(\"faction\", \"civil\");\n"
2334 code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"Player\");\n"
2335 code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"\");\n"
2337 else
2338 code = code.."()"..prefix.."setFactionProp(\"faction\", \"kami\");\n"
2339 code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"Player|kami\");\n"
2340 code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"bandit|kitin|kitinWorker\");\n"
2342 elseif category == "Bandit" then
2343 if botAttackable == 0 then
2344 code = code.."()setFactionProp(\"faction\", \"civil\");\n"
2345 if playerAttackable == 1 then
2346 code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"Player\");\n"
2347 code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"\");\n"
2348 else
2349 code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"\");\n"
2350 code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"\");\n"
2353 else
2354 code = code.."()"..prefix.."setFactionProp(\"faction\", \"bandit\");\n"
2355 code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"bandit\");\n"
2356 if playerAttackable == 1 then
2357 code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"Player|guard|karavan|kami\");\n"
2358 else
2359 code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"guard|karavan|kami\");\n"
2362 elseif category == "Carnivore" then
2363 if botAttackable == 0 then
2364 code = code.."()"..prefix.."setFactionProp(\"faction\", \"civil\");\n"
2365 if playerAttackable == 1 then
2366 code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"Player\");\n"
2367 code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"\");\n"
2368 else
2369 code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"\");\n"
2370 code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"\");\n"
2373 else
2374 code = code.."()"..prefix.."setFactionProp(\"faction\", \"carnivore\");\n"
2375 code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"\");\n"
2376 if playerAttackable == 1 then
2377 code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"Player|guard|bandit|herbivore|karavan\");\n"
2378 else
2379 code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"guard|bandit|herbivore|karavan\");\n"
2382 elseif category == "Herbivore" then
2383 if botAttackable == 0 then
2384 code = code.."()"..prefix.."setFactionProp(\"faction\", \"civil\");\n"
2385 code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"\");\n"
2386 code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"\");\n"
2388 else
2389 code = code.."()"..prefix.."setFactionProp(\"faction\", \"herbivore\");\n"
2390 code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"\");\n"
2391 code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"\");\n"
2394 elseif category == "Plant" then
2395 if botAttackable == 0 then
2396 code = code.."()"..prefix.."setFactionProp(\"faction\", \"civil\");\n"
2397 code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"\");\n"
2398 code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"\");\n"
2399 else
2400 code = code.."()"..prefix.."setFactionProp(\"faction\", \"plant\");\n"
2401 code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"plant\");\n"
2402 code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"\");\n"
2405 elseif category == "Degen" then
2406 if botAttackable == 0 then
2407 code = code.."()"..prefix.."setFactionProp(\"faction\", \"civil\");\n"
2408 code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"\");\n"
2409 code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"\");\n"
2411 else
2412 code = code.."()"..prefix.."setFactionProp(\"faction\", \"degen\");\n"
2413 code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"degen\");\n"
2414 if playerAttackable == 1 then
2415 code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"Player|guard|bandit|plant|herbivore|carnivore|kitin|kitinWorker|kami|karavan\");\n"
2416 else
2417 code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"guard|bandit|plant|herbivore|carnivore|kitin|kitinWorker|kami|karavan\");\n"
2421 elseif category =="WorkerKitin" then
2422 if botAttackable == 0 then
2423 code = code.."()"..prefix.."setFactionProp(\"faction\", \"civil\");\n"
2424 code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"\");\n"
2425 code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"\");\n"
2427 else
2428 code = code.."()"..prefix.."setFactionProp(\"faction\", \"kitinWorker\");\n"
2429 code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"kitin|kitinWorker\");\n"
2430 code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"\");\n"
2433 elseif category =="SoldierKitin" then
2434 if botAttackable == 0 then
2435 code = code.."()"..prefix.."setFactionProp(\"faction\", \"civil\");\n"
2436 if playerAttackable == 1 then
2437 code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"Player\");\n"
2438 code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"\");\n"
2439 else
2440 code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"\");\n"
2441 code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"\");\n"
2444 else
2445 code = code.."()"..prefix.."setFactionProp(\"faction\", \"kitin\");\n"
2446 code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"kitin|kitinWorker\");\n"
2447 if playerAttackable == 1 then
2448 code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"Player|guard|bandit|karavan|kami\");\n"
2449 else
2450 code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"guard|bandit|karavan|kami\");\n"
2453 else
2454 code = code.."()"..prefix.."setFactionProp(\"faction\", \"civil\");\n" -- don't assist
2455 code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"\");\n"
2456 code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"\");\n"
2457 end
2458 code = code .. "()"..prefix.."setAggro("..tostring(aggroDist)..", 20);\n"
2459 action.Parameters = code
2460 action.Action = "code"
2461 return action
2464 --set player_attackable
2465 if actionType == "set_player_attackable" then
2466 local rtGrpId = arg[2]
2467 local prefix = ""
2468 if rtGrpId and rtGrpId ~= "" then
2469 prefix = r2:getNamespace() ..rtGrpId.."."
2472 assert(type(arg[3]) == "number")
2474 local playerAttackable = arg[3]
2475 action.Parameters = "()"..prefix.."setPlayerAttackable("..playerAttackable..");"
2476 action.Action = "code"
2477 return action
2480 --set bot_attackable
2481 if actionType == "set_bot_attackable" then
2482 local rtGrpId = arg[2]
2483 local prefix = ""
2484 if rtGrpId and rtGrpId ~= "" then
2485 prefix = r2:getNamespace() ..rtGrpId.."."
2488 assert(type(arg[3]) == "number")
2490 local botAttackable = arg[3]
2491 action.Parameters = "()"..prefix.."setBotAttackable("..botAttackable..");"
2492 action.Action = "code"
2493 return action
2496 --make a npc run
2497 if actionType == "set_running_speed" then
2498 local rtGrpId = arg[2]
2499 local prefix = ""
2500 if rtGrpId and rtGrpId ~= "" then
2501 prefix = r2:getNamespace() ..rtGrpId.. "."
2504 action.Parameters = "()"..prefix.."addPersistentProfileParameter(\"running\");"
2505 action.Action = "code"
2506 return action
2509 --make a npc walk
2510 if actionType == "set_walking_speed" then
2511 local rtGrpId = arg[2]
2512 local prefix = ""
2513 if rtGrpId and rtGrpId ~= "" then
2514 prefix = r2:getNamespace() ..rtGrpId.. "."
2517 action.Parameters = "()"..prefix.."removePersistentProfileParameter(\"running\");"
2518 action.Action = "code"
2519 return action
2522 if actionType == "generic_event_trigger"
2523 then
2524 local rtGrpId = arg[2]
2525 local prefix = ""
2526 if rtGrpId and rtGrpId ~= "" then
2527 prefix = r2:getNamespace() .. rtGrpId.."."
2530 local eventId = tonumber(arg[3])
2531 assert(eventId and 0 <= eventId and eventId <= 9)
2533 action.Parameters = prefix.."e="..eventId..";\n" ..
2534 "()"..prefix.."setEvent(0);\n"
2536 action.Action = "code"
2537 return action
2540 if actionType == "user_event_trigger"
2541 then
2542 local rtGrpId = arg[2]
2543 local prefix = ""
2544 if rtGrpId and rtGrpId ~= "" then
2545 prefix = r2:getNamespace() .. rtGrpId.."."
2548 local eventId = tonumber(arg[3])
2549 assert(eventId and 0 <= eventId and eventId <= 9)
2551 action.Parameters = "()"..prefix.."setEvent(".. eventId..");\n"
2553 action.Action = "code"
2554 return action
2559 -- generci_event
2562 if actionType == "dssStartAct" then
2563 local actId = tonumber(arg[2])
2564 assert(actId)
2565 local sessionId = r2:getScenarioId()
2566 assert(sessionId)
2567 action.Action = "code"
2568 action.Parameters = "()dssStartAct(" .. sessionId .. ", " .. actId .. ");\n"
2569 return action, action
2572 --trigger_event action
2573 if string.find(actionType, "trigger_event_%d") ~= nil
2574 then
2575 action.Parameters = arg[2]
2576 return action
2579 --spawn/despawn action
2580 if (actionType == "null_action")
2581 then
2582 return action
2585 if actionType == "spawn" then
2586 local rtNpcGrpId = arg[2]
2587 action.Action = "code"
2588 local prefix = ""
2589 if rtNpcGrpId then
2590 prefix = r2:getNamespace() .. rtNpcGrpId.."."
2592 action.Parameters = "()"..prefix.. actionType.."();"
2593 return action
2597 if actionType == "despawn" then
2598 local rtNpcGrpId = arg[2]
2599 action.Action = "code"
2600 local prefix = ""
2601 if rtNpcGrpId then
2602 prefix = r2:getNamespace() .. rtNpcGrpId.."."
2604 action.Parameters = "()"..prefix.. actionType.."(0);"
2605 return action
2609 if (actionType == "sit_down") or (actionType == "stand_up") then
2610 local rtGrpId = arg[2]
2611 action.Action = "code"
2613 local prefix = ""
2614 if rtGrpId then
2615 prefix = r2:getNamespace() .. rtGrpId.."."
2618 local sitting = 0
2619 if actionType=="sit_down" then
2620 sitting = 1
2622 if sitting == 1 then
2623 action.Parameters =
2624 "()"..prefix.."sitDown();\n" ..
2625 "()"..prefix.."setTimer(40,1);\n" -- wait 4 second
2626 .. prefix.."isSitting = ".. tostring( sitting) .. ";"
2627 else
2628 action.Parameters =
2629 "()"..prefix.."standUp();\n" ..
2630 "()"..prefix.."setTimer(40,1);\n" -- wait 4 second
2631 .. prefix.."isSitting = ".. tostring( sitting) .. ";"
2636 --multi actions
2637 if actionType == "multi_actions" then
2638 local actions = arg[2]
2639 if actions ~= nil then
2640 local max = table.getn(actions)
2641 for i=1, max do
2642 assert(actions[i])
2643 table.insert(action.Children, actions[i])
2646 return action
2649 --say action
2650 if actionType == "say"
2651 then
2652 action.Parameters = "say: "..arg[2]
2653 return action
2656 if actionType == "switch_actions"
2657 then
2658 action.Parameters = arg[2]
2659 return action
2662 --npc_say action
2663 if actionType == "npc_say"
2664 then
2665 action.Parameters = ""
2667 local str = arg[2]
2669 if str == nil then str = "\n" end
2670 if (string.find(str, "\n") == nil) then
2671 str = str .. "\n"
2674 if (table.getn(arg)==3)
2675 then
2676 assert(arg[3])
2677 assert( tostring(arg[3]) )
2678 action.Parameters = tostring(arg[3]).."\n"
2680 action.Parameters = action.Parameters..str
2681 return action
2683 --emot action
2684 if actionType == "emot"
2685 then
2686 local max = table.getn(arg)
2687 debugInfo(colorTag(255,0,0,255).."action emot")
2688 local parameters =""
2689 for i=2, max do
2690 parameters = parameters .. arg[i]
2691 parameters = parameters .. "\n"
2693 action.Parameters = parameters
2694 return action
2697 --if action
2698 --arg2: expression
2699 --arg3: action if expression is true
2700 --arg4(optional): action if expression false
2701 if (actionType == "condition_if")or(actionType == "condition_if_else") or (actionType == "dynamic_if")
2702 then
2703 local max = table.getn(arg)
2704 if max == 4 then
2705 -- action.Action="dynamic_if_else"
2706 action.Action="dynamic_if"
2707 table.insert(action.Children, arg[3])
2708 table.insert(action.Children, arg[4])
2709 elseif max ==3 then
2710 action.Action="dynamic_if"
2711 table.insert(action.Children, arg[3])
2712 elseif max ==2 then
2713 action.Action="dynamic_if"
2714 else
2715 return nil
2718 action.Parameters = arg[2]
2719 return action
2722 -- waraning
2723 if actionType == "code"
2724 then
2725 action.Parameters = arg[2]
2726 return action
2729 --random action
2730 if actionType == "random_select"
2731 then
2732 local max = table.getn(arg)
2733 for i=2, max do
2734 table.insert(action.Children, arg[i])
2736 return action
2739 --set timer action
2740 if string.find(actionType, "set_timer_t") ~= nil
2741 then
2742 local max = table.getn(arg)
2743 parameters=""
2744 for i=2, max do
2745 parameters = parameters .. arg[i]
2747 action.Parameters = parameters
2748 return action
2751 --modify variable action
2752 if actionType == "modify_variable" or actionType == "begin_state"
2753 then
2754 action.Parameters = arg[2]
2755 return action
2758 if actionType == "punctual_state"
2759 then
2760 action.Parameters = arg[2]
2761 return action
2764 if (actionType == "stand_up")or(actionType == "sit_down")or(actionType == "punctual_state_end")
2765 then
2766 return action
2768 printWarning("Unhandled action " .. actionType)
2769 return nil
2773 --first param : event type
2774 --second param: StatesByName
2775 --third param : GroupsByName
2776 --then, parameters
2777 Translator.createEvent = function(...)
2778 local arg = {...}
2779 local event = r2.newComponent("RtNpcEventHandler")
2780 local eventType = arg[1]
2781 event.Event = eventType
2782 event.StatesByName = arg[2]
2783 event.GroupsByName = arg[3]
2784 assert(arg[1])
2785 assert(arg[2])
2786 assert(arg[3])
2788 if eventType == nil then
2789 debugInfo("Error invalid eventType")
2790 assert(nil)
2791 return nil
2794 if string.find(eventType, "timer_t%d_triggered") ~=nil or string.find(eventType, "user_event_%d")
2795 then
2796 return event
2799 if (eventType == "end_of_state") or (eventType == "start_of_state")
2800 or (eventType == "group_under_attack") or (eventType == "destination_reached_all")
2801 or (eventType == "bot_killed") or (eventType == "group_eliminated") or (eventType == "group_under_attack")
2802 or (eventType == "destination_reached") or (eventType == "variable_changed")
2803 or (eventType == "group_despawned") or (eventType == "group_spawned") or (eventType == "bot_target_killed")
2804 or (eventType == "player_target_npc")
2806 or string.find(eventType, "variable_v%d_changed") ~= nil
2807 then
2808 return event
2811 if (eventType == "on_player_arrived") then
2812 event.Event = "player_arrived_trigger_zone"
2813 event.IsTriggerZone = 1
2814 return event
2817 if (eventType == "on_player_left") then
2818 event.Event = "player_left_trigger_zone"
2819 event.IsTriggerZone = 1
2820 return event
2824 printWarning("Error invalid event ".. eventType)
2826 return nil
2829 -- it adds a new simple activity in zone within the given context
2830 Translator.createSimpleActivityInZone = function(context, zoneName, groupsByName, mode, static, aiScriptDebug)
2831 local action
2832 local event
2833 local code
2835 -- init when the group arrives in the zone
2836 code = '()setMode("' .. mode .. '");\n'
2837 if static then
2838 code = code .. '()stopMoving();\n';
2840 if aiScriptDebug then
2841 code = 'log("destination_reached_all: zone=' .. zoneName .. ', group=' .. groupsByName .. '");\n' .. code
2843 event = Translator.createEvent("destination_reached_all", zoneName, groupsByName)
2844 table.insert(context.RtAct.Events, event)
2845 action = Translator.createAction("code", code)
2846 table.insert(context.RtAct.Actions, action)
2847 table.insert(event.ActionsId, action.Id)
2849 -- restore things when the group quits the zone
2850 code = '()setMode("Normal");'
2851 if aiScriptDebug then
2852 code = 'log("end_of_state: zone=' .. zoneName .. ', group=' .. groupsByName .. '");\n' .. code
2854 event = Translator.createEvent("end_of_state", zoneName, groupsByName)
2855 table.insert(context.RtAct.Events, event)
2856 action = Translator.createAction("code", code)
2857 table.insert(context.RtAct.Actions, action)
2858 table.insert(event.ActionsId, action.Id)
2861 -- it adds a new activity in zone within the given context
2862 Translator.createActivityInZone = function(context, zoneName, groupsByName, mode, timerId, wanderTime, activityTime, aiScriptDebug)
2863 assert(wanderTime > 0)
2864 assert(activityTime > 0)
2866 local action
2867 local event
2868 local code
2869 local timerEventName = "timer_t" .. timerId .. "_triggered"
2871 -- init start of state
2872 code = 'nextState = 0;\n'
2873 if aiScriptDebug then
2874 code = 'log("start_of_state: zone=' .. zoneName .. ', group=' .. groupsByName .. '");\n' .. code
2876 event = Translator.createEvent("start_of_state", zoneName, groupsByName)
2877 table.insert(context.RtAct.Events, event)
2878 action = Translator.createAction("code", code)
2879 table.insert(context.RtAct.Actions, action)
2880 table.insert(event.ActionsId, action.Id)
2882 -- init when the group arrives in the zone
2883 code =
2884 'if (nextState == 0)\n' ..
2885 '{\n'
2886 if aiScriptDebug then
2887 code = code ..
2888 ' log("destination_reached_all: zone=' .. zoneName .. ', group=' .. groupsByName .. '");\n'
2890 code = code ..
2891 ' nextState = 1;\n' ..
2892 ' ()setTimer(1, ' .. timerId .. ');\n' ..
2893 '}\n'
2894 event = Translator.createEvent("destination_reached_all", zoneName, groupsByName)
2895 table.insert(context.RtAct.Events, event)
2896 action = Translator.createAction("code", code)
2897 table.insert(context.RtAct.Actions, action)
2898 table.insert(event.ActionsId, action.Id)
2900 -- activity states
2901 code =
2902 'if (nextState == 1) {\n' ..
2903 ' nextState = 2;\n' ..
2904 ' ()stopMoving();\n' ..
2905 ' ()setMode("' .. mode .. '");\n' ..
2906 ' ()setTimer(' .. activityTime .. ', ' .. timerId .. ');\n' ..
2907 '} else if (nextState == 2) {\n' ..
2908 ' nextState = 1;\n' ..
2909 ' ()setMode("Normal");\n' ..
2910 ' ()wander();\n' ..
2911 ' ()setTimer(' .. wanderTime .. ', ' .. timerId .. ');\n' ..
2912 '} else {\n' ..
2913 ' log("unknown state=", nextState, ", zone=' .. zoneName .. ', group=' .. groupsByName .. '");\n' ..
2914 ' ()break();\n' ..
2915 '}\n'
2916 if aiScriptDebug then
2917 code = 'log("' .. timerEventName .. ': state=", nextState, ", zone=' .. zoneName .. ', group=' .. groupsByName .. '");\n' .. code
2919 event = Translator.createEvent(timerEventName, zoneName, groupsByName)
2920 table.insert(context.RtAct.Events, event)
2921 action = Translator.createAction("code", code)
2922 table.insert(context.RtAct.Actions, action)
2923 table.insert(event.ActionsId, action.Id)
2925 -- restore things when the group quits the zone
2926 code =
2927 '()timerDisable(' .. timerId .. ');\n' ..
2928 '()setMode("Normal");\n'
2929 if aiScriptDebug then
2930 code = 'log("end_of_state: zone=' .. zoneName .. ', group=' .. groupsByName .. '");\n' .. code
2932 event = Translator.createEvent("end_of_state", zoneName, groupsByName)
2933 table.insert(context.RtAct.Events, event)
2934 action = Translator.createAction("code", code)
2935 table.insert(context.RtAct.Actions, action)
2936 table.insert(event.ActionsId, action.Id)
2939 -- it adds a new hunt activity in zone within the given context
2940 Translator.createHuntActivityInZone = function(context, zoneName, groupsByName, timerId, wanderTime, alertTime, eatTime, aiScriptDebug)
2941 assert(wanderTime > 0)
2942 assert(alertTime > 0)
2943 assert(eatTime > 0)
2945 local action
2946 local event
2947 local code
2948 local timerEventName = "timer_t" .. timerId .. "_triggered"
2950 -- init start of state
2951 code = 'nextState = 0;\n'
2952 if aiScriptDebug then
2953 code = 'log("start_of_state: zone=' .. zoneName .. ', group=' .. groupsByName .. '");\n' .. code
2955 event = Translator.createEvent("start_of_state", zoneName, groupsByName)
2956 table.insert(context.RtAct.Events, event)
2957 action = Translator.createAction("code", code)
2958 table.insert(context.RtAct.Actions, action)
2959 table.insert(event.ActionsId, action.Id)
2961 -- init when the group arrives in the zone
2962 code =
2963 'if (nextState == 0)\n' ..
2964 '{\n'
2965 if aiScriptDebug then
2966 code = code ..
2967 ' log("destination_reached_all: zone=' .. zoneName .. ', group=' .. groupsByName .. '");\n'
2969 code = code ..
2970 ' nextState = 1;\n' ..
2971 --- ' ()setFactionProp("ennemyFaction", "' .. Translator.PredatorEnemyFaction .. '");\n' ..
2972 ' ()setTimer(1, ' .. timerId .. ');\n' ..
2973 '}\n'
2974 event = Translator.createEvent("destination_reached_all", zoneName, groupsByName)
2975 table.insert(context.RtAct.Events, event)
2976 action = Translator.createAction("code", code)
2977 table.insert(context.RtAct.Actions, action)
2978 table.insert(event.ActionsId, action.Id)
2980 -- activity states
2981 code =
2982 'if (nextState == 1) {\n' ..
2983 ' nextState = 2;\n' ..
2984 ' ()stopMoving();\n' ..
2985 ' ()setMode("Alert");\n' ..
2986 ' ()setTimer(' .. alertTime .. ', ' .. timerId .. ');\n' ..
2987 '} else if (nextState == 2) {\n' ..
2988 ' nextState = 1;\n' ..
2989 ' ()setMode("Normal");\n' ..
2990 ' ()wander();\n' ..
2991 ' ()setTimer(' .. wanderTime .. ', ' .. timerId .. ');\n' ..
2992 '} else if (nextState == 3) {\n' ..
2993 ' nextState = 1;\n' ..
2994 -- ' ()setFactionProp("ennemyFaction", "'.. Translator.PredatorEnemyFaction .. '");\n' ..
2995 ' ()setMode("Normal");\n' ..
2996 ' ()wander();\n' ..
2997 ' ()setTimer(' .. wanderTime .. ', ' .. timerId .. ');\n' ..
2998 '} else {\n' ..
2999 ' log("unknown state=", nextState, ", zone=' .. zoneName .. ', group=' .. groupsByName .. '");\n' ..
3000 ' ()break();\n' ..
3001 '}\n'
3002 if aiScriptDebug then
3003 code = 'log("' .. timerEventName .. ': state=", nextState, ", zone=' .. zoneName .. ', group=' .. groupsByName .. '");\n' .. code
3005 event = Translator.createEvent(timerEventName, zoneName, groupsByName)
3006 table.insert(context.RtAct.Events, event)
3007 action = Translator.createAction("code", code)
3008 table.insert(context.RtAct.Actions, action)
3009 table.insert(event.ActionsId, action.Id)
3011 -- eat the corpse when the target is killed
3012 code =
3013 'nextState = 3;\n' ..
3014 --. '()setFactionProp("ennemyFaction", "");\n' ..
3015 '()stopMoving();\n' ..
3016 '()setMode("Eat");\n' ..
3017 '()setTimer(' .. eatTime .. ', ' .. timerId .. ');\n'
3018 if aiScriptDebug then
3019 code = 'log("bot_target_killed: zone=' .. zoneName .. ', group=' .. groupsByName .. '");\n' .. code
3021 event = Translator.createEvent("bot_target_killed", zoneName, groupsByName)
3022 table.insert(context.RtAct.Events, event)
3023 action = Translator.createAction("code", code)
3024 table.insert(context.RtAct.Actions, action)
3025 table.insert(event.ActionsId, action.Id)
3027 -- restore things when the group quits the zone
3028 code =
3029 '()timerDisable(' .. timerId .. ');\n' ..
3030 '()setMode("Normal");\n'
3031 -- .. '()setFactionProp("ennemyFaction", "Player");\n'
3032 if aiScriptDebug then
3033 code = 'log("end_of_state: zone=' .. zoneName .. ', group=' .. groupsByName .. '");\n' .. code
3035 event = Translator.createEvent("end_of_state", zoneName, groupsByName)
3036 table.insert(context.RtAct.Events, event)
3037 action = Translator.createAction("code", code)
3038 table.insert(context.RtAct.Actions, action)
3039 table.insert(event.ActionsId, action.Id)
3042 -- set GroupParameters of a rt Group by readin a hl Np
3043 -- eg set BotAttackable, aggro_range ..
3044 Translator.setGroupParameters = function(hlNpc, rtNpcGrp)
3045 assert(hlNpc and type(hlNpc) == "userdata")
3046 rtNpcGrp.GrpParameters = "ring\n" .. rtNpcGrp.GrpParameters
3047 rtNpcGrp.AiProfilParams = ""
3049 local botAttackable = hlNpc.BotAttackable
3050 if botAttackable == 1
3051 then
3052 rtNpcGrp.GrpParameters = rtNpcGrp.GrpParameters.."bot_attackable".. "\n"
3055 local playerAttackable = hlNpc.PlayerAttackable
3056 if playerAttackable == 1
3057 then
3058 rtNpcGrp.GrpParameters = rtNpcGrp.GrpParameters.."player_attackable".. "\n"
3061 local aggroRange = hlNpc.Aggro
3062 if aggroRange ~= nil and aggroRange >= 0
3063 then
3064 if (aggroRange > 120) then aggroRange = 120 end
3065 rtNpcGrp.GrpParameters = rtNpcGrp.GrpParameters.."aggro range: "..aggroRange.."\n"
3069 -- if hlNpc.UseFame and hlNpc.UseFame == 1 and hlNpc.Fame then
3070 -- rtNpcGrp.AiProfilParams = rtNpcGrp.AiProfilParams
3071 -- .. "faction:" .. hlNpc.Fame .. "\n"
3072 -- .. "fame_for_guard_attack:-300000\n"
3073 -- end
3076 local speed = hlNpc.Speed
3077 if speed ~= nil and type(speed) == "number" and speed == 1 then
3078 rtNpcGrp.AiProfilParams = rtNpcGrp.AiProfilParams .. "running\n"
3081 local autoSpawn = hlNpc.AutoSpawn
3082 if autoSpawn ~= nil and autoSpawn == 0 then
3083 rtNpcGrp.AutoSpawn = 0
3086 local noRespawn = hlNpc.NoRespawn
3087 if noRespawn ~= nil and noRespawn == 1 then
3088 rtNpcGrp.GrpParameters = rtNpcGrp.GrpParameters.. "respawn time:-1\n"
3091 local isFauna = hlNpc.IsFauna
3092 if isFauna ~= nil and isFauna == 1 then
3093 rtNpcGrp.GrpParameters = rtNpcGrp.GrpParameters.. "denied_astar_flags:WaterAndNoGo\n"
3099 -- TODO doc
3103 ---- EventHandlers
3105 -- Components
3106 --- Condition
3107 Translator.getComponentGenericEvent =function(rtNpcGrp, id)
3108 assert(rtNpcGrp)
3109 assert(id)
3111 local prefix = ""
3113 if rtNpcGrp.Id and rtNpcGrp.Id ~= "" then
3114 prefix = r2:getNamespace() .. rtNpcGrp.Id.."."
3117 local eventHandler = Translator.createEvent("user_event_0", "", rtNpcGrp.Id)
3119 local condition = prefix.. "e == " .. tostring(id)
3121 local firstCondition = Translator.createAction("dynamic_if", condition)
3123 return eventHandler, firstCondition, firstCondition
3126 Translator.getComponentUserEvent =function(rtNpcGrp, id)
3127 assert(rtNpcGrp)
3128 assert(rtNpcGrp.Id)
3129 assert(id)
3131 local eventHandler = Translator.createEvent("user_event_".. id, "", rtNpcGrp.Id)
3133 -- local condition = "1 == 1"
3135 -- local firstCondition = Translator.createAction("dynamic_if", condition)
3137 return eventHandler, nil, nil
3138 --, firstCondition, firstCondition
3143 -- NPC
3144 -- Selecter
3146 Translator.getNpcLogicCondition = function(entity, context, condition )
3147 assert( condition.Class == "ConditionStep")
3148 local rtNpcGrp = Translator.getRtGroup(context, condition.Entity)
3149 assert(rtNpcGrp)
3150 local funs ={}
3151 funs["is in activity sequence"] =Translator.getNpcLogicConditionIsInActivitySequence
3152 funs["is in activity step"] = Translator.getNpcLogicConditionIsInActivityStep
3153 funs["is in chat sequence"] = Translator.getNpcLogicConditionIsInChatSequence
3154 funs["is in chat step"] = Translator.getNpcLogicConditionIsInChatStep
3155 funs["is dead"] = Translator.getNpcLogicConditionIsDead
3156 funs["is alive"] = Translator.getNpcLogicConditionIsAlive
3159 local fun = funs[ condition.Condition.Type ]
3160 if fun then
3161 return fun(entity, context, condition, rtNpcGrp)
3164 local firstAction, lastAction = nil,nil
3166 return firstAction, lastAction
3170 Translator.getNpcLogicAction = function(entity, context, action)
3171 assert( action.Class == "ActionStep")
3172 local rtNpcGrp = Translator.getRtGroup(context, action.Entity)
3173 assert(rtNpcGrp)
3174 local funs ={}
3175 funs["Deactivate"] =Translator.getNpcLogicActionDeactivate
3176 funs["Activate"] =Translator.getNpcLogicActionActivate
3177 funs["Kill"] = Translator.getNpcLogicActionKill
3178 funs["begin activity sequence"] = Translator.getNpcLogicActionBeginActivitySequence
3179 funs["begin chat sequence"] = Translator.getNpcLogicActionBeginChatSequence
3180 funs["Stand Up"] = Translator.getNpcLogicActionStandUp
3181 funs["Sit Down"] = Translator.getNpcLogicActionSitDown
3182 funs["Fight with player"] = Translator.getNpcLogicActionFightPlayer
3183 funs["Fight with Npcs"] = Translator.getNpcLogicActionFightNpcs
3184 funs["Dont fight with player"] = Translator.getNpcLogicActionDontFightPlayer
3185 funs["Dont fight with Npcs"] = Translator.getNpcLogicActionDontFightNpcs
3186 funs["Run"] = Translator.getNpcLogicActionRun
3187 funs["Dont run"] = Translator.getNpcLogicActionDontRun
3188 funs["emits user event"] = Translator.getNpcLogicActionEmitsUserEvent
3191 local fun = funs[ action.Action.Type ]
3192 if fun then
3193 return fun(entity, context, action, rtNpcGrp)
3197 local firstAction, lastAction = nil,nil
3199 return firstAction, lastAction
3205 Translator.getNpcLogicEvent = function(entity, context, event)
3206 assert( event.Class == "LogicEntityAction")
3207 local rtNpcGrp = Translator.getRtGroup(context, entity.InstanceId)
3208 assert(rtNpcGrp)
3210 local funs ={}
3211 funs["activation"] = Translator.getNpcLogicEventActivation
3212 funs["desactivation"] = Translator.getNpcLogicEventDesactivation
3213 funs["death"] = Translator.getNpcLogicEventDeath
3215 funs["end of activity step"] = Translator.getNpcLogicEventEndOfActivityStep
3216 funs["begin of activity step"] = Translator.getNpcLogicEventBeginOfActivityStep
3218 funs["end of activity sequence"] = Translator.getNpcLogicEventEndOfActivitySequence
3219 funs["begin of activity sequence"] = Translator.getNpcLogicEventBeginOfActivitySequence
3221 funs["end of chat step"] = Translator.getNpcLogicEventEndOfChatStep
3222 funs["end of chat sequence"] = Translator.getNpcLogicEventEndOfChatSequence
3223 funs["user event emitted"] = Translator.getNpcLogicEventUserEventEmitted
3227 -- There is also group specific functions
3229 local eventHandler, firsCondition, lastCondition = nil, nil, nil
3230 local value = event.Event.Type
3231 local fun = funs[value ]
3232 if fun then
3233 return fun(entity, context, event, rtNpcGrp)
3236 if value == "member death" then
3237 local eventHandler = Translator.createEvent("bot_killed", "", rtNpcGrp.Id)
3238 return eventHandler, nil, nil
3239 elseif value == "group death" then
3240 local eventHandler = Translator.createEvent("group_eliminated", "", rtNpcGrp.Id)
3241 return eventHandler, nil, nil
3242 elseif value == "targeted by player" then
3243 local eventHandler = Translator.createEvent("player_target_npc", "", rtNpcGrp.Id)
3244 return eventHandler, nil, nil
3247 return eventHandler, firsCondition, lastCondition
3249 --- Event
3251 Translator.getGenericLogicEventDesactivation = function (rtNpcGrp)
3252 local eventHandler, firsCondition, lastCondition = nil, nil, nil
3253 eventHandler = Translator.createEvent("group_despawned", "", rtNpcGrp.Id)
3254 return eventHandler, firsCondition, lastCondition
3259 Translator.getNpcLogicEventDesactivation = function (hlComponent, context, event, rtNpcGrp)
3260 return Translator.getGenericLogicEventDesactivation(rtNpcGrp)
3263 Translator.getNpcLogicEventUserEventEmitted = function (hlComponent, context, event, rtNpcGrp)
3264 local eventHandler, firsCondition, lastCondition = nil, nil, nil
3265 value = event.Event.ValueString
3266 if value then value = tonumber(value) end
3267 if not value then return end
3268 return Translator.getComponentGenericEvent(rtNpcGrp, value)
3272 Translator.getNpcLogicEventActivation = function (hlComponent, context, event, rtNpcGrp)
3273 local eventHandler, firsCondition, lastCondition = nil, nil, nil
3274 eventHandler = Translator.createEvent("group_spawned", "", rtNpcGrp.Id)
3275 return eventHandler, firsCondition, lastCondition
3279 Translator.getGenericLogicEventDeath= function(rtNpcGrp)
3280 local eventHandler, firsCondition, lastCondition = nil, nil, nil
3281 eventHandler = Translator.createEvent("bot_killed", "", rtNpcGrp.Id)
3282 return eventHandler, firsCondition, lastCondition
3286 Translator.getNpcLogicEventDeath= function(hlComponent, context, event, rtNpcGrp)
3287 return Translator.getGenericLogicEventDeath(rtNpcGrp)
3291 Translator.getGenericLogicEventEndOfActivitySequence = function(hlComponent, value, rtNpcGrp)
3292 local sequenceInstanceId = tostring(value)
3293 local sequence = r2:getInstanceFromId(sequenceInstanceId)
3294 assert(sequence)
3296 local n = table.getn(sequence.Components)
3298 if n > 0 then
3300 local firstStep = sequence.Components[ n-1 ].InstanceId
3301 eventHandler = Translator.createEvent("timer_t0_triggered", "", rtNpcGrp.Id)
3302 local value = tostring(firstStep)
3303 local tab=Logic.findActivityStepIdByInstanceId(sequence.Parent.Parent.Parent, value)
3304 local id, id2 = tab[1], tab[2]
3306 if (id == -1 or id2 == -1) then
3307 printWarning("error in translation: the event '"..event.Name .. "' in component '" .. hlComponent.Name ..
3308 "': the selected activity step can not be found");
3309 return nil, nil, nil
3313 local prefix = ""
3314 local condition1 = prefix .. "oldActivityStepVar2 == ".. tostring(id + 1) -- in theory it must be (id-1) +1
3315 local condition2 = prefix .. "currentActivitySequenceVar == ".. tostring(id2-1)
3316 local firstCondition = Translator.createAction("dynamic_if", condition1)
3317 local lastCondition = Translator.createAction("dynamic_if", condition2)
3318 table.insert(firstCondition.Children, lastCondition)
3320 return eventHandler, firstCondition, lastCondition
3322 else
3324 local eventHandler, firsCondition, lastCondition = nil, nil, nil
3325 eventHandler = Translator.createEvent("timer_t0_triggered", "", rtNpcGrp.Id)
3327 local prefix = ""
3328 local tab=Logic.findActivitySequenceIdByInstanceId(sequence.Parent.Parent.Parent, value)
3329 local id = tab[1]
3330 local condition = prefix .. "currentActivitySequenceVar == ".. tostring(id-1)
3331 local firstCondition = Translator.createAction("dynamic_if", condition)
3332 return eventHandler, firstCondition, firstCondition
3338 Translator.getGenericLogicEventStartOfActivitySequence = function(value, rtNpcGrp)
3339 local sequenceInstanceId = tostring(value)
3340 local sequence = r2:getInstanceFromId(sequenceInstanceId)
3341 assert(sequence)
3343 local n = table.getn(sequence.Components)
3345 if n > 0 then
3346 local firstStep = sequence.Components[0].InstanceId
3348 local eventHandler, firsCondition, lastCondition = nil, nil, nil
3350 eventHandler = Translator.createEvent("timer_t0_triggered", "", rtNpcGrp.Id)
3351 local value = tostring(firstStep)
3352 local tab=Logic.findActivityStepIdByInstanceId(sequence.Parent.Parent.Parent, value)
3353 local id, id2 = tab[1], tab[2]
3355 if (id == -1 or id2 == -1) then
3356 printWarning("error in translation: the event '"..event.Name .. "' in component '" .. hlComponent.Name ..
3357 "': the selected activity step can not be found");
3358 return nil, nil, nil
3362 local prefix = ""
3363 local condition1 = prefix .. "oldActivityStepVar2 == ".. tostring(id ) -- in theory it must be (id-1) +1
3364 local condition2 = prefix .. "currentActivitySequenceVar == ".. tostring(id2-1)
3365 local firstCondition = Translator.createAction("dynamic_if", condition1)
3366 local lastCondition = Translator.createAction("dynamic_if", condition2)
3367 table.insert(firstCondition.Children, lastCondition)
3368 return eventHandler, firstCondition, lastCondition
3369 else
3371 local eventHandler, firsCondition, lastCondition = nil, nil, nil
3372 eventHandler = Translator.createEvent("timer_t0_triggered", "", rtNpcGrp.Id)
3374 local prefix = ""
3375 local tab=Logic.findActivitySequenceIdByInstanceId(sequence.Parent.Parent.Parent, value)
3376 local id = tab[1]
3377 local condition = prefix .. "currentActivitySequenceVar == ".. tostring(id-1)
3378 local firstCondition = Translator.createAction("dynamic_if", condition)
3379 return eventHandler, firstCondition, firstCondition
3383 Translator.getNpcLogicEventBeginOfActivitySequence = function(hlComponent, context, event, rtNpcGrp)
3384 local value = tostring(event.Event.Value)
3385 return Translator.getGenericLogicEventStartOfActivitySequence(value, rtNpcGrp)
3389 Translator.getNpcLogicEventEndOfActivitySequence = function(hlComponent, context, event, rtNpcGrp)
3390 local value = tostring(event.Event.Value)
3391 return Translator.getGenericLogicEventEndOfActivitySequence(hlComponent, value, rtNpcGrp)
3396 Translator.getNpcLogicEventEndOfActivityStepImpl = function(value, rtNpcGrp)
3397 local eventHandler, firsCondition, lastCondition = nil, nil, nil
3399 eventHandler = Translator.createEvent("timer_t0_triggered", "", rtNpcGrp.Id)
3401 local step = r2:getInstanceFromId(value)
3402 assert(step)
3403 local sequence = step.Parent.Parent
3404 assert(sequence)
3405 local hlComponent = sequence.Parent.Parent.Parent
3406 assert(hlComponent)
3408 local tab=Logic.findActivityStepIdByInstanceId(hlComponent, value)
3409 local id, id2 = tab[1], tab[2]
3411 if (id == -1 or id2 == -1) then
3412 printWarning("error in translation: the event '"..event.Name .. "' in component '" .. hlComponent.Name ..
3413 "': the selected activity step can not be found");
3414 return nil, nil, nil
3418 local prefix = ""
3419 local condition1 = prefix .. "oldActivityStepVar2 == ".. tostring(id+1) -- in theory it must be (id-1) +1
3420 local condition2 = prefix .. "currentActivitySequenceVar == ".. tostring(id2-1)
3421 local firstCondition = Translator.createAction("dynamic_if", condition1)
3422 local lastCondition = Translator.createAction("dynamic_if", condition2)
3423 table.insert(firstCondition.Children, lastCondition)
3424 return eventHandler, firstCondition, lastCondition
3427 Translator.getNpcLogicEventEndOfActivityStep = function(hlComponent, context, event, rtNpcGrp)
3428 local value = tostring(event.Event.Value)
3429 return Translator.getNpcLogicEventEndOfActivityStepImpl( value, rtNpcGrp)
3433 Translator.getNpcLogicEventBeginOfActivityStepImpl = function(value, rtNpcGrp)
3434 local eventHandler, firsCondition, lastCondition = nil, nil, nil
3436 assert(rtNpcGrp)
3437 local step = r2:getInstanceFromId(value)
3438 assert(step)
3439 local sequence = step.Parent.Parent
3440 assert(sequence)
3441 local hlComponent = sequence.Parent.Parent.Parent
3442 assert(hlComponent)
3444 eventHandler = Translator.createEvent("timer_t0_triggered", "", rtNpcGrp.Id)
3446 local tab=Logic.findActivityStepIdByInstanceId(hlComponent, value)
3447 local id, id2 = tab[1], tab[2]
3449 if (id == -1 or id2 == -1) then
3450 printWarning("error in translation: the event '"..event.Name .. "' in component '" .. hlComponent.Name ..
3451 "': the selected activity step can not be found");
3452 return nil, nil, nil
3456 local prefix = ""
3457 local condition1 = prefix .. "oldActivityStepVar2 == ".. tostring(id ) -- in theory it must be (id-1) +1
3458 local condition2 = prefix .. "currentActivitySequenceVar == ".. tostring(id2-1)
3459 local firstCondition = Translator.createAction("dynamic_if", condition1)
3460 local lastCondition = Translator.createAction("dynamic_if", condition2)
3461 table.insert(firstCondition.Children, lastCondition)
3462 return eventHandler, firstCondition, lastCondition
3466 Translator.getNpcLogicEventBeginOfActivityStep = function(hlComponent, context, event, rtNpcGrp)
3467 local value = tostring(event.Event.Value)
3468 return Translator.getNpcLogicEventBeginOfActivityStepImpl( value, rtNpcGrp)
3474 Translator.getNpcLogicEventEndOfChatStepImpl = function(hlComponent, context, event, rtNpcGrp)
3475 local eventHandler, firsCondition, lastCondition = nil, nil, nil
3477 eventHandler = Translator.createEvent("timer_t1_triggered", "", rtNpcGrp.Id)
3478 local value = tostring(event.Event.Value)
3480 local tab=Logic.findChatStepIdByInstanceId(hlComponent, value)
3481 local id, id2 = tab[1], tab[2]
3485 if (id ==-1 or id2 == -1) then
3486 printWarning("error in translation: the event '"..event.Name .. "' in component '" .. hlComponent.Name ..
3487 "': the selected chat step can not be found");
3488 return nil, nil, nil
3491 local prefix = ""
3492 local condition1 = prefix.."oldChatStepVar == ".. tostring(id-1)
3493 local condition2 = prefix.."v0 == ".. tostring(id2-1)
3494 local firstCondition = Translator.createAction("dynamic_if", condition1)
3495 local lastCondition = Translator.createAction("dynamic_if", condition2)
3496 table.insert(firstCondition.Children, lastCondition)
3497 return eventHandler, firstCondition, lastCondition
3501 Translator.getNpcLogicEventEndOfChatStep = function(hlComponent, context, event, rtNpcGrp)
3502 local value = tostring(event.Event.Value)
3503 return Translator.getNpcLogicEventEndOfChatStepImpl(hlComponent, value, rtNpcGrp)
3505 --- Conditions
3508 Translator.getGenericLogicConditionIsInActivitySequence = function(entity, conditionValue, rtNpcGrp)
3509 local prefix = ""
3510 if rtNpcGrp then prefix = r2.getNamespace() ..rtNpcGrp.Id.."." end
3512 local theValue = conditionValue
3513 local tab=Logic.findActivitySequenceIdByInstanceId(entity, theValue)
3514 local id, id2 = tab[1], tab[2]
3516 assert(id ~= -1)
3518 local condition1 = prefix.."oldActivitySequenceVar == ".. tostring(id-1)
3519 local firstCondition = Translator.createAction("dynamic_if", condition1)
3520 local lastCondition = firstCondition
3521 return firstCondition, lastCondition
3525 Translator.getNpcLogicConditionIsInActivitySequence = function(entity, context, condition, rtNpcGrp)
3526 local theValue = condition.Condition.Value
3527 return Translator.getGenericLogicConditionIsInActivitySequence(entity, theValue, rtNpcGrp)
3530 Translator.getGenericLogicConditionIsInActivityStep = function(entity, conditionValue, rtNpcGrp)
3531 assert(entity and type(entity) == "userdata")
3532 assert(conditionValue and type(conditionValue) == "string")
3533 assert(rtNpcGrp and type(rtNpcGrp) == "table")
3535 local prefix = ""
3536 if rtNpcGrp then prefix = r2.getNamespace() ..rtNpcGrp.Id.."." end
3539 local theValue = conditionValue
3540 local tab=Logic.findActivityStepIdByInstanceId(entity, theValue)
3541 local id, id2 = tab[1], tab[2]
3543 assert(id ~= -1 and id2 ~= -2);
3545 local condition1 = prefix.."oldActivityStepVar2 == ".. tostring(id)
3546 local condition2 = prefix.."currentActivitySequenceVar == ".. tostring(id2-1)
3547 local firstCondition = Translator.createAction("dynamic_if", condition1)
3548 local lastCondition = Translator.createAction("dynamic_if", condition2)
3549 table.insert(firstCondition.Children, lastCondition)
3550 return firstCondition, lastCondition
3553 Translator.getNpcLogicConditionIsInActivityStep = function(entity, context, condition, rtNpcGrp)
3554 assert(entity and type(entity) == "userdata")
3555 assert(context and type(context) == "table")
3556 assert(condition and type(condition) == "userdata" and condition.Class == "ConditionStep")
3557 assert(rtNpcGrp and type(rtNpcGrp) == "table")
3559 local conditionValue = condition.Condition.Value
3560 return Translator.getGenericLogicConditionIsInActivityStep(entity, conditionValue, rtNpcGrp)
3563 Translator.getNpcLogicConditionIsDeadOrAlive = function(entity, context, condition, rtNpcGrp, isAlive)
3564 assert(entity and type(entity) == "userdata")
3565 assert(context and type(context) == "table")
3566 assert(condition and type(condition) == "userdata" and condition.Class == "ConditionStep")
3567 assert(rtNpcGrp and type(rtNpcGrp) == "table")
3569 local prefix = ""
3570 if rtNpcGrp then prefix = r2.getNamespace() ..rtNpcGrp.Id.."." end
3572 local lastCondition = Translator.createAction("dynamic_if", prefix.."alive == "..tonumber(isAlive) )
3573 local firstCondition = Translator.createAction("multi_actions",
3575 Translator.createAction("code","("..prefix.."alive)"..prefix.."isAlived();" ),
3576 lastCondition
3578 return firstCondition, lastCondition
3582 Translator.getNpcLogicConditionIsDead = function(entity, context, condition, rtNpcGrp)
3583 return Translator.getNpcLogicConditionIsDeadOrAlive(entity, context, condition, rtNpcGrp, 0)
3586 Translator.getNpcLogicConditionIsAlive = function(entity, context, condition, rtNpcGrp)
3587 return Translator.getNpcLogicConditionIsDeadOrAlive(entity, context, condition, rtNpcGrp, 1)
3591 -- Action
3593 Translator.getNpcLogicActionDeactivate = function(entity, context, action, rtNpcGrp)
3595 if (not entity or not rtNpcGrp) then
3596 return nil
3599 local prefix = ""
3600 if rtNpcGrp then prefix = r2.getNamespace() ..rtNpcGrp.Id.."." end
3602 local retAction = Translator.createAction("code", "()"..prefix.."despawn(0);", "")
3603 assert(retAction)
3604 retAction.Name = "desactivate"
3605 return retAction, retAction
3611 Translator.getNpcLogicActionActivate = function(entity, context, action, rtNpcGrp)
3613 if (not entity or not rtNpcGrp) then
3614 return nil
3617 local prefix = ""
3618 if rtNpcGrp then prefix = r2.getNamespace() ..rtNpcGrp.Id.."." end
3619 --()setAutoSpawn(1);
3620 local retAction = Translator.createAction("code", "()"..prefix.."spawn();", "")
3621 assert(retAction)
3622 retAction.Name = "activate"
3623 return retAction, retAction
3627 Translator.getNpcLogicActionKill = function(entity, context, action, rtNpcGrp)
3628 local prefix = ""
3629 if rtNpcGrp then prefix = r2.getNamespace() ..rtNpcGrp.Id.."." end
3631 local retAction = Translator.createAction("code", "()"..prefix.."setHPScale(0);")
3632 assert(retAction)
3633 retAction.Name = "kill"
3634 return retAction, retAction
3637 Translator.getGenericLogicActionBeginActivitySequence = function(sequenceInstanceId, rtNpcGrp)
3639 local activityStates = Logic.ActivitiesStates[sequenceInstanceId]
3640 assert(activityStates)
3641 local activityStatesId = activityStates[sequenceInstanceId][1].Id
3643 local retAction = Translator.createAction("code", "()"..r2:getNamespace() .. rtNpcGrp.Id .. "." .. "postNextState(\""..r2:getNamespace()..activityStatesId.."\");", rtNpcGrp.Id)
3644 return retAction, retAction
3647 Translator.getNpcLogicActionBeginActivitySequence = function(entity, context, action, rtNpcGrp)
3648 local sequenceInstanceId = action.Action.Value
3649 return Translator.getGenericLogicActionBeginActivitySequence(sequenceInstanceId, rtNpcGrp)
3653 Translator.getNpcLogicActionSitDown = function(entity, context, action, rtNpcGrp)
3654 local retAction = Translator.createAction("sit_down", rtNpcGrp.Id)
3655 assert(retAction)
3656 retAction.Name = "sitDown"
3657 return retAction, retAction
3661 Translator.getNpcLogicActionStandUp = function(entity, context, action, rtNpcGrp)
3662 local retAction =Translator.createAction("stand_up", rtNpcGrp.Id)
3663 retAction.Name = "standUp"
3664 return retAction, retAction
3668 Translator.getNpcLogicActionFightPlayer = function(entity, context, action, rtNpcGrp)
3669 local leader = entity
3670 if entity:isKindOf("NpcGrpFeature") then
3671 if table.getn(entity.Components) >= 0 then
3672 leader = entity.Components[0]
3673 else
3674 leader = nil
3677 assert(leader)
3678 local category = leader.SubCategory
3679 local aggro = leader.Aggro
3680 if not category then
3681 category = leader.Category
3682 end
3684 local action1 = Translator.createAction("set_player_attackable", rtNpcGrp.Id, 1)
3685 local action2 = r2.Translator.createAction("faction_init", rtNpcGrp.Id, category, aggro, leader.BotAttackable, 1)
3686 local retAction = r2.Translator.createAction("multi_actions", {action1, action2})
3687 retAction.Name = "Fight with player"
3688 return retAction ,retAction
3691 Translator.getNpcLogicActionDontFightPlayer = function(entity, context, action, rtNpcGrp)
3692 local leader = entity
3693 if entity:isKindOf("NpcGrpFeature") then
3694 if table.getn(entity.Components) >= 0 then
3695 leader = entity.Components[0]
3696 else
3697 leader = nil
3700 assert(leader)
3701 local category = leader.SubCategory
3702 local aggro = leader.Aggro
3703 if not category then
3704 category = leader.Category
3705 end
3707 local action1 = Translator.createAction("set_player_attackable", rtNpcGrp.Id, 0)
3708 local action2 = r2.Translator.createAction("faction_init", rtNpcGrp.Id, category, aggro, leader.BotAttackable, 0)
3709 local retAction = r2.Translator.createAction("multi_actions", {action1, action2})
3710 retAction.Name = "Dont fight with player"
3711 return retAction ,retAction
3715 Translator.getNpcLogicActionFightNpcs = function(entity, context, action, rtNpcGrp)
3716 local leader = entity
3717 if entity:isKindOf("NpcGrpFeature") then
3718 if table.getn(entity.Components) >= 0 then
3719 leader = entity.Components[0]
3720 else
3721 leader = nil
3724 assert(leader)
3725 local category = leader.SubCategory
3726 local aggro = leader.Aggro
3727 if not category then
3728 category = leader.Category
3729 end
3731 local action1 = Translator.createAction("set_bot_attackable", rtNpcGrp.Id, 1)
3732 local action2 = Translator.createAction("faction_init", rtNpcGrp.Id, category, aggro, 1, leader.PlayerAttackable)
3733 local retAction = r2.Translator.createAction("multi_actions", {action1, action2})
3734 retAction.Name = "Fight with Npcs"
3735 --inspect(action2)
3736 return retAction ,retAction
3739 Translator.getNpcLogicActionDontFightNpcs = function(entity, context, action, rtNpcGrp)
3740 local leader = entity
3741 if entity:isKindOf("NpcGrpFeature") then
3742 if table.getn(entity.Components) >= 0 then
3743 leader = entity.Components[0]
3744 else
3745 leader = nil
3748 assert(leader)
3749 local category = leader.SubCategory
3750 local aggro = leader.Aggro
3751 if not category then
3752 category = leader.Category
3753 end
3755 local action1 = Translator.createAction("set_bot_attackable", rtNpcGrp.Id, 0)
3756 local action2 = r2.Translator.createAction("faction_init", rtNpcGrp.Id, category, aggro, 0, leader.PlayerAttackable)
3758 local retAction = r2.Translator.createAction("multi_actions", {action1, action2})
3759 retAction.Name = "Dont fight with Npcs"
3760 return retAction ,retAction
3764 Translator.getNpcLogicActionRun = function(entity, context, action, rtNpcGrp)
3765 local action1 = Translator.createAction("set_running_speed", rtNpcGrp.Id)
3766 action1.Name = "Run"
3767 return action1, action1
3771 Translator.getNpcLogicActionDontRun = function(entity, context, action, rtNpcGrp)
3772 local action1 = Translator.createAction("set_walking_speed", rtNpcGrp.Id)
3773 action1.Name = "Dont run"
3774 return action1, action1
3777 Translator.getNpcLogicActionEmitsUserEvent = function(entity, context, action, rtNpcGrp)
3778 if not action.Action.ValueString then return end
3779 local value = tostring(action.Action.ValueString)
3781 local action1 = Translator.createAction("generic_event_trigger", rtNpcGrp.Id, value)
3782 action1.Name = "Trigger User Event"
3783 return action1, action1
3785 -- TODO to up
3786 -- Register an RtNpcGrp to a specific instanceId
3787 Translator.registerManager = function(context, comp)
3788 local rtNpcGrp = r2.newComponent("RtNpcGrp")
3789 table.insert(context.RtAct.NpcGrps, rtNpcGrp)
3790 context.RtGroups[tostring(comp.InstanceId)] = rtNpcGrp
3791 rtNpcGrp.Name = rtNpcGrp.Id
3795 function Translator.createAiGroup(entity, context)
3796 local rtNpcGrp = Translator.getRtGroup(context, entity.InstanceId)
3797 rtNpcGrp.GrpParameters = "ring\n".. rtNpcGrp.GrpParameters
3799 rtNpcGrp.AutoSpawn = 0
3801 local aiState = r2.newComponent("RtAiState")
3803 aiState.AiActivity = "normal"
3804 table.insert(context.RtAct.AiStates, aiState)
3805 table.insert(aiState.Children, rtNpcGrp.Id)
3806 context.GroupStatesName[rtNpcGrp.Id] = aiState.Id
3808 return rtNpcGrp, aiState
3811 function Translator.translateAiGroup(entity, context)
3812 local rtNpcGrp = Translator.getRtGroup(context, entity.InstanceId)
3813 if entity.Behavior.Actions then
3814 Translator.translateEventHandlers( context, entity, entity.Behavior.Actions, rtNpcGrp)
3820 function Translator.translateAiGroupEvent(eventName, entity, context, rtAction)
3821 assert(rtAction)
3822 --inspect(context)
3823 local rtNpcGrp = Translator.getRtGroup(context, entity.InstanceId)
3824 local states = Translator.getRtStatesNames(context, entity.InstanceId)
3825 -- local rtAct = context.RtAct
3827 local act = entity:getParentAct()
3828 local rtAct2 = context.ActIdToRtAct[act.InstanceId]
3829 local entityAct = context.Act
3831 local entityIndex = context.Scenario:getActIndex(act.InstanceId)
3832 local componentIndex = context.Scenario:getActIndex(context.Act.InstanceId)
3834 -- entity on act2, component on act1 (they can not interact)
3835 if entityIndex ~= componentIndex and entityIndex ~= 0 and componentIndex ~= 0 then
3836 return
3839 local rtAct = context.RtAct
3840 if rtAct2 ~= rtAct then
3841 local baseAct = context.Scenario:getBaseAct()
3842 local index = context.Scenario:getActIndex(context.Act.InstanceId)
3843 if index == -1 then
3844 printWarning("Invalid Scenario")
3846 -- Permanent content is known by everyone
3847 if index ~= 0 then
3848 local rtNpcGrpBase = r2.Translator.getRtGroup(context, baseAct.InstanceId)
3850 local action = Translator.createAction("test_act", rtNpcGrpBase.Id , index)
3851 table.insert(action.Children, rtAction)
3852 rtAction = action
3856 local rtEvent = Translator.createEvent(eventName, states, rtNpcGrp.Id)
3857 table.insert(rtEvent.ActionsId, rtAction.Id)
3858 table.insert(rtAct2.Events, rtEvent)
3859 table.insert(rtAct2.Actions, rtAction)
3862 function Translator.translateAiGroupInitialState(entity, context, rtAction)
3863 return Translator.translateAiGroupEvent("start_of_state", entity, context, rtAction)
3866 function Translator.translateAiGroupPlayerTargetNpc(entity, context, rtAction)
3867 return Translator.translateAiGroupEvent("player_target_npc", entity, context, rtAction)
3870 --Group
3871 Translator.getNpcGroupLogicGroupDeath= function(this, context, eventrtNpcGrp, rtNpcGrp)
3872 local eventHandler, firsCondition, lastCondition = nil, nil, nil
3873 eventHandler = Translator.createEvent("group_eliminated", "", rtNpcGrp.Id)
3874 return eventHandler, firsCondition, lastCondition
3878 function Translator.translateDialog(entity, context)
3879 local rtNpcGrp = Translator.getRtGroup(context, entity.InstanceId)
3881 local beforeWait = 0
3883 if (table.getn(entity.Components) > 0) then
3884 local i = 0
3885 while i < table.getn(entity.Components) and not entity.Components[i]:isKindOf("ChatStep") do
3886 i = i + 1
3888 if i < table.getn(entity.Components) and entity.Components[i]:isKindOf("ChatStep") then
3889 beforeWait = entity.Components[i].Time
3893 local rtEventStart = Translator.createEvent("timer_t1_triggered", "", rtNpcGrp.Id) -- Start Of Chat Step
3897 local rtDialogOk = Translator.createAction("switch_actions", Logic.chatStepVar)
3898 local rtAction = nil
3899 local rtAction2 = nil
3901 rtAction = Translator.createAction("chat_step_first", rtNpcGrp.Id, beforeWait)
3902 table.insert(rtDialogOk.Children, rtAction)
3903 local chatStepIndex = 0
3904 local componentIndex, component = next(entity.Components)
3906 local endParam = { Grps={}, Whos={}, Emotes={}, Indexs={}, Says={}, WhoNoEntitys={}}
3908 while componentIndex do
3910 if component and component:isKindOf("ChatStep") then
3911 chatStepIndex = chatStepIndex + 1
3912 local param = {}
3915 local who = r2:getInstanceFromId(component.Actions[0].Who)
3916 local facing = r2:getInstanceFromId(component.Actions[0].Facing)
3920 local whoGrp = nil
3921 local whoName = nil
3922 local facingGrp = nil
3923 local facingName = nil
3925 if who then
3926 whoGrp = Translator.getRtGroup(context, who.InstanceId)
3927 whoGrp = whoGrp.Id
3928 whoName = who.Name
3931 if facing then
3932 facingGrp = Translator.getRtGroup(context, facing.InstanceId)
3933 facingGrp = facingGrp.Id
3934 facingName = facing.Name
3937 param.WhoGrp = whoGrp
3938 param.Who = whoName
3939 param.FacingGrp = facingGrp
3940 param.Facing = facingName
3941 if not param.Facing then param.Facing = "" end
3942 param.Says = r2.Features.TextManager.getRtId(context, component.Actions[0].Says)
3943 if not param.Says then param.Says = "" end
3944 param.Emote = component.Actions[0].Emote
3945 if not param.Emote then param.Emote = "" end
3946 param.Index = chatStepIndex
3948 param.WhoNoEntity = component.Actions[0].WhoNoEntity
3949 if not param.WhoNoEntity then param.WhoNoEntity = "" end
3951 param.Break = 0
3952 if component.BreakAtEnd then
3953 param.Break = component.BreakAtEnd
3956 componentIndex, component = next(entity.Components, componentIndex)
3958 if component then
3959 param.Time = component.Time
3960 else
3961 param.Time = 3
3964 rtAction = Translator.createAction("chat_step", rtNpcGrp.Id, param)
3965 table.insert(rtDialogOk.Children, rtAction)
3967 table.insert(endParam.Indexs, param.Index)
3968 table.insert(endParam.Grps, param.WhoGrp)
3969 table.insert(endParam.Whos, param.Who)
3970 table.insert(endParam.Emotes, param.Emote)
3971 table.insert(endParam.Says, param.Says)
3972 table.insert(endParam.WhoNoEntitys, param.WhoNoEntity)
3975 else -- !if isKindOf("ChatStep")
3976 componentIndex, component = next(entity.Components, componentIndex)
3980 rtAction = Translator.createAction("chat_step_last", rtNpcGrp.Id, chatStepIndex+1)
3981 table.insert(rtDialogOk.Children, rtAction)
3985 local rtDialogStart = Translator.createAction("dynamic_if", "start == 1" , rtDialogOk )
3989 table.insert(rtEventStart.ActionsId, rtDialogStart.Id)
3990 table.insert(context.RtAct.Events, rtEventStart)
3991 table.insert(context.RtAct.Actions, rtDialogStart)
3994 local baseAct = context.Scenario:getBaseAct()
3995 local rtNpcGrpBase = r2.Translator.getRtGroup(context, baseAct.InstanceId)
3998 local rtActionEnd = Translator.createAction("chat_step_end", rtNpcGrp.Id, endParam, rtNpcGrpBase.Id)
3999 if (rtActionEnd) then
4000 local rtEvenEnd = Translator.createEvent("timer_t0_triggered", "", rtNpcGrp.Id) -- Endo Of Chat Step
4001 table.insert(rtEvenEnd.ActionsId, rtActionEnd.Id)
4002 table.insert(context.RtAct.Events, rtEvenEnd)
4003 table.insert(context.RtAct.Actions, rtActionEnd)
4009 local rtInitialState= Translator.createAction("dialog_init", rtNpcGrp.Id , entity.Repeating, entity.AutoStart )
4010 Translator.translateAiGroupInitialState(entity, context, rtInitialState)
4013 if (entity.AutoStart == 1) then
4014 local rtInitialState = r2.Translator.createAction("dynamic_if", r2:getNamespace()..rtNpcGrp.Id..".Active == 1",
4015 Translator.createAction("dialog_starts", rtNpcGrp.Id )
4017 Translator.translateAiGroupInitialState(entity, context, rtInitialState)
4021 Translator.translateAiGroup(entity, context)
4025 Translator.getNpcGroupLogicGroupAMemberDeath = Translator.getNpcLogicEventDeath
4027 -- user Event 0
4028 -- start = 1
4032 -- TODO: démêler les events (tmp: on utilise les events 7 et 8 pour respectivement activate et deactivate)
4034 function Translator.getDialogLogicAction(entity, context, action)
4035 assert( action.Class == "ActionStep")
4037 local firstAction, lastAction = nil, nil
4039 assert( action.Class == "ActionStep")
4040 local component = r2:getInstanceFromId(action.Entity)
4041 assert(component)
4042 local rtNpcGrp = Translator.getRtGroup(context, component.InstanceId)
4043 assert(rtNpcGrp)
4045 if action.Action.Type == 'activate' then
4046 local action1 = r2.Translator.createAction("set_value", rtNpcGrp.Id, "Active", 1)
4047 local action2 = r2.Translator.createAction("user_event_trigger", rtNpcGrp.Id, 7)
4048 local action3 = r2.Translator.createAction("dynamic_if", r2:getNamespace()..rtNpcGrp.Id..".AutoStart == 1",
4049 Translator.createAction("dialog_starts", rtNpcGrp.Id)
4051 local actionActivate = r2.Translator.createAction("multi_actions", {action1, action2, action3})
4053 local retAction = r2.Translator.createAction("dynamic_if", r2:getNamespace()..rtNpcGrp.Id..".Active == 0", actionActivate)
4054 return retAction, retAction
4055 elseif action.Action.Type == 'deactivate' then
4056 --local action1 = r2.Translator.createAction("set_value", rtNpcGrp.Id, "Active", 0)
4057 local action1 = r2.Translator.createAction("dialog_deactivate", rtNpcGrp.Id)
4058 local action2 = r2.Translator.createAction("user_event_trigger", rtNpcGrp.Id, 8)
4059 --local action3 = r2.Translator.createAction("dialog_stops", rtNpcGrp.Id)
4060 local retAction = r2.Translator.createAction("if_value_equal", rtNpcGrp.Id, "Active", 1,
4061 r2.Translator.createAction("multi_actions", {action1, action2}))
4062 return retAction, retAction
4063 elseif action.Action.Type == 'starts dialog' then
4064 local retAction = r2.Translator.createAction("dynamic_if", r2:getNamespace()..rtNpcGrp.Id..".Active == 1",
4065 Translator.createAction("dialog_starts", rtNpcGrp.Id)
4067 return retAction, retAction
4068 elseif action.Action.Type == 'continues dialog' then
4069 local retAction = r2.Translator.createAction("dynamic_if", r2:getNamespace()..rtNpcGrp.Id..".Active == 1",
4070 Translator.createAction("dialog_continues", rtNpcGrp.Id)
4072 return retAction, retAction
4073 elseif action.Action.Type == 'starts chat' then
4074 local index = Translator.getChatPositionFromDialog(component, action.Action.Value)
4075 if index == -1 then return nil end
4076 local retAction = r2.Translator.createAction("dynamic_if", r2:getNamespace()..rtNpcGrp.Id..".Active == 1",
4077 Translator.createAction("chat_starts", rtNpcGrp.Id, index)
4079 return retAction, retAction
4080 elseif action.Action.Type == 'stops dialog' then
4081 --add condition if Active == 1 ?
4082 local retAction = Translator.createAction("dialog_stops", rtNpcGrp.Id)
4083 return retAction, retAction
4087 printWarning('Action not implemented yet :'.. action.Action.Type)
4088 assert(nil)
4089 return nil, nil
4095 function Translator.getChatPositionFromDialog(dialog, chatInstanceId)
4096 assert(dialog)
4097 assert(dialog.Class == 'ChatSequence' or dialog.Class == "ProximityDialog")
4098 assert(chatInstanceId ~= nil and chatInstanceId ~= "")
4099 local index = -1
4100 local componentIndex, component = next(dialog.Components)
4101 while componentIndex do
4102 if component.Class == 'ChatStep' then
4103 index = index + 1
4104 if tostring(component.InstanceId) == tostring(chatInstanceId) then
4105 return index
4108 componentIndex, component = next(dialog.Components, componentIndex)
4110 return -1
4115 -- TODO: démêler les events (tmp: on utilise les events 7 et 8 pour respectivement activate et deactivate)
4117 function Translator.getDialogLogicEvent(entity, context, event)
4118 assert(entity)
4119 assert( event.Class == "LogicEntityAction")
4122 local component = entity -- r2:getInstanceFromId(event.Entity)
4123 assert(component)
4124 local rtNpcGrp = Translator.getRtGroup(context, component.InstanceId)
4125 assert(rtNpcGrp)
4127 local states = Translator.getRtStatesNames(context, entity.InstanceId)
4131 local eventType = tostring(event.Event.Type)
4133 if eventType == 'activation' then
4134 return r2.Translator.getComponentUserEvent(rtNpcGrp, 7)
4136 elseif eventType == 'deactivation' then
4137 return r2.Translator.getComponentUserEvent(rtNpcGrp, 8)
4139 elseif eventType == 'end of chat' then
4140 local action = Translator.createEvent("timer_t2_triggered", states, rtNpcGrp.Id)
4141 local index = Translator.getChatPositionFromDialog(component, event.Event.Value)
4142 if index == -1 then return nil end
4143 local firstCondition = Translator.createAction("if_value_equal", rtNpcGrp.Id, "v1", index + 2, firstCondition)
4144 return action, firstCondition, firstCondition
4146 elseif eventType == 'end of dialog' then
4147 return Translator.getComponentUserEvent(rtNpcGrp, 2)
4149 elseif eventType == 'start of chat' then
4150 local action = Translator.createEvent("user_event_4", states, rtNpcGrp.Id)
4151 local index = Translator.getChatPositionFromDialog(component, event.Event.Value)
4152 if index == -1 then return nil end
4153 local firstCondition = Translator.createAction("if_value_equal", rtNpcGrp.Id, "v1", index+2, firstCondition)
4154 return action, firstCondition, firstCondition
4156 elseif eventType == 'start of dialog' then
4157 return Translator.getComponentUserEvent(rtNpcGrp, 1)
4160 printWarning('Event not implemented yet :'.. event.Event.Type)
4161 assert(nil)
4165 Translator.getDialogLogicCondition = function(entity, context, condition )
4166 assert( condition.Class == "ConditionStep")
4167 local rtNpcGrp = Translator.getRtGroup(context, condition.Entity)
4168 assert(rtNpcGrp)
4169 local funs ={}
4171 if condition.Condition.Type == "is in dialog" then
4172 local firstCondition = Translator.createAction("if_value_equal", rtNpcGrp.Id, "start", 1)
4173 return firstCondition, firstCondition
4176 if condition.Condition.Type == "is not in dialog" then
4177 local firstCondition = Translator.createAction("if_value_equal", rtNpcGrp.Id, "start", 0)
4178 return firstCondition, firstCondition
4182 if condition.Condition.Type == "is in chat" then
4183 local index = Translator.getChatPositionFromDialog(entity, condition.Condition.Value)
4184 assert(index ~= -1)
4185 local lastCondition = Translator.createAction("if_value_equal", rtNpcGrp.Id, "v1", index+2)
4186 local firstCondition = Translator.createAction("if_value_equal", rtNpcGrp.Id, "start", 1, lastCondition)
4187 return firstCondition, lastCondition
4190 printWarning('Condition not implemented yet :'.. condition.Condition.Type)
4191 return nil, nil
4195 function Translator.translateDefaultFeature(entity, context, translateActivity)
4196 local components = entity.Components
4197 --luaObject(context.Feature)
4198 local key,comp = next(components,nil)
4199 while(key ~= nil)
4201 -- Npc case (npc alone not object)
4202 if (comp.isKindOf and comp:isKindOf("Npc")) then
4203 local hlNpc = comp
4204 context.Feature = hlNpc
4206 -- create and set rtNpc
4208 local rtNpc = r2.Translator.translateNpc(hlNpc, context)
4209 table.insert(context.RtAct.Npcs, rtNpc)
4211 -- create or get rtGrp
4212 -- set rtGrp.GroupParameter by reading hlNpc (Aggro, Player attackable..)
4213 local rtNpcGrp = r2.Translator.getRtGroup(context,hlNpc.InstanceId)
4214 r2.Translator.setGroupParameters (hlNpc, rtNpcGrp)
4215 table.insert(rtNpcGrp.Children, rtNpc.Id)
4217 -- set activity
4218 -- when translating a usercomponentholder (container which has aiActivities), we must translate the AiActivities
4219 if translateActivity and translateActivity == true
4220 then
4221 local aiActivity = r2.Translator.getAiActivity(hlNpc)
4222 r2.Translator.translateActivities(context, hlNpc, hlNpc:getBehavior(), rtNpcGrp, aiActivity)
4225 -- set eventHandlers
4226 r2.Translator.translateEventHandlers(context, hlNpc, hlNpc:getBehavior().Actions, rtNpcGrp)
4228 key,comp = next(components,key)
4232 function Translator.pretranslateDefaultFeature(this, context)
4233 local components = this.Components
4235 local key, comp = next(components, nil)
4236 while (key ~= nil) do
4237 if (comp.isKindOf and comp:isKindOf("Npc")) then
4238 local rtNpcGrp = r2.Translator.getRtGroup(context,comp.InstanceId)
4240 key, comp = next(components, key)
4244 function Translator.pretranslateDefaultFeature2(this, context)
4245 local components = this.Components
4247 local key, comp = next(components, nil)
4248 while (key ~= nil) do
4249 if (comp.isKindOf and comp:isKindOf("Npc")) then
4250 local rtNpcGrp = r2.Translator.getRtGroup(context,comp.InstanceId)
4251 -- set activity
4252 local hlNpc = comp
4253 context.Feature = hlNpc
4254 local aiActivity = r2.Translator.getAiActivity(hlNpc)
4255 r2.Translator.translateActivities(context, hlNpc, hlNpc:getBehavior(), rtNpcGrp, aiActivity)
4258 key, comp = next(components, key)
4265 function Translator.getDefaultFeatureActivitiesIds(this)
4267 local activitiesIds = {}
4269 local function getActivitiesIdsFrom(entity)
4270 local components = entity.Components
4271 local key,comp = next(components,nil)
4272 while(key ~= nil)
4274 -- Npc case (npc alone not object)
4275 if (comp.isKindOf and comp:isKindOf("Npc")) then
4276 local behavior = comp:getBehavior()
4277 local k, v = next(behavior.Activities, nil)
4278 while k do
4279 table.insert(activitiesIds, v.InstanceId)
4280 k, v = next(behavior.Activities, k)
4282 else
4283 if comp.Components then
4284 getActivitiesIdsFrom(comp)
4287 key,comp = next(components, key)
4291 getActivitiesIdsFrom(this)
4293 return activitiesIds
4298 --function Translator.getTopParentTreeNode(instance)
4299 -- local tmpInstance = instance
4300 -- if tmpInstance.ParentInstance.Class ~= "LogicEntity" and tmpInstance.ParentInstance.Class ~= "DefaultFeature"
4301 -- and tmpInstance.ParentInstance.Class ~= "Act" then
4302 -- return tmpInstance:getFeatureParentTreeNode()--tmpInstance:getParentTreeNode()
4303 -- else
4304 -- return tmpInstance:getFeatureParentTreeNode()
4305 -- end
4306 --end
4308 function Translator.getDebugBase(base)
4309 if dataDevMode then
4310 return "palette.entities.botobjects.milestone"
4311 else
4312 return base
4316 function Translator.getDebugCreature(creature)
4317 if dataDevMode then
4318 return "object_milestone.creature"
4319 else
4320 return creature
4325 -- feature generic activate & deactivate
4326 function Translator.getFeatureActivationLogicAction(rtNpcGrp, action)
4327 if (action.Action.Type == "activate") then
4328 local action1 = r2.Translator.createAction("set_value", rtNpcGrp.Id, "Active", 1)
4329 local action2 = r2.Translator.createAction("user_event_trigger", rtNpcGrp.Id, 4)
4330 local retAction = r2.Translator.createAction("multi_actions", {action1, action2})
4331 assert(retAction)
4332 return retAction, retAction
4333 elseif (action.Action.Type == "deactivate") then
4334 local action1 = r2.Translator.createAction("set_value", rtNpcGrp.Id, "Active", 0)
4335 local action2 = r2.Translator.createAction("user_event_trigger", rtNpcGrp.Id, 5)
4336 local retAction = r2.Translator.createAction("multi_actions", {action1, action2})
4337 assert(retAction)
4338 return retAction, retAction
4340 return nil, nil
4343 function Translator.getFeatureActivationLogicEvent(rtNpcGrp, event)
4345 local eventType = event.Event.Type
4346 if eventType == "activation" then
4347 return r2.Translator.getComponentUserEvent(rtNpcGrp, 4)
4348 elseif eventType == "deactivation" then
4349 return r2.Translator.getComponentUserEvent(rtNpcGrp, 5)
4351 return nil, nil, nil
4354 function Translator.getFeatureActivationCondition(condition, rtNpcGrp)
4355 if condition.Condition.Type == "is active" then
4356 local action1 = r2.Translator.createAction("if_value_equal", rtNpcGrp.Id, "Active", 1);
4357 return action1, action1
4358 elseif condition.Condition.Type == "is inactive" then
4359 local action1 = r2.Translator.createAction("if_value_equal", rtNpcGrp.Id, "Active", 0);
4360 return action1, action1
4362 return nil, nil
4366 function Translator.translateFeatureActivation(instance, context)
4367 local rtNpcGrp = r2.Translator.getRtGroup(context, instance.InstanceId)
4368 assert(rtNpcGrp)
4369 if instance.Active and instance.Active == 1 then
4370 local action1 = r2.Translator.createAction("set_value", rtNpcGrp.Id, "Active", 1)
4371 local action2 = r2.Translator.createAction("user_event_trigger", rtNpcGrp.Id, 4)
4372 local retAction = r2.Translator.createAction("multi_actions", {action1, action2})
4373 r2.Translator.translateAiGroupEvent("start_of_state" , instance, context, retAction)
4374 else
4375 local retAction = r2.Translator.createAction("set_value", rtNpcGrp.Id, "Active", 0)
4376 r2.Translator.translateAiGroupEvent("start_of_state" , instance, context, retAction)
4381 function Translator.addActivationToTranslations(logicTranslations)
4382 if logicTranslations.ApplicableActions == nil then logicTranslations.ApplicableActions = {} end
4383 --logicTranslations.ApplicableActions.activate = {menu=i18n.get("uiR2EdActivate"):toUtf8(), text="activates"}
4384 --logicTranslations.ApplicableActions.deactivate = {menu=i18n.get("uiR2EdDesactivate"):toUtf8(), text="deactivates"}
4385 --logicTranslations.ApplicableActions.trigger = {menu=i18n.get("uiR2EdTrigger"):toUtf8(), text="triggers"}
4387 if logicTranslations.Events == nil then logicTranslations.Events = {} end
4388 --logicTranslations.Events.activation = {menu=i18n.get("uiR2EdActivation"):toUtf8(), text=r2:lowerTranslate("uiR2EdActivation")}
4389 --logicTranslations.Events.deactivation = {menu=i18n.get("uiR2EdDesactivation"):toUtf8(), text=r2:lowerTranslate("uiR2EdDesactivation")}
4390 --logicTranslations.Events.trigger = {menu=i18n.get("uiR2EdTrigger"):toUtf8(), text=r2:lowerTranslate("uiR2EdTrigger")}
4392 if logicTranslations.Conditions == nil then logicTranslations.Conditions = {} end
4393 --logicTranslations.Conditions["is active"] = {menu=i18n.get("uiR2EdIsActive"):toUtf8(), text=r2:lowerTranslate("uiR2EdIsActive")}
4394 --logicTranslations.Conditions["is inactive"] = {menu=i18n.get("uiR2EdIsInactive"):toUtf8(), text=r2:lowerTranslate("uiR2EdIsInactive")}
4395 return logicTranslations
4399 function Translator.CreateUserComponent(featureName)
4400 if not featureName or featureName == "" then
4401 debugInfo("Translator: calling createUserComponent on nil or empty featureName")
4402 return
4405 local function posOk(x, y, z)
4406 debugInfo(string.format("Validate creation of '"..featureName.."' at pos (%d, %d, %d)", x, y, z))
4407 local component = r2.Features[featureName].createUserComponent( x, y)
4408 component.Texts = nil
4409 r2.requestInsertNode(r2:getCurrentAct().InstanceId, "Features", -1, "", component)
4412 local function posCancel()
4413 debugInfo("Cancel choice '"..featureName.."' position")
4416 r2:choosePos("object_component_user_event.creature", posOk, posCancel, "")
4419 function Translator.CheckPickedEntity(component, prop)
4420 local k, v = next(prop, nil)
4421 while k do
4422 local property = v
4424 if property.Type and property.Type == "RefId" then
4425 local this = r2:getInstanceFromId(component.InstanceId)
4427 local targetId = this[property.Name]
4429 if targetId ~= r2.RefId("") then
4430 debugInfo("targetId:" ..targetId)
4431 local filterFunc = "return " ..property.PickFunction .."('"..targetId.."')"
4432 debugInfo("filterfunc: " ..filterFunc)
4433 local ok = loadstring(filterFunc)()
4434 if ok == false then
4435 debugInfo("name: " ..property.Name)
4436 r2.requestSetNode(this.InstanceId, property.Name, r2.RefId(""))
4441 k, v = next(prop, k)
4448 function Translator.checkActForPicking(componentId, entityId)
4449 local component = r2:getInstanceFromId(componentId)
4450 assert(component)
4451 --debugInfo("CheckActForPicking: EntityId =" ..entityId)
4452 --inspect(component)
4453 local entity = r2:getInstanceFromId(entityId)
4454 assert(entity)
4456 return entity:getParentAct().InstanceId == r2.Scenario.Acts[0].InstanceId
4457 or entity:getParentAct().InstanceId == component:getParentAct().InstanceId
4461 function Translator.getEventFromType(instance, context, eventType)
4462 if not context or not instance or not instance.getLogicEvent then return nil end
4463 local fakeEvent = {}
4464 fakeEvent.Class = "LogicEntityAction"
4465 fakeEvent.Event = {}
4466 fakeEvent.Event.Type = eventType
4467 return instance:getLogicEvent(context, fakeEvent)
4470 ----------------------------------------
4471 --- TASK MODULE ------------------------
4472 ----------------------------------------
4474 Translator.Tasks = {}
4476 --Start of state (init) = event 7
4477 function Translator.Tasks.startOfStateLogic(component, context, rtGrp)
4479 local action = r2.Translator.createAction("user_event_trigger", rtGrp.Id, 7)
4480 r2.Translator.translateAiGroupEvent("start_of_state" , component, context, action)
4484 local repeatable = component.Repeatable
4485 if not repeatable then repeatable = 0 end
4487 local rtAction1 = r2.Translator.createAction("set_value", rtGrp.Id, "Active", component.Active)
4488 local rtAction2 = r2.Translator.createAction("set_value", rtGrp.Id, "v1", repeatable)
4489 local rtAction3 = r2.Translator.createAction("set_value", rtGrp.Id, "v2", 0)
4490 local rtAction3 = r2.Translator.createAction("set_value", rtGrp.Id, "v3", 0) -- Success
4491 local rtAction = r2.Translator.createAction("multi_actions", { rtAction1, rtAction2, rtAction3, } )
4492 r2.Translator.translateAiGroupEvent("user_event_7", component, context, rtAction)
4496 --Activation = event 4
4497 function Translator.Tasks.activationLogic(component, context, rtGrp)
4499 local repeatable = component.Repeatable
4500 if not repeatable then repeatable = 0 end
4502 local rtAction1 = r2.Translator.createAction("set_value", rtGrp.Id, "Active", 1)
4503 local rtAction2 = r2.Translator.createAction("set_value", rtGrp.Id, "v1", repeatable)
4504 local rtAction3 = r2.Translator.createAction("set_value", rtGrp.Id, "v2", 0) -- Success
4505 local rtAction = r2.Translator.createAction("multi_actions", { rtAction1, rtAction2, rtAction3, } )
4506 r2.Translator.translateAiGroupEvent("user_event_4", component, context, rtAction)
4510 --Deactivation = event 5
4511 function Translator.Tasks.deactivationLogic(component, context, rtGrp)
4513 local rtAction = r2.Translator.createAction("multi_actions", {
4514 r2.Translator.createAction("set_value", rtGrp.Id, "Active", 0 ),
4515 r2.Translator.createAction("set_value", rtGrp.Id, "v2", 0 ),
4517 r2.Translator.translateAiGroupEvent("user_event_5", component, context, rtAction)
4521 --When using talkTo, giveItem or requestItem actions, event 3 is emitted when the player took the missin (contextual validation)
4522 function Translator.Tasks.setStatusLogic(component, context, rtGrp)
4524 local action = r2.Translator.createAction("set_value", rtGrp.Id, "v2", 1 )
4525 r2.Translator.translateAiGroupEvent("user_event_3", component, context, action)
4529 --Success = event 9
4530 --No broadcast means the broadcast action is done elsewhere in the translate (not on success)
4531 function Translator.Tasks.successNoBroadcastLogic(component, context, rtGrp)
4533 --if repeatable
4534 local action1 = r2.Translator.createAction("if_value_equal", rtGrp.Id, "v1", 1,
4535 r2.Translator.createAction("multi_actions", {
4536 r2.Translator.createAction("set_value", rtGrp.Id, "Active", 1 ),
4537 r2.Translator.createAction("set_value", rtGrp.Id, "v2", 0 ),
4538 r2.Translator.createAction("set_value", rtGrp.Id, "v3", 1 ),
4541 --if not repeatable
4542 local action2 = r2.Translator.createAction("if_value_equal", rtGrp.Id, "v1", 0,
4543 r2.Translator.createAction("multi_actions", {
4544 r2.Translator.createAction("set_value", rtGrp.Id, "Active", 0 ) ,
4545 r2.Translator.createAction("set_value", rtGrp.Id, "v2", 2 ),
4546 r2.Translator.createAction("set_value", rtGrp.Id, "v3", 1 ),
4547 r2.Translator.createAction("user_event_trigger", rtGrp.Id, 5),
4551 local actions = r2.Translator.createAction("multi_actions", {action1, action2})
4553 local action = r2.Translator.createAction("if_value_equal", rtGrp.Id, "v2", 2,
4554 r2.Translator.createAction("condition_if", r2:getNamespace()..rtGrp.Id..".Active == 1", actions))
4555 r2.Translator.translateAiGroupEvent("user_event_9", component, context, action)
4559 --Success with broadcast : for components using event 8 as an intermediate step.
4560 function Translator.Tasks.successBroadcastLogic(component, context, rtGrp)
4561 local validationNeeded = component.ValidationNeeded
4563 local action2 = r2.Translator.createAction("if_value_equal", rtGrp.Id, "v1", 1, --if Repeatable
4564 r2.Translator.createAction("multi_actions", {
4565 r2.Translator.createAction("set_value", rtGrp.Id, "Active", 1 ),
4566 r2.Translator.createAction("set_value", rtGrp.Id, "v2", 0 ),
4567 r2.Translator.createAction("set_value", rtGrp.Id, "v3", 1 ),
4570 local action3 = r2.Translator.createAction("if_value_equal", rtGrp.Id, "v1", 0, -- if not Repeatable
4571 r2.Translator.createAction("multi_actions", {
4572 r2.Translator.createAction("set_value", rtGrp.Id, "Active", 0 ) ,
4573 r2.Translator.createAction("set_value", rtGrp.Id, "v2", 2 ),
4574 r2.Translator.createAction("set_value", rtGrp.Id, "v3", 1 ),
4575 r2.Translator.createAction("user_event_trigger", rtGrp.Id, 5)
4579 local actions = {}
4580 if validationNeeded == 1 then
4581 actions = {action2, action3}
4582 else
4583 local baseAct = r2.Scenario:getBaseAct()
4584 local baseActRtGrp = r2.Translator.getRtGroup(context, baseAct.InstanceId)
4585 local actionBroadcast = r2.Translator.createAction("broadcast_msg",baseActRtGrp.Id, component:textAdapter(component.BroadcastText) )
4587 actions = {action2, action3, actionBroadcast}
4589 local multiActions = r2.Translator.createAction("multi_actions", actions)
4591 local action = r2.Translator.createAction("if_value_equal", rtGrp.Id, "v2", 2,
4592 r2.Translator.createAction("if_value_equal", rtGrp.Id, "Active", 1, multiActions))
4593 r2.Translator.translateAiGroupEvent("user_event_9", component, context, action)
4596 --When validation is needed, emit success event when targeting mission giver
4597 function Translator.Tasks.validationByMissionGiver(component, giver, context, rtGrp)
4598 local rtGiverGrp = r2.Translator.getRtGroup(context, giver.InstanceId)
4599 assert(rtGiverGrp)
4601 local actionEvent = r2.Translator.createAction("user_event_trigger", rtGrp.Id, 9)
4603 local action1 = r2.Translator.createAction("npc_say", component:textAdapter(component.MissionSucceedText), rtGiverGrp.Id ..":"..giver.Name)
4605 local action = r2.Translator.createAction("if_value_equal", rtGrp.Id, "v2", 2,
4606 r2.Translator.createAction("condition_if", r2:getNamespace()..rtGrp.Id..".Active == 1",
4607 r2.Translator.createAction("multi_actions", {actionEvent, action1})))
4609 r2.Translator.translateAiGroupEvent("player_target_npc", giver, context, action)
4613 -- when receiving event 8, just broadcast a msg indicating that the mission is successful but that the player has
4614 -- to go back to the giver to complete it.
4615 function Translator.Tasks.broadcastOnEvent8(component, context)
4616 local baseAct = r2.Scenario:getBaseAct()
4617 local baseActRtGrp = r2.Translator.getRtGroup(context, baseAct.InstanceId)
4618 local actionBroadcast = r2.Translator.createAction("broadcast_msg",baseActRtGrp.Id, component:textAdapter(component.BroadcastText) )
4620 r2.Translator.translateAiGroupEvent("user_event_8", component, context, actionBroadcast)
4623 function Translator.Tasks.giverLogic(component, giver, context, rtGrp)
4624 local rtGiverGrp = r2.Translator.getRtGroup(context, giver.InstanceId)
4625 assert(rtGiverGrp)
4627 local actionWaitValidation = r2.Translator.createAction("if_value_equal", rtGrp.Id, "Active", 1, -- Active
4628 r2.Translator.createAction("if_value_equal", rtGrp.Id, "v2", 1, -- giver has been spoken to
4629 r2.Translator.createAction("multi_actions", {
4630 r2.Translator.createAction("npc_say", component:textAdapter(component.WaitValidationText), rtGiverGrp.Id ..":"..giver.Name),
4631 r2.Translator.createAction("user_event_trigger", rtGrp.Id, 2)
4632 })))
4634 --say mission text + contextual text (talk to)
4635 local multiActions = r2.Translator.createAction("multi_actions", {
4636 r2.Translator.createAction("npc_say", component:textAdapter(component.MissionText), rtGiverGrp.Id ..":"..giver.Name),
4637 r2.Translator.createAction("talk_to", rtGrp.Id, component:textAdapter(component.ContextualText)),
4640 local actionTalkTo = r2.Translator.createAction("if_value_equal", rtGrp.Id, "Active", 1, -- Active
4641 r2.Translator.createAction("if_value_equal", rtGrp.Id, "v2", 0, multiActions))
4643 local rtAction = r2.Translator.createAction("multi_actions", {actionWaitValidation, actionTalkTo})
4645 r2.Translator.translateAiGroupEvent("player_target_npc", giver, context, rtAction)