Skip to content

Commit ec01597

Browse files
committed
Updated changelog, added Materal::GetColorIndex(), updated MOSprite bitmap manipulation functions sorry i can't remember all the the changes but they're good i promise
1 parent 98445c9 commit ec01597

File tree

5 files changed

+115
-47
lines changed

5 files changed

+115
-47
lines changed

CHANGELOG.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,22 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
7979

8080
- New `Attachable` INI and Lua (R/W) properties `InheritsVelWhenDetached` and `InheritsAngularVelWhenDetached`, which determine how much of these velocities an attachable inherits from its parent when detached. Defaults to 1.
8181

82+
- Added Lua-accessible bitmap manipulation functions to `MOSprite`s:
83+
```
84+
GetSpritePixelIndex(int x, int y, int whichFrame) - Returns the color index of the pixel at the given coordinate on the given frame of the sprite ((0, 0) is the upper left corner!)
85+
86+
SetSpritePixelIndex(int x, int y, int whichFrame, int colorIndex, int ignoreIndex, bool invert) - Sets the color of the pixel at the given coordinate on thegiven frame of the sprite, skipping if the pixel has same color index as given in ignoreIndex. If invert is set to true, only pixels of that color index are set.
87+
88+
GetAllSpritePixelPositions(const Vector& origin, float angle, bool hflipped, int whichFrame, int ignoreIndex, bool invert, bool includeChildren) - Returns a list of vectors pointing to the absolute positions of all pixels in the given frame of the sprite, rotated to match angle, flipped to match hflipped and positioned around origin, providing a full silhouette of the MOSprite. IgnoreIndex and invert are like above, include children denotes whether or not to include all children of the MOSprite (no effect if not at least an MOSRotating).
89+
90+
GetAllVisibleSpritePixelPositions(bool includeChildren) - Simplified version of the above, returning a list of absolute positions of the visible pixels of the current frame of the sprite as it is currently drawn.
91+
92+
SetAllSpritePixelIndexes(int whichFrame, int colorIndex, int ignoreIndex, bool invert) - Sets all pixels in the given frame of the sprite to the given color index, ignoring and inverting as above.
93+
94+
SetAllVisibleSpritePixelIndexes(int colorIndex) - Simplified version of the above, sets all visible pixels of the currently visible sprite to the given color index.
95+
```
96+
- Added `Material` Lua function `GetColorIndex()`, which returns the color index of the calling material.
97+
8298
- New `ACraft` INI and Lua (R/W) property `CanEnterOrbit`, which determines whether a craft can enter orbit (and refund gold appropriately) or not. If false, default out-of-bounds deletion logic applies.
8399

84100
</details>
@@ -149,6 +165,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
149165

150166
- Fixed an issue where internal Lua functions OriginalDoFile, OriginalLoadFile, and OriginalRequire were polluting the global namespace. They have now been made inaccessible.
151167

168+
- Fixed `MOSprite:UnRotateOffset()` giving the wrong results on HFLipped sprites.
169+
152170
- Various fixes and improvements to inventory management when dual-wielding or carrying a shield, to stop situations where the actor unexpectedly puts their items away.
153171

154172
- Fixed issue where MOSR `Gib`s, `AEmitter` or `PEmitter` `Emission`s, and MetaMan `Player`s were not correctly accessible from script.

Source/Entities/MOSprite.cpp

Lines changed: 59 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -353,51 +353,47 @@ Vector MOSprite::RotateOffset(const Vector& offset) const {
353353
}
354354

355355
Vector MOSprite::UnRotateOffset(const Vector& offset) const {
356-
Vector rotOff(offset.GetXFlipped(m_HFlipped));
356+
Vector rotOff(offset);
357357
rotOff /= const_cast<Matrix&>(m_Rotation);
358-
return rotOff;
358+
return rotOff.GetXFlipped(m_HFlipped);
359359
}
360360

361-
void MOSprite::SetPixelIndex(int x, int y, unsigned int whichFrame, int colorIndex, int ignoreIndex, bool invert) {
362-
if (!m_SpriteModified) {
363-
std::vector<BITMAP*> spriteList;
364-
365-
for (BITMAP* sprite: m_aSprite) {
366-
BITMAP* spriteCopy = create_bitmap_ex(8, sprite->w, sprite->h);
367-
rectfill(spriteCopy, 0, 0, spriteCopy->w - 1, spriteCopy->h - 1, 0);
368-
draw_sprite(spriteCopy, sprite, 0, 0);
369-
spriteList.push_back(spriteCopy);
370-
}
371-
372-
m_aSprite = spriteList;
373-
m_SpriteModified = true;
374-
}
375-
376-
BITMAP* targetSprite = m_aSprite[CLAMP(m_FrameCount - 1, 0, whichFrame)];
377-
if (ignoreIndex < 0 || (getpixel(targetSprite, x, y) == ignoreIndex) != invert) {
378-
putpixel(targetSprite, x, y, colorIndex);
361+
int MOSprite::GetSpritePixelIndex(int x, int y, int whichFrame) const {
362+
unsigned int clampedFrame = std::max(std::min(whichFrame, static_cast<int>(m_FrameCount) - 1), 0);
363+
BITMAP* targetSprite = m_aSprite[clampedFrame];
364+
if (is_inside_bitmap(targetSprite, x, y, 0)) {
365+
return _getpixel(targetSprite, x, y);
379366
}
367+
return -1;
380368
}
381369

382-
std::vector<Vector>* MOSprite::GetAllPixelPositions(const Vector& origin, float angle, bool hflipped, unsigned int whichFrame, int ignoreIndex, bool invert) {
370+
std::vector<Vector>* MOSprite::GetAllSpritePixelPositions(const Vector& origin, float angle, bool hflipped, int whichFrame, int ignoreIndex, bool invert, bool includeChildren) {
383371
std::vector<Vector>* posList = new std::vector<Vector>();
384-
CLAMP(m_FrameCount - 1, 0, whichFrame);
385-
BITMAP* sprite = m_aSprite[whichFrame];
386-
BITMAP* temp = create_bitmap_ex(8, m_SpriteDiameter, m_SpriteDiameter);
372+
unsigned int clampedFrame = std::max(std::min(whichFrame, static_cast<int>(m_FrameCount) - 1), 0);
373+
int spriteSize = m_SpriteDiameter;
374+
if (includeChildren && dynamic_cast<MOSRotating*>(this)) {
375+
spriteSize = dynamic_cast<MOSRotating*>(this)->GetDiameter();
376+
}
377+
BITMAP* sprite = m_aSprite[clampedFrame];
378+
BITMAP* temp = create_bitmap_ex(8, spriteSize, spriteSize);
387379
rectfill(temp, 0, 0, temp->w - 1, temp->h - 1, 0);
388380
Vector tempCentre = Vector(temp->w / 2, temp->h / 2);
389381
Vector spriteCentre = Vector(sprite->w / 2, sprite->h / 2);
390-
Vector offset = (tempCentre + (m_SpriteOffset + spriteCentre).GetXFlipped(m_HFlipped).RadRotate(m_Rotation.GetRadAngle()) - spriteCentre);
391382

392-
if (!hflipped) {
393-
rotate_scaled_sprite(temp, sprite, offset.m_X, offset.m_Y, ftofix(GetAllegroAngle(-m_Rotation.GetDegAngle())), ftofix(m_Scale));
383+
if (includeChildren) {
384+
Draw(temp, m_Pos - tempCentre);
394385
} else {
395-
rotate_scaled_sprite_v_flip(temp, sprite, offset.m_X, offset.m_Y, ftofix(GetAllegroAngle(-m_Rotation.GetDegAngle())) + itofix(128), ftofix(m_Scale));
386+
Vector offset = (tempCentre + (m_SpriteOffset + spriteCentre).GetXFlipped(m_HFlipped).RadRotate(m_Rotation.GetRadAngle()) - spriteCentre);
387+
if (!hflipped) {
388+
rotate_scaled_sprite(temp, sprite, offset.m_X, offset.m_Y, ftofix(GetAllegroAngle(-m_Rotation.GetDegAngle())), ftofix(m_Scale));
389+
} else {
390+
rotate_scaled_sprite_v_flip(temp, sprite, offset.m_X, offset.m_Y, ftofix(GetAllegroAngle(-m_Rotation.GetDegAngle())) + itofix(128), ftofix(m_Scale));
391+
}
396392
}
397393

398394
for (int y = 0; y < temp->h; y++) {
399395
for (int x = 0; x < temp->w; x++) {
400-
int pixelIndex = getpixel(temp, x, y);
396+
int pixelIndex = _getpixel(temp, x, y);
401397
if (pixelIndex >= 0 && (pixelIndex != ignoreIndex) != invert) {
402398
Vector pixelPos = (Vector(x, y) - tempCentre) + origin;
403399
posList->push_back(pixelPos);
@@ -409,6 +405,40 @@ std::vector<Vector>* MOSprite::GetAllPixelPositions(const Vector& origin, float
409405
return posList;
410406
}
411407

408+
bool MOSprite::SetSpritePixelIndex(int x, int y, int whichFrame, int colorIndex, int ignoreIndex, bool invert) {
409+
if (!m_SpriteModified) {
410+
std::vector<BITMAP*> spriteList;
411+
412+
for (BITMAP* sprite : m_aSprite) {
413+
BITMAP* spriteCopy = create_bitmap_ex(8, sprite->w, sprite->h);
414+
rectfill(spriteCopy, 0, 0, spriteCopy->w - 1, spriteCopy->h - 1, 0);
415+
draw_sprite(spriteCopy, sprite, 0, 0);
416+
spriteList.push_back(spriteCopy);
417+
}
418+
419+
m_aSprite = spriteList;
420+
m_SpriteModified = true;
421+
}
422+
423+
unsigned int clampedFrame = std::max(std::min(whichFrame, static_cast<int>(m_FrameCount) - 1), 0);
424+
BITMAP* targetSprite = m_aSprite[clampedFrame];
425+
if (is_inside_bitmap(targetSprite, x, y, 0) && (ignoreIndex < 0 || (_getpixel(targetSprite, x, y) != ignoreIndex) != invert)) {
426+
_putpixel(targetSprite, x, y, colorIndex);
427+
return true;
428+
}
429+
return false;
430+
}
431+
432+
void MOSprite::SetAllSpritePixelIndexes(int whichFrame, int colorIndex, int ignoreIndex, bool invert) {
433+
unsigned int clampedFrame = std::max(std::min(whichFrame, static_cast<int>(m_FrameCount) - 1), 0);
434+
BITMAP* targetSprite = m_aSprite[clampedFrame];
435+
for (int y = 0; y < targetSprite->h; y++) {
436+
for (int x = 0; x < targetSprite->w; x++) {
437+
SetSpritePixelIndex(x, y, clampedFrame, colorIndex, ignoreIndex, invert);
438+
}
439+
}
440+
}
441+
412442
void MOSprite::Update() {
413443
MovableObject::Update();
414444

Source/Entities/MOSprite.h

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -95,30 +95,42 @@ namespace RTE {
9595
/// @param y Y coordinate on the bitmap of the pixel to get.
9696
/// @param whichFrame Which frame of the sprite sequence to check.
9797
/// @return Color index of the indicated pixel.
98-
int GetPixelIndex(int x, int y, unsigned int whichFrame = 0) const { return getpixel(m_aSprite[CLAMP(m_FrameCount - 1, 0, whichFrame)], x, y); }
99-
100-
/// Sets the color index of the pixel at position (X, Y) in the sprite bitmap
101-
/// @param x X coordinate on the bitmap of the pixel to set.
102-
/// @param y Y coordinate on the bitmap of the pixel to set.
103-
/// @param whichFrame Which frame of the sprite sequence to affect.
104-
/// @param colorIndex Desired color index of the indicated pixel.
105-
/// @param ignoreIndex Avoid setting pixel colour if it has this color index; set below 0 to disable.
106-
/// @param invert Whether or not to invert the ignoreIndex so it ONLY colors that index.
107-
void SetPixelIndex(int x, int y, unsigned int whichFrame, int colorIndex, int ignoreIndex, bool invert);
98+
int GetSpritePixelIndex(int x, int y, int whichFrame = 0) const;
10899

109100
/// Returns a list of vectors pointing to all matching pixels of the given frame in the sprite, accounting for flipping, rotation and scale.
110-
/// @param origin The position around which the vectors are centered.
101+
/// @param origin The absolute position around which the vectors are centered.
111102
/// @param angle The angle at which the sprite is rotated.
112103
/// @param hflipped Whether or not the sprite is flipped horizontally.
113104
/// @param whichFrame Which frame of the sprite sequence to check.
114105
/// @param ignoreIndex Which color index to ignore when checking; set below 0 to include everything.
115106
/// @param invert Whether or not to invert the above check so it ONLY counts that index.
116107
/// @return List of vectors pointing to all visible pixels of the given frame in the sprite.
117-
std::vector<Vector>* GetAllPixelPositions(const Vector& origin, float angle, bool hflipped, unsigned int whichFrame, int ignoreIndex, bool invert);
108+
std::vector<Vector>* GetAllSpritePixelPositions(const Vector& origin, float angle, bool hflipped, int whichFrame, int ignoreIndex, bool invert, bool includeChildren);
118109

119110
/// Returns a list of vectors pointing to all visible pixels of the given frame in the sprite, accounting for flipping, rotation and scale.
120111
/// @return List of vectors pointing to all visible pixels of the given frame in the sprite.
121-
std::vector<Vector>* GetAllVisiblePixelPositions() { return GetAllPixelPositions(m_Pos, m_Rotation.GetRadAngle(), m_HFlipped, m_Frame, 0, false); };
112+
std::vector<Vector>* GetAllVisibleSpritePixelPositions(bool includeChildren) { return GetAllSpritePixelPositions(m_Pos, m_Rotation.GetRadAngle(), m_HFlipped, m_Frame, 0, false, includeChildren); };
113+
114+
/// Sets the color index of the pixel at position (X, Y) in the sprite bitmap
115+
/// @param x X coordinate on the bitmap of the pixel to set.
116+
/// @param y Y coordinate on the bitmap of the pixel to set.
117+
/// @param whichFrame Which frame of the sprite sequence to affect.
118+
/// @param colorIndex Desired color index of the indicated pixel.
119+
/// @param ignoreIndex Avoid setting pixel colour if it has this color index; set below 0 to disable.
120+
/// @param invert Whether or not to invert the ignoreIndex so it ONLY colors that index.
121+
/// @return Whether or not the pixel index was successfully set.
122+
bool SetSpritePixelIndex(int x, int y, int whichFrame, int colorIndex, int ignoreIndex, bool invert);
123+
124+
/// Sets the color index of all matching pixels in the sprite bitmap.
125+
/// @param whichFrame Which frame of the sprite sequence to affect.
126+
/// @param colorIndex Desired color index of the pixels.
127+
/// @param ignoreIndex Avoid setting pixel colour if it has this color index; set below 0 to disable.
128+
/// @param invert Whether or not to invert the ignoreIndex so it ONLY colors that index.
129+
void SetAllSpritePixelIndexes(int whichFrame, int colorIndex, int ignoreIndex, bool invert);
130+
131+
/// Sets the color index of all visible pixels in the sprite bitmap.
132+
/// @param colorIndex Desired color index of the pixels.
133+
void SetAllVisibleSpritePixelIndexes(int colorIndex) { SetAllSpritePixelIndexes(m_Frame, colorIndex, 0, false); };
122134

123135
/// Gets the width of the bitmap of this MOSprite
124136
/// @return Sprite width if loaded.

Source/Entities/Material.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,10 @@ namespace RTE {
108108
/// @return The color of this material.
109109
Color GetColor() const { return m_Color; }
110110

111+
/// Gets the color index of this Material.
112+
/// @return The color index of this material.
113+
int GetColorIndex() const { return m_Color.GetIndex(); }
114+
111115
/// Indicates whether or not to use the Material's own color when a pixel of this Material is knocked loose from the terrain.
112116
/// @return Whether the Material's color, or the terrain pixel's color should be applied.
113117
bool UsesOwnColor() const { return m_UseOwnColor; }

Source/Lua/LuaBindingsEntities.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -774,7 +774,9 @@ LuaBindingRegisterFunctionDefinitionForType(EntityLuaBindings, Material) {
774774
.property("SettleMaterial", &Material::GetSettleMaterial)
775775
.property("SpawnMaterial", &Material::GetSpawnMaterial)
776776
.property("TransformsInto", &Material::GetSpawnMaterial)
777-
.property("IsScrap", &Material::IsScrap);
777+
.property("IsScrap", &Material::IsScrap)
778+
779+
.def("GetColorIndex", &Material::GetColorIndex);
778780
}
779781

780782
LuaBindingRegisterFunctionDefinitionForType(EntityLuaBindings, MetaPlayer) {
@@ -836,10 +838,12 @@ LuaBindingRegisterFunctionDefinitionForType(EntityLuaBindings, MOSprite) {
836838
.def("SetExitWound", &MOSprite::SetExitWound)
837839
.def("GetEntryWoundPresetName", &MOSprite::GetEntryWoundPresetName)
838840
.def("GetExitWoundPresetName", &MOSprite::GetExitWoundPresetName)
839-
.def("GetPixelIndex", &MOSprite::GetPixelIndex)
840-
.def("SetPixelIndex", &MOSprite::SetPixelIndex)
841-
.def("GetAllVisiblePixelPositions", &MOSprite::GetAllVisiblePixelPositions, luabind::return_stl_iterator)
842-
.def("GetAllPixelPositions", &MOSprite::GetAllPixelPositions, luabind::return_stl_iterator)
841+
.def("GetSpritePixelIndex", &MOSprite::GetSpritePixelIndex)
842+
.def("SetSpritePixelIndex", &MOSprite::SetSpritePixelIndex)
843+
.def("GetAllSpritePixelPositions", &MOSprite::GetAllSpritePixelPositions, luabind::return_stl_iterator)
844+
.def("GetAllVisibleSpritePixelPositions", &MOSprite::GetAllVisibleSpritePixelPositions, luabind::return_stl_iterator)
845+
.def("SetAllSpritePixelIndexes", &MOSprite::SetAllSpritePixelIndexes)
846+
.def("SetAllVisibleSpritePixelIndexes", &MOSprite::SetAllVisibleSpritePixelIndexes)
843847

844848
.enum_("SpriteAnimMode")[luabind::value("NOANIM", SpriteAnimMode::NOANIM),
845849
luabind::value("ALWAYSLOOP", SpriteAnimMode::ALWAYSLOOP),

0 commit comments

Comments
 (0)