Countdown wird Übersprungen

» Siedler Map Source Forum » Siedler DEdK Script Forum » Countdown wird Übersprungen

Seiten: 1

Narnius
#1
12.11.2018 13:00
Beiträge: 34

Countdown wird Übersprungen

Bei einer Map die ich gerade erstelle, es soll eine Dreispieler Coop-Map werden, habe ich einen Troop Spawn Generator eingebaut, welcher kontinuierlich Truppen aussenden soll. Mein Endziel damit, ist das dieser Abwechselnd die drei Spieler angreift. Derzeit arbeite ich allerdings noch daran, das das Grundprinzip funktioniert. Es soll ein Trupp spawnen, dann startet ein Countdown. Wenn dieser abgelaufen ist, greift der bestehende Trupp an, und ein neuer spawnt, um das Gebiet zu verteidigen. Ich habe in mein Script eine Countdown-Comfort-Funktion eingebaut und glaube, dass der Fehler bei dieser liegt. Wird Am ende der Funktion ControlArmyOne() wird CreateArmyOne() aufgerufen und dann spawnt auch ein neuer Trupp. Allerdings wird dann der Countdown missachtet, ControlArmyOne() wird sofort wieder aufgerufen und die Truppen schießen wie Pilze aus dem Boden. Hier das Script:

Hinweis: Viele der Kommentierungen stammen nicht von mir, sondern von den Machern der Comfortfunktionen.

-- MapName: Der Fluch der Schwarzen Berge 
-- MapOriginalAuthor: Christian & Matthias
-- Author: Narnius
-- Coop Referencescript für zwei Spieler, Diese spielen gegen eine bestimmte Anzahl an KI Spieler
-- Man muß im Editor beim Kartenscriptassistenten nur die zwei menschlichen Spieler festlegen, damit auch nur diese zwei Plätze später in der Lobby angezeigt werden.
-- Beim Start in der MP Lobby oder im Lan kann man beide Spieler in unterschiedlichen Teams stehen lassen , nach dem Start werden sie im Game verbündet sein .
-- Bei dieser Map sind auch die MP Bugtools von chromix eingebaut Enable Alarmlimit und  enable overtimelimit
--------------------------------------------------------------------------------
-- Hiermit wird die Lobbyfunktion umgangen, so dass die beiden menschlichen Spieler nach dem Start verbündet sind und auch das Gebiet des anderen sehen
if XNetwork then
    XNetwork.GameInformation_GetLogicPlayerTeam = function() return 1; end
    XNetwork.GameInformation_GetFreeAlliancesFlag = function() return 1; end
end
 
function GameCallback_OnGameStart()     
 
    -- Include global tool script functions 
    Script.Load(Folders.MapTools.."Ai\\Support.lua")
    Script.Load( Folders.MapTools.."Main.lua" )
    -- Unbedingt muß für die Einbindung der Ki hier auch dieses am Anfang geladen werden
    IncludeGlobals("MapEditorTools")
    Script.Load( "Data\\Script\\MapTools\\Counter.lua" )
    Script.Load( "Data\\Script\\MapTools\\MultiPlayer\\MultiplayerTools.lua" )  
    Script.Load( "Data\\Script\\MapTools\\Tools.lua" )  
    Script.Load( "Data\\Script\\MapTools\\WeatherSets.lua" )
    IncludeGlobals("Comfort")
    -- notwendig damit die Siegbedingungen greifen 
    gvMission = {}
    gvMission.PlayerID = GUI.GetPlayerID()
 
    
    --Init local map stuff
    Mission_InitWeatherGfxSets()
    InitWeather()
    Mission_InitGroups()    
    Mission_InitLocalResources()
    
    -- Init  global MP stuff
    --MultiplayerTools.InitResources("normal")
    MultiplayerTools.InitCameraPositionsForPlayers()    
    MultiplayerTools.SetUpGameLogicOnMPGameConfig()
    MultiplayerTools.GiveBuyableHerosToHumanPlayer( 1 ) -- 1 Held pro Spieler
    StartSimpleJob("VictoryJob")
    NewTribute1();
    ModelOverwrite();
    CreateArmyOne();
    MakeInvulnerable();

 
    if XNetwork.Manager_DoesExist() == 0 then      
        for i = 1, 3 do    -- Für 3 Spieler eingestellt
            MultiplayerTools.DeleteFastGameStuff(i)
        end
        local PlayerID = GUI.GetPlayerID()
        Logic.PlayerSetIsHumanFlag( PlayerID, 1 )
        Logic.PlayerSetGameStateToPlaying( PlayerID )
    end
    -- Die weiteren menschlichen Spieler müssen auf Feind gestellt werden so dies gewünscht ist zu allen KI's
    SetHostile( 5, 2 )
    SetHostile( 5, 3 )
    
    
    
    LocalMusic.UseSet = HIGHLANDMUSIC
    --Befehlsatz einfach Kommentierung durch entfernen der beiden Bindestriche rausnehmen
    -- nicht vergessen das jeweils nur ein Set gesetzt sein sollte
    --LocalMusic.UseSet = EUROPEMUSIC
    --LocalMusic.UseSet = HIGHLANDMUSIC
    --LocalMusic.UseSet = MEDITERANEANMUSIC
    --LocalMusic.UseSet = DARKMOORMUSIC
    --LocalMusic.UseSet = EVELANCEMUSIC
    
    -- Diese  Zeilen kommen noch vom Karteneditor und setzen die Standardsiegbedingung vernicht die Player Id
    MapEditor_SetupDestroyVictoryCondition(5)
    MapEditor_CreateHQDefeatCondition()
 
    -- Hier gehts mit den Parametern für den KI Spieler los. In diesem Fall Spieler 3, denn Spieler 2 ist ja der 2. menschliche Spieler
    -- Man kann diese Werte natürlich auch direkt in die Funktion eintragen,
    -- anstatt sie wie hier übersichtlich aufzulisten
    
 
    --Nächste Ki
    local aiID = 5;
    local strength = 3;
    local range = 3000;
    local techlevel = 3;    
    local position = "P5_AI_HQ"; -- natürlich sollte man P5_AI_HQ als Skriptnamen dem Hauptquartier geben, natürlich bei player 4 P4_AI_HQ etc..
    local aggressiveness = 3;   
    local peacetime = 0;  
    MapEditor_SetupAI( aiID, strength, range, techlevel, position, aggressiveness, peacetime );
    SetupPlayerAi( aiID, { extracting = 1, repairing = 1 } );
    SetPlayerName( aiID, "Nebelvolk" );
 
    --Der Teil hier ist nur wichtig wenn man gezielt die Ressourcen bestimmen möchte die die Ki bekommt.
    -- Falls man dies nicht möchte, kann dieser Teil weggelassen werden
    -- Die Parmeter sollten individuelle angpasst werden
    
    SetupPlayerAi( 5, {
    resources =
    { 
        gold                =   10000,
        clay                =   100,
        iron                =   1500,
        sulfur        = 1500,
        stone            =  100,
        wood                =   100,
    }
    } );
    SetupPlayerAi( 5, {
    refresh =
    { 
        gold                =   10000,
        clay                =   1000,
        iron                =   1500,
        sulfur        = 1500,
        stone            =  100,
        wood                =   100,
        updateTime      = 1000
    }
    } );
