Ok, I should have asked more specific
See this:
if (_qp == nil) then
_qp = {}
end
_qp.cmd = {}
_qp.cmd.objThis = emptyObject
_qp.cmd.objLast = emptyObject
_qp.cmd.cmdLast = emptyObject
_qp.cmd.curCmd = _qp.cmd['cmdWalk']
_qp.cmd.altObj = emptyObject
_qp.cmd.altName = ""
_qp.cmd['cmdWalk'] = getObject('Interfaces[_default].InterfaceButtons[cmdWalk]')
_qp.cmd['cmdLook'] = getObject('Interfaces[_default].InterfaceButtons[cmdLook]')
_qp.cmd['cmdUse'] = getObject('Interfaces[_default].InterfaceButtons[cmdUse]')
_qp.cmd['cmdTalk'] = getObject('Interfaces[_default].InterfaceButtons[cmdTalk]')
_qp.cmd['cmdGive'] = getObject('Interfaces[_default].InterfaceButtons[cmdGive]')
_qp.cmd['cmdTake'] = getObject('Interfaces[_default].InterfaceButtons[cmdTake]')
_qp.cmd['cmdPush'] = getObject('Interfaces[_default].InterfaceButtons[cmdPush]')
_qp.cmd['cmdPull'] = getObject('Interfaces[_default].InterfaceButtons[cmdPull]')
_qp.cmd['cmdOpen'] = getObject('Interfaces[_default].InterfaceButtons[cmdOpen]')
_qp.cmd['cmdClose'] = getObject('Interfaces[_default].InterfaceButtons[cmdClose]')
-- mainloop hooking function
function _qphookMain()
_qp.cmd.objThis = game:getLink(VGameCurrentObject)
-- skip if nothing happend
if _qp.cmd.objThis == _qp.cmd.objLast
then return end
_qp.cmd.setAltText(emptyObject, "")
_qp.cmd.onChangeObjectcommand()
_qp.cmd.objLast = _qp.cmd.objThis
end
-- get displayed object name in current language
_qp.getObjLangName = function(obj)
if obj:isEmpty() then return "" end
local id = obj:getId().tableId
if id == eObjects then
return obj:getTextStr(VObjectName)
elseif id == eCharacters then
return obj:getTextStr(VCharacterName)
elseif id == eScenes then
return obj:getTextStr(VSceneName)
elseif id == eButtons then
return obj:getTextStr(VButtonName)
end
end
-- set displayed object name in current language
_qp.setObjLangName = function(_obj, _name)
if _obj:isEmpty() then return end
-- get all texts belonging to the object
local texts = _obj.ObjectName.TextTextLanguages
local ldef = game.StandardLanguage:getId().id
for _,v in ipairs(texts) do
if v.language == ldef then
v.text = _name
-- reassign to trigger update
_obj.ObjectName.TextTextLanguages = texts
break
end
end
end
-- set alternative temporary text
_qp.cmd.setAltText = function(_obj, _altText)
if _qp.cmd.altObj ~= emptyObject then
_qp.setObjLangName(_qp.cmd.altObj,_qp.cmd.altName)
end
_qp.cmd.altObj = _obj
if _qp.cmd.altObj ~= emptyObject then
_qp.cmd.altName = _qp.getObjLangName(_qp.cmd.altObj)
_qp.setObjLangName(_qp.cmd.altObj,_altText)
end
end
-- call an items command
_qp.cmd.callItemCommand = function(_cmd, _item)
local cmds = _item:getLinks(VObjectActions)
for _,v in ipairs(cmds) do
if v.ActionCommand == _cmd then
startAction(v)
end
end
end
-- change current command
_qp.cmd.changeCommand = function(_cmd)
game:setValue(VGameActiveCommand, _cmd)
_qp.cmd.curCmd = _cmd
end
-- called if current target has just changed
_qp.cmd.onChangeObjectcommand = function()
if _qp.cmd.objThis:isEmpty() or
_qp.cmd.objThis:getId().tableId ~= eObjects then
return false
end
-- get command object and internal command name
_qp.cmd.curCmd = game:getLink(VGameActiveCommand)
local nameCmd = _qp.cmd.curCmd:getName()
for _,v in ipairs(_qp.cmd.objThis:getLinks(VObjectValues)) do
local attribute = v:getName()
local valString = v:getStr(VValueString)
-- check if cmd is redirected by object
if attribute == nameCmd then
if _qp.cmd[valString] ~= nil then
_qp.cmd.changeCommand(_qp.cmd[valString])
nameCmd = _qp.cmd.curCmd:getName()
end
end
-- check for cmdWalk with walkto
if attribute == "walkto" and nameCmd == "cmdWalk" then
-- change action text
_qp.cmd.setAltText(_qp.cmd.objThis, _qp.getObjLangName(Scenes[valString]))
return true
end
-- check if object represents an item
if attribute == "item" then
-- call items command action
return _qp.cmd.callItemCommand(_qp.cmd.curCmd, game:getLinks(VGameItems)[valString])
end
end
return false
end
registerEventHandler('mainLoop', '_qphookMain')
Currently, the function
callItemCommand is called from
onChangeObjectcommand if an object has the attribute
item with the value of the items internal name. Its purpose it to tell the engine that a scene object *is* an item, so any actions that are not explicitly defined in the scene object should be handled by the item. So the logic I want to get is something that should be part of the engine, but is not, so I have to do this myself:
If a scene object is connected to an item, forward all actions not explicitly stated in the scene object to the connected item. The purpose is of course that there are some actions that would require different handling depending of an objects position (standing somewhere in the scene, held in inventory), but most action (like "look at apple") should get the same action. That action in this examples apple will have some ActionExecutionType and I need to forward the action only if that has already been met.
For now, this works immediately, so if an item has an action that should be issued on the view command, it will get called as soon as the mouse reached the object-item regardless of that items actions ActionExecutionType.
So I need to delay that depending on the current ActionExecutionType (has a mouse button been pressed? Has the character already reached the item? etc.)
The other three alternatives I can envision are:
Copy all actions not defined in scene-object from item to scene-object…
- at load of game
- at first start of scene
- by a tool that I have to write which does it directly in the *.vis-file (not preferred, because it will lead to a mess keeping manually track of those changes)