khanat-client-data-NeL/data/ryz/ryz_ring/r2_features_random_chest.lua

472 lines
14 KiB
Lua

-- In Translation file
-- Category : uiR2EdEasterEgg --
-- CreationFrom : uiR2EdEasterEggParameters
r2.Features.RandomChest = {}
local feature = r2.Features.RandomChest
feature.Name="RandomChest"
feature.Description="A feature that allows a NPC to take some item(s) from easter eggs"
feature.Components = {}
feature.Components.RandomChest =
{
BaseClass="LogicEntity",
Name="RandomChest",
InEventUI = true,
Menu="ui:interface:r2ed_feature_menu",
DisplayerProperties = "R2::CDisplayerLua",
DisplayerPropertiesParams = "randomChestDisplayer",
DisplayerUI = "R2::CDisplayerLua",
DisplayerUIParams = "defaultUIDisplayer",
DisplayerVisual = "R2::CDisplayerVisualEntity",
Parameters = {},
ApplicableActions = { "activate", "deactivate"},
Events = { "activation", "deactivation", "opened"},
Conditions = { "is active", "is inactive" },
TextContexts = {},
TextParameters = {},
LiveParameters = {},
Prop =
{
{Name="InstanceId", Type="String", WidgetStyle="StaticText", Visible = false},
{Name="Components", Type="Table", Visible = false},
{Name="Name", Type="String", MaxNumChar="32"},
{Name="ItemNumber", Type="Number", Category="uiR2EDRollout_Items", WidgetStyle="EnumDropDown",
Enum={"1", "2", "3"}, },
{Name="Item1Qty", Type="Number", Category="uiR2EDRollout_Items", Min="1", Max="50",DefaultValue="1", Visible= function(this) return this:displayRefId(1) end},
{Name="Item1Id", Type="RefId", WidgetStyle="PlotItem", Category="uiR2EDRollout_Items", Visible= function(this) return this:displayRefId(1) end},
{Name="Item1Weight", Type="Number", Category="uiR2EDRollout_Items", Min="1", Max="100", DefaultValue="33", Visible= function(this) return this:displayRefId(1) end},
{Name="Item2Qty", Type="Number", Category="uiR2EDRollout_Items", Min="0", Max="50",DefaultValue="0", Visible= function(this) return this:displayRefId(2) end},
{Name="Item2Id", Type="RefId", WidgetStyle="PlotItem", Category="uiR2EDRollout_Items", Visible= function(this) return this:displayRefId(2) end},
{Name="Item2Weight", Type="Number", Category="uiR2EDRollout_Items", Min="1", Max="100", DefaultValue="33", Visible= function(this) return this:displayRefId(2) end},
{Name="Item3Qty", Type="Number", Category="uiR2EDRollout_Items", Min="0",Max="50", DefaultValue="0", Visible= function(this) return this:displayRefId(3) end},
{Name="Item3Id", Type="RefId", WidgetStyle="PlotItem", Category="uiR2EDRollout_Items", Visible= function(this) return this:displayRefId(3) end},
{Name="Item3Weight", Type="Number", Category="uiR2EDRollout_Items", Min="1", Max="100", DefaultValue="33", Visible= function(this) return this:displayRefId(3) end},
{Name="Active", Type="Number", WidgetStyle="Boolean", Min="0", DefaultValue="1"},
},
--
-- from base class
getParentTreeNode = function(this)
return this:getFeatureParentTreeNode()
end,
getAvailableCommands = function(this, dest)
r2.Classes.LogicEntity.getAvailableCommands(this, dest) -- fill by ancestor
this:getAvailableDisplayModeCommands(dest)
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,
--
-- Called when running EditMode to create locally the feature without sending anything into the act (speed purpose).
--
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,
pretranslate = function(this, context)
r2.Translator.createAiGroup(this, context)
local eggId = this:getEggId(context)
end,
translate = function(this, context)
local entity = this
r2.Translator.translateAiGroup(this, context)
local rtNpcGrp = r2.Translator.getRtGroup(context, this.InstanceId)
if (this.Active == 1)
then
local eggId = this:getEggId(context)
local initialAction = this:createActionActivateRandomChest(context)
r2.Translator.translateAiGroupInitialState(this, context, initialAction)
end
r2.Translator.translateFeatureActivation(this, context)
end
}
-------------------------------------------------------------------------------------------------------------------------
local component = feature.Components.RandomChest
function component:displayRefId(index)
local nbItems = self.ItemNumber + 1
if index <= nbItems then
return true
end
return false
end
local randomChestDisplayerTable = clone(r2:propertySheetDisplayer())
function randomChestDisplayerTable:onAttrModified(instance, attributeName)
if attributeName == "ItemNumber" then
local propertySheet = r2:getPropertySheet(instance)
local nbRefId = instance.ItemNumber + 1
local i = 1
while i <= 3 do
if i > nbRefId then
local name = "Item"..tostring(i).."Id"
local qty = "Item"..tostring(i).."Qty"
local weight = "Item"..tostring(i).."Weight"
r2.requestSetNode(instance.InstanceId, name, r2.RefId(""))
r2.requestSetNode(instance.InstanceId, qty, 0)
r2.requestSetNode(instance.InstanceId, weight, 0)
end
i = i + 1
end
propertySheet.Env.updatePropVisibility()
return
end
r2:propertySheetDisplayer():onAttrModified(instance, attributeName)
end
function randomChestDisplayerTable:onSelect(instance, isSelected)
r2:logicEntityPropertySheetDisplayer():onSelect(instance, isSelected)
end
function r2:randomChestDisplayer()
return randomChestDisplayerTable -- returned shared displayer to avoid wasting memory
end
--
-- Create the logic actions relative to the feature via the translator.
--
function getPlotItemIdByInstance(missionItem)
if not missionItem then return "" end
local container = r2.Scenario.PlotItems
local k, v = next(container)
local id = 0
while k do
if tostring(v.InstanceId) == tostring(missionItem.InstanceId) then return id end
id = id + 1
k, v = next(container, k)
end
return ""
end
function component:getItems()
local str = ""
local id = 1
while id <= 3 do
local item = self["Item"..tostring(id).."Id"]
--r2.print("ITEM= '" ..item.."'")
if item and item ~= "" then
local qt = tonumber(self["Item"..tostring(id).."Qty"])
local plotItem = r2:getInstanceFromId(item)
if plotItem then
local plotItemId = getPlotItemIdByInstance(plotItem)
if str ~= "" then str = str ..";" end
str = str .. tostring(plotItemId)..":"..qt
end
end
id = id + 1
end
return str
end
function component:computeItemWeight(index)
local total = tonumber(self.Item1Weight) + tonumber(self.Item2Weight) + tonumber(self.Item3Weight)
if total == 0 then return -1 end
local coeff = 100.0 / total
local weight = tonumber(self["Item"..tostring(index).."Weight"]) * coeff
return weight
end
function component:createActionActivateRandomChest(context)
local rtGrp = r2.Translator.getRtGroup(context, self.InstanceId)
local eggId = self:getEggId(context)
local pos = r2.getWorldPos(self)
local x = pos.x
local y = pos.y
local z = r2:snapZToGround(x, y)
local item1Weight = self:computeItemWeight(1)
local item1Id = tostring(getPlotItemIdByInstance(r2:getInstanceFromId(self.Item1Id)))
local item1Qty = tonumber(self.Item1Qty)
local item2Weight = self:computeItemWeight(2)
local item2Id = tostring(getPlotItemIdByInstance(r2:getInstanceFromId(self.Item2Id)))
local item2Qty = tonumber(self.Item2Qty)
local item3Weight = self:computeItemWeight(3)
local item3Id = tostring(getPlotItemIdByInstance(r2:getInstanceFromId(self.Item3Id)))
local item3Qty = tonumber(self.Item3Qty)
if item1Weight == -1 or item2Weight == -1 or item3Weight == -1 then
debugInfo("Random chest: cannot divide by 0!")
return
end
local randomChestActivation = r2.Translator.createAction("random_chest_activate", rtGrp.Id, eggId, r2:getActId(context.Act), x, y, z,
item1Weight, item1Id, item1Qty,
item2Weight, item2Id, item2Qty,
item3Weight, item3Id, item3Qty,
self.Name)
local setValue = r2.Translator.createAction("set_value", rtGrp.Id, "Active", 1)
local rtAction = r2.Translator.createAction("multi_actions", {randomChestActivation, setValue})
return rtAction
end
function component:createActionDeactivateEasterEgg(context)
local eggId = self:getEggId(context)
local rtGrp = r2.Translator.getRtGroup(context, self.InstanceId)
local actionDeactivate = r2.Translator.createAction("easter_egg_deactivate", rtGrp.Id, eggId, r2:getActId(context.Act))
local actionSetValue = r2.Translator.createAction("set_value", rtGrp.Id, "Active", 0)
return r2.Translator.createAction("multi_actions", {actionDeactivate, actionSetValue})
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)
if (action.Action.Type == "activate") then
local retAction = component:createActionActivateRandomChest(context)
return retAction, retAction
elseif (action.Action.Type == "deactivate") then
local retAction = component:createActionDeactivateEasterEgg(context)
return retAction, retAction
end
local firstAction, lastAction = nil, nil
return firstAction, lastAction
end
--
-- Checks the conditions defined for this feature
--
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
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 eventType = tostring(event.Event.Type)
local eventHandler, lastCondition = nil, nil
if eventType == "opened" then
return r2.Translator.getComponentUserEvent(rtNpcGrp, 2)
elseif eventType == "activation" then
return r2.Translator.getComponentUserEvent(rtNpcGrp, 4)
elseif eventType == "deactivation" then
return r2.Translator.getComponentUserEvent(rtNpcGrp, 5)
end
return eventHandler, firstCondition, lastCondition
end
-- feature part
--
-- Creates an instance of the feature with attributes retrieved from the creation form
--
function component.createComponent(x, y)
local comp = r2.newComponent("RandomChest")
assert(comp)
comp.Base = "palette.entities.botobjects.chest_wisdom_std_sel"
comp.Name = r2:genInstanceName(i18n.get("uiR2EdRandomChest")):toUtf8()
comp.Position.x = x
comp.Position.y = y
comp.Position.z = r2:snapZToGround(x, y)
comp.ItemQty = 1
comp._Seed = os.time()
return comp
end
function component:getEggId(context)
assert(context)
local n = 0
if context.EasterEggUniqId == nil then
context.EasterEggUniqId = {}
context.EasterEggMaxId = 0
end
local rtNpcGrp = r2.Translator.getRtGroup(context, self.InstanceId)
if context.EasterEggUniqId[rtNpcGrp.Id] == nil then
local n = context.EasterEggMaxId + 1
context.EasterEggUniqId[rtNpcGrp.Id] = n
context.EasterEggMaxId = n
end
return context.EasterEggUniqId[rtNpcGrp.Id]
end
-- from ihm
-- Displays the creation form of the feature and calls CreateComponent with the user input values
--
function component.create()
if not r2:checkAiQuota() then return end
local function paramsOk(resultTable)
local x = tonumber( resultTable["X"] )
local y = tonumber( resultTable["Y"] )
local showAgain = tonumber(resultTable["Display"])
if showAgain == 1 then
r2.setDisplayInfo("EasterEggForm", 0)
else r2.setDisplayInfo("EasterEggForm", 1) end
if not x or not y
then
debugInfo("Can't create Component")
return
end
local comp = component.createComponent( x, y)
r2:setCookie(comp.InstanceId, "DisplayProp", 1)
r2.requestInsertNode(r2:getCurrentAct().InstanceId, "Features", -1, "", comp)
end
local function paramsCancel()
debugInfo("Cancel form for 'RandomChest' creation")
end
local function posOk(x, y, z)
debugInfo(string.format("Validate creation of 'RandomChest' at pos (%d, %d, %d)", x, y, z))
if r2.mustDisplayInfo("RandomChest") == 1 then
r2.displayFeatureHelp("RandomChest")
end
r2.requestNewAction(i18n.get("uiR2EDNewRandomChestAction"))
local comp = component.createComponent( x, y)
r2:setCookie(comp.InstanceId, "DisplayProp", 1)
r2.requestInsertNode(r2:getCurrentAct().InstanceId, "Features", -1, "", comp)
end
local function posCancel()
debugInfo("Cancel choice 'RandomChest' position")
end
r2:choosePos("object_chest_wisdom_std_sel.creature", posOk, posCancel, "createFeatureEasterEgg")
end
-----------------------------------------
--- register the current Feature to menu
----------------------------------------------------------------------------
-- add a line to the event menu
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()},
},
["Events"] = {
["activation"] = { menu=i18n.get( "uiR2Event0Spawn" ):toUtf8(),
text=i18n.get( "uiR2Event1Spawn" ):toUtf8()},
["deactivation"] = { menu=i18n.get( "uiR2Event0Despawn" ):toUtf8(),
text=i18n.get( "uiR2Event1Despawn" ):toUtf8()},
["opened"] = { menu=i18n.get( "uiR2Event0ChestOpened" ):toUtf8(),
text=i18n.get( "uiR2Event1ChestOpened" ):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()}
}
}
return logicTranslations
end
r2.Features["RandomChest"] = feature