end
 
--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-- This function is called on game start and after save game is loaded, setup your weather gfx
-- sets here
function Mission_InitWeatherGfxSets()
    -- Use gfx sets
    SetupHighlandWeatherGfxSet()
    --Befehlsatz einfach Kommentierung durch entfernen der beiden Bindestriche rausnehmen nicht vergessen das man nur ein setzten sollte
    --SetupNormalWeatherGfxSet()
    --SetupHighlandWeatherGfxSet()
    --SetupSteppeWeatherGfxSet()
    --SetupMoorWeatherGfxSet()
    --SetupEvelanceWeatherGfxSet()
end
 
--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-- This function is called on game start you should setup your weather periods here
function InitWeather()
    -- Hier wird der Wetterwechsel festgelegtl 
    -- Beispiel 4 Min Sommer, dann 2 Minuten Winter, dann wieder alles von vorne
    AddPeriodicSummer(240) 
    AddPeriodicWinter(120)
    --Befehlsatz einfach Kommentierung durch entfernen der beiden Bindestriche rausnehmen
    --AddPeriodicSummer(600) 
    --AddPeriodicWinter(300) 
    --AddPeriodicRain(120) 
 
end
 
--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-- Build Groups and attach Leaders
function Mission_InitGroups()
        
end
 
--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-- Limit the Technologies here. For example Weathermashine.
function
Mission_InitTechnologies()
    --no limitation in this map
end
 
--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-- Set local resources
function
Mission_InitLocalResources()
    local HumenPlayer = XNetwork.GameInformation_GetMapMaximumNumberOfHumanPlayer()
    
 
    -- Dies sind die Startresourcen für alle Spieler. Diese sollten angepasst werden
    local InitGoldRaw     = 300
    local InitClayRaw     = 600
    local InitWoodRaw     = 400
    local InitStoneRaw   = 300
    local InitIronRaw     = 300
    local InitSulfurRaw  = 250
 
    
    --Add Players Resources
    for i = 1, 3 do
        Tools.GiveResouces(i, InitGoldRaw , InitClayRaw,InitWoodRaw, InitStoneRaw,InitIronRaw,InitSulfurRaw)

        --Befehlsatz einfach Kommentierung durch entfernen der beiden Bindestriche rausnehmen
        --Unitechnologien
        
        --ResearchTechnology(Technologies.GT_Mercenaries, i) -->Wehrpflicht 
        --ResearchTechnology(Technologies.GT_StandingArmy, i) -- -> stehendes Heer
        --ResearchTechnology(Technologies.GT_Tactics, i)--> Taktiken
        --ResearchTechnology(Technologies.GT_Strategies, i) ---> Pferdezucht
        
        ResearchTechnology(Technologies.GT_Construction, i) ----> Konstruktion
        --ResearchTechnology(Technologies.GT_ChainBlock, i) --Flaschenzug
        --ResearchTechnology(Technologies.GT_GearWheel, i) --Zahnräder
        --ResearchTechnology(Technologies.GT_Architecture, i) --Architektur
        
        ResearchTechnology(Technologies.GT_Alchemy, i) --Alchimie
        --ResearchTechnology(Technologies.GT_Alloying, i) --Legierungen
        --ResearchTechnology(Technologies.GT_Metallurgy, i) --Metallurgie
        --ResearchTechnology(Technologies.GT_Chemistry, i) --Chemie
        
        
        --ResearchTechnology(Technologies.GT_Taxation, i) --
        --ResearchTechnology(Technologies.GT_Trading, i) --Handelswesen
        --ResearchTechnology(Technologies.GT_Banking, i) --
        --ResearchTechnology(Technologies.GT_Gilds, i) --
        
        --ResearchTechnology(Technologies.GT_Literacy, i) --Bildung
        --ResearchTechnology(Technologies.GT_Printing, i) --Buchdruck
        --ResearchTechnology(Technologies.GT_Laws, i) --
        --ResearchTechnology(Technologies.GT_Library, i) --Büchereien
        
        ResearchTechnology(Technologies.GT_Mathematics, i) --Mathematik
        --ResearchTechnology(Technologies.GT_Binocular, i) -- Ferngläser
        --ResearchTechnology(Technologies.GT_Matchlock, i) --Luntenschloss
        --ResearchTechnology(Technologies.GT_PulledBarrel, i) --gezogener Lauf
            
        --ResearchTechnology(Technologies.T_ChangeWeather, i)
        --ResearchTechnology(Technologies.T_WeatherForecast,i)
        --ResearchTechnology(Technologies.T_ThiefSabotage,i) 
        --ResearchTechnology(Technologies., i)
        --ResearchTechnology(Technologies., i)
    end
