2017-03-15 19:43:10 +00:00
--
-- *****************
-- * FAUNA FEATURE *
-- *****************
--
-- The fauna feature contains 2 herds of creatures (herbivores and carnivores) that wander between 2 life zones (sleep zone and
-- food zone).There are 2 differents kinds of components in this feature: fauna system and creature.
-- The fauna system component is some kind of manager for the feature. It creates the creatures and their life zones, and then
-- store them in its components table, so that their createChostComponents call and translation are automatically done by
-- the translator.
-- The created life zones are affected to each of the creature components. But the properties panel of the creature components allows
-- the DM to choose other zones in the scenario through RefId picking.
r2.Features . FaunaFeature = { }
local feature = r2.Features . FaunaFeature
feature.Name = " FaunaFeature "
feature.Description = " Generates a pack of carnivores and a herd of herbivores that will wander between two life zones (sleep zone, food zone) each. "
feature.Components = { }
-- *********************
-- * FEATURE FUNCTIONS *
-- *********************
--Form functions
-- Reinit makes sure the enums are reinitialized, ie contain all creatures (respectively herbivores or carnivores) from
-- the desert ecosystem and with a level between 1 and 50.
local function reinit ( form , creature )
if form == nil then
debugInfo ( " Reinit impossible: nil form " )
return
end
local creatureEnum = form : find ( creature .. " Race " )
if creatureEnum == nil then
debugInfo ( " Reinit impossible: can't find " .. creature .. " Race enum " )
return
end
creatureEnum : resetTexts ( )
local creaturePalette = { }
if creature == " Carnivore " then
creaturePalette = r2.Palette . Entries.creature . creatures_predators.instances
else
creaturePalette = r2.Palette . Entries.creature . creatures_passive.instances
end
local k , v = next ( creaturePalette , nil )
while k do
if r2.isInPalette ( v.Id ) then
local paletteElt = r2.getPaletteElement ( v.Id )
if paletteElt and paletteElt.RingAccess and
r2.RingAccess . testAccess ( paletteElt.RingAccess ) then
if paletteElt.Ecosystem == " Desert " and paletteElt.Level >= 1 and paletteElt.Level <= 50 then
creatureEnum : addText ( ucstring ( i18n.get ( v.Translation ) ) )
end
end
end
k , v = next ( creaturePalette , k )
end
end
-- Returns the chosen bases from the form before creating the components.
local function getBase ( creature , form )
if ( form == nil ) then
debugInfo ( " getBase: form is nil " )
return
end
local creaturePalette = { }
if creature == " Carnivore " then
creaturePalette = r2.Palette . Entries.creature . creatures_predators.instances
else
creaturePalette = r2.Palette . Entries.creature . creatures_passive.instances
end
local creatureEnum = form : find ( creature .. " Race " )
local race = creatureEnum.selection_text
local k , v = next ( creaturePalette , nil )
while k do
local name = i18n.get ( v.Translation ) : toUtf8 ( )
if name == race then
return v.Id , name
end
k , v = next ( creaturePalette , k )
end
end
-- When the selected ecosystem or level changes, the corresponding creature combobox is updated.
local function updateEnum ( creature )
local currentForm = r2.CurrentForm
if ( currentForm == nil ) then
debugInfo ( " UpdatePredators: r2.CurrentForm is nil " )
return
end
local creatureEnum = currentForm : find ( creature .. " Race " )
local ecoEnum = currentForm : find ( creature .. " Ecosystem " )
local currentEco = ecoEnum.selection_text
if currentEco == " Lakes " then
currentEco = " Lacustre "
end
local levelEnum = currentForm : find ( creature .. " Level " )
local levelRange = levelEnum.selection + 1
local levelMin
local levelMax
if levelRange == 0 then
levelMin = 1
levelMax = 250
else
levelMin = ( levelRange - 1 ) * 50 + 1
levelMax = levelMin + 49
end
creatureEnum : resetTexts ( )
local creaturePalette = { }
if creature == " Carnivore " then
creaturePalette = r2.Palette . Entries.creature . creatures_predators.instances
else
creaturePalette = r2.Palette . Entries.creature . creatures_passive.instances
end
local k , v = next ( creaturePalette , nil )
while k do
if r2.isInPalette ( v.Id ) then
local paletteElt = r2.getPaletteElement ( v.Id )
if paletteElt and paletteElt.RingAccess and
r2.RingAccess . testAccess ( paletteElt.RingAccess ) then
if paletteElt.Ecosystem == currentEco and paletteElt.Level >= levelMin and paletteElt.Level <= levelMax then
creatureEnum : addText ( ucstring ( i18n.get ( v.Translation ) ) )
end
end
end
k , v = next ( creaturePalette , k )
end
end
-- Calls update function for the carnivores combobox.
local function updateCarnivores ( form )
updateEnum ( " Carnivore " )
end
-- Calls update function for the herbivores combobox.
local function updateHerbivores ( form )
updateEnum ( " Herbivore " )
end
local function resetForm ( )
local currentForm = r2 : getForm ( " Fauna_Form " )
assert ( currentForm )
do
local creature = " Carnivore "
local ecoEnum = currentForm : find ( creature .. " Ecosystem " )
ecoEnum.selection_text = " Desert "
local levelEnum = currentForm : find ( creature .. " Level " )
levelEnum.selection = 0
updateCarnivores ( form )
end
do
local creature = " Herbivore "
local ecoEnum = currentForm : find ( creature .. " Ecosystem " )
ecoEnum.selection_text = " Desert "
local levelEnum = currentForm : find ( creature .. " Level " )
levelEnum.selection = 0
updateHerbivores ( form )
end
end
--
-- The creation form lets the DM choose the type of creatures and their number.
-- Like the palette tree, the available creatures are filtered by their ecosystems and level.
-- Each life cycle duration is defined in the properties panel of the creature component.
-- The creation form will return the chosen creature base when ok button is pressed.
-- The form is reinitialized each time the ok or cancel button is pressed.
--
feature.registerForms = function ( )
-- Initializes the creature comboboxes. Default ecosystem is desert and default level range is 1-50.
local function init ( creature )
local initEnum = { }
local creaturePalette = { }
if not r2.Palette . Entries.creature then
return -- special case for the 'light' palette
end
if creature == " Carnivore " then
creaturePalette = r2.Palette . Entries.creature . creatures_predators.instances
else
creaturePalette = r2.Palette . Entries.creature . creatures_passive.instances
end
local k , v = next ( creaturePalette , nil )
while k do
if r2.isInPalette ( v.Id ) then
local paletteElt = r2.getPaletteElement ( v.Id )
if paletteElt then
if paletteElt.Ecosystem == " Desert " and paletteElt.Level >= 1 and paletteElt.Level <= 50 then
table.insert ( initEnum , i18n.get ( v.Translation ) )
end
end
end
k , v = next ( creaturePalette , k )
end
return initEnum
end
r2.Forms . Fauna_Form =
{
Caption = " uiR2EdFauna " ,
Prop =
{
{ Name = " CarnivoresCount " , Type = " Number " , Category = " uiR2EDRollout_Carnivores " , Min = " 1 " , Max = " 12 " , Default = " 3 " , Translation = " uiR2EDProp_Count " } ,
{ Name = " CarnivoreRace " , Type = " Number " , Category = " uiR2EDRollout_Carnivores " , WidgetStyle = " EnumDropDown " , Translation = " uiR2EDProp_Race " ,
Enum = init ( " Carnivore " )
} ,
{ Name = " CarnivoreEcosystem " , Type = " Number " , Category = " uiR2EDRollout_Carnivores " , WidgetStyle = " EnumDropDown " , Translation = " uiR2EDProp_Ecosystem " ,
Enum = { " Desert " , " Forest " , " Jungle " , " Lakes " , " PrimeRoots " , " Goo " } ,
onChange = updateCarnivores
} ,
{ Name = " CarnivoreLevel " , Type = " Number " , Category = " uiR2EDRollout_Carnivores " , WidgetStyle = " EnumDropDown " , Translation = " uiR2EDProp_Level " ,
Enum = { " 1-50 " , " 51-100 " , " 101-150 " , " 151-200 " , " 201-250 " } ,
onChange = updateCarnivores
} ,
{ Name = " HerbivoresCount " , Type = " Number " , Category = " uiR2EDRollout_Herbivores " , Min = " 1 " , Max = " 12 " , Default = " 7 " , Translation = " uiR2EDProp_Count " } ,
{ Name = " HerbivoreRace " , Type = " Number " , Category = " uiR2EDRollout_Herbivores " , WidgetStyle = " EnumDropDown " , Translation = " uiR2EDProp_Race " ,
Enum = init ( " Herbivore " )
} ,
{ Name = " HerbivoreEcosystem " , Type = " Number " , Category = " uiR2EDRollout_Herbivores " , WidgetStyle = " EnumDropDown " , Translation = " uiR2EDProp_Ecosystem " ,
Enum = { " Desert " , " Forest " , " Jungle " , " Lakes " , " PrimeRoots " , " Goo " } ,
onChange = updateHerbivores
} ,
{ Name = " HerbivoreLevel " , Type = " Number " , Category = " uiR2EDRollout_Herbivores " , WidgetStyle = " EnumDropDown " , Translation = " uiR2EDProp_Level " ,
Enum = { " 1-50 " , " 51-100 " , " 101-150 " , " 151-200 " , " 201-250 " } ,
onChange = updateHerbivores
} ,
}
}
end
-- **************
-- * COMPONENTS *
-- **************
local FaunaRegionRadius = 5
-----------------------------------------------------------------------------------------------
-- CREATURE COMPONENT
feature.Components . Creature =
{
BaseClass = " LogicEntity " ,
Name = " Creature " ,
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 = " Components " , Type = " Table " , Visible = false } ,
{ Name = " Ghosts " , Type = " Table " , Visible = false } ,
{ Name = " Name " , Type = " String " , MaxNumChar = " 32 " } ,
{ Name = " CrittersCount " , Type = " String " , WidgetStyle = " StaticText " , Translation = " uiR2EDProp_CrittersCount " } ,
{ Name = " RaceBase " , Type = " String " , WidgetStyle = " StaticText " , Visible = false } ,
{ Name = " RaceName " , Type = " String " , WidgetStyle = " StaticText " , Translation = " uiR2EDProp_Race " } ,
{ Name = " SleepZone " , Type = " RefId " , PickFuntion = " r2:canPickZone " , SetRefIdFunction = " r2:setZoneRefIdTarget " , Translation = " uiR2EDProp_SleepZone " } ,
{ Name = " FoodZone " , Type = " RefId " , PickFuntion = " r2:canPickZone " , SetRefIdFunction = " r2:setZoneRefIdTarget " , Translation = " uiR2EDProp_FoodZone " } ,
{ Name = " FoodDuration " , Type = " Number " , Category = " uiR2EDRollout_LifeCyclesInSeconds " , Min = " 1 " , Max = " 40000 " , Default = " 30 " , Translation = " uiR2EDProp_FoodDuration " } ,
{ Name = " SleepDuration " , Type = " Number " , Category = " uiR2EDRollout_LifeCyclesInSeconds " , Min = " 1 " , Max = " 40000 " , Default = " 30 " , Translation = " uiR2EDProp_SleepDuration " } ,
} ,
getAvailableCommands = function ( this , dest )
r2.Classes . LogicEntity.getAvailableCommands ( this , dest ) -- fill by ancestor
this : getAvailableDisplayModeCommands ( dest )
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 )
this : createGhostComponents ( )
end ,
translate = function ( this , context )
--local rtNpcGrp = r2.Translator.getRtGroup(context, context.Feature.InstanceId)
--local aiState = r2.newComponent("RtAiState")
--aiState.AiActivity = "normal"
--table.insert(context.RtAct.AiStates, aiState)
--table.insert(aiState.Children, rtNpcGrp.Id)
--local rtNpcGrp = r2.Translator.getRtGroup(context, this.InstanceId)
--r2.Translator.translateEventHandlers( context, this, this.Behavior.Actions, rtNpcGrp)
r2.Translator . translateAiGroup ( this , context )
end ,
pretranslate = function ( this , context )
--local instance = r2:getInstanceFromId(context.Feature.InstanceId);
--r2.Translator.registerManager(context, context.Feature)
r2.Translator . createAiGroup ( this , context )
end
}
local component = feature.Components . Creature
component.getLogicAction = function ( entity , context , action )
return nil , nil
end
component.getLogicCondition = function ( this , context , condition )
return nil , nil
end
component.getLogicEvent = function ( this , context , event )
return nil , nil , nil
end
function component : getLogicTranslations ( )
local logicTranslations = {
[ " ApplicableActions " ] = { } ,
[ " Events " ] = { }
}
return nil --logicTranslations
end
component.createGhostComponents = function ( this , act )
local comp = this
local leader = nil
local herd = nil
local isHerbivore
if act then
herd = r2.newComponent ( " NpcGrpFeature " )
end
if comp._Seed then math.randomseed ( comp._Seed ) end
do
local x = comp.Position . x
local y = comp.Position . y
local n = comp._CrittersCount
local pas = ( 2 * math.pi ) / n
local r = ( n / ( 2 * math.pi ) ) + 2
for i = 1 , n do
local npc = r2.newComponent ( " Npc " )
npc.Name = comp.RaceName
npc.Base = comp.RaceBase --"palette.entities.creatures.cbadc1"
local rr = FaunaRegionRadius - 1 --r + math.random() * 5
npc.Position . x = ( rr - 1 ) * math.cos ( ( i - 1 ) * pas )
npc.Position . y = ( rr - 1 ) * math.sin ( ( i - 1 ) * pas )
npc.Position . z = 0
npc.Angle = 2 * math.pi * math.random ( 0 , 100 ) / 100.0
if i == 1 then
local manager = r2 : getInstanceFromId ( comp.ManagerId )
assert ( manager )
if manager.Active == 1 then npc.AutoSpawn = 1 else npc.AutoSpawn = 0 end
leader = npc
r2.requestSetGhostNode ( comp.InstanceId , " _LeaderId " , npc.InstanceId )
isHerbivore = r2.getPropertyValue ( npc , " IsHerbivore " )
end
if act then -- TestMode --
table.insert ( herd.Components , npc )
else
r2.requestInsertGhostNode ( this.InstanceId , " Ghosts " , - 1 , " " , npc )
r2 : getInstanceFromId ( npc.InstanceId ) . Selectable = false
end
end
end
-- 2 wander sequences corresponding to the activities in both life zones attached to the herd
do
local sequence = r2.newComponent ( " ActivitySequence " )
table.insert ( leader.Behavior . Activities , sequence )
sequence.Name = " Life Cycle "
sequence.Repeating = 1
-- Wander in sleep zone
local step = r2.newComponent ( " ActivityStep " )
table.insert ( sequence.Components , step )
step.Type = " None "
step.Name = " Rest In Zone "
step.Activity = " Rest In Zone "
step.ActivityZoneId = r2.RefId ( comp.SleepZone )
step.TimeLimit = " Few Sec "
step.TimeLimitValue = tostring ( comp.SleepDuration )
-- Wander in food zone
local step = r2.newComponent ( " ActivityStep " )
table.insert ( sequence.Components , step )
step.Type = " None "
if isHerbivore == 1 then
step.Name = " Feed In Zone "
step.Activity = " Feed In Zone "
else
step.Name = " Hunt In Zone "
step.Activity = " Hunt In Zone "
end
step.ActivityZoneId = r2.RefId ( comp.FoodZone )
step.TimeLimit = " Few Sec "
step.TimeLimitValue = tostring ( comp.FoodDuration )
end
if act then
comp.User . _Herd = herd.InstanceId
--herd.Name = r2:genInstanceName(i18n.get("uiR2EdFaunaFeature")):toUtf8()
herd.InheritPos = 0
herd.Position . x = comp.Position . x
herd.Position . y = comp.Position . y
r2.requestInsertGhostNode ( act.InstanceId , " Features " , - 1 , " " , herd )
end
end
component.createComponent = function ( x , y , nbcritters , raceBase , raceName ,
sleepZoneId , foodZoneId )
local comp = r2.newComponent ( " Creature " )
assert ( comp )
--comp.Base = "palette.entities.botobjects.user_event"
comp.Base = r2.Translator . getDebugBase ( " palette.entities.botobjects.user_event " )
comp.Name = r2 : genInstanceName ( i18n.get ( " uiR2EdCreatureComponent " ) ) : toUtf8 ( )
comp.Position . x = x
comp.Position . y = y
comp.Position . z = r2 : snapZToGround ( x , y )
comp._CrittersCount = nbcritters
comp.CrittersCount = tostring ( nbcritters )
comp.RaceBase = raceBase
comp.RaceName = raceName
comp.SleepDuration = 30
comp.FoodDuration = 30
comp._Seed = os.time ( )
comp.SleepZone = sleepZoneId
comp.FoodZone = foodZoneId
return comp
end
-----------------------------------------------------------------------------------------------
-- FAUNA SYSTEM COMPONENT
-- Fauna system containing 2 Creature components (herbivores & carnivores) and 3 life zones.
feature.Components . Fauna =
{
BaseClass = " LogicEntity " ,
Name = " Fauna " ,
Menu = " ui:interface:r2ed_feature_menu " ,
InEventUI = true ,
DisplayerUI = " R2::CDisplayerLua " ,
DisplayerUIParams = " defaultUIDisplayer " ,
DisplayerVisual = " R2::CDisplayerVisualEntity " ,
-----------------------------------------------------------------------------------------------
Parameters = { } ,
ApplicableActions = { " activate " , " deactivate " } ,
Events = { " deactivation " , " activation " } ,
Conditions = { " is active " , " is inactive " } ,
TextContexts = { } ,
TextParameters = { } ,
LiveParameters = { } ,
-----------------------------------------------------------------------------------------------
Prop =
{
{ Name = " InstanceId " , Type = " String " , WidgetStyle = " StaticText " , Visible = false } ,
{ Name = " Components " , Type = " Table " , Visible = false } ,
{ Name = " Ghosts " , Type = " Table " , Visible = false } ,
{ Name = " Name " , Type = " String " , MaxNumChar = " 32 " } ,
{ Name = " Active " , Type = " Number " , WidgetStyle = " Boolean " , DefaultValue = " 1 " } ,
{ Name = " CarnivoresCount " , Type = " String " , Category = " uiR2EDRollout_Carnivores " , WidgetStyle = " StaticText " , Translation = " uiR2EDProp_Count " } ,
{ Name = " CarnivoreBase " , Type = " String " , Category = " uiR2EDRollout_Carnivores " , WidgetStyle = " StaticText " , Visible = false } ,
{ Name = " CarnivoreRace " , Type = " String " , Category = " uiR2EDRollout_Carnivores " , WidgetStyle = " StaticText " , Translation = " uiR2EDProp_Race " } ,
{ Name = " HerbivoresCount " , Type = " String " , Category = " uiR2EDRollout_Herbivores " , WidgetStyle = " StaticText " , Translation = " uiR2EDProp_Count " } ,
{ Name = " HerbivoreBase " , Type = " String " , Category = " uiR2EDRollout_Herbivores " , WidgetStyle = " StaticText " , Visible = false } ,
{ Name = " HerbivoreRace " , Type = " String " , Category = " uiR2EDRollout_Herbivores " , WidgetStyle = " StaticText " , Translation = " uiR2EDProp_Race " } ,
} ,
getParentTreeNode = function ( this )
return this : getFeatureParentTreeNode ( )
end ,
getAvailableCommands = function ( this , dest )
r2.Classes . LogicEntity.getAvailableCommands ( this , dest ) -- fill by ancestor
this : getAvailableDisplayModeCommands ( dest )
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 )
--this:createGhostComponents()
if this.User . DisplayProp and this.User . DisplayProp == 1 then
r2 : setSelectedInstanceId ( this.InstanceId )
r2 : showProperties ( this )
this.User . DisplayProp = nil
end
end ,
translate = function ( this , context )
r2.Translator . translateAiGroup ( this , context )
r2.Translator . translateFeatureActivation ( this , context )
end ,
pretranslate = function ( this , context )
r2.Translator . createAiGroup ( this , context )
end
}
component = feature.Components . Fauna
local FaunaRegionNumCorners = 6
--local FaunaRegionRadius = 5
local FaunaRegionOffsets = { { x = 10 , y = 0 } , { x = - 7 , y = - 7 } , { x = 0 , y = 10 } }
component.create = function ( )
if not r2 : checkAiQuota ( ) then return end
local function paramsOk ( resultTable , form )
local carnivoreBase , carnivoreName = getBase ( " Carnivore " , form )
local herbivoreBase , herbivoreName = getBase ( " Herbivore " , form )
local x = tonumber ( resultTable [ " X " ] )
local y = tonumber ( resultTable [ " Y " ] )
local carnCount = tonumber ( resultTable [ " CarnivoresCount " ] )
local herbCount = tonumber ( resultTable [ " HerbivoresCount " ] )
if not r2 : checkAiQuota ( carnCount + herbCount + 1 ) then return end
if not x or not y or not carnivoreBase or not carnivoreName or not carnCount or not herbivoreBase
or not herbivoreName or not herbCount
then
r2 : doForm ( " Fauna_Form " , resultTable , paramsOk , paramsCancel )
resetForm ( )
printMsg ( " FaunaSystem: Failed to create component either because your scenario is full or because you don't yet have access to creatures of the level and ecosystem that you have selected " )
return
end
r2.requestNewAction ( i18n.get ( " uiR2EDNewFaunaFeatureAction " ) )
local component = feature.Components . Fauna.createComponent ( x , y , carnCount , carnivoreBase , carnivoreName ,
herbCount , herbivoreBase , herbivoreName )
r2 : setCookie ( component.InstanceId , " DisplayProp " , 1 )
r2.requestInsertNode ( r2 : getCurrentAct ( ) . InstanceId , " Features " , - 1 , " " , component )
resetForm ( )
end
local function paramsCancel ( data , form )
resetForm ( )
end
local function posOk ( x , y , z )
debugInfo ( string.format ( " Validate creation of 'FaunaFeature' at pos (%d, %d, %d) " , x , y , z ) )
if r2.mustDisplayInfo ( " Fauna " ) == 1 then
r2.displayFeatureHelp ( " Fauna " )
end
r2 : doForm ( " Fauna_Form " , { X = x , Y = y } , paramsOk , paramsCancel )
resetForm ( )
end
local function posCancel ( )
debugInfo ( " Cancel choice 'FaunaFeature' position " )
end
--r2:choosePos("object_component_user_event.creature", posOk, posCancel, "createFeatureFauna")
local creature = r2.Translator . getDebugCreature ( " object_component_user_event.creature " )
--r2:choosePos(creature, posOk, posCancel, "createFeatureFauna")
local polys = { }
for p = 1 , table.getn ( FaunaRegionOffsets ) do
local poly = { }
local step = 2 * math.pi / FaunaRegionNumCorners
for k = 0 , FaunaRegionNumCorners - 1 do
table.insert ( poly , CVector2f ( FaunaRegionOffsets [ p ] . x + FaunaRegionRadius * math.cos ( k * step ) ,
FaunaRegionOffsets [ p ] . y + FaunaRegionRadius * math.sin ( k * step ) ) )
end
table.insert ( polys , poly )
end
r2 : choosePos ( creature , posOk , posCancel , " createFeatureFauna " ,
" curs_create.tga " ,
" curs_stop.tga " ,
polys , r2.PrimRender . ComponentRegionLook , r2.PrimRender . ComponentRegionInvalidLook )
end
function component . getAiCost ( this )
if this.User . GhostDuplicate then return 0 end
return r2.getAiCost ( this ) - 2
end
--
-- create the fauna system component by creating and inserting zones and creature component into its own components table.
-- Generates a sleep zone and a food zone for the herbivores, and a sleep zone for the carnivores. The carnivore hunt zone is
-- one of the herbivore zones (default is herbivore sleep zone).
--
component.createComponent = function ( x , y , carnCount , carnivoreBase , carnivoresName ,
herbCount , herbivoreBase , herbivoresName )
local comp = r2.newComponent ( " Fauna " )
assert ( comp )
--TODO: replace this milestone base by some default feature base
comp.Base = " palette.entities.botobjects.user_event "
comp.Name = r2 : genInstanceName ( i18n.get ( " uiR2EdFaunaFeature " ) ) : toUtf8 ( )
comp.Position . x = x
comp.Position . y = y
comp.Position . z = r2 : snapZToGround ( x , y )
comp._CarnCount = carnCount
comp.CarnivoresCount = tostring ( carnCount )
comp.CarnivoreBase = carnivoreBase
comp.CarnivoreRace = tostring ( carnivoresName )
comp._HerbCount = herbCount
comp.HerbivoresCount = tostring ( herbCount )
comp.HerbivoreBase = herbivoreBase
comp.HerbivoresName = herbivoresName
comp.HerbivoreRace = tostring ( herbivoresName )
comp._Seed = os.time ( )
-- Herbivore sleep zone
local zoneSleep1 = r2.newComponent ( " Region " )
r2.Utils . createRegion ( zoneSleep1 , 0 , 0 , FaunaRegionRadius , FaunaRegionNumCorners )
zoneSleep1.Deletable = 1
zoneSleep1.Position . x = comp.Position . x + FaunaRegionOffsets [ 1 ] . x
zoneSleep1.Position . y = comp.Position . y + FaunaRegionOffsets [ 1 ] . y
zoneSleep1.Position . z = comp.Position . z
zoneSleep1.InheritPos = 0
zoneSleep1.Name = r2 : genInstanceName ( i18n.get ( " uiR2EDNameSleepRegion " ) ) : toUtf8 ( )
table.insert ( comp.Components , zoneSleep1 )
-- Carnivore sleep zone
local zoneSleep2 = r2.newComponent ( " Region " )
r2.Utils . createRegion ( zoneSleep2 , 0 , 0 , FaunaRegionRadius , FaunaRegionNumCorners )
zoneSleep2.Deletable = 1
zoneSleep2.Position . x = comp.Position . x + FaunaRegionOffsets [ 2 ] . x
zoneSleep2.Position . y = comp.Position . y + FaunaRegionOffsets [ 2 ] . y
zoneSleep2.Position . z = comp.Position . z
zoneSleep2.InheritPos = 0
zoneSleep2.Name = r2 : genInstanceName ( i18n.get ( " uiR2EDNameSleepRegion " ) ) : toUtf8 ( )
table.insert ( comp.Components , zoneSleep2 )
--Herbivore sleep zone
local zoneFood = r2.newComponent ( " Region " )
r2.Utils . createRegion ( zoneFood , 0 , 0 , FaunaRegionRadius , FaunaRegionNumCorners )
zoneFood.Deletable = 1
zoneFood.Position . x = comp.Position . x + FaunaRegionOffsets [ 3 ] . x
zoneFood.Position . y = comp.Position . y + FaunaRegionOffsets [ 3 ] . y
zoneFood.Position . z = comp.Position . z
zoneFood.InheritPos = 0
zoneFood.Name = r2 : genInstanceName ( i18n.get ( " uiR2EDNameFoodRegion " ) ) : toUtf8 ( )
table.insert ( comp.Components , zoneFood )
-- Herd of herbivores
local herbivores = feature.Components . Creature.createComponent ( zoneSleep1.Position . x , zoneSleep1.Position . y , herbCount , herbivoreBase ,
herbivoresName , zoneSleep1.InstanceId , zoneFood.InstanceId )
herbivores.Name = i18n.get ( " uiR2EdHerbivores " ) : toUtf8 ( )
--herbivores.Position.x = zoneSleep1.Position.x--comp.Position.x + 10
--herbivores.Position.y = zoneSleep1.Position.y--comp.Position.y + 10
herbivores.InheritPos = 0
--herbivores.Active = comp.Active
herbivores.ManagerId = comp.InstanceId
table.insert ( comp.Components , herbivores )
comp._HerbId = herbivores.InstanceId
-- Pack of carnivores
local carnivores = feature.Components . Creature.createComponent ( zoneSleep2.Position . x , zoneSleep2.Position . y , carnCount , carnivoreBase ,
carnivoresName , zoneSleep2.InstanceId , zoneSleep1.InstanceId )
carnivores.Name = i18n.get ( " uiR2EdCarnivores " ) : toUtf8 ( )
carnivores.InheritPos = 0
carnivores.ManagerId = comp.InstanceId
table.insert ( comp.Components , carnivores )
comp._CarnId = carnivores.InstanceId
return comp
end
component.getLogicAction = function ( entity , context , action )
assert ( action.Class == " ActionStep " )
local component = r2 : getInstanceFromId ( action.Entity )
assert ( component )
local rtNpcGrp = r2.Translator . getRtGroup ( context , component.InstanceId )
assert ( rtNpcGrp )
local herbi = r2 : getInstanceFromId ( component._HerbId )
assert ( herbi )
local herbivores = r2 : getInstanceFromId ( herbi.User . _Herd )
assert ( herbivores )
local rtHerbiGrp = r2.Translator . getRtGroup ( context , herbivores.InstanceId )
assert ( rtHerbiGrp )
local carni = r2 : getInstanceFromId ( component._CarnId )
assert ( carni )
local carnivores = r2 : getInstanceFromId ( carni.User . _Herd )
assert ( carnivores )
local rtCarniGrp = r2.Translator . getRtGroup ( context , carnivores.InstanceId )
assert ( rtCarniGrp )
if action.Action . Type == " deactivate " then
local action1 = r2.Translator . createAction ( " set_value " , rtNpcGrp.Id , " Active " , 0 )
local action2 = r2.Translator . getNpcLogicActionDeactivate ( herbivores , context , action , rtHerbiGrp )
local action3 = r2.Translator . getNpcLogicActionDeactivate ( carnivores , context , action , rtCarniGrp )
local action4 = r2.Translator . createAction ( " user_event_trigger " , rtNpcGrp.Id , 5 )
local multiaction = r2.Translator . createAction ( " multi_actions " , { action1 , action2 , action3 , action4 } )
return multiaction , multiaction
elseif ( action.Action . Type == " activate " ) then
local action1 = r2.Translator . createAction ( " set_value " , rtNpcGrp.Id , " Active " , 1 )
local action2 = r2.Translator . getNpcLogicActionActivate ( herbivores , context , action , rtHerbiGrp )
local action3 = r2.Translator . getNpcLogicActionActivate ( carnivores , context , action , rtCarniGrp )
local action4 = r2.Translator . createAction ( " user_event_trigger " , rtNpcGrp.Id , 4 )
local multiaction = r2.Translator . createAction ( " multi_actions " , { action1 , action2 , action3 , action4 } )
return multiaction , multiaction
end
return r2.Translator . getFeatureActivationLogicAction ( rtNpcGrp , action )
end
component.getLogicEvent = function ( this , context , event )
assert ( event.Class == " LogicEntityAction " )
local component = this
assert ( component )
local rtNpcGrp = r2.Translator . getRtGroup ( context , component.InstanceId )
assert ( rtNpcGrp )
return r2.Translator . getFeatureActivationLogicEvent ( rtNpcGrp , event )
end
component.getLogicCondition = function ( this , context , condition )
assert ( condition.Class == " ConditionStep " )
local component = r2 : getInstanceFromId ( condition.Entity )
assert ( component )
local rtNpcGrp = r2.Translator . getRtGroup ( context , component.InstanceId )
assert ( rtNpcGrp )
return r2.Translator . getFeatureActivationCondition ( condition , rtNpcGrp )
end
function component : getLogicTranslations ( )
local logicTranslations = { }
r2.Translator . addActivationToTranslations ( logicTranslations )
return logicTranslations
end
function component : registerMenu ( logicEntityMenu )
local name = i18n.get ( " uiR2EdFaunaFeature " )
logicEntityMenu : addLine ( ucstring ( name ) , " lua " , " " , " FaunaFeature " )
end
r2.Features [ " FaunaFeature " ] = feature