Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementation of scriptable sprite overlays. #120

Draft
wants to merge 3 commits into
base: oxce-plus
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
47 changes: 24 additions & 23 deletions src/Battlescape/AlienInventory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@
#include "../Mod/RuleInterface.h"
#include "../Savegame/BattleUnit.h"
#include "../Savegame/SavedGame.h"
#include "../Savegame/SavedBattleGame.h"
#include "../Ufopaedia/Ufopaedia.h"
#include "InventoryItemSprite.h"

namespace OpenXcom
{
Expand Down Expand Up @@ -151,40 +153,39 @@ void AlienInventory::drawGrid()
/**
* Draws the items contained in the alien's hands.
*/
void AlienInventory::drawItems()
void AlienInventory::drawItems() const
{
const SavedBattleGame* save = _game->getSavedGame()->getSavedBattle();
ScriptWorkerBlit work;
_items->clear();
if (_selUnit != 0)
if (_selUnit != nullptr)
{
SurfaceSet *texture = _game->getMod()->getSurfaceSet("BIGOBS.PCK");
const SurfaceSet* surfaceSet = _game->getMod()->getSurfaceSet("BIGOBS.PCK");
for (const auto* item : *_selUnit->getInventory())
{
if (item->getSlot()->getType() == INV_HAND)
{
const Surface* frame = item->getBigSprite(texture, save, _animFrame);

if (!frame)
continue;
if (item->getSlot()->getType() != INV_HAND) { continue; }

int x = item->getSlot()->getX() + item->getRules()->getHandSpriteOffX();
x += _game->getMod()->getAlienInventoryOffsetX();
const auto handSlot = item->getSlot();
SDL_Rect spriteBounds = InventoryItemSprite::getHandCenteredSpriteBounds(*item);
spriteBounds.x += handSlot->getX() + _game->getMod()->getAlienInventoryOffsetX();
spriteBounds.y += handSlot->getY();

if (item->getSlot()->isRightHand())
x -= _dynamicOffset;
else if (item->getSlot()->isLeftHand())
x += _dynamicOffset;
// offset bounds by dynamic offset to account for large aliens.
spriteBounds.x -= (handSlot->isRightHand() ? -_dynamicOffset :
handSlot->isLeftHand() ? _dynamicOffset :
throw std::logic_error("Item in hand slot with bad hand value."));

int y = item->getSlot()->getY() + item->getRules()->getHandSpriteOffY();
InventoryItemSprite(*item, *save, *_items, spriteBounds).draw(*surfaceSet, InventorySpriteContext::ALIEN_INV_HAND, _animFrame);

BattleItem::ScriptFill(&work, item, save, BODYPART_ITEM_INVENTORY, _animFrame, 0);
work.executeBlit(frame, _items, x, y, 0);
}
else
{
continue;
}
/// offset for hand overlay
auto handSlotBounds = SDL_Rect{
static_cast<Sint16>(handSlot->getX() + 1 + _game->getMod()->getAlienInventoryOffsetX()),
static_cast<Sint16>(handSlot->getY() + 1),
RuleInventory::HAND_SLOT_W-1,
RuleInventory::HAND_SLOT_H-2,
};
// this should render no default effects, but allows for scripting.
InventoryItemSprite(*item, *save, *_items, handSlotBounds).drawHandOverlay(InventorySpriteContext::ALIEN_INV_HAND, _animFrame);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Battlescape/AlienInventory.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class AlienInventory : public InteractiveSurface
/// Draws the inventory grid.
void drawGrid();
/// Draws the inventory items.
void drawItems();
void drawItems() const;
/// Blits the inventory onto another surface.
void blit(SDL_Surface *surface) override;
/// Special handling for mouse clicks.
Expand Down
123 changes: 20 additions & 103 deletions src/Battlescape/BattlescapeState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
#include "UnitInfoState.h"
#include "InventoryState.h"
#include "AlienInventoryState.h"
#include "InventoryItemSprite.h"
#include "SpriteOverlay.h"
#include "Pathfinding.h"
#include "BattlescapeGame.h"
#include "WarningMessage.h"
Expand Down Expand Up @@ -163,22 +165,6 @@ BattlescapeState::BattlescapeState() :
_btnZeroTUs = new BattlescapeButton(10, 23, x + 49, y + 33);
_btnLeftHandItem = new InteractiveSurface(32, 48, x + 8, y + 4);
_btnRightHandItem = new InteractiveSurface(32, 48, x + 280, y + 4);
_numAmmoLeft.reserve(RuleItem::AmmoSlotMax);
_numAmmoRight.reserve(RuleItem::AmmoSlotMax);
for (int slot = 0; slot < RuleItem::AmmoSlotMax; ++slot)
{
_numAmmoLeft.push_back(new NumberText(30, 5, x + 8, y + 4 + 6 * slot));
_numAmmoRight.push_back(new NumberText(30, 5, x + 280, y + 4 + 6 * slot));
}
_numMedikitLeft.reserve(RuleItem::MedikitSlots);
_numMedikitRight.reserve(RuleItem::MedikitSlots);
for (int slot = 0; slot < RuleItem::MedikitSlots; ++slot)
{
_numMedikitLeft.push_back(new NumberText(30, 5, x + 9, y + 32 + 7 * slot));
_numMedikitRight.push_back(new NumberText(30, 5, x + 281, y + 32 + 7 * slot));
}
_numTwoHandedIndicatorLeft = new NumberText(10, 5, x + 36, y + 46);
_numTwoHandedIndicatorRight = new NumberText(10, 5, x + 308, y + 46);
const int visibleUnitX = _game->getMod()->getInterface("battlescape")->getElement("visibleUnits")->x;
const int visibleUnitY = _game->getMod()->getInterface("battlescape")->getElement("visibleUnits")->y;
for (int i = 0; i < VISIBLE_MAX; ++i)
Expand Down Expand Up @@ -357,18 +343,6 @@ BattlescapeState::BattlescapeState() :
add(_btnZeroTUs, "buttonZeroTUs", "battlescape", _icons);
add(_btnLeftHandItem, "buttonLeftHand", "battlescape", _icons);
add(_btnRightHandItem, "buttonRightHand", "battlescape", _icons);
for (int slot = 0; slot < RuleItem::AmmoSlotMax; ++slot)
{
add(_numAmmoLeft[slot], "numAmmoLeft", "battlescape", _icons);
add(_numAmmoRight[slot], "numAmmoRight", "battlescape", _icons);
}
for (int slot = 0; slot < RuleItem::MedikitSlots; ++slot)
{
add(_numMedikitLeft[slot], "numMedikitLeft", "battlescape", _icons);
add(_numMedikitRight[slot], "numMedikitRight", "battlescape", _icons);
}
add(_numTwoHandedIndicatorLeft, "numTwoHandedIndicatorLeft", "battlescape", _icons);
add(_numTwoHandedIndicatorRight, "numTwoHandedIndicatorRight", "battlescape", _icons);
for (int i = 0; i < VISIBLE_MAX; ++i)
{
add(_btnVisibleUnit[i]);
Expand Down Expand Up @@ -415,19 +389,6 @@ BattlescapeState::BattlescapeState() :
_numLayers->setColor(Palette::blockOffset(1)-2);
_numLayers->setValue(1);

for (int slot = 0; slot < RuleItem::AmmoSlotMax; ++slot)
{
_numAmmoLeft[slot]->setValue(999);
_numAmmoRight[slot]->setValue(999);
}
for (int slot = 0; slot < RuleItem::MedikitSlots; ++slot)
{
_numMedikitLeft[slot]->setValue(999);
_numMedikitRight[slot]->setValue(999);
}
_numTwoHandedIndicatorLeft->setValue(2);
_numTwoHandedIndicatorRight->setValue(2);

_icons->onMouseIn((ActionHandler)&BattlescapeState::mouseInIcons);
_icons->onMouseOut((ActionHandler)&BattlescapeState::mouseOutIcons);

Expand Down Expand Up @@ -1875,72 +1836,19 @@ bool BattlescapeState::playableUnitSelected()
}

/**
* Draw hand item with ammo number.
* Draw hand item inventory sprite and reaction indicator.
*/
void BattlescapeState::drawItem(BattleItem* item, Surface* hand, std::vector<NumberText*> &ammoText, std::vector<NumberText*> &medikitText, NumberText *twoHandedText, bool drawReactionIndicator)
void BattlescapeState::drawItem(const BattleItem* item, Surface* hand, bool drawReactionIndicator) const
{
hand->clear();
for (int slot = 0; slot < RuleItem::AmmoSlotMax; ++slot)
{
ammoText[slot]->setVisible(false);
}
for (int slot = 0; slot < RuleItem::MedikitSlots; ++slot)
{
medikitText[slot]->setVisible(false);
}
twoHandedText->setVisible(false);

if (item)
{
const RuleItem *rule = item->getRules();
rule->drawHandSprite(_game->getMod()->getSurfaceSet("BIGOBS.PCK"), hand, item, _save, _save->getAnimFrame());
for (int slot = 0; slot < RuleItem::AmmoSlotMax; ++slot)
{
if (item->isAmmoVisibleForSlot(slot))
{
BattleItem* ammo = item->getAmmoForSlot(slot);
if (!ammo)
{
ammoText[slot]->setVisible(true);
ammoText[slot]->setValue(0);
}
else
{
ammoText[slot]->setVisible(true);
ammoText[slot]->setValue(ammo->getAmmoQuantity());
}
}
}
twoHandedText->setVisible(rule->isTwoHanded());
twoHandedText->setColor(rule->isBlockingBothHands() ? _twoHandedRed : _twoHandedGreen);
if (rule->getBattleType() == BT_MEDIKIT)
{
medikitText[0]->setVisible(true);
medikitText[0]->setValue(item->getPainKillerQuantity());
medikitText[1]->setVisible(true);
medikitText[1]->setValue(item->getStimulantQuantity());
medikitText[2]->setVisible(true);
medikitText[2]->setValue(item->getHealQuantity());
}
const SurfaceSet* surfaceSet = _game->getMod()->getSurfaceSet("BIGOBS.PCK");
int animFrame = _save->getAnimFrame();

// primed grenade indicator (static)
/*
if (item->getFuseTimer() >= 0)
{
Surface *tempSurface = _game->getMod()->getSurfaceSet("SCANG.DAT")->getFrame(6);
tempSurface->setX((RuleInventory::HAND_W - rule->getInventoryWidth()) * RuleInventory::SLOT_W / 2);
tempSurface->setY((RuleInventory::HAND_H - rule->getInventoryHeight()) * RuleInventory::SLOT_H / 2);
tempSurface->blit(hand);
}
*/
// primed grenade indicator (animated)
if (item->getFuseTimer() >= 0)
{
const int Pulsate[8] = { 0, 1, 2, 3, 4, 3, 2, 1 };
Surface *tempSurface = _game->getMod()->getSurfaceSet("SCANG.DAT")->getFrame(6);
int x = (RuleInventory::HAND_W - rule->getInventoryWidth()) * RuleInventory::SLOT_W / 2;
int y = (RuleInventory::HAND_H - rule->getInventoryHeight()) * RuleInventory::SLOT_H / 2;
tempSurface->blitNShade(hand, x, y, Pulsate[_save->getAnimFrame() % 8], false, item->isFuseEnabled() ? 0 : 32);
}
InventoryItemSprite(*item, *_save, *hand, InventoryItemSprite::getHandCenteredSpriteBounds(*item)).draw(*surfaceSet, InventorySpriteContext::BATTSCAPE_HAND, animFrame);
InventoryItemSprite(*item, *_save, *hand, SpriteOverlay::getSurfaceBounds(*hand)).drawHandOverlay(InventorySpriteContext::BATTSCAPE_HAND, animFrame);
}
if (drawReactionIndicator)
{
Expand Down Expand Up @@ -1988,8 +1896,8 @@ void BattlescapeState::drawHandsItems()
}
}
}
drawItem(leftHandItem, _btnLeftHandItem, _numAmmoLeft, _numMedikitLeft, _numTwoHandedIndicatorLeft, left);
drawItem(rightHandItem, _btnRightHandItem, _numAmmoRight, _numMedikitRight, _numTwoHandedIndicatorRight, right);
drawItem(leftHandItem, _btnLeftHandItem, left);
drawItem(rightHandItem, _btnRightHandItem, right);
}

/**
Expand Down Expand Up @@ -2138,6 +2046,8 @@ void BattlescapeState::updateSoldierInfo(bool checkFOV)
crop.blit(_rank);
}
}
auto overlay = SpriteOverlay(*_rank, SpriteOverlay::getSurfaceBounds(*_rank), _save);
overlay.draw<ModScript::UnitRankOverlay>(*soldier->getArmor(), battleUnit, _save->getAnimFrame());
}
else
{
Expand Down Expand Up @@ -2418,6 +2328,13 @@ void BattlescapeState::animate()
blinkVisibleUnitButtons();
blinkHealthBar();

if(auto unit = _save->getSelectedUnit())
{
auto overlay = SpriteOverlay(*_rank, SpriteOverlay::getSurfaceBounds(*_rank), _save);
overlay.draw<ModScript::UnitRankOverlay>(*unit->getArmor(), unit, _save->getAnimFrame());
}


if (!_map->getProjectile())
{
drawHandsItems();
Expand Down
5 changes: 1 addition & 4 deletions src/Battlescape/BattlescapeState.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,6 @@ class BattlescapeState : public State
WarningMessage *_warning;
Text *_txtName;
NumberText *_numTimeUnits, *_numEnergy, *_numHealth, *_numMorale, *_numLayers;
std::vector<NumberText*> _numAmmoLeft, _numAmmoRight;
std::vector<NumberText*> _numMedikitLeft, _numMedikitRight;
NumberText *_numTwoHandedIndicatorLeft, *_numTwoHandedIndicatorRight;
Uint8 _twoHandedRed, _twoHandedGreen;
Bar *_barTimeUnits, *_barEnergy, *_barHealth, *_barMorale, *_barMana;
bool _manaBarVisible;
Expand Down Expand Up @@ -103,7 +100,7 @@ class BattlescapeState : public State
/// Shifts the red colors of the visible unit buttons backgrounds.
void blinkVisibleUnitButtons();
/// Draw hand item with ammo number.
void drawItem(BattleItem *item, Surface *hand, std::vector<NumberText*> &ammoText, std::vector<NumberText*> &medikitText, NumberText *twoHandedText, bool drawReactionIndicator);
void drawItem(const BattleItem *item, Surface *hand, bool drawReactionIndicator) const;
/// Draw both hands sprites.
void drawHandsItems();
/// Shifts the colors of the health bar when unit has fatal wounds.
Expand Down