void noFigure::NodeFreed(const MapPoint pt) { // Stehen wir gerade aus diesem Grund? if(waiting_for_free_node) { // Ist das der Punkt, zu dem wir hin wollen? if(pt == gwg->GetNeighbour(this->pos, GetCurMoveDir())) { // Gehen wir in ein Gebäude? Dann wieder ausgleichen, weil wir die Türen sonst doppelt aufmachen! if(GetCurMoveDir() == 1 && gwg->GetNO(gwg->GetNeighbour(this->pos, 1))->GetType() == NOP_BUILDING) gwg->GetSpecObj<noBuilding>(gwg->GetNeighbour(this->pos, 1))->CloseDoor(); // oder aus einem raus? if(GetCurMoveDir() == 4 && gwg->GetNO(this->pos)->GetType() == NOP_BUILDING) gwg->GetSpecObj<noBuilding>(this->pos)->CloseDoor(); // Wir stehen nun nicht mehr waiting_for_free_node = false; // Dann loslaufen StartWalking(GetCurMoveDir()); // anderen Leuten noch ggf Bescheid sagen gwg->RoadNodeAvailable(this->pos); } } }
void noFigure::DrawWalking(int x, int y) { // Figurentyp unterscheiden switch(job_) { case JOB_PACKDONKEY: { // Wenn wir warten, ani-step 2 benutzen unsigned ani_step = waiting_for_free_node ? 2 : GAMECLIENT.Interpolate(ASCENT_ANIMATION_STEPS[ascent], current_ev) % 8; // Wenn man wartet, stehend zeichnen, es sei denn man wartet mittem auf dem Weg! if(!waiting_for_free_node || pause_walked_gf) CalcFigurRelative(x, y); // Esel LOADER.GetMapImageN(2000 + ((GetCurMoveDir() + 3) % 6) * 8 + ani_step)->Draw(x, y); // Schatten des Esels LOADER.GetMapImageN(2048 + GetCurMoveDir() % 3)->Draw(x, y, 0, 0, 0, 0, 0, 0, COLOR_SHADOW); } return; case JOB_CHARBURNER: { DrawWalking(x, y, "charburner_bobs", 53); } return; default: { DrawWalkingBobJobs(x, y, job_); } return; } }
/// Zeichnet normales Fahren auf dem Meer ohne irgendwelche Güter void noShip::DrawDriving(DrawPoint& drawPt) { // Interpolieren zwischen beiden Knotenpunkten drawPt += CalcWalkingRelative(); LOADER.GetImageN("boot_z", 13 + ((GetCurMoveDir() + 3) % 6) * 2)->Draw(drawPt, 0, 0, 0, 0, 0, 0, COLOR_SHADOW); LOADER.GetImageN("boot_z", 12 + ((GetCurMoveDir() + 3) % 6) * 2)->Draw(drawPt); }
/// Zeichnet normales Fahren auf dem Meer ohne irgendwelche Güter void noShip::DrawDriving(int& x, int& y) { // Interpolieren zwischen beiden Knotenpunkten CalcWalkingRelative(x, y); LOADER.GetImageN("boot_z", 13 + ((GetCurMoveDir() + 3) % 6) * 2)->Draw(x, y, 0, 0, 0, 0, 0, 0, COLOR_SHADOW); LOADER.GetImageN("boot_z", 12 + ((GetCurMoveDir() + 3) % 6) * 2)->Draw(x, y); }
/// Zeichnet das Schiff stehend mit oder ohne Waren void noShip::DrawFixed(const int x, const int y, const bool draw_wares) { LOADER.GetImageN("boot_z", ((GetCurMoveDir() + 3) % 6) * 2 + 1)->Draw(x, y, 0, 0, 0, 0, 0, 0, COLOR_SHADOW); LOADER.GetImageN("boot_z", ((GetCurMoveDir() + 3) % 6) * 2)->Draw(x, y); if(draw_wares) /// Waren zeichnen LOADER.GetImageN("boot_z", 30 + ((GetCurMoveDir() + 3) % 6))->Draw(x, y); }
bool noFigure::CalcFigurRelative(int& x, int& y) { int x1 = static_cast<int>(gwg->GetTerrainX(pos)); int y1 = static_cast<int>(gwg->GetTerrainY(pos)); int x2 = static_cast<int>(gwg->GetTerrainX(gwg->GetNeighbour(pos, GetCurMoveDir()))); int y2 = static_cast<int>(gwg->GetTerrainY(gwg->GetNeighbour(pos, GetCurMoveDir()))); // Gehen wir über einen Kartenrand (horizontale Richung?) if(std::abs(x1 - x2) >= gwg->GetWidth() * TR_W / 2) { if(std::abs(x1 - int(gwg->GetWidth())*TR_W - x2) < std::abs(x1 - x2)) x1 -= gwg->GetWidth() * TR_W; else x1 += gwg->GetWidth() * TR_W; } // Und dasselbe für vertikale Richtung if(std::abs(y1 - y2) >= gwg->GetHeight() * TR_H / 2) { if(std::abs(y1 - int(gwg->GetHeight())*TR_H - y2) < std::abs(y1 - y2)) y1 -= gwg->GetHeight() * TR_H; else y1 += gwg->GetHeight() * TR_H; } MapPoint nb = gwg->GetNeighbour(pos, 1); if(GetCurMoveDir() == 1 && (gwg->GetNO(nb)->GetType() == NOP_BUILDINGSITE || gwg->GetNO(nb)->GetType() == NOP_BUILDING)) { noBaseBuilding* bld = gwg->GetSpecObj<noBaseBuilding>(nb); x2 += bld->GetDoorPointX(); y2 += bld->GetDoorPointY(); x += bld->GetDoorPointX(); y += bld->GetDoorPointY(); } else if(gwg->GetNO(this->pos)->GetType() == NOP_BUILDINGSITE || gwg->GetNO(this->pos)->GetType() == NOP_BUILDING) { noBaseBuilding* bld = gwg->GetSpecObj<noBaseBuilding>(this->pos); x1 += bld->GetDoorPointX(); y1 += bld->GetDoorPointY(); x += bld->GetDoorPointX(); y += bld->GetDoorPointY(); } // Wenn die Träger runterlaufne, muss es andersrum sein, da die Träger dann immer vom OBEREN Punkt aus gezeichnet werden if(GetCurMoveDir() == 1 || GetCurMoveDir() == 2) { std::swap(x1, x2); std::swap(y1, y2); } CalcRelative(x, y, x1, y1, x2, y2); return 1; }
/// Zeichnet standardmäßig die Figur, wenn sie läuft aus einem bestimmten normalen LST Archiv void noFigure::DrawWalking(int x, int y, const char* const file, unsigned int id) { // Wenn wir warten, ani-step 2 benutzen unsigned ani_step = waiting_for_free_node ? 2 : GAMECLIENT.Interpolate(ASCENT_ANIMATION_STEPS[ascent], current_ev) % 8; // Wenn man wartet, stehend zeichnen, es sei denn man wartet mittem auf dem Weg! if(!waiting_for_free_node || pause_walked_gf) CalcFigurRelative(x, y); LOADER.GetImageN(file, id + ((GetCurMoveDir() + 3) % 6) * 8 + ani_step)->Draw(x, y, 0, 0, 0, 0, 0, 0, COLOR_WHITE, COLORS[gwg->GetPlayer(player).color]); DrawShadow(x, y, ani_step, GetCurMoveDir()); }
void noFigure::CorrectSplitData(const RoadSegment* const rs2) { // cur_rs entspricht Teilstück 1 ! // Wenn man sich auf den ersten Teilstück befindet... if((rs_pos < cur_rs->GetLength() && !rs_dir) || (rs_pos > rs2->GetLength() && rs_dir)) { // Nur Position berichtigen if(rs_dir) rs_pos -= rs2->GetLength(); } // Wenn man auf dem 2. steht, ... else if((rs_pos > cur_rs->GetLength() && !rs_dir) || (rs_pos < rs2->GetLength() && rs_dir)) { // Position berichtigen (wenn man in umgekehrter Richtung läuft, beibehalten!) if(!rs_dir) rs_pos -= cur_rs->GetLength(); // wir laufen auf dem 2. Teilstück cur_rs = rs2; } else if((rs_pos == cur_rs->GetLength() && !rs_dir) || (rs_pos == rs2->GetLength() && rs_dir)) { // wir stehen genau in der Mitte // abhängig von der Richtung machen, in die man gerade läuft if(GetCurMoveDir() == rs2->GetRoute(0)) { // wir laufen auf dem 2. Teilstück cur_rs = rs2; // und wir sind da noch am Anfang rs_pos = 0; } else if(GetCurMoveDir() == (cur_rs->GetRoute(cur_rs->GetLength() - 1) + 3) % 6) { // wir laufen auf dem 1. Teilstück // und wir sind da noch am Anfang rs_pos = 0; } else { // Wahrscheinlich stehen wir // dann einfach auf das 2. gehen cur_rs = rs2; rs_pos = 0; rs_dir = 0; } } CorrectSplitData_Derived(); }
void noShip::Driven() { MapPoint enemy_territory_discovered(MapPoint::Invalid()); gwg->RecalcMovingVisibilities(pos, player, GetVisualRange(), GetCurMoveDir(), &enemy_territory_discovered); // Feindliches Territorium entdeckt? if(enemy_territory_discovered.isValid()) { // Send message if necessary if(gwg->GetPlayer(player).ShipDiscoveredHostileTerritory(enemy_territory_discovered)) SendPostMessage(player, new PostMsg(GetEvMgr().GetCurrentGF(), _("A ship disovered an enemy territory"), PostCategory::Military, enemy_territory_discovered)); } switch(state) { case STATE_GOTOHARBOR: HandleState_GoToHarbor(); break; case STATE_EXPEDITION_DRIVING: HandleState_ExpeditionDriving(); break; case STATE_EXPLORATIONEXPEDITION_DRIVING: HandleState_ExplorationExpeditionDriving(); break; case STATE_TRANSPORT_DRIVING: HandleState_TransportDriving(); break; case STATE_SEAATTACK_DRIVINGTODESTINATION: HandleState_SeaAttackDriving(); break; case STATE_SEAATTACK_RETURN_DRIVING: HandleState_SeaAttackReturn(); break; default: RTTR_Assert(false); break; } }
void nofPlaner::HandleDerivedEvent(const unsigned int id) { if(id == 1) { // Planieren (falls Baustelle noch existiert) if(building_site) gwg->ChangeAltitude(pos, gwg->GetNode(building_site->GetPos()).altitude); /// Sounds abmelden SOUNDMANAGER.WorkingFinished(this); state = STATE_WALKING; // Planierung fertig --> weiterlaufen unsigned char curDir = GetCurMoveDir(); // Das erste Mal gelaufen? if(pd == PD_CLOCKWISE && curDir == 5) StartWalking(1); else if(pd == PD_COUNTERCLOCKWISE && curDir == 3) StartWalking(1); // Fertig -> zur Baustelle zurücklaufen else if(pd == PD_CLOCKWISE && curDir == 4) StartWalking(0); else if(pd == PD_COUNTERCLOCKWISE && curDir == 4) StartWalking(2); // In nächste Richtung gehen else if(pd == PD_CLOCKWISE) StartWalking((curDir + 1) % 6); else StartWalking((6 + curDir - 1) % 6); } }
void noShip::Driven() { MapPoint enemy_territory_discovered(0xffff, 0xffff); gwg->RecalcMovingVisibilities(pos, player, GetVisualRange(), GetCurMoveDir(), &enemy_territory_discovered); // Feindliches Territorium entdeckt? if(enemy_territory_discovered.x != 0xffff) { // Send message if necessary if(players->getElement(player)->ShipDiscoveredHostileTerritory (enemy_territory_discovered) && player == GAMECLIENT.GetPlayerID()) GAMECLIENT.SendPostMessage(new PostMsgWithLocation(_("A ship disovered an enemy territory"), PMC_MILITARY, enemy_territory_discovered)); } switch(state) { case STATE_GOTOHARBOR: HandleState_GoToHarbor(); break; case STATE_EXPEDITION_DRIVING: HandleState_ExpeditionDriving(); break; case STATE_EXPLORATIONEXPEDITION_DRIVING: HandleState_ExplorationExpeditionDriving(); break; case STATE_TRANSPORT_DRIVING: HandleState_TransportDriving(); break; case STATE_SEAATTACK_DRIVINGTODESTINATION: HandleState_SeaAttackDriving(); break; case STATE_SEAATTACK_RETURN: HandleState_SeaAttackReturn(); break; default: break; } }
void noFigure::DrawWalking(int x, int y, glArchivItem_Bob* file, unsigned int id, bool fat, bool waitingsoldier) { // Wenn wir warten auf ein freies Plätzchen, müssen wir den stehend zeichnen! unsigned ani_step = waiting_for_free_node || waitingsoldier ? 2 : GAMECLIENT.Interpolate(ASCENT_ANIMATION_STEPS[ascent], current_ev) % 8; // Wenn man wartet, stehend zeichnen, es sei denn man wartet mittem auf dem Weg! if(!waitingsoldier && (!waiting_for_free_node || pause_walked_gf)) CalcFigurRelative(x, y); if(file) file->Draw(id, GetCurMoveDir(), fat, ani_step, x, y, COLORS[gwg->GetPlayer(player).color]); DrawShadow(x, y, ani_step, GetCurMoveDir()); /*char number[256]; sprintf(number,"%u",obj_id); NormalFont->Draw(x,y,number,0,0xFFFF0000);*/ }
void nofTradeLeader::Walked() { // Exception handling: goal destroyed or sth. like this if(fails > 1) { WanderFailedTrade(); return; } bool invalid_goal = false; noBase* nob = gwg->GetNO(goal_); if(nob->GetType() != NOP_BUILDING) invalid_goal = true; if(!static_cast<noBuilding*>(nob)->IsWarehouse()) invalid_goal = true; unsigned char next_dir; if(invalid_goal) { TryToGoHome(); next_dir = tr.GetNextDir(); StartWalking(next_dir); } else { next_dir = tr.GetNextDir(); // Are we now at the goal? if(next_dir == REACHED_GOAL) { gwg->GetPlayer(static_cast<nobBaseWarehouse*>(nob)->GetPlayer()).IncreaseInventoryJob(this->GetJobType(), 1); gwg->RemoveFigure(this, pos); static_cast<nobBaseWarehouse*>(nob)->AddFigure(this); } else if(next_dir != NO_PATH) StartWalking(next_dir); else { TryToGoHome(); next_dir = tr.GetNextDir(); if(next_dir == NO_PATH) { CancelTradeCaravane(); next_dir = GetCurMoveDir(); //StartWanderingFailedTrade(); } StartWalking(next_dir); //next_dir=tr.GetNextDir(); //next_dir = dir; } } //if(successor&&next_dir!=NO_PATH) if(successor) { successor->AddNextDir(next_dir); } }
void noFigure::WalkFigure() { // Tür hinter sich zumachen, wenn wir aus einem Gebäude kommen if(GetCurMoveDir() == 4 && gwg->GetNO(pos)->GetType() == NOP_BUILDING) gwg->GetSpecObj<noBuilding>(pos)->CloseDoor(); Walk(); if(cur_rs) ++rs_pos; // oder in eins reingegangen sind if(GetCurMoveDir() == 1 && gwg->GetNO(pos)->GetType() == NOP_BUILDING) gwg->GetSpecObj<noBuilding>(pos)->CloseDoor(); }
void noFigure::StopIfNecessary(const MapPoint pt) { // Lauf ich auf Wegen --> wenn man zum Ziel oder Weg läuft oder die Träger, die natürlich auch auf Wegen arbeiten if(fs == FS_GOHOME || fs == FS_GOTOGOAL || (fs == FS_JOB && GetGOT() == GOT_NOF_CARRIER)) { // Laufe ich zu diesem Punkt? if(current_ev) { if(!waiting_for_free_node && gwg->GetNeighbour(this->pos, GetCurMoveDir()) == pt) { // Dann stehenbleiben PauseWalking(); waiting_for_free_node = true; gwg->StopOnRoads(this->pos, GetCurMoveDir()); } } } }
void noFigure::HandleEvent(const unsigned int id) { // Bei ID = 0 ists ein Laufevent, bei allen anderen an abgeleitete Klassen weiterleiten if(id) { HandleDerivedEvent(id); } else { current_ev = NULL; WalkFigure(); // Alte Richtung und Position für die Berechnung der Sichtbarkeiten merken unsigned char old_dir = GetCurMoveDir(); MapPoint old_pos(pos); switch(fs) { case FS_GOHOME: case FS_GOTOGOAL: { WalkToGoal(); } break; case FS_JOB: { Walked(); break; } case FS_WANDER: { Wander(); break; } } // Ggf. Sichtbereich testen if(GetVisualRange()) { // Use old position (don't use this->x/y because it might be different now // Figure could be in a ship etc.) gwg->RecalcMovingVisibilities(old_pos, player, GetVisualRange(), old_dir, NULL); std::vector<noBase*> figures = gwg->GetDynamicObjectsFrom(old_pos); // Wenn Figur verschwunden ist, muss ihr ehemaliger gesamter Sichtbereich noch einmal // neue berechnet werden if(!helpers::contains(figures, this)) CalcVisibilities(old_pos); } } }
void noFigure::DrawWalkingBobCarrier(int x, int y, unsigned int ware, bool fat) { // Wenn wir warten auf ein freies Plätzchen, müssen wir den stehend zeichnen! unsigned ani_step = waiting_for_free_node ? 2 : GAMECLIENT.Interpolate(ASCENT_ANIMATION_STEPS[ascent], current_ev) % 8; // Wenn man wartet, stehend zeichnen, es sei denn man wartet mittem auf dem Weg! if(!waiting_for_free_node || pause_walked_gf) CalcFigurRelative(x, y); LOADER.carrier_cache[ware][GetCurMoveDir()][ani_step][fat].draw(x, y, COLOR_WHITE, COLORS[gwg->GetPlayer(player).color]); }
void nofBuilder::StartFreewalk() { std::vector<unsigned char> possible_directions; unsigned char waiting_walk = ((state == STATE_WAITINGFREEWALK) ? 0 : 1); // Wohin kann der Bauarbeiter noch laufen? // Nach links if(rel_x - FREEWALK_LENGTH[waiting_walk] >= LEFT_MAX) possible_directions.push_back(0); // Nach rechts if(rel_x + FREEWALK_LENGTH[waiting_walk] <= RIGHT_MAX) possible_directions.push_back(3); // Nach links/oben if(rel_x - FREEWALK_LENGTH_SLANTWISE[waiting_walk] >= LEFT_MAX && rel_y - FREEWALK_LENGTH_SLANTWISE[waiting_walk] >= UP_MAX) possible_directions.push_back(1); // Nach links/unten if(rel_x - FREEWALK_LENGTH_SLANTWISE[waiting_walk] >= LEFT_MAX && rel_y + FREEWALK_LENGTH_SLANTWISE[waiting_walk] <= DOWN_MAX) possible_directions.push_back(5); // Nach rechts/oben if(rel_x + FREEWALK_LENGTH_SLANTWISE[waiting_walk] <= RIGHT_MAX && rel_y - FREEWALK_LENGTH_SLANTWISE[waiting_walk] >= UP_MAX) possible_directions.push_back(2); // Nach rechts/unten if(rel_x + FREEWALK_LENGTH_SLANTWISE[waiting_walk] <= RIGHT_MAX && rel_y + FREEWALK_LENGTH_SLANTWISE[waiting_walk] <= DOWN_MAX) possible_directions.push_back(4); assert(possible_directions.size() > 0); // Zufällige Richtung von diesen auswählen FaceDir(possible_directions[RANDOM.Rand(__FILE__, __LINE__, GetObjId(), possible_directions.size())]); // Und dort auch hinlaufen current_ev = em->AddEvent(this, (state == STATE_WAITINGFREEWALK) ? 24 : 17, 1); // Zukünftigen Platz berechnen next_rel_x = rel_x; next_rel_y = rel_y; switch(GetCurMoveDir()) { case 0: next_rel_x -= FREEWALK_LENGTH[waiting_walk]; break; case 1: next_rel_x -= FREEWALK_LENGTH_SLANTWISE[waiting_walk]; next_rel_y -= FREEWALK_LENGTH_SLANTWISE[waiting_walk]; break; case 2: next_rel_x += FREEWALK_LENGTH_SLANTWISE[waiting_walk]; next_rel_y -= FREEWALK_LENGTH_SLANTWISE[waiting_walk]; break; case 3: next_rel_x += FREEWALK_LENGTH[waiting_walk]; break; case 4: next_rel_x += FREEWALK_LENGTH_SLANTWISE[waiting_walk]; next_rel_y += FREEWALK_LENGTH_SLANTWISE[waiting_walk]; break; case 5: next_rel_x -= FREEWALK_LENGTH_SLANTWISE[waiting_walk]; next_rel_y += FREEWALK_LENGTH_SLANTWISE[waiting_walk]; break; } }
void noFigure::DrawWalkingBobJobs(int x, int y, unsigned int job) { if ((job == JOB_SCOUT) || ((job >= JOB_PRIVATE) && (job <= JOB_GENERAL))) { DrawWalking(x, y, LOADER.GetBobN("jobs"), JOB_CONSTS[job].jobs_bob_id + NATION_RTTR_TO_S2[gwg->GetPlayer(player).nation] * 6, false); return; } // Wenn wir warten auf ein freies Plätzchen, müssen wir den stehend zeichnen! unsigned ani_step = waiting_for_free_node ? 2 : GAMECLIENT.Interpolate(ASCENT_ANIMATION_STEPS[ascent], current_ev) % 8; // Wenn man wartet, stehend zeichnen, es sei denn man wartet mittem auf dem Weg! if(!waiting_for_free_node || pause_walked_gf) CalcFigurRelative(x, y); LOADER.bob_jobs_cache[gwg->GetPlayer(player).nation][job][GetCurMoveDir()][ani_step].draw(x, y, 0xFFFFFFFF, COLORS[gwg->GetPlayer(player).color]); }
/** * * * @author OLiver */ void nofCarrier::FetchWare(const bool swap_wares) { // Ware aufnehmnen carried_ware = gwg->GetSpecObj<noFlag>(pos)->SelectWare((GetCurMoveDir() + 3) % 6, swap_wares, this); if(carried_ware) { carried_ware->Carry((rs_dir) ? workplace->GetF2() : workplace->GetF1()); // Und zum anderen Ende laufen state = CARRS_CARRYWARE; rs_dir = !rs_dir; rs_pos = 0; StartWalking(cur_rs->GetDir(rs_dir, rs_pos)); } else // zurücklaufen lassen state = CARRS_GOTOMIDDLEOFROAD; }
MapPoint noAnimal::HunterIsNear() { // Steht es gerade? if(state == STATE_PAUSED) { // dann bleibt es einfach stehen und gibt seine jetzigen Koordinaten zurück state = STATE_WAITINGFORHUNTER; // Warteevent abmelden em->RemoveEvent(current_ev); current_ev = 0; return pos; } else { // ansonsten nach dem Laufen stehenbleiben und die Koordinaten zurückgeben von dem Punkt, der erreicht wird state = STATE_WALKINGUNTILWAITINGFORHUNTER; return gwg->GetNeighbour(pos, GetCurMoveDir()); } }
/** * * * @author OLiver */ void nofCarrier::GoalReached() { // Erstes Produktivitätsevent anmelden productivity_ev = em->AddEvent(this, PRODUCTIVITY_GF, 1); // Wir arbeiten schonmal StartWorking(); noRoadNode* rn = gwg->GetSpecObj<noRoadNode>(pos); for(unsigned char i = 0; i < 6; ++i) { //noRoadNode * rn = gwg->GetSpecObj<noRoadNode>(x,y); if(rn->routes[i] == workplace) { // Am neuen Arbeitsplatz angekommen StartWalking(i); cur_rs = workplace; rs_pos = 0; rs_dir = (rn == cur_rs->GetF1()) ? false : true; state = CARRS_GOTOMIDDLEOFROAD; // Wenn hier schon Waren liegen, diese gleich transportieren if(workplace->AreWareJobs(rs_dir, ct, true)) { // Ware aufnehmen carried_ware = static_cast<noFlag*>(rn)->SelectWare(GetCurMoveDir(), false, this); if(carried_ware) { carried_ware->Carry( (rs_dir ? workplace->GetF1() : workplace->GetF2()) ); state = CARRS_CARRYWARE; } } // wenn was an der gegenüberliegenden Flaggge liegt, ebenfalls holen else if(workplace->AreWareJobs(!rs_dir, ct, false)) state = CARRS_FETCHWARE; return; } } LOG.lprintf("nofCarrier::GoalReached: ERROR: Road of carrier (id: %u) not found!\n", GetObjId()); }
/// Zeichnet normales Fahren auf dem Meer mit Gütern void noShip::DrawDrivingWithWares(DrawPoint& drawPt) { DrawDriving(drawPt); /// Waren zeichnen LOADER.GetImageN("boot_z", 30 + ((GetCurMoveDir() + 3) % 6))->Draw(drawPt); }
void noShip::Draw(int x, int y) { unsigned flag_drawing_type = 1; // Sind wir verloren? Dann immer stehend zeichnen if(lost) { DrawFixed(x, y, true); return; } switch(state) { default: break; case STATE_IDLE: case STATE_SEAATTACK_WAITING: { DrawFixed(x, y, false); flag_drawing_type = 0; } break; case STATE_GOTOHARBOR: { DrawDriving(x, y); } break; case STATE_EXPEDITION_LOADING: case STATE_EXPEDITION_UNLOADING: case STATE_TRANSPORT_LOADING: case STATE_TRANSPORT_UNLOADING: case STATE_SEAATTACK_LOADING: case STATE_SEAATTACK_UNLOADING: case STATE_EXPLORATIONEXPEDITION_LOADING: case STATE_EXPLORATIONEXPEDITION_UNLOADING: { DrawFixed(x, y, false); } break; case STATE_EXPLORATIONEXPEDITION_WAITING: case STATE_EXPEDITION_WAITING: { DrawFixed(x, y, true); } break; case STATE_EXPEDITION_DRIVING: case STATE_TRANSPORT_DRIVING: case STATE_SEAATTACK_DRIVINGTODESTINATION: case STATE_EXPLORATIONEXPEDITION_DRIVING: { DrawDrivingWithWares(x, y); } break; case STATE_SEAATTACK_RETURN: { if(!figures.empty() || !wares.empty()) DrawDrivingWithWares(x, y); else DrawDriving(x, y); } break; } LOADER.GetImageN("boot_z", 40 + GAMECLIENT.GetGlobalAnimation(6, 1, 1, GetObjId()))-> Draw(x + SHIPS_FLAG_POS[GetCurMoveDir() + flag_drawing_type * 6].x, y + SHIPS_FLAG_POS[GetCurMoveDir() + flag_drawing_type * 6].y, 0, 0, 0, 0, 0, 0, COLOR_WHITE, COLORS[gwg->GetPlayer(player).color]); // Second, white flag, only when on expedition, always swinging in the opposite direction if(state >= STATE_EXPEDITION_LOADING && state <= STATE_EXPEDITION_DRIVING) LOADER.GetImageN("boot_z", 40 + GAMECLIENT.GetGlobalAnimation(6, 1, 1, GetObjId() + 4))-> Draw(x + SHIPS_FLAG_POS[GetCurMoveDir() + flag_drawing_type * 6].x, y + 4 + SHIPS_FLAG_POS[GetCurMoveDir() + flag_drawing_type * 6].y, 0, 0, 0, 0, 0, 0, COLOR_WHITE, COLOR_WHITE); }
/** * * * @author OLiver */ void nofCarrier::LostWork() { workplace = 0; em->RemoveEvent(productivity_ev); productivity_ev = 0; if(state == CARRS_FIGUREWORK) GoHome(); else { // Wenn ich noch ne Ware in der Hand habe, muss die gelöscht werden if(carried_ware) { carried_ware->WareLost(player); delete carried_ware; carried_ware = 0; } // Is this a boat carrier (i.e. he is on the water) if(ct == CT_BOAT) { MapPoint tmpPos(pos); if(state != CARRS_WAITFORWARE && state != CARRS_WAITFORWARESPACE) { // If we are walking choose the destination point as start point // for the pathfinding! tmpPos = gwg->GetNeighbour(tmpPos, GetCurMoveDir()); } // Look for the shore for(MapCoord tx = gwg->GetXA(tmpPos, 0), r = 1; r <= 5; tx = gwg->GetXA(tx, tmpPos.y, 0), ++r) { MapPoint t2(tx, tmpPos.y); for(unsigned i = 2; i < 8; ++i) { for(MapCoord r2 = 0; r2 < r; t2 = gwg->GetNeighbour(t2, i % 6), ++r2) { if(gwg->IsCoastalPoint(t2) && gwg->IsNodeForFigures(t2)) { shore_path = new std::vector<unsigned char>; if(gwg->FindShipPath(tmpPos, t2, shore_path, NULL)) { // Ok let's paddle to the coast rs_pos = 0; cur_rs = NULL; if(state == CARRS_WAITFORWARE || state == CARRS_WAITFORWARESPACE) WanderOnWater(); state = CARRS_BOATCARRIER_WANDERONWATER; return; } } } } } } StartWandering(); if(state == CARRS_WAITFORWARE || state == CARRS_WAITFORWARESPACE) Wander(); } state = CARRS_FIGUREWORK; }
void noAnimal::Draw(int x, int y) { // Tier zeichnen /*char str[255]; sprintf(str,"%u",obj_id); LOADER.GetFontN("resource",0)->Draw(x,y,str,0,0xFFFF0000);*/ switch(state) { default: break; case STATE_WALKINGUNTILWAITINGFORHUNTER: case STATE_WALKING: { // Laufend (bzw. Ente schwimmend zeichnen) // Interpolieren zwischen beiden Knotenpunkten CalcWalkingRelative(x, y); unsigned ani_step = GAMECLIENT.Interpolate(ASCENT_ANIMATION_STEPS[ascent], current_ev) % ANIMALCONSTS[species].animation_steps; // Zeichnen LOADER.animal_cache[species][GetCurMoveDir()][ani_step].draw(x, y); // Bei Enten und Schafen: Soll ein Sound gespielt werden? if(species == SPEC_DUCK || species == SPEC_SHEEP) { unsigned int now = VIDEODRIVER.GetTickCount(); // Wurde der Soundzeitpunkt schon überschritten? if(now > sound_moment) { // Wenns in dem jeweiligen Rahmen liegt, Sound abspielen if((now < sound_moment + 1000) && !GAMECLIENT.IsPaused()) LOADER.GetSoundN("sound", (species == SPEC_SHEEP) ? 94 : 95)->Play(50 + rand() % 70, false); // Neuen Zeitpunkt errechnen sound_moment = now + 8000 + rand() % 5000; } } } break; case STATE_WAITINGFORHUNTER: case STATE_PAUSED: { // Stehend zeichnen LOADER.animal_cache[species][GetCurMoveDir()][0].draw(x, y); } break; case STATE_DEAD: { if (LOADER.animal_cache[species][0][ANIMAL_MAX_ANIMATION_STEPS].isGenerated()) { LOADER.animal_cache[species][0][ANIMAL_MAX_ANIMATION_STEPS].draw(x, y); } } break; case STATE_DISAPPEARING: { // Alpha-Wert ausrechnen unsigned char alpha = 0xFF - GAMECLIENT.Interpolate(0xFF, current_ev); // Gibts ein Leichenbild? if (LOADER.animal_cache[species][0][ANIMAL_MAX_ANIMATION_STEPS].isGenerated()) { LOADER.animal_cache[species][0][ANIMAL_MAX_ANIMATION_STEPS].draw(x, y, SetAlpha(COLOR_WHITE, alpha)); } else { // Stehend zeichnen LOADER.animal_cache[species][GetCurMoveDir()][0].draw(x, y, SetAlpha(COLOR_WHITE, alpha)); } } break; } }
/** * * * @author OLiver */ void nofCarrier::Walked() { // Bootssounds ggf. löschen if(ct == CT_BOAT && state != CARRS_FIGUREWORK) SOUNDMANAGER.WorkingFinished(this); switch(state) { default: break; case CARRS_GOTOMIDDLEOFROAD: { // Gibts an der Flagge in der entgegengesetzten Richtung, in die ich laufe, evtl Waren zu tragen // (da wir darüber nicht unmittelbar informiert werden!) if(workplace->AreWareJobs(rs_dir, ct, false)) { // Dann umdrehen und holen rs_dir = !rs_dir; rs_pos = workplace->GetLength() - rs_pos; state = CARRS_FETCHWARE; StartWalking(cur_rs->GetDir(rs_dir, rs_pos)); } else if(rs_pos == cur_rs->GetLength() / 2 || rs_pos == cur_rs->GetLength() / 2 + cur_rs->GetLength() % 2) { // Wir sind in der Mitte angekommen state = CARRS_WAITFORWARE; if(GetCurMoveDir() == 0 || GetCurMoveDir() == 1 || GetCurMoveDir() == 5) FaceDir(5); else FaceDir(4); current_ev = 0; // Jetzt wird wieder nur rumgegammelt, dann kriegen wir aber evtl keinen schönen IH-AH! StopWorking(); // Animation auf später verschieben, damit die nicht mittendrin startet SetNewAnimationMoment(); } else { // Eventuell laufen wir in die falsche Richtung? if(rs_pos > cur_rs->GetLength() / 2) { rs_dir = !rs_dir; rs_pos = cur_rs->GetLength() - rs_pos; } StartWalking(cur_rs->GetDir(rs_dir, rs_pos)); } } break; case CARRS_FETCHWARE: { // Zur Flagge laufen, um die Ware zu holen // Sind wir schon da? if(rs_pos == cur_rs->GetLength()) // Dann Ware aufnehmnen FetchWare(false); else StartWalking(cur_rs->GetDir(rs_dir, rs_pos)); } break; case CARRS_CARRYWARE: { // Sind wir schon da? if(rs_pos == cur_rs->GetLength()) { // Flagge, an der wir gerade stehen noFlag* this_flag = static_cast<noFlag*>(((rs_dir) ? workplace->GetF1() : workplace->GetF2())); bool calculated = false; // Will die Waren jetzt gleich zur Baustelle neben der Flagge? if(WantInBuilding(&calculated)) { // Erst noch zur Baustelle bzw Gebäude laufen state = CARRS_CARRYWARETOBUILDING; StartWalking(1); cur_rs = this_flag->routes[1]; // location wird immer auf nächste Flagge gesetzt --> in dem Fall aktualisieren carried_ware->Carry((cur_rs->GetF1() == this_flag) ? cur_rs->GetF2() : cur_rs->GetF1()); } else { // Ist an der Flagge noch genügend Platz (wenn wir wieder eine Ware mitnehmen, kann sie auch voll sein) if(this_flag->IsSpaceForWare()) { carried_ware->LieAtFlag(this_flag); // Ware soll ihren weiteren Weg berechnen if (!calculated) { carried_ware->RecalcRoute(); } // Ware ablegen this_flag->AddWare(carried_ware); // Wir tragen erstmal keine Ware mehr carried_ware = 0; // Gibts an den Flaggen etwas, was ich tragen muss, ansonsten wieder in die Mitte gehen und warten LookForWares(); } else if(workplace->AreWareJobs(!rs_dir, ct, true)) { // die Flagge ist voll, aber wir können eine Ware mitnehmen, daher erst Ware nehmen und dann erst ablegen // Ware "merken" Ware* tmp_ware = carried_ware; // neue Ware aufnehmen FetchWare(true); // alte Ware ablegen tmp_ware->LieAtFlag(this_flag); if (!calculated) { tmp_ware->RecalcRoute(); } this_flag->AddWare(tmp_ware); } else { // wenn kein Platz mehr ist --> wieder umdrehen und zurückgehen state = CARRS_GOBACKFROMFLAG; rs_dir = !rs_dir; rs_pos = cur_rs->GetLength() - rs_pos; StartWalking((GetCurMoveDir() + 3) % 6); } } } else if(rs_pos == cur_rs->GetLength() - 1) { // Wenn wir fast da sind, gucken, ob an der Flagge noch ein freier Platz ist noFlag* this_flag = static_cast<noFlag*>(((rs_dir) ? workplace->GetF1() : workplace->GetF2())); if(this_flag->IsSpaceForWare() || WantInBuilding(NULL) || cur_rs->AreWareJobs(!rs_dir, ct, true)) { // Es ist Platz, dann zur Flagge laufen StartWalking(cur_rs->GetDir(rs_dir, rs_pos)); } else { // Wenn kein Platz ist, stehenbleiben und warten! state = CARRS_WAITFORWARESPACE; FaceDir(cur_rs->GetDir(rs_dir, rs_pos)); } } else { StartWalking(cur_rs->GetDir(rs_dir, rs_pos)); } } break; case CARRS_CARRYWARETOBUILDING: { // Ware ablegen gwg->GetSpecObj<noRoadNode>(pos)->AddWare(carried_ware); // Ich trag' keine Ware mehr carried_ware = 0; // Wieder zurück zu meinem Weg laufen state = CARRS_LEAVEBUILDING; StartWalking(4); } break; case CARRS_LEAVEBUILDING: { // So tun, als ob der Träger gerade vom anderen Ende des Weges kommt, damit alles korrekt funktioniert cur_rs = workplace; FaceDir(workplace->GetDir(rs_dir, workplace->GetLength() - 1)); LookForWares(); } break; case CARRS_GOBACKFROMFLAG: { // Wieder umdrehen und so tun, als wären wir gerade normal angekommen rs_dir = !rs_dir; rs_pos = cur_rs->GetLength() - rs_pos; state = CARRS_CARRYWARE; Walked(); } break; case CARRS_BOATCARRIER_WANDERONWATER: { WanderOnWater(); } break; } }
void nofBuilder::Draw(int x, int y) { switch(state) { case STATE_FIGUREWORK: { DrawWalkingBobJobs(x, y, JOB_BUILDER); } break; case STATE_BUILDFREEWALK: case STATE_WAITINGFREEWALK: { // Interpolieren und Door-Point von Baustelle draufaddieren x += (GAMECLIENT.Interpolate(rel_x, next_rel_x, current_ev) + building_site->GetDoorPointX()); y += (GAMECLIENT.Interpolate(rel_y, next_rel_y, current_ev) + building_site->GetDoorPointY()); LOADER.bob_jobs_cache[building_site->GetNation()][JOB_BUILDER][GetCurMoveDir()][GAMECLIENT.Interpolate(12, current_ev) % 8].draw(x, y, COLOR_WHITE, COLORS[gwg->GetPlayer(player).color]); // LOADER.GetBobN("jobs")->Draw(23,dir,false,GAMECLIENT.Interpolate(12,current_ev)%8,x,y,COLORS[gwg->GetPlayer(player).color]); // DrawShadow(x,y,GAMECLIENT.Interpolate(12,current_ev)%8,dir); /*LOADER.GetBobN("jobs")->Draw(23,dir,false,GAMECLIENT.Interpolate((state==STATE_WAITINGFREEWALK)?8:5,current_ev),x,y,COLORS[gwg->GetPlayer(player).color]); DrawShadow(x,y,GAMECLIENT.Interpolate(16,current_ev)%8);*/ } break; case STATE_BUILD: { unsigned index = GAMECLIENT.Interpolate(28, current_ev); // Je nachdem, wie weit der Bauarbeiter links bzw rechts oder in der Mitte steht, so wird auch die Animation angezeigt if(rel_x < -5) { // von links mit Hammer if(index < 12 || index > 19) { // Bauarbeiter steht LOADER.GetImageN("rom_bobs", 353 + index % 4)->Draw(x + building_site->GetDoorPointX() + rel_x, y + building_site->GetDoorPointY() + rel_y, 0, 0, 0, 0, 0, 0, COLOR_WHITE, COLORS[gwg->GetPlayer(building_site->GetPlayer()).color]); if(index % 4 == 2) SOUNDMANAGER.PlayNOSound(78, this, index, 160 - rand() % 60); } else { // er kniet LOADER.GetImageN("rom_bobs", 283 + index % 4)->Draw(x + building_site->GetDoorPointX() + rel_x, y + building_site->GetDoorPointY() + rel_y, 0, 0, 0, 0, 0, 0, COLOR_WHITE, COLORS[gwg->GetPlayer(building_site->GetPlayer()).color]); if(index % 4 == 2) SOUNDMANAGER.PlayNOSound(72, this, index, 160 - rand() % 60); } } else if(rel_x < 5) { // in der Mitte mit "Händen" LOADER.GetImageN("rom_bobs", 287 + (index / 2) % 4)->Draw(x + building_site->GetDoorPointX() + rel_x, y + building_site->GetDoorPointY() + rel_y, 0, 0, 0, 0, 0, 0, COLOR_WHITE, COLORS[gwg->GetPlayer(building_site->GetPlayer()).color]); } else { // von rechts mit Hammer if(index < 12 || index > 19) { // Bauarbeiter steht LOADER.GetImageN("rom_bobs", 279 + index % 4)->Draw(x + building_site->GetDoorPointX() + rel_x, y + building_site->GetDoorPointY() + rel_y, 0, 0, 0, 0, 0, 0, COLOR_WHITE, COLORS[gwg->GetPlayer(building_site->GetPlayer()).color]); if(index % 4 == 2) SOUNDMANAGER.PlayNOSound(78, this, index, 160 - rand() % 60); } else { // er kniet LOADER.GetImageN("rom_bobs", 283 + index % 4)->Draw(x + building_site->GetDoorPointX() + rel_x, y + building_site->GetDoorPointY() + rel_y, 0, 0, 0, 0, 0, 0, COLOR_WHITE, COLORS[gwg->GetPlayer(building_site->GetPlayer()).color]); if(index % 4 == 2) SOUNDMANAGER.PlayNOSound(72, this, index, 160 - rand() % 60); } } } break; } //char number[256]; //sprintf(number,"%u",obj_id); //NormalFont->Draw(x,y,number,0,0xFFFF0000); }
/** * * * @author OLiver */ void nofCarrier::Draw(int x, int y) { // Unterscheiden, um was für eine Art von Träger es sich handelt switch(ct) { case CT_NORMAL: { if(state == CARRS_WAITFORWARE || (waiting_for_free_node && !pause_walked_gf && !carried_ware)) { bool animation = false; // Ist es schon Zeit für eine Animation? unsigned current_gf = GAMECLIENT.GetGFNumber(); if(current_gf >= next_animation) { // Animationstype bestimmen unsigned animation_id = next_animation % 4; // <Silvesteregg> // day of year, 0-365, accuracy about 1/4 day int doy = (TIME.CurrentTime() % 31556925) / 86400; // last hours of last or first day of year if ((doy > 364) || (doy < 1)) { animation_id = next_animation % 5; } // </Silvesteregg> // Ist die Animation schon vorbei? if (((animation_id < 4) && (current_gf >= next_animation + ANIMATION_FRAME_LENGTHS[fat ? 1 : 0][animation_id]*FRAME_GF)) || ((animation_id == 4) && (current_gf >= next_animation + 32 * 3))) { // Neuen nächsten Animationszeitpunkt bestimmen SetNewAnimationMoment(); } else { animation = true; if (animation_id < 4) { // Nein, dann Animation abspielen LOADER.GetImageN("rom_bobs", ANIMATION[fat ? 1 : 0][animation_id][(current_gf - next_animation) / FRAME_GF]) ->Draw(x, y, 0, 0, 0, 0, 0, 0, COLOR_WHITE, COLORS[gwg->GetPlayer(player)->color]); } else if (animation_id == 4) // Silvesteregg { glArchivItem_Bitmap* bmp = LOADER.GetImageN("firework", (current_gf - next_animation) / 3 + 1); if (bmp) { bmp->Draw(x - 26, y - 104, 0, 0, 0, 0, 0, 0, COLOR_WHITE, COLORS[gwg->GetPlayer(player)->color]); } else { SetNewAnimationMoment(); animation = false; } } } } if(!animation) { Loader::bob_jobs_cache[gwg->GetPlayer(player)->nation][fat ? JOB_TYPES_COUNT : 0][GetCurMoveDir()][2].draw(x, y, COLOR_WHITE, COLORS[gwg->GetPlayer(player)->color]); } else // Steht und wartet (ohne Ware) // LOADER.GetBobN("jobs")->Draw(0,dir,fat,2,x,y,COLORS[gwg->GetPlayer(player)->color]); DrawShadow(x, y, 0, GetCurMoveDir()); } else if(state == CARRS_WAITFORWARESPACE || (waiting_for_free_node && !pause_walked_gf && carried_ware)) { // Steht und wartet (mit Ware) Loader::carrier_cache[carried_ware->type][GetCurMoveDir()][2][fat].draw(x, y, COLOR_WHITE, COLORS[gwg->GetPlayer(player)->color]); // Japaner-Schild-Animation existiert leider nicht --> Römerschild nehmen // LOADER.GetBobN("carrier")->Draw((carried_ware->type==GD_SHIELDJAPANESE)?GD_SHIELDROMANS:carried_ware->type, // dir,fat,2,x,y,COLORS[gwg->GetPlayer(player)->color]); // DrawShadow(x,y,0,dir); } else { // Läuft normal mit oder ohne Ware if(carried_ware) DrawWalkingBobCarrier(x, y, carried_ware->type, fat); // DrawWalking(x,y,LOADER.GetBobN("carrier"),(carried_ware->type==GD_SHIELDJAPANESE)?GD_SHIELDROMANS:carried_ware->type,fat); else DrawWalkingBobJobs(x, y, fat ? JOB_TYPES_COUNT : 0); } } break; case CT_DONKEY: { if(state == CARRS_WAITFORWARE || (waiting_for_free_node && !pause_walked_gf && !carried_ware)) { // Steht und wartet (ohne Ware) // Esel Loader::donkey_cache[GetCurMoveDir()][0].draw(x, y); } else if(state == CARRS_WAITFORWARESPACE || (waiting_for_free_node && !pause_walked_gf && carried_ware)) { //// Steht und wartet (mit Ware) //// Japaner-Schild-Animation existiert leider nicht --> Römerschild nehmen // Esel Loader::donkey_cache[GetCurMoveDir()][0].draw(x, y); // Ware im Korb zeichnen LOADER.GetMapImageN(2350 + carried_ware->type)->Draw(x + WARE_POS_DONKEY[GetCurMoveDir() * 16], y + WARE_POS_DONKEY[GetCurMoveDir() * 16 + 1]); } else { // Wenn wir warten auf ein freies Plätzchen, müssen wir den stehend zeichnen! // Wenn event = 0, dann sind wir mittem auf dem Weg angehalten! unsigned ani_step = waiting_for_free_node ? 2 : GAMECLIENT.Interpolate(ASCENT_ANIMATION_STEPS[ascent], current_ev) % 8; CalcFigurRelative(x, y); // Läuft normal mit oder ohne Ware // Esel Loader::donkey_cache[GetCurMoveDir()][ani_step].draw(x, y); if(carried_ware) { // Ware im Korb zeichnen LOADER.GetMapImageN(2350 + carried_ware->type)->Draw(x + WARE_POS_DONKEY[GetCurMoveDir() * 16 + ani_step * 2], y + WARE_POS_DONKEY[GetCurMoveDir() * 16 + ani_step * 2 + 1]); } } } break; case CT_BOAT: { if(state == CARRS_FIGUREWORK) { // Beim normalen Laufen Träger mit Boot über den Schultern zeichnen DrawWalkingBobCarrier(x, y, GD_BOAT, fat); // DrawWalking(x,y,LOADER.GetBobN("carrier"),GD_BOAT,fat); } else if(state == CARRS_WAITFORWARE || (waiting_for_free_node && !pause_walked_gf && !carried_ware)) { Loader::boat_cache[GetCurMoveDir()][0].draw(x, y, 0xFFFFFFFF, COLORS[gwg->GetPlayer(player)->color]); } else if(state == CARRS_WAITFORWARESPACE || (waiting_for_free_node && !pause_walked_gf && carried_ware)) { Loader::boat_cache[GetCurMoveDir()][0].draw(x, y, 0xFFFFFFFF, COLORS[gwg->GetPlayer(player)->color]); // Ware im Boot zeichnen LOADER.GetMapImageN(2350 + carried_ware->type)->Draw(x + WARE_POS_BOAT[GetCurMoveDir() * 2], y + WARE_POS_BOAT[GetCurMoveDir() * 2 + 1]); } else { // Wenn wir warten auf ein freies Plätzchen, müssen wir den (fest)stehend zeichnen! // Wenn event = 0, dann sind wir mittem auf dem Weg angehalten! unsigned ani_step = waiting_for_free_node ? 2 : GAMECLIENT.Interpolate(ASCENT_ANIMATION_STEPS[ascent], current_ev) % 8; CalcFigurRelative(x, y); // ruderndes Boot zeichnen Loader::boat_cache[GetCurMoveDir()][ani_step].draw(x, y, 0xFFFFFFFF, COLORS[gwg->GetPlayer(player)->color]); // Läuft normal mit oder ohne Ware if(carried_ware) // Ware im Boot zeichnen LOADER.GetMapImageN(2350 + carried_ware->type)->Draw(x + WARE_POS_BOAT[GetCurMoveDir() * 2], y + WARE_POS_BOAT[GetCurMoveDir() * 2 + 1]); // Sound ggf. abspielen if(ani_step == 2) SOUNDMANAGER.PlayNOSound(84, this, 0); last_id = ani_step; } } break; } }