mirror of
https://port.numenaute.org/aleajactaest/khanat-opennel-code.git
synced 2024-12-25 18:30:53 +00:00
2102 lines
80 KiB
Lua
2102 lines
80 KiB
Lua
|
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 =
|
|||
|
[[
|
|||
|
<ctrl style="text_button_16" id="customize" active="true" posref="TL TL" onclick_l="lua" x="0" y="0" params_l="r2:getSelectedInstance():customizeLook()" hardtext="uiR2EDCustomizeLook"/>
|
|||
|
]],
|
|||
|
-- 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<6F>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
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|