alte Version

Code:
Logic.ExecuteInLuaLocalState([[local MessageText = XGUIEng.GetStringTableText("Feedback_TextLines/TextLine_GenericUnreachable")
    if MessageText == "Nicht erreichbar!" then
        GUI.SendScriptCommand('GameInstallationLanguage = "de" ')
    elseif MessageText == "Unreachable!" then
        GUI.SendScriptCommand('GameInstallationLanguage = "en" ')
    else 
        GUI.SendScriptCommand('GameInstallationLanguage = "en"' )
    end
    ]])
    
function MachQuests(_Quests,_GraphViz)-------------------------Alle vom Start weg aktiven Quests erstellen
 
    if not WikiQSB.GameLanguage then 
        StartSimpleJobEx(function(_Q, _V) if WikiQSB.GameLanguage then MachQuests(_Q,_V) return true end; end, _Quests, _GraphViz) 
        return 
    end
    local Result = _GraphViz and {}
    local MapName = Framework.GetCurrentMapName()
    if _GraphViz then table.insert( Result, 'Von hier an ausschneiden==> \r\ndigraph G { graph [    fontname = "Helvetica-Oblique", fontsize = 30, label = "'..MapName.. '" ]\r\nnode [ fontname = "Courier-Bold" shape = "box" ]' ) end
    for _, QuestTable in ipairs(_Quests) do MachQuest(QuestTable, Result) end
    if _GraphViz then
        table.insert( Result, "}\r\n<=====Bis hier auschneiden")
        Framework.WriteToLog(table.concat( Result, "\r\n" ))
    end
end
 
