@@ -922,6 +922,139 @@ MovableObject* SceneMan::DislodgePixel(int posX, int posY) {
922
922
return pixelMO;
923
923
}
924
924
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
+
925
1058
void SceneMan::MakeAllUnseen (Vector pixelSize, const int team) {
926
1059
RTEAssert (m_pCurrentScene, " Messing with scene before the scene exists!" );
927
1060
if (team < Activity::TeamOne || team >= Activity::MaxTeamCount)
0 commit comments