You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
486 lines
19 KiB
C#
486 lines
19 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using Otter;
|
|
using _1869_Remake;
|
|
|
|
namespace _1869_Remake.Entities
|
|
{
|
|
public class Schiff : Entity
|
|
{
|
|
//Eventuell eine Auflistung machen von den Verschiedenen Schiffstypen hier und andere Entitäten davon objekte erstellen lassen
|
|
//Hinweis: Wenn waren eingeladert/ausgelagert werden, die NICHT verderblich sind kann gefahrlos immer nur ein Objekt dieser Ware in der Ladeliste stehen bleiben.
|
|
//Problematisch wird es bei Verderblichen Sachen -> Hier muss mit dem Verderblich kennzeichen der Ware gearbeitet werden damit bei Ankauf und Verkauf der Ware richtiges Handling stattfindet
|
|
//-> Bei einkauf: Immer neue Objekte erstellen und Einkaufspreis ist abhängig von Verderbtheitsgrad
|
|
//-> Bei Verkauf: Durchlauf der gesamten Ware und verkauf aller Exemplare dieser Ware; Verkaufspreis ist wie bei Einkaufspreis abhängig von Verderbtheitsgrad -> Alle Warenexemplare müssen mit ihrem jeweiligen Verderbtheitsmultiplikator verrechnet werden und als Angebotspreis angeboten werden.
|
|
//-> Preisberechnung sollte immer vom Hafen aus erfolgen um Kosten/Wert zentral berechnen zu lassen
|
|
|
|
//-> Schiffe sind wie eigene Filiale, die aber nicht Hafengebunden sind (und eventuell Kampfgefährt im Freibeuter modus)
|
|
|
|
#region Schiffsbasis Vars
|
|
// Name des Schiffs
|
|
public string NAME;
|
|
// Besitzer des Schiffs
|
|
public Spieler COMMANDEUR;
|
|
|
|
//Zustandseigenschaften des Schiffs
|
|
// SCHIFFSTYP beschreibt die Art von Schiff -> Es gibt unterkategorien jedoch wird der hier eingetragene Wert größtenteils generalisiert
|
|
public string SCHIFFSTYP;
|
|
// Mögliche Baumaterialien
|
|
// HOLZ
|
|
// EISEN
|
|
public string BAUMATERIAL;
|
|
//Anzahl Kabinen für Passagiere
|
|
public int KABINEN;
|
|
//Größe des Lagerraums(in Tonnen)
|
|
public int LADERAUM;
|
|
// Bauzeit -> Wird von Werftklasse benötigt für ermittlung der benötigten Bauzeit
|
|
public int LIEFERZEIT;
|
|
// Wird bei errichten des Schiffes gesetzt und be jedem Jahr hochgezählt -> Schiffe mit hohem alter haben höhere Wahrscheinlichkeit kaputt zu gehen
|
|
public int ALTER;
|
|
// Maximal Mögliche Geschwindigkeit (Ohne Abzüge durch äußere Einflüsse)
|
|
public int OPTIMALSPEED;
|
|
//Altags-Schiffszustände
|
|
public int ZUSTAND_GEFLUTET;
|
|
public int ZUSTAND_VERMUSCHELT;
|
|
public int ZUSTAND_TAKELAGE;
|
|
public string angedocktAnHafen;
|
|
public DateTime FERTIGSTELLUNGSDATUM;
|
|
public bool inBau = false;
|
|
public bool inBereitstellung = false;
|
|
public bool inReparatur = false;
|
|
#endregion
|
|
|
|
#region Geldspezifischen Vars
|
|
// Neuwert, den Werften für das Bauen des Schiffes oder für ein <1 Jahre altes Schiff verlangen werden
|
|
public int NEUWERT;
|
|
public int ANZAHLUNGSPREIS;
|
|
// Tatsächliche Preis der zuletzt für dieses Schiff bezahlt wurde
|
|
public int VERKAUFSWERT;
|
|
// Kasse des Schiffs -> Hiervon wird Sold der Crew und geschäfte mit Häfen über das Schiff verrechnet
|
|
public int SCHIFFSBUDGET;
|
|
// Laufende Kosten durch Crew -> wenn Schiffsbudget nicht groß genug ist für nächste Reise wird crew streiken (Außnahme erste Reise nach Rekrutierung der Crew)
|
|
public int BESATZUNGSKOSTEN;
|
|
public int RESTBETRAGKAUFPREIS;
|
|
public bool bezahlt = false;
|
|
#endregion
|
|
|
|
#region Ladungsspezifische Vars
|
|
// Liste der geladenen Waren
|
|
public List<Ware> LADUNG = new List<Ware>();
|
|
#endregion
|
|
|
|
#region Mannschafts Vars
|
|
// Indikator, ob eine Crew vorhanden ist
|
|
public bool MANNSCHAFT_VORHANDEN;
|
|
public bool MANNSCHAFT_UNTERWEGS;
|
|
// Indikator, wie erfahren Crew ist -> Erfahrene Crew erhält weniger Malus auf Reise und nutzt das Schiff nicht so stark ab
|
|
public int MANNSCHAFT_ERFAHRUNG;
|
|
// Indikator, wie ausgelaugt Crew ist -> Wenn Fittness zu niedrig für nächste Reise, wird Crew streiken (Außnahme erste Reise nach Rektrutierung der Crew))
|
|
public int MANNSCHAFT_VITALITÄT;
|
|
// Indikator für Befehlsgewalt des Captains -> Je nach Abstufung wird Schiff schneller befördert oder nicht (schneller = mehr VITALITÄTSVERLUST & mehr Abnutzung)
|
|
public string KAPITÄNSORDER;
|
|
// Maximale Besatzungsgröße
|
|
public int MANNSCHAFT_MAXGRÖßE;
|
|
#endregion
|
|
|
|
//Standardkonstruktor
|
|
public Schiff()
|
|
{
|
|
|
|
}
|
|
|
|
//ParameterKontruktor
|
|
public Schiff(string Name, string Typ, int Alter, Spieler Commandeur = null)
|
|
{
|
|
this.NAME = Name;
|
|
|
|
this.ALTER = Alter;
|
|
if(ALTER > 0)
|
|
{
|
|
//Wenn Alter gesetzt ist muss das theoretische Fertigstellungsdatum errechnet werden
|
|
FERTIGSTELLUNGSDATUM = Globals.AktuellesDatum-new TimeSpan(ALTER*365,0,0,0);
|
|
|
|
}
|
|
if (Commandeur != null)
|
|
this.COMMANDEUR = Commandeur;
|
|
|
|
this.SCHIFFSTYP = Typ;
|
|
setzeSchiffsTypParameter(SCHIFFSTYP);
|
|
|
|
Globals.registriereEntität(this);
|
|
|
|
}
|
|
|
|
//Kopierkonstruktor
|
|
public Schiff(Schiff KopierSchiff)
|
|
{
|
|
this.NAME = KopierSchiff.NAME;
|
|
this.ALTER = KopierSchiff.ALTER;
|
|
if(COMMANDEUR != null)
|
|
this.COMMANDEUR = KopierSchiff.COMMANDEUR;
|
|
this.angedocktAnHafen = KopierSchiff.angedocktAnHafen;
|
|
this.SCHIFFSTYP = KopierSchiff.SCHIFFSTYP;
|
|
this.setzeSchiffsTypParameter(SCHIFFSTYP);
|
|
this.bezahlt = KopierSchiff.bezahlt;
|
|
this.FERTIGSTELLUNGSDATUM = KopierSchiff.FERTIGSTELLUNGSDATUM;
|
|
this.inBau = KopierSchiff.inBau;
|
|
this.inReparatur = KopierSchiff.inReparatur;
|
|
|
|
this.ZUSTAND_GEFLUTET = KopierSchiff.ZUSTAND_GEFLUTET;
|
|
this.ZUSTAND_TAKELAGE = KopierSchiff.ZUSTAND_TAKELAGE;
|
|
this.ZUSTAND_VERMUSCHELT = KopierSchiff.ZUSTAND_VERMUSCHELT;
|
|
|
|
this.SCHIFFSBUDGET = KopierSchiff.SCHIFFSBUDGET;
|
|
this.LADUNG = KopierSchiff.LADUNG;
|
|
this.BESATZUNGSKOSTEN = KopierSchiff.BESATZUNGSKOSTEN;
|
|
|
|
this.MANNSCHAFT_ERFAHRUNG = KopierSchiff.MANNSCHAFT_ERFAHRUNG;
|
|
this.MANNSCHAFT_VITALITÄT = KopierSchiff.MANNSCHAFT_VITALITÄT;
|
|
this.MANNSCHAFT_VORHANDEN = KopierSchiff.MANNSCHAFT_VORHANDEN;
|
|
this.MANNSCHAFT_UNTERWEGS = KopierSchiff.MANNSCHAFT_UNTERWEGS;
|
|
this.KAPITÄNSORDER = KopierSchiff.KAPITÄNSORDER;
|
|
|
|
}
|
|
|
|
public override void Update()
|
|
{
|
|
base.Update();
|
|
}
|
|
|
|
//Verwaltungsmethoden für Budget
|
|
public void erhöhenBudget(int Einnahmen)
|
|
{
|
|
SCHIFFSBUDGET += Einnahmen;
|
|
}
|
|
|
|
public void vermindernBudget(int Ausgaben)
|
|
{
|
|
SCHIFFSBUDGET -= Ausgaben;
|
|
}
|
|
|
|
public void initiereBau(DateTime FertigstellungAm)
|
|
{
|
|
//Funktion wird bei Bau des Schiffs aufgerufen um alles für den Bau festzusetzen
|
|
bezahlt = false;
|
|
inBau = true;
|
|
FERTIGSTELLUNGSDATUM = FertigstellungAm;
|
|
RESTBETRAGKAUFPREIS = NEUWERT - ANZAHLUNGSPREIS;
|
|
|
|
}
|
|
|
|
public void initiereBereitstellung(DateTime BereitstellungAm)
|
|
{
|
|
bezahlt = false;
|
|
inBereitstellung = true;
|
|
FERTIGSTELLUNGSDATUM = BereitstellungAm;
|
|
}
|
|
|
|
public void initiiereFertigstellung()
|
|
{
|
|
bezahlt = true;
|
|
inBau = false;
|
|
inBereitstellung = false;
|
|
|
|
}
|
|
|
|
public string schiffAbbezahlen(int GeldBetrag)
|
|
{
|
|
//Funktion wird aufgerufen um restbetrag zu tilgen (Aufrufendes Programm muss vorab abfangen, ob zu zahlender Betrag <= RESTBETRAGDESKAUFPREISES ist)
|
|
RESTBETRAGKAUFPREIS -= GeldBetrag;
|
|
|
|
if(RESTBETRAGKAUFPREIS > 0)
|
|
{
|
|
//Teilbetrag wurde getilgt
|
|
return "ERFOLG";
|
|
}
|
|
else
|
|
{
|
|
if (RESTBETRAGKAUFPREIS == 0)
|
|
{
|
|
//Schiff ist abbezahlt und bei erreichen des Datums wird schiff auf Spieler geschrieben
|
|
bezahlt = true;
|
|
return "ERFOLG_BEZAHLT";
|
|
}
|
|
else
|
|
{
|
|
//Falls man versucht hat mehr als den Restbetrag zu bezahlen
|
|
RESTBETRAGKAUFPREIS += GeldBetrag;
|
|
return "FEHLER";
|
|
}
|
|
}
|
|
}
|
|
|
|
public void setzeSchiffsTypParameter(string Typ)
|
|
{
|
|
//Hier werden alle Parameter des Schiffs gemäß seines Typs gesetzt
|
|
switch (Typ)
|
|
{
|
|
case "SCHONER":
|
|
KABINEN = 0;
|
|
MANNSCHAFT_MAXGRÖßE = 12;
|
|
LADERAUM = 300;
|
|
LIEFERZEIT = 78;
|
|
BAUMATERIAL = "HOLZ";
|
|
NEUWERT = 400000;
|
|
ANZAHLUNGSPREIS = 100000;
|
|
break;
|
|
case "BARK":
|
|
KABINEN = 0;
|
|
MANNSCHAFT_MAXGRÖßE = 14;
|
|
LADERAUM = 450;
|
|
LIEFERZEIT = 88;
|
|
BAUMATERIAL = "HOLZ";
|
|
NEUWERT = 600000;
|
|
ANZAHLUNGSPREIS = 150000;
|
|
break;
|
|
case "HOLZDAMPFSCHIFF":
|
|
KABINEN = 0;
|
|
MANNSCHAFT_MAXGRÖßE = 12;
|
|
LADERAUM = 399;
|
|
LIEFERZEIT = 85;
|
|
BAUMATERIAL = "HOLZ";
|
|
NEUWERT = 800000;
|
|
ANZAHLUNGSPREIS = 200000;
|
|
break;
|
|
case "EISENDAMPFSCHIFF":
|
|
KABINEN = 30;
|
|
MANNSCHAFT_MAXGRÖßE = 19;
|
|
LADERAUM = 699;
|
|
LIEFERZEIT = 104;
|
|
BAUMATERIAL = "EISEN";
|
|
NEUWERT = 1400000;
|
|
ANZAHLUNGSPREIS = 350000;
|
|
break;
|
|
case "BRIGG":
|
|
KABINEN = 0;
|
|
MANNSCHAFT_MAXGRÖßE = 19;
|
|
LADERAUM = 600;
|
|
LIEFERZEIT = 97;
|
|
BAUMATERIAL = "EISEN";
|
|
NEUWERT = 800000;
|
|
ANZAHLUNGSPREIS = 200000;
|
|
break;
|
|
case "FREGATTE":
|
|
KABINEN = 40;
|
|
MANNSCHAFT_MAXGRÖßE = 25;
|
|
LADERAUM = 999;
|
|
LIEFERZEIT = 123;
|
|
BAUMATERIAL = "EISEN";
|
|
NEUWERT = 1600000;
|
|
ANZAHLUNGSPREIS = 400000;
|
|
break;
|
|
case "KLIPPER":
|
|
KABINEN = 45;
|
|
MANNSCHAFT_MAXGRÖßE = 27;
|
|
LADERAUM = 1197;
|
|
LIEFERZEIT = 135;
|
|
BAUMATERIAL = "HOLZ";
|
|
NEUWERT = 1900000;
|
|
ANZAHLUNGSPREIS = 475000;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//Verwaltungsmethoden für Waren (Überladung, damit man die Verwaltung sowohl mit dem Namen der Ware als auch mit der Ware selbst erledigen kann... jedenfalls beim Auslagern)
|
|
public void einlagernLadung(Ware neueWare)
|
|
{
|
|
// Einlagerung von Waren benötigt immer die effektiv erzeugte Ware
|
|
Ware TempWare = new Ware(neueWare);
|
|
//Überprüfen, ob dies hinzuzufügende Ware verderblich ist
|
|
if (neueWare.istVerderblich())
|
|
{
|
|
// Wenn ja, regulär hinzubuchen (verderbliche Ware verfolgt angepasste Logik)
|
|
// To Do: Einlagerlogik für verderbliche Ware implementieren
|
|
}
|
|
else
|
|
{
|
|
// Wenn Nein neue Ware wird erstellt und der Ladung hinzugefügt oder bei existierender Ware hinzugebucht
|
|
bool wareHinzugebucht = false;
|
|
foreach (Ware item in LADUNG)
|
|
{
|
|
if (item.BEZEICHNUNG == neueWare.BEZEICHNUNG)
|
|
{
|
|
item.MENGE += neueWare.MENGE;
|
|
wareHinzugebucht = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!wareHinzugebucht)
|
|
{
|
|
LADUNG.Add(TempWare);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
}
|
|
public void löscheLadung(string Ladung, int Menge)
|
|
{
|
|
|
|
// gegebenenfalls feature im Remake: Löschen der Ladung hat zeitaufwand(Eventuelle Dauer = 1 Tag in dem eventuell ausgeraubt werden kann)
|
|
|
|
bool verderblich = false;
|
|
|
|
// Vorabcheck ob Ware existiert und ob diese verderblich ist
|
|
foreach (Ware item in LADUNG)
|
|
{
|
|
if (item.BEZEICHNUNG == Ladung)
|
|
{
|
|
verderblich = item.istVerderblich();
|
|
//Wenn Ware gefunden wurde müssen wir nicht mehr weiter durchsuchen
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (verderblich)
|
|
{
|
|
// Sonderlogik bei verderblicher Ware
|
|
// To Do: Implementieren / durchdenken!!
|
|
}
|
|
else
|
|
{
|
|
foreach (Ware item in LADUNG)
|
|
{
|
|
if (item.BEZEICHNUNG == Ladung)
|
|
{
|
|
// Angefragte Menge Reduzieren
|
|
// Wenn nicht mehr genug ware vorhanden ist wird null ausgegeben
|
|
if (item.MENGE - Menge < 0)
|
|
{
|
|
// Wenn auszulagernder Menge unter 0 ist ist ein fehler Passiert ergo nichts tun!
|
|
}
|
|
else
|
|
{
|
|
item.MENGE -= Menge;
|
|
// Wenn wir mit der Auslagerung das Lager geleert haben wird es aus dem Bestand genommen
|
|
if (item.MENGE == 0)
|
|
LADUNG.Remove(item);
|
|
}
|
|
//Wenn Ware gefunden wurde müssen wir nicht mehr weiter durchsuchen
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
private void sortiereVerderblichListe()
|
|
{
|
|
//Aufspalten in 2 Listen(Verderbliche/normale Waren) -> am Ende wieder zusammen setzen (normale Waren werden an verderblichen drangehängt [damit die zuerst gelesen werden]
|
|
List<Ware> TempListe = new List<Ware>();
|
|
List<Ware> VerderbListe = new List<Ware>();
|
|
|
|
foreach (Ware item in LADUNG)
|
|
{
|
|
if (item.istVerderblich())
|
|
{
|
|
if (VerderbListe.Count() == 0)
|
|
{
|
|
VerderbListe.Add(item);
|
|
}
|
|
else
|
|
{
|
|
//Wenn Liste nicht leer ist -> Vergleiche MHDs miteinander und vorne/hinten anstellen (immer nur check erstes und letztes element weil rest bereits sortiert wurde
|
|
// schnelle sortiercodes gugen (ToDo)
|
|
}
|
|
|
|
|
|
}
|
|
else
|
|
{
|
|
//Wenn Ware nicht verderblich -> keine besondere Sortierlogik
|
|
TempListe.Add(item);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
public void fahreInHafenEin(string HafenName)
|
|
{
|
|
angedocktAnHafen = HafenName;
|
|
}
|
|
|
|
public void fahreAusHafenHeraus()
|
|
{
|
|
if (angedocktAnHafen != "")
|
|
angedocktAnHafen = "";
|
|
}
|
|
|
|
public int verkaufsWertBestimmen()
|
|
{//Funktion ist vorgesehen für interner Verkaufswert zu bestimmen
|
|
// Wird erst eingebaut wenn schiffszustand(Reperaturen) implementiert sind und
|
|
// die Berechnung des Verkaufswertes vom schiff übernommen wird statt vom aufrufer
|
|
|
|
//Berechnung: (Neuwert/(Alter+1))*(100-Zustand des Schiffs in %)
|
|
return 0;
|
|
}
|
|
|
|
public void besatzungBereitstellen()
|
|
{
|
|
MANNSCHAFT_UNTERWEGS = true;
|
|
}
|
|
|
|
public void besatzungEinstellen(string BesatzungsTyp)
|
|
{
|
|
int PreisProNase = 0;
|
|
//Setzen der spezifischen Eigenschaften
|
|
switch (BesatzungsTyp)
|
|
{
|
|
case "SPITZE":
|
|
MANNSCHAFT_ERFAHRUNG = 100;
|
|
PreisProNase = Globals.MannschaftskostenMin + Globals.ErfahrungsFaktor[0];
|
|
break;
|
|
case "ERFAHREN":
|
|
MANNSCHAFT_ERFAHRUNG = 90;
|
|
PreisProNase = Globals.MannschaftskostenMin + Globals.ErfahrungsFaktor[1];
|
|
break;
|
|
case "TÜCHTIG":
|
|
MANNSCHAFT_ERFAHRUNG = 80;
|
|
PreisProNase = Globals.MannschaftskostenMin + Globals.ErfahrungsFaktor[2];
|
|
break;
|
|
case "ZUVERLÄSSIG":
|
|
MANNSCHAFT_ERFAHRUNG = 70;
|
|
PreisProNase = Globals.MannschaftskostenMin + Globals.ErfahrungsFaktor[3];
|
|
break;
|
|
case "STANDARD":
|
|
MANNSCHAFT_ERFAHRUNG = 60;
|
|
PreisProNase = Globals.MannschaftskostenMin + Globals.ErfahrungsFaktor[4];
|
|
break;
|
|
case "FÄHIG":
|
|
MANNSCHAFT_ERFAHRUNG = 50;
|
|
PreisProNase = Globals.MannschaftskostenMin + Globals.ErfahrungsFaktor[5];
|
|
break;
|
|
case "BRAUCHBAR":
|
|
MANNSCHAFT_ERFAHRUNG = 40;
|
|
PreisProNase = Globals.MannschaftskostenMin + Globals.ErfahrungsFaktor[6];
|
|
break;
|
|
case "BILLIG":
|
|
MANNSCHAFT_ERFAHRUNG = 30;
|
|
PreisProNase = Globals.MannschaftskostenMin + Globals.ErfahrungsFaktor[7];
|
|
break;
|
|
case "GRÜNSCHNABEL":
|
|
MANNSCHAFT_ERFAHRUNG = 20;
|
|
PreisProNase = Globals.MannschaftskostenMin + Globals.ErfahrungsFaktor[8];
|
|
break;
|
|
case "IDIOTEN":
|
|
MANNSCHAFT_ERFAHRUNG = 10;
|
|
PreisProNase = Globals.MannschaftskostenMin + Globals.ErfahrungsFaktor[9];
|
|
break;
|
|
}
|
|
//Setzen Mannschaftskosten
|
|
this.BESATZUNGSKOSTEN = PreisProNase * MANNSCHAFT_MAXGRÖßE;
|
|
|
|
//Setzen der allgemeinen Eigenschaften
|
|
MANNSCHAFT_VORHANDEN = true;
|
|
MANNSCHAFT_UNTERWEGS = false;
|
|
MANNSCHAFT_VITALITÄT = 100;
|
|
KAPITÄNSORDER = "MITTEL";
|
|
}
|
|
}
|
|
}
|