function MachQuest(_MQT, Result)-------------------Einzelne Quest erstellen
 
    _MQT.QuestGeber = _MQT.QuestGeber or _MQT.Sender or 1
    _MQT.QuestEmpfaenger = _MQT.QuestEmpfaenger or _MQT.Receiver or 1
    _MQT.ZeitLimit = _MQT.ZeitLimit or _MQT.Time or 0
    _MQT.EndeFunktion = _MQT.EndeFunktion or _MQT.EndFunction
    _MQT.LoopFunktion = _MQT.LoopFunktion or _MQT.LoopFunction
    _MQT.VersteckteQuest = _MQT.VersteckteQuest or _MQT.Hidden 
    _MQT.Beschreibung = Umlaute(_MQT.Beschreibung or _MQT.Description)
    _MQT.ErfolgsNachricht = Umlaute(_MQT.ErfolgsNachricht or _MQT.SuccessMessage)
    _MQT.NiederlageNachricht = Umlaute(_MQT.NiederlageNachricht or _MQT.FailureMessage)
    _MQT.StartNachricht = Umlaute(_MQT.StartNachricht or _MQT.StartMessage)
    _MQT.VersteckeEndNachricht = _MQT.VersteckeEndNachricht or _MQT.HideEndMessage 
        
    -- 1. Block Debug Checks
    if type(_MQT.Name) ~= "string" then
        return Logic.DEBUG_AddNote("DEBUG: Kein QuestName vergeben")
    elseif type(_MQT.QuestGeber) ~= "number" or _MQT.QuestGeber < 1 or _MQT.QuestGeber > 8 then
        return Logic.DEBUG_AddNote("DEBUG: QuestGeber in ".._MQT.Name.." hat falschen Wert")
    elseif type(_MQT.QuestEmpfaenger) ~= "number" or _MQT.QuestEmpfaenger < 1 or _MQT.QuestEmpfaenger > 8 then
        return Logic.DEBUG_AddNote("DEBUG: QuestEmpfaenger in ".._MQT.Name.." hat falschen Wert")
    elseif type(_MQT.ZeitLimit) ~= "number" or _MQT.ZeitLimit < 0 then
        return Logic.DEBUG_AddNote("DEBUG: ZeitLimit in ".._MQT.Name.." hat falschen Wert")
    end
        
    -- Behavior Table Building
    local BehaviourType, BehaviourFound = nil, nil
    local bTable = {Trigger = {}, Goal = {}, Reward = {}, Reprisal = {}}
    for k, v in ipairs(_MQT) do
        v = ( type(v) == "table" and type(v.Name) == "string" and type(v.Description) == "table" and v.Name ) or v
        if type(v) == "string" then
            for Key, Behavior in pairs(g_QuestBehaviorTypes) do
                if (Behavior.Name == v) then
                    for beha, behaTable in pairs(bTable) do
                        local BehaviorTemplate = GetBehaviorTemplateByName(v)
                        if BehaviorTemplate["Get"..beha.."Table"] ~= nil then
                            behaTable[#behaTable+1] = {v}
                            BehaviourType = beha
                            BehaviourFound = true
                            break
                        end
                    end
                end
            end
        end
        if (not BehaviourFound) and BehaviourType then
            local b = bTable[BehaviourType]
            table.insert(b[#b], v)
        elseif not BehaviourFound then     
            Logic.DEBUG_AddNote( "Falsche oder fehlende Verhaltensangabe in Quest ".._MQT.Name);return
        end
        BehaviourFound = false
    end
    
    -- 2. Block Debug Checks
    local gLanguage = WikiQSB.GameLanguage
    local debug1 = {"StartNachricht", "ErfolgsNachricht", "NiederlageNachricht", "Beschreibung" }
    local function cF(_field) if not field then Logic.DEBUG_AddNote("Translation missing in ".._MQT.Name) else return _field end; end
    for _, field in ipairs(debug1) do
        if type(_MQT[field]) == "table" then
            for Language, _ in pairs(_MQT[field]) do
                if type(Language) == "string" then
                    if gLanguage == "de" or gLanguage == "en" then _MQT[field] = cF(_MQT[field][gLanguage]); break
                    else _MQT[field] = cF(_MQT[field].en); break
                    end
                elseif gLanguage == "de" then _MQT[field] = _MQT[field][1]; break 
                elseif gLanguage == "en" then _MQT[field] = cF(_MQT[field][2]); break 
                else _MQT[field] = cF(_MQT[field][2]); break
                end
            end
        end
        if _MQT[field] and type(_MQT[field]) ~= "string" then return Logic.DEBUG_AddNote("DEBUG: "..field.." in ".._MQT.Name.." ist kein String") end
    end
    if _MQT.EndeFunktion and type(_MQT.EndeFunktion) ~= "function"  then return Logic.DEBUG_AddNote("DEBUG: Angegebene EndeFunktion in ".._MQT.Name.." existiert nicht")
    elseif _MQT.LoopFunktion and type(_MQT.LoopFunktion) ~= "function" then return Logic.DEBUG_AddNote("DEBUG: Angegebene LoopFunktion in ".._MQT.Name.." existiert nicht")
    elseif (#bTable.Goal == 0) or (#bTable.Trigger == 0) then return Logic.DEBUG_AddNote("DEBUG: Entweder fehlt ein Trigger oder ein Goal in ".._MQT.Name)
    end
    
    -------------------------------------Graphviz Ausgabe---------------------------------------------------------
    if Result then
        local ArrowColorTable = {Succeed = 'color="#00ff00"', Fail = 'color="#ff0000"', Interrupt = 'color="#999999"', Default = 'color="#0000ff"' }
        local function EscapeString( _String ) return string.match( string.format( "%q", tostring(_String) ), '^"(.*)"$' ) or "nil"    end
        local function LimitString( _String, _Limit )
            assert( _String )
            assert( _Limit > 3 )
            if string.len( _String ) <= _Limit then return _String
            else return string.sub( _String, 1, _Limit - 3 ) .. "..."
            end
        end
            local fontColor = ""
        local BehaviorNames = {}
            local bTableCounter = 0    
        for _, behaType in pairs(bTable) do
            bTableCounter = bTableCounter + 1
            for _, behavior in ipairs(behaType) do
                local BehaviorName = behavior[1]        
                local BehaviorTemplate = GetBehaviorTemplateByName(BehaviorName)
                local FoundQuestNames = {}
                local BehaviorNameParameters = {}
                -- Set arrow color based on the behavior name (triggers on/causes quest success/failure)
                local ArrowColor = (string.find( BehaviorName, "Succe" ) and ArrowColorTable.Succeed)
                    or (string.find( BehaviorName, "Fail" )and ArrowColorTable.Fail)
                    or (string.find( BehaviorName, "Interrupt" )and ArrowColorTable.Interrupt)
                    or ArrowColorTable.Default
                fontColor = (string.find( BehaviorName, "Wait" ) and 'fontcolor="red"') or ""
                -- Type of relation
                local BDependsOn = ( BehaviorTemplate.GetTriggerTable and "Triggers" ) or ( BehaviorTemplate.GetGoalTable and "Goals" )
                -- Find all parameters that use a quest name
                for j = 2, #behavior do
                    if GameCallback_QuestSytemBehavior_GetParameterType( "BB", BehaviorName, j-1 ) == ParameterType.QuestName then
                        FoundQuestNames[behavior[j]] = true
                        -- GraphViz relation definition
                        table.insert( Result, (BDependsOn and string.format( '%q -> %q [%s]', behavior[j], _MQT.Name, ArrowColor ))  
                                                                                            or string.format( '%q -> %q [%s, arrowhead = "odot", arrowtail = "invempty" style="dashed"]', _MQT.Name, behavior[j], ArrowColor ) )
                    end
                    table.insert( BehaviorNameParameters, behavior[j] )
                end
                -- Entry for BehaviorName + Parameters
                table.insert( BehaviorNames, EscapeString((#BehaviorNameParameters > 0 and string.format( "%s (%s)", BehaviorName, table.concat(BehaviorNameParameters, ", ") ) )  or BehaviorName))
            end
            -- Graphviz definition of the "quest bubbles"
            if bTableCounter == 4 then
                local Desc = EscapeString(LimitString(_MQT.Beschreibung or "", 40))
                Desc = (Desc ~= "" and "\\nDesc: " .. Desc) or ""
                table.sort(BehaviorNames )
                table.insert( Result, string.format( '%q [ %s label = "Name: %s%s%s\\n--- Params %d -> %d ---\\n%s" %s%s]', _MQT.Name, fontColor, EscapeString(_MQT.Name),
                Desc, _MQT.ZeitLimit ~= 0 and ('\\nTime: ' .. _MQT.ZeitLimit) or '', _MQT.QuestGeber, _MQT.QuestEmpfaenger, table.concat(BehaviorNames, "\\n"),
                _MQT.ZeitLimit ~= 0 and 'shape="octagon" ' or '', _MQT.VersteckteQuest and 'style="filled" fillcolor="#dddddd" ' or '' ) )
            end
        end
    end
    ------------------------------------GraphVizAusgabeEnde--------------------------------------------------
    
    local beTable = {Trigger = {}, Goal = {}, Reward = {}, Reprisal = {}}
    for beTypeName, bType in pairs(bTable) do
        local beType = beTable[beTypeName]
        for i = 1, #bType do     
            local BehaviorTemplate = GetBehaviorTemplateByName(bType[i][1])
            local NewBehavior = {}   
            Table_Copy(NewBehavior, BehaviorTemplate)
            for k, v in pairs(bType[i]) do
                if k > 1 then 
                    assert(NewBehavior.AddParameter, "MachQuests: Wrong Behavior name in ".._MQT.Name)
                    NewBehavior:AddParameter(k-2, v)
                end
            end    
            beType[#beType + 1] = NewBehavior["Get" .. beTypeName .. "Table"](NewBehavior)
            if beTypeName == "Goal" then
                beType[#beType].Context = NewBehavior
                beType[#beType].FuncOverrideIcon = NewBehavior.GetIcon
                beType[#beType].FuncOverrideMsgKey = NewBehavior.GetMsgKey
            end
        end
    end
    local ShowEndMessage = (((_MQT.ErfolgsNachricht or _MQT.NiederlageNachricht) or ( _MQT.VersteckeEndNachricht == false)) and true) or nil
    
    -- quest ID              
    local QuestID = QuestTemplate:New( _MQT.Name, _MQT.QuestGeber, _MQT.QuestEmpfaenger, beTable.Goal, beTable.Trigger,
                                       _MQT.ZeitLimit, beTable.Reward, beTable.Reprisal, _MQT.EndeFunktion, _MQT.LoopFunktion, 
                                       (not _MQT.VersteckteQuest), ShowEndMessage, _MQT.Beschreibung, _MQT.StartNachricht,
                    _MQT.ErfolgsNachricht, _MQT.NiederlageNachricht )
    g_QuestNameToID[_MQT.Name] = QuestID
    if _MQT.VersteckeEndNachricht then Quests[QuestID].ShowEndMessage = false end
    return QuestID
end
Aufgrund zwei kleiner Fehler (rot markiert) funktioniert die Erstellung zweisprachiger Quests nicht. Der Block am Anfang ist nutzlos und kann komplett raus. WikiQSB.GameLanguage gibt es nicht, muss durch Network.GetDesiredLanguage() ersetzt werden. Zu guter letzt fehlt ein Unterstrich vor field.


korrigierte Version

Code:
function MachQuests(_Quests,_GraphViz)-------------------------Alle vom Start weg aktiven Quests erstellen
 
    if not WikiQSB.GameLanguage then 
        StartSimpleJobEx(function(_Q, _V) if WikiQSB.GameLanguage then MachQuests(_Q,_V) return true end; end, _Quests, _GraphViz) 
        return 
    end
    local Result = _GraphViz and {}
    local MapName = Framework.GetCurrentMapName()
    if _GraphViz then table.insert( Result, 'Von hier an ausschneiden==> \r\ndigraph G { graph [    fontname = "Helvetica-Oblique", fontsize = 30, label = "'..MapName.. '" ]\r\nnode [ fontname = "Courier-Bold" shape = "box" ]' ) end
    for _, QuestTable in ipairs(_Quests) do MachQuest(QuestTable, Result) end
    if _GraphViz then
        table.insert( Result, "}\r\n<=====Bis hier auschneiden")
        Framework.WriteToLog(table.concat( Result, "\r\n" ))
    end
end
 
function MachQuest(_MQT, Result)-------------------Einzelne Quest erstellen
 
    _MQT.QuestGeber = _MQT.QuestGeber or _MQT.Sender or 1
    _MQT.QuestEmpfaenger = _MQT.QuestEmpfaenger or _MQT.Receiver or 1
    _MQT.ZeitLimit = _MQT.ZeitLimit or _MQT.Time or 0
    _MQT.EndeFunktion = _MQT.EndeFunktion or _MQT.EndFunction
    _MQT.LoopFunktion = _MQT.LoopFunktion or _MQT.LoopFunction
    _MQT.VersteckteQuest = _MQT.VersteckteQuest or _MQT.Hidden 
    _MQT.Beschreibung = Umlaute(_MQT.Beschreibung or _MQT.Description)
    _MQT.ErfolgsNachricht = Umlaute(_MQT.ErfolgsNachricht or _MQT.SuccessMessage)
    _MQT.NiederlageNachricht = Umlaute(_MQT.NiederlageNachricht or _MQT.FailureMessage)
    _MQT.StartNachricht = Umlaute(_MQT.StartNachricht or _MQT.StartMessage)
    _MQT.VersteckeEndNachricht = _MQT.VersteckeEndNachricht or _MQT.HideEndMessage 
        
    -- 1. Block Debug Checks
    if type(_MQT.Name) ~= "string" then
        return Logic.DEBUG_AddNote("DEBUG: Kein QuestName vergeben")
    elseif type(_MQT.QuestGeber) ~= "number" or _MQT.QuestGeber < 1 or _MQT.QuestGeber > 8 then
        return Logic.DEBUG_AddNote("DEBUG: QuestGeber in ".._MQT.Name.." hat falschen Wert")
    elseif type(_MQT.QuestEmpfaenger) ~= "number" or _MQT.QuestEmpfaenger < 1 or _MQT.QuestEmpfaenger > 8 then
        return Logic.DEBUG_AddNote("DEBUG: QuestEmpfaenger in ".._MQT.Name.." hat falschen Wert")
    elseif type(_MQT.ZeitLimit) ~= "number" or _MQT.ZeitLimit < 0 then
        return Logic.DEBUG_AddNote("DEBUG: ZeitLimit in ".._MQT.Name.." hat falschen Wert")
    end
        
    -- Behavior Table Building
    local BehaviourType, BehaviourFound = nil, nil
    local bTable = {Trigger = {}, Goal = {}, Reward = {}, Reprisal = {}}
    for k, v in ipairs(_MQT) do
        v = ( type(v) == "table" and type(v.Name) == "string" and type(v.Description) == "table" and v.Name ) or v
        if type(v) == "string" then
            for Key, Behavior in pairs(g_QuestBehaviorTypes) do
                if (Behavior.Name == v) then
                    for beha, behaTable in pairs(bTable) do
                        local BehaviorTemplate = GetBehaviorTemplateByName(v)
                        if BehaviorTemplate["Get"..beha.."Table"] ~= nil then
                            behaTable[#behaTable+1] = {v}
                            BehaviourType = beha
                            BehaviourFound = true
                            break
                        end
                    end
                end
            end
        end
        if (not BehaviourFound) and BehaviourType then
            local b = bTable[BehaviourType]
            table.insert(b[#b], v)
        elseif not BehaviourFound then     
            Logic.DEBUG_AddNote( "Falsche oder fehlende Verhaltensangabe in Quest ".._MQT.Name);return
        end
        BehaviourFound = false
    end
    
    -- 2. Block Debug Checks
    local gLanguage = Network.GetDesiredLanguage()
    local debug1 = {"StartNachricht", "ErfolgsNachricht", "NiederlageNachricht", "Beschreibung" }
    local function cF(_field) if not _field then Logic.DEBUG_AddNote("Translation missing in ".._MQT.Name) else return _field end; end
    for _, field in ipairs(debug1) do
        if type(_MQT[field]) == "table" then
            for Language, _ in pairs(_MQT[field]) do
                if type(Language) == "string" then
                    if gLanguage == "de" or gLanguage == "en" then _MQT[field] = cF(_MQT[field][gLanguage]); break
                    else _MQT[field] = cF(_MQT[field].en); break
                    end
                elseif gLanguage == "de" then _MQT[field] = _MQT[field][1]; break 
                elseif gLanguage == "en" then _MQT[field] = cF(_MQT[field][2]); break 
                else _MQT[field] = cF(_MQT[field][2]); break
                end
            end
        end
        if _MQT[field] and type(_MQT[field]) ~= "string" then return Logic.DEBUG_AddNote("DEBUG: "..field.." in ".._MQT.Name.." ist kein String") end
    end
    if _MQT.EndeFunktion and type(_MQT.EndeFunktion) ~= "function"  then return Logic.DEBUG_AddNote("DEBUG: Angegebene EndeFunktion in ".._MQT.Name.." existiert nicht")
    elseif _MQT.LoopFunktion and type(_MQT.LoopFunktion) ~= "function" then return Logic.DEBUG_AddNote("DEBUG: Angegebene LoopFunktion in ".._MQT.Name.." existiert nicht")
    elseif (#bTable.Goal == 0) or (#bTable.Trigger == 0) then return Logic.DEBUG_AddNote("DEBUG: Entweder fehlt ein Trigger oder ein Goal in ".._MQT.Name)
    end
    
    -------------------------------------Graphviz Ausgabe---------------------------------------------------------
    if Result then
        local ArrowColorTable = {Succeed = 'color="#00ff00"', Fail = 'color="#ff0000"', Interrupt = 'color="#999999"', Default = 'color="#0000ff"' }
        local function EscapeString( _String ) return string.match( string.format( "%q", tostring(_String) ), '^"(.*)"$' ) or "nil"    end
        local function LimitString( _String, _Limit )
            assert( _String )
            assert( _Limit > 3 )
            if string.len( _String ) <= _Limit then return _String
            else return string.sub( _String, 1, _Limit - 3 ) .. "..."
            end
        end
            local fontColor = ""
        local BehaviorNames = {}
            local bTableCounter = 0    
        for _, behaType in pairs(bTable) do
            bTableCounter = bTableCounter + 1
            for _, behavior in ipairs(behaType) do
                local BehaviorName = behavior[1]        
                local BehaviorTemplate = GetBehaviorTemplateByName(BehaviorName)
                local FoundQuestNames = {}
                local BehaviorNameParameters = {}
                -- Set arrow color based on the behavior name (triggers on/causes quest success/failure)
                local ArrowColor = (string.find( BehaviorName, "Succe" ) and ArrowColorTable.Succeed)
                    or (string.find( BehaviorName, "Fail" )and ArrowColorTable.Fail)
                    or (string.find( BehaviorName, "Interrupt" )and ArrowColorTable.Interrupt)
                    or ArrowColorTable.Default
                fontColor = (string.find( BehaviorName, "Wait" ) and 'fontcolor="red"') or ""
                -- Type of relation
                local BDependsOn = ( BehaviorTemplate.GetTriggerTable and "Triggers" ) or ( BehaviorTemplate.GetGoalTable and "Goals" )
                -- Find all parameters that use a quest name
                for j = 2, #behavior do
                    if GameCallback_QuestSytemBehavior_GetParameterType( "BB", BehaviorName, j-1 ) == ParameterType.QuestName then
                        FoundQuestNames[behavior[j]] = true
                        -- GraphViz relation definition
                        table.insert( Result, (BDependsOn and string.format( '%q -> %q [%s]', behavior[j], _MQT.Name, ArrowColor ))  
                                                                                            or string.format( '%q -> %q [%s, arrowhead = "odot", arrowtail = "invempty" style="dashed"]', _MQT.Name, behavior[j], ArrowColor ) )
                    end
                    table.insert( BehaviorNameParameters, behavior[j] )
                end
                -- Entry for BehaviorName + Parameters
                table.insert( BehaviorNames, EscapeString((#BehaviorNameParameters > 0 and string.format( "%s (%s)", BehaviorName, table.concat(BehaviorNameParameters, ", ") ) )  or BehaviorName))
            end
            -- Graphviz definition of the "quest bubbles"
            if bTableCounter == 4 then
                local Desc = EscapeString(LimitString(_MQT.Beschreibung or "", 40))
                Desc = (Desc ~= "" and "\\nDesc: " .. Desc) or ""
                table.sort(BehaviorNames )
                table.insert( Result, string.format( '%q [ %s label = "Name: %s%s%s\\n--- Params %d -> %d ---\\n%s" %s%s]', _MQT.Name, fontColor, EscapeString(_MQT.Name),
                Desc, _MQT.ZeitLimit ~= 0 and ('\\nTime: ' .. _MQT.ZeitLimit) or '', _MQT.QuestGeber, _MQT.QuestEmpfaenger, table.concat(BehaviorNames, "\\n"),
                _MQT.ZeitLimit ~= 0 and 'shape="octagon" ' or '', _MQT.VersteckteQuest and 'style="filled" fillcolor="#dddddd" ' or '' ) )
            end
        end
    end
    ------------------------------------GraphVizAusgabeEnde--------------------------------------------------
    
    local beTable = {Trigger = {}, Goal = {}, Reward = {}, Reprisal = {}}
    for beTypeName, bType in pairs(bTable) do
        local beType = beTable[beTypeName]
        for i = 1, #bType do     
            local BehaviorTemplate = GetBehaviorTemplateByName(bType[i][1])
            local NewBehavior = {}   
            Table_Copy(NewBehavior, BehaviorTemplate)
            for k, v in pairs(bType[i]) do
                if k > 1 then 
                    assert(NewBehavior.AddParameter, "MachQuests: Wrong Behavior name in ".._MQT.Name)
                    NewBehavior:AddParameter(k-2, v)
                end
            end    
            beType[#beType + 1] = NewBehavior["Get" .. beTypeName .. "Table"](NewBehavior)
            if beTypeName == "Goal" then
                beType[#beType].Context = NewBehavior
                beType[#beType].FuncOverrideIcon = NewBehavior.GetIcon
                beType[#beType].FuncOverrideMsgKey = NewBehavior.GetMsgKey
            end
        end
    end
    local ShowEndMessage = (((_MQT.ErfolgsNachricht or _MQT.NiederlageNachricht) or ( _MQT.VersteckeEndNachricht == false)) and true) or nil
    
    -- quest ID              
    local QuestID = QuestTemplate:New( _MQT.Name, _MQT.QuestGeber, _MQT.QuestEmpfaenger, beTable.Goal, beTable.Trigger,
                                       _MQT.ZeitLimit, beTable.Reward, beTable.Reprisal, _MQT.EndeFunktion, _MQT.LoopFunktion, 
                                       (not _MQT.VersteckteQuest), ShowEndMessage, _MQT.Beschreibung, _MQT.StartNachricht,
                    _MQT.ErfolgsNachricht, _MQT.NiederlageNachricht )
    g_QuestNameToID[_MQT.Name] = QuestID
    if _MQT.VersteckeEndNachricht then Quests[QuestID].ShowEndMessage = false end
    return QuestID
end