local registerFeature = function () local feature={} feature.Name="DefaultFeature" feature.Description="The default feature" feature.Components= { ActiveLogicEntity = { Name="ActiveLogicEntity", BaseClass="LogicEntity", DisplayerVisual = "R2::CDisplayerVisualEntity", DisplayerVisualParams = { InheritDisplayMode = true }, DisplayerUI = "R2::CDisplayerLua", DisplayerUIParams = "defaultUIDisplayer", DisplayerProperties = "R2::CDisplayerLua", DisplayerPropertiesParams = "activeLogicEntityPropertySheetDisplayer", Menu="ui:interface:r2ed_entity_menu", Prop= { {Name="Behavior", Type="Behavior"}, {Name="ActivitiesId",Type="Table" }, }, isNextSelectable = function(this) return true end, --------------------------------------------------------------------------------------------------------- -- get list of command for display in the mini toolbar getAvailableMiniCommands = function(this, result) -- OBSOLETE --local result = this:delegate():getAvailableMiniCommands(this) r2.Classes.LogicEntity.getAvailableMiniCommands(this, result) end, -------------------------------------------------------------------------------------------- -- Test if this entity is a bot object isBotObject = function(this) return false end, -------------------------------------------------------------------------------------------- -- Test if thisentity is a plant isPlant = function(this) return false end, -------------------------------------------------------------------------------------------- -- is it a named entity ? isNamed = function(this) if this.IsNamed and this.IsNamed == 1 then return true end return false end, -------------------------------------------------------------------------------------------- addPrimitiveActivities = function (this, dest, activityWnd) if activityWnd then table.insert(dest, "Wander") table.insert(dest, "Follow Route") table.insert(dest, "Patrol") table.insert(dest, "Repeat Road") table.insert(dest, "Stand Still") else table.insert(dest, this:buildActivityCommand(this.onPickWanderZone, "wander_zone", "uimR2EDMenuPickZone", "r2_toolbar_wander_zone.tga", true)) table.insert(dest, this:buildActivityCommand(this.onPickFollowRoute, "follow_route", "uimR2EDMenuFollowRoute", "r2_toolbar_follow_road.tga", false)) table.insert(dest, this:buildActivityCommand(this.onPickPatrolRoute, "patrol_route", "uimR2EDMenuPatrolRoute", "r2_toolbar_patrol_road.tga", false)) table.insert(dest, this:buildActivityCommand(this.onPickRepeatRoute, "repeat_route", "uimR2EDMenuRepeatRoute", "r2_toolbar_repeat_road.tga", false)) table.insert(dest, this:buildActivityCommand(this.onStandStill, "stand_still", "uimR2EDMenuStandInPlace", "r2_toolbar_stand_still.tga", false)) end end, -- from 'BaseClass' getAvailableCommands = function(this, dest, activityWnd) --local result = this:delegate():getAvailableCommands(this) if not activityWnd then r2.Classes.LogicEntity.getAvailableCommands(this, dest) end local category = this:getCategory() if category == "Herbivore" then if this:isNamed() then if activityWnd then table.insert(dest, "Guard Zone") table.insert(dest, "Follow Route") table.insert(dest, "Patrol") table.insert(dest, "Repeat Road") table.insert(dest, "Stand Still") else table.insert(dest, this:buildActivityCommand(this.onPickGuardZone, "guard_zone", "uimR2EDMenuPickGuardZone", "r2ed_toolbar_guard_zone.tga", true)) table.insert(dest, this:buildActivityCommand(this.onPickFollowRoute, "follow_route", "uimR2EDMenuFollowRoute", "r2_toolbar_follow_road.tga", false)) table.insert(dest, this:buildActivityCommand(this.onPickPatrolRoute, "patrol_route", "uimR2EDMenuPatrolRoute", "r2_toolbar_patrol_road.tga", false)) table.insert(dest, this:buildActivityCommand(this.onPickRepeatRoute, "repeat_route", "uimR2EDMenuRepeatRoute", "r2_toolbar_repeat_road.tga", false)) table.insert(dest, this:buildActivityCommand(this.onStandStill, "stand_still", "uimR2EDMenuStandInPlace", "r2_toolbar_stand_still.tga", false)) end else if activityWnd then table.insert(dest, "Rest In Zone") table.insert(dest, "Feed In Zone") else table.insert(dest, this:buildActivityCommand(this.onPickRestZone, "rest_zone", "uimR2EDMenuPickRestZone", "r2ed_toolbar_rest_zone.tga", true)) table.insert(dest, this:buildActivityCommand(this.onPickFeedZone, "feed_zone", "uimR2EDMenuPickFeedZone", "r2ed_toolbar_feed_zone.tga", false)) end end elseif category == "Carnivore" then if this:isNamed() then if activityWnd then table.insert(dest, "Guard Zone") table.insert(dest, "Follow Route") table.insert(dest, "Patrol") table.insert(dest, "Repeat Road") table.insert(dest, "Stand Still") else table.insert(dest, this:buildActivityCommand(this.onPickGuardZone, "guard_zone", "uimR2EDMenuPickGuardZone", "r2ed_toolbar_guard_zone.tga", true)) table.insert(dest, this:buildActivityCommand(this.onPickFollowRoute, "follow_route", "uimR2EDMenuFollowRoute", "r2_toolbar_follow_road.tga", false)) table.insert(dest, this:buildActivityCommand(this.onPickPatrolRoute, "patrol_route", "uimR2EDMenuPatrolRoute", "r2_toolbar_patrol_road.tga", false)) table.insert(dest, this:buildActivityCommand(this.onPickRepeatRoute, "repeat_route", "uimR2EDMenuRepeatRoute", "r2_toolbar_repeat_road.tga", false)) table.insert(dest, this:buildActivityCommand(this.onStandStill, "stand_still", "uimR2EDMenuStandInPlace", "r2_toolbar_stand_still.tga", false)) end else if activityWnd then table.insert(dest, "Rest In Zone") table.insert(dest, "Hunt In Zone") else table.insert(dest, this:buildActivityCommand(this.onPickRestZone, "rest_zone", "uimR2EDMenuPickRestZone", "r2ed_toolbar_rest_zone.tga", true)) table.insert(dest, this:buildActivityCommand(this.onPickHuntZone, "hunt_zone", "uimR2EDMenuPickHuntZone", "r2ed_toolbar_hunt_zone.tga", false)) end end --table.insert(dest, this:buildActivityCommand(this.onPickGuardZone, "guard_zone", "uimR2EDMenuPickGuardZone", "r2ed_toolbar_guard_zone.tga", true)) elseif category == "WorkerKitin" then if activityWnd then table.insert(dest, "Feed In Zone") table.insert(dest, "Follow Route") table.insert(dest, "Patrol") table.insert(dest, "Repeat Road") table.insert(dest, "Stand Still") --table.insert(dest, "Guard Zone") else table.insert(dest, this:buildActivityCommand(this.onPickFeedZone, "feed_zone", "uimR2EDMenuPickWorkZone", "r2ed_toolbar_work_zone.tga", true)) table.insert(dest, this:buildActivityCommand(this.onPickFollowRoute, "follow_route", "uimR2EDMenuFollowRoute", "r2_toolbar_follow_road.tga", false)) table.insert(dest, this:buildActivityCommand(this.onPickPatrolRoute, "patrol_route", "uimR2EDMenuPatrolRoute", "r2_toolbar_patrol_road.tga", false)) table.insert(dest, this:buildActivityCommand(this.onPickRepeatRoute, "repeat_route", "uimR2EDMenuRepeatRoute", "r2_toolbar_repeat_road.tga", false)) table.insert(dest, this:buildActivityCommand(this.onStandStill, "stand_still", "uimR2EDMenuStandInPlace", "r2_toolbar_stand_still.tga", false)) --table.insert(dest, this:buildActivityCommand(this.onPickGuardZone, "guard_zone", "uimR2EDMenuPickGuardZone", "r2ed_toolbar_guard_zone.tga", true)) end elseif category == "SoldierKitin" then if activityWnd then table.insert(dest, "Guard Zone") table.insert(dest, "Follow Route") table.insert(dest, "Patrol") table.insert(dest, "Repeat Road") table.insert(dest, "Stand Still") else table.insert(dest, this:buildActivityCommand(this.onPickGuardZone, "guard_zone", "uimR2EDMenuPickGuardZone", "r2ed_toolbar_guard_zone.tga", true)) table.insert(dest, this:buildActivityCommand(this.onPickFollowRoute, "follow_route", "uimR2EDMenuFollowRoute", "r2_toolbar_follow_road.tga", false)) table.insert(dest, this:buildActivityCommand(this.onPickPatrolRoute, "patrol_route", "uimR2EDMenuPatrolRoute", "r2_toolbar_patrol_road.tga", false)) table.insert(dest, this:buildActivityCommand(this.onPickRepeatRoute, "repeat_route", "uimR2EDMenuRepeatRoute", "r2_toolbar_repeat_road.tga", false)) table.insert(dest, this:buildActivityCommand(this.onStandStill, "stand_still", "uimR2EDMenuStandInPlace", "r2_toolbar_stand_still.tga", false)) end elseif not this:isBotObject() and not this:isPlant() then -- activity (only if not a plant) this:addPrimitiveActivities(dest, activityWnd) end end, -- for activities UI getAvailableActivities = function(this, dest) r2.Classes.ActiveLogicEntity.getAvailableCommands(this, dest, true) end, -------------------------------------------------------------------------------------------- -- Called when the menu is displayed onSetupMenu = function(this) --this:delegate():onSetupMenu() r2.Classes.LogicEntity.onSetupMenu(this) local class = r2:getClass(this) local isBO = this:isBotObject() local isPlant = this:isPlant() getUI(class.Menu .. ":activities").active = not isBO and not isPlant if not isBO and not isPlant then getUI(class.Menu .. ":activities").uc_hardtext = i18n.get("uimR2EDNewActivity") end end, -------------------------------------------------------------------------------------------- -- function to change activity onStandStill = function(this) r2:setNPCStandInPlace(this) end, onPickWanderZone = function(this) runAH(nil, "r2ed_picker_lua", "CursCanPickPos=curs_create.tga|CursCannotPickPos=curs_stop.tga|TestFunc=r2:testCanPickZoneForNPC|PickFunc=r2:affectZoneToSelectedNPC|PickPosFunc=r2:createZoneAndAffectZoneToNPC|WantMouseUp=true|IgnoreInstances=Npc,Road") r2.ContextualCommands:highlightCommandButton("wander_zone") end, onPickRestZone = function(this) runAH(nil, "r2ed_picker_lua", "CursCanPickPos=curs_create.tga|CursCannotPickPos=curs_stop.tga|TestFunc=r2:testCanPickZoneForNPC|PickFunc=r2:affectRestZoneToSelectedNPC|PickPosFunc=r2:createRestZoneAndAffectZoneToNPC|WantMouseUp=true|IgnoreInstances=Npc,Road") r2.ContextualCommands:highlightCommandButton("rest_zone") end, onPickFeedZone = function(this) runAH(nil, "r2ed_picker_lua", "CursCanPickPos=curs_create.tga|CursCannotPickPos=curs_stop.tga|TestFunc=r2:testCanPickZoneForNPC|PickFunc=r2:affectFeedZoneToSelectedNPC|PickPosFunc=r2:createFeedZoneAndAffectZoneToNPC|WantMouseUp=true|IgnoreInstances=Npc,Road") r2.ContextualCommands:highlightCommandButton("feed_zone") end, onPickHuntZone = function(this) runAH(nil, "r2ed_picker_lua", "CursCanPickPos=curs_create.tga|CursCannotPickPos=curs_stop.tga|TestFunc=r2:testCanPickZoneForNPC|PickFunc=r2:affectHuntZoneToSelectedNPC|PickPosFunc=r2:createHuntZoneAndAffectZoneToNPC|WantMouseUp=true|IgnoreInstances=Npc,Road") r2.ContextualCommands:highlightCommandButton("hunt_zone") end, onPickGuardZone = function(this) runAH(nil, "r2ed_picker_lua", "CursCanPickPos=curs_create.tga|CursCannotPickPos=curs_stop.tga|TestFunc=r2:testCanPickZoneForNPC|PickFunc=r2:affectGuardZoneToSelectedNPC|PickPosFunc=r2:createGuardZoneAndAffectZoneToNPC|WantMouseUp=true|IgnoreInstances=Npc,Road") r2.ContextualCommands:highlightCommandButton("guard_zone") end, onPickFollowRoute = function(this) runAH(nil, "r2ed_picker_lua", "CursCanPickPos=curs_create.tga|CursCannotPickPos=curs_stop.tga|TestFunc=r2:testCanPickRoadForNPC|PickFunc=r2:setBehaviorFollowRouteToNPC|PickPosFunc=r2:createRouteAndSetBehaviorFollowRouteToNPC|WantMouseUp=true|IgnoreInstances=Npc, Region ") r2.ContextualCommands:highlightCommandButton("follow_route") end, onPickPatrolRoute = function(this) runAH(nil, "r2ed_picker_lua", "CursCanPickPos=curs_create.tga|CursCannotPickPos=curs_stop.tga|TestFunc=r2:testCanPickRoadForNPC|PickFunc=r2:setBehaviorPatrolRouteToNPC|PickPosFunc=r2:createRouteAndSetBehaviorPatrolRouteToNPC|WantMouseUp=true|IgnoreInstances=Npc,Region") r2.ContextualCommands:highlightCommandButton("patrol_route") end, onPickRepeatRoute = function(this) runAH(nil, "r2ed_picker_lua", "CursCanPickPos=curs_create.tga|CursCannotPickPos=curs_stop.tga|TestFunc=r2:testCanPickRoadForNPC|PickFunc=r2:setBehaviorRepeatRoadToNPC|PickPosFunc=r2:createRoadAndSetBehaviorRepeatRoadToNPC|WantMouseUp=true|IgnoreInstances=Npc,Region") r2.ContextualCommands:highlightCommandButton("repeat_route") end, --------------------------------------------------------------------------------------------------------- -- From base class isSequencable = function(this) return not this:isPlant() and not this:isBotObject() end, --------------------------------------------------------------------------------------------------------- -- From base class getActivityVerbLookupName = function (this, activityName) if this.Category == "WorkerKitin" and activityName == "Feed In Zone" then return "Work In Zone" end return activityName end, initEventValuesMenu = function(this, menu, categoryEvent) -- activity sequences for ev=0,menu:getNumLine()-1 do local eventType = tostring(menu:getLineId(ev)) if r2.events.eventTypeWithValue[eventType] == "Number" then menu:addSubMenu(ev) local subMenu = menu:getSubMenu(ev) local func = "" for i=0, 9 do local uc_name = ucstring() uc_name:fromUtf8( tostring(i) ) func = "r2.events:setEventValue('','" .. categoryEvent .."','".. tostring(i).."')" subMenu:addLine(uc_name, "lua", func, tostring(i)) end elseif r2.events.eventTypeWithValue[eventType]~=nil then menu:addSubMenu(ev) local subMenu = menu:getSubMenu(ev) for s=0, this:getBehavior().Activities.Size-1 do local sequence = this:getBehavior().Activities[s] local func = "" if r2.events.eventTypeWithValue[eventType]=="ActivitySequence" then func = "r2.events:setEventValue('".. sequence.InstanceId .."','" .. categoryEvent .."')" end local uc_name = ucstring() uc_name:fromUtf8(sequence:getName()) subMenu:addLine(uc_name, "lua", func, sequence.InstanceId) end if this:getBehavior().Activities.Size==0 then subMenu:addLine(i18n.get("uiR2EdNoSelelection"), "", "", "") -- activity steps elseif r2.events.eventTypeWithValue[eventType]=="ActivityStep" then for s=0,subMenu:getNumLine()-1 do local sequenceId = tostring(subMenu:getLineId(s)) local sequence = r2:getInstanceFromId(sequenceId) assert(sequence) subMenu:addSubMenu(s) local activitiesMenu = subMenu:getSubMenu(s) for a=0, sequence.Components.Size-1 do local activity = sequence.Components[a] local uc_name = ucstring() uc_name:fromUtf8(activity:getShortName()) activitiesMenu:addLine(uc_name, "lua", "r2.events:setEventValue('".. activity.InstanceId .."','" .. categoryEvent .."')", activity.InstanceId) end -- no activity in the sequence if sequence.Components.Size==0 then activitiesMenu:addLine(i18n.get("uiR2EdNoSelelection"), "", "", "") end end end end end end, }, Behavior = { Name="Behavior", BaseClass="LogicEntityBehavior", Prop= { {Name="Type", Type="String",DefaultValue=""},--TEMP {Name="ZoneId", Type="String"},--TEMP {Name="Activities",Type="Table"}, {Name="ChatSequences",Type="Table"} }, }, ------------------------------------------------------------------------------------------------------ Npc = { PropertySheetHeader = r2.DisplayNpcHeader(), Name="Npc", InEventUI = true, BaseClass="ActiveLogicEntity", DisplayerVisual = "R2::CDisplayerVisualEntity", DisplayerUI = "R2::CDisplayerLua", DisplayerUIParams = "defaultUIDisplayer", DisplayerProperties = "R2::CDisplayerLua", DisplayerPropertiesParams = "npcPropertySheetDisplayer", ----------------------------------------------------------------------------------------------- Parameters = { }, ApplicableActions = { "Activate", "Deactivate", "Kill", "begin activity sequence", "Sit Down", "Stand Up", "Fight with player", "Fight with Npcs", "Dont fight with player", "Dont fight with Npcs", "Run", "Dont run", -- "emits user event", }, Events = { "activation", "desactivation", "death", "end of activity step", "end of activity sequence", "begin of activity step", "begin of activity sequence", -- "user event emitted", "targeted by player" }, Conditions = { --"is dead", "is alive", "is active", "is inactive", "is dead", "is alive", "is in activity sequence", "is in activity step", }, TextContexts = { "NPC is dead", "NPC is alive" }, TextParameters = { }, LiveParameters = { "is active", "current activity sequence and activity step", "current chat sequence and chat step" }, ----------------------------------------------------------------------------------------------- Prop= { {Name="Base", Type="String", WidgetStyle="StaticText", Category="Advanced", Visible=false}, {Name="Name", Type="String", DefaultInBase=1, MaxNumChar="32"}, {Name="Angle", Type="Number", WidgetStyle="Slider", Min="0", Max="360", -------------------- convertToWidgetValue = function(value) local result = math.mod(math.floor(180 * value / math.pi), 360) if result < 0 then result = 360 + result end return result end, -------------------- convertFromWidgetValue = function(value) return math.pi * math.min(359, value) / 180 end, }, { Name="PlayerAttackable", Type="Number", WidgetStyle="Boolean", Default="0", DefaultInBase=1, Visible=function(this) return this:isGroupedAndLeader() or not this:isGrouped() and not this:isBotObject() and this:canUpdatePlayerAttackable() end }, { Name="BotAttackable", Type="Number", WidgetStyle="Boolean", Default="0", DefaultInBase=1, Visible=function(this) return this:isGroupedAndLeader() or not this:isGrouped() and not this:isBotObject() and this:canUpdateBotAttackable() end }, -- { -- Name="UseFame", Type="Number", WidgetStyle="Boolean", Default="0", DefaultInBase=1, -- Visible=function(this) return this.SubCategory and ( this.SubCategory == "Kami" or this.SubCategory == "Karavan") end -- }, { Name="AutoSpawn", Type="Number", WidgetStyle="Boolean", Default="0", DefaultInBase=1, --Visible=function(this) return not this:isBotObject() end Visible = function(this) return this:isGroupedAndLeader() or not this:isGrouped() and not this:isBotObject() end }, { Name="NoRespawn", Type="Number", WidgetStyle="Boolean", Default="0", DefaultInBase=1, Visible=function(this) return this:isGroupedAndLeader() or not this:isGrouped() and not this:isBotObject() end }, {Name="Aggro", Type="Number", Min="0", Max="120", DefaultValue="30", DefaultInBase=1, Visible=function(this) return this:isGroupedAndLeader() or not this:isGrouped() and not this:isBotObject() end }, {Name="TypeNPC", Type="Number", WidgetStyle="EnumDropDown", SecondRequestFunc=r2.updateType, Enum= {}, Visible=true, DefaultValue="-1", }, -- -- --{Name="TestRefId", Type="RefId", Category="uiR2EDRollout_Test"}, }, isGroupedAndLeader = function(this) if this:isGrouped() and this:isLeader() then return true end return false end, TreeIcon= function(this) if this:isKindOf("NpcCreature") or this:isKindOf("NpcPlant") then return "r2ed_icon_creatures.tga" elseif not this:isBotObject() then return "r2ed_icon_npc.tga" end return "" end, PermanentTreeIcon= function(this) if this:isKindOf("NpcCreature") or this:isKindOf("NpcPlant") then return "r2ed_icon_permanent_creatures.tga" elseif not this:isBotObject() then return "r2ed_permanent_node.tga" end return "" end, --------------------------------------------------------------------------------------------------------- -- get select bar type SelectBarType = function(this) if not this:isBotObject() then return i18n.get("uiR2EDScene"):toUtf8() else return i18n.get("uiR2EDbotObjects"):toUtf8() end end, --------------------------------------------------------------------------------------------------------- -- from base class getContextualTreeIcon = function(this) if this:getParentAct():isBaseAct() then return this:getPermanentTreeIcon() end return "" end, getSelectBarIcon = function(this) if this:isBotObject() then return "r2ed_icon_botobject.tga" else return r2.Classes.BaseClass.getContextualTreeIcon(this) end end, ---------------------------------------------- updatePermanentStatutIcon = function(this) --this.DisplayerVisual:updatePermanentStatutIcon(this:getContextualTreeIcon()) this.DisplayerVisual:updatePermanentStatutIcon(this:getPermanentStatutIcon()) end, -------------------------------------------------------------------------------------------- onPostCreate= function(this) if this.BoxSelection == 1 and this.DisplayerVisual ~= nil then -- read in palette this.DisplayerVisual.SelectionDisplayMode = 1 end if this:isBotObject() then this.DisplayerVisual.DisplayMode = select(r2.BotObjectsFrozen, 2, 0) end end, onActChanged = function(this) if this:isBotObject() then this.DisplayerVisual.DisplayMode = select(r2.BotObjectsFrozen, 2, 0) end end, -------------------------------------------------------------------------------------------- -- from WorldObject isDisplayModeToggleSupported = function(this, displayMode) if not this:isBotObject() then return displayMode == 3 end return false end, -------------------------------------------------------------------------------------------- -- Test if this entity is a bot object isBotObject = function(this) return r2:isBotObject(this.SheetClient) end, canUpdatePlayerAttackable = function(this) if this.CanUpdatePlayerAttackable == 0 then return false end if this.CanUpdatePlayerAttackable == 1 then return true end return this:isBotObject() == false end, canUpdateBotAttackable = function(this) return this:isBotObject() == false end, -------------------------------------------------------------------------------------------- -- Test if this entity is a plant isPlant = function(this) return string.match(this.SheetClient, "cp[%w_]*%.creature") end, -------------------------------------------------------------------------------------------- -- check if that npc is the leader of its group isLeader = function(this) if not this:isGrouped() then return false end return this.IndexInParent == 0 end, -------------------------------------------------------------------------------------------- -- return the group of this npc if it has one, else return nil getParentGroup = function(this) if this.ParentInstance:isKindOf("NpcGrpFeature") then return this.ParentInstance else return nil end end, -------------------------------------------------------------------------------------------- -- change the mouse to choose a new group to group with onChooseGroup = function(this) if this:isGrouped() then return end runAH(nil, "r2ed_picker_lua", "TestFunc=r2:testCanGroupSelectedInstance|PickFunc=r2:groupSelectedInstance") r2.ContextualCommands:highlightCommandButton("group") end, -------------------------------------------------------------------------------------------- -- if this npc was part of a group, ungroup it onUngroup = function(this) r2:ungroup(this) end, -------------------------------------------------------------------------------------------- -- If this npc is part of a group, make it the leader of its group onSetAsLeader = function(this) if this:isLeader() then return end r2:setAsGroupLeader(this) end, -------------------------------------------------------------------------------------------- -- from 'BaseClass' getAvailableCommands = function(this, dest) --local result = this:delegate():getAvailableCommands(this) r2.Classes.ActiveLogicEntity.getAvailableCommands(this, dest) if not this:isBotObject() and not this:isPlant() then if not this:isGrouped() then table.insert(dest, this:buildCommand(this.onChooseGroup, "group", "uimR2EDMenuGroup", "r2_toolbar_group.tga", true)) else table.insert(dest, this:buildCommand(this.onUngroup, "ungroup", "uimR2EDMenuUngroup", "r2_toolbar_ungroup.tga", true)) if not this:isLeader() then table.insert(dest, this:buildCommand(this.onSetAsLeader, "set_as_leader", "uimR2EDMenuSetAsGroupLeader", "r2_toolbar_set_as_leader.tga", false)) end end --debugInfo(this.SheetClient) end this:getAvailableDisplayModeCommands(dest) end, -------------------------------------------------------------------------------------------- -- from 'BaseClass' getParentTreeNode = function(this) if not this:isInDefaultFeature() then return r2.Classes.ActiveLogicEntity.getParentTreeNode(this) end if this:isBotObject() then local container = getUI("ui:interface:r2ed_scenario") --return {container:find("content_tree_list"):getRootNode():getNodeFromId("scenery_objects")} return {container:find("content_tree_list"):getRootNode()} elseif ( this:isKindOf("NpcCreature") or this:isKindOf("NpcPlant") ) then return this:getParentAct():getContentTreeNodes("creatures") else return this:getParentAct():getContentTreeNodes("people") end end, -------------------------------------------------------------------------------------------- -- special handler for deletion : this method is called when the user click on 'delete' in the -- context menu and should perform the actual deletion onDelete = function(this) if this.User.DeleteInProgress == true then return end this.User.DeleteInProgress = true this:setDeleteActionName() -- if deleted object is not in the default group, and was the last of its group, then -- its parent group should be removed if not this:isInDefaultFeature() then if this.Parent.Size <= 2 then local parentTable = this.Parent local parentGroup = this.ParentInstance local defaultFeature = this:getParentAct():getDefaultFeature() for i = parentTable.Size - 1, 0, -1 do if parentTable[i].InstanceId ~= this.InstanceId then parentTable[i]:requestMakePosRelativeTo(defaultFeature) r2:setSelectedInstanceId(parentTable[i].InstanceId) r2.requestMoveNode(parentTable[i].InstanceId, "", -1, defaultFeature.InstanceId, "Components", -1) break end end r2.requestEraseNode(parentGroup.InstanceId, "", -1) r2.requestEndAction() return end end this:selectNext() r2.requestEraseNode(this.InstanceId, "", -1) r2.requestEndAction() end, -------------------------------------------------------------------------------------------- -- return the behavior object, depending on wether this npc is grouped or not getBehavior = function(this) if this:isGrouped() and this.ParentInstance:isKindOf("NpcGrpFeature") then return this.ParentInstance.Components[0].Behavior else return this.Behavior end end, ----------------------------------------------------------------------------------------------- -- from base class hasScenarioCost = function(this) return true end, ----------------------------------------------------------------------------------------------- -- from base class isCopyable = function(this) return true end, ----------------------------------------------------------------------------------------------- -- from base class paste = function(src, newPlace, srcInstanceId) local Q, leftQ, leftStaticQ = r2:getLeftQuota() local quota = leftQ if r2:isBotObject(r2.getPropertyValue(src, "SheetClient")) then quota = leftStaticQ end if quota <= 0 then r2:makeRoomMsg() return end local options = { CopyEvents = 0, CopyActivities = 0, -- CopyChatSequences = 0 DuplicateGroup = -1 } -- if component is the leader and original group is still present, then give the option to duplicate the whole group local srcInstance if srcInstanceId then srcInstance = r2:getInstanceFromId(srcInstanceId) end local groupCopy = nil if srcInstance and srcInstance:isLeader() then groupCopy = srcInstance.ParentInstance:copy() groupCopy = r2.Classes[groupCopy.Class].newCopy(groupCopy) options.DuplicateGroup = 0 -- offer option to do the copy end if srcInstance and srcInstance.isBotObject then if srcInstance:isBotObject() then if not r2:checkStaticQuota() then return end else if not r2:checkAiQuota() then return end end end -- local function paramsOk(options) if options.DuplicateGroup == 1 then r2.Classes[groupCopy.Class].paste(groupCopy, src.Position, nil, options) return end if options.CopyActivities == 0 then src.ActivitiesId = {} src.Behavior.Activities = {} end if options.CopyEvents == 0 then src.Behavior.Actions = {} end --if options.CopyChatSequences == 0 then -- src.Behavior.ChatSequences = {} -- end if newPlace then src.Position.x, src.Position.y, src.Position.z = r2:getPastePosition() end r2:setCookie(src.InstanceId, "Select", true) if r2:isBotObject(r2.getPropertyValue(src, "SheetClient")) then -- not already an object, so can't call a method yet ... -- add to permanent content r2.requestInsertNode(r2.Scenario:getBaseAct():getDefaultFeature().InstanceId , "Components",-1,"", src) else -- insert in current act r2.requestInsertNode(r2:getCurrentAct():getDefaultFeature().InstanceId , "Components", -1,"", src) end end local function paramsCancel() debugInfo('paste was cancelled') end if table.getn(src.Behavior.Activities) == 0 then options.CopyActivities = -1 end if table.getn(src.Behavior.Actions) == 0 then options.CopyEvents = -1 end --if table.getn(src.Behavior.ChatSequences) == 0 then -- options.CopyChatSequences = -1 -- end if options.CopyActivities >= 0 or options.CopyEvents >= 0 --or options.CopyChatSequences >= 0 then r2:doForm("SpecialPaste", options, paramsOk, paramsCancel) else -- nothing specific to copy, do direct paste paramsOk(options) end end, ----------------------------------------------------------------------------------------------- -- from base class pasteGhost = function(src) local target if r2:isBotObject(r2.getPropertyValue(src, "SheetClient")) then -- not already an object, so can't call a method yet ... -- insert in current act target = r2.Scenario:getBaseAct():getDefaultFeature() if not r2:checkStaticQuota() then return end else -- insert in current act target = r2:getCurrentAct():getDefaultFeature() if not r2:checkAiQuota() then return end end -- create the 'Ghosts' entry locally if it doesn't already exists if target.Ghosts == nil then r2.requestInsertGhostNode(target.InstanceId, "", -1, "Ghosts", {}) end -- r2.requestInsertGhostNode(target.InstanceId, "Ghosts",-1,"", src) -- insertion should have been done right now return r2:getInstanceFromId(src.InstanceId) end, getAiCost = function(this) if this.User.GhostDuplicate then return 0 end assert(this) if this.IsBotObject == 0 then return 1 end return 0 end, getStaticObjectCost = function(this) if this.User.GhostDuplicate then return 0 end assert(this) if this.IsBotObject == 1 then return 1 end return 0 end, -- from 'ActiveLogicEntity' getApplicableActions = function(this) local actions = r2.Classes[this.Class].ApplicableActions if not this:canUpdateBotAttackable() then local actionsTemp = {} for k, v in pairs(actions) do if v~="Fight with Npcs" and v~="Dont fight with Npcs" then --and v~="Sit Down" and v~="Stand Up" then table.insert(actionsTemp, v) end end actions = actionsTemp end if not this:canUpdatePlayerAttackable() then local actionsTemp = {} for k, v in pairs(actions) do if v~="Fight with player" and v~="Dont fight with player" then -- and v~="Sit Down" and v~="Stand Up" then table.insert(actionsTemp, v) end end actions = actionsTemp end return actions end, }, ------------------------------------------------------------------------------------------------------ -- a 'custom' npc : this is a npc that is customizable NpcCustom = { Name="NpcCustom", BaseClass="Npc", DisplayerProperties = "R2::CDisplayerLua", DisplayerPropertiesParams = "npcCustomPropertySheetDisplayer", Prop= { -- Look (all widgets have Visible=false because they are edited in the npc editor, not in the property sheet) { Name="GabaritHeight", Type="Number", Visible=false, DefaultInBase=1 }, { Name="GabaritTorsoWidth", Type="Number", Visible=false, DefaultInBase=1 }, { Name="GabaritArmsWidth", Type="Number", Visible=false, DefaultInBase=1 }, { Name="GabaritLegsWidth", Type="Number", Visible=false, DefaultInBase=1 }, { Name="GabaritBreastSize", Type="Number", Visible=false, DefaultInBase=1 }, { Name="HairType", Type="Number", Visible=false, DefaultInBase=1 }, { Name="HairColor", Type="Number", Visible=false, DefaultInBase=1 }, { Name="Tattoo", Type="Number", Visible=false, DefaultInBase=1 }, { Name="EyesColor", Type="Number", Visible=false, DefaultInBase=1 }, { Name="MorphTarget1", Type="Number", Visible=false, DefaultInBase=1 }, { Name="MorphTarget2", Type="Number", Visible=false, DefaultInBase=1 }, { Name="MorphTarget3", Type="Number", Visible=false, DefaultInBase=1 }, { Name="MorphTarget4", Type="Number", Visible=false, DefaultInBase=1 }, { Name="MorphTarget5", Type="Number", Visible=false, DefaultInBase=1 }, { Name="MorphTarget6", Type="Number", Visible=false, DefaultInBase=1 }, { Name="MorphTarget7", Type="Number", Visible=false, DefaultInBase=1 }, { Name="MorphTarget8", Type="Number", Visible=false, DefaultInBase=1 }, --{ Name="Sex", Type="Number", Visible=false, DefaultInBase=1 }, { Name="JacketModel", Type="Number", Visible=false, DefaultInBase=1 }, { Name="TrouserModel", Type="Number", Visible=false, DefaultInBase=1 }, { Name="FeetModel", Type="Number", Visible=false, DefaultInBase=1 }, { Name="HandsModel", Type="Number", Visible=false, DefaultInBase=1 }, { Name="ArmModel", Type="Number", Visible=false, DefaultInBase=1 }, { Name="WeaponRightHand", Type="Number", Visible=false, DefaultInBase=1 }, { Name="WeaponLeftHand", Type="Number", Visible=false, DefaultInBase=1 }, { Name="JacketColor", Type="Number", Visible=false, DefaultInBase=1 }, { Name="ArmColor", Type="Number", Visible=false, DefaultInBase=1 }, { Name="HandsColor", Type="Number", Visible=false, DefaultInBase=1 }, { Name="TrouserColor", Type="Number", Visible=false, DefaultInBase=1 }, { Name="FeetColor", Type="Number", Visible=false, DefaultInBase=1 }, { Name="LinkColor", Type="Number", Visible=false, DefaultInBase=0 }, --{ Name="Notes", Type="String", Visible=false, DefaultInBase=1 }, { Name="Function", Type="String", Visible=false, DefaultInBase=1 }, --{ Name="Level", Type="String", Visible=false, DefaultInBase=1 }, { Name="Profile", Type="String", Visible=false, DefaultInBase=1 }, {Name="Speed", Type="Number", WidgetStyle="EnumDropDown", Category="uiR2EDRollout_NpcCustom", Enum= { "uiR2EDWalk", "uiR2EDRun"}, Visible=true }, {Name="Level", Type="Number", WidgetStyle="EnumDropDown", Category="uiR2EDRollout_NpcCustom", Enum= { "uiR2EDLowLevel", "uiR2EDAverageLevel", "uiR2EDHighLevel", "uiR2EDVeryHighLevel"}, SecondRequestFunc=r2.updateLevel, Visible=function(this) return this:isGroupedAndLeader() or not this:isGrouped() and not this:isBotObject() end }, }, -- from "BaseClass" getAvailableCommands = function(this, dest) --local result = this:delegate():getAvailableCommands() r2.Classes.Npc.getAvailableCommands(this, dest) end, -- Additionnal property sheet header to access npc customisation PropertySheetHeader = [[ ]], -- Pop the npc editor customizeLook = function(this) -- if the npc edition window is not shown, display it local npcEditionWnd = getUI("ui:interface:r2ed_npc") if not npcEditionWnd.active then npcEditionWnd.active = true npcEditionWnd:updateCoords() npcEditionWnd:center() -- update the npc window content this.DisplayerProperties:updateAll(this) else setTopWindow(npcEditionWnd) npcEditionWnd:blink(1) end end, ----------------------------------------------------------------------------------------------- -- from base class hasScenarioCost = function(this) return true end, ----------------------------------------------------------------------------------------------- -- special paste with renaming paste = function(src, newPlace, srcInstanceId) local base = r2.getPaletteElement(src.Base) local sex = r2.getPropertyValue(base, "Sex") r2.Classes.Npc.paste(src, newPlace, srcInstanceId) end, }, ------------------------------------------------------------------------------------------------------ -- NPC CREATURE NpcCreature = { Name="NpcCreature", InEventUI = true, BaseClass="Npc", DisplayerProperties = "R2::CDisplayerLua", DisplayerPropertiesParams = "npcPropertySheetDisplayer", Prop= { {Name="Speed", Type="Number", WidgetStyle="EnumDropDown", Category="uiR2EDRollout_Default", Enum= { "uiR2EDWalk", "uiR2EDRun"}, Visible=function(this) return not this:isKindOf("NpcPlant") end, }, }, getApplicableActions = function(this) local actions = r2.Classes[this.Class].ApplicableActions local actionsTemp = {} for k, v in pairs(actions) do if v~="Sit Down" and v~="Stand Up" then table.insert(actionsTemp, v) end end return actionsTemp end, }, ------------------------------------------------------------------------------------------------------ -- NPC PLANT NpcPlant = { Name="NpcPlant", InEventUI = true, BaseClass="NpcCreature", DisplayerProperties = "R2::CDisplayerLua", DisplayerPropertiesParams = "npcPropertySheetDisplayer", Prop= { }, ApplicableActions = { "Activate", "Deactivate", "Kill", }, Events = { "activation", "desactivation", "death", }, Conditions = {}, }, -- base class for primitives, include copy-paste code { BaseClass="WorldObject", Name="BasePrimitive", Prop= { {Name="Name", Type="String", MaxNumChar="32"} }, -------------------------------------------------------------------------------------------- onPostCreate = function(this) this.DisplayerVisual.DisplayMode = r2:getPrimDisplayMode() this.DisplayerVisual.ContextualVisibilityActive = r2.PrimDisplayContextualVisibility end, onActChanged = function(this) this.DisplayerVisual.ContextualVisibilityActive = r2.PrimDisplayContextualVisibility end, -------------------------------------------------------------------------------------------- onPostCreate = function(this) this.DisplayerVisual.DisplayMode = r2:getPrimDisplayMode() this.DisplayerVisual.ContextualVisibilityActive = r2.PrimDisplayContextualVisibility end, onActChanged = function(this) this.DisplayerVisual.ContextualVisibilityActive = r2.PrimDisplayContextualVisibility end, -------------------------------------------------------------------------------------------- -- from WorldObject canChangeDisplayMode = function(this) return true end, ----------------------------------------------------------------------------------------------- -- from base class isCopyable = function(this) return true end, isNextSelectable = function(this) return true end, ----------------------------------------------------------------------------------------------- -- from base class getAvailableCommands = function(this, dest) r2.Classes.WorldObject.getAvailableCommands(this, dest) -- fill by ancestor table.insert(dest, this:buildCommand(this.onNewVertexTool, "new_vertex", "uimR2EDAddNewVertices", "r2ed_tool_new_vertex.tga")) end, ----------------------------------------------------------------------------------------------- onNewVertexTool = function(this) r2:setCurrentTool('R2::CToolNewVertex') r2.ContextualCommands:highlightCurrentCommandButton("new_vertex") end, ----------------------------------------------------------------------------------------------- -- from base class paste = function(src, newPlace, srcInstanceId) --if r2:getLeftQuota() <= 0 then -- r2:makeRoomMsg() -- return --end if newPlace then --if r2.Classes[src.Class].isCopyInsideCurrIsland(src) then -- src.Position.x = src.Position.x + 4 * (math.random() - 0.5) -- src.Position.y = src.Position.y + 4 * (math.random() - 0.5) -- src.Position.z = src.Position.z + 4 * (math.random() - 0.5) --else local mx, my, mz = r2.Classes[src.Class].getCopyCenter(src) -- express in world mx = mx + src.Position.x my = my + src.Position.y mz = mz + src.Position.z -- get player pos in world local px, py, pz = getPlayerPos() -- add delta to have primitive center in world over player pos src.Position.x = src.Position.x + px - mx + 4 * (math.random() - 0.5) src.Position.y = src.Position.y + py - my + 4 * (math.random() - 0.5) src.Position.z = src.Position.z + pz - mz + 4 * (math.random() - 0.5) --end end r2.requestInsertNode(r2.Scenario:getBaseAct():getDefaultFeature().InstanceId, "Components", -1, "", src) r2:setCookie(src.InstanceId, "Select", true) end, ----------------------------------------------------------------------------------------------- -- Function (not method) : test if the passed primitive copy (obtained -- with BasePrimitive:copy is inside the current island -- The default behavior is to test each vertices inside the 'Points' array -- are inside the current island rectangle. If a derivers is not defined -- as a set of points, it should provide the good test here isCopyInsideCurrIsland = function(src) for k, v in pairs(src.Points) do if not r2:isInIslandRect(v.Position.x, v.Position.y) then return false end end return true end, ----------------------------------------------------------------------------------------------- -- Function (not method) : return the center a a copîed primitive obtained with -- BasePrimitive:copy getCopyCenter = function(src) local x = 0 local y = 0 local z = 0 local count = 0 for k, v in pairs(src.Points) do x = x + v.Position.x y = y + v.Position.y z = z + v.Position.z count = count + 1 end if count ~= 0 then x = x / count y = y / count z = z / count end return x, y, z end, ----------------------------------------------------------------------------------------------- -- from base class pasteGhost = function(src) --if r2:getLeftQuota() <= 0 then -- r2:makeRoomMsg() -- return --end target = r2.Scenario:getBaseAct():getDefaultFeature() if target.Ghosts == nil then r2.requestInsertGhostNode(target.InstanceId, "", -1, "Ghosts", {}) end r2.requestInsertNode(target.InstanceId, "Ghosts", -1, "", src) return r2:getInstanceFromId(src.InstanceId) end, }, ------------------------------------------------------------------------------------------------------ { BaseClass="BasePrimitive", Name="Region", Menu="ui:interface:r2ed_base_menu", TreeIcon= function(this) if this:isInDefaultFeature() then return "" else return "r2ed_icon_region.tga" end end, DisplayerUI = "R2::CDisplayerLua", DisplayerUIParams = "defaultUIDisplayer", DisplayerVisual = "R2::CDisplayerVisualGroup", DisplayerVisualParams = { Look = r2.PrimRender.RegionLook, InvalidLook = r2.PrimRender.RegionInvalidLook, -- ArrayName = "Points" }, Prop= { -- {Name="Base", Type="String", WidgetStyle="StaticText", Category="Advanced"}, {Name="Points", Type="Table"}, }, -------------------------------------------------------------------------------------------- getSelectBarIcon = function(this) return "r2ed_icon_region.tga" end, getAvailableCommands = function(this, dest) r2.Classes.BasePrimitive.getAvailableCommands(this, dest) -- fill by ancestor this:getAvailableDisplayModeCommands(dest) end, --------------------------------------------------------------------------------------------------------- -- get select bar type SelectBarType = function(this) return i18n.get("uiR2EDbotObjects"):toUtf8() end, -------------------------------------------------------------------------------------------- -- from 'BaseClass' getParentTreeNode = function(this) -- if not this:isInDefaultFeature() then -- return r2.Classes.WorldObject.getParentTreeNode(this) -- end -- local tree = getUI("ui:interface:r2ed_scenario") -- return tree:find("content_tree_list"):getRootNode():getNodeFromId("places") return {} end, ----------------------------------------------------------------------------------------------- -- from base class --getUsedQuota = function(this) -- return 1 --end }, ------------------------------------------------------------------------------------------------------ { BaseClass="BasePrimitive", Name="Road", --DisplayerVisual = "R2::CDisplayerVisualRoad", DisplayerVisual = "R2::CDisplayerVisualGroup", TreeIcon= function(this) if this:isInDefaultFeature() then return "" else return "r2ed_icon_road.tga" end end, DisplayerVisualParams = { Look = r2.PrimRender.RoadLook, InvalidLook = r2.PrimRender.RoadLookInvalid, -- ArrayName = "Points" }, DisplayerUI = "R2::CDisplayerLua", DisplayerUIParams = "defaultUIDisplayer", Menu="ui:interface:r2ed_base_menu", Prop= { -- {Name="Base", Type="String", WidgetStyle="StaticText", Category="Advanced"}, {Name="Points", Type="Table"} }, -------------------------------------------------------------------------------------------- getSelectBarIcon = function(this) return "r2ed_icon_road.tga" end, --------------------------------------------------------------------------------------------------------- -- get select bar type SelectBarType = function(this) return i18n.get("uiR2EDbotObjects"):toUtf8() end, -------------------------------------------------------------------------------------------- -- from 'BaseClass' getParentTreeNode = function(this) -- if not this:isInDefaultFeature() then -- return r2.Classes.WorldObject.getParentTreeNode(this) -- end -- local tree = getUI("ui:interface:r2ed_scenario") -- return tree:find("content_tree_list"):getRootNode():getNodeFromId("routes") return {} end, ----------------------------------------------------------------------------------------------- -- from base class getAvailableCommands = function(this, dest) r2.Classes.BasePrimitive.getAvailableCommands(this, dest) -- fill by ancestor table.insert(dest, this:buildCommand(this.onExtendRoad, "extend_road", "uiR2EDExtendRoad", "r2ed_tool_extend_prim.tga")) this:getAvailableDisplayModeCommands(dest) end, ----------------------------------------------------------------------------------------------- onExtendRoad = function(this) r2:setCurrentTool('R2::CToolDrawPrim', { Look = r2.PrimRender.RoadCreateLook, InvalidLook = r2.PrimRender.RoadCreateInvalidLook, Type="Road", ExtendedPrimitiveId = this.InstanceId } ) r2.ContextualCommands:highlightCurrentCommandButton("extend_road") end, ----------------------------------------------------------------------------------------------- -- from base class --getUsedQuota = function(this) -- return 1 --end }, ------------------------------------------------------------------------------------------------------ { BaseClass="WorldObject", Name="WayPoint", BuildPropertySheet = false, DisplayerVisual = "R2::CDisplayerVisualShape", DisplayerVisualParams = { ShapeName = r2.PrimRender.RoadCreateLook.VertexShapeName, Scale = r2.PrimRender.RoadCreateLook.VertexShapeScale, InheritDisplayMode = true }, DisplayerUI = "", Menu="ui:interface:r2ed_base_menu", Prop= { -- NOTE : position inherit from 'WorldObject' }, onDelete = function(this) if this.User.DeleteInProgress == true then return end this.User.DeleteInProgress = true this:setDeleteActionName() -- if I'm the last in the array, then delete my parent if this.Parent.Size <= 2 then this.ParentInstance:selectNext() r2.requestEraseNode(this.ParentInstance.InstanceId, "", -1) else -- just delete my self this:selectNext() r2.requestEraseNode(this.InstanceId, "", -1) end r2.requestEndAction() end, setDeleteActionName = function(this) r2.requestNewAction(i18n.get("uiR2EDDeletingWayPoint")) end, isNextSelectable = function(this) return true end }, ------------------------------------------------------------------------------------------------------ { BaseClass="WorldObject", Name="RegionVertex", BuildPropertySheet = false, DisplayerVisual = "R2::CDisplayerVisualShape", DisplayerVisualParams = { ShapeName = r2.PrimRender.RegionCreateLook.VertexShapeName, Scale = r2.PrimRender.RegionCreateLook.VertexShapeScale, InheritDisplayMode = true }, DisplayerUI = "", Menu="ui:interface:r2ed_base_menu", Prop= { -- NOTE : position inherit from 'WorldObject' }, setDeleteActionName = function(this) r2.requestNewAction(i18n.get("uiR2EDDeletingRegionVertex")) end, onDelete = function(this) if this.User.DeleteInProgress == true then return end this.User.DeleteInProgress = true this:setDeleteActionName() -- if I'm the last in the array, then delete my parent if this.Parent.Size <= 3 then this.ParentInstance:selectNext() r2.requestEraseNode(this.ParentInstance.InstanceId, "", -1) else -- just delete my self this:selectNext() r2.requestEraseNode(this.InstanceId, "", -1) end r2.requestEndAction() end, isNextSelectable = function(this) return true end }, ------------------------------------------------------------------------------------------------------ { BaseClass="BasePrimitive", Name="Place", DisplayerUI = "R2::CDisplayerLua", DisplayerUIParams = "defaultUIDisplayer", Menu="ui:interface:r2ed_base_menu", Prop= { {Name="Radius", Type="Number"} }, -- from BasePrimitive isCopyInsideCurrIsland = function(src) return r2:isInIslandRect(src.Position.x, src.Position.y) end, -- from BasePrimitive getCopyCenter = function(src) return src.Position.x, src.Position.y, src.Position.z end, -- getAvailableCommands = function(this, dest) r2.Classes.BasePrimitive.getAvailableCommands(this, dest) -- fill by ancestor this:getAvailableDisplayModeCommands(dest) end, }, ------------------------------------------------------------------------------------------------------ { BaseClass="BaseClass", Name="Position", DisplayerUI = "", Prop= { {Name="x", Type="Number"}, {Name="y", Type="Number"}, {Name="z", Type="Number"} }, -- test if this position is equal to another position (not necessarily an instance, -- may be any table with the { x = ..., y = ..., z = ... } format equals = function(this, other) return this.x == other.x and this.y == other.y and this.z == other.z end, -- return string version of position toString = function(this) return "(" .. tostring(this.x) .. ", " .. tostring(this.y) .. ", " .. tostring(this.z) .. ")" end }, UserComponentHolder = { BaseClass="LogicEntity", Name="UserComponentHolder", Menu="ui:interface:r2ed_feature_menu", DisplayerUI = "R2::CDisplayerLua", DisplayerUIParams = "defaultUIDisplayer", DisplayerVisual = "R2::CDisplayerVisualEntity", Parameters = {}, ApplicableActions = {}, Events = {}, Conditions = {}, TextContexts = {}, TextParameters = {}, LiveParameters = {}, Prop = { {Name="InstanceId", Type="String", WidgetStyle="StaticText", Visible = false}, {Name="Name", Type="String"}, {Name="Description", Type="String"}, {Name="Components", Type="Table", Visible=false}, }, getParentTreeNode = function(this) return this:getFeatureParentTreeNode() end, appendInstancesByType = function(this, destTable, kind) assert(type(kind) == "string") r2.Classes.LogicEntity.appendInstancesByType(this, destTable, kind) for k, component in specPairs(this.Components) do component:appendInstancesByType(destTable, kind) end end, getSelectBarSons = function(this) return Components end, canHaveSelectBarSons = function(this) return false; end, onPostCreate = function(this) end, pretranslate = function(this, context) r2.Translator.createAiGroup(this, context) r2.Translator.pretranslateDefaultFeature(this, context) end, translate = function(this, context) r2.Translator.translateDefaultFeature(this, context, true) end, getActivitiesIds = r2.Translator.getDefaultFeatureActivitiesIds, -- TODO use sexy images getAvailableCommands = function(this, dest) r2.Classes.LogicEntity.getAvailableCommands(this, dest) table.insert(dest, this:buildActivityCommand(this.onPickAddEntity, "add_entity", "uimR2EDMenuPickAddEntity", "r2_toolbar_customize_look.tga", true)) table.insert(dest, this:buildActivityCommand(this.onPickRemoveEntity, "remove_entity", "uimR2EDMenuPickRemoveEntity", "r2_toolbar_delete.tga", false)) table.insert(dest, this:buildActivityCommand(this.onPickExport, "export", "uimR2EDMenuPickExport", "r2_toolbar_properties.tga", false)) end, }, } -- !feature.Components ------------------------------------------------------------------------------------------------------ classLogicEntityBehaviorVersion = 1 feature.Components.LogicEntityBehavior = { Name="LogicEntityBehavior", BaseClass="BaseClass", Version = classLogicEntityBehaviorVersion, Prop= { {Name="Actions", Type="Table"}, -- {Name="Reactions", Type="Table"} }, updateVersion = function(this, scenarioValue, currentValue) local patchValue = scenarioValue if patchValue < 1 then -- Patch only for old save (not the 0.0.3) if this.Reactions ~= nil then -- TODO use identifier instead r2.requestEraseNode(this.InstanceId, "Reactions", -1) end patchValue = 1 end if patchValue == currentValue then return true end return false end } ------------------------------------------------------------------------------------------------------ local userComponentHolder = feature.Components.UserComponentHolder userComponentHolder.getLogicAction = function(entity, context, action) local firstAction, lastAction = nil,nil return firstAction, lastAction end userComponentHolder.getLogicCondition = function(this, context, condition) return nil,nil end userComponentHolder.getLogicEvent = function(this, context, event) local eventHandler, firstCondition, lastCondition = nil, nil, nil return eventHandler, firstCondition, lastCondition end function userComponentHolder:registerMenu(logicEntityMenu) local name = i18n.get("uiR2EdUserComponent") logicEntityMenu:addLine(ucstring(name), "lua", "", "uiR2EdUserComponent") end function userComponentHolder:getLogicTranslations() local logicTranslations = { ["ApplicableActions"] = {}, ["Events"] = {}, } return logicTranslations end function userComponentHolder.onPickExport(this) local refX = this.Position.x local refY = this.Position.y local refZ = this.Position.z local components = this.Components r2_core.UserComponentManager.CurrentDesc = this.Description local exportList = {} local k, v = next(components, nil) while k do if v.InstanceId then table.insert(exportList, v.InstanceId) end k, v = next(components, k) end r2_core.UserComponentManager:export(exportList, refX, refY, refZ) end function userComponentHolder.create() if not r2:checkAiQuota() then return end local function paramsCancel() debugInfo("Cancel form for 'User Component' creation") end local function posOk(x, y, z) debugInfo(string.format("Validate creation of 'User Component' at pos (%d, %d, %d)", x, y, z)) if r2.mustDisplayInfo("UserComponent") == 1 then r2.displayFeatureHelp("UserComponent") end local component = r2.newComponent("UserComponentHolder") component.Base = r2.Translator.getDebugBase("palette.entities.botobjects.user_event") component.Name = r2:genInstanceName(i18n.get("uiR2EdUserComponent")):toUtf8() component.Position.x = x component.Position.y = y component.Position.z = r2:snapZToGround(x, y) r2:setCookie(component.InstanceId, "DisplayProp", 1) r2.requestInsertNode(r2:getCurrentAct().InstanceId, "Features", -1, "", component) end local function posCancel() debugInfo("Cancel choice 'User Component' position") end local creature = r2.Translator.getDebugCreature("object_component_user_event.creature") r2:choosePos(creature, posOk, posCancel, "createUserComponent") end function userComponentHolder:registerMenu(logicEntityMenu) local name = i18n.get("uiR2EdUserComponent") logicEntityMenu:addLine(ucstring(name), "lua", "", "uiR2EdUserComponent") end function userComponentHolder.onPickAddEntity(this) r2_core.CurrentHolderId = this.InstanceId runAH(nil, "r2ed_picker_lua", "CursCanPickPos=curs_create.tga|CursCannotPickPos=curs_stop.tga|TestFunc=r2_core:testIsExportable|PickFunc=r2_core:addEntityToExporter|PickPosFunc=r2_core:doNothing|WantMouseUp=true") r2.ContextualCommands:highlightCommandButton("add_entity") end function userComponentHolder.onPickRemoveEntity(this) r2_core.CurrentHolderId = this.InstanceId runAH(nil, "r2ed_picker_lua", "CursCanPickPos=curs_create.tga|CursCannotPickPos=curs_stop.tga|TestFunc=r2_core:testCanPickUserComponentElement|PickFunc=r2_core:removeUserComponentElement|PickPosFunc=r2_core:doNothing|WantMouseUp=true") r2.ContextualCommands:highlightCommandButton("remove_entity") end function userComponentHolder.onPostCreate(this) if this.User.DisplayProp and this.User.DisplayProp == 1 then r2:setSelectedInstanceId(this.InstanceId) r2:showProperties(this) this.User.DisplayProp = nil end end function userComponentHolder.onPickExport(this) local refX = this.Position.x local refY = this.Position.y local refZ = this.Position.z local components = this.Components r2_core.UserComponentManager.CurrentDesc = this.Description local exportList = {} local k, v = next(components, nil) while k do if v.InstanceId then table.insert(exportList, v.InstanceId) end k, v = next(components, k) end r2_core.UserComponentManager:export(exportList, refX, refY, refZ) end function userComponentHolder.create() if not r2:checkAiQuota() then return end local function paramsCancel() debugInfo("Cancel form for 'User Component' creation") end local function posOk(x, y, z) debugInfo(string.format("Validate creation of 'User Component' at pos (%d, %d, %d)", x, y, z)) if r2.mustDisplayInfo("UserComponent") == 1 then r2.displayFeatureHelp("UserComponent") end local component = r2.newComponent("UserComponentHolder") component.Base = r2.Translator.getDebugBase("palette.entities.botobjects.user_event") component.Name = r2:genInstanceName(i18n.get("uiR2EdUserComponent")):toUtf8() component.Position.x = x component.Position.y = y component.Position.z = r2:snapZToGround(x, y) r2:setCookie(component.InstanceId, "DisplayProp", 1) r2.requestInsertNode(r2:getCurrentAct().InstanceId, "Features", -1, "", component) end local function posCancel() debugInfo("Cancel choice 'User Component' position") end local creature = r2.Translator.getDebugCreature("object_component_user_event.creature") r2:choosePos(creature, posOk, posCancel, "createUserComponent") end feature.Components.DefaultFeature = { BaseClass="BaseClass", Name="DefaultFeature", --TreeIcon="r2ed_icon_default_feature.tga", DisplayerUI = "", Menu="ui:interface:r2ed_base_menu", Prop= { {Name="Components", Type="Table"}, }, --------------------------------------------------------------------------------------------------------- getFirstSelectableSon = function(this) for k = 0, this.Components.Size - 1 do if this.Components[k].Selectable then return this.Components[k] end end return nil end, --------------------------------------------------------------------------------------------------------- -- from base class appendInstancesByType = function(this, destTable, kind) assert(type(kind) == "string") --this:delegate():appendInstancesByType(destTable, kind) r2.Classes.BaseClass.appendInstancesByType(this, destTable, kind) for k, component in specPairs(this.Components) do component:appendInstancesByType(destTable, kind) end end, ----------------------------------------------------------------------------------------------- -- from base class hasScenarioCost = function(this) return true end, ----------------------------------------------------------------------------------------------- -- from base class displayInSelectBar = function(this) return false end, pretranslate = r2.Translator.pretranslateDefaultFeature, pretranslate2 = r2.Translator.pretranslateDefaultFeature2, translate = r2.Translator.translateDefaultFeature, getAiCost = function(this) return r2.getAiCost(this) - 1 end, getStaticObjectCost = function(this) return r2.getStaticObjectCost(this) end } function feature.Components.DefaultFeature.getActivitiesIds(this) return r2.Translator.getDefaultFeatureActivitiesIds(this) end --- Npc local componentNpc = feature.Components.Npc ---------------------------------------------------------------------------- -- add a line to the event menu function componentNpc.initLogicEntitiesMenu(this, logicEntityMenu, testApplicableAction) local name = i18n.get("uiR2EDnpc") local existPeople = nil local enumerator = r2:enumInstances("Npc") while 1 do local inst = enumerator:next() if not inst then break end local condExistPeople = not (inst:isKindOf("NpcCreature") or inst:isBotObject() or inst:isPlant()) if not r2.events.memberManagement then --TEMP condExistPeople = not (inst:isKindOf("NpcCreature") or inst:isBotObject() or inst:isPlant() or inst:isGrouped()) --TEMP end --TEMP if condExistPeople then existPeople = inst break end end if existPeople and (not r2.events.memberManagement or testApplicableAction==nil or (testApplicableAction==true and r2.events:hasApplicableActions(existPeople))) then logicEntityMenu:addLine(name, "lua", "", "Npc") end end ---------------------------------------------------------------------------- -- add a line to the event sub menu function componentNpc.initLogicEntitiesInstancesMenu(this, subMenu, calledFunction) local empty = true local enumerator = r2:enumInstances("Npc") while 1 do local entity = enumerator:next() if not entity then break end local addLine = not (entity:isKindOf("NpcCreature") or entity:isBotObject() or entity:isPlant()) if not r2.events.memberManagement then --TEMP addLine = not (entity:isKindOf("NpcCreature") or entity:isBotObject() or entity:isPlant() or entity:isGrouped()) --TEMP end --TEMP if addLine then local uc_name = ucstring() uc_name:fromUtf8(entity.Name) subMenu:addLine(uc_name, "lua", calledFunction.."('".. entity.InstanceId .."')", entity.InstanceId) empty = false end end if empty==true then subMenu:addLine(i18n.get("uiR2EdNoSelelection"), "", "", "") end end ---------------------------------------------------------------------------- -- add a line to the event menu function componentNpc:getLogicTranslations() local logicTranslations = { ["ApplicableActions"] = { ["Activate"] = {menu=i18n.get("uiR2EdActivates"):toUtf8(), text=r2:lowerTranslate("uiR2EdActivates")}, ["Deactivate"] = {menu=i18n.get("uiR2EdDeactivates"):toUtf8(), text=r2:lowerTranslate("uiR2EdDeactivates")}, ["Sit Down"] = {menu=i18n.get("uiR2EdSitDown"):toUtf8(), text=r2:lowerTranslate("uiR2EdSitsDown")}, ["Stand Up"] = {menu=i18n.get("uiR2EdStandUp"):toUtf8(), text=r2:lowerTranslate("uiR2EdStandsUp")}, ["Kill"] = {menu=i18n.get("uiR2EdKill"):toUtf8(), text=r2:lowerTranslate("uiR2EdKills")}, ["begin activity sequence"] = {menu=i18n.get("uiR2EdBeginActivitySequ"):toUtf8(), text=r2:lowerTranslate("uiR2EdSequenceStarts")}, ["Fight with player"] = {menu=i18n.get("uiR2EdFightWithPlayer"):toUtf8(), text=r2:lowerTranslate("uiR2EdFightWithPlayer")}, ["Fight with Npcs"] = {menu=i18n.get("uiR2EdFightWithNpcs"):toUtf8(), text=r2:lowerTranslate("uiR2EdFightWithNpcs")}, ["Dont fight with player"] = {menu=i18n.get("uiR2EdDontFightWithPlayer"):toUtf8(), text=r2:lowerTranslate("uiR2EdDontFightWithPlayer")}, ["Dont fight with Npcs"] = {menu=i18n.get("uiR2EdDontFightWithNpcs"):toUtf8(), text=r2:lowerTranslate("uiR2EdDontFightWithNpcs")}, ["Run"] = {menu=i18n.get("uiR2EdRun"):toUtf8(), text=r2:lowerTranslate("uiR2EdRun")}, ["Dont run"] = {menu=i18n.get("uiR2EdDontRun"):toUtf8(), text=r2:lowerTranslate("uiR2EdDontRun")}, }, ["Events"] = { ["activation"] = {menu=i18n.get("uiR2EdActivation"):toUtf8(), text=r2:lowerTranslate("uiR2EdActivation")}, ["desactivation"] = {menu=i18n.get("uiR2EdDeactivation"):toUtf8(), text=r2:lowerTranslate("uiR2EdDeactivation")}, ["death"] = {menu=i18n.get("uiR2EdDeath"):toUtf8(), text=r2:lowerTranslate("uiR2EdDeath")}, ["end of activity step"] = {menu=i18n.get("uiR2EdEndActivityStep"):toUtf8(), text=r2:lowerTranslate("uiR2EdEndActivityStep")}, ["end of activity sequence"] = {menu=i18n.get("uiR2EdEndActivitySequ"):toUtf8(), text=r2:lowerTranslate("uiR2EdEndActivitySequ")}, ["begin of activity step"] = {menu=i18n.get("uiR2EdBeginActivityStep"):toUtf8(), text=r2:lowerTranslate("uiR2EdBeginActivityStep")}, ["begin of activity sequence"] = {menu=i18n.get("uiR2EdBeginOfActivitySequ"):toUtf8(), text=r2:lowerTranslate("uiR2EdBeginOfActivitySequ")}, ["targeted by player"] = {menu=i18n.get("uiR2EdTargetedByplayer"):toUtf8(), text=r2:lowerTranslate("uiR2EdTargetedByplayer")} }, ["Conditions"] = { ["is active"] = { menu=i18n.get( "uiR2Test0Spawned" ):toUtf8(), text=i18n.get( "uiR2Test1Spawned" ):toUtf8()}, ["is inactive"] = { menu=i18n.get( "uiR2Test0Despawned" ):toUtf8(), text=i18n.get( "uiR2Test1Despawned" ):toUtf8()}, ["is dead"] = { menu=i18n.get( "uiR2Test0Dead" ):toUtf8(), text=i18n.get( "uiR2Test1Dead" ):toUtf8()}, ["is alive"] = { menu=i18n.get( "uiR2Test0Alive" ):toUtf8(), text=i18n.get( "uiR2Test1Alive" ):toUtf8()}, ["is in activity sequence"] = { menu=i18n.get( "uiR2Test0Seq" ):toUtf8(), text=i18n.get( "uiR2Test1Seq" ):toUtf8()}, ["is in activity step"] = { menu=i18n.get( "uiR2Test0Step" ):toUtf8(), text=i18n.get( "uiR2Test1Step" ):toUtf8()}, } } return logicTranslations end componentNpc.getLogicCondition = r2.Translator.getNpcLogicCondition componentNpc.getLogicAction = r2.Translator.getNpcLogicAction componentNpc.getLogicEvent = r2.Translator.getNpcLogicEvent -- obsolete feature.getCost = function (featureInstance) local cost = 0 local components = featureInstance.Components local key,comp = next(components,nil) while(key ~= nil) do if (comp.Class == "Npc" or comp.Class == "NpcCustom") then cost = cost +1 end key,comp = next(components,key) end return cost end -- obsolete feature.Translator = function (context) local components = context.Feature.Components --luaObject(context.Feature) local key,comp = next(components,nil) while(key ~= nil) do -- Npc case (npc alone not object) if (comp.isKindOf and comp:isKindOf( "Npc")) then local hlNpc = comp context.Feature = hlNpc -- create and set rtNpc local rtNpc = r2.Translator.translateNpc(hlNpc, context) table.insert(context.RtAct.Npcs, rtNpc) -- create or get rtGrp -- set rtGrp.GroupParameter by reading hlNpc (Aggro, Player attackable..) local rtNpcGrp = r2.Translator.getRtGroup(context,hlNpc.InstanceId) r2.Translator.setGroupParameters(hlNpc, rtNpcGrp) --table.insert(context.RtAct.NpcGrps, rtNpcGrp) table.insert(rtNpcGrp.Children, rtNpc.Id) -- set activity local aiActivity = r2.Translator.getAiActivity(hlNpc) r2.Translator.translateActivities(context, hlNpc, hlNpc:getBehavior(), rtNpcGrp, aiActivity) -- set eventHandlers r2.Translator.translateEventHandlers(context, hlNpc, hlNpc:getBehavior().Actions, rtNpcGrp) end key,comp = next(components,key) end end -- NpcCustom local componentNpcCustom = feature.Components.NpcCustom ---------------------------------------------------------------------------- -- add no line to the event menu function componentNpcCustom.initLogicEntitiesMenu(this, logicEntityMenu) end ---------------------------------------------------------------------------- -- add a line to the event sub menu function componentNpcCustom.initLogicEntitiesInstancesMenu(this, subMenu, calledFunction) end ---------------------------------------------------------------------------- -- add a line to the event menu --function componentNpcCustom:getLogicTranslations() -- return { --end function componentNpcCustom.newCopy(this) local result = r2.Classes.BaseClass.newCopy(this) local sex if isR2PlayerMale(result.SheetClient) then sex = r2.male else sex = r2.female end local race = getR2PlayerRace(result.SheetClient) result.Name = r2:randomNPCName2(race, sex) return result end --------------------------------------------------------------------------------------------------------- -- Show the property window for this instance function componentNpcCustom.onShowProperties(this) local npcUI = getUI("ui:interface:r2ed_npc") assert(npcUI) if npcUI.active then r2:updateName() end r2.Classes.BaseClass.onShowProperties(this) end -- NpcCreature local componentNpcCreature = feature.Components.NpcCreature ---------------------------------------------------------------------------- -- add no line to the event menu function componentNpcCreature.initLogicEntitiesMenu(this, logicEntityMenu, testApplicableAction) local name = i18n.get("uiR2EDCreatures") local existCreature = nil local enumerator = r2:enumInstances("NpcCreature") while 1 do local inst = enumerator:next() if not inst then break end local condExistCreature = not inst:isKindOf("NpcPlant") if not r2.events.memberManagement then --TEMP condExistCreature = not (inst:isKindOf("NpcPlant") or inst:isGrouped()) --TEMP end --TEMP if condExistCreature then existCreature = inst break end end if existCreature and (not r2.events.memberManagement or testApplicableAction==nil or (testApplicableAction==true and r2.events:hasApplicableActions(existCreature))) then logicEntityMenu:addLine(name, "lua", "", "NpcCreature") end end ---------------------------------------------------------------------------- -- add a line to the event sub menu function componentNpcCreature.initLogicEntitiesInstancesMenu(this, subMenu, calledFunction) local empty = true local enumerator = r2:enumInstances("NpcCreature") while 1 do local entity = enumerator:next() if not entity then break end local addLine = not entity:isKindOf("NpcPlant") if not r2.events.memberManagement then addLine = not (entity:isKindOf("NpcPlant") or entity:isGrouped()) end if addLine then local uc_name = ucstring() uc_name:fromUtf8(entity.Name) subMenu:addLine(uc_name, "lua", calledFunction.."('".. entity.InstanceId .."')", entity.InstanceId) empty = false end end if empty==true then subMenu:addLine(i18n.get("uiR2EdNoSelelection"), "", "", "") end end -- NpcPlant local componentNpcPlant = feature.Components.NpcPlant ---------------------------------------------------------------------------- -- add no line to the event menu function componentNpcPlant.initLogicEntitiesMenu(this, logicEntityMenu) r2.Classes.LogicEntity.initLogicEntitiesMenu(this, logicEntityMenu) end ---------------------------------------------------------------------------- -- add a line to the event sub menu function componentNpcPlant.initLogicEntitiesInstancesMenu(this, subMenu, calledFunction) r2.Classes.LogicEntity.initLogicEntitiesInstancesMenu(this, subMenu, calledFunction) end ---------------------------------------------------------------------------- -- add a line to the event menu function componentNpcPlant:getLogicTranslations() local logicTranslations = { ["ApplicableActions"] = { ["Activate"] = {menu=i18n.get("uiR2EdActivates"):toUtf8(), text=r2:lowerTranslate("uiR2EdActivates")}, ["Deactivate"] = {menu=i18n.get("uiR2EdDeactivates"):toUtf8(), text=r2:lowerTranslate("uiR2EdDeactivates")}, ["Kill"] = {menu=i18n.get("uiR2EdKill"):toUtf8(), text=r2:lowerTranslate("uiR2EdKills")}, }, ["Events"] = { ["activation"] = {menu=i18n.get("uiR2EdActivation"):toUtf8(), text=r2:lowerTranslate("uiR2EdActivation")}, ["desactivation"] = {menu=i18n.get("uiR2EdDeactivation"):toUtf8(), text=r2:lowerTranslate("uiR2EdDeactivation")}, ["death"] = {menu=i18n.get("uiR2EdDeath"):toUtf8(), text=r2:lowerTranslate("uiR2EdDeath")}, ["targeted by player"] = {menu=i18n.get("uiR2EdTargetedByplayer"):toUtf8(), text=r2:lowerTranslate("uiR2EdTargetedByplayer")} }, ["Conditions"] = { ["is active"] = {menu=i18n.get("uiR2EdIsActive"):toUtf8(), text=r2:lowerTranslate("uiR2EdIsActive")}, ["is dead"] = {menu=i18n.get("uiR2EdIsDead"):toUtf8(), text=r2:lowerTranslate("uiR2EdIsDead")}, ["is alive"] = {menu=i18n.get("uiR2EdIsAlive"):toUtf8(), text=r2:lowerTranslate("uiR2EdIsAlive")}, ["is inactive"] = {menu=i18n.get("uiR2EdIsInactive"):toUtf8(), text=r2:lowerTranslate("uiR2EdIsInactive")}, } } return logicTranslations end return feature end r2.Features["DefaultFeature"] = registerFeature() -------------------------------------------------------------------------------------------------- -------------------------- ACTIVE LOGIC ENTITY DisplayerProperties ----------------------------------------- -------------------------------------------------------------------------------------------------- local activeLogicEntityPropertySheetDisplayerTable = clone(r2:propertySheetDisplayer()) ------------------------------------------------ function activeLogicEntityPropertySheetDisplayerTable:onPostCreate(instance) end ------------------------------------------------ function activeLogicEntityPropertySheetDisplayerTable:onErase(instance) r2:logicEntityPropertySheetDisplayer():onErase(instance) end ------------------------------------------------ function activeLogicEntityPropertySheetDisplayerTable:onPreHrcMove(instance) end ------------------------------------------------ function activeLogicEntityPropertySheetDisplayerTable:onPostHrcMove(instance) end ------------------------------------------------ function activeLogicEntityPropertySheetDisplayerTable:onFocus(instance, hasFocus) end ------------------------------------------------ r2.activitiesAndChatsUIUpdate = false function activeLogicEntityPropertySheetDisplayerTable:onSelect(instance, isSelected) r2:logicEntityPropertySheetDisplayer():onSelect(instance, isSelected) if not isSelected or (instance.Ghost == true) then r2.activities:closeEditor() r2.miniActivities:closeEditor() else if instance:isKindOf("Npc") then local helpButton = getUI("ui:interface:r2ed_property_sheet_Npc:header_opened:help") assert(helpButton) if instance:isBotObject() then debugInfo("1") helpButton.active = false helpButton.parent.parent.title_delta_max_w = r2.DefaultPropertySheetTitleClampSize else debugInfo("2") helpButton.active = true helpButton:updateCoords() helpButton.parent.parent.title_delta_max_w = r2.DefaultPropertySheetTitleClampSize - helpButton.w_real - 4 end end r2.activities.isInitialized = false r2.miniActivities:openEditor() end end ------------------------------------------------ function activeLogicEntityPropertySheetDisplayerTable:onAttrModified(instance, attributeName) r2:logicEntityPropertySheetDisplayer():onAttrModified(instance, attributeName) if attributeName == "Name" then if r2.events.filteredLogicEntityId == instance.InstanceId then r2.events:updateSequenceUI() end if not r2.activitiesAndChatsUIUpdate or instance ~= r2:getSelectedInstance() then return end local activitiesUI = getUI(r2.activities.uiId) assert(activitiesUI) local dialogsUI = getUI(r2.dialogs.uiId) assert(dialogsUI) activitiesUI.uc_title = i18n.get("uiR2EDActivitySequenceEditor"):toUtf8() .. instance[attributeName] dialogsUI.uc_title = i18n.get("uiR2EDChatSequenceEditor"):toUtf8() .. instance[attributeName] end end ------------------------------------------------ function r2:activeLogicEntityPropertySheetDisplayer() return activeLogicEntityPropertySheetDisplayerTable -- returned shared displayer to avoid wasting memory end