/** ** Load the graphics for the unit-types. */ void LoadUnitTypes() { for (std::vector<CUnitType *>::size_type i = 0; i < UnitTypes.size(); ++i) { CUnitType &type = *UnitTypes[i]; // Lookup icons. type.Icon.Load(); // Lookup missiles. type.Missile.MapMissile(); type.Explosion.MapMissile(); // Lookup impacts for (int i = 0; i < ANIMATIONS_DEATHTYPES + 2; ++i) { type.Impact[i].MapMissile(); } // Lookup corpse. if (!type.CorpseName.empty()) { type.CorpseType = UnitTypeByIdent(type.CorpseName); } #ifndef DYNAMIC_LOAD // Load Sprite if (!type.Sprite) { ShowLoadProgress(_("Unit \"%s\""), type.Name.c_str()); LoadUnitTypeSprite(type); } #endif // FIXME: should i copy the animations of same graphics? } }
/** ** Load the graphics for the unit-types. */ void LoadUnitTypes(void) { CUnitType *type; for (size_t i = 0; i < UnitTypes.size(); ++i) { type = UnitTypes[i]; // // Lookup icons. // type->Icon.Load(); // // Lookup missiles. // type->Missile.Missile = MissileTypeByIdent(type->Missile.Name); if (!type->Explosion.Name.empty()) { type->Explosion.Missile = MissileTypeByIdent(type->Explosion.Name); } // // Lookup corpse. // if (!type->CorpseName.empty()) { type->CorpseType = UnitTypeByIdent(type->CorpseName); } // // Load Sprite // if (!type->Sprite) { ShowLoadProgress("Unit \"%s\"", type->Name.c_str()); LoadUnitTypeSprite(type); } } }
void CUnitDrawProxy::operator=(const CUnit *unit) { int action = unit->CurrentAction(); bool IsVisible = unit->IsVisible(ThisPlayer); IsAlive = action != UnitActionDie; Player = unit->RescuedFrom ? unit->RescuedFrom : unit->Player; cframe = NULL; CurrentResource = unit->CurrentResource; Selected = unit->Selected; TeamSelected = unit->TeamSelected; Blink = unit->Blink; ResourcesHeld = unit->ResourcesHeld > 0; if (unit->GroupId) { if (unit->Player->AiEnabled) { GroupId = unit->GroupId; } else { int num = 0; while(!(unit->GroupId & (1 << num))) { ++num; } GroupId = num + 1; } } else { GroupId = 0; } if (unit->Variable) { const unsigned int num_dec = UnitTypeVar.DecoVar.size(); if (!Variable) { Variable = new CVariable[num_dec]; } for (unsigned int i = 0; i < num_dec; ++i) { Variable[i] = unit->Variable[UnitTypeVar.DecoVar[i]->Index]; } } else { if (Variable) { const unsigned int num_dec = UnitTypeVar.DecoVar.size(); for (unsigned int i = 0; i < num_dec; ++i) { Variable[i] = Type->Variable[UnitTypeVar.DecoVar[i]->Index]; } } } if (ReplayRevealMap || IsVisible) { Type = unit->Type; frame = unit->Frame; IY = unit->IY; IX = unit->IX; X = unit->tilePos.x; Y = unit->tilePos.y; state = (action == UnitActionBuilt) | ((action == UnitActionUpgradeTo) << 1); // Reset Type to the type being upgraded to if (state == 2) { Type = unit->CurrentOrder()->Arg1.Type; } if (unit->Constructed) { // This is trash unless the unit is being built, and that's when we use it. cframe = unit->Data.Built.Frame; } } else { IY = unit->Seen.IY; IX = unit->Seen.IX; X = unit->Seen.X; Y = unit->Seen.Y; frame = unit->Seen.Frame; Type = unit->Seen.Type; state = unit->Seen.State; if (unit->Seen.Constructed) { cframe = unit->Seen.CFrame; } } #ifdef DYNAMIC_LOAD if (!Type->Sprite) { LoadUnitTypeSprite(*(CUnitType*)Type); } #endif }
/** ** 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 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 { 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); }