void TileObjectBattleItem::draw(Renderer &r, TileTransform &, Vec2<float> screenPosition, TileViewMode mode, bool visible, int, bool, bool) { // Mode isn't used as TileView::tileToScreenCoords already transforms according to the mode std::ignore = mode; auto item = this->item.lock(); if (!item) { LogError("Called with no owning item object"); return; } Vec2<float> transformedScreenPos = screenPosition; sp<Image> sprite; switch (mode) { case TileViewMode::Isometric: sprite = item->item->type->dropped_sprite; transformedScreenPos -= item->item->type->dropped_offset; break; case TileViewMode::Strategy: { if (item->falling || !visible) break; sprite = item->strategySprite; transformedScreenPos -= Vec2<float>{4, 4}; break; } default: LogError("Unsupported view mode"); } if (sprite) drawTinted(r, sprite, transformedScreenPos, visible); }
void TileObjectBattleMapPart::draw(Renderer &r, TileTransform &transform, Vec2<float> screenPosition, TileViewMode mode, bool visible, int, bool, bool) { std::ignore = transform; // Mode isn't used as TileView::tileToScreenCoords already transforms according to the mode auto &type = map_part->type; sp<Image> sprite; Vec2<float> transformedScreenPos = screenPosition; switch (mode) { case TileViewMode::Isometric: { int frame = map_part->getAnimationFrame(); if (frame == -1) { sprite = type->sprite; } else { auto &curType = map_part->alternative_type ? map_part->alternative_type : map_part->type; sprite = curType->animation_frames[frame]; } transformedScreenPos -= type->imageOffset; break; } case TileViewMode::Strategy: sprite = type->strategySprite; // All strategy sprites so far are 8x8 so offset by 4 to draw from the center // FIXME: Not true for large sprites (2x2 UFOs?) transformedScreenPos -= Vec2<float>{4, 4}; break; default: LogError("Unsupported view mode"); } if (sprite) drawTinted(r, sprite, transformedScreenPos, visible); }
void TileObjectBattleUnit::draw(Renderer &r, TileTransform &transform, Vec2<float> screenPosition, TileViewMode mode, bool visible, int currentLevel, bool friendly, bool hostile) { // We never draw non-visible units? Or maybe we do? if (!visible) return; static const int offset_prone = 8; static const int offset_large = 32; static const std::map<Vec2<int>, int> offset_dir_map = { {{0, -1}, 0}, {{1, -1}, 1}, {{1, 0}, 2}, {{1, 1}, 3}, {{0, 1}, 4}, {{-1, 1}, 5}, {{-1, 0}, 6}, {{-1, -1}, 7}, }; static const std::map<int, int> offset_prone_map = { {0, offset_prone + 0}, {1, offset_prone + 2}, {2, offset_prone + 6}, {3, offset_prone + 8}, {4, offset_prone + 12}, {5, offset_prone + 14}, {6, offset_prone + 18}, {7, offset_prone + 20}, }; static const int ICON_STANDART = 0; static const int ICON_PRONE = 1; static const int ICON_LARGE = 2; std::ignore = transform; auto unit = getUnit(); if (!unit) { LogError("Called with no owning unit object"); return; } switch (mode) { case TileViewMode::Isometric: { int firingAngle = 0; if (unit->current_hand_state == HandState::Firing) { Vec3<float> targetVector = unit->targetTile - owningTile->position; Vec3<float> targetVectorZeroZ = {targetVector.x, targetVector.y, 0.0f}; // Firing angle is 0 for -15..15, +-1 for -30..-15 and 15..30, and 2 for everything // else firingAngle = (int)((glm::angle(glm::normalize(targetVector), glm::normalize(targetVectorZeroZ)) * 360.0f / 2.0f / M_PI) / 15.0f); if (targetVector.z < 0) { firingAngle = -firingAngle; } firingAngle = clamp(firingAngle, -2, 2); } unit->agent->getAnimationPack()->drawUnit( r, screenPosition, unit->agent->getImagePack(BodyPart::Body), unit->agent->getImagePack(BodyPart::Legs), unit->agent->getImagePack(BodyPart::Helmet), unit->agent->getImagePack(BodyPart::LeftArm), unit->agent->getImagePack(BodyPart::RightArm), unit->displayedItem, unit->facing, unit->current_body_state, unit->target_body_state, unit->current_hand_state, unit->target_hand_state, unit->usingLift ? MovementState::None : unit->current_movement_state, unit->getBodyAnimationFrame(), unit->getHandAnimationFrame(), unit->getDistanceTravelled(), firingAngle, visible); break; } case TileViewMode::Strategy: { // Dead or non-visible units don't appear on strategy screen if (unit->isDead() || !visible) break; // 0 = enemy, 3 = friendly, 2 = neutral int side_offset = friendly ? 3 : (hostile ? 0 : 2); // Icon type, 0 = normal, 1 = prone, 2 = large int icon_type = unit->isLarge() ? ICON_LARGE : ((unit->current_body_state == BodyState::Prone || unit->target_body_state == BodyState::Prone) ? ICON_PRONE : ICON_STANDART); // Unit facing, in game starts with north (0,-1) and goes clockwise, from 0 to 7 int facing_offset = offset_dir_map.at(unit->facing); // Current level offset, 0 = current 1 = above 2 = below int curent_level_offset = currentLevel < 0 ? 2 : (currentLevel > 0 ? 1 : 0); switch (icon_type) { case ICON_STANDART: drawTinted(r, unit->strategyImages->at( side_offset * 120 + curent_level_offset * 40 + facing_offset), screenPosition - Vec2<float>{4, 4}, visible); break; case ICON_PRONE: // Vertical if (facing_offset == 0 || facing_offset == 4) { drawTinted(r, unit->strategyImages->at( side_offset * 120 + curent_level_offset * 40 + offset_prone_map.at(facing_offset) + 0), screenPosition - Vec2<float>{4.0f, 8.0f}, visible); drawTinted(r, unit->strategyImages->at( side_offset * 120 + curent_level_offset * 40 + offset_prone_map.at(facing_offset) + 1), screenPosition - Vec2<float>{4.0f, 0.0f}, visible); } // Horizontal else if (facing_offset == 2 || facing_offset == 6) { drawTinted(r, unit->strategyImages->at( side_offset * 120 + curent_level_offset * 40 + offset_prone_map.at(facing_offset) + 0), screenPosition - Vec2<float>{8.0f, 4.0f}, visible); drawTinted(r, unit->strategyImages->at( side_offset * 120 + curent_level_offset * 40 + offset_prone_map.at(facing_offset) + 1), screenPosition - Vec2<float>{0.0f, 4.0f}, visible); } // Diagonal else { drawTinted(r, unit->strategyImages->at( side_offset * 120 + curent_level_offset * 40 + offset_prone_map.at(facing_offset) + 0), screenPosition - Vec2<float>{8.0f, 8.0f}, visible); drawTinted(r, unit->strategyImages->at( side_offset * 120 + curent_level_offset * 40 + offset_prone_map.at(facing_offset) + 1), screenPosition - Vec2<float>{0.0f, 8.0f}, visible); drawTinted(r, unit->strategyImages->at( side_offset * 120 + curent_level_offset * 40 + offset_prone_map.at(facing_offset) + 2), screenPosition - Vec2<float>{8.0f, 0.0f}, visible); drawTinted(r, unit->strategyImages->at( side_offset * 120 + curent_level_offset * 40 + offset_prone_map.at(facing_offset) + 3), screenPosition - Vec2<float>{0.0f, 0.0f}, visible); } break; case ICON_LARGE: drawTinted(r, unit->strategyImages->at( side_offset * 120 + curent_level_offset * 40 + offset_large + 0), screenPosition - Vec2<float>{8.0f, 8.0f}, visible); drawTinted(r, unit->strategyImages->at( side_offset * 120 + curent_level_offset * 40 + offset_large + 1), screenPosition - Vec2<float>{0.0f, 8.0f}, visible); drawTinted(r, unit->strategyImages->at( side_offset * 120 + curent_level_offset * 40 + offset_large + 2), screenPosition - Vec2<float>{8.0f, 0.0f}, visible); drawTinted(r, unit->strategyImages->at( side_offset * 120 + curent_level_offset * 40 + offset_large + 3), screenPosition - Vec2<float>{0.0f, 0.0f}, visible); break; } break; } default: LogError("Unsupported view mode"); } }