900 lines
30 KiB
Lua
900 lines
30 KiB
Lua
|
||
r2.Features.BanditCampFeature = {}
|
||
|
||
local feature = r2.Features.BanditCampFeature
|
||
|
||
feature.Name = "BanditCampFeature"
|
||
|
||
feature.BanditCount = 0
|
||
|
||
feature.Description = "A bandits camp feature"
|
||
|
||
feature.Components = {}
|
||
|
||
local BanditZoneRadius = 5
|
||
local BanditZoneNumCorners = 6
|
||
|
||
local BanditCampVersion = 2
|
||
feature.Components.BanditCamp =
|
||
{
|
||
BaseClass = "LogicEntity",
|
||
Name = "BanditCamp",
|
||
InEventUI = true,
|
||
Menu = "ui:interface:r2ed_feature_menu",
|
||
Version = BanditCampVersion,
|
||
DisplayerUI = "R2::CDisplayerLua",
|
||
DisplayerUIParams = "defaultUIDisplayer",
|
||
DisplayerVisual = "R2::CDisplayerVisualEntity",
|
||
-----------------------------------------------------------------------------------------------
|
||
Parameters = {
|
||
},
|
||
ApplicableActions = {
|
||
"activate",
|
||
"deactivate", "Wander", "Sit Down",
|
||
"Kill"
|
||
},
|
||
Events = {
|
||
"activation",
|
||
"deactivation",
|
||
"member death", "group death",
|
||
"head to wander zone", "arrive at wander zone", "head to camp",
|
||
"arrive at camp"
|
||
},
|
||
Conditions = {
|
||
"is active", "is inactive",--"is dead",
|
||
"is wandering", "is sitting",
|
||
"is heading to wander zone", "is heading to camp"
|
||
},
|
||
TextContexts = {
|
||
},
|
||
TextParameters = {
|
||
"max bandits number", "still alive bandits number"
|
||
},
|
||
LiveParameters = {
|
||
"is active", "alive bandits number",
|
||
"max bandits number", state = {"sitting", "heading to wander", "wandering or heading home"}
|
||
},
|
||
-----------------------------------------------------------------------------------------------
|
||
--Category = "uiR2EDRollout_BanditsCamp",
|
||
Prop =
|
||
{
|
||
{Name = "InstanceId", Type = "String", WidgetStyle = "StaticText", Visible = false},
|
||
{Name = "Components", Type = "Table"},
|
||
{Name = "Name", Type="String", MaxNumChar="32"},
|
||
{Name = "BanditsCount", Type = "String", WidgetStyle = "StaticText"},
|
||
{Name = "Race", Type = "String", WidgetStyle = "StaticText"},
|
||
{Name = "BanditsLevel", Type = "String", WidgetStyle = "StaticText"},
|
||
--{Name = "Cycle", Type = "Number", Min = "10", Max = "999999", DefaultValue = "30"},
|
||
{Name = "SitDuration", Type = "Number", Min = "10", Max = "999999", DefaultValue = "20"},
|
||
{Name = "WanderDuration", Type = "Number", Min = "10", Max = "999999", DefaultValue = "20"},
|
||
--{Name = "Behavior", Type = "Table"},
|
||
{Name = "Cost", Type = "Number", Visible = false },
|
||
{Name = "Ghosts", Type = "Table", Visible = false },
|
||
{Name = "Active", Type = "Number", WidgetStyle="Boolean", DefaultValue="1" },
|
||
{Name = "NoRespawn", Type ="Number", WidgetStyle = "Boolean", DefaultValue="0"},
|
||
|
||
},
|
||
-----------------------------------------------------------------------------------------------
|
||
-- from base class
|
||
getParentTreeNode = function(this)
|
||
return this:getFeatureParentTreeNode()
|
||
end,
|
||
---------------------------------------------------------------------------------------------------------
|
||
-- from base class
|
||
appendInstancesByType = function(this, destTable, kind)
|
||
assert(type(kind) == "string")
|
||
--this:delegate():appendInstancesByType(destTable, kind)
|
||
r2.Classes.LogicEntity.appendInstancesByType(this, destTable, kind)
|
||
for k, component in specPairs(this.Components) do
|
||
component:appendInstancesByType(destTable, kind)
|
||
end
|
||
end,
|
||
---------------------------------------------------------------------------------------------------------
|
||
-- from base class
|
||
getSelectBarSons = function(this)
|
||
return Components
|
||
end,
|
||
---------------------------------------------------------------------------------------------------------
|
||
-- from base class
|
||
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,
|
||
|
||
updateVersion = function(this, scenarioValue, currentValue )
|
||
local patchValue = scenarioValue
|
||
if patchValue < 1 then
|
||
r2.requestEraseNode(this.InstanceId, "Cost", -1)
|
||
patchValue = 1
|
||
end
|
||
if patchValue < 2 then
|
||
local invalidEvents = {}
|
||
invalidEvents["desactivation"] = "deactivation"
|
||
r2.updateLogicEvents(this, invalidEvents)
|
||
r2.requestSetNode(this.InstanceId, "BanditsLevel", "22")
|
||
patchValue = 2
|
||
end
|
||
|
||
if patchValue == currentValue then return true end
|
||
return false
|
||
end,
|
||
|
||
}
|
||
local component = feature.Components.BanditCamp
|
||
|
||
|
||
function component.onPostCreate(this)
|
||
|
||
if this.User.DisplayProp and this.User.DisplayProp == 1 then
|
||
r2:setSelectedInstanceId(this.InstanceId)
|
||
r2:showProperties(this)
|
||
this.User.DisplayProp = nil
|
||
end
|
||
|
||
this:setLocalCost(_BanditCount)
|
||
local comp = this
|
||
if comp._Seed then math.randomseed(comp._Seed) end
|
||
do
|
||
local x = comp.Position.x
|
||
local y = comp.Position.y
|
||
local n = comp._BanditsCount
|
||
local pas = (2 * math.pi)/n
|
||
local r = (n/(2*math.pi))+2
|
||
for i = 1, n do
|
||
local npc = r2:randomNPC( component.getBanditPaletteId(comp), component.Races[comp._Race + 1])
|
||
npc.Position.x = (r-1) * math.cos((i-1)*pas) -- make position relative to the feature positio
|
||
npc.Position.y = (r-1) * math.sin((i-1)*pas)
|
||
npc.Position.z = 0
|
||
npc.Angle = (i-1)*pas + math.pi
|
||
|
||
r2.requestInsertGhostNode(this.InstanceId, "Ghosts", -1, "", npc)
|
||
local comp = r2:getInstanceFromId(npc.InstanceId)
|
||
comp.Selectable = false
|
||
end
|
||
end
|
||
end
|
||
|
||
|
||
function component.onPostHrcMove(this)
|
||
|
||
for i=0, this.Ghosts.Size-1 do
|
||
local entity = this.Ghosts[i]
|
||
entity.DisplayerVisual:updateName()
|
||
entity:updatePermanentStatutIcon()
|
||
end
|
||
r2.events:updateElementsUI()
|
||
end
|
||
|
||
function component:getLogicTranslations()
|
||
|
||
local logicTranslations = {
|
||
["ApplicableActions"] = {
|
||
["activate"] = { menu=i18n.get( "uiR2AA0Spawn" ):toUtf8(),
|
||
text=i18n.get( "uiR2AA1Spawn" ):toUtf8()},
|
||
["deactivate"] = { menu=i18n.get( "uiR2AA0Despawn" ):toUtf8(),
|
||
text=i18n.get( "uiR2AA1Despawn" ):toUtf8()},
|
||
["Wander"] = { menu=i18n.get( "uiR2AA0BanditWander" ):toUtf8(),
|
||
text=i18n.get( "uiR2AA1BanditWander" ):toUtf8()},
|
||
["Sit Down"] = { menu=i18n.get( "uiR2AA0BanditSitDown" ):toUtf8(),
|
||
text=i18n.get( "uiR2AA1BanditSitDown" ):toUtf8()},
|
||
["Kill"] = { menu=i18n.get( "uiR2AA0BanditKill" ):toUtf8(),
|
||
text=i18n.get( "uiR2AA1BanditKill" ):toUtf8()},
|
||
},
|
||
["Events"] = {
|
||
["activation"] = { menu=i18n.get( "uiR2Event0Spawn" ):toUtf8(),
|
||
text=i18n.get( "uiR2Event1Spawn" ):toUtf8()},
|
||
["deactivation"] = { menu=i18n.get( "uiR2Event0Despawn" ):toUtf8(),
|
||
text=i18n.get( "uiR2Event1Despawn" ):toUtf8()},
|
||
["member death"] = { menu=i18n.get( "uiR2Event0MemberDeath" ):toUtf8(),
|
||
text=i18n.get( "uiR2Event1MemberDeath" ):toUtf8()},
|
||
["group death"] = { menu=i18n.get( "uiR2Event0GroupDeath" ):toUtf8(),
|
||
text=i18n.get( "uiR2Event1GroupDeath" ):toUtf8()},
|
||
["head to wander zone"] = { menu=i18n.get( "uiR2Event0BanditHeadWander" ):toUtf8(),
|
||
text=i18n.get( "uiR2Event1BanditHeadWander" ):toUtf8()},
|
||
["arrive at wander zone"] = { menu=i18n.get( "uiR2Event0BanditArriveWander" ):toUtf8(),
|
||
text=i18n.get( "uiR2Event1BanditArriveWander" ):toUtf8()},
|
||
["head to camp"] = { menu=i18n.get( "uiR2Event0BanditHeadCamp" ):toUtf8(),
|
||
text=i18n.get( "uiR2Event1BanditHeadCamp" ):toUtf8()},
|
||
["arrive at camp"] = { menu=i18n.get( "uiR2Event0BanditArriveCamp" ):toUtf8(),
|
||
text=i18n.get( "uiR2Event1BanditArriveCamp" ):toUtf8()},
|
||
|
||
},
|
||
["Conditions"] = {
|
||
["is active"] = { menu=i18n.get( "uiR2Test0Spawned" ):toUtf8(),
|
||
text=i18n.get( "uiR2Test1Spawned" ):toUtf8()},
|
||
["is inactive"] = { menu=i18n.get( "uiR2Test0Despawned" ):toUtf8(),
|
||
text=i18n.get( "uiR2Test1Despawned" ):toUtf8()},
|
||
["is dead"] = { menu=i18n.get( "uiR2Test0BanditDead" ):toUtf8(),
|
||
text=i18n.get( "uiR2Test1BanditDead" ):toUtf8()},
|
||
["is wandering"] = { menu=i18n.get( "uiR2Test0BanditPatrolZone" ):toUtf8(),
|
||
text=i18n.get( "uiR2Test1BanditPatrolZone" ):toUtf8()},
|
||
["is sitting"] = { menu=i18n.get( "uiR2Test0BanditAtCamp" ):toUtf8(),
|
||
text=i18n.get( "uiR2Test1BanditAtCamp" ):toUtf8()},
|
||
["is heading to wander zone"]= {menu=i18n.get( "uiR2Test0BanditHeadPatrolZone" ):toUtf8(),
|
||
text=i18n.get( "uiR2Test1BanditHeadPatrolZone" ):toUtf8()},
|
||
["is heading to camp"] = { menu=i18n.get( "uiR2Test0BanditHeadCamp" ):toUtf8(),
|
||
text=i18n.get( "uiR2Test1BanditHeadCamp" ):toUtf8()},
|
||
}
|
||
}
|
||
return logicTranslations
|
||
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 banditEntity = r2:getInstanceFromId(component.User._BanditGroup)
|
||
BOMB_IF(banditEntity, "In feature '".. component.Name .. "' associated bandit camp not found.")
|
||
local banditRtNpcGrp = r2.Translator.getRtGroup( context, banditEntity.InstanceId)
|
||
BOMB_IF(banditEntity, "In feature '" .. component.Name .. "' associated bandit camp rtGroup not found.")
|
||
|
||
if action.Action.Type == "deactivate" then
|
||
local action1 = r2.Translator.createAction("set_value", rtNpcGrp.Id, "Active", 0)
|
||
local action2 = r2.Translator.getNpcLogicActionDeactivate(banditEntity, context, action, banditRtNpcGrp)
|
||
local action3 = r2.Translator.createAction("user_event_trigger", rtNpcGrp.Id, 5)
|
||
local multiaction = r2.Translator.createAction("multi_actions", {action1, action2, action3})
|
||
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(banditEntity, context, action, banditRtNpcGrp)
|
||
local action3 = r2.Translator.createAction("user_event_trigger", rtNpcGrp.Id, 4)
|
||
local multiaction = r2.Translator.createAction("multi_actions", {action1, action2, action3})
|
||
return multiaction, multiaction
|
||
elseif action.Action.Type == "Kill" then
|
||
return r2.Translator.getNpcLogicActionKill(banditEntity, context, action, banditRtNpcGrp)
|
||
elseif action.Action.Type == "Sit Down" then
|
||
return r2.Translator.getGenericLogicActionBeginActivitySequence(entity.User._SequenceHeadToFire, banditRtNpcGrp)
|
||
elseif action.Action.Type == "Wander" then
|
||
return r2.Translator.getGenericLogicActionBeginActivitySequence(entity.User._SequenceHeadToWander, banditRtNpcGrp)
|
||
end
|
||
|
||
local firstAction, lastAction = nil,nil
|
||
|
||
return firstAction, lastAction
|
||
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)
|
||
|
||
local banditEntity = r2:getInstanceFromId(component.User._BanditGroup)
|
||
BOMB_IF(banditEntity, "In feature '".. component.Name .. "' associated bandit camp not found.")
|
||
local banditRtNpcGrp = r2.Translator.getRtGroup( context, banditEntity.InstanceId)
|
||
BOMB_IF(banditEntity, "In feature '" .. component.Name .. "' associated bandit camp rtGroup not found.")
|
||
|
||
local conditionType = condition.Condition.Type
|
||
if conditionType == "is wandering" then
|
||
return r2.Translator.getGenericLogicConditionIsInActivitySequence(banditEntity, component.User._SequenceWander, banditRtNpcGrp)
|
||
elseif conditionType == "is sitting" then
|
||
return r2.Translator.getGenericLogicConditionIsInActivitySequence(banditEntity, component.User._SequenceStayNearFire, banditRtNpcGrp)
|
||
elseif conditionType == "is heading to wander zone" then
|
||
return r2.Translator.getGenericLogicConditionIsInActivitySequence(banditEntity, component.User._SequenceHeadToWander, banditRtNpcGrp)
|
||
elseif conditionType == "is heading to camp" then
|
||
return r2.Translator.getGenericLogicConditionIsInActivitySequence(banditEntity, component.User._SequenceHeadToFire, banditRtNpcGrp)
|
||
end
|
||
return r2.Translator.getFeatureActivationCondition(condition, rtNpcGrp)
|
||
|
||
end
|
||
|
||
component.getLogicEvent = function(this, context, event)
|
||
assert( event.Class == "LogicEntityAction")
|
||
|
||
local component = this -- r2:getInstanceFromId(event.Entity)
|
||
assert(component)
|
||
local rtNpcGrp = r2.Translator.getRtGroup(context, component.InstanceId)
|
||
assert(rtNpcGrp)
|
||
|
||
local banditEntity = r2:getInstanceFromId(component.User._BanditGroup)
|
||
BOMB_IF(banditEntity, "In feature '".. component.Name .. "' associated bandit camp not found.")
|
||
local banditRtNpcGrp = r2.Translator.getRtGroup( context, banditEntity.InstanceId)
|
||
BOMB_IF(banditEntity, "In feature '" .. component.Name .. "' associated bandit camp rtGroup not found.")
|
||
|
||
local eventType = event.Event.Type
|
||
if eventType == "activation" then
|
||
return r2.Translator.getComponentUserEvent(rtNpcGrp, 4)
|
||
elseif eventType == "deactivation" then
|
||
return r2.Translator.getComponentUserEvent(rtNpcGrp, 5)
|
||
elseif eventType == "member death" or eventType == "group death" then
|
||
return r2.Translator.getNpcLogicEvent(banditEntity, context, event)
|
||
elseif eventType == "head to wander zone" then
|
||
return r2.Translator.getNpcLogicEventBeginOfActivityStepImpl(this.User._StepHeadToWander, banditRtNpcGrp)
|
||
elseif eventType == "arrive at wander zone" then
|
||
return r2.Translator.getNpcLogicEventEndOfActivityStepImpl(this.User._StepHeadToWander, banditRtNpcGrp)
|
||
elseif eventType == "head to camp" then
|
||
return r2.Translator.getNpcLogicEventBeginOfActivityStepImpl(this.User._StepHeadToFire, banditRtNpcGrp)
|
||
elseif eventType == "arrive at camp" then
|
||
return r2.Translator.getNpcLogicEventEndOfActivityStepImpl(this.User._StepHeadToFire, banditRtNpcGrp)
|
||
end
|
||
|
||
local eventHandler, firsCondition, lastCondition = nil, nil, nil
|
||
return eventHandler, firsCondition, lastCondition
|
||
end
|
||
|
||
component.Races = { [1] = "Fyros", [2] = "Matis", [3] = "Tryker", [4] = "Zorai"}
|
||
|
||
component.RacesId = { [1] = "f", [2] = "m", [3] = "t", [4] = "z"}
|
||
|
||
component.LevelsId = { [1] = "20", [2] = "70", [3] = "120", [4] = "170", [5] = "220"}
|
||
|
||
component.RolesId = {
|
||
[1] = "melee_dd", [2] = "melee_tank", [3] = "light_melee", [4] = "mage_damage_dealer",
|
||
[5] = "mage_aoe", [6] = "mage_atysian_curser", [7] = "mage_celestial_curser"
|
||
}
|
||
|
||
--component.createComponent = function(x, y, banditsCount, race, banditsLevel, cycle, ZoneSize)
|
||
component.createComponent = function(x, y, banditsCount, race, banditsLevel, ZoneSize)
|
||
|
||
r2.requestNewAction(i18n.get("uiR2EDCreateBanditCampAction"))
|
||
local comp = r2.newComponent("BanditCamp")
|
||
assert(comp)
|
||
|
||
-- base is the camp fire, to display the bandit camp as a camp fire
|
||
comp.Base = "palette.entities.botobjects.campfire"
|
||
|
||
--feature.BanditCount = feature.BanditCount + 1
|
||
--comp.Name = "BanditCampFeature[".. feature.BanditCount .."]"
|
||
comp.Name = r2:genInstanceName(i18n.get("uiR2EDNameBanditCampFeature")):toUtf8()
|
||
|
||
local fire = comp.Fire
|
||
|
||
--do
|
||
-- fire.Base = "palette.entities.botobjects.campfire"
|
||
-- fire.Name = "Camp Fire"
|
||
-- local tmpPosition = fire.Position
|
||
-- tmpPosition.x = x
|
||
-- tmpPosition.y = y
|
||
-- tmpPosition.z = r2:snapZToGround(x, y)
|
||
--end
|
||
comp.Position.x = x
|
||
comp.Position.y = y
|
||
comp.Position.z = r2:snapZToGround(x, y)
|
||
|
||
comp._BanditsCount = banditsCount
|
||
comp._Race = race
|
||
comp._BanditsLevel = banditsLevel
|
||
comp.BanditsCount = tostring(banditsCount)
|
||
comp.Race = component.Races[race+1]
|
||
comp.BanditsLevel = component.LevelsId[banditsLevel + 1]
|
||
--comp.Cycle = cycle
|
||
comp.WanderDuration = 20
|
||
comp.SitDuration = 20
|
||
comp.ZoneSize = tostring(ZoneSize)
|
||
|
||
local zone = r2.newComponent("Region")
|
||
r2.Utils.createNonDeleteableRegion(zone, 0, 0, BanditZoneRadius, BanditZoneNumCorners) -- the region doesn't inherit the feature position, so must give its pos
|
||
zone.Deletable = 0
|
||
zone.Position.x = comp.Position.x
|
||
zone.Position.y = comp.Position.y
|
||
zone.Position.z = comp.Position.z
|
||
zone.InheritPos = 0 -- don't inherit position of parents
|
||
zone.Name = r2:genInstanceName(i18n.get("uiR2EDNameWanderRegion")):toUtf8()
|
||
comp._Zone = zone.InstanceId
|
||
table.insert(comp.Components, zone)
|
||
comp._Seed = os.time()
|
||
|
||
-- r2.registerText("Pas fach<63> que cette journ<72>e se termine !")
|
||
-- r2.registerText("On rentre a la maison!")
|
||
-- r2.registerText("Asseyez vous mes fr<66>res!")
|
||
-- r2.registerText("Allons detrousser les honnetes gens!")
|
||
-- r2.registerText("Allez, au boulot!")
|
||
-- r2.registerText("A l'attaque!!")
|
||
|
||
return comp
|
||
end
|
||
-- Global function are bad
|
||
function updateBanditCampEnum()
|
||
local currentForm = r2.CurrentForm
|
||
if (currentForm == nil) then
|
||
return
|
||
end
|
||
|
||
local formRace = currentForm:find("Race")
|
||
if not formRace then
|
||
return
|
||
end
|
||
local formLevel = currentForm:find("BanditsLevel")
|
||
if not formLevel then
|
||
return
|
||
end
|
||
local previousLevel = formLevel.selection
|
||
formLevel:resetTexts()
|
||
local k, v = next(component.LevelsId, nil)
|
||
while k do
|
||
local race = component.RacesId[formRace.selection + 1]
|
||
local level = v
|
||
local elementName = "palette.entities.npcs.bandits."..race.."_melee_dd_"..tostring(level)
|
||
local ok = false
|
||
if r2.isInPalette(elementName) then
|
||
|
||
local paletteElt = r2.getPaletteElement(elementName)
|
||
if paletteElt and paletteElt.RingAccess and r2.RingAccess.testAccess(paletteElt.RingAccess) then
|
||
formLevel:addText(ucstring(tostring(level)))
|
||
ok = true
|
||
-- local levelEnum = currentForm:find(creature.."Level")
|
||
|
||
end
|
||
end
|
||
if k == previousLevel and not ok then
|
||
formLevel.selection = 0
|
||
end
|
||
k, v = next(component.LevelsId, k)
|
||
end
|
||
|
||
|
||
end
|
||
|
||
local function initValue()
|
||
|
||
local toRet = {}
|
||
|
||
local k, v = next(component.LevelsId, nil)
|
||
while k do
|
||
local race = component.RacesId[0+ 1]
|
||
local level = v
|
||
local elementName = "palette.entities.npcs.bandits."..race.."_melee_dd_"..tostring(level)
|
||
|
||
if r2.isInPalette(elementName) then
|
||
local paletteElt = r2.getPaletteElement(elementName)
|
||
if paletteElt and paletteElt.RingAccess and r2.RingAccess.testAccess(paletteElt.RingAccess) then
|
||
table.insert(toRet, level)
|
||
|
||
end
|
||
end
|
||
k, v = next(component.LevelsId, k)
|
||
end
|
||
return toRet
|
||
end
|
||
|
||
|
||
function feature.registerForms()
|
||
r2.Forms.BanditCamp_Form =
|
||
{
|
||
Caption = "uiR2EDBanditCamp",
|
||
Prop =
|
||
{
|
||
-- following field are tmp for property sheet building testing
|
||
{Name = "BanditsCount", Type = "Number", Category = "uiR2EDRollout_BanditsCamp", Min = "1", Max = "12", Default = "6"},
|
||
|
||
{Name = "Race", Type = "Number", WidgetStyle = "EnumDropDown", Category = "uiR2EDRollout_BanditsCamp",
|
||
Enum = component.Races,
|
||
onChange = updateBanditCampEnum
|
||
},
|
||
|
||
{Name = "BanditsLevel", Type = "Number", WidgetStyle = "EnumDropDown", Category = "uiR2EDRollout_BanditsCamp",
|
||
Enum = initValue(),
|
||
onChange = updateBanditCampEnum
|
||
},
|
||
|
||
--{Name = "Cycle", Type = "Number", Category = "uiR2EDRollout_BanditsCamp", Min = "0", Max = "999999", Default = "30"},
|
||
}
|
||
}
|
||
end
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
-- read values from a BanditsComp and get Sheet Id
|
||
component.getBanditPaletteId = function(comp)
|
||
-- local tmpId = "palette.entities.npcs.cuthroats.cuthroat_b_melee_a_z_f"
|
||
-- return tmpId
|
||
local id = "palette.entities.npcs.bandits." ..
|
||
component.RacesId[comp._Race + 1] .."_" ..
|
||
component.RolesId[math.random(0,5) + 1] .."_" ..
|
||
component.LevelsId[comp._BanditsLevel + 1]
|
||
|
||
return id
|
||
end
|
||
|
||
component.init = function()
|
||
math.randomseed( os.time() ) -- To remove
|
||
end
|
||
|
||
component.createGhostComponents = function(comp, act)
|
||
local bandits
|
||
local npcGroup = r2.newComponent("NpcGrpFeature")
|
||
assert(npcGroup)
|
||
|
||
|
||
local leader = nil
|
||
local sequences = {}
|
||
local stepSitDown = nil
|
||
local stepStandUp = nil
|
||
|
||
|
||
do
|
||
|
||
local fire = r2.newComponent("Npc")
|
||
fire.Name = "Fire"
|
||
fire.Base = "palette.entities.botobjects.campfire"
|
||
fire.Position.x = comp.Position.x
|
||
fire.Position.y = comp.Position.y
|
||
fire.Position.z = 0
|
||
fire.Angle = 0
|
||
r2.requestInsertGhostNode(act.Features[0].InstanceId, "Components", -1, "", fire)
|
||
end
|
||
|
||
if comp._Seed then math.randomseed(comp._Seed) end
|
||
do
|
||
local x = comp.Position.x
|
||
local y = comp.Position.y
|
||
local n = comp._BanditsCount
|
||
|
||
local pas = (2 * math.pi)/n
|
||
local r = (n/(2*math.pi))+2
|
||
for i = 1, n do
|
||
local npc = r2:randomNPC( component.getBanditPaletteId(comp), component.Races[comp._Race + 1])
|
||
npc.Position.x = (r-1) * math.cos((i-1)*pas) -- make position relative to the feature positio
|
||
npc.Position.y = (r-1) * math.sin((i-1)*pas)
|
||
npc.Position.z = 0
|
||
npc.Angle = (i-1)*pas + math.pi
|
||
|
||
if comp.Active == 1 then npc.AutoSpawn = 1 else npc.AutoSpawn = 0 end
|
||
if i == 1 then leader = npc end
|
||
|
||
if comp.NoRespawn then
|
||
-- debugInfo("setting no respawn for a bandit -- value : " ..comp.NoRespawn)
|
||
npc.NoRespawn = comp.NoRespawn
|
||
end
|
||
|
||
table.insert(npcGroup.Components, npc)
|
||
end
|
||
npcGroup.Name = r2:genInstanceName(i18n.get("uiR2EDNameBanditCamp")):toUtf8()
|
||
bandits = npcGroup
|
||
bandits.Position.x = x
|
||
bandits.Position.y = y
|
||
bandits.InheritPos = 0
|
||
end
|
||
|
||
-- Sequence1 standUp -> Wander
|
||
do
|
||
local sequence = r2.newComponent("ActivitySequence")
|
||
|
||
|
||
table.insert(leader.Behavior.Activities, sequence)
|
||
table.insert(bandits.ActivitiesId, sequence.InstanceId)
|
||
sequences[1] = sequence
|
||
|
||
sequence.Name = "Head to Wander"
|
||
sequence.Repeating = 0
|
||
|
||
-- Initial wait
|
||
do
|
||
|
||
local step = r2.newComponent("ActivityStep")
|
||
table.insert(sequence.Components, step)
|
||
step.Type = "None"
|
||
step.Name = "Stand Up"
|
||
|
||
step.Activity = "Stand Up"
|
||
step.ActivityZoneId = r2.RefId("")
|
||
|
||
step.TimeLimit = "Few Sec"
|
||
step.TimeLimitValue = "5"
|
||
end
|
||
|
||
|
||
-- head to Wander
|
||
do
|
||
local step = r2.newComponent("ActivityStep")
|
||
comp.User._StepHeadToWander = step.InstanceId
|
||
table.insert(sequence.Components, step)
|
||
step.Type = "None"
|
||
|
||
|
||
step.Activity = "Go To Zone"
|
||
step.ActivityZoneId = r2.RefId(comp._Zone)
|
||
|
||
step.TimeLimit = "No Limit"
|
||
-- step.TimeLimitValue = ""
|
||
-- step.Chat = r2.RefId("")
|
||
end
|
||
|
||
-- Go to zone until arrived
|
||
end
|
||
|
||
-- Sequence2 Wander
|
||
do
|
||
local sequence = r2.newComponent("ActivitySequence")
|
||
|
||
|
||
table.insert(leader.Behavior.Activities, sequence)
|
||
table.insert(bandits.ActivitiesId, sequence.InstanceId)
|
||
sequences[2] = sequence
|
||
|
||
sequence.Name = "Wander"
|
||
sequence.Repeating = 0
|
||
-- Stand up
|
||
do
|
||
local step = r2.newComponent("ActivityStep")
|
||
table.insert(sequence.Components, step)
|
||
step.Type = "None"
|
||
step.Name = "Wander"
|
||
|
||
step.Activity = "Wander"
|
||
step.ActivityZoneId = r2.RefId(comp._Zone)
|
||
|
||
--if comp.Cycle ~= 0 then
|
||
if comp.WanderDuration ~= 0 then
|
||
step.TimeLimit = "Few Sec"
|
||
step.TimeLimitValue = tostring( math.ceil(comp.WanderDuration) )
|
||
else
|
||
step.TimeLimit = "No Limit"
|
||
end
|
||
-- step.TimeLimitValue = ""
|
||
-- step.Chat = r2.RefId("")
|
||
|
||
end
|
||
-- Go to zone until arrived
|
||
end
|
||
|
||
|
||
-- Sequence3 wander - >sit
|
||
do
|
||
local sequence = r2.newComponent("ActivitySequence")
|
||
sequence.Name = "Head to Fire"
|
||
sequence.Repeating = 0
|
||
table.insert(leader.Behavior.Activities, sequence)
|
||
table.insert(bandits.ActivitiesId, sequence.InstanceId)
|
||
|
||
sequences[3] = sequence
|
||
|
||
|
||
|
||
-- to fire
|
||
do
|
||
local step = r2.newComponent("ActivityStep")
|
||
comp.User._StepHeadToFire = step.InstanceId
|
||
table.insert(sequence.Components, step)
|
||
step.Type = "None"
|
||
step.Name = "head to fire"
|
||
|
||
step.Activity = "Go To Start Point"
|
||
step.ActivityZoneId = r2.RefId("")
|
||
|
||
step.TimeLimit = "No Limit"
|
||
stepSitDown = step
|
||
-- step.TimeLimitValue = ""
|
||
-- step.Chat = r2.RefId("")
|
||
end
|
||
|
||
do
|
||
local step = r2.newComponent("ActivityStep")
|
||
table.insert(sequence.Components, step)
|
||
step.Type = "None"
|
||
step.Name = "Sit Down"
|
||
|
||
step.Activity = "Sit Down"
|
||
step.ActivityZoneId = r2.RefId("")
|
||
|
||
step.TimeLimit = "Few Sec"
|
||
step.TimeLimitValue = "5"
|
||
end
|
||
|
||
end
|
||
-- Sequence3 wander - >sit
|
||
do
|
||
local sequence = r2.newComponent("ActivitySequence")
|
||
sequence.Name = "Head to Fire"
|
||
sequence.Repeating = 0
|
||
table.insert(leader.Behavior.Activities, sequence)
|
||
table.insert(bandits.ActivitiesId, sequence.InstanceId)
|
||
|
||
sequences[4] = sequence
|
||
-- stand up : go to start point
|
||
do
|
||
local step = r2.newComponent("ActivityStep")
|
||
|
||
table.insert(sequence.Components, step)
|
||
step.Type = "None"
|
||
step.Name = "Initial Wait"
|
||
|
||
step.Activity = "Stand On Start Point"
|
||
step.ActivityZoneId = r2.RefId("")
|
||
|
||
--if comp.Cycle ~= 0 then
|
||
if comp.SitDuration ~= 0 then
|
||
step.TimeLimit = "Few Sec"
|
||
step.TimeLimitValue = tostring( math.ceil(comp.SitDuration) )
|
||
else
|
||
step.TimeLimit = "No Limit"
|
||
end
|
||
-- step.Chat = r2.RefId("")
|
||
end
|
||
|
||
|
||
|
||
end
|
||
|
||
-- activitySequence1 -> activitySequence2
|
||
do
|
||
local eventHandler = r2.newComponent("LogicEntityAction")
|
||
eventHandler.Name = "Heading to wander"
|
||
table.insert(leader.Behavior.Actions, eventHandler)
|
||
|
||
local action = r2.newComponent("ActionStep")
|
||
table.insert(eventHandler.Actions, action)
|
||
action.Entity = r2.RefId(leader.InstanceId)
|
||
action.Action.Type = "begin activity sequence"
|
||
action.Action.Value = r2.RefId(sequences[2].InstanceId)
|
||
|
||
|
||
eventHandler.Event.Type = "end of activity sequence"
|
||
eventHandler.Event.Value = r2.RefId(sequences[1].InstanceId)
|
||
end
|
||
|
||
-- activitySequence3 -> activitySequence4
|
||
do
|
||
local eventHandler = r2.newComponent("LogicEntityAction")
|
||
eventHandler.Name = "Wander"
|
||
table.insert(leader.Behavior.Actions, eventHandler)
|
||
|
||
local action = r2.newComponent("ActionStep")
|
||
table.insert(eventHandler.Actions, action)
|
||
action.Entity = r2.RefId(leader.InstanceId)
|
||
action.Action.Type = "begin activity sequence"
|
||
action.Action.Value = r2.RefId(sequences[4].InstanceId)
|
||
eventHandler.Event.Type = "end of activity sequence"
|
||
eventHandler.Event.Value = r2.RefId(sequences[3].InstanceId)
|
||
end
|
||
|
||
--if comp.Cycle ~= 0 then
|
||
if comp.WanderDuration ~= 0 then
|
||
-- activitySequence2 -> activitySequence3
|
||
do
|
||
local eventHandler = r2.newComponent("LogicEntityAction")
|
||
eventHandler.Name = "Heading to Fire"
|
||
table.insert(leader.Behavior.Actions, eventHandler)
|
||
|
||
local action = r2.newComponent("ActionStep")
|
||
table.insert(eventHandler.Actions, action)
|
||
action.Entity = r2.RefId(leader.InstanceId)
|
||
action.Action.Type = "begin activity sequence"
|
||
action.Action.Value = r2.RefId(sequences[3].InstanceId)
|
||
|
||
|
||
eventHandler.Event.Type = "end of activity sequence"
|
||
eventHandler.Event.Value = r2.RefId(sequences[2].InstanceId)
|
||
end
|
||
end
|
||
|
||
-- activitySequence4 -> activitySequence1
|
||
if comp.SitDuration ~= 0 then
|
||
do
|
||
local eventHandler = r2.newComponent("LogicEntityAction")
|
||
eventHandler.Name = "Stay around fire"
|
||
table.insert(leader.Behavior.Actions, eventHandler)
|
||
|
||
local action = r2.newComponent("ActionStep")
|
||
table.insert(eventHandler.Actions, action)
|
||
action.Entity = r2.RefId(leader.InstanceId)
|
||
action.Action.Type = "begin activity sequence"
|
||
action.Action.Value = r2.RefId(sequences[1].InstanceId)
|
||
eventHandler.Event.Type = "end of activity sequence"
|
||
eventHandler.Event.Value = r2.RefId(sequences[4].InstanceId)
|
||
end
|
||
end
|
||
|
||
|
||
r2.requestInsertGhostNode(act.InstanceId, "Features", -1, "", bandits)
|
||
-- r2.requestInsertGhostNode(this.InstanceId, "Ghost", -1, "", ghostNpc)
|
||
-- r2.requestInsertGhostNode(r2:getCurrentAct().InstanceId, "Features", -1, "", bandits)
|
||
--
|
||
local k, sequence = next(sequences, nil)
|
||
while k do
|
||
r2.requestInsertGhostNode(act.InstanceId, "ActivitiesIds", -1, "", sequence.InstanceId)
|
||
k, sequence = next(sequences, k)
|
||
end
|
||
|
||
local k, bandit = next(npcGroup.Components, nil)
|
||
while k do
|
||
r2:getInstanceFromId(bandit.InstanceId).Selectable = true -- for debug
|
||
k, bandit = next(npcGroup.Components, k)
|
||
end
|
||
|
||
comp.User._BanditGroup = npcGroup.InstanceId
|
||
comp.User._SequenceHeadToWander = sequences[1].InstanceId
|
||
comp.User._SequenceWander = sequences[2].InstanceId
|
||
comp.User._SequenceHeadToFire = sequences[3].InstanceId
|
||
comp.User._SequenceStayNearFire = sequences[4].InstanceId
|
||
|
||
end
|
||
|
||
component.create = function()
|
||
if not r2:checkAiQuota() then return end
|
||
|
||
local function paramsOk(resultTable)
|
||
|
||
local banditsCount = tonumber( resultTable["BanditsCount"] )
|
||
if not r2:checkAiQuota(banditsCount) then return end
|
||
|
||
local race = tonumber( resultTable["Race"] )
|
||
local banditsLevel = tonumber( resultTable["BanditsLevel"] )
|
||
local x = tonumber( resultTable["X"] )
|
||
local y = tonumber( resultTable["Y"] )
|
||
--local cycle = tonumber( resultTable["Cycle"] )
|
||
--local sitDuration = tonumber( resultTable["SitDuration"] )
|
||
--local wanderDuration= tonumber( resultTable["WanderDuration"] )
|
||
local ZoneSize = tonumber(resultTable["ZoneSize"])
|
||
if banditsCount == nil or race == nil or banditsLevel == nil
|
||
then
|
||
debugInfo("Can't create Feature")
|
||
return
|
||
end
|
||
|
||
--local component = feature.Components.BanditCamp.createComponent( x, y, banditsCount, race, banditsLevel, cycle,ZoneSize)
|
||
local component = feature.Components.BanditCamp.createComponent( x, y, banditsCount, race, banditsLevel, ZoneSize)
|
||
r2:setCookie(component.InstanceId, "DisplayProp", 1)
|
||
r2.requestInsertNode(r2:getCurrentAct().InstanceId, "Features", -1, "", component)
|
||
|
||
-- feature.createContent(component)
|
||
|
||
end
|
||
|
||
local function paramsCancel()
|
||
debugInfo("Cancel form for bandit camp creation")
|
||
end
|
||
local function posOk(x, y, z)
|
||
debugInfo(string.format("Validate creation of bandit camp at pos (%d, %d, %d)", x, y, z))
|
||
if r2.mustDisplayInfo("BanditCamp") == 1 then
|
||
r2.displayFeatureHelp("BanditCamp")
|
||
end
|
||
r2:doForm("BanditCamp_Form", {X = x, Y = y}, paramsOk, paramsCancel)
|
||
updateBanditCampEnum()
|
||
end
|
||
local function posCancel()
|
||
debugInfo("Cancel choice of bandit camp position")
|
||
end
|
||
local poly = {}
|
||
local step = 2 * math.pi / BanditZoneNumCorners
|
||
for k = 0, BanditZoneNumCorners - 1 do
|
||
table.insert(poly, CVector2f(BanditZoneRadius * math.cos(k * step), BanditZoneRadius * math.sin(k * step)))
|
||
end
|
||
r2:choosePos("object_campfire.creature", posOk, posCancel, "createFeatureBanditCamp",
|
||
"curs_create.tga",
|
||
"curs_stop.tga",
|
||
{ poly }, r2.PrimRender.ComponentRegionLook, r2.PrimRender.ComponentRegionInvalidLook)
|
||
end
|
||
|
||
|
||
|
||
|
||
|
||
function feature.hasScenarioCost(this)
|
||
return true
|
||
end
|
||
|
||
component.init()
|
||
r2.Features["BanditCampFeature"] = feature
|
||
|
||
|