end  
 
-- victory funktion muß bei coop sein 
-- Hier wird die Siegbedingung vorgegeben
function VictoryJob()
    if IsDead("P5_AI_HQ") then
        Victory();
        return true;
    end
end  

function CreateArmyOne()  
  armyOne            = {}
  
  armyOne.player     = 5
  armyOne.id         = 7
  armyOne.strength   = 3
  armyOne.position   = GetPosition("NVolk")
  armyOne.rodeLength = 500  
 
  SetupArmy(armyOne)  

  local troopDescription  = {  
  maxNumberOfSoldiers     = 16,
  minNumberOfSoldiers     = 0,
  experiencePoints        = VERYLOW_EXPERIENCE,
 }

 troopDescription.leaderType = Entities.CU_Evil_LeaderBearman1  

 EnlargeArmy(armyOne,troopDescription)
 EnlargeArmy(armyOne,troopDescription)  

 Defend(armyOne)  

 StartCountdown(20, ControlArmyOne, true) 

end  

function ControlArmyOne()
    --if not armyOne.created then
        --armyOne.created = not IsDead(armyOne)
        --return false
    --end
    Redeploy(armyOne, GetPosition("StartPos" ), 5000);
    Fanfare()   
end

function Fanfare()

    Sound.PlayGUISound(Sounds.fanfare,95)
    CreateArmyOne()

end

function StartCountdown(_Limit, _Callback, _Show)
    assert(type(_Limit) == "number")
    assert( not _Callback or type(_Callback) == "function" )
 
    Counter.Index = (Counter.Index or 0) + 1
    
    if _Show and CountdownIsVisisble() then
        assert(false, "StartCountdown: A countdown is already visible")
    end
    
    Counter["counter" .. Counter.Index] = {Limit = _Limit, TickCount = 0, Callback = _Callback, Show = _Show, Finished = false}
    
    if _Show then
        MapLocal_StartCountDown(_Limit)
    end
    
    if Counter.JobId == nil then
        Counter.JobId = StartSimpleJob("CountdownTick")
    end
    
    return Counter.Index
end
 
function StopCountdown(_Id)
    if Counter.Index == nil then
        return
    end
 
    if _Id == nil then
        for i = 1, Counter.Index do
            if Counter.IsValid("counter" .. i) then
                if Counter["counter" .. i].Show then
                    MapLocal_StopCountDown()
                end
                Counter["counter" .. i] = nil
            end
        end
    else
        if Counter.IsValid("counter" .. _Id) then
            if Counter["counter" .. _Id].Show then
                MapLocal_StopCountDown()
            end
            Counter["counter" .. _Id] = nil
            i=1
        end
    end
end
 
function CountdownTick()
    local empty = true
    for i = 1, Counter.Index do
        if Counter.IsValid("counter" .. i) then
            if Counter.Tick("counter" .. i) then
                Counter["counter" .. i].Finished = true
            end
            
            if Counter["counter" .. i].Finished and not IsBriefingActive() then
                if Counter["counter" .. i].Show then
                    MapLocal_StopCountDown()
                end
                
                -- callback function
                if type(Counter["counter" .. i].Callback) == "function" then
                    Counter["counter" .. i].Callback()
                end
                
                Counter["counter" .. i] = nil
            end
            
            empty = false
        end
    end
    
    if empty then
        Counter.JobId = nil
        Counter.Index = nil
        return true
    end
end
 
function CountdownIsVisisble()
    for i = 1, Counter.Index do
        if Counter.IsValid("counter" .. i) and Counter["counter" .. i].Show then
            return true
        end
    end
    
    return false
end

function AddTribute( _tribute )
    assert( type( _tribute ) == "table", "Tribut muß ein Table sein" );
    assert( type( _tribute.text ) == "string", "Tribut.text muß ein String sein" );
    assert( type( _tribute.cost ) == "table", "Tribut.cost muß ein Table sein" );
    assert( type( _tribute.playerId ) == "number", "Tribut.playerId muß eine Nummer sein" );
    assert( not _tribute.Tribute , "Tribut.Tribute darf nicht vorbelegt sein");
    
    uniqueTributeCounter = uniqueTributeCounter or 1;
    _tribute.Tribute = uniqueTributeCounter;
    uniqueTributeCounter = uniqueTributeCounter + 1;
    
    local tResCost = {};
    for k, v in pairs( _tribute.cost ) do
        assert( ResourceType[k] );
        assert( type( v ) == "number" );
        table.insert( tResCost, ResourceType[k] );
        table.insert( tResCost, v );
    end
    
    Logic.AddTribute( _tribute.playerId, _tribute.Tribute, 0, 0, _tribute.text, unpack( tResCost ) );
    SetupTributePaid( _tribute );
    
    return _tribute.Tribute;
end  
      
--+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
--Hier werden unsere Tribute erstellt
--+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
--Tribut Packen WS0
 
function NewTribute1() 
    local tribute =  {};
    tribute.playerId = 3; 
    tribute.text = "Bietet Spieler 1 an, das Tor gegen 200 Gold zu oeffnen"; 
    tribute.cost = { Gold = 0}; 
    tribute.Callback = Tributcallback1; 
    TributId1 = AddTribute( tribute ); 
end
 
function Tributcallback1()

NewTribute2()

end

function NewTribute2()
    local tribute =  {};
    tribute.playerId = 1; 
    tribute.text = "Gebt Spieler 2 200 Gold um das Tor zu oeffnen"; 
    tribute.cost = { Gold = 200}; 
    tribute.Callback = Tributcallback2; 
    TributId1 = AddTribute( tribute ); 
