/// Sagt dem Schiff, dass ein neuer Hafen erbaut wurde void noShip::NewHarborBuilt(nobHarborBuilding* hb) { if(lost) { // Liegt der Hafen auch am Meer von diesem Schiff? if(!gwg->IsAtThisSea(hb->GetHarborPosID(), seaId_)) return; //LOG.lprintf("lost ship has new goal harbor player %i state %i pos %u,%u \n",player,state,x,y); home_harbor = goal_harbor_id = hb->GetHarborPosID(); lost = false; StartDrivingToHarborPlace(); switch(state) { case STATE_EXPLORATIONEXPEDITION_DRIVING: case STATE_EXPEDITION_DRIVING: case STATE_TRANSPORT_DRIVING: { Driven(); } break; default: assert(false); // Das darf eigentlich nicht passieren } } }
/// Sagt dem Schiff, dass ein neuer Hafen erbaut wurde void noShip::NewHarborBuilt(nobHarborBuilding* hb) { if(!lost) return; // Liegt der Hafen auch am Meer von diesem Schiff? if(!gwg->IsHarborAtSea(hb->GetHarborPosID(), seaId_)) return; //LOG.write(("lost ship has new goal harbor player %i state %i pos %u,%u \n",player,state,x,y); home_harbor = goal_harborId = hb->GetHarborPosID(); lost = false; StartDrivingToHarborPlace(); switch(state) { case STATE_EXPLORATIONEXPEDITION_DRIVING: case STATE_EXPEDITION_DRIVING: case STATE_TRANSPORT_DRIVING: case STATE_SEAATTACK_RETURN_DRIVING: Driven(); break; default: RTTR_Assert(false); // Das darf eigentlich nicht passieren LOG.write("Bug detected: Invalid state in NewHarborBuilt"); break; } }
void noShip::HandleEvent(const unsigned int id) { current_ev = 0; switch(id) { // Laufevent case 0: { // neue Position einnehmen Walk(); // entscheiden, was als nächstes zu tun ist Driven(); } break; default: { switch(state) { default: break; case STATE_EXPEDITION_LOADING: { // Schiff ist nun bereit und Expedition kann beginnen state = STATE_EXPEDITION_WAITING; // Spieler benachrichtigen if(GAMECLIENT.GetPlayerID() == this->player) GAMECLIENT.SendPostMessage(new ShipPostMsg(_("A ship is ready for an expedition."), PMC_GENERAL, GAMECLIENT.GetPlayer(player).nation, pos)); // KI Event senden GAMECLIENT.SendAIEvent(new AIEvent::Location(AIEvent::ExpeditionWaiting, pos), player); } break; case STATE_EXPLORATIONEXPEDITION_LOADING: { // Schiff ist nun bereit und Expedition kann beginnen ContinueExplorationExpedition(); } break; case STATE_EXPLORATIONEXPEDITION_WAITING: { // Schiff ist nun bereit und Expedition kann beginnen ContinueExplorationExpedition(); } break; case STATE_EXPEDITION_UNLOADING: { // Hafen herausfinden MapPoint goal_pos(gwg->GetHarborPoint(goal_harbor_id)); noBase* hb = gwg->GetNO(goal_pos); if(hb->GetGOT() == GOT_NOB_HARBORBUILDING) { Goods goods; memset(&goods, 0, sizeof(Goods)); unsigned char nation = players->getElement(player)->nation; goods.goods[GD_BOARDS] = BUILDING_COSTS[nation][BLD_HARBORBUILDING].boards; goods.goods[GD_STONES] = BUILDING_COSTS[nation][BLD_HARBORBUILDING].stones; goods.people[JOB_BUILDER] = 1; static_cast<nobBaseWarehouse*>(hb)->AddGoods(goods); // Wieder idlen und ggf. neuen Job suchen StartIdling(); players->getElement(player)->GetJobForShip(this); } else { // target harbor for unloading doesnt exist anymore -> set state to driving and handle the new state state = STATE_EXPEDITION_DRIVING; HandleState_ExpeditionDriving(); } } break; case STATE_EXPLORATIONEXPEDITION_UNLOADING: { // Hafen herausfinden MapPoint goal_pos(gwg->GetHarborPoint(goal_harbor_id)); noBase* hb = gwg->GetNO(goal_pos); unsigned old_visual_range = GetVisualRange(); if(hb->GetGOT() == GOT_NOB_HARBORBUILDING) { // Späher wieder entladen Goods goods; memset(&goods, 0, sizeof(Goods)); goods.people[JOB_SCOUT] = SCOUTS_EXPLORATION_EXPEDITION; static_cast<nobBaseWarehouse*>(hb)->AddGoods(goods); // Wieder idlen und ggf. neuen Job suchen StartIdling(); players->getElement(player)->GetJobForShip(this); } else { // target harbor for unloading doesnt exist anymore -> set state to driving and handle the new state state = STATE_EXPLORATIONEXPEDITION_DRIVING; HandleState_ExplorationExpeditionDriving(); } // Sichtbarkeiten neu berechnen gwg->RecalcVisibilitiesAroundPoint(pos, old_visual_range, player, NULL); } break; case STATE_TRANSPORT_LOADING: { StartTransport(); } break; case STATE_TRANSPORT_UNLOADING: { // Hafen herausfinden remaining_sea_attackers = 0; //can be 1 in case we had sea attackers on board - set to 1 for a special check when the return harbor is destroyed to set the returning attackers goal to 0 MapPoint goal_pos(gwg->GetHarborPoint(goal_harbor_id)); noBase* hb = gwg->GetNO(goal_pos); if(hb->GetGOT() == GOT_NOB_HARBORBUILDING) { static_cast<nobHarborBuilding*>(hb)->ReceiveGoodsFromShip(figures, wares); figures.clear(); wares.clear(); // Hafen bescheid sagen, dass er das Schiff nun nutzen kann static_cast<nobHarborBuilding*>(hb)->ShipArrived(this); // Hafen hat keinen Job für uns? if (state == STATE_TRANSPORT_UNLOADING) { // Wieder idlen und ggf. neuen Job suchen StartIdling(); players->getElement(player)->GetJobForShip(this); } } else { // target harbor for unloading doesnt exist anymore -> set state to driving and handle the new state state = STATE_TRANSPORT_DRIVING; HandleState_TransportDriving(); } } break; case STATE_SEAATTACK_LOADING: { StartSeaAttack(); } break; case STATE_SEAATTACK_WAITING: { // Nächsten Soldaten nach draußen beordern if(figures.empty()) break; nofAttacker* attacker = static_cast<nofAttacker*>(*figures.begin()); // Evtl. ist ein Angreifer schon fertig und wieder an Board gegangen // der darf dann natürlich nicht noch einmal raus, sonst kann die schöne Reise // böse enden if(attacker->IsSeaAttackCompleted()) break; figures.pop_front(); gwg->AddFigure(attacker, pos); current_ev = em->AddEvent(this, 30, 1); attacker->StartAttackOnOtherIsland(pos, GetObjId()); ; }; case STATE_SEAATTACK_UNLOADING: { } break; } } break; } }
void noShip::HandleEvent(const unsigned int id) { RTTR_Assert(current_ev); RTTR_Assert(current_ev->id == id); current_ev = NULL; if(id == 0) { // Move event // neue Position einnehmen Walk(); // entscheiden, was als nächstes zu tun ist Driven(); }else { switch(state) { default: RTTR_Assert(false); LOG.write("Bug detected: Invalid state in ship event"); break; case STATE_EXPEDITION_LOADING: // Schiff ist nun bereit und Expedition kann beginnen state = STATE_EXPEDITION_WAITING; // Spieler benachrichtigen SendPostMessage(player, new ShipPostMsg(GetEvMgr().GetCurrentGF(), _("A ship is ready for an expedition."), PostCategory::Economy, *this)); gwg->GetNotifications().publish(ExpeditionNote(ExpeditionNote::Waiting, player, pos)); break; case STATE_EXPLORATIONEXPEDITION_LOADING: case STATE_EXPLORATIONEXPEDITION_WAITING: // Schiff ist nun bereit und Expedition kann beginnen ContinueExplorationExpedition(); break; case STATE_EXPEDITION_UNLOADING: { // Hafen herausfinden noBase* hb = goal_harborId ? gwg->GetNO(gwg->GetHarborPoint(goal_harborId)) : NULL; if(hb && hb->GetGOT() == GOT_NOB_HARBORBUILDING) { Inventory goods; unsigned char nation = gwg->GetPlayer(player).nation; goods.goods[GD_BOARDS] = BUILDING_COSTS[nation][BLD_HARBORBUILDING].boards; goods.goods[GD_STONES] = BUILDING_COSTS[nation][BLD_HARBORBUILDING].stones; goods.people[JOB_BUILDER] = 1; static_cast<nobBaseWarehouse*>(hb)->AddGoods(goods, false); // Wieder idlen und ggf. neuen Job suchen StartIdling(); gwg->GetPlayer(player).GetJobForShip(this); } else { // target harbor for unloading doesnt exist anymore -> set state to driving and handle the new state state = STATE_EXPEDITION_DRIVING; HandleState_ExpeditionDriving(); } break; } case STATE_EXPLORATIONEXPEDITION_UNLOADING: { // Hafen herausfinden noBase* hb = goal_harborId ? gwg->GetNO(gwg->GetHarborPoint(goal_harborId)): NULL; unsigned old_visual_range = GetVisualRange(); if(hb && hb->GetGOT() == GOT_NOB_HARBORBUILDING) { // Späher wieder entladen Inventory goods; goods.people[JOB_SCOUT] = gwg->GetGGS().GetNumScoutsExedition(); static_cast<nobBaseWarehouse*>(hb)->AddGoods(goods, false); // Wieder idlen und ggf. neuen Job suchen StartIdling(); gwg->GetPlayer(player).GetJobForShip(this); } else { // target harbor for unloading doesnt exist anymore -> set state to driving and handle the new state state = STATE_EXPLORATIONEXPEDITION_DRIVING; HandleState_ExplorationExpeditionDriving(); } // Sichtbarkeiten neu berechnen gwg->RecalcVisibilitiesAroundPoint(pos, old_visual_range, player, NULL); break; } case STATE_TRANSPORT_LOADING: StartTransport(); break; case STATE_TRANSPORT_UNLOADING: case STATE_SEAATTACK_UNLOADING: { // Hafen herausfinden RTTR_Assert(state == STATE_SEAATTACK_UNLOADING || remaining_sea_attackers == 0); noBase* hb = goal_harborId ? gwg->GetNO(gwg->GetHarborPoint(goal_harborId)): NULL; if(hb && hb->GetGOT() == GOT_NOB_HARBORBUILDING) { static_cast<nobHarborBuilding*>(hb)->ReceiveGoodsFromShip(figures, wares); figures.clear(); wares.clear(); state = STATE_TRANSPORT_UNLOADING; // Hafen bescheid sagen, dass er das Schiff nun nutzen kann static_cast<nobHarborBuilding*>(hb)->ShipArrived(this); // Hafen hat keinen Job für uns? if (state == STATE_TRANSPORT_UNLOADING) { // Wieder idlen und ggf. neuen Job suchen StartIdling(); gwg->GetPlayer(player).GetJobForShip(this); } } else { // target harbor for unloading doesnt exist anymore -> set state to driving and handle the new state if(state == STATE_TRANSPORT_UNLOADING) FindUnloadGoal(STATE_TRANSPORT_DRIVING); else FindUnloadGoal(STATE_SEAATTACK_RETURN_DRIVING); } break; } case STATE_SEAATTACK_LOADING: StartSeaAttack(); break; case STATE_SEAATTACK_WAITING: { // Nächsten Soldaten nach draußen beordern if(figures.empty()) break; nofAttacker* attacker = static_cast<nofAttacker*>(figures.front()); // Evtl. ist ein Angreifer schon fertig und wieder an Board gegangen // der darf dann natürlich nicht noch einmal raus, sonst kann die schöne Reise // böse enden if(attacker->IsSeaAttackCompleted()) break; figures.pop_front(); gwg->AddFigure(attacker, pos); current_ev = GetEvMgr().AddEvent(this, 30, 1); attacker->StartAttackOnOtherIsland(pos, GetObjId()); break; } } } }