/** ** Draw unit on map. */ void CUnit::Draw(const CViewport &vp) const { int frame; int state; int constructed; const CConstructionFrame *cframe; const CUnitType *type; if (this->Destroyed || this->Container || this->Type->Revealer) { // Revealers are not drawn return; } bool IsVisible = this->IsVisible(*ThisPlayer); // Those should have been filtered. Check doesn't make sense with ReplayRevealMap Assert(ReplayRevealMap || this->Type->VisibleUnderFog || IsVisible); int player = this->RescuedFrom ? this->RescuedFrom->Index : this->Player->Index; int action = this->CurrentAction(); PixelPos screenPos; if (ReplayRevealMap || IsVisible) { screenPos = vp.MapToScreenPixelPos(this->GetMapPixelPosTopLeft()); type = this->Type; frame = this->Frame; state = (action == UnitActionBuilt) | ((action == UnitActionUpgradeTo) << 1); constructed = this->Constructed; // Reset Type to the type being upgraded to if (action == UnitActionUpgradeTo) { const COrder_UpgradeTo &order = *static_cast<COrder_UpgradeTo *>(this->CurrentOrder()); type = &order.GetUnitType(); } if (this->CurrentAction() == UnitActionBuilt) { COrder_Built &order = *static_cast<COrder_Built *>(this->CurrentOrder()); cframe = &order.GetFrame(); } else { cframe = NULL; } } else { screenPos = vp.TilePosToScreen_TopLeft(this->Seen.tilePos); screenPos.x += this->Seen.IX; screenPos.y += this->Seen.IY; frame = this->Seen.Frame; type = this->Seen.Type; constructed = this->Seen.Constructed; state = this->Seen.State; cframe = this->Seen.CFrame; } #ifdef DYNAMIC_LOAD if (!type->Sprite) { LoadUnitTypeSprite(type); } #endif if (!IsVisible && frame == UnitNotSeen) { DebugPrint("FIXME: Something is wrong, unit %d not seen but drawn time %lu?.\n" _C_ UnitNumber(*this) _C_ GameCycle); return; } if (state == 1 && constructed && cframe) { DrawConstructionShadow(*type, cframe, frame, screenPos); } else { if (action != UnitActionDie) { DrawShadow(*type, frame, screenPos); } } // // Show that the unit is selected // DrawUnitSelection(vp, *this); // // Adjust sprite for Harvesters. // CPlayerColorGraphic *sprite = type->Sprite; if (type->Harvester && this->CurrentResource) { ResourceInfo *resinfo = type->ResInfo[this->CurrentResource]; if (this->ResourcesHeld) { if (resinfo->SpriteWhenLoaded) { sprite = resinfo->SpriteWhenLoaded; } } else { if (resinfo->SpriteWhenEmpty) { sprite = resinfo->SpriteWhenEmpty; } } } // // Now draw! // Buildings under construction/upgrade/ready. // if (state == 1) { if (constructed && cframe) { const PixelPos pos(screenPos + (type->GetPixelSize()) / 2); DrawConstruction(GameSettings.Presets[player].PlayerColor, cframe, *type, frame, pos); } else { DrawUnitType(*type, sprite, GameSettings.Presets[player].PlayerColor, frame, screenPos); } // // Draw the future unit type, if upgrading to it. // } else { DrawUnitType(*type, sprite, GameSettings.Presets[player].PlayerColor, frame, screenPos); } // Unit's extras not fully supported.. need to be decorations themselves. DrawInformations(*this, *type, screenPos); }
/** ** Draw unit on map. */ void CUnit::Draw(const CViewport *vp) const { int x; int y; int frame; int state; int constructed; CPlayerColorGraphic *sprite; ResourceInfo *resinfo; CConstructionFrame *cframe; CUnitType *type; /* * Since we can draw in parallel to game logic units may be already destroyed * or removed (this->Container != NULL) most dangerus is destroyed state * but due existence of UnitCashe, unit memory is always valid only we need check * Destroyed flag... the hack is that this->Type == NULL but 'or' logic * should secure this scenario and retir before this->Type->Revealer check */ if (this->Destroyed || this->Container || this->Type->Revealer) { // Revealers are not drawn return; } bool IsVisible = this->IsVisible(ThisPlayer); // Those should have been filtered. Check doesn't make sense with ReplayRevealMap Assert(ReplayRevealMap || this->Type->VisibleUnderFog || IsVisible); int player = this->RescuedFrom ? this->RescuedFrom->Index : this->Player->Index; int action = this->CurrentAction(); if (ReplayRevealMap || IsVisible) { type = this->Type; frame = this->Frame; y = this->IY; x = this->IX; x += vp->Map2ViewportX(this->tilePos.x); y += vp->Map2ViewportY(this->tilePos.y); state = (action == UnitActionBuilt) | ((action == UnitActionUpgradeTo) << 1); constructed = this->Constructed; // Reset Type to the type being upgraded to if (state == 2) { type = this->CurrentOrder()->Arg1.Type; } // This is trash unless the unit is being built, and that's when we use it. cframe = this->Data.Built.Frame; } else { y = this->Seen.IY; x = this->Seen.IX; x += vp->Map2ViewportX(this->Seen.X); y += vp->Map2ViewportY(this->Seen.Y); frame = this->Seen.Frame; type = this->Seen.Type; constructed = this->Seen.Constructed; state = this->Seen.State; cframe = this->Seen.CFrame; } #ifdef DYNAMIC_LOAD if (!type->Sprite) { LoadUnitTypeSprite(*type); } #endif if (!IsVisible && frame == UnitNotSeen) { DebugPrint("FIXME: Something is wrong, unit %d not seen but drawn time %lu?.\n" _C_ this->Slot _C_ GameCycle); return; } if (state == 1 && constructed) { DrawConstructionShadow(*type, cframe, frame, x, y); } else { if (action != UnitActionDie) { DrawShadow(*type, frame, x, y); } } // // Show that the unit is selected // DrawUnitSelection(vp, *this); // // Adjust sprite for Harvesters. // sprite = type->Sprite; if (type->Harvester && this->CurrentResource) { resinfo = type->ResInfo[this->CurrentResource]; if (this->ResourcesHeld) { if (resinfo->SpriteWhenLoaded) { sprite = resinfo->SpriteWhenLoaded; } } else { if (resinfo->SpriteWhenEmpty) { sprite = resinfo->SpriteWhenEmpty; } } } // // Now draw! // Buildings under construction/upgrade/ready. // if (state == 1) { if (constructed) { DrawConstruction(player, cframe, *type, frame, x + (type->TileWidth * TileSizeX) / 2, y + (type->TileHeight * TileSizeY) / 2); } // // Draw the future unit type, if upgrading to it. // } else if (state == 2) { // FIXME: this frame is hardcoded!!! DrawUnitType(*type, sprite, player, frame < 0 ? /*-1*/ - 1 : 1, x, y); } else { DrawUnitType(*type, sprite, player, frame, x, y); } // Unit's extras not fully supported.. need to be decorations themselves. DrawInformations(*this, type, x, y); }
/** ** Draw unit on map. */ void CUnit::Draw() const { int x; int y; int frame; int state; int constructed; CPlayerColorGraphic *sprite; ResourceInfo *resinfo; CConstructionFrame *cframe; CUnitType *type; if (this->Type->Revealer) { // Revealers are not drawn return; } // Those should have been filtered. Check doesn't make sense with ReplayRevealMap Assert(ReplayRevealMap || this->Type->VisibleUnderFog || this->IsVisible(ThisPlayer)); if (ReplayRevealMap || this->IsVisible(ThisPlayer)) { type = this->Type; frame = this->Frame; y = this->IY; x = this->IX; x += CurrentViewport->Map2ViewportX(this->X); y += CurrentViewport->Map2ViewportY(this->Y); state = (this->Orders[0]->Action == UnitActionBuilt) | ((this->Orders[0]->Action == UnitActionUpgradeTo) << 1); constructed = this->Constructed; // Reset Type to the type being upgraded to if (state == 2) { type = this->Orders[0]->Type; } // This is trash unless the unit is being built, and that's when we use it. cframe = this->Data.Built.Frame; } else { y = this->Seen.IY; x = this->Seen.IX; x += CurrentViewport->Map2ViewportX(this->Seen.X); y += CurrentViewport->Map2ViewportY(this->Seen.Y); frame = this->Seen.Frame; type = this->Seen.Type; constructed = this->Seen.Constructed; state = this->Seen.State; cframe = this->Seen.CFrame; } #ifdef DYNAMIC_LOAD if (!type->Sprite) { LoadUnitTypeSprite(type); } #endif if (!this->IsVisible(ThisPlayer) && frame == UnitNotSeen) { DebugPrint("FIXME: Something is wrong, unit %d not seen but drawn time %lu?.\n" _C_ this->Slot _C_ GameCycle); return; } if (state == 1 && constructed) { DrawConstructionShadow(this, cframe, frame, x, y); } else { DrawShadow(this, NULL, frame, x, y); } // // Show that the unit is selected // DrawUnitSelection(this); // // Adjust sprite for Harvesters. // sprite = type->Sprite; if (type->Harvester && this->CurrentResource) { resinfo = type->ResInfo[this->CurrentResource]; if (this->ResourcesHeld) { if (resinfo->SpriteWhenLoaded) { sprite = resinfo->SpriteWhenLoaded; } } else { if (resinfo->SpriteWhenEmpty) { sprite = resinfo->SpriteWhenEmpty; } } } // // Now draw! // Buildings under construction/upgrade/ready. // if (state == 1) { if (constructed) { DrawConstruction(this, cframe, type, frame, x + (type->TileWidth * TileSizeX) / 2, y + (type->TileHeight * TileSizeY) / 2); } // // Draw the future unit type, if upgrading to it. // } else if (state == 2) { // FIXME: this frame is hardcoded!!! DrawUnitType(type, sprite, this->RescuedFrom ? this->RescuedFrom->Index : this->Player->Index, frame < 0 ? -1 - 1 : 1, x, y); } else { DrawUnitType(type, sprite, this->RescuedFrom ? this->RescuedFrom->Index : this->Player->Index, frame, x, y); } // Unit's extras not fully supported.. need to be decorations themselves. DrawInformations(this, type, x, y); }