end

function Tributcallback2()
AddGold( 1, -200)
AddGold( 3, 200)
ReplaceEntity ("Tor1", Entities.XD_WallStraightGate )

end


--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++



function ModelOverwrite()
   Logic.SetModelAndAnimSet(GetEntityId("steinmauer"), Models.XD_RuinWall1)
   Logic.SetModelAndAnimSet(GetEntityId("wall1"), Models.XD_Palisade1)
   Logic.SetModelAndAnimSet(GetEntityId("wall2"), Models.XD_Palisade1)
   Logic.SetModelAndAnimSet(GetEntityId("wall3"), Models.XD_Palisade1)
   Logic.SetModelAndAnimSet(GetEntityId("wall4"), Models.XD_Palisade1)
   Logic.SetModelAndAnimSet(GetEntityId("wall5"), Models.XD_Palisade1)
-- wall1-wall5 sind sprengbare Steine, die steinmauer ist eigentlich ein abbaubarer Steinhaufen.
end

function GameCallback_FulfillTribute() --Im Multiplayer sind Tribute standardmäßig deaktiviert, daher muss man sie erst wieder aktivieren
    return 1
end



Weiß jemand, wie man dieses Problem beheben kann?
Wenn ja, freue ich mich sehr über eine schnelle Antwort!

Vielen Dank schon mal im Voraus,

Narnius

Play4FuN
#2
13.11.2018 10:24
Beiträge: 704

Moin,
ich denke sofern du den Countdown Code richtig kopiert hast, sollte der ordentlich laufen. Ich nutze den so seit Jahren ohne Probleme und bin da sicher nicht der einzige.

Was mir aber beim Überfliegen direkt auffällt: nach 20 Sekunden wird armyOne neu erstellt, das heißt die alte wird überschrieben (die Truppen sind aber ggf noch da...)
Das könnte durchaus zu solch einem Verhalten führen, denke ich.

Daher bevor du die armyOne neu erstellst, erst mal prüfen, ob es die bisherige Army one noch gibt. Alternativ kannst du auch in deinem Countdown Callback anstatt CreateArymOne eine andere Funktion aufrufen, die nur das macht:

local troopDescription  = {  
  maxNumberOfSoldiers     = 16,
  minNumberOfSoldiers     = 0,
  experiencePoints        = VERYLOW_EXPERIENCE,
 }

 troopDescription.leaderType = Entities.CU_Evil_LeaderBearman1  

 EnlargeArmy(armyOne,troopDescription)
 EnlargeArmy(armyOne,troopDescription) 


... dann sollten nur neue Trupps zur bestehenden Armee hinzugefügt werden. Countdown neu starten nicht vergessen.

Inb4 falls du mal in das Problem rennst: IsDead bei Armeen funzt nicht ordentlich, falls diese noch gar nicht erstellt wurde, siehe dazu: http://www.siedler-games.de/si...id=utilfunctions:isdeadwrapper

____________________
LG Play4FuN

Siedler DEdK Mapping + Scripting Tutorials

Narnius
#3
13.11.2018 12:39
Beiträge: 34

Zitat von Play4FuN:
Moin,
ich denke sofern du den Countdown Code richtig kopiert hast, sollte der ordentlich laufen. Ich nutze den so seit Jahren ohne Probleme und bin da sicher nicht der einzige.

Was mir aber beim Überfliegen direkt auffällt: nach 20 Sekunden wird armyOne neu erstellt, das heißt die alte wird überschrieben (die Truppen sind aber ggf noch da...)
Das könnte durchaus zu solch einem Verhalten führen, denke ich.

Daher bevor du die armyOne neu erstellst, erst mal prüfen, ob es die bisherige Army one noch gibt. Alternativ kannst du auch in deinem Countdown Callback anstatt CreateArymOne eine andere Funktion aufrufen, die nur das macht:

local troopDescription  = {  
  maxNumberOfSoldiers     = 16,
  minNumberOfSoldiers     = 0,
  experiencePoints        = VERYLOW_EXPERIENCE,
 }

 troopDescription.leaderType = Entities.CU_Evil_LeaderBearman1  

 EnlargeArmy(armyOne,troopDescription)
 EnlargeArmy(armyOne,troopDescription) 


... dann sollten nur neue Trupps zur bestehenden Armee hinzugefügt werden. Countdown neu starten nicht vergessen.

Inb4 falls du mal in das Problem rennst: IsDead bei Armeen funzt nicht ordentlich, falls diese noch gar nicht erstellt wurde, siehe dazu: http://www.siedler-games.de/si...id=utilfunctions:isdeadwrapper



Danke für die Antwort, den CD hatte ich zu Testzwecken verkürzt, das isDead/notCreated Hilfsskript ist auch schon drin. Mit EnlargeArmyOne hatte ich es auch schon probiert, aber was meinst du mit "Countdown neu starten"?
Mir kam es nämlich so vor, als ob der Countdownwert nicht resetet wird und dadurch beim wiederholten Aufruf direkt zum Callback übergegangen wird.

Play4FuN
#4
13.11.2018 17:45
Beiträge: 704

Ich meine schlicht den StartCountdown Aufruf.
Kommt denn die Fanfare wie du es erwartest, oder wird die auch gespammt?

____________________
LG Play4FuN

Siedler DEdK Mapping + Scripting Tutorials

Narnius
#5
13.11.2018 17:49
Beiträge: 34

Doch

Zitat von Play4FuN:
Ich meine schlicht den StartCountdown Aufruf.
Kommt denn die Fanfare wie du es erwartest, oder wird die auch gespammt?



Die wird auch gespammt.

mcb
#6
13.11.2018 20:32
Beiträge: 1472

Ich glaube ich weiß, was los ist: Wenn der Countdown abgelaufen ist, wird die entsprechende Callback-Funktion aufgerufen, bevor der Countdown entfernt wird. Da du im Callback direkt einen neuen Countdown erstellst und beide sichtbar seien sollen, erzeugt StartCountdown eine Fehlermeldung, da nicht 2 Countdowns gleichzeitig angezeigt werden können.
Du bekommst die Fehlermeldung angezeigt, wenn du das hier machst: http://www.siedler-games.de/si...als:fehlermeldungen_aktivieren
oder den LuaDebugger benutzt.

Als einfachste Lösung würde ich Vorschlagen diese beiden Funktionen so abzuändern:

function ControlArmyOne()
	Redeploy(armyOne, GetPosition("StartPos" ), 5000);
	Fanfare()
	StartCountdown(1, CreateArmyOne, false)
end

function Fanfare()
	Sound.PlayGUISound(Sounds.fanfare,95)
end

Narnius
#7
13.11.2018 21:34
Beiträge: 34

Juhu!

Vielen Dank, jetzt geht es, das einzige Problem ist jetzt noch, das die Truppen ihren Angriff abbrechen, wenn neue spawnen. Das lag auch nicht an dem Defend() Befehl, auch ohne war dies noch der Fall. Ich schätze PlayForFuns's Vorschlag könnte da Abhilfe schaffen, nur gibt der Editor mir einen Errsyntax, wenn ich das so reinkopiere (natürlich mit/zwischen Funktionskopf und end).

mcb
#8
16.11.2018 16:59
Beiträge: 1472

Also das der Mapeditor ErrSyntax sagt muss nix heißen, gerade wenn du TinyScript verwendest funktioniert das nur selten. Aktiviere einfach die Fehlermeldungen und starte die Map, dann weißt du ob du wirklich nen Syntaxfehler hast. (Wenn ja, poste mal den entsprechenden Code und die genaue Fehlermeldung.)

Narnius
#9
16.11.2018 18:27
Beiträge: 34

ähm

Zitat von mcb:
Also das der Mapeditor ErrSyntax sagt muss nix heißen, gerade wenn du TinyScript verwendest funktioniert das nur selten. Aktiviere einfach die Fehlermeldungen und starte die Map, dann weißt du ob du wirklich nen Syntaxfehler hast. (Wenn ja, poste mal den entsprechenden Code und die genaue Fehlermeldung.)



Ich benutze den LuaDebugger gar nicht, der ging bei mir auch nicht...

mcb
#10
16.11.2018 18:56
Beiträge: 1472

Ich meinte auch das hier, nicht den Debugger: http://www.siedler-games.de/si...als:fehlermeldungen_aktivieren

Narnius
#11
17.11.2018 12:09
Beiträge: 34

Hm

Ich glaube, ich habe jetzt den Fehler gefunden und er liegt nicht in meinem Skript. Die Gruppen bzw. Armeen, die ich für den Gegner erstelle, halten einfach immer zusammen. Der letzte Befehl, den ich der einen Armee gebe, wirkt auch auf die andere.
Mir kam nämlich der Geistesblitz, die Truppen in zwei Gruppen aufzuspalten. Ich versprach mir viel davon, da ich die Truppen ja so auch viel einfacher an verschiedene Orte schicken kann. Außerdem ermöglicht mir das, verschiedene Arten von Truppen zu spawnen. armyOne sind Bärenmenschen und armyTwo besteht aus Speerwerfern. Auf meine Schlussfolgerung kam ich, da die Speerwerfer immer mit den Bärenmenschen mitgingen und dann alle Truppen umkehrten, wenn ein neuer gespawnt war. Dieser Fehler blieb dann auch bestehen, als ich die armyTwo in "armeeZweite" umbenannt hatte. Das Endergebnis war dann, dass die Truppen sich langsam in Richtung PlayerHQ vorarbeiteten, und zwischendurch immer wieder umkehrten. Da sie aber nur sieben Sekunden hatten bis zum Angriffsbefehl, und 13, bis zum Spawn neuer Truppen, kamen sie tatsächlich voran. Anbei mein Skript, wisst ihr vielleicht einen Weg das zu umgehen?

-- MapName: Der Fluch der Schwarzen Berge 
-- MapOriginalAuthor: Christian & Matthias
-- Author: Narnius
-- Coop Referencescript für zwei Spieler, Diese spielen gegen eine bestimmte Anzahl an KI Spieler
-- Man muß im Editor beim Kartenscriptassistenten nur die zwei menschlichen Spieler festlegen, damit auch nur diese zwei Plätze später in der Lobby angezeigt werden.
-- Beim Start in der MP Lobby oder im Lan kann man beide Spieler in unterschiedlichen Teams stehen lassen , nach dem Start werden sie im Game verbündet sein .
-- Bei dieser Map sind auch die MP Bugtools von chromix eingebaut Enable Alarmlimit und  enable overtimelimit
--------------------------------------------------------------------------------
-- Hiermit wird die Lobbyfunktion umgangen, so dass die beiden menschlichen Spieler nach dem Start verbündet sind und auch das Gebiet des anderen sehen
if XNetwork then
    XNetwork.GameInformation_GetLogicPlayerTeam = function() return 1; end
    XNetwork.GameInformation_GetFreeAlliancesFlag = function() return 1; end
end
 
function GameCallback_OnGameStart()     
 
    -- Include global tool script functions 
    Script.Load(Folders.MapTools.."Ai\\Support.lua")
    Script.Load( Folders.MapTools.."Main.lua" )
    -- Unbedingt muß für die Einbindung der Ki hier auch dieses am Anfang geladen werden
    IncludeGlobals("MapEditorTools")
    Script.Load( "Data\\Script\\MapTools\\Counter.lua" )
    Script.Load( "Data\\Script\\MapTools\\MultiPlayer\\MultiplayerTools.lua" )  
    Script.Load( "Data\\Script\\MapTools\\Tools.lua" )  
    Script.Load( "Data\\Script\\MapTools\\WeatherSets.lua" )
    IncludeGlobals("Comfort")
    -- notwendig damit die Siegbedingungen greifen 
    gvMission = {}
    gvMission.PlayerID = GUI.GetPlayerID()
 
    
    --Init local map stuff
    Mission_InitWeatherGfxSets()
    InitWeather()
    Mission_InitGroups()    
    Mission_InitLocalResources()
    
    -- Init  global MP stuff
    --MultiplayerTools.InitResources("normal")
    MultiplayerTools.InitCameraPositionsForPlayers()    
    MultiplayerTools.SetUpGameLogicOnMPGameConfig()
    MultiplayerTools.GiveBuyableHerosToHumanPlayer( 1 ) -- 1 Held pro Spieler
    StartSimpleJob("VictoryJob")
    NewTribute1();
    ModelOverwrite();
    CreateArmyOne();
    MakeInvulnerable();

 
    if XNetwork.Manager_DoesExist() == 0 then      
        for i = 1, 3 do    -- Für 3 Spieler eingestellt
            MultiplayerTools.DeleteFastGameStuff(i)
        end
        local PlayerID = GUI.GetPlayerID()
        Logic.PlayerSetIsHumanFlag( PlayerID, 1 )
        Logic.PlayerSetGameStateToPlaying( PlayerID )
    end
    -- Die weiteren menschlichen Spieler müssen auf Feind gestellt werden so dies gewünscht ist zu allen KI's
    SetHostile( 5, 2 )
    SetHostile( 5, 3 )
    
    
    
    LocalMusic.UseSet = HIGHLANDMUSIC
    --Befehlsatz einfach Kommentierung durch entfernen der beiden Bindestriche rausnehmen
    -- nicht vergessen das jeweils nur ein Set gesetzt sein sollte
    --LocalMusic.UseSet = EUROPEMUSIC
    --LocalMusic.UseSet = HIGHLANDMUSIC
    --LocalMusic.UseSet = MEDITERANEANMUSIC
    --LocalMusic.UseSet = DARKMOORMUSIC
    --LocalMusic.UseSet = EVELANCEMUSIC
    
    -- Diese  Zeilen kommen noch vom Karteneditor und setzen die Standardsiegbedingung vernicht die Player Id
    MapEditor_SetupDestroyVictoryCondition(5)
    MapEditor_CreateHQDefeatCondition()
 
    -- Hier gehts mit den Parametern für den KI Spieler los. In diesem Fall Spieler 3, denn Spieler 2 ist ja der 2. menschliche Spieler
    -- Man kann diese Werte natürlich auch direkt in die Funktion eintragen,
    -- anstatt sie wie hier übersichtlich aufzulisten
    
 
    --Nächste Ki
    local aiID = 5;
    local strength = 3;
    local range = 3000;
    local techlevel = 3;    
    local position = "P5_AI_HQ"; -- natürlich sollte man P5_AI_HQ als Skriptnamen dem Hauptquartier geben, natürlich bei player 4 P4_AI_HQ etc..
    local aggressiveness = 3;   
    local peacetime = 0;  
    MapEditor_SetupAI( aiID, strength, range, techlevel, position, aggressiveness, peacetime );
    SetupPlayerAi( aiID, { extracting = 1, repairing = 1 } );
    SetPlayerName( aiID, "Nebelvolk" );
 
    --Der Teil hier ist nur wichtig wenn man gezielt die Ressourcen bestimmen möchte die die Ki bekommt.
    -- Falls man dies nicht möchte, kann dieser Teil weggelassen werden
    -- Die Parmeter sollten individuelle angpasst werden
    
    SetupPlayerAi( 5, {
    resources =
    { 
        gold                =   10000,
        clay                =   100,
        iron                =   1500,
        sulfur        = 1500,
        stone            =  100,
        wood                =   100,
    }
    } );
    SetupPlayerAi( 5, {
    refresh =
    { 
        gold                =   10000,
        clay                =   1000,
        iron                =   1500,
        sulfur        = 1500,
        stone            =  100,
        wood                =   100,
        updateTime      = 1000
    }
    } );
end
 
--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-- This function is called on game start and after save game is loaded, setup your weather gfx
-- sets here
function Mission_InitWeatherGfxSets()
    -- Use gfx sets
    SetupHighlandWeatherGfxSet()
    --Befehlsatz einfach Kommentierung durch entfernen der beiden Bindestriche rausnehmen nicht vergessen das man nur ein setzten sollte
    --SetupNormalWeatherGfxSet()
    --SetupHighlandWeatherGfxSet()
    --SetupSteppeWeatherGfxSet()
    --SetupMoorWeatherGfxSet()
    --SetupEvelanceWeatherGfxSet()
end
 
--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-- This function is called on game start you should setup your weather periods here
function InitWeather()
    -- Hier wird der Wetterwechsel festgelegtl 
    -- Beispiel 4 Min Sommer, dann 2 Minuten Winter, dann wieder alles von vorne
    AddPeriodicSummer(240) 
    AddPeriodicWinter(120)
    --Befehlsatz einfach Kommentierung durch entfernen der beiden Bindestriche rausnehmen
    --AddPeriodicSummer(600) 
    --AddPeriodicWinter(300) 
    --AddPeriodicRain(120) 
 
end
 
--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-- Build Groups and attach Leaders
function Mission_InitGroups()
        
end
 
--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-- Limit the Technologies here. For example Weathermashine.
function
Mission_InitTechnologies()
    --no limitation in this map
end
 
--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-- Set local resources
function
Mission_InitLocalResources()
    local HumenPlayer = XNetwork.GameInformation_GetMapMaximumNumberOfHumanPlayer()
    
 
    -- Dies sind die Startresourcen für alle Spieler. Diese sollten angepasst werden
    local InitGoldRaw     = 300
    local InitClayRaw     = 600
    local InitWoodRaw     = 400
    local InitStoneRaw   = 300
    local InitIronRaw     = 300
    local InitSulfurRaw  = 250
 
    
    --Add Players Resources
    for i = 1, 3 do
        Tools.GiveResouces(i, InitGoldRaw , InitClayRaw,InitWoodRaw, InitStoneRaw,InitIronRaw,InitSulfurRaw)

        --Befehlsatz einfach Kommentierung durch entfernen der beiden Bindestriche rausnehmen
        --Unitechnologien
        
        --ResearchTechnology(Technologies.GT_Mercenaries, i) -->Wehrpflicht 
        --ResearchTechnology(Technologies.GT_StandingArmy, i) -- -> stehendes Heer
        --ResearchTechnology(Technologies.GT_Tactics, i)--> Taktiken
        --ResearchTechnology(Technologies.GT_Strategies, i) ---> Pferdezucht
        
        ResearchTechnology(Technologies.GT_Construction, i) ----> Konstruktion
        --ResearchTechnology(Technologies.GT_ChainBlock, i) --Flaschenzug
        --ResearchTechnology(Technologies.GT_GearWheel, i) --Zahnräder
        --ResearchTechnology(Technologies.GT_Architecture, i) --Architektur
        
        ResearchTechnology(Technologies.GT_Alchemy, i) --Alchimie
        --ResearchTechnology(Technologies.GT_Alloying, i) --Legierungen
        --ResearchTechnology(Technologies.GT_Metallurgy, i) --Metallurgie
        --ResearchTechnology(Technologies.GT_Chemistry, i) --Chemie
        
        
        --ResearchTechnology(Technologies.GT_Taxation, i) --
        --ResearchTechnology(Technologies.GT_Trading, i) --Handelswesen
        --ResearchTechnology(Technologies.GT_Banking, i) --
        --ResearchTechnology(Technologies.GT_Gilds, i) --
        
        --ResearchTechnology(Technologies.GT_Literacy, i) --Bildung
        --ResearchTechnology(Technologies.GT_Printing, i) --Buchdruck
        --ResearchTechnology(Technologies.GT_Laws, i) --
        --ResearchTechnology(Technologies.GT_Library, i) --Büchereien
        
        ResearchTechnology(Technologies.GT_Mathematics, i) --Mathematik
        --ResearchTechnology(Technologies.GT_Binocular, i) -- Ferngläser
        --ResearchTechnology(Technologies.GT_Matchlock, i) --Luntenschloss
        --ResearchTechnology(Technologies.GT_PulledBarrel, i) --gezogener Lauf
            
        --ResearchTechnology(Technologies.T_ChangeWeather, i)
        --ResearchTechnology(Technologies.T_WeatherForecast,i)
        --ResearchTechnology(Technologies.T_ThiefSabotage,i) 
        --ResearchTechnology(Technologies., i)
        --ResearchTechnology(Technologies., i)
    end
end  
 
-- victory funktion muß bei coop sein 
-- Hier wird die Siegbedingung vorgegeben
function VictoryJob()
    if IsDead("P5_AI_HQ") then
        Victory();
        return true;
    end
end  

function CreateArmyOne()  
  armyOne            = {}
  
  armyOne.player     = 5
  armyOne.id         = 7
  armyOne.strength   = 3
  armyOne.position   = GetPosition("NVolk")
  armyOne.rodeLength = 500  
 
  SetupArmy(armyOne)  

  troopDescription  = {  
  maxNumberOfSoldiers     = 16,
  minNumberOfSoldiers     = 0,
  experiencePoints        = VERYLOW_EXPERIENCE,
 }

 troopDescription.leaderType = Entities.CU_Evil_LeaderBearman1  

 EnlargeArmy(armyOne,troopDescription)
 EnlargeArmy(armyOne,troopDescription)  
 
 StartCountdown(20, ControlArmyOne, true)

end


function CreateArmyTwo()  
  armeeZweite            = {}
  
  armeeZweite.player     = 5
  armeeZweite.id         = 7
  armeeZweite.strength   = 3
  armeeZweite.position   = GetPosition("NVolk")
  armeeZweite.rodeLength = 500  
 
  SetupArmy(armeeZweite)  

  troopDescription  = {  
  maxNumberOfSoldiers     = 16,
  minNumberOfSoldiers     = 0,
  experiencePoints        = VERYLOW_EXPERIENCE,
 }

 troopDescription.leaderType = Entities.CU_Evil_LeaderSkirmisher1  

 EnlargeArmy(armeeZweite,troopDescription)
 EnlargeArmy(armeeZweite,troopDescription)  
 
 StartCountdown(20, ControlArmyTwo, true)

end

function ControlArmyOne()
    --if not armyOne.created then
        --armyOne.created = not IsDead(armyOne)
        --return false
    --end
    StartCountdown(1, CreateArmyTwo, false)
    StartCountdown(7, AngriffEins, false)
end

function ControlArmyTwo()
 StartCountdown(1, CreateArmyOne, false)
 StartCountdown(7, AngriffZwei, false)
end

function AngriffEins()

 Redeploy(armyOne, GetPosition("StartPos" ), 5000);
 --Attack(armyOne,"P3_HQ")
 Sound.PlayGUISound(Sounds.fanfare,95)

end

function AngriffZwei()

 Redeploy(armeeZweite, GetPosition("P3StartPos" ), 5000);
 --Attack(armeeZweite,"HQ1")
 Sound.PlayGUISound(Sounds.fanfare,95)

end

function StartCountdown(_Limit, _Callback, _Show)
    assert(type(_Limit) == "number")
    assert( not _Callback or type(_Callback) == "function" )
 
    Counter.Index = (Counter.Index or 0) + 1
    
    if _Show and CountdownIsVisisble() then
        assert(false, "StartCountdown: A countdown is already visible")
    end
    
    Counter["counter" .. Counter.Index] = {Limit = _Limit, TickCount = 0, Callback = _Callback, Show = _Show, Finished = false}
    
    if _Show then
        MapLocal_StartCountDown(_Limit)
    end
    
    if Counter.JobId == nil then
        Counter.JobId = StartSimpleJob("CountdownTick")
    end
    
    return Counter.Index
end
 
function StopCountdown(_Id)
    if Counter.Index == nil then
        return
    end
 
    if _Id == nil then
        for i = 1, Counter.Index do
            if Counter.IsValid("counter" .. i) then
                if Counter["counter" .. i].Show then
                    MapLocal_StopCountDown()
                end
                Counter["counter" .. i] = nil
            end
        end
    else
        if Counter.IsValid("counter" .. _Id) then
            if Counter["counter" .. _Id].Show then
                MapLocal_StopCountDown()
            end
            Counter["counter" .. _Id] = nil
            i=1
        end
    end
end
 
function CountdownTick()
    local empty = true
    for i = 1, Counter.Index do
        if Counter.IsValid("counter" .. i) then
            if Counter.Tick("counter" .. i) then
                Counter["counter" .. i].Finished = true
            end
            
            if Counter["counter" .. i].Finished and not IsBriefingActive() then
                if Counter["counter" .. i].Show then
                    MapLocal_StopCountDown()
                end
                
                -- callback function
                if type(Counter["counter" .. i].Callback) == "function" then
                    Counter["counter" .. i].Callback()
                end
                
                Counter["counter" .. i] = nil
            end
            
            empty = false
        end
    end
    
    if empty then
        Counter.JobId = nil
        Counter.Index = nil
        return true
    end
end
 
function CountdownIsVisisble()
    for i = 1, Counter.Index do
        if Counter.IsValid("counter" .. i) and Counter["counter" .. i].Show then
            return true
        end
    end
    
    return false
end

function AddTribute( _tribute )
    assert( type( _tribute ) == "table", "Tribut muß ein Table sein" );
    assert( type( _tribute.text ) == "string", "Tribut.text muß ein String sein" );
    assert( type( _tribute.cost ) == "table", "Tribut.cost muß ein Table sein" );
    assert( type( _tribute.playerId ) == "number", "Tribut.playerId muß eine Nummer sein" );
    assert( not _tribute.Tribute , "Tribut.Tribute darf nicht vorbelegt sein");
    
    uniqueTributeCounter = uniqueTributeCounter or 1;
    _tribute.Tribute = uniqueTributeCounter;
    uniqueTributeCounter = uniqueTributeCounter + 1;
    
    local tResCost = {};
    for k, v in pairs( _tribute.cost ) do
        assert( ResourceType[k] );
        assert( type( v ) == "number" );
        table.insert( tResCost, ResourceType[k] );
        table.insert( tResCost, v );
    end
    
    Logic.AddTribute( _tribute.playerId, _tribute.Tribute, 0, 0, _tribute.text, unpack( tResCost ) );
    SetupTributePaid( _tribute );
    
    return _tribute.Tribute;
end  
      
--+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
--Hier werden unsere Tribute erstellt
--+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
--Tribut Packen WS0
 
function NewTribute1() 
    local tribute =  {};
    tribute.playerId = 3; 
    tribute.text = "Bietet Spieler 1 an, das Tor gegen 200 Gold zu oeffnen"; 
    tribute.cost = { Gold = 0}; 
    tribute.Callback = Tributcallback1; 
    TributId1 = AddTribute( tribute ); 
end
 
function Tributcallback1()

NewTribute2()

end

function NewTribute2()
    local tribute =  {};
    tribute.playerId = 1; 
    tribute.text = "Gebt Spieler 2 200 Gold um das Tor zu oeffnen"; 
    tribute.cost = { Gold = 200}; 
    tribute.Callback = Tributcallback2; 
    TributId1 = AddTribute( tribute ); 
end

function Tributcallback2()
AddGold( 1, -200)
AddGold( 3, 200)
ReplaceEntity ("Tor1", Entities.XD_WallStraightGate )

end


--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++



function ModelOverwrite()
   Logic.SetModelAndAnimSet(GetEntityId("steinmauer"), Models.XD_RuinWall1)
   Logic.SetModelAndAnimSet(GetEntityId("wall1"), Models.XD_Palisade1)
   Logic.SetModelAndAnimSet(GetEntityId("wall2"), Models.XD_Palisade1)
   Logic.SetModelAndAnimSet(GetEntityId("wall3"), Models.XD_Palisade1)
   Logic.SetModelAndAnimSet(GetEntityId("wall4"), Models.XD_Palisade1)
   Logic.SetModelAndAnimSet(GetEntityId("wall5"), Models.XD_Palisade1)
-- wall1-wall5 sind sprengbare Steine, die steinmauer ist eigentlich ein abbaubarer Steinhaufen.
end

function GameCallback_FulfillTribute() --Im Multiplayer sind Tribute standardmäßig deaktiviert, daher muss man sie erst wieder aktivieren
    return 1
end

mcb
#12
17.11.2018 14:59
Beiträge: 1472

Du benutzt für beide Armeen dieselbe id, wenn du die

armeeZweite.id         = 7

in

armeeZweite.id         = 8

änderst, sollte es besser funktionieren.

Narnius
#13
17.11.2018 16:37
Beiträge: 34

Oh...

Zitat von mcb:
Du benutzt für beide Armeen dieselbe id, wenn du die

armeeZweite.id         = 7

in

armeeZweite.id         = 8

änderst, sollte es besser funktionieren.



Ups.

Vielen Dank!

Seiten: 1

SiteEngine v1.5.0 by nevermind, ©2005-2007
Design by SpiderFive (www.siedler-games.de) - English translation by juja

Impressum