"demo4-2-scale-out-add-worker.py" did not exist on "12db4e6441591f4a0baee7a2ace0fbe394fb2e05"
Select Git revision
CaveExamples.umap
Unit.cpp 6.16 KiB
/**
* Unit.cpp
*
* @authors Max Körschen
* @author Nicolas Will
* @author Frederik Keens
*/
#include "Unit.hpp"
#include "../core/Config.hpp"
#include "../physics/PhysicsBody.hpp"
#include "../physics/PhysicsEngine.hpp"
#include <memory>
namespace advanced_wars
{
Unit::Unit(
int unitId, b2World* world, int tileX, int tileY, Faction faction, UnitTypeId unitTypeId,
UnitState state, Config& config)
: m_unitId(unitId), m_tileX(tileX), m_tileY(tileY), m_health(100),
m_cost(config.getUnitCost(unitTypeId)), m_ammo(config.getUnitAmmo(unitTypeId)),
m_minRange(config.getUnitMinRange(unitTypeId)),
m_maxRange(config.getUnitMaxRange(unitTypeId)), m_maxHealth(100),
m_movementPoints(config.getUnitMovementPoints(unitTypeId)),
m_movementType(config.getUnitMovementType(unitTypeId)), m_faction(faction),
m_unitTypeId(unitTypeId), m_state(state), m_world(world), m_animX(tileX), m_animY(tileY)
{
m_physicsBody = std::make_unique<PhysicsBody>(
m_world, tileX, tileY, 8.0F, 8.0F, 1.0, 0.3, true, BodyType::UNIT);
if (m_physicsBody && (m_physicsBody->getBody() != nullptr))
{
BodyUserData* bud = new BodyUserData();
bud->type = BodyUserData::Type::UNIT;
bud->id = m_unitId;
bud->data = this;
m_physicsBody->getBody()->GetUserData().pointer = reinterpret_cast<uintptr_t>(bud);
}
// Initialisieren der Primär- und Sekundärwaffe
std::unordered_map<UnitTypeId, int> primaryDamage;
std::unordered_map<UnitTypeId, int> secondaryDamage;
for (int targetIt = static_cast<int>(UnitTypeId::FIRST);
targetIt <= static_cast<int>(UnitTypeId::LAST); ++targetIt)
{
auto targetId = static_cast<UnitTypeId>(targetIt);
if (auto damage = config.getUnitPrimaryWeaponDamage(m_unitTypeId, targetId))
{
primaryDamage[targetId] = *damage;
}
if (auto damage = config.getUnitSecondaryWeaponDamage(m_unitTypeId, targetId))
{
secondaryDamage[targetId] = *damage;
}
}
m_primaryWeapon =
std::make_unique<Weapon>(Weapon(config.getUnitPrimaryWeapon(m_unitTypeId), primaryDamage));
m_secondaryWeapon = std::make_unique<Weapon>(
Weapon(config.getUnitSecondaryWeapon(m_unitTypeId), secondaryDamage));
}
void Unit::update(float deltaTime)
{
if (!m_physicsBody)
{
return;
}
m_physicsBody->update(deltaTime);
b2Vec2 pos = m_physicsBody->getPosition();
calcState(static_cast<int>(pos.x), static_cast<int>(pos.y));
m_animX = static_cast<int>(pos.x);
m_animY = static_cast<int>(pos.y);
}
void Unit::moveTo(int posX, int posY)
{
if (!m_physicsBody)
{
return;
}
m_physicsBody->setTargetPosition(posX, posY);
calcState(posX, posY);
m_tileX = posX;
m_tileY = posY;
}
void Unit::calcState(int posX, int posY)
{
int deltaX = this->m_animX - posX;
int deltaY = this->m_animY - posY;
if (deltaX == 0 && deltaY == 0)
{
if (m_hasMoved)
{
m_state = UnitState::UNAVAILABLE;
}
return;
}
if (abs(deltaX) >= abs(deltaY))
{
this->m_state = (deltaX > 0) ? UnitState::MOVEMENTLEFT : UnitState::MOVEMENTRIGHT;
}
else
{
this->m_state = (deltaY > 0) ? UnitState::MOVEMENTUP : UnitState::MOVEMENTDOWN;
}
}
void Unit::render(Engine& engine, int scale)
{
Spritesheet* spritesheet = engine.getSpritesheet();
int step = engine.getStage() % spritesheet->getUnitTextures()
.at(static_cast<int>(m_faction))
.at(static_cast<int>(m_unitTypeId))
.at(static_cast<int>(m_state))
.second;
SDL_Rect src;
SDL_Rect dst;
if (m_state == UnitState::IDLE || m_state == UnitState::UNAVAILABLE)
{
src.x = step * spritesheet->getUnitWidth();
src.y = 0;
src.w = spritesheet->getUnitWidth();
src.h = spritesheet->getUnitHeight();
dst.x = m_animX * spritesheet->getUnitWidth() * scale;
dst.y = m_animY * spritesheet->getUnitHeight() * scale;
dst.w = spritesheet->getUnitWidth() * scale;
dst.h = spritesheet->getUnitHeight() * scale;
}
else
{
src.x = step * spritesheet->getUnitMovingWidth();
src.y = 0;
src.w = spritesheet->getUnitMovingWidth();
src.h = spritesheet->getUnitMovingHeight();
dst.x = ((m_animX * spritesheet->getUnitWidth()) - 4) * scale;
dst.y = ((m_animY * spritesheet->getUnitHeight()) - 8) * scale;
dst.w = spritesheet->getUnitMovingWidth() * scale;
dst.h = spritesheet->getUnitMovingHeight() * scale;
}
SDL_RenderCopyEx(
engine.renderer(),
spritesheet->getUnitTextures()
.at(static_cast<int>(m_faction))
.at(static_cast<int>(m_unitTypeId))
.at(static_cast<int>(m_state))
.first,
&src, &dst, 0, nullptr, SDL_FLIP_NONE);
renderHP(engine, scale);
}
void Unit::renderHP(Engine& engine, int scale)
{
Spritesheet* spritesheet = engine.getSpritesheet();
SDL_Texture* numbers = spritesheet->getNumberTexture();
int numberWidth = spritesheet->getNumberWidth();
int numberHeight = spritesheet->getNumberHeight();
int unitHp = ceil((double)m_health / 10);
SDL_Rect src;
SDL_Rect dest;
src.x = unitHp % 10 * numberWidth;
src.y = 0;
src.w = numberWidth;
src.h = numberHeight;
dest.x = (m_animX * spritesheet->getTileWidth() + 8) * scale;
dest.y = (m_animY * spritesheet->getTileHeight() + 12) * scale;
dest.w = numberWidth * scale;
dest.h = numberHeight * scale;
SDL_RenderCopy(engine.renderer(), numbers, &src, &dest);
if (unitHp == 10)
{
src.x = 8;
dest.x = (m_animX * spritesheet->getTileWidth() + 1) * scale;
SDL_RenderCopy(engine.renderer(), numbers, &src, &dest);
}
}
void Unit::destroyBody()
{
if (m_physicsBody)
{
m_physicsBody->getBody()->GetUserData().pointer = 0;
m_physicsBody->destroy();
m_physicsBody.reset();
}
}
Unit::~Unit() {}
} // namespace advanced_wars