1 local registerFeature
= function ()
4 feature
.Name
="DefaultFeature"
6 feature
.Description
="The default feature"
11 Name
="ActiveLogicEntity",
12 BaseClass
="LogicEntity",
13 DisplayerVisual
= "R2::CDisplayerVisualEntity",
14 DisplayerVisualParams
= { InheritDisplayMode
= true },
15 DisplayerUI
= "R2::CDisplayerLua",
16 DisplayerUIParams
= "defaultUIDisplayer",
17 DisplayerProperties
= "R2::CDisplayerLua",
18 DisplayerPropertiesParams
= "activeLogicEntityPropertySheetDisplayer",
19 Menu
="ui:interface:r2ed_entity_menu",
23 {Name
="Behavior", Type
="Behavior"},
24 {Name
="ActivitiesId",Type
="Table" },
26 isNextSelectable
= function(this
)
29 ---------------------------------------------------------------------------------------------------------
30 -- get list of command for display in the mini toolbar
31 getAvailableMiniCommands
= function(this
, result
)
33 --local result = this:delegate():getAvailableMiniCommands(this)
34 r2
.Classes
.LogicEntity
.getAvailableMiniCommands(this
, result
)
36 --------------------------------------------------------------------------------------------
37 -- Test if this entity is a bot object
38 isBotObject
= function(this
)
41 --------------------------------------------------------------------------------------------
42 -- Test if thisentity is a plant
43 isPlant
= function(this
)
46 --------------------------------------------------------------------------------------------
47 -- is it a named entity ?
48 isNamed
= function(this
)
49 if this
.IsNamed
and this
.IsNamed
== 1 then return true end
52 --------------------------------------------------------------------------------------------
53 addPrimitiveActivities
= function (this
, dest
, activityWnd
)
55 table.insert(dest
, "Wander")
56 table.insert(dest
, "Follow Route")
57 table.insert(dest
, "Patrol")
58 table.insert(dest
, "Repeat Road")
59 table.insert(dest
, "Stand Still")
61 table.insert(dest
, this
:buildActivityCommand(this
.onPickWanderZone
, "wander_zone", "uimR2EDMenuPickZone", "r2_toolbar_wander_zone.tga", true))
62 table.insert(dest
, this
:buildActivityCommand(this
.onPickFollowRoute
, "follow_route", "uimR2EDMenuFollowRoute", "r2_toolbar_follow_road.tga", false))
63 table.insert(dest
, this
:buildActivityCommand(this
.onPickPatrolRoute
, "patrol_route", "uimR2EDMenuPatrolRoute", "r2_toolbar_patrol_road.tga", false))
64 table.insert(dest
, this
:buildActivityCommand(this
.onPickRepeatRoute
, "repeat_route", "uimR2EDMenuRepeatRoute", "r2_toolbar_repeat_road.tga", false))
65 table.insert(dest
, this
:buildActivityCommand(this
.onStandStill
, "stand_still", "uimR2EDMenuStandInPlace", "r2_toolbar_stand_still.tga", false))
70 getAvailableCommands
= function(this
, dest
, activityWnd
)
72 --local result = this:delegate():getAvailableCommands(this)
73 if not activityWnd
then
74 r2
.Classes
.LogicEntity
.getAvailableCommands(this
, dest
)
76 local category
= this
:getCategory()
78 if category
== "Herbivore" then
79 if this
:isNamed() then
82 table.insert(dest
, "Guard Zone")
83 table.insert(dest
, "Follow Route")
84 table.insert(dest
, "Patrol")
85 table.insert(dest
, "Repeat Road")
86 table.insert(dest
, "Stand Still")
88 table.insert(dest
, this
:buildActivityCommand(this
.onPickGuardZone
, "guard_zone", "uimR2EDMenuPickGuardZone", "r2ed_toolbar_guard_zone.tga", true))
89 table.insert(dest
, this
:buildActivityCommand(this
.onPickFollowRoute
, "follow_route", "uimR2EDMenuFollowRoute", "r2_toolbar_follow_road.tga", false))
90 table.insert(dest
, this
:buildActivityCommand(this
.onPickPatrolRoute
, "patrol_route", "uimR2EDMenuPatrolRoute", "r2_toolbar_patrol_road.tga", false))
91 table.insert(dest
, this
:buildActivityCommand(this
.onPickRepeatRoute
, "repeat_route", "uimR2EDMenuRepeatRoute", "r2_toolbar_repeat_road.tga", false))
92 table.insert(dest
, this
:buildActivityCommand(this
.onStandStill
, "stand_still", "uimR2EDMenuStandInPlace", "r2_toolbar_stand_still.tga", false))
97 table.insert(dest
, "Rest In Zone")
98 table.insert(dest
, "Feed In Zone")
100 table.insert(dest
, this
:buildActivityCommand(this
.onPickRestZone
, "rest_zone", "uimR2EDMenuPickRestZone", "r2ed_toolbar_rest_zone.tga", true))
101 table.insert(dest
, this
:buildActivityCommand(this
.onPickFeedZone
, "feed_zone", "uimR2EDMenuPickFeedZone", "r2ed_toolbar_feed_zone.tga", false))
104 elseif category
== "Carnivore" then
105 if this
:isNamed() then
108 table.insert(dest
, "Guard Zone")
109 table.insert(dest
, "Follow Route")
110 table.insert(dest
, "Patrol")
111 table.insert(dest
, "Repeat Road")
112 table.insert(dest
, "Stand Still")
114 table.insert(dest
, this
:buildActivityCommand(this
.onPickGuardZone
, "guard_zone", "uimR2EDMenuPickGuardZone", "r2ed_toolbar_guard_zone.tga", true))
115 table.insert(dest
, this
:buildActivityCommand(this
.onPickFollowRoute
, "follow_route", "uimR2EDMenuFollowRoute", "r2_toolbar_follow_road.tga", false))
116 table.insert(dest
, this
:buildActivityCommand(this
.onPickPatrolRoute
, "patrol_route", "uimR2EDMenuPatrolRoute", "r2_toolbar_patrol_road.tga", false))
117 table.insert(dest
, this
:buildActivityCommand(this
.onPickRepeatRoute
, "repeat_route", "uimR2EDMenuRepeatRoute", "r2_toolbar_repeat_road.tga", false))
118 table.insert(dest
, this
:buildActivityCommand(this
.onStandStill
, "stand_still", "uimR2EDMenuStandInPlace", "r2_toolbar_stand_still.tga", false))
123 table.insert(dest
, "Rest In Zone")
124 table.insert(dest
, "Hunt In Zone")
126 table.insert(dest
, this
:buildActivityCommand(this
.onPickRestZone
, "rest_zone", "uimR2EDMenuPickRestZone", "r2ed_toolbar_rest_zone.tga", true))
127 table.insert(dest
, this
:buildActivityCommand(this
.onPickHuntZone
, "hunt_zone", "uimR2EDMenuPickHuntZone", "r2ed_toolbar_hunt_zone.tga", false))
130 --table.insert(dest, this:buildActivityCommand(this.onPickGuardZone, "guard_zone", "uimR2EDMenuPickGuardZone", "r2ed_toolbar_guard_zone.tga", true))
131 elseif category
== "WorkerKitin" then
134 table.insert(dest
, "Feed In Zone")
135 table.insert(dest
, "Follow Route")
136 table.insert(dest
, "Patrol")
137 table.insert(dest
, "Repeat Road")
138 table.insert(dest
, "Stand Still")
139 --table.insert(dest, "Guard Zone")
141 table.insert(dest
, this
:buildActivityCommand(this
.onPickFeedZone
, "feed_zone", "uimR2EDMenuPickWorkZone", "r2ed_toolbar_work_zone.tga", true))
142 table.insert(dest
, this
:buildActivityCommand(this
.onPickFollowRoute
, "follow_route", "uimR2EDMenuFollowRoute", "r2_toolbar_follow_road.tga", false))
143 table.insert(dest
, this
:buildActivityCommand(this
.onPickPatrolRoute
, "patrol_route", "uimR2EDMenuPatrolRoute", "r2_toolbar_patrol_road.tga", false))
144 table.insert(dest
, this
:buildActivityCommand(this
.onPickRepeatRoute
, "repeat_route", "uimR2EDMenuRepeatRoute", "r2_toolbar_repeat_road.tga", false))
145 table.insert(dest
, this
:buildActivityCommand(this
.onStandStill
, "stand_still", "uimR2EDMenuStandInPlace", "r2_toolbar_stand_still.tga", false))
146 --table.insert(dest, this:buildActivityCommand(this.onPickGuardZone, "guard_zone", "uimR2EDMenuPickGuardZone", "r2ed_toolbar_guard_zone.tga", true))
148 elseif category
== "SoldierKitin" then
150 table.insert(dest
, "Guard Zone")
151 table.insert(dest
, "Follow Route")
152 table.insert(dest
, "Patrol")
153 table.insert(dest
, "Repeat Road")
154 table.insert(dest
, "Stand Still")
156 table.insert(dest
, this
:buildActivityCommand(this
.onPickGuardZone
, "guard_zone", "uimR2EDMenuPickGuardZone", "r2ed_toolbar_guard_zone.tga", true))
157 table.insert(dest
, this
:buildActivityCommand(this
.onPickFollowRoute
, "follow_route", "uimR2EDMenuFollowRoute", "r2_toolbar_follow_road.tga", false))
158 table.insert(dest
, this
:buildActivityCommand(this
.onPickPatrolRoute
, "patrol_route", "uimR2EDMenuPatrolRoute", "r2_toolbar_patrol_road.tga", false))
159 table.insert(dest
, this
:buildActivityCommand(this
.onPickRepeatRoute
, "repeat_route", "uimR2EDMenuRepeatRoute", "r2_toolbar_repeat_road.tga", false))
160 table.insert(dest
, this
:buildActivityCommand(this
.onStandStill
, "stand_still", "uimR2EDMenuStandInPlace", "r2_toolbar_stand_still.tga", false))
162 elseif not this
:isBotObject() and not this
:isPlant() then
163 -- activity (only if not a plant)
164 this
:addPrimitiveActivities(dest
, activityWnd
)
169 getAvailableActivities
= function(this
, dest
)
170 r2
.Classes
.ActiveLogicEntity
.getAvailableCommands(this
, dest
, true)
172 --------------------------------------------------------------------------------------------
173 -- Called when the menu is displayed
174 onSetupMenu
= function(this
)
176 --this:delegate():onSetupMenu()
177 r2
.Classes
.LogicEntity
.onSetupMenu(this
)
178 local class
= r2
:getClass(this
)
179 local isBO
= this
:isBotObject()
180 local isPlant
= this
:isPlant()
181 getUI(class
.Menu
.. ":activities").active
= not isBO
and not isPlant
183 if not isBO
and not isPlant
then
184 getUI(class
.Menu
.. ":activities").uc_hardtext
= i18n
.get("uimR2EDNewActivity")
187 --------------------------------------------------------------------------------------------
188 -- function to change activity
189 onStandStill
= function(this
)
190 r2
:setNPCStandInPlace(this
)
192 onPickWanderZone
= function(this
)
193 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")
194 r2
.ContextualCommands
:highlightCommandButton("wander_zone")
196 onPickRestZone
= function(this
)
197 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")
198 r2
.ContextualCommands
:highlightCommandButton("rest_zone")
200 onPickFeedZone
= function(this
)
201 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")
202 r2
.ContextualCommands
:highlightCommandButton("feed_zone")
204 onPickHuntZone
= function(this
)
205 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")
206 r2
.ContextualCommands
:highlightCommandButton("hunt_zone")
208 onPickGuardZone
= function(this
)
209 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")
210 r2
.ContextualCommands
:highlightCommandButton("guard_zone")
212 onPickFollowRoute
= function(this
)
213 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 ")
214 r2
.ContextualCommands
:highlightCommandButton("follow_route")
216 onPickPatrolRoute
= function(this
)
217 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")
218 r2
.ContextualCommands
:highlightCommandButton("patrol_route")
220 onPickRepeatRoute
= function(this
)
221 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")
222 r2
.ContextualCommands
:highlightCommandButton("repeat_route")
224 ---------------------------------------------------------------------------------------------------------
226 isSequencable
= function(this
)
227 return not this
:isPlant() and not this
:isBotObject()
230 ---------------------------------------------------------------------------------------------------------
232 getActivityVerbLookupName
= function (this
, activityName
)
233 if this
.Category
== "WorkerKitin" and activityName
== "Feed In Zone" then
234 return "Work In Zone"
238 initEventValuesMenu
= function(this
, menu
, categoryEvent
)
240 -- activity sequences
241 for ev
=0,menu
:getNumLine()-1 do
243 local eventType
= tostring(menu
:getLineId(ev
))
245 if r2
.events
.eventTypeWithValue
[eventType
] == "Number" then
247 local subMenu
= menu
:getSubMenu(ev
)
250 local uc_name
= ucstring()
251 uc_name
:fromUtf8( tostring(i
) )
252 func
= "r2.events:setEventValue('','" .. categoryEvent
.."','".. tostring(i
).."')"
253 subMenu
:addLine(uc_name
, "lua", func
, tostring(i
))
256 elseif r2
.events
.eventTypeWithValue
[eventType
]~=nil then
258 local subMenu
= menu
:getSubMenu(ev
)
260 for s
=0, this
:getBehavior().Activities
.Size
-1 do
261 local sequence
= this
:getBehavior().Activities
[s
]
263 if r2
.events
.eventTypeWithValue
[eventType
]=="ActivitySequence" then
264 func
= "r2.events:setEventValue('".. sequence
.InstanceId
.."','" .. categoryEvent
.."')"
267 local uc_name
= ucstring()
268 uc_name
:fromUtf8(sequence
:getName())
269 subMenu
:addLine(uc_name
, "lua", func
, sequence
.InstanceId
)
272 if this
:getBehavior().Activities
.Size
==0 then
273 subMenu
:addLine(i18n
.get("uiR2EdNoSelelection"), "", "", "")
276 elseif r2
.events
.eventTypeWithValue
[eventType
]=="ActivityStep" then
278 for s
=0,subMenu
:getNumLine()-1 do
279 local sequenceId
= tostring(subMenu
:getLineId(s
))
280 local sequence
= r2
:getInstanceFromId(sequenceId
)
283 subMenu
:addSubMenu(s
)
284 local activitiesMenu
= subMenu
:getSubMenu(s
)
286 for a
=0, sequence
.Components
.Size
-1 do
287 local activity
= sequence
.Components
[a
]
288 local uc_name
= ucstring()
289 uc_name
:fromUtf8(activity
:getShortName())
290 activitiesMenu
:addLine(uc_name
, "lua",
291 "r2.events:setEventValue('".. activity
.InstanceId
.."','" .. categoryEvent
.."')", activity
.InstanceId
)
294 -- no activity in the sequence
295 if sequence
.Components
.Size
==0 then
296 activitiesMenu
:addLine(i18n
.get("uiR2EdNoSelelection"), "", "", "")
307 BaseClass
="LogicEntityBehavior",
310 {Name
="Type", Type
="String",DefaultValue
=""},--TEMP
311 {Name
="ZoneId", Type
="String"},--TEMP
312 {Name
="Activities",Type
="Table"},
313 {Name
="ChatSequences",Type
="Table"}
317 ------------------------------------------------------------------------------------------------------
319 PropertySheetHeader
= r2
.DisplayNpcHeader(),
322 BaseClass
="ActiveLogicEntity",
323 DisplayerVisual
= "R2::CDisplayerVisualEntity",
324 DisplayerUI
= "R2::CDisplayerLua",
325 DisplayerUIParams
= "defaultUIDisplayer",
326 DisplayerProperties
= "R2::CDisplayerLua",
327 DisplayerPropertiesParams
= "npcPropertySheetDisplayer",
328 -----------------------------------------------------------------------------------------------
331 ApplicableActions
= {
333 "Deactivate", "Kill", "begin activity sequence",
334 "Sit Down", "Stand Up",
335 "Fight with player", "Fight with Npcs",
336 "Dont fight with player", "Dont fight with Npcs",
338 -- "emits user event",
342 "desactivation", "death",
343 "end of activity step", "end of activity sequence",
344 "begin of activity step", "begin of activity sequence",
345 -- "user event emitted",
350 --"is dead", "is alive", "is active", "is inactive",
351 "is dead", "is alive",
352 "is in activity sequence",
353 "is in activity step",
356 "NPC is dead", "NPC is alive"
361 "is active", "current activity sequence and activity step",
362 "current chat sequence and chat step"
364 -----------------------------------------------------------------------------------------------
367 {Name
="Base", Type
="String", WidgetStyle
="StaticText", Category
="Advanced", Visible
=false},
368 {Name
="Name", Type
="String", DefaultInBase
=1, MaxNumChar
="32"},
369 {Name
="Angle", Type
="Number",
370 WidgetStyle
="Slider", Min
="0", Max
="360",
372 convertToWidgetValue
=
374 local result
= math
.fmod(math
.floor(180 * value
/ math
.pi
), 360)
375 if result
< 0 then result
= 360 + result
end
379 convertFromWidgetValue
=
381 return math
.pi
* math
.min(359, value
) / 180
384 { Name
="PlayerAttackable", Type
="Number", WidgetStyle
="Boolean", Default
="0", DefaultInBase
=1,
385 Visible
=function(this
) return this
:isGroupedAndLeader() or not this
:isGrouped() and not this
:isBotObject() and this
:canUpdatePlayerAttackable() end
388 Name
="BotAttackable", Type
="Number", WidgetStyle
="Boolean", Default
="0", DefaultInBase
=1,
389 Visible
=function(this
) return this
:isGroupedAndLeader() or not this
:isGrouped() and not this
:isBotObject() and this
:canUpdateBotAttackable() end
392 -- Name="UseFame", Type="Number", WidgetStyle="Boolean", Default="0", DefaultInBase=1,
393 -- Visible=function(this) return this.SubCategory and ( this.SubCategory == "Kami" or this.SubCategory == "Karavan") end
397 Name
="AutoSpawn", Type
="Number", WidgetStyle
="Boolean", Default
="0", DefaultInBase
=1,
398 --Visible=function(this) return not this:isBotObject() end
399 Visible
= function(this
) return this
:isGroupedAndLeader() or not this
:isGrouped() and not this
:isBotObject() end
402 Name
="NoRespawn", Type
="Number", WidgetStyle
="Boolean", Default
="0", DefaultInBase
=1,
403 Visible
=function(this
) return this
:isGroupedAndLeader() or not this
:isGrouped() and not this
:isBotObject() end
405 {Name
="Aggro", Type
="Number", Min
="0", Max
="120", DefaultValue
="30", DefaultInBase
=1,
406 Visible
=function(this
) return this
:isGroupedAndLeader() or not this
:isGrouped() and not this
:isBotObject() end
408 {Name
="TypeNPC", Type
="Number", WidgetStyle
="EnumDropDown", SecondRequestFunc
=r2
.updateType
,
409 Enum
= {}, Visible
=true, DefaultValue
="-1",
414 --{Name="TestRefId", Type="RefId", Category="uiR2EDRollout_Test"},
420 isGroupedAndLeader
= function(this
)
421 if this
:isGrouped() and this
:isLeader() then return true end
425 TreeIcon
= function(this
)
427 if this
:isKindOf("NpcCreature") or this
:isKindOf("NpcPlant") then
428 return "r2ed_icon_creatures.tga"
429 elseif not this
:isBotObject() then
430 return "r2ed_icon_npc.tga"
436 PermanentTreeIcon
= function(this
)
437 if this
:isKindOf("NpcCreature") or this
:isKindOf("NpcPlant") then
438 return "r2ed_icon_permanent_creatures.tga"
439 elseif not this
:isBotObject() then
440 return "r2ed_permanent_node.tga"
446 ---------------------------------------------------------------------------------------------------------
447 -- get select bar type
448 SelectBarType
= function(this
)
449 if not this
:isBotObject() then
450 return i18n
.get("uiR2EDScene"):toUtf8()
452 return i18n
.get("uiR2EDbotObjects"):toUtf8()
456 ---------------------------------------------------------------------------------------------------------
458 getContextualTreeIcon
= function(this
)
459 if this
:getParentAct():isBaseAct() then
460 return this
:getPermanentTreeIcon()
465 getSelectBarIcon
= function(this
)
466 if this
:isBotObject() then
467 return "r2ed_icon_botobject.tga"
469 return r2
.Classes
.BaseClass
.getContextualTreeIcon(this
)
473 ----------------------------------------------
474 updatePermanentStatutIcon
= function(this
)
475 --this.DisplayerVisual:updatePermanentStatutIcon(this:getContextualTreeIcon())
476 this
.DisplayerVisual
:updatePermanentStatutIcon(this
:getPermanentStatutIcon())
479 --------------------------------------------------------------------------------------------
480 onPostCreate
= function(this
)
481 if this
.BoxSelection
== 1 and this
.DisplayerVisual
~= nil then -- read in palette
482 this
.DisplayerVisual
.SelectionDisplayMode
= 1
484 if this
:isBotObject() then
485 this
.DisplayerVisual
.DisplayMode
= select(r2
.BotObjectsFrozen
, 2, 0)
488 onActChanged
= function(this
)
489 if this
:isBotObject() then
490 this
.DisplayerVisual
.DisplayMode
= select(r2
.BotObjectsFrozen
, 2, 0)
493 --------------------------------------------------------------------------------------------
495 isDisplayModeToggleSupported
= function(this
, displayMode
)
496 if not this
:isBotObject() then
497 return displayMode
== 3
501 --------------------------------------------------------------------------------------------
502 -- Test if this entity is a bot object
503 isBotObject
= function(this
)
504 return r2
:isBotObject(this
.SheetClient
)
508 canUpdatePlayerAttackable
= function(this
)
509 if this
.CanUpdatePlayerAttackable
== 0 then return false end
510 if this
.CanUpdatePlayerAttackable
== 1 then return true end
511 return this
:isBotObject() == false
514 canUpdateBotAttackable
= function(this
)
515 return this
:isBotObject() == false
518 --------------------------------------------------------------------------------------------
519 -- Test if this entity is a plant
520 isPlant
= function(this
)
521 return string.match(this
.SheetClient
, "cp[%w_]*%.creature")
523 --------------------------------------------------------------------------------------------
524 -- check if that npc is the leader of its group
525 isLeader
= function(this
)
526 if not this
:isGrouped() then
529 return this
.IndexInParent
== 0
531 --------------------------------------------------------------------------------------------
532 -- return the group of this npc if it has one, else return nil
533 getParentGroup
= function(this
)
534 if this
.ParentInstance
:isKindOf("NpcGrpFeature")
536 return this
.ParentInstance
541 --------------------------------------------------------------------------------------------
542 -- change the mouse to choose a new group to group with
543 onChooseGroup
= function(this
)
544 if this
:isGrouped() then return end
545 runAH(nil, "r2ed_picker_lua", "TestFunc=r2:testCanGroupSelectedInstance|PickFunc=r2:groupSelectedInstance")
546 r2
.ContextualCommands
:highlightCommandButton("group")
548 --------------------------------------------------------------------------------------------
549 -- if this npc was part of a group, ungroup it
550 onUngroup
= function(this
)
553 --------------------------------------------------------------------------------------------
554 -- If this npc is part of a group, make it the leader of its group
555 onSetAsLeader
= function(this
)
556 if this
:isLeader() then return end
557 r2
:setAsGroupLeader(this
)
559 --------------------------------------------------------------------------------------------
561 getAvailableCommands
= function(this
, dest
)
562 --local result = this:delegate():getAvailableCommands(this)
563 r2
.Classes
.ActiveLogicEntity
.getAvailableCommands(this
, dest
)
565 if not this
:isBotObject() and not this
:isPlant() then
566 if not this
:isGrouped() then
567 table.insert(dest
, this
:buildCommand(this
.onChooseGroup
, "group", "uimR2EDMenuGroup", "r2_toolbar_group.tga", true))
569 table.insert(dest
, this
:buildCommand(this
.onUngroup
, "ungroup", "uimR2EDMenuUngroup", "r2_toolbar_ungroup.tga", true))
570 if not this
:isLeader() then
571 table.insert(dest
, this
:buildCommand(this
.onSetAsLeader
, "set_as_leader", "uimR2EDMenuSetAsGroupLeader", "r2_toolbar_set_as_leader.tga", false))
574 --debugInfo(this.SheetClient)
577 this
:getAvailableDisplayModeCommands(dest
)
579 --------------------------------------------------------------------------------------------
581 getParentTreeNode
= function(this
)
582 if not this
:isInDefaultFeature() then
583 return r2
.Classes
.ActiveLogicEntity
.getParentTreeNode(this
)
585 if this
:isBotObject() then
586 local container
= getUI("ui:interface:r2ed_scenario")
587 --return {container:find("content_tree_list"):getRootNode():getNodeFromId("scenery_objects")}
588 return {container
:find("content_tree_list"):getRootNode()}
589 elseif ( this
:isKindOf("NpcCreature") or this
:isKindOf("NpcPlant") ) then
590 return this
:getParentAct():getContentTreeNodes("creatures")
592 return this
:getParentAct():getContentTreeNodes("people")
595 --------------------------------------------------------------------------------------------
596 -- special handler for deletion : this method is called when the user click on 'delete' in the
597 -- context menu and should perform the actual deletion
598 onDelete
= function(this
)
599 if this
.User
.DeleteInProgress
== true then return end
600 this
.User
.DeleteInProgress
= true
601 this
:setDeleteActionName()
602 -- if deleted object is not in the default group, and was the last of its group, then
603 -- its parent group should be removed
604 if not this
:isInDefaultFeature() then
605 if this
.Parent
.Size
<= 2 then
606 local parentTable
= this
.Parent
607 local parentGroup
= this
.ParentInstance
608 local defaultFeature
= this
:getParentAct():getDefaultFeature()
609 for i
= parentTable
.Size
- 1, 0, -1 do
610 if parentTable
[i
].InstanceId
~= this
.InstanceId
then
611 parentTable
[i
]:requestMakePosRelativeTo(defaultFeature
)
612 r2
:setSelectedInstanceId(parentTable
[i
].InstanceId
)
613 r2
.requestMoveNode(parentTable
[i
].InstanceId
, "", -1, defaultFeature
.InstanceId
, "Components", -1)
617 r2
.requestEraseNode(parentGroup
.InstanceId
, "", -1)
618 r2
.requestEndAction()
623 r2
.requestEraseNode(this
.InstanceId
, "", -1)
624 r2
.requestEndAction()
626 --------------------------------------------------------------------------------------------
627 -- return the behavior object, depending on wether this npc is grouped or not
628 getBehavior
= function(this
)
629 if this
:isGrouped() and this
.ParentInstance
:isKindOf("NpcGrpFeature") then
630 return this
.ParentInstance
.Components
[0].Behavior
635 -----------------------------------------------------------------------------------------------
637 hasScenarioCost
= function(this
)
640 -----------------------------------------------------------------------------------------------
642 isCopyable
= function(this
)
645 -----------------------------------------------------------------------------------------------
647 paste
= function(src
, newPlace
, srcInstanceId
)
649 local Q
, leftQ
, leftStaticQ
= r2
:getLeftQuota()
651 if r2
:isBotObject(r2
.getPropertyValue(src
, "SheetClient")) then quota
= leftStaticQ
end
660 -- CopyChatSequences = 0
664 -- if component is the leader and original group is still present, then give the option to duplicate the whole group
666 if srcInstanceId
then
667 srcInstance
= r2
:getInstanceFromId(srcInstanceId
)
669 local groupCopy
= nil
670 if srcInstance
and srcInstance
:isLeader() then
671 groupCopy
= srcInstance
.ParentInstance
:copy()
672 groupCopy
= r2
.Classes
[groupCopy
.Class
].newCopy(groupCopy
)
673 options
.DuplicateGroup
= 0 -- offer option to do the copy
675 if srcInstance
and srcInstance
.isBotObject
then
676 if srcInstance
:isBotObject() then
677 if not r2
:checkStaticQuota() then return end
679 if not r2
:checkAiQuota() then return end
684 local function paramsOk(options
)
685 if options
.DuplicateGroup
== 1 then
686 r2
.Classes
[groupCopy
.Class
].paste(groupCopy
, src
.Position
, nil, options
)
689 if options
.CopyActivities
== 0 then
690 src
.ActivitiesId
= {}
691 src
.Behavior
.Activities
= {}
693 if options
.CopyEvents
== 0 then
694 src
.Behavior
.Actions
= {}
696 --if options.CopyChatSequences == 0 then
697 -- src.Behavior.ChatSequences = {}
700 src
.Position
.x
, src
.Position
.y
, src
.Position
.z
= r2
:getPastePosition()
702 r2
:setCookie(src
.InstanceId
, "Select", true)
703 if r2
:isBotObject(r2
.getPropertyValue(src
, "SheetClient")) then -- not already an object, so can't call a method yet ...
704 -- add to permanent content
705 r2
.requestInsertNode(r2
.Scenario
:getBaseAct():getDefaultFeature().InstanceId
, "Components",-1,"", src
)
707 -- insert in current act
708 r2
.requestInsertNode(r2
:getCurrentAct():getDefaultFeature().InstanceId
, "Components", -1,"", src
)
711 local function paramsCancel()
712 debugInfo('paste was cancelled')
714 if table.getn(src
.Behavior
.Activities
) == 0 then
715 options
.CopyActivities
= -1
717 if table.getn(src
.Behavior
.Actions
) == 0 then
718 options
.CopyEvents
= -1
720 --if table.getn(src.Behavior.ChatSequences) == 0 then
721 -- options.CopyChatSequences = -1
723 if options
.CopyActivities
>= 0 or
724 options
.CopyEvents
>= 0
725 --or options.CopyChatSequences >= 0
727 r2
:doForm("SpecialPaste", options
, paramsOk
, paramsCancel
)
729 -- nothing specific to copy, do direct paste
733 -----------------------------------------------------------------------------------------------
735 pasteGhost
= function(src
)
738 if r2
:isBotObject(r2
.getPropertyValue(src
, "SheetClient")) then -- not already an object, so can't call a method yet ...
739 -- insert in current act
740 target
= r2
.Scenario
:getBaseAct():getDefaultFeature()
741 if not r2
:checkStaticQuota() then return end
743 -- insert in current act
744 target
= r2
:getCurrentAct():getDefaultFeature()
745 if not r2
:checkAiQuota() then return end
747 -- create the 'Ghosts' entry locally if it doesn't already exists
748 if target
.Ghosts
== nil then
749 r2
.requestInsertGhostNode(target
.InstanceId
, "", -1, "Ghosts", {})
752 r2
.requestInsertGhostNode(target
.InstanceId
, "Ghosts",-1,"", src
)
753 -- insertion should have been done right now
754 return r2
:getInstanceFromId(src
.InstanceId
)
757 getAiCost
= function(this
)
758 if this
.User
.GhostDuplicate
then return 0 end
760 if this
.IsBotObject
== 0 then
766 getStaticObjectCost
= function(this
)
767 if this
.User
.GhostDuplicate
then return 0 end
769 if this
.IsBotObject
== 1 then
775 -- from 'ActiveLogicEntity'
776 getApplicableActions
= function(this
)
777 local actions
= r2
.Classes
[this
.Class
].ApplicableActions
779 if not this
:canUpdateBotAttackable() then
780 local actionsTemp
= {}
781 for k
, v
in pairs(actions
) do
782 if v
~="Fight with Npcs" and v
~="Dont fight with Npcs" then --and v~="Sit Down" and v~="Stand Up" then
783 table.insert(actionsTemp
, v
)
786 actions
= actionsTemp
789 if not this
:canUpdatePlayerAttackable() then
790 local actionsTemp
= {}
791 for k
, v
in pairs(actions
) do
792 if v
~="Fight with player" and v
~="Dont fight with player" then -- and v~="Sit Down" and v~="Stand Up" then
793 table.insert(actionsTemp
, v
)
796 actions
= actionsTemp
803 ------------------------------------------------------------------------------------------------------
804 -- a 'custom' npc : this is a npc that is customizable
808 DisplayerProperties
= "R2::CDisplayerLua",
809 DisplayerPropertiesParams
= "npcCustomPropertySheetDisplayer",
812 -- Look (all widgets have Visible=false because they are edited in the npc editor, not in the property sheet)
814 { Name
="GabaritHeight", Type
="Number", Visible
=false, DefaultInBase
=1 },
815 { Name
="GabaritTorsoWidth", Type
="Number", Visible
=false, DefaultInBase
=1 },
816 { Name
="GabaritArmsWidth", Type
="Number", Visible
=false, DefaultInBase
=1 },
817 { Name
="GabaritLegsWidth", Type
="Number", Visible
=false, DefaultInBase
=1 },
818 { Name
="GabaritBreastSize", Type
="Number", Visible
=false, DefaultInBase
=1 },
820 { Name
="HairType", Type
="Number", Visible
=false, DefaultInBase
=1 },
821 { Name
="HairColor", Type
="Number", Visible
=false, DefaultInBase
=1 },
822 { Name
="Tattoo", Type
="Number", Visible
=false, DefaultInBase
=1 },
823 { Name
="EyesColor", Type
="Number", Visible
=false, DefaultInBase
=1 },
825 { Name
="MorphTarget1", Type
="Number", Visible
=false, DefaultInBase
=1 },
826 { Name
="MorphTarget2", Type
="Number", Visible
=false, DefaultInBase
=1 },
827 { Name
="MorphTarget3", Type
="Number", Visible
=false, DefaultInBase
=1 },
828 { Name
="MorphTarget4", Type
="Number", Visible
=false, DefaultInBase
=1 },
829 { Name
="MorphTarget5", Type
="Number", Visible
=false, DefaultInBase
=1 },
830 { Name
="MorphTarget6", Type
="Number", Visible
=false, DefaultInBase
=1 },
831 { Name
="MorphTarget7", Type
="Number", Visible
=false, DefaultInBase
=1 },
832 { Name
="MorphTarget8", Type
="Number", Visible
=false, DefaultInBase
=1 },
834 --{ Name="Sex", Type="Number", Visible=false, DefaultInBase=1 },
836 { Name
="JacketModel", Type
="Number", Visible
=false, DefaultInBase
=1 },
837 { Name
="TrouserModel", Type
="Number", Visible
=false, DefaultInBase
=1 },
838 { Name
="FeetModel", Type
="Number", Visible
=false, DefaultInBase
=1 },
839 { Name
="HandsModel", Type
="Number", Visible
=false, DefaultInBase
=1 },
840 { Name
="ArmModel", Type
="Number", Visible
=false, DefaultInBase
=1 },
841 { Name
="WeaponRightHand", Type
="Number", Visible
=false, DefaultInBase
=1 },
842 { Name
="WeaponLeftHand", Type
="Number", Visible
=false, DefaultInBase
=1 },
844 { Name
="JacketColor", Type
="Number", Visible
=false, DefaultInBase
=1 },
845 { Name
="ArmColor", Type
="Number", Visible
=false, DefaultInBase
=1 },
846 { Name
="HandsColor", Type
="Number", Visible
=false, DefaultInBase
=1 },
847 { Name
="TrouserColor", Type
="Number", Visible
=false, DefaultInBase
=1 },
848 { Name
="FeetColor", Type
="Number", Visible
=false, DefaultInBase
=1 },
850 { Name
="LinkColor", Type
="Number", Visible
=false, DefaultInBase
=0 },
852 --{ Name="Notes", Type="String", Visible=false, DefaultInBase=1 },
853 { Name
="Function", Type
="String", Visible
=false, DefaultInBase
=1 },
854 --{ Name="Level", Type="String", Visible=false, DefaultInBase=1 },
855 { Name
="Profile", Type
="String", Visible
=false, DefaultInBase
=1 },
856 {Name
="Speed", Type
="Number", WidgetStyle
="EnumDropDown", Category
="uiR2EDRollout_NpcCustom",
857 Enum
= { "uiR2EDWalk", "uiR2EDRun"},
860 {Name
="Level", Type
="Number", WidgetStyle
="EnumDropDown", Category
="uiR2EDRollout_NpcCustom",
861 Enum
= { "uiR2EDLowLevel", "uiR2EDAverageLevel", "uiR2EDHighLevel", "uiR2EDVeryHighLevel"}, SecondRequestFunc
=r2
.updateLevel
,
862 Visible
=function(this
) return this
:isGroupedAndLeader() or not this
:isGrouped() and not this
:isBotObject() end
866 getAvailableCommands
= function(this
, dest
)
867 --local result = this:delegate():getAvailableCommands()
868 r2
.Classes
.Npc
.getAvailableCommands(this
, dest
)
870 -- Additionnal property sheet header to access npc customisation
871 PropertySheetHeader
=
873 <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"/>
875 -- Pop the npc editor
876 customizeLook
= function(this
)
877 -- if the npc edition window is not shown, display it
878 local npcEditionWnd
= getUI("ui:interface:r2ed_npc")
879 if not npcEditionWnd
.active
then
880 npcEditionWnd
.active
= true
881 npcEditionWnd
:updateCoords()
882 npcEditionWnd
:center()
883 -- update the npc window content
884 this
.DisplayerProperties
:updateAll(this
)
886 setTopWindow(npcEditionWnd
)
887 npcEditionWnd
:blink(1)
890 -----------------------------------------------------------------------------------------------
892 hasScenarioCost
= function(this
)
895 -----------------------------------------------------------------------------------------------
896 -- special paste with renaming
897 paste
= function(src
, newPlace
, srcInstanceId
)
898 local base
= r2
.getPaletteElement(src
.Base
)
899 local sex
= r2
.getPropertyValue(base
, "Sex")
901 r2
.Classes
.Npc
.paste(src
, newPlace
, srcInstanceId
)
905 ------------------------------------------------------------------------------------------------------
911 DisplayerProperties
= "R2::CDisplayerLua",
912 DisplayerPropertiesParams
= "npcPropertySheetDisplayer",
915 {Name
="Speed", Type
="Number", WidgetStyle
="EnumDropDown", Category
="uiR2EDRollout_Default",
916 Enum
= { "uiR2EDWalk", "uiR2EDRun"},
917 Visible
=function(this
) return not this
:isKindOf("NpcPlant") end,
921 getApplicableActions
= function(this
)
922 local actions
= r2
.Classes
[this
.Class
].ApplicableActions
924 local actionsTemp
= {}
925 for k
, v
in pairs(actions
) do
926 if v
~="Sit Down" and v
~="Stand Up" then
927 table.insert(actionsTemp
, v
)
935 ------------------------------------------------------------------------------------------------------
940 BaseClass
="NpcCreature",
941 DisplayerProperties
= "R2::CDisplayerLua",
942 DisplayerPropertiesParams
= "npcPropertySheetDisplayer",
948 ApplicableActions
= {
950 "Deactivate", "Kill",
954 "desactivation", "death",
961 -- base class for primitives, include copy-paste code
963 BaseClass
="WorldObject",
964 Name
="BasePrimitive",
967 {Name
="Name", Type
="String", MaxNumChar
="32"}
969 --------------------------------------------------------------------------------------------
970 onPostCreate
= function(this
)
971 this
.DisplayerVisual
.DisplayMode
= r2
:getPrimDisplayMode()
972 this
.DisplayerVisual
.ContextualVisibilityActive
= r2
.PrimDisplayContextualVisibility
974 onActChanged
= function(this
)
975 this
.DisplayerVisual
.ContextualVisibilityActive
= r2
.PrimDisplayContextualVisibility
977 --------------------------------------------------------------------------------------------
978 onPostCreate
= function(this
)
979 this
.DisplayerVisual
.DisplayMode
= r2
:getPrimDisplayMode()
980 this
.DisplayerVisual
.ContextualVisibilityActive
= r2
.PrimDisplayContextualVisibility
982 onActChanged
= function(this
)
983 this
.DisplayerVisual
.ContextualVisibilityActive
= r2
.PrimDisplayContextualVisibility
985 --------------------------------------------------------------------------------------------
987 canChangeDisplayMode
= function(this
)
990 -----------------------------------------------------------------------------------------------
992 isCopyable
= function(this
)
995 isNextSelectable
= function(this
)
998 -----------------------------------------------------------------------------------------------
1000 getAvailableCommands
= function(this
, dest
)
1001 r2
.Classes
.WorldObject
.getAvailableCommands(this
, dest
) -- fill by ancestor
1002 table.insert(dest
, this
:buildCommand(this
.onNewVertexTool
, "new_vertex", "uimR2EDAddNewVertices", "r2ed_tool_new_vertex.tga"))
1004 -----------------------------------------------------------------------------------------------
1005 onNewVertexTool
= function(this
)
1006 r2
:setCurrentTool('R2::CToolNewVertex')
1007 r2
.ContextualCommands
:highlightCurrentCommandButton("new_vertex")
1009 -----------------------------------------------------------------------------------------------
1011 paste
= function(src
, newPlace
, srcInstanceId
)
1012 --if r2:getLeftQuota() <= 0 then
1017 --if r2.Classes[src.Class].isCopyInsideCurrIsland(src) then
1018 -- src.Position.x = src.Position.x + 4 * (math.random() - 0.5)
1019 -- src.Position.y = src.Position.y + 4 * (math.random() - 0.5)
1020 -- src.Position.z = src.Position.z + 4 * (math.random() - 0.5)
1022 local mx
, my
, mz
= r2
.Classes
[src
.Class
].getCopyCenter(src
)
1024 mx
= mx
+ src
.Position
.x
1025 my
= my
+ src
.Position
.y
1026 mz
= mz
+ src
.Position
.z
1027 -- get player pos in world
1028 local px
, py
, pz
= getPlayerPos()
1030 -- add delta to have primitive center in world over player pos
1031 src
.Position
.x
= src
.Position
.x
+ px
- mx
+ 4 * (math
.random() - 0.5)
1032 src
.Position
.y
= src
.Position
.y
+ py
- my
+ 4 * (math
.random() - 0.5)
1033 src
.Position
.z
= src
.Position
.z
+ pz
- mz
+ 4 * (math
.random() - 0.5)
1036 r2
.requestInsertNode(r2
.Scenario
:getBaseAct():getDefaultFeature().InstanceId
, "Components", -1, "", src
)
1037 r2
:setCookie(src
.InstanceId
, "Select", true)
1039 -----------------------------------------------------------------------------------------------
1040 -- Function (not method) : test if the passed primitive copy (obtained
1041 -- with BasePrimitive:copy is inside the current island
1042 -- The default behavior is to test each vertices inside the 'Points' array
1043 -- are inside the current island rectangle. If a derivers is not defined
1044 -- as a set of points, it should provide the good test here
1045 isCopyInsideCurrIsland
= function(src
)
1046 for k
, v
in pairs(src
.Points
) do
1047 if not r2
:isInIslandRect(v
.Position
.x
, v
.Position
.y
) then return false end
1051 -----------------------------------------------------------------------------------------------
1052 -- Function (not method) : return the center a a copîed primitive obtained with
1053 -- BasePrimitive:copy
1054 getCopyCenter
= function(src
)
1059 for k
, v
in pairs(src
.Points
) do
1060 x
= x
+ v
.Position
.x
1061 y
= y
+ v
.Position
.y
1062 z
= z
+ v
.Position
.z
1072 -----------------------------------------------------------------------------------------------
1074 pasteGhost
= function(src
)
1075 --if r2:getLeftQuota() <= 0 then
1079 target
= r2
.Scenario
:getBaseAct():getDefaultFeature()
1080 if target
.Ghosts
== nil then
1081 r2
.requestInsertGhostNode(target
.InstanceId
, "", -1, "Ghosts", {})
1083 r2
.requestInsertNode(target
.InstanceId
, "Ghosts", -1, "", src
)
1084 return r2
:getInstanceFromId(src
.InstanceId
)
1087 ------------------------------------------------------------------------------------------------------
1089 BaseClass
="BasePrimitive",
1091 Menu
="ui:interface:r2ed_base_menu",
1092 TreeIcon
= function(this
)
1093 if this
:isInDefaultFeature() then return "" else return "r2ed_icon_region.tga" end
1095 DisplayerUI
= "R2::CDisplayerLua",
1096 DisplayerUIParams
= "defaultUIDisplayer",
1097 DisplayerVisual
= "R2::CDisplayerVisualGroup",
1098 DisplayerVisualParams
=
1100 Look
= r2
.PrimRender
.RegionLook
,
1101 InvalidLook
= r2
.PrimRender
.RegionInvalidLook
,
1103 ArrayName
= "Points"
1107 -- {Name="Base", Type="String", WidgetStyle="StaticText", Category="Advanced"},
1108 {Name
="Points", Type
="Table"},
1110 --------------------------------------------------------------------------------------------
1111 getSelectBarIcon
= function(this
)
1112 return "r2ed_icon_region.tga"
1114 getAvailableCommands
= function(this
, dest
)
1115 r2
.Classes
.BasePrimitive
.getAvailableCommands(this
, dest
) -- fill by ancestor
1116 this
:getAvailableDisplayModeCommands(dest
)
1119 ---------------------------------------------------------------------------------------------------------
1120 -- get select bar type
1121 SelectBarType
= function(this
)
1122 return i18n
.get("uiR2EDbotObjects"):toUtf8()
1124 --------------------------------------------------------------------------------------------
1126 getParentTreeNode
= function(this
)
1127 -- if not this:isInDefaultFeature() then
1128 -- return r2.Classes.WorldObject.getParentTreeNode(this)
1130 -- local tree = getUI("ui:interface:r2ed_scenario")
1131 -- return tree:find("content_tree_list"):getRootNode():getNodeFromId("places")
1135 -----------------------------------------------------------------------------------------------
1137 --getUsedQuota = function(this)
1141 ------------------------------------------------------------------------------------------------------
1143 BaseClass
="BasePrimitive",
1145 --DisplayerVisual = "R2::CDisplayerVisualRoad",
1146 DisplayerVisual
= "R2::CDisplayerVisualGroup",
1147 TreeIcon
= function(this
)
1148 if this
:isInDefaultFeature() then return "" else return "r2ed_icon_road.tga" end
1150 DisplayerVisualParams
=
1152 Look
= r2
.PrimRender
.RoadLook
,
1153 InvalidLook
= r2
.PrimRender
.RoadLookInvalid
,
1155 ArrayName
= "Points"
1157 DisplayerUI
= "R2::CDisplayerLua",
1158 DisplayerUIParams
= "defaultUIDisplayer",
1159 Menu
="ui:interface:r2ed_base_menu",
1162 -- {Name="Base", Type="String", WidgetStyle="StaticText", Category="Advanced"},
1163 {Name
="Points", Type
="Table"}
1165 --------------------------------------------------------------------------------------------
1166 getSelectBarIcon
= function(this
)
1167 return "r2ed_icon_road.tga"
1170 ---------------------------------------------------------------------------------------------------------
1171 -- get select bar type
1172 SelectBarType
= function(this
)
1173 return i18n
.get("uiR2EDbotObjects"):toUtf8()
1175 --------------------------------------------------------------------------------------------
1177 getParentTreeNode
= function(this
)
1178 -- if not this:isInDefaultFeature() then
1179 -- return r2.Classes.WorldObject.getParentTreeNode(this)
1181 -- local tree = getUI("ui:interface:r2ed_scenario")
1182 -- return tree:find("content_tree_list"):getRootNode():getNodeFromId("routes")
1186 -----------------------------------------------------------------------------------------------
1188 getAvailableCommands
= function(this
, dest
)
1189 r2
.Classes
.BasePrimitive
.getAvailableCommands(this
, dest
) -- fill by ancestor
1190 table.insert(dest
, this
:buildCommand(this
.onExtendRoad
, "extend_road", "uiR2EDExtendRoad", "r2ed_tool_extend_prim.tga"))
1191 this
:getAvailableDisplayModeCommands(dest
)
1193 -----------------------------------------------------------------------------------------------
1194 onExtendRoad
= function(this
)
1195 r2
:setCurrentTool('R2::CToolDrawPrim',
1197 Look
= r2
.PrimRender
.RoadCreateLook
,
1198 InvalidLook
= r2
.PrimRender
.RoadCreateInvalidLook
,
1200 ExtendedPrimitiveId
= this
.InstanceId
1203 r2
.ContextualCommands
:highlightCurrentCommandButton("extend_road")
1205 -----------------------------------------------------------------------------------------------
1207 --getUsedQuota = function(this)
1211 ------------------------------------------------------------------------------------------------------
1213 BaseClass
="WorldObject",
1215 BuildPropertySheet
= false,
1216 DisplayerVisual
= "R2::CDisplayerVisualShape",
1217 DisplayerVisualParams
= { ShapeName
= r2
.PrimRender
.RoadCreateLook
.VertexShapeName
,
1218 Scale
= r2
.PrimRender
.RoadCreateLook
.VertexShapeScale
,
1219 InheritDisplayMode
= true
1222 Menu
="ui:interface:r2ed_base_menu",
1225 -- NOTE : position inherit from 'WorldObject'
1227 onDelete
= function(this
)
1228 if this
.User
.DeleteInProgress
== true then return end
1229 this
.User
.DeleteInProgress
= true
1230 this
:setDeleteActionName()
1231 -- if I'm the last in the array, then delete my parent
1232 if this
.Parent
.Size
<= 2 then
1233 this
.ParentInstance
:selectNext()
1234 r2
.requestEraseNode(this
.ParentInstance
.InstanceId
, "", -1)
1236 -- just delete my self
1238 r2
.requestEraseNode(this
.InstanceId
, "", -1)
1240 r2
.requestEndAction()
1242 setDeleteActionName
= function(this
)
1243 r2
.requestNewAction(i18n
.get("uiR2EDDeletingWayPoint"))
1245 isNextSelectable
= function(this
)
1249 ------------------------------------------------------------------------------------------------------
1251 BaseClass
="WorldObject",
1252 Name
="RegionVertex",
1253 BuildPropertySheet
= false,
1254 DisplayerVisual
= "R2::CDisplayerVisualShape",
1255 DisplayerVisualParams
= { ShapeName
= r2
.PrimRender
.RegionCreateLook
.VertexShapeName
,
1256 Scale
= r2
.PrimRender
.RegionCreateLook
.VertexShapeScale
,
1257 InheritDisplayMode
= true
1260 Menu
="ui:interface:r2ed_base_menu",
1263 -- NOTE : position inherit from 'WorldObject'
1265 setDeleteActionName
= function(this
)
1266 r2
.requestNewAction(i18n
.get("uiR2EDDeletingRegionVertex"))
1268 onDelete
= function(this
)
1269 if this
.User
.DeleteInProgress
== true then return end
1270 this
.User
.DeleteInProgress
= true
1271 this
:setDeleteActionName()
1272 -- if I'm the last in the array, then delete my parent
1273 if this
.Parent
.Size
<= 3 then
1274 this
.ParentInstance
:selectNext()
1275 r2
.requestEraseNode(this
.ParentInstance
.InstanceId
, "", -1)
1277 -- just delete my self
1279 r2
.requestEraseNode(this
.InstanceId
, "", -1)
1281 r2
.requestEndAction()
1283 isNextSelectable
= function(this
)
1287 ------------------------------------------------------------------------------------------------------
1289 BaseClass
="BasePrimitive",
1291 DisplayerUI
= "R2::CDisplayerLua",
1292 DisplayerUIParams
= "defaultUIDisplayer",
1293 Menu
="ui:interface:r2ed_base_menu",
1296 {Name
="Radius", Type
="Number"}
1298 -- from BasePrimitive
1299 isCopyInsideCurrIsland
= function(src
)
1300 return r2
:isInIslandRect(src
.Position
.x
, src
.Position
.y
)
1302 -- from BasePrimitive
1303 getCopyCenter
= function(src
)
1304 return src
.Position
.x
, src
.Position
.y
, src
.Position
.z
1307 getAvailableCommands
= function(this
, dest
)
1308 r2
.Classes
.BasePrimitive
.getAvailableCommands(this
, dest
) -- fill by ancestor
1309 this
:getAvailableDisplayModeCommands(dest
)
1312 ------------------------------------------------------------------------------------------------------
1314 BaseClass
="BaseClass",
1319 {Name
="x", Type
="Number"},
1320 {Name
="y", Type
="Number"},
1321 {Name
="z", Type
="Number"}
1323 -- test if this position is equal to another position (not necessarily an instance,
1324 -- may be any table with the { x = ..., y = ..., z = ... } format
1325 equals
= function(this
, other
)
1326 return this
.x
== other
.x
and this
.y
== other
.y
and this
.z
== other
.z
1328 -- return string version of position
1329 toString
= function(this
)
1330 return "(" .. tostring(this
.x
) .. ", " .. tostring(this
.y
) .. ", " .. tostring(this
.z
) .. ")"
1333 UserComponentHolder
=
1335 BaseClass
="LogicEntity",
1336 Name
="UserComponentHolder",
1338 Menu
="ui:interface:r2ed_feature_menu",
1339 DisplayerUI
= "R2::CDisplayerLua",
1340 DisplayerUIParams
= "defaultUIDisplayer",
1341 DisplayerVisual
= "R2::CDisplayerVisualEntity",
1346 ApplicableActions
= {},
1354 TextParameters
= {},
1356 LiveParameters
= {},
1360 {Name
="InstanceId", Type
="String", WidgetStyle
="StaticText", Visible
= false},
1361 {Name
="Name", Type
="String"},
1362 {Name
="Description", Type
="String"},
1363 {Name
="Components", Type
="Table", Visible
=false},
1366 getParentTreeNode
= function(this
)
1367 return this
:getFeatureParentTreeNode()
1370 appendInstancesByType
= function(this
, destTable
, kind
)
1371 assert(type(kind
) == "string")
1372 r2
.Classes
.LogicEntity
.appendInstancesByType(this
, destTable
, kind
)
1373 for k
, component
in specPairs(this
.Components
) do
1374 component
:appendInstancesByType(destTable
, kind
)
1378 getSelectBarSons
= function(this
)
1382 canHaveSelectBarSons
= function(this
)
1386 onPostCreate
= function(this
)
1389 pretranslate
= function(this
, context
)
1390 r2
.Translator
.createAiGroup(this
, context
)
1391 r2
.Translator
.pretranslateDefaultFeature(this
, context
)
1394 translate
= function(this
, context
)
1395 r2
.Translator
.translateDefaultFeature(this
, context
, true)
1398 getActivitiesIds
= r2
.Translator
.getDefaultFeatureActivitiesIds
,
1399 -- TODO use sexy images
1400 getAvailableCommands
= function(this
, dest
)
1401 r2
.Classes
.LogicEntity
.getAvailableCommands(this
, dest
)
1402 table.insert(dest
, this
:buildActivityCommand(this
.onPickAddEntity
, "add_entity", "uimR2EDMenuPickAddEntity", "r2_toolbar_customize_look.tga", true))
1403 table.insert(dest
, this
:buildActivityCommand(this
.onPickRemoveEntity
, "remove_entity", "uimR2EDMenuPickRemoveEntity", "r2_toolbar_delete.tga", false))
1404 table.insert(dest
, this
:buildActivityCommand(this
.onPickExport
, "export", "uimR2EDMenuPickExport", "r2_toolbar_properties.tga", false))
1410 -- !feature.Components
1411 ------------------------------------------------------------------------------------------------------
1412 classLogicEntityBehaviorVersion
= 1
1414 feature
.Components
.LogicEntityBehavior
= {
1415 Name
="LogicEntityBehavior",
1416 BaseClass
="BaseClass",
1417 Version
= classLogicEntityBehaviorVersion
,
1420 {Name
="Actions", Type
="Table"},
1421 -- {Name="Reactions", Type="Table"}
1424 updateVersion
= function(this
, scenarioValue
, currentValue
)
1425 local patchValue
= scenarioValue
1426 if patchValue
< 1 then
1427 -- Patch only for old save (not the 0.0.3)
1428 if this
.Reactions
~= nil then
1429 -- TODO use identifier instead
1430 r2
.requestEraseNode(this
.InstanceId
, "Reactions", -1)
1435 if patchValue
== currentValue
then return true end
1441 ------------------------------------------------------------------------------------------------------
1442 local userComponentHolder
= feature
.Components
.UserComponentHolder
1444 userComponentHolder
.getLogicAction
= function(entity
, context
, action
)
1445 local firstAction
, lastAction
= nil,nil
1446 return firstAction
, lastAction
1450 userComponentHolder
.getLogicCondition
= function(this
, context
, condition
)
1455 userComponentHolder
.getLogicEvent
= function(this
, context
, event
)
1456 local eventHandler
, firstCondition
, lastCondition
= nil, nil, nil
1457 return eventHandler
, firstCondition
, lastCondition
1460 function userComponentHolder
:registerMenu(logicEntityMenu
)
1461 local name
= i18n
.get("uiR2EdUserComponent")
1462 logicEntityMenu
:addLine(ucstring(name
), "lua", "", "uiR2EdUserComponent")
1466 function userComponentHolder
:getLogicTranslations()
1467 local logicTranslations
= {
1468 ["ApplicableActions"] = {},
1471 return logicTranslations
1473 function userComponentHolder
.onPickExport(this
)
1474 local refX
= this
.Position
.x
1475 local refY
= this
.Position
.y
1476 local refZ
= this
.Position
.z
1478 local components
= this
.Components
1479 r2_core
.UserComponentManager
.CurrentDesc
= this
.Description
1480 local exportList
= {}
1481 local k
, v
= next(components
, nil)
1483 if v
.InstanceId
then
1484 table.insert(exportList
, v
.InstanceId
)
1486 k
, v
= next(components
, k
)
1488 r2_core
.UserComponentManager
:export(exportList
, refX
, refY
, refZ
)
1491 function userComponentHolder
.create()
1492 if not r2
:checkAiQuota() then return end
1494 local function paramsCancel()
1495 debugInfo("Cancel form for 'User Component' creation")
1497 local function posOk(x
, y
, z
)
1498 debugInfo(string.format("Validate creation of 'User Component' at pos (%d, %d, %d)", x
, y
, z
))
1499 if r2
.mustDisplayInfo("UserComponent") == 1 then
1500 r2
.displayFeatureHelp("UserComponent")
1502 local component
= r2
.newComponent("UserComponentHolder")
1503 component
.Base
= r2
.Translator
.getDebugBase("palette.entities.botobjects.user_event")
1504 component
.Name
= r2
:genInstanceName(i18n
.get("uiR2EdUserComponent")):toUtf8()
1506 component
.Position
.x
= x
1507 component
.Position
.y
= y
1508 component
.Position
.z
= r2
:snapZToGround(x
, y
)
1510 r2
:setCookie(component
.InstanceId
, "DisplayProp", 1)
1511 r2
.requestInsertNode(r2
:getCurrentAct().InstanceId
, "Features", -1, "", component
)
1514 local function posCancel()
1515 debugInfo("Cancel choice 'User Component' position")
1517 local creature
= r2
.Translator
.getDebugCreature("object_component_user_event.creature")
1518 r2
:choosePos(creature
, posOk
, posCancel
, "createUserComponent")
1521 function userComponentHolder
:registerMenu(logicEntityMenu
)
1522 local name
= i18n
.get("uiR2EdUserComponent")
1523 logicEntityMenu
:addLine(ucstring(name
), "lua", "", "uiR2EdUserComponent")
1526 function userComponentHolder
.onPickAddEntity(this
)
1527 r2_core
.CurrentHolderId
= this
.InstanceId
1528 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")
1529 r2
.ContextualCommands
:highlightCommandButton("add_entity")
1532 function userComponentHolder
.onPickRemoveEntity(this
)
1533 r2_core
.CurrentHolderId
= this
.InstanceId
1534 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")
1535 r2
.ContextualCommands
:highlightCommandButton("remove_entity")
1538 function userComponentHolder
.onPostCreate(this
)
1539 if this
.User
.DisplayProp
and this
.User
.DisplayProp
== 1 then
1540 r2
:setSelectedInstanceId(this
.InstanceId
)
1541 r2
:showProperties(this
)
1542 this
.User
.DisplayProp
= nil
1546 function userComponentHolder
.onPickExport(this
)
1547 local refX
= this
.Position
.x
1548 local refY
= this
.Position
.y
1549 local refZ
= this
.Position
.z
1551 local components
= this
.Components
1552 r2_core
.UserComponentManager
.CurrentDesc
= this
.Description
1553 local exportList
= {}
1554 local k
, v
= next(components
, nil)
1556 if v
.InstanceId
then
1557 table.insert(exportList
, v
.InstanceId
)
1559 k
, v
= next(components
, k
)
1561 r2_core
.UserComponentManager
:export(exportList
, refX
, refY
, refZ
)
1564 function userComponentHolder
.create()
1565 if not r2
:checkAiQuota() then return end
1567 local function paramsCancel()
1568 debugInfo("Cancel form for 'User Component' creation")
1570 local function posOk(x
, y
, z
)
1571 debugInfo(string.format("Validate creation of 'User Component' at pos (%d, %d, %d)", x
, y
, z
))
1572 if r2
.mustDisplayInfo("UserComponent") == 1 then
1573 r2
.displayFeatureHelp("UserComponent")
1575 local component
= r2
.newComponent("UserComponentHolder")
1576 component
.Base
= r2
.Translator
.getDebugBase("palette.entities.botobjects.user_event")
1577 component
.Name
= r2
:genInstanceName(i18n
.get("uiR2EdUserComponent")):toUtf8()
1579 component
.Position
.x
= x
1580 component
.Position
.y
= y
1581 component
.Position
.z
= r2
:snapZToGround(x
, y
)
1583 r2
:setCookie(component
.InstanceId
, "DisplayProp", 1)
1584 r2
.requestInsertNode(r2
:getCurrentAct().InstanceId
, "Features", -1, "", component
)
1587 local function posCancel()
1588 debugInfo("Cancel choice 'User Component' position")
1590 local creature
= r2
.Translator
.getDebugCreature("object_component_user_event.creature")
1591 r2
:choosePos(creature
, posOk
, posCancel
, "createUserComponent")
1594 feature
.Components
.DefaultFeature
= {
1595 BaseClass
="BaseClass",
1596 Name
="DefaultFeature",
1597 --TreeIcon="r2ed_icon_default_feature.tga",
1599 Menu
="ui:interface:r2ed_base_menu",
1602 {Name
="Components", Type
="Table"},
1604 ---------------------------------------------------------------------------------------------------------
1605 getFirstSelectableSon
= function(this
)
1606 for k
= 0, this
.Components
.Size
- 1 do
1607 if this
.Components
[k
].Selectable
then
1608 return this
.Components
[k
]
1613 ---------------------------------------------------------------------------------------------------------
1615 appendInstancesByType
= function(this
, destTable
, kind
)
1616 assert(type(kind
) == "string")
1617 --this:delegate():appendInstancesByType(destTable, kind)
1618 r2
.Classes
.BaseClass
.appendInstancesByType(this
, destTable
, kind
)
1619 for k
, component
in specPairs(this
.Components
) do
1620 component
:appendInstancesByType(destTable
, kind
)
1623 -----------------------------------------------------------------------------------------------
1625 hasScenarioCost
= function(this
)
1628 -----------------------------------------------------------------------------------------------
1630 displayInSelectBar
= function(this
)
1634 pretranslate
= r2
.Translator
.pretranslateDefaultFeature
,
1635 pretranslate2
= r2
.Translator
.pretranslateDefaultFeature2
,
1637 translate
= r2
.Translator
.translateDefaultFeature
,
1639 getAiCost
= function(this
)
1640 return r2
.getAiCost(this
) - 1
1643 getStaticObjectCost
= function(this
)
1644 return r2
.getStaticObjectCost(this
)
1649 function feature
.Components
.DefaultFeature
.getActivitiesIds(this
)
1650 return r2
.Translator
.getDefaultFeatureActivitiesIds(this
)
1654 local componentNpc
= feature
.Components
.Npc
1656 ----------------------------------------------------------------------------
1657 -- add a line to the event menu
1658 function componentNpc
.initLogicEntitiesMenu(this
, logicEntityMenu
, testApplicableAction
)
1659 local name
= i18n
.get("uiR2EDnpc")
1660 local existPeople
= nil
1662 local enumerator
= r2
:enumInstances("Npc")
1664 local inst
= enumerator
:next()
1665 if not inst
then break end
1666 local condExistPeople
= not (inst
:isKindOf("NpcCreature") or inst
:isBotObject() or inst
:isPlant())
1667 if not r2
.events
.memberManagement
then --TEMP
1668 condExistPeople
= not (inst
:isKindOf("NpcCreature") or inst
:isBotObject() or inst
:isPlant() or inst
:isGrouped()) --TEMP
1670 if condExistPeople
then
1676 if existPeople
and (not r2
.events
.memberManagement
or testApplicableAction
==nil or (testApplicableAction
==true and r2
.events
:hasApplicableActions(existPeople
))) then
1677 logicEntityMenu
:addLine(name
, "lua", "", "Npc")
1681 ----------------------------------------------------------------------------
1682 -- add a line to the event sub menu
1683 function componentNpc
.initLogicEntitiesInstancesMenu(this
, subMenu
, calledFunction
)
1685 local enumerator
= r2
:enumInstances("Npc")
1687 local entity
= enumerator
:next()
1688 if not entity
then break end
1689 local addLine
= not (entity
:isKindOf("NpcCreature") or entity
:isBotObject() or entity
:isPlant())
1690 if not r2
.events
.memberManagement
then --TEMP
1691 addLine
= not (entity
:isKindOf("NpcCreature") or entity
:isBotObject() or entity
:isPlant() or entity
:isGrouped()) --TEMP
1694 local uc_name
= ucstring()
1695 uc_name
:fromUtf8(entity
.Name
)
1696 subMenu
:addLine(uc_name
, "lua", calledFunction
.."('".. entity
.InstanceId
.."')", entity
.InstanceId
)
1702 subMenu
:addLine(i18n
.get("uiR2EdNoSelelection"), "", "", "")
1706 ----------------------------------------------------------------------------
1707 -- add a line to the event menu
1708 function componentNpc
:getLogicTranslations()
1710 local logicTranslations
= {
1711 ["ApplicableActions"] = {
1712 ["Activate"] = {menu
=i18n
.get("uiR2EdActivates"):toUtf8(),
1713 text
=r2
:lowerTranslate("uiR2EdActivates")},
1714 ["Deactivate"] = {menu
=i18n
.get("uiR2EdDeactivates"):toUtf8(),
1715 text
=r2
:lowerTranslate("uiR2EdDeactivates")},
1716 ["Sit Down"] = {menu
=i18n
.get("uiR2EdSitDown"):toUtf8(),
1717 text
=r2
:lowerTranslate("uiR2EdSitsDown")},
1718 ["Stand Up"] = {menu
=i18n
.get("uiR2EdStandUp"):toUtf8(),
1719 text
=r2
:lowerTranslate("uiR2EdStandsUp")},
1720 ["Kill"] = {menu
=i18n
.get("uiR2EdKill"):toUtf8(),
1721 text
=r2
:lowerTranslate("uiR2EdKills")},
1722 ["begin activity sequence"] = {menu
=i18n
.get("uiR2EdBeginActivitySequ"):toUtf8(),
1723 text
=r2
:lowerTranslate("uiR2EdSequenceStarts")},
1724 ["Fight with player"] = {menu
=i18n
.get("uiR2EdFightWithPlayer"):toUtf8(),
1725 text
=r2
:lowerTranslate("uiR2EdFightWithPlayer")},
1726 ["Fight with Npcs"] = {menu
=i18n
.get("uiR2EdFightWithNpcs"):toUtf8(),
1727 text
=r2
:lowerTranslate("uiR2EdFightWithNpcs")},
1728 ["Dont fight with player"] = {menu
=i18n
.get("uiR2EdDontFightWithPlayer"):toUtf8(),
1729 text
=r2
:lowerTranslate("uiR2EdDontFightWithPlayer")},
1730 ["Dont fight with Npcs"] = {menu
=i18n
.get("uiR2EdDontFightWithNpcs"):toUtf8(),
1731 text
=r2
:lowerTranslate("uiR2EdDontFightWithNpcs")},
1732 ["Run"] = {menu
=i18n
.get("uiR2EdRun"):toUtf8(),
1733 text
=r2
:lowerTranslate("uiR2EdRun")},
1734 ["Dont run"] = {menu
=i18n
.get("uiR2EdDontRun"):toUtf8(),
1735 text
=r2
:lowerTranslate("uiR2EdDontRun")},
1739 ["activation"] = {menu
=i18n
.get("uiR2EdActivation"):toUtf8(),
1740 text
=r2
:lowerTranslate("uiR2EdActivation")},
1741 ["desactivation"] = {menu
=i18n
.get("uiR2EdDeactivation"):toUtf8(),
1742 text
=r2
:lowerTranslate("uiR2EdDeactivation")},
1743 ["death"] = {menu
=i18n
.get("uiR2EdDeath"):toUtf8(),
1744 text
=r2
:lowerTranslate("uiR2EdDeath")},
1745 ["end of activity step"] = {menu
=i18n
.get("uiR2EdEndActivityStep"):toUtf8(),
1746 text
=r2
:lowerTranslate("uiR2EdEndActivityStep")},
1747 ["end of activity sequence"] = {menu
=i18n
.get("uiR2EdEndActivitySequ"):toUtf8(),
1748 text
=r2
:lowerTranslate("uiR2EdEndActivitySequ")},
1749 ["begin of activity step"] = {menu
=i18n
.get("uiR2EdBeginActivityStep"):toUtf8(),
1750 text
=r2
:lowerTranslate("uiR2EdBeginActivityStep")},
1751 ["begin of activity sequence"] = {menu
=i18n
.get("uiR2EdBeginOfActivitySequ"):toUtf8(),
1752 text
=r2
:lowerTranslate("uiR2EdBeginOfActivitySequ")},
1753 ["targeted by player"] = {menu
=i18n
.get("uiR2EdTargetedByplayer"):toUtf8(),
1754 text
=r2
:lowerTranslate("uiR2EdTargetedByplayer")}
1758 ["is active"] = { menu
=i18n
.get( "uiR2Test0Spawned" ):toUtf8(),
1759 text
=i18n
.get( "uiR2Test1Spawned" ):toUtf8()},
1760 ["is inactive"] = { menu
=i18n
.get( "uiR2Test0Despawned" ):toUtf8(),
1761 text
=i18n
.get( "uiR2Test1Despawned" ):toUtf8()},
1762 ["is dead"] = { menu
=i18n
.get( "uiR2Test0Dead" ):toUtf8(),
1763 text
=i18n
.get( "uiR2Test1Dead" ):toUtf8()},
1764 ["is alive"] = { menu
=i18n
.get( "uiR2Test0Alive" ):toUtf8(),
1765 text
=i18n
.get( "uiR2Test1Alive" ):toUtf8()},
1766 ["is in activity sequence"] = { menu
=i18n
.get( "uiR2Test0Seq" ):toUtf8(),
1767 text
=i18n
.get( "uiR2Test1Seq" ):toUtf8()},
1768 ["is in activity step"] = { menu
=i18n
.get( "uiR2Test0Step" ):toUtf8(),
1769 text
=i18n
.get( "uiR2Test1Step" ):toUtf8()},
1772 return logicTranslations
1775 componentNpc
.getLogicCondition
= r2
.Translator
.getNpcLogicCondition
1776 componentNpc
.getLogicAction
= r2
.Translator
.getNpcLogicAction
1777 componentNpc
.getLogicEvent
= r2
.Translator
.getNpcLogicEvent
1780 feature
.getCost
= function (featureInstance
)
1782 local components
= featureInstance
.Components
1784 local key
,comp
= next(components
,nil)
1788 if (comp
.Class
== "Npc" or comp
.Class
== "NpcCustom")
1792 key
,comp
= next(components
,key
)
1798 feature
.Translator
= function (context
)
1800 local components
= context
.Feature
.Components
1801 --luaObject(context.Feature)
1802 local key
,comp
= next(components
,nil)
1805 -- Npc case (npc alone not object)
1806 if (comp
.isKindOf
and comp
:isKindOf( "Npc"))
1810 context
.Feature
= hlNpc
1812 -- create and set rtNpc
1813 local rtNpc
= r2
.Translator
.translateNpc(hlNpc
, context
)
1814 table.insert(context
.RtAct
.Npcs
, rtNpc
)
1816 -- create or get rtGrp
1817 -- set rtGrp.GroupParameter by reading hlNpc (Aggro, Player attackable..)
1818 local rtNpcGrp
= r2
.Translator
.getRtGroup(context
,hlNpc
.InstanceId
)
1819 r2
.Translator
.setGroupParameters(hlNpc
, rtNpcGrp
)
1820 --table.insert(context.RtAct.NpcGrps, rtNpcGrp)
1821 table.insert(rtNpcGrp
.Children
, rtNpc
.Id
)
1824 local aiActivity
= r2
.Translator
.getAiActivity(hlNpc
)
1825 r2
.Translator
.translateActivities(context
, hlNpc
, hlNpc
:getBehavior(), rtNpcGrp
, aiActivity
)
1827 -- set eventHandlers
1828 r2
.Translator
.translateEventHandlers(context
, hlNpc
, hlNpc
:getBehavior().Actions
, rtNpcGrp
)
1831 key
,comp
= next(components
,key
)
1836 local componentNpcCustom
= feature
.Components
.NpcCustom
1838 ----------------------------------------------------------------------------
1839 -- add no line to the event menu
1840 function componentNpcCustom
.initLogicEntitiesMenu(this
, logicEntityMenu
)
1843 ----------------------------------------------------------------------------
1844 -- add a line to the event sub menu
1845 function componentNpcCustom
.initLogicEntitiesInstancesMenu(this
, subMenu
, calledFunction
)
1848 ----------------------------------------------------------------------------
1849 -- add a line to the event menu
1850 --function componentNpcCustom:getLogicTranslations()
1854 function componentNpcCustom
.newCopy(this
)
1855 local result
= r2
.Classes
.BaseClass
.newCopy(this
)
1858 if isR2PlayerMale(result
.SheetClient
) then
1863 local race
= getR2PlayerRace(result
.SheetClient
)
1865 result
.Name
= r2
:randomNPCName2(race
, sex
)
1870 ---------------------------------------------------------------------------------------------------------
1871 -- Show the property window for this instance
1872 function componentNpcCustom
.onShowProperties(this
)
1873 local npcUI
= getUI("ui:interface:r2ed_npc")
1876 if npcUI
.active
then
1880 r2
.Classes
.BaseClass
.onShowProperties(this
)
1885 local componentNpcCreature
= feature
.Components
.NpcCreature
1887 ----------------------------------------------------------------------------
1888 -- add no line to the event menu
1889 function componentNpcCreature
.initLogicEntitiesMenu(this
, logicEntityMenu
, testApplicableAction
)
1891 local name
= i18n
.get("uiR2EDCreatures")
1892 local existCreature
= nil
1893 local enumerator
= r2
:enumInstances("NpcCreature")
1895 local inst
= enumerator
:next()
1896 if not inst
then break end
1897 local condExistCreature
= not inst
:isKindOf("NpcPlant")
1898 if not r2
.events
.memberManagement
then --TEMP
1899 condExistCreature
= not (inst
:isKindOf("NpcPlant") or inst
:isGrouped()) --TEMP
1901 if condExistCreature
then
1902 existCreature
= inst
1907 if existCreature
and (not r2
.events
.memberManagement
or testApplicableAction
==nil or (testApplicableAction
==true and r2
.events
:hasApplicableActions(existCreature
))) then
1908 logicEntityMenu
:addLine(name
, "lua", "", "NpcCreature")
1912 ----------------------------------------------------------------------------
1913 -- add a line to the event sub menu
1914 function componentNpcCreature
.initLogicEntitiesInstancesMenu(this
, subMenu
, calledFunction
)
1916 local enumerator
= r2
:enumInstances("NpcCreature")
1918 local entity
= enumerator
:next()
1919 if not entity
then break end
1920 local addLine
= not entity
:isKindOf("NpcPlant")
1921 if not r2
.events
.memberManagement
then
1922 addLine
= not (entity
:isKindOf("NpcPlant") or entity
:isGrouped())
1925 local uc_name
= ucstring()
1926 uc_name
:fromUtf8(entity
.Name
)
1927 subMenu
:addLine(uc_name
, "lua", calledFunction
.."('".. entity
.InstanceId
.."')", entity
.InstanceId
)
1933 subMenu
:addLine(i18n
.get("uiR2EdNoSelelection"), "", "", "")
1939 local componentNpcPlant
= feature
.Components
.NpcPlant
1941 ----------------------------------------------------------------------------
1942 -- add no line to the event menu
1943 function componentNpcPlant
.initLogicEntitiesMenu(this
, logicEntityMenu
)
1944 r2
.Classes
.LogicEntity
.initLogicEntitiesMenu(this
, logicEntityMenu
)
1947 ----------------------------------------------------------------------------
1948 -- add a line to the event sub menu
1949 function componentNpcPlant
.initLogicEntitiesInstancesMenu(this
, subMenu
, calledFunction
)
1950 r2
.Classes
.LogicEntity
.initLogicEntitiesInstancesMenu(this
, subMenu
, calledFunction
)
1953 ----------------------------------------------------------------------------
1954 -- add a line to the event menu
1955 function componentNpcPlant
:getLogicTranslations()
1956 local logicTranslations
= {
1957 ["ApplicableActions"] = {
1958 ["Activate"] = {menu
=i18n
.get("uiR2EdActivates"):toUtf8(),
1959 text
=r2
:lowerTranslate("uiR2EdActivates")},
1960 ["Deactivate"] = {menu
=i18n
.get("uiR2EdDeactivates"):toUtf8(),
1961 text
=r2
:lowerTranslate("uiR2EdDeactivates")},
1962 ["Kill"] = {menu
=i18n
.get("uiR2EdKill"):toUtf8(),
1963 text
=r2
:lowerTranslate("uiR2EdKills")},
1967 ["activation"] = {menu
=i18n
.get("uiR2EdActivation"):toUtf8(),
1968 text
=r2
:lowerTranslate("uiR2EdActivation")},
1969 ["desactivation"] = {menu
=i18n
.get("uiR2EdDeactivation"):toUtf8(),
1970 text
=r2
:lowerTranslate("uiR2EdDeactivation")},
1971 ["death"] = {menu
=i18n
.get("uiR2EdDeath"):toUtf8(),
1972 text
=r2
:lowerTranslate("uiR2EdDeath")},
1973 ["targeted by player"] = {menu
=i18n
.get("uiR2EdTargetedByplayer"):toUtf8(),
1974 text
=r2
:lowerTranslate("uiR2EdTargetedByplayer")}
1977 ["is active"] = {menu
=i18n
.get("uiR2EdIsActive"):toUtf8(),
1978 text
=r2
:lowerTranslate("uiR2EdIsActive")},
1979 ["is dead"] = {menu
=i18n
.get("uiR2EdIsDead"):toUtf8(),
1980 text
=r2
:lowerTranslate("uiR2EdIsDead")},
1981 ["is alive"] = {menu
=i18n
.get("uiR2EdIsAlive"):toUtf8(),
1982 text
=r2
:lowerTranslate("uiR2EdIsAlive")},
1983 ["is inactive"] = {menu
=i18n
.get("uiR2EdIsInactive"):toUtf8(),
1984 text
=r2
:lowerTranslate("uiR2EdIsInactive")},
1987 return logicTranslations
1997 r2
.Features
["DefaultFeature"] = registerFeature()
2004 --------------------------------------------------------------------------------------------------
2005 -------------------------- ACTIVE LOGIC ENTITY DisplayerProperties -----------------------------------------
2006 --------------------------------------------------------------------------------------------------
2008 local activeLogicEntityPropertySheetDisplayerTable
= clone(r2
:propertySheetDisplayer())
2010 ------------------------------------------------
2011 function activeLogicEntityPropertySheetDisplayerTable
:onPostCreate(instance
)
2013 ------------------------------------------------
2014 function activeLogicEntityPropertySheetDisplayerTable
:onErase(instance
)
2015 r2
:logicEntityPropertySheetDisplayer():onErase(instance
)
2017 ------------------------------------------------
2018 function activeLogicEntityPropertySheetDisplayerTable
:onPreHrcMove(instance
)
2020 ------------------------------------------------
2021 function activeLogicEntityPropertySheetDisplayerTable
:onPostHrcMove(instance
)
2023 ------------------------------------------------
2024 function activeLogicEntityPropertySheetDisplayerTable
:onFocus(instance
, hasFocus
)
2027 ------------------------------------------------
2028 r2
.activitiesAndChatsUIUpdate
= false
2029 function activeLogicEntityPropertySheetDisplayerTable
:onSelect(instance
, isSelected
)
2031 r2
:logicEntityPropertySheetDisplayer():onSelect(instance
, isSelected
)
2033 if not isSelected
or (instance
.Ghost
== true) then
2035 r2
.activities
:closeEditor()
2036 r2
.miniActivities
:closeEditor()
2038 if instance
:isKindOf("Npc") then
2039 local helpButton
= getUI("ui:interface:r2ed_property_sheet_Npc:header_opened:help")
2041 if instance
:isBotObject() then
2043 helpButton
.active
= false
2044 helpButton
.parent
.parent
.title_delta_max_w
= r2
.DefaultPropertySheetTitleClampSize
2047 helpButton
.active
= true
2048 helpButton
:updateCoords()
2049 helpButton
.parent
.parent
.title_delta_max_w
= r2
.DefaultPropertySheetTitleClampSize
- helpButton
.w_real
- 4
2052 r2
.activities
.isInitialized
= false
2053 r2
.miniActivities
:openEditor()
2057 ------------------------------------------------
2058 function activeLogicEntityPropertySheetDisplayerTable
:onAttrModified(instance
, attributeName
)
2060 r2
:logicEntityPropertySheetDisplayer():onAttrModified(instance
, attributeName
)
2062 if attributeName
== "Name" then
2064 if r2
.events
.filteredLogicEntityId
== instance
.InstanceId
then
2065 r2
.events
:updateSequenceUI()
2068 if not r2
.activitiesAndChatsUIUpdate
or instance
~= r2
:getSelectedInstance() then
2072 local activitiesUI
= getUI(r2
.activities
.uiId
)
2073 assert(activitiesUI
)
2074 local dialogsUI
= getUI(r2
.dialogs
.uiId
)
2077 activitiesUI
.uc_title
= i18n
.get("uiR2EDActivitySequenceEditor"):toUtf8() .. instance
[attributeName
]
2078 dialogsUI
.uc_title
= i18n
.get("uiR2EDChatSequenceEditor"):toUtf8() .. instance
[attributeName
]
2082 ------------------------------------------------
2083 function r2
:activeLogicEntityPropertySheetDisplayer()
2084 return activeLogicEntityPropertySheetDisplayerTable
-- returned shared displayer to avoid wasting memory