Objekt im Hook temporär umbenennen?

  • #1, by rhavin grobertWednesday, 29. November 2017, 20:30 5 years ago
    Ich bin im MainLoop-Hook.

    cmd is mein aktuelles Command.
    obj is mein aktuelles Objekt.

    Ich hab bereits gecheckt dass mein cmd und obj das jerweils gesuchte sind.

    walkto is ein String, den ich aus dem Objekt ausgelesen hab, er gibt den Namen (interner Objekt-Name) einer Szene an.

    Wie kann ich jetzt:

    a)  von dieser Szene den Namen in der aktuellen Sprache bekommen.
    b) den Aktionstext so abändern, dass sich der Objektname im Aktionstext auf den namen in der entsprechenden Sprache ändert.


    Also (pseudocode):
    setActionText(
      cmd:getCurrentLanguageName()
      .." "..
      getScene(walkto):getCurrentLanguageName()
    )
    

    Newbie

    47 Posts


  • #2, by afrlmeWednesday, 29. November 2017, 20:52 5 years ago
    You have to iterate.

    Here's a function I wrote a while ago for updating the action text of anything that allows it. Add the script below to the script section of the editor as a definition script.
    -- * function which updates the action text of an object for the current language * --
    function setText(obj, txt)
     local texts = obj.TextTextLanguages -- get all texts belonging to the object
     -- + --
     for i = 1, #texts do -- iterate through the stored texts
      if texts[i].language == game.StandardLanguage:getId().id then
       texts[i].text = txt;  obj.TextTextLanguages = texts -- update old text with new text
       break -- no need to keep iterating, cancel the loop
      end
     end
    end


    Here's an example of how to update the action text of a scene object belonging to the current scene...
    setText(game.CurrentScene.SceneObjects["example"].ObjectName, "some new text")

    The first input varible has to link to a scene object, item, character, scene or interface button. The second input variable should contain a "string" value.

    Imperator

    7211 Posts

  • #3, by rhavin grobertWednesday, 29. November 2017, 21:23 5 years ago
    So I really have to do this to get the current language name of an object, which instead should be a simple method of any object?:

    function getObjLangName(obj)
    
      if obj:isEmpty() then
    
        return nil
      end
    
      local name
      if obj:getId().tableId == eObjects then
    
        name = obj:getLink(VObjectName)
    
      elseif obj:getId().tableId == eCharacters then
    
        name = obj:getLink(VCharacterName)
    
      end
    
      if name:isEmpty() then
    
        return obj:getName()
    
      end
    
      local names = name.TextTextLanguages
    
      for _,v in ipairs(names) do
    
        if v.language == game.StandardLanguage:getId().id then
    
          return v.text
    
        end
    
      end
    
    end 
    

    Fucking unbelievable grin

    Newbie

    47 Posts

  • #4, by sebastianWednesday, 29. November 2017, 22:29 5 years ago
    there is indeed a builtin function to get the object/character/button name depending on current language: getTextStr 
    try this:
    ObjName(game.UsedItem)
    function ObjName(obj)
      local table = obj:getId().tableId
      if table == eObjects then
        return obj:getTextStr(VObjectName)
      elseif table == eCharacters then
        return obj:getTextStr(VCharacterName)
      elseif table == eButtons then
        return obj:getTextStr(VButtonName)
      end
    end

    Also in the wiki: https://wiki.visionaire-tracker.net/wiki/ObjName_(CMS)
    (copy the url. the forum destrys the link)

    Thread Captain

    2346 Posts

  • #5, by afrlmeWednesday, 29. November 2017, 22:34 5 years ago
    Ah yeah, sorry. I used an online translator to translate your text. I guess something got lost in the translation.

    Scenes["example"]:getTextStr(VSceneName)

    Will return the name of the scene based on the currently active language. You can also return the name of a specified language too, but it requires the id rather than the language name. Like so...
    Scenes["example"]:getTextStr( VSceneName, Languages["English"]):getId().id )

    Imperator

    7211 Posts

  • #6, by sebastianWednesday, 29. November 2017, 22:36 5 years ago
    Ah yeah, sorry. I used an online translator to translate your text. I guess something got lost in the translation.

    Scenes["example"]:getTextStr(VSceneName)

    Will return the name of the scene based on the currently active language. You can also return the name of a specified language too, but it requires the id rather than the language name. Like so...
    Scenes["example"]:getTextStr( VSceneName, Languages["English"]):getId().id )

    no, you were right, AFRLme. He wanted to set a language depending text. But his last post was regarding getting it. wink

    Thread Captain

    2346 Posts

  • #7, by rhavin grobertWednesday, 29. November 2017, 23:15 5 years ago
    ObjName(game.UsedItem)
    function ObjName(obj)
      local table = obj:getId().tableId
      if table == eObjects then
        return obj:getTextStr(VObjectName)
      elseif table == eCharacters then
        return obj:getTextStr(VCharacterName)
      elseif table == eButtons then
        return obj:getTextStr(VButtonName)
      end
    end


    Ok,  makes it a little bit easier. Now tell me:

    Why do I have to call the same function on different objects with different arbitrary constants to get the same result (current language ingame name)?

    Why not have getGuiName() that every object understands?

    At least, shouldnt it be the job of the object to know where to find its name?

    Newbie

    47 Posts

  • #8, by sebastianWednesday, 29. November 2017, 23:26 5 years ago
    ObjName(game.UsedItem)
    function ObjName(obj)
      local table = obj:getId().tableId
      if table == eObjects then
        return obj:getTextStr(VObjectName)
      elseif table == eCharacters then
        return obj:getTextStr(VCharacterName)
      elseif table == eButtons then
        return obj:getTextStr(VButtonName)
      end
    end


    Ok,  makes it a little bit easier. Now tell me:

    Why do I have to call the same function on different objects with different arbitrary constants to get the same result (current language ingame name)?

    Why not have getGuiName() that every object understands?

    At least, shouldnt it be the job of the object to know where to find its name?
    mostly historical reasons and the slow process of transition to the new naming system they introduced in V5. 
    If you have a look at the luadocs you see that the tables characters/buttons/object/etc already have only "Name" for the actiontext name.
    Im not sure if obj:getTextStr(Name) would work, because the getTextStr function is still an older method... -i created it some time ago...

    Regarding implementing new functions only Simon can answer these.
    EDIT: Easiest would be to just accept the new shorter names in older functions.

    Thread Captain

    2346 Posts

  • #9, by rhavin grobertWednesday, 29. November 2017, 23:55 5 years ago
    Now I just need to know:

    how do I change the action text?

    Newbie

    47 Posts

  • #10, by sebastianThursday, 30. November 2017, 00:04 5 years ago
    Now I just need to know:

    how do I change the action text?
    There is a whole hook function which gets triggered when the action text changes it returns the new actiontext..
    Sadly it doesnt contain the original actiontext itself, so you have to rebuilt it with the stuff like UsedItem,ActiveCommand,etc.

    So you dont need the main loop you mentioned in the first post (but will also work).

    Did it and happy about it =) Will be covered also in an upcoming tutorial by me (german).

    Thread Captain

    2346 Posts

  • #11, by rhavin grobertThursday, 30. November 2017, 00:45 5 years ago
    Almost there…


    if (_qp == nil) then
    
      _qp = {}
    
      math.randomseed( os.time() )
    
    end
    
    
    
    _qp.cmd = {}
    
    _qp.cmd.objThis = emptyObject
    
    _qp.cmd.objLast = emptyObject
    
    _qp.cmd.cmdLast = emptyObject
    
    _qp.cmd.altAction = nil
    
    _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]')
    
    
    
    registerEventHandler('mainLoop', '_qpmain')
    
    
    
    _qp.getObjLangName = function(obj)
    
      if obj:isEmpty() then
    
        return "--: empty :--"
    
      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
    
    
    
    _qp.cmd.setActionText = function(text)
    
      print(text)
    
    end
    
    
    
    _qp.cmd.callItemCommand = function(_cmd, _item)
    
      -- NYI
    
      return false
    
    end
    
    
    
    function _qpmain()
    
      _qp.cmd.objThis = game:getLink(VGameCurrentObject)
    
      -- skip if nothing happend
    
      if _qp.cmd.objThis == _qp.cmd.lastObj
    
        then return end
    
      _qp.cmd.altAction = nil
    
      _qp.cmd.onChangeObjectcommand()
    
      _qp.cmd.lastObj = _qp.cmd.objThis
    
    end
    
    
    
    _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
    
      local cmd = game:getLink(VGameActiveCommand)
    
      local cmdName = cmd:getName()
    
    
    
      for _,v in ipairs(_qp.cmd.objThis:getLinks(VObjectValues)) do
    
        local valName = v:getName()
    
        local valStr = v:getStr(VValueString)
    
        -- check if cmd is overridden by object
    
        if valName == cmdName then
    
          if _qp.cmd[valStr] ~= nil then
    
            game:setValue(VGameActiveCommand, _qp.cmd[valStr])
    
          end
    
          return true
    
        end
    
        -- check for cmdWalk with walkto
    
        if cmdName == "cmdWalk" and valName == "walkto" then
    
          -- change action text
    
          _qp.cmd.altAction = _qp.getObjLangName(cmd)..
    
            " ".._qp.getObjLangName(Scenes[valStr])
    
          return true
    
        end
    
        -- check if object represents an item
    
        if valName == "item" then
    
          -- call items command action
    
          return _qp.cmd.callItemCommand(cmd, Items[valStr])
    
        end
    
      end
    
      return false
    
    end

    Newbie

    47 Posts