Objekt im Hook temporär umbenennen?

  • #1, by rhavin grobertWednesday, 29. November 2017, 20:30 2 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()
    )
    1
    2
    3
    4
    5
    6

    Newbie

    47 Posts


  • #2, by afrlmeWednesday, 29. November 2017, 20:52 2 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
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11


    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")
    1

    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

    6775 Posts

  • #3, by rhavin grobertWednesday, 29. November 2017, 21:23 2 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 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21

    Fucking unbelievable grin

    Newbie

    47 Posts

  • #4, by sebastianWednesday, 29. November 2017, 22:29 2 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)
    1
    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
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

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

    Thread Captain

    2331 Posts

  • #5, by afrlmeWednesday, 29. November 2017, 22:34 2 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)
    1

    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 )
    1

    Imperator

    6775 Posts

  • #6, by sebastianWednesday, 29. November 2017, 22:36 2 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)
    1

    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 )
    1

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

    Thread Captain

    2331 Posts

  • #7, by rhavin grobertWednesday, 29. November 2017, 23:15 2 years ago
    ObjName(game.UsedItem)
    1
    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
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10


    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 2 years ago
    ObjName(game.UsedItem)
    1
    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
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10


    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

    2331 Posts

  • #9, by rhavin grobertWednesday, 29. November 2017, 23:55 2 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 2 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

    2331 Posts

  • #11, by rhavin grobertThursday, 30. November 2017, 00:45 2 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
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92

    Newbie

    47 Posts

Write post