Problem mit Countdown in Coop map

» Siedler Map Source Forum » Siedler DEdK Script Forum » Problem mit Countdown in Coop map

Seiten: 1

Lordcerii
#1
20.05.2010 20:58
Beiträge: 51

Problem mit Countdown in Coop map

Ich hab da ein kleines Problem auf meiner Coop-map:
Mein Countdown Startet gar nicht und meine Söldnerposten funktionieren nicht.
Skriptausschnitt:
StartCountdown(900,OpenDoor,true)
--++Söldnerposten
Logic.AddMercenaryOffer( "mercant1", Entities.CU_BanditLeaderSword1, 10, ResourceType.Gold, 150, ResourceType.Iron, 200 );
Logic.AddMercenaryOffer( "mercant1", Entities.CU_BanditLeaderBow1, 10, ResourceType.Gold, 150, ResourceType.Wood, 200 );
Logic.AddMercenaryOffer( "mercant2", Entities.CU_Evil_LeaderBearman1, 10, ResourceType.Gold, 350, ResourceType.Iron, 450 );
Logic.AddMercenaryOffer( "mercant2", Entities.CU_Evil_LeaderSkirmisher1, 10, ResourceType.Gold, 300, ResourceType.Wood, 400 );

Der Skriptausschnitt ist in der function GameCallback_OnGameStart()

Kann mir wer helfen?

____________________
Schaut doch mal auf mein Profil...

Grüsse
Lord Cer II

Mordred
#2
20.05.2010 21:11
Beiträge: 939

Zitat von Lordcerii:

StartCountdown(900,OpenDoor,true)
Logic.AddMercenaryOffer( "mercant1", Entities.CU_BanditLeaderSword1, 10, ResourceType.Gold, 150, ResourceType.Iron, 200 );
Logic.AddMercenaryOffer( "mercant1", Entities.CU_BanditLeaderBow1, 10, ResourceType.Gold, 150, ResourceType.Wood, 200 );
Logic.AddMercenaryOffer( "mercant2", Entities.CU_Evil_LeaderBearman1, 10, ResourceType.Gold, 350, ResourceType.Iron, 450 );
Logic.AddMercenaryOffer( "mercant2", Entities.CU_Evil_LeaderSkirmisher1, 10, ResourceType.Gold, 300, ResourceType.Wood, 400 );

Der Skriptausschnitt ist in der function GameCallback_OnGameStart()

Kann mir wer helfen?


Also ich kenne mich mit MP maps quasi nicht aus, aber ohne den richtigen Comfort klappt garnix.
Ist der drin?

Lordcerii
#3
20.05.2010 21:15
Beiträge: 51

Comfort?

Zitat von Mordred:

Zitat von Lordcerii:

StartCountdown(900,OpenDoor,true)
Logic.AddMercenaryOffer( "mercant1", Entities.CU_BanditLeaderSword1, 10, ResourceType.Gold, 150, ResourceType.Iron, 200 );
Logic.AddMercenaryOffer( "mercant1", Entities.CU_BanditLeaderBow1, 10, ResourceType.Gold, 150, ResourceType.Wood, 200 );
Logic.AddMercenaryOffer( "mercant2", Entities.CU_Evil_LeaderBearman1, 10, ResourceType.Gold, 350, ResourceType.Iron, 450 );
Logic.AddMercenaryOffer( "mercant2", Entities.CU_Evil_LeaderSkirmisher1, 10, ResourceType.Gold, 300, ResourceType.Wood, 400 );

Der Skriptausschnitt ist in der function GameCallback_OnGameStart()

Kann mir wer helfen?


Also ich kenne mich mit MP maps quasi nicht aus, aber ohne den richtigen Comfort klappt garnix.
Ist der drin?


Was meinst du mit Comfort? Und welche Art von Comfort?
Also das basisskript hab ich einfach aus der wiki kopiert:
Hier Klicken

____________________
Schaut doch mal auf mein Profil...

Grüsse
Lord Cer II

warrior1024
#4
20.05.2010 21:22
Beiträge: 345

Bevor du gleich bei jedem Problem im Forum nachfragst:
http://www.siedler-games.de/si...als:fehlermeldungen_aktivieren

Und ich fürchte, dass würde zu einem Desync führen, wenn ich das richtig verstanden habe:
Nach Ablauf der Zeit wird auf beiden Rechnern das Söldnerlager gefühlt, alles noch in Ordnung.
Dann kommt aber ein Spieler, drückt auf den Button, um Einheiten zu kaufen und siehe da:
Auf dem einen PC wird die Truppe erstellt, auf anderen nicht->Desync
Aber da ich von MP-Scripting fast keine Ahnung habe, sollte das lieber von Anarki bestätigt/widerlegt werden.

Und noch was:
http://www.siedler-maps.de/forum/Siedler-Map-Source/BBCodes-29.htm
Mit [code]Hier könnte ihre Werbung stehen! [/code] kannst du Skript posten. Das sieht dann so aus:

Hier könnte ihre Werbung stehen! :)


Siehst du, kein Smiley.

warrior1024

Edit:
http://www.siedler-games.de/si.../tutorials:countdown_zeitlimit
Ganz unten ist der Code, den du brauchst.

Edit2:
War schneller, Mordred

____________________
"Banken machen keine Fehlentscheidungen! Haben Euch das Eure Eltern nicht beigebracht?"
- Bankier Samael Silren, Enderal

Mordred
#5
20.05.2010 21:22
Beiträge: 939

Na dann ists ja klar dass es nicht klappt.

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


Das hier muss noch rein.

Lordcerii
#6
20.05.2010 21:27
Beiträge: 51

Zitat von warrior1024:


Und ich fürchte, dass würde zu einem Desync führen, wenn ich das richtig verstanden habe:
Nach Ablauf der Zeit wird auf beiden Rechnern das Söldnerlager gefühlt, alles noch in Ordnung.

Edit:
http://www.siedler-games.de/si.../tutorials:countdown_zeitlimit
Ganz unten ist der Code, den du brauchst.


Nein, nach dem Countdown soll die function OpenDoor() ausgeführt werden...

____________________
Schaut doch mal auf mein Profil...

Grüsse
Lord Cer II

Lordcerii
#7
20.05.2010 21:28
Beiträge: 51

Zitat von Mordred:
Na dann ists ja klar dass es nicht klappt.

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


Das hier muss noch rein.


WOW, darum funktionierts also net!
Aber was is mit den Söldnerposten...
Da steht nur: AUSVERKAUFT

____________________
Schaut doch mal auf mein Profil...

Grüsse
Lord Cer II

Dieser Beitrag wurde von Lordcerii am 21.05.2010 um 11:40 editiert.

warrior1024
#8
20.05.2010 21:30
Beiträge: 345

Trotzdem wird das Söldnerlager erstellt, dass bei Interaktion mit dem Spieler wie beschrieben für Desync sorgt.

warrior1024

Edit:
Du hast Skriptnamen angegeben, brauchst aber Skript-IDs.
Auf den ersten Blick müsste es so gehen:

Logic.AddMercenaryOffer( GetEntityId("mercant1"), Entities.CU_BanditLeaderSword1, 10, ResourceType.Gold, 150, ResourceType.Iron, 200 );
Logic.AddMercenaryOffer( GetEntityId("mercant1"), Entities.CU_BanditLeaderBow1, 10, ResourceType.Gold, 150, ResourceType.Wood, 200 );
Logic.AddMercenaryOffer( GetEntityId("mercant2"), Entities.CU_Evil_LeaderBearman1, 10, ResourceType.Gold, 350, ResourceType.Iron, 450 );
Logic.AddMercenaryOffer( GetEntityId("mercant2"), Entities.CU_Evil_LeaderSkirmisher1, 10, ResourceType.Gold, 300, ResourceType.Wood, 400 );



____________________
"Banken machen keine Fehlentscheidungen! Haben Euch das Eure Eltern nicht beigebracht?"
- Bankier Samael Silren, Enderal

Mordred
#9
20.05.2010 21:34
Beiträge: 939

Comforts sind Funktionen mit sog. Parametern.
Du kannst sie ganz normal aufrufen.
Und das heißt, wenn sie nicht im Skript stehen, kannst du sie nicht aufrufen.
ein Beispiel für Comforts:

function Lordceriis_Nachricht()
 Message("Hallo!")
end


wenn du diesen sog. "Job" (wird nur einmal ausgeführt) mit

 Lordceriis_Nachricht()


aufrufst, dann gibt das Spiel eine Nachricht "Hallo" aus.
Diese Funktion hat keine Parameter.
Das kann man aber ändern.

function Lordceriis_Nachricht(_ParamterDessenNameEgalIst)
 Message("Hallo!")
end


Nun hast du dieselbe funktion, in der nun eine sog. "lokale Variable" enthalten ist, und zwar

 _ParamterDessenNameEgalIst


diese Funktion "musst" du nun so aufrufen:

 Lordceriis_Nachricht(99)


Da der Parameter nicht verwendet wird, kannst du ihn genausogut weglassen.
Aber:
Du kannst ihn auch verwenden!

function Lordceriis_Nachricht(_Paramter)
 Message("Du hast ".._Paramter.." eingegeben.")
end


So, nun wird der Parameter verwendet.

 Lordceriis_Nachricht(99)
  -- Ausgabe:
 "Du hast 99 eingegeben."
  -- mal was anderes:
 Lordceriis_Nachricht("Hallo")
  -- Ausgabe:
 "Du hast Hallo eingegeben."


Damit kannst du primitive funktionen machen, aber auch richtig komplexe --> So wie der Countdown zum Beispiel.
Das heißt, wenn er nicht im Skript steht, dann gibts ihn halt nicht.
Alle Funktionen, die du so aufrufen kannst, zb.

 Message("Hallo!")


sind schon im Spiel enthalten; nämlich in

 Script.Load(Folders.MapTools.."Main.lua")


Ich hoffe es hat dir grob die Funktion von Comforts erklärt, sonst - PN
Lg, Mordred

nevermind
Siedler Map Source Admin (Web)
#10
20.05.2010 21:43
Beiträge: 483

Zitat von warrior1024:
Trotzdem wird das Söldnerlager erstellt, dass bei Interaktion mit dem Spieler wie beschrieben für Desync sorgt.



Demnach würden auch Truppen in den eigenen Kasernen nur auf deinem Rechner erzeugt?

Die Klicks auf solche Buttons sind zwar lokal, aber der entsprechende Callback ruft dann eine GUI Funktion auf, in diesem Fall GUI.BuyMerchantOffer(). Das "tolle" an GUI Funktionen ist, dass sie auch im Multiplayer funktionieren und das Spiel mit den anderen Teilnehmern synchronisiert wird. Mit Logic Funktionen funktioniert das leider nicht.

____________________
LUA_ERRSYNTAX: [string "?"]:1: `=' expected near `<eof>'

Lordcerii
#11
21.05.2010 08:17
Beiträge: 51

Zitat von Mordred:
Comforts sind Funktionen mit sog. Parametern.
Du kannst sie ganz normal aufrufen.
Und das heißt, wenn sie nicht im Skript stehen, kannst du sie nicht aufrufen.
ein Beispiel für Comforts:

function Lordceriis_Nachricht()
 Message("Hallo!")
end


wenn du diesen sog. "Job" (wird nur einmal ausgeführt) mit

 Lordceriis_Nachricht()


aufrufst, dann gibt das Spiel eine Nachricht "Hallo" aus.
Diese Funktion hat keine Parameter.
Das kann man aber ändern.

function Lordceriis_Nachricht(_ParamterDessenNameEgalIst)
 Message("Hallo!")
end


Nun hast du dieselbe funktion, in der nun eine sog. "lokale Variable" enthalten ist, und zwar

 _ParamterDessenNameEgalIst


diese Funktion "musst" du nun so aufrufen:

 Lordceriis_Nachricht(99)


Da der Parameter nicht verwendet wird, kannst du ihn genausogut weglassen.
Aber:
Du kannst ihn auch verwenden!

function Lordceriis_Nachricht(_Paramter)
 Message("Du hast ".._Paramter.." eingegeben.")
end


So, nun wird der Parameter verwendet.

 Lordceriis_Nachricht(99)
  -- Ausgabe:
 "Du hast 99 eingegeben."
  -- mal was anderes:
 Lordceriis_Nachricht("Hallo")
  -- Ausgabe:
 "Du hast Hallo eingegeben."


Damit kannst du primitive funktionen machen, aber auch richtig komplexe --> So wie der Countdown zum Beispiel.
Das heißt, wenn er nicht im Skript steht, dann gibts ihn halt nicht.
Alle Funktionen, die du so aufrufen kannst, zb.

 Message("Hallo!")


sind schon im Spiel enthalten; nämlich in

 Script.Load(Folders.MapTools.."Main.lua")


Ich hoffe es hat dir grob die Funktion von Comforts erklärt, sonst - PN
Lg, Mordred



Hey danke gute Erklärung!

____________________
Schaut doch mal auf mein Profil...

Grüsse
Lord Cer II

Lordcerii
#12
21.05.2010 08:22
Beiträge: 51

Zitat von nevermind:

Zitat von warrior1024:
Trotzdem wird das Söldnerlager erstellt, dass bei Interaktion mit dem Spieler wie beschrieben für Desync sorgt.



Demnach würden auch Truppen in den eigenen Kasernen nur auf deinem Rechner erzeugt?

Die Klicks auf solche Buttons sind zwar lokal, aber der entsprechende Callback ruft dann eine GUI Funktion auf, in diesem Fall GUI.BuyMerchantOffer(). Das "tolle" an GUI Funktionen ist, dass sie auch im Multiplayer funktionieren und das Spiel mit den anderen Teilnehmern synchronisiert wird. Mit Logic Funktionen funktioniert das leider nicht.



Cool, also muss ich local. nur durch GUI. ersetzen?

Is ja simpel!

____________________
Schaut doch mal auf mein Profil...

Grüsse
Lord Cer II

Anarki
#13
21.05.2010 18:19
Beiträge: 518

nicht local sondern die Logic.X Funktionen sind gemeint.

So einfach ist das auch nicht, wie du gerade gejubelt hast
Du wirst wohl mit wachsender Skripterfahrung schon Wissen was hier gemeint ist.

Viel Erfolg bei der Koop-Map, davon gibt es viel zu wenige!
Lass dich nicht entmutigen - bei auftretenden Desyncs sag einfach hier im Forum bescheid - ich kenne eine Methode diese zu verhindern.

____________________
Siedler V Tool: Selbstextrahierende Maps erstellen
Bitte testen und kommentieren

Seiten: 1

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

Impressum