#include "Map.h" #include #include #include #include #include #include #include // Inhalt der Map Klasse aus Map.h // Konstruktor Map::Map(KSGClient::MinigameServerClient* klient) : ReferenceCounter() { this->klient = klient; gegner = new RCArray< Spieler >(); ziele = new RCArray< Spieler >(); spieler = 0; feld = new LRahmen(); feld->setFarbe(0xFFFFFFFF); kam = new LRahmen(); kam->setFarbe(0xFF777777); map = new LRahmen(); map->setFarbe(0xFFFFFFFF); map->setPosition(10, 10); //map->setSize( 200, 200 ); beendet = 1; gameTime = 0; tastenStände = 0; rGen = 0; } // Destruktor Map::~Map() { speichern(); gegner->release(); ziele->release(); if (spieler) spieler->release(); feld->release(); kam->release(); map->release(); if (rGen) rGen->release(); if (klient) klient->release(); } // nicht constant void Map::reset(Text* zOptionen) { gameTime = 0; tastenStände = 0; if (rGen) rGen = (RandomGenerator*)rGen->release(); beendet = 0; score = 0; scoreCheck = score * 11197; gegner->leeren(); ziele->leeren(); if (spieler) spieler = (Spieler*)spieler->release(); ziele->leeren(); Text* tmp = zOptionen->getTeilText(zOptionen->positionVon('=') + 1, zOptionen->positionVon(',')); breite = (int)*tmp; tmp->release(); tmp = zOptionen->getTeilText(zOptionen->positionVon('=', 1) + 1, zOptionen->positionVon(',', 1)); höhe = (int)*tmp; tmp->release(); tmp = zOptionen->getTeilText(zOptionen->positionVon('=', 2) + 1, zOptionen->positionVon(',', 2)); zAnzahl = (int)*tmp; tmp->release(); tmp = zOptionen->getTeilText(zOptionen->positionVon('=', 3) + 1, zOptionen->positionVon(',', 3)); neuGegner = (int)*tmp; tmp->release(); tmp = zOptionen->getTeilText(zOptionen->positionVon('=', 4) + 1, zOptionen->positionVon(',', 4)); geschwindigkeit = (int)*tmp; tmp->release(); tmp = zOptionen->getTeilText(zOptionen->positionVon('=', 5) + 1, zOptionen->positionVon(',', 5)); bool fortsetzen = (int)*tmp != 0; tmp->release(); kamX = 0; kamY = 0; if (breite > 80) kamX = breite / 2 - 400; if (höhe > 50) kamY = höhe / 2 - 250; if (fortsetzen && DateiExistiert("data/Minigames/Fangen/data/game.save") && klient) { if (capture.istOffen()) capture.close(); capture.setDatei("data/Minigames/Fangen/data/game.mgc"); capture.open(Datei::Style::schreiben | Datei::Style::ende | Datei::Style::lesen); Datei* save = new Datei(); save->setDatei("data/Minigames/Fangen/data/game.save"); save->open(Datei::Style::lesen); int br = 0; int hö = 0; __int64 seed; save->lese((char*)&seed, 8); rGen = new RandomGenerator(); rGen->setSeed(seed); save->lese((char*)&gameTime, 8); save->lese((char*)&br, 4); save->lese((char*)&hö, 4); if (br == breite && hö == höhe) { save->lese((char*)&score, 4); scoreCheck = score * 11197; spieler = new Spieler(SPIELER, save); int anz = 0; save->lese((char*)&anz, 4); for (int i = 0; i < anz; i++) gegner->add(new Spieler(GEGNER, save)); save->lese((char*)&anz, 4); for (int i = 0; i < anz; i++) ziele->add(new Spieler(ZIEL, save)); } save->close(); save->release(); } else { rGen = new RandomGenerator(); if (klient) { if (capture.istOffen()) capture.close(); DateiRemove("data/Minigames/Fangen/data/game.mgc"); capture.setDatei("data/Minigames/Fangen/data/game.mgc"); capture.erstellen(); capture.open(Datei::Style::schreiben); __int64 seed = rGen->getSeed(); capture.schreibe((char*)&seed, 8); } else { tmp = zOptionen->getTeilText(zOptionen->positionVon('=', 6) + 1); rGen->setSeed((__int64)*tmp); tmp->release(); } } if (!spieler) spieler = new Spieler(SPIELER, breite, höhe, rGen); if (!gegner->getEintragAnzahl()) { for (int i = 0; i < neuGegner; i++) gegner->add(new Spieler(GEGNER, breite, höhe, rGen)); } if (!ziele->getEintragAnzahl()) { for (int i = 0; i < zAnzahl; i++) ziele->add(new Spieler(ZIEL, breite, höhe, rGen)); } } void Map::doPublicMausEreignis(MausEreignis& me) { } void Map::doTastaturEreignis(TastaturEreignis& te) { cs.lock(); bool ok = 1; if (!beendet) { char tmp = tastenStände; if (te.taste == 'w' || te.taste == 'W' || te.taste == T_Oben) { if (te.id == TE_Press) tastenStände |= 1; else tastenStände &= ~1; } if (te.taste == 'd' || te.taste == 'D' || te.taste == T_Rechts) { if (te.id == TE_Press) tastenStände |= 2; else tastenStände &= ~2; } if (te.taste == 'a' || te.taste == 'A' || te.taste == T_Links) { if (te.id == TE_Press) tastenStände |= 4; else tastenStände &= ~4; } if (te.taste == 's' || te.taste == 'S' || te.taste == T_Unten) { if (te.id == TE_Press) tastenStände |= 8; else tastenStände &= ~8; } if (tmp != tastenStände && klient) { if (klient) { capture.schreibe((char*)&gameTime, 8); capture.schreibe(&tastenStände, 1); } } } cs.unlock(); } bool Map::tick(double tickVal) { if (beendet || !spieler) return 0; if (score * 11197 != scoreCheck) { beendet = 1; score = 0; scoreCheck = 0; } cs.lock(); gameTime += tickVal; double t = tickVal * geschwindigkeit / 1000; spieler->tick(t, breite, höhe, tastenStände); int anz = gegner->getEintragAnzahl(); for (int i = 0; i < anz; i++) { gegner->z(i)->tick(t, breite, höhe, tastenStände); if (gegner->z(i)->berührt(spieler->getX(), spieler->getY())) beendet = 1; } anz = ziele->getEintragAnzahl(); for (int i = 0; i < anz; i++) { ziele->z(i)->tick(t, breite, höhe, tastenStände); if (ziele->z(i)->berührt(spieler->getX(), spieler->getY())) { score++; scoreCheck = score * 11197; ziele->leeren(); for (int i = 0; i < zAnzahl; i++) ziele->add(new Spieler(ZIEL, breite, höhe, rGen)); for (int i = 0; i < neuGegner; i++) gegner->add(new Spieler(GEGNER, breite, höhe, rGen)); } } if (breite > 800) { kamX = (int)spieler->getX() - 400; if (kamX < 0) kamX = 0; if (kamX + 800 > breite) kamX = breite - 800; } if (höhe > 500) { kamY = (int)spieler->getY() - 250; if (kamY < 0) kamY = 0; if (kamY + 500 > höhe) kamY = höhe - 500; } if (beendet && klient) { capture.close(); DateiRemove("data/Minigames/Fangen/data/upload.mgc"); DateiUmbenennen("data/Minigames/Fangen/data/game.mgc", "data/Minigames/Fangen/data/upload.mgc"); int tmpScore = score; KSGClient::MinigameServerClient* tmpKlient = dynamic_cast(klient->getThis()); new AsynchronCall([tmpScore, tmpKlient]() { InitDatei* opd = new InitDatei("data/Minigames/Fangen/data/optionen.ini"); opd->laden(); Text optionen = "Width="; optionen += opd->zWert("Breite")->getText(); optionen += ",Height="; optionen += opd->zWert("Höhe")->getText(); optionen += ",Ziele="; optionen += opd->zWert("Ziele")->getText(); optionen += ",Gegner="; optionen += opd->zWert("+Gegner")->getText(); optionen += ",Speed="; optionen += opd->zWert("Geschwindigkeit")->getText(); opd->release(); Datei d; d.setDatei("data/Minigames/Fangen/data/upload.mgc"); tmpKlient->reportEndOfGame("Fangen", optionen, tmpScore, &d); DateiRemove("data/Minigames/Fangen/data/upload.mgc"); tmpKlient->release(); }); KSGTDatei* stb = new KSGTDatei("data/Minigames/Fangen/data/score.ksgt"); if (!stb->laden()) DateiPfadErstellen("data/Minigames/Fangen/data/score.ksgt"); RCArray< Text >* zeile = new RCArray< Text >(); Zeit* zeit = getZeit(); zeile->add(zeit->getZeit("y-m-d h:i:s")); zeit->release(); Text* scoreT = new Text(); scoreT->append(score); zeile->add(scoreT); Text* breiteT = new Text(); breiteT->append(breite); zeile->add(breiteT); Text* höheT = new Text(); höheT->append(höhe); zeile->add(höheT); Text* geschwindigkeitT = new Text(); geschwindigkeitT->append(geschwindigkeit); zeile->add(geschwindigkeitT); Text* zAnzahlT = new Text(); zAnzahlT->append(zAnzahl); zeile->add(zAnzahlT); Text* nAnzahlT = new Text(); nAnzahlT->append(neuGegner); zeile->add(nAnzahlT); stb->addZeile(7, zeile); zeile->release(); stb->speichern(); stb->release(); DateiRemove("data/Minigames/Fangen/data/game.save"); } cs.unlock(); return 1; } void Map::render(Bild& zRObj) { if (!spieler) return; int xStart = 0; int yStart = 0; if (breite < 800) xStart = 400 - breite / 2; else xStart -= kamX; if (höhe < 500) yStart = 250 - höhe / 2; else yStart -= kamY; feld->setPosition(xStart, yStart); feld->setSize(breite, höhe); feld->render(zRObj); bool rMap = breite > 800 || höhe > 500; zRObj.addScrollOffset(-xStart, -yStart); spieler->render(zRObj); int gAnz = gegner->getEintragAnzahl(); for (int i = 0; i < gAnz; i++) gegner->z(i)->render(zRObj); int zAnz = ziele->getEintragAnzahl(); for (int i = 0; i < zAnz; i++) ziele->z(i)->render(zRObj); zRObj.addScrollOffset(xStart, yStart); if (rMap) { const Punkt& dOff = zRObj.getDrawOff(); map->render(zRObj); zRObj.setPixelDP(10 + (200 * spieler->getX()) / breite + dOff.x, 10 + (200 * spieler->getY()) / höhe + dOff.y, 0xFF00FF00); for (int i = 0; i < gAnz; i++) zRObj.setPixelDP(10 + (200 * gegner->z(i)->getX()) / breite + dOff.x, 10 + (200 * gegner->z(i)->getY()) / höhe + dOff.y, 0xFFFF0000); for (int i = 0; i < zAnz; i++) zRObj.setPixelDP(10 + (200 * ziele->z(i)->getX()) / breite + dOff.x, 10 + (200 * ziele->z(i)->getY()) / höhe + dOff.y, 0xFF00FFFF); kam->setPosition(10 + (200 * kamX) / breite, 10 + (200 * kamY) / höhe); kam->setSize((200 * 800) / breite, (200 * 500) / höhe); if (kam->getBreite() > 200) kam->setSize(200, kam->getHeight()); if (kam->getHeight() > 200) kam->setSize(kam->getBreite(), 200); kam->render(zRObj); } } void Map::speichern() { if (!beendet && spieler) { if (capture.istOffen()) capture.close(); Datei* d = new Datei(); d->setDatei("data/Minigames/Fangen/data/game.save"); d->erstellen(); d->open(Datei::Style::schreiben); __int64 seed = rGen->getSeed(); d->schreibe((char*)&seed, 8); d->schreibe((char*)&gameTime, 8); d->schreibe((char*)&breite, 4); d->schreibe((char*)&höhe, 4); d->schreibe((char*)&score, 4); spieler->save(d); int anz = gegner->getEintragAnzahl(); d->schreibe((char*)&anz, 4); for (int i = 0; i < anz; i++) gegner->z(i)->save(d); anz = ziele->getEintragAnzahl(); d->schreibe((char*)&anz, 4); for (int i = 0; i < anz; i++) ziele->z(i)->save(d); d->close(); d->release(); } else if (klient) DateiRemove("data/Minigames/Fangen/data/game.save"); } Map::Save* Map::saveState() { Save* s = new Save(); s->beendet = beendet; s->gameTime = gameTime; s->score = score; s->scoreCheck = scoreCheck; s->gegner = new RCArray(); for (auto g : *gegner) s->gegner->add(g->copy()); s->ziele = new RCArray(); for (auto z : *ziele) s->ziele->add(z->copy()); s->spieler = spieler->copy(); return s; } void Map::reloadState(Map::Save* s) { beendet = s->beendet; gameTime = s->gameTime; score = s->score; scoreCheck = s->scoreCheck; gegner->leeren(); for (auto g : *s->gegner) gegner->add(dynamic_cast(g->getThis())); ziele->leeren(); for (auto z : *s->ziele) ziele->add(dynamic_cast(z->getThis())); spieler->release(); spieler = dynamic_cast(s->spieler->getThis()); s->ziele->release(); s->gegner->release(); s->spieler->release(); delete s; } bool Map::canGoLeft() const { return spieler->getX() > 10; } bool Map::canGoUp() const { return spieler->getY() > 10; } bool Map::canGoRight() const { return spieler->getX() < breite - 10; } bool Map::canGoDown() const { return spieler->getY() < höhe - 10; } int Map::getBestOption(bool* left, bool* up, bool* right, bool* down, int maxSteps) { if (!maxSteps && !beendet) return score; else if (beendet) return -1; int best = 0; int maxScore = -2; int order[] = { 0, 1, 2, 4, 8, 3, 9, 6, 12 }; int orderCount = 9; for (int x = 0; x < orderCount; x++) { int i = order[x]; Save* save = saveState(); TastaturEreignis te; te.taste = T_Links; te.verarbeitet = 0; te.id = (i | 0x1) == i ? TE_Press : TE_Release; doTastaturEreignis(te); te.taste = T_Oben; te.verarbeitet = 0; te.id = (i | 0x2) == i ? TE_Press : TE_Release; doTastaturEreignis(te); te.taste = T_Rechts; te.verarbeitet = 0; te.id = (i | 0x4) == i ? TE_Press : TE_Release; doTastaturEreignis(te); te.taste = T_Unten; te.verarbeitet = 0; te.id = (i | 0x8) == i ? TE_Press : TE_Release; doTastaturEreignis(te); tick(0.05); tick(0.05); tick(0.05); tick(0.05); tick(0.05); Save* save2 = saveState(); tick(0.05); tick(0.05); tick(0.05); tick(0.05); tick(0.05); if (beendet && !save2->beendet) { reloadState(save2); save2 = 0; } int score = getBestOption(left, up, right, down, maxSteps - 1); if (this->score > save->score) score += maxSteps; if (score > maxScore) { maxScore = score; best = i; } if (save2) reloadState(save2); reloadState(save); } *left = (best | 0x1) == best; *up = (best | 0x2) == best; *right = (best | 0x4) == best; *down = (best | 0x8) == best; return maxScore; } // constant int Map::getScore() const { return score; } bool Map::istBeendet() const { return beendet; }