khanat-opennel-code/code/ryzom/common/data_common/r2/r2_features_fauna.lua
2017-03-15 20:29:34 +01:00

840 lines
29 KiB
Lua

--
-- *****************
-- * 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