Skip to content

Commit e407977

Browse files
committed
Added line, circle and box variants of DislodgePixel with optional deletion
1 parent 035d450 commit e407977

File tree

3 files changed

+189
-1
lines changed

3 files changed

+189
-1
lines changed

Source/Lua/LuaBindingsManagers.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,14 @@ LuaBindingRegisterFunctionDefinitionForType(ManagerLuaBindings, SceneMan) {
331331
.def("ObscuredPoint", (bool(SceneMan::*)(int, int, int)) & SceneMan::ObscuredPoint)
332332
.def("AddSceneObject", &SceneMan::AddSceneObject, luabind::adopt(_2))
333333
.def("CheckAndRemoveOrphans", (int(SceneMan::*)(int, int, int, int, bool)) & SceneMan::RemoveOrphans)
334-
.def("DislodgePixel", &SceneMan::DislodgePixel);
334+
.def("DislodgePixel", &SceneMan::DislodgePixel)
335+
.def("DislodgePixel", &SceneMan::DislodgePixelBool)
336+
.def("DislodgePixelLine", (const std::vector<MovableObject*>* (SceneMan::*)(const Vector& start, const Vector& ray, int skip, bool deletePixels) const) & SceneMan::DislodgePixelLine, luabind::adopt(luabind::return_value) + luabind::return_stl_iterator)
337+
.def("DislodgePixelLine", (const std::vector<MovableObject*>* (SceneMan::*)(const Vector& start, const Vector& ray, int skip) const) & SceneMan::DislodgePixelLineNoBool, luabind::adopt(luabind::return_value) + luabind::return_stl_iterator)
338+
.def("DislodgePixelCircle", (const std::vector<MovableObject*>* (SceneMan::*)(const Vector& centre, float radius, bool deletePixels) const) & SceneMan::DislodgePixelCircle, luabind::adopt(luabind::return_value) + luabind::return_stl_iterator)
339+
.def("DislodgePixelCircle", (const std::vector<MovableObject*>* (SceneMan::*)(const Vector& centre, float radius) const) & SceneMan::DislodgePixelCircleNoBool, luabind::adopt(luabind::return_value) + luabind::return_stl_iterator)
340+
.def("DislodgePixelBox", (const std::vector<MovableObject*>* (SceneMan::*)(const Vector& upperLeftCorner, const Vector& lowerRightCorner, bool deletePixels) const) & SceneMan::DislodgePixelBox, luabind::adopt(luabind::return_value) + luabind::return_stl_iterator)
341+
.def("DislodgePixelBox", (const std::vector<MovableObject*>* (SceneMan::*)(const Vector& upperLeftCorner, const Vector& lowerRightCorner) const) & SceneMan::DislodgePixelBoxNoBool, luabind::adopt(luabind::return_value) + luabind::return_stl_iterator);
335342
}
336343

337344
LuaBindingRegisterFunctionDefinitionForType(ManagerLuaBindings, CameraMan) {

Source/Managers/SceneMan.cpp

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -922,6 +922,139 @@ MovableObject* SceneMan::DislodgePixel(int posX, int posY) {
922922
return pixelMO;
923923
}
924924

925+
// Bool variant to avoid changing the original
926+
MovableObject* SceneMan::DislodgePixelBool(int posX, int posY, bool deletePixel) {
927+
MovableObject* pixelMO = DislodgePixel(posX, posY);
928+
pixelMO->SetToDelete(deletePixel);
929+
return pixelMO;
930+
}
931+
932+
std::vector<MovableObject*>* SceneMan::DislodgePixelCircle(const Vector& centre, float radius, bool deletePixels) {
933+
std::vector<MovableObject*>* pixelList = new std::vector<MovableObject*>();
934+
for (float x = 0; x <= radius * 2; x++) {
935+
for (float y = 0; y <= radius * 2; y++) {
936+
Vector checkPos = Vector(x - radius, y - radius) + centre;
937+
if (!ShortestDistance(centre, checkPos, true).MagnitudeIsGreaterThan(radius)) {
938+
MovableObject* px = DislodgePixel(checkPos.m_X, checkPos.m_Y);
939+
if (px) {
940+
px->SetToDelete(deletePixels);
941+
pixelList->push_back(px);
942+
}
943+
}
944+
}
945+
}
946+
947+
return pixelList;
948+
}
949+
950+
std::vector<MovableObject*>* SceneMan::DislodgePixelCircleNoBool(const Vector& centre, float radius) {
951+
return DislodgePixelCircle(centre, radius, false);
952+
}
953+
954+
std::vector<MovableObject*>* SceneMan::DislodgePixelBox(const Vector& upperLeftCorner, const Vector& lowerRightCorner, bool deletePixels) {
955+
std::vector<MovableObject*>* pixelList = new std::vector<MovableObject*>();
956+
957+
// Make sure it works even if people input corners in the wrong order
958+
Vector start = Vector(std::min(upperLeftCorner.m_X, lowerRightCorner.m_X), std::min(upperLeftCorner.m_Y, lowerRightCorner.m_Y));
959+
Vector end = Vector(std::max(upperLeftCorner.m_X, lowerRightCorner.m_X), std::max(upperLeftCorner.m_Y, lowerRightCorner.m_Y));
960+
961+
float width = end.m_X - start.m_X;
962+
float height = end.m_Y - start.m_Y;
963+
for (float x = 0; x <= width * 2; x++) {
964+
for (float y = 0; y <= height * 2; y++) {
965+
Vector checkPos = start + Vector(x, y);
966+
MovableObject* px = DislodgePixel(checkPos.m_X, checkPos.m_Y);
967+
if (px) {
968+
px->SetToDelete(deletePixels);
969+
pixelList->push_back(px);
970+
}
971+
}
972+
}
973+
974+
return pixelList;
975+
}
976+
977+
std::vector<MovableObject*>* SceneMan::DislodgePixelBoxNoBool(const Vector& upperLeftCorner, const Vector& lowerRightCorner) {
978+
return DislodgePixelBox(upperLeftCorner, lowerRightCorner, false);
979+
}
980+
981+
std::vector<MovableObject*>* SceneMan::DislodgePixelLine(const Vector& start, const Vector& ray, int skip, bool deletePixels) {
982+
std::vector<MovableObject*>* pixelList = new std::vector<MovableObject*>();
983+
int error, dom, sub, domSteps, skipped = skip;
984+
int intPos[2], delta[2], delta2[2], increment[2];
985+
986+
intPos[X] = std::floor(start.m_X);
987+
intPos[Y] = std::floor(start.m_Y);
988+
delta[X] = std::floor(start.m_X + ray.m_X) - intPos[X];
989+
delta[Y] = std::floor(start.m_Y + ray.m_Y) - intPos[Y];
990+
991+
//if (delta[X] == 0 && delta[Y] == 0)
992+
// return false;
993+
994+
/////////////////////////////////////////////////////
995+
// Bresenham's line drawing algorithm preparation
996+
997+
if (delta[X] < 0) {
998+
increment[X] = -1;
999+
delta[X] = -delta[X];
1000+
} else
1001+
increment[X] = 1;
1002+
1003+
if (delta[Y] < 0) {
1004+
increment[Y] = -1;
1005+
delta[Y] = -delta[Y];
1006+
} else
1007+
increment[Y] = 1;
1008+
1009+
// Scale by 2, for better accuracy of the error at the first pixel
1010+
delta2[X] = delta[X] << 1;
1011+
delta2[Y] = delta[Y] << 1;
1012+
1013+
// If X is dominant, Y is submissive, and vice versa.
1014+
if (delta[X] > delta[Y]) {
1015+
dom = X;
1016+
sub = Y;
1017+
} else {
1018+
dom = Y;
1019+
sub = X;
1020+
}
1021+
1022+
error = delta2[sub] - delta[dom];
1023+
1024+
/////////////////////////////////////////////////////
1025+
// Bresenham's line drawing algorithm execution
1026+
1027+
for (domSteps = 0; domSteps < delta[dom]; ++domSteps) {
1028+
intPos[dom] += increment[dom];
1029+
if (error >= 0) {
1030+
intPos[sub] += increment[sub];
1031+
error -= delta2[dom];
1032+
}
1033+
error += delta2[sub];
1034+
1035+
// Only check pixel if we're not due to skip any, or if this is the last pixel
1036+
if (++skipped > skip || domSteps + 1 == delta[dom]) {
1037+
// Scene wrapping
1038+
g_SceneMan.WrapPosition(intPos[X], intPos[Y]);
1039+
1040+
MovableObject* px = DislodgePixel(intPos[X], intPos[Y]);
1041+
if (px) {
1042+
px->SetToDelete(deletePixels);
1043+
pixelList->push_back(px);
1044+
}
1045+
1046+
// Reset skip counter
1047+
skipped = 0;
1048+
}
1049+
}
1050+
1051+
return pixelList;
1052+
}
1053+
1054+
std::vector<MovableObject*>* SceneMan::DislodgePixelLineNoBool(const Vector& start, const Vector& ray, int skip) {
1055+
return DislodgePixelLine(start, ray, skip, false);
1056+
}
1057+
9251058
void SceneMan::MakeAllUnseen(Vector pixelSize, const int team) {
9261059
RTEAssert(m_pCurrentScene, "Messing with scene before the scene exists!");
9271060
if (team < Activity::TeamOne || team >= Activity::MaxTeamCount)

Source/Managers/SceneMan.h

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,54 @@ namespace RTE {
403403
/// @return The newly dislodged pixel, if one was found.
404404
MovableObject* DislodgePixel(int posX, int posY);
405405

406+
/// Removes a pixel from the terrain and adds it to MovableMan.
407+
/// @param posX The X coordinate of the terrain pixel.
408+
/// @param posX The Y coordinate of the terrain pixel.
409+
/// @param deletePixel Whether or not to immediately mark the pixel for deletion.
410+
/// @return The newly dislodged pixel, if one was found.
411+
MovableObject* DislodgePixelBool(int posX, int posY, bool deletePixel);
412+
413+
/// Removes a circle of pixels from the terrain and adds them to MovableMan.
414+
/// @param centre The vector position of the centre of the circle.
415+
/// @param radius The radius of the circle of pixels to remove.
416+
/// @param deletePixels Whether or not to immediately mark all found pixels for deletion.
417+
/// @return A list of the removed pixels, if any.
418+
std::vector<MovableObject*>* DislodgePixelCircle(const Vector& centre, float radius, bool deletePixels);
419+
420+
/// Removes a circle of pixels from the terrain and adds them to MovableMan.
421+
/// @param centre The vector position of the centre of the circle.
422+
/// @param radius The radius of the circle of pixels to remove.
423+
/// @return A list of the removed pixels, if any.
424+
std::vector<MovableObject*>* DislodgePixelCircleNoBool(const Vector& centre, float radius);
425+
426+
/// Removes a box of pixels from the terrain and adds them to MovableMan.
427+
/// @param upperLeftCorner The vector position of the upper left corner of the box.
428+
/// @param lowerRightCorner The vector position of the lower right corner of the box.
429+
/// @param deletePixels Whether or not to immediately mark all found pixels for deletion.
430+
/// @return A list of the removed pixels, if any.
431+
std::vector<MovableObject*>* DislodgePixelBox(const Vector& upperLeftCorner, const Vector& lowerRightCorner, bool deletePixels);
432+
433+
/// Removes a box of pixels from the terrain and adds them to MovableMan.
434+
/// @param upperLeftCorner The vector position of the upper left corner of the box.
435+
/// @param lowerRightCorner The vector position of the lower right corner of the box.
436+
/// @return A list of the removed pixels, if any.
437+
std::vector<MovableObject*>* DislodgePixelBoxNoBool(const Vector& upperLeftCorner, const Vector& lowerRightCorner);
438+
439+
/// Removes a line of pixels from the terrain and adds them to MovableMan.
440+
/// @param start The starting position.
441+
/// @param ray The vector to trace along.
442+
/// @param skip For every pixel checked along the line, how many to skip between them.
443+
/// @param deletePixels Whether or not to immediately mark all found pixels for deletion.
444+
/// @return A list of the removed pixels, if any.
445+
std::vector<MovableObject*>* DislodgePixelLine(const Vector& start, const Vector& ray, int skip, bool deletePixels);
446+
447+
/// Removes a line of pixels from the terrain and adds them to MovableMan.
448+
/// @param start The starting position.
449+
/// @param ray The vector to trace along.
450+
/// @param skip For every pixel checked along the line, how many to skip between them.
451+
/// @return A list of the removed pixels, if any.
452+
std::vector<MovableObject*>* DislodgePixelLineNoBool(const Vector& start, const Vector& ray, int skip);
453+
406454
/// Sets one team's view of the scene to be unseen, using a generated map
407455
/// of a specific resolution chunkiness.
408456
/// @param pixelSize The dimensions of the pixels that should make up the unseen layer.

0 commit comments

Comments
 (0)