using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Otter; using _1869_Remake; using _1869_Remake.Scenes; namespace _1869_Remake.Entities { public class Hafen : Entity { //ToDo Waren Restock logik ausbauen -> Wie wird Schablone Daten entnommen sodass wir oder Hafen weiß welche Waren zu welchem Einkaufspreis in welcher Menge zu welchem Monat nachgefüöllt werden public string NAME { get; set; } public string KÖNIGREICH { get; set; } //Mögliches Feature an dieser Stelle für das Remake -> Wandelnder Hauptexport und generell Wandelnde Export/Import Güter, //je nachdem wie die Spieler diese Häfen mit Waren Versorgen //Beispiel wenn Spieler A immer wieder zu den selben 3 Häfen fährt und die selben Rohstoffe liefert wird der Bedarf an diesen jeweiligen //Waren gedeckt sein und der Verkaufspreis sinkt bis hin zu keinem Import dieser Ware mehr //Dieses Feature würde dazu führen, dass die Spieler Überlegen müssen wo sie hinfahren und wie oft sie dort hinfahren //Nachteil -> sehr feines Balancing notwendig da eine Art Grundbedarf von Gütern für ein Land eingebaut werden muss //(Aber machbar da die Ur-Entwickler sich viel Mühe mit den historischen Daten gegeben haben -> die Bedürfnisse können davon extrahiert werden public string HAUPTEXPORT { get; set; } public string POLITIK { get; set; } //Aktiv => wenn Symbolleiste nach einem Click auf Hafen für den Spieler angezeigt wird // Wenn geklickt und nicht aktiv => anzeige des Infoscreens public bool Aktiv; public bool istAktivesSubelement = false; //Um zu verhindern dass bei jedem Update die Icons immer wieder neu angezeigt werden wird einmalig anzeigeFertig gesetzt; Wenn False dann anzeige verändern public bool anzeigeFertig; public bool werftVorhanden; public Dictionary SchiffsBauPipeline; public bool filialeVorhanden; public bool eigenesSchiffLiegtVorAnker; //Liste aller aktuell im Hafen befindlicher Schiffe (Eventuel im Remake eine Kapazität für die Menge an Schiffen einbauen -> Nicht jeder Hafen kann unendlich viele Schiffe herbergen) public List angedockteSchiffe = new List(); public int anzahlEigenerSchiffe = 0; //Liste aller Filialen in diesem Hafen public List vorhandeneFilialen = new List(); //Jeder Hafen hat ein internes Lager. Bei Start und zeitlich getriggert werden Import und export waren mit festen mengen neu gesetzt //Unterscheidung von Import schablonen und Export schablonen -> bei Nachfüllen muss über beide Listen gegangen werden public List IMPORTWARE = new List(); public Dictionary> RESTOCKSCHABLONEIMPORT = new Dictionary>(); public List EXPORTWARE = new List(); public Dictionary> RESTOCKSCHABLONEEXPORT = new Dictionary>(); public Image InfoIcon = new Image(Assets.HAFENINFO); public Image WerftIcon = new Image(Assets.HAFENWERFT); public Image BarIcon = new Image(Assets.HAFENBAR); public Image FilialeIcon = new Image(Assets.HAFENFILIALE); public Image Fähnchen = new Image(Assets.HAFENFAHNE); public Image Schiffchen = new Image(Assets.HAFENSCHIFF); public Image InfoScreen = new Image(Assets.MAINSCREEN_INFO_SCHABLONE); private bool FadeOutAktiv = false; private string FadeOutZiel; private string FadeOutParam; public Image BlackScreen = new Image(Assets.BLACKSCREEN); public Hafen() { } public Hafen(string Name, string Land, int xPos, int yPos, bool Werft) { this.NAME = Name; this.KÖNIGREICH = Land; Aktiv = false; anzeigeFertig = true; werftVorhanden = Werft; //Position auf der Weltkarte -> aus der Position erstellt die Weltkarte die Clickbereiche this.X = xPos; this.Y = yPos; InfoIcon.X = -60; InfoIcon.Y = -60; InfoIcon.Alpha = 0; AddGraphics(InfoIcon); BarIcon.X = -20; BarIcon.Y = -60; BarIcon.Alpha = 0; AddGraphics(BarIcon); //Pauschales hinzufügen des Filialen Icons damit dieses später bei Bedarf eingeblendet werden kann if (Werft) { WerftIcon.X = 20; WerftIcon.Y = -60; WerftIcon.Alpha = 0; AddGraphics(WerftIcon); //Filialne Icon FilialeIcon.X = 60; } else { FilialeIcon.X = 20; } FilialeIcon.Y = -60; FilialeIcon.Alpha = 0; AddGraphics(FilialeIcon); //Immer an de selben Position rendern nicht relativ zum Hafen selbst InfoScreen.Relative = false; InfoScreen.X = 50; InfoScreen.Y = 55; InfoScreen.Alpha = 0; AddGraphics(InfoScreen); //Fähnchen wenn man eine Filiale in dem Hafen besitzt Fähnchen.X = 5; Fähnchen.Y = -17; Fähnchen.Alpha = 0; AddGraphic(Fähnchen); //Schiffchen Icon setzen (Hat eigene Position je nachdem welcher Hafen das ist) #region SchiffchenPositionen je Hafen switch (NAME) { //Amerika case "SAN FRANZISKO": break; case "NEW ORLEANS": break; case "SAVANNAH": break; case "NEW YORK": break; case "LOS ANGELES": break; case "PUERTO BELLO": break; case "CEYENNE": break; case "CALLAO": break; case "ARICA": break; case "RIO DE JANEIRO": break; //Afrika case "AKKRA": break; case "LAGOS": break; case "LUANDA": break; case "KAPSTADT": break; case "MOCAMBIQUE": break; case "TANGA": break; case "PORT SAID": break; case "ADEN": break; case "TUNIS": break; //Europa case "ODESSA": break; case "TRIEST": break; case "BARCELONA": break; case "LISSABON": break; case "LE HAVRE": break; case "AMSTERDAM": break; case "HAMBURG": break; case "LONDON": break; case "LIVERPOOL": setzeSchiffsIcon(-30, -5); break; //Asien/Australien case "DIU": break; case "BOMBAY": break; case "COLOMBO": break; case "RANGOON": break; case "MACAO": break; case "SHANGHAI": break; case "SINGAPORE": break; case "MANDAO": break; case "PERTH": break; case "MELBOURNE": break; case "SIDNEY": break; } #endregion Globals.registriereEntität(this); } public override void Update() { base.Update(); //TODO: KlickLogik anpassen wegen SubElement aktiv (Darf immer nur ein Element geklickt und aktiv geschaltet werden) //Einblenden der Icons if (!anzeigeFertig) { //überprüfen was angezeigt werden muss => wenn spieler Filiale oder Schiff hier hat muss Hafenorte angezeigt werden(Icons) wenn nicht dann info screen if (Aktiv) { //anzeige der Icons InfoIcon.Alpha = 1; BarIcon.Alpha = 1; if (werftVorhanden) { WerftIcon.Alpha = 1; } if (filialeVorhanden) { FilialeIcon.Alpha = 1; } } else { //InfoScreen anzeige InfoScreen.Alpha = 1; //Während Infoscreen keine Fähnchen oder Schiffchen anzeigen (Global) for (int index = 0; index < Globals.AlleHäfen.Count(); index++) { Globals.AlleHäfen.ElementAt(index).Value.Fähnchen.Alpha = 0; Globals.AlleHäfen.ElementAt(index).Value.Schiffchen.Alpha = 0; } } //Wenn alles aktiviert dann nicht wieder Zeichnen anzeigeFertig = true; } //Click auf den Hafen verursacht anzeige von Icons oder Infoscreen zu Hafen if (Util.InRect(this.Scene.MouseX, this.Scene.MouseY, X - 10, Y - 10, 20, 20)) { if (Globals.PlayerSession.Controller.Button("MausLinks").Released && !Globals.DisplaySubElementAktiv && !Aktiv) { Console.Clear(); Console.WriteLine("Hafen " + NAME + " geclicked! "); if (checkVerfügbareIcons(Globals.AktuellerSpieler)) { this.FadeOutZiel = "Handel"; this.FadeOutParam = this.NAME; this.FadeOutAktiv = true; //Wenn Wechsel zu andereer Szene werden Fähnchen und Schiffchen nicht angezeigt for (int index = 0; index < Globals.AlleHäfen.Count(); index++) { Globals.AlleHäfen.ElementAt(index).Value.Fähnchen.Alpha = 0; Globals.AlleHäfen.ElementAt(index).Value.Schiffchen.Alpha = 0; } } else { //Infoscreen wird geladen Wenn Linksklick ohne Filiale oder Schiff im Hafen anzeigeFertig = false; Aktiv = false; for (int index = 0; index < Globals.AlleHäfen.Count(); index++) { Globals.AlleHäfen.ElementAt(index).Value.Fähnchen.Alpha = 0; Globals.AlleHäfen.ElementAt(index).Value.Schiffchen.Alpha = 0; } } //Wenn kein SubelementAktiv ist und dieser Hafen aktiviert wurde muss globale Klick Logik auf dieser Entitäten Fokusiert bleiben Globals.DisplaySubElementAktiv = true; istAktivesSubelement = true; } if (Globals.PlayerSession.Controller.Button("MausRechts").Released && !Globals.DisplaySubElementAktiv && !Aktiv) { Console.Clear(); Console.WriteLine("Hafen " + NAME + " geclicked! "); //überprüfen, ob icons oder info angezeigt wird + überprüfen ob klickender hier eine filiale hat -> Wenn ja wird filiale Icon mit angezeigt Aktiv = checkVerfügbareIcons(Globals.AktuellerSpieler); anzeigeFertig = false; //Wenn kein SubelementAktiv ist und dieser Hafen aktiviert wurde muss globale Klick Logik auf dieser Entitäten Fokusiert bleiben Globals.DisplaySubElementAktiv = true; istAktivesSubelement = true; } } else { //Wenn nicht auf den Hafen geklickt -> erst überprüfen ob Klick einem Icon galt (Wenn zu vor Icons angezeigt wurden) if (Globals.PlayerSession.Controller.Button("MausLinks").Released && istAktivesSubelement) { if (Aktiv) { //Icons sind aktiv -> check, ob click einem Icon galt if (Util.InRect(this.Scene.MouseX, this.Scene.MouseY, X - 60, Y - 80, 40, 50) ) { Console.WriteLine("Infoicon geklicked!"); anzeigeFertig = false; Aktiv = false; } if (Util.InRect(this.Scene.MouseX, this.Scene.MouseY, X - 20, Y - 80, 40, 50) ) { Console.WriteLine("Baricon geklicked!"); this.FadeOutZiel = "Bar"; this.FadeOutParam = this.NAME; this.FadeOutAktiv = true; } if (werftVorhanden) { if (Util.InRect(this.Scene.MouseX, this.Scene.MouseY, X + 20, Y - 80, 40, 50) ) { Console.WriteLine("Werfticon geklicked!"); this.FadeOutZiel = "Werft"; this.FadeOutParam = this.NAME; this.FadeOutAktiv = true; } } if (filialeVorhanden) { if (werftVorhanden) { //Rechte Filialposition (Wenn Werft dabei) if (Util.InRect(this.Scene.MouseX, this.Scene.MouseY, X + 60, Y - 80, 40, 50) ) { Console.WriteLine("Filialeticon geklicked!"); this.FadeOutZiel = "Filiale"; this.FadeOutParam = this.NAME; this.FadeOutAktiv = true; } } else { //Linke Filialposition (wenn Werft nicht vorhanden) if (Util.InRect(this.Scene.MouseX, this.Scene.MouseY, X + 20, Y - 80, 40, 50)) { Console.WriteLine("Filialeticon geklicked!"); this.FadeOutZiel = "Filiale"; this.FadeOutParam = this.NAME; this.FadeOutAktiv = true; } } } Console.WriteLine("Hafen " + NAME + " weg geclicked! "); filialeVorhanden = false; // check ob filiale hier wirklich deaktiviert wird!!! Aktiv = false; //Wenn weggeklickt wurde dann alle Graphicen unsichtbar schalten InfoIcon.Alpha = 0; BarIcon.Alpha = 0; WerftIcon.Alpha = 0; FilialeIcon.Alpha = 0; } else { //keine Icons wurden angezeigt -> Wegclicken des infoscreens InfoScreen.Alpha = 0; for (int index = 0; index < Globals.AlleHäfen.Count(); index++) { Globals.AlleHäfen.ElementAt(index).Value.aktiviereFähnchen(Globals.AktuellerSpieler); Globals.AlleHäfen.ElementAt(index).Value.aktiviereSchiffsIcon(Globals.AktuellerSpieler); } } //Wenn SubelementAktiv ist muss globale Klick Fokus wieder frei gegeben werden Globals.DisplaySubElementAktiv = false; istAktivesSubelement = false; } } } public void setzeRestockListe(string Monat, Ware Item, string richtung) { //Schablone wird nur einmal gesetzt in Config und bei Spielstandladung!! //Überprüfung: Wenn einer neuen Monatsliste etwas hinzugefügt werden soll, muss diese erst erstellt werden //TODO: Wenn Mitte des Monats sachen hinzugefügt werden sollen muss in Ware neues Feld"RestockTag" hinzugefügt und hier eine Routine zu dessen Verwaltung eingebaut werden switch (richtung) { case "IMPORT": if (!RESTOCKSCHABLONEIMPORT.ContainsKey(Monat)) { RESTOCKSCHABLONEIMPORT.Add(Monat, new List()); } RESTOCKSCHABLONEIMPORT[Monat].Add(Item); break; case "EXPORT": if (!RESTOCKSCHABLONEEXPORT.ContainsKey(Monat)) { RESTOCKSCHABLONEEXPORT.Add(Monat, new List()); } RESTOCKSCHABLONEEXPORT[Monat].Add(Item); break; } } public void NeuAuffüllenLager(string reStockMonat) {// jeder Hafen arbeitet mit der Logik, dass zu einem Gewissen Datum eine gewisse Ware um eine bestimmte Menge "restockt" wird //-> Beispiel in Tunis wird Jeden Januar, April und Oktober Früchte nachgestockt und im März und September Pflanzen öl // zu untersuchen gilt folgendes: Ändern sich die verkaufs/einkaufspreise bei den Waren wenn sie "Knapper" werden in HafenLager // für restock balancing UNBEDINGT das Handbuch lesen-> Wahrscheinlich stehen hier tipps oder hinweise zu den Zyklen der Häfen drin !!! // Was wann um wie viel aufgestockt wird, wird bei obj erstellung definiert List TempWare; //Hier werden alte Bestände gelöscht (Muss überprüft werden ob bei nicht verderblichen Waren nach ReStock die alte Menge noch existiert[würde Sinn machen da Maschinen nicht verderben]) //IMPORT-Schablonen TempWare = new List(RESTOCKSCHABLONEIMPORT[reStockMonat]); foreach (Ware item in TempWare) { //überprüfen ob noch Restbestände in der Liste sind( EVTL durch testen ob bei restmenge und nachstockung die Menge sich erhöht oder neu setzt auf default!!) for (int i = 0; i < IMPORTWARE.Count(); i++) { Ware vergleichItem = IMPORTWARE[i]; if (vergleichItem.BEZEICHNUNG == item.BEZEICHNUNG) { IMPORTWARE.RemoveAt(i); } } // Neu Hinzufügen der Schablone IMPORTWARE.Add(new Ware(item)); } //EXPORT-Schablonen TempWare = new List(RESTOCKSCHABLONEEXPORT[reStockMonat]); foreach (Ware item in TempWare) { //überprüfen ob noch Restbestände in der Liste sind( EVTL durch testen ob bei restmenge und nachstockung die Menge sich erhöht oder neu setzt auf default!!) for (int i = 0; i < EXPORTWARE.Count(); i++) { Ware vergleichItem = EXPORTWARE[i]; if (vergleichItem.BEZEICHNUNG == item.BEZEICHNUNG) { EXPORTWARE.RemoveAt(i); } } // Neu Hinzufügen der Schablone EXPORTWARE.Add(new Ware(item)); } } public void politischeVeränderung(string Zustand) { switch (Zustand) { //Zustandsspezifische Ereignisse case "STABIL": POLITIK = Zustand; break; case "UNRUHEN": POLITIK = Zustand; break; case "AUFSTÄNDE": POLITIK = Zustand; break; case "KRIEG": POLITIK = Zustand; break; } } private bool checkVerfügbareIcons(Spieler anfragenderSpieler) { // Methode zur ermittlung ob Icons oder info screen gezeigt wird //True = Icons, False = Info //Überprüfen aller Filialen im Hafen auf Besitzer foreach (Filiale f in vorhandeneFilialen) { if (f.BESITZER == anfragenderSpieler) { filialeVorhanden = true; return true; } } //Überprüfen aller angedockten Schiffe auf deren Commandeure(Spielerzugehörigkeit) foreach (Schiff s in angedockteSchiffe) { if (s.COMMANDEUR == anfragenderSpieler) { eigenesSchiffLiegtVorAnker = true; anzahlEigenerSchiffe++; } } if (eigenesSchiffLiegtVorAnker) return true; else return false; } public Filiale überprüfeAktuelleFilialeVorhanden(Spieler anfrageSpieler) { // Überprüfen ob eigene Filiale vorhanden ist foreach (Filiale f in vorhandeneFilialen) { if (f.BESITZER == anfrageSpieler) { filialeVorhanden = true; return f; } } //Wenn es keine eigene aktive Filiale im Hafen gibt filialeVorhanden = false; return null; } public List überprüfeEigeneSchiffeVorhanden(Spieler anfrageSpieler) { //Überprüfen, ob und welche eigenen schiffe im Hafen angedockt sind List Schiffsliste = new List(); foreach (Schiff s in angedockteSchiffe) { if (s.COMMANDEUR == anfrageSpieler) { eigenesSchiffLiegtVorAnker = true; Schiffsliste.Add(new Schiff(s)); } } if (Schiffsliste.Count() > 0) return Schiffsliste; else //Wenn es keine eigene aktive Filiale im Hafen gibt return null; } // Methode zur Verwaltung der Filialen im Hafen public void filialenAktivität(int ereignis, Filiale betroffeneFiliale) { //Ereignis 1 => Filiale wird gegründet //Rest => Filiale wird aufgelöst if (ereignis == 1) { //Wenn Filiale noch nicht in der Liste -> gründung der Filiale if (!vorhandeneFilialen.Contains(betroffeneFiliale)) { vorhandeneFilialen.Add(betroffeneFiliale); } } else { //Löschen der Filiale bei Auflösung if (vorhandeneFilialen.Contains(betroffeneFiliale)) { vorhandeneFilialen.Remove(betroffeneFiliale); } } } // Methode zur Verwaltung der Schiffe im Hafen public void schiffsAktivität(string richtung, Schiff betroffenesSchiff) { //Richtung 1 => Schiff fährt in den Hafen //Rest => Schiff fährt aus dem Hafen if (richtung == "Einfahren") { //Schiff fährt in den Hafen => ist jetzt angedockt //Überprüfung ob schiff bereits angedockt ist um fehler zu vermeiden if (!angedockteSchiffe.Contains(betroffenesSchiff)) { angedockteSchiffe.Add(betroffenesSchiff); } } else { //Schiff fährt aus dem Hafen => ist nicht mehr angedockt if (angedockteSchiffe.Contains(betroffenesSchiff)) { angedockteSchiffe.Remove(betroffenesSchiff); } } } public void prüfeExternerFadeOut(out string Ziel, out string Param) { bool FadeOut = this.FadeOutAktiv; if (FadeOut) { Ziel = this.FadeOutZiel; Param = this.FadeOutParam; } else { Ziel = "Error"; Param = "Error"; } } public void resetFadeOut() { this.FadeOutAktiv = false; } public void aktiviereFähnchen(Spieler aktuellerSpieler) { //aktiviere das Fähnchen Symbol wenn eine Filiale für den Aktuellen Spieler im Hafen existiert Fähnchen.Alpha = 0f; foreach (Filiale f in vorhandeneFilialen) { if (f.BESITZER == aktuellerSpieler) { Fähnchen.Alpha = 1f; break; } } } public void aktiviereSchiffsIcon(Spieler aktuellerSpieler) { //aktiviere das Schiffchen Symbol wenn mind. 1 Schiff des aktuellen Spielers im Hafen angedockt ist Schiffchen.Alpha = 0f; foreach (Schiff s in angedockteSchiffe) { if (s.COMMANDEUR == aktuellerSpieler && s.inBau == false && s.inBereitstellung == false) { Schiffchen.Alpha = 1f; break; } } } public void setzeSchiffsIcon(int xPos, int yPos) { Schiffchen.X = xPos; Schiffchen.Y = yPos; Schiffchen.Alpha = 0f; AddGraphic(Schiffchen); } } }