diff --git a/code/redalert/bigoverlay.cpp b/code/redalert/bigoverlay.cpp index 683ed28..d51eac3 100644 --- a/code/redalert/bigoverlay.cpp +++ b/code/redalert/bigoverlay.cpp @@ -4,6 +4,7 @@ #include "function.h" #include "bigoverlay.h" #include "image.h" +#include #include BigOverlayManager bigOverlayManager; @@ -15,6 +16,7 @@ BigOverlay::BigOverlay */ BigOverlay::BigOverlay() { image = NULL; + numOverlayedCells = 0; enabled = false; } @@ -26,10 +28,12 @@ BigOverlay::Place void BigOverlay::Place(int screenx, int screeny) { COORDINATE lightCoord; + Map.FlagBigOverlayCells(this, screenx, screeny); + CellClass::ConvertIsoCoordsToScreen(screenx, screeny); position = Map.Pixel_To_Coord(screenx, screeny); - enabled = true; + enabled = true; } /* @@ -225,6 +229,29 @@ BigOverlayManager::Write_Scenerio_Lights ==================== */ void BigOverlayManager::Write_Scenerio(CCINIClass* ini) { + std::vector coord_table; + ini->Clear("BigOverlayCoords"); + for (int i = 0; i < MAX_WORLD_BIGOVERLAYS; i++) { + if (bigOverlays[i].IsEnabled() == false) { + continue; + } + + bigOverlays[i].startOverlayCoord = coord_table.size(); + for (int d = 0; d < bigOverlays[i].numOverlayedCells; d++) + { + coord_table.push_back(bigOverlays[i].overlayedCells[d]); + } + } + + for (int i = 0; i < coord_table.size(); i++) { + char buffer[2048*12]; + sprintf(buffer, "%d", coord_table[i]); + + char name[256]; + sprintf(name, "%d", i); + ini->Put_String("BigOverlayCoords", name, buffer); + } + ini->Clear("BigOverlay"); // Write out the lights. @@ -233,11 +260,21 @@ void BigOverlayManager::Write_Scenerio(CCINIClass* ini) { continue; } - char buffer[2048]; - char name[256]; - sprintf(buffer, "%d,%d", bigOverlays[i].GetPosition(), bigOverlays[i].GetIndex()); + //char buffer[2048*12]; + //sprintf(buffer, "%d,%d,%d", bigOverlays[i].GetPosition(), bigOverlays[i].GetIndex(), bigOverlays[i].numOverlayedCells); + + std::string buffer; + buffer += std::to_string(bigOverlays[i].GetPosition()); + buffer += ","; + buffer += std::to_string(bigOverlays[i].GetIndex()); + buffer += ","; + buffer += std::to_string(bigOverlays[i].startOverlayCoord); + buffer += ","; + buffer += std::to_string(bigOverlays[i].numOverlayedCells); + + char name[256]; sprintf(name, "%d", i); - ini->Put_String("BigOverlay", name, buffer); + ini->Put_String("BigOverlay", name, buffer.c_str()); } } @@ -248,9 +285,20 @@ BigOverlayManager::Read_Scenerio */ void BigOverlayManager::Read_Scenerio(CCINIClass* ini) { char buf[2048]; + std::vector coord_table; Reset(); + { + int len = ini->Entry_Count("BigOverlayCoords"); + for (int index = 0; index < len; index++) { + char const* entry = ini->Get_Entry("BigOverlayCoords", index); + ini->Get_String("BigOverlayCoords", entry, NULL, buf, sizeof(buf)); + + coord_table.push_back(atoi(buf)); + } + } + int len = ini->Entry_Count("BigOverlay"); for (int index = 0; index < len; index++) { char const* entry = ini->Get_Entry("BigOverlay", index); @@ -264,6 +312,14 @@ void BigOverlayManager::Read_Scenerio(CCINIClass* ini) { int in = atoi(strtok(NULL, ",")); Image_t* image = bigOverlayTypes[in].image; - bigOverlay->SetImage(in, image); + bigOverlay->SetImage(in, image); + + bigOverlay->startOverlayCoord = atoi(strtok(NULL, ",")); + bigOverlay->numOverlayedCells = atoi(strtok(NULL, ",")); + for (int d = 0; d < bigOverlay->numOverlayedCells; d++) { + bigOverlay->overlayedCells[d] = coord_table[bigOverlay->startOverlayCoord + d]; + CellClass* cellptr = &(Map)[bigOverlay->overlayedCells[d]]; + cellptr->bigOverlay = bigOverlay; + } } } \ No newline at end of file diff --git a/code/redalert/bigoverlay.h b/code/redalert/bigoverlay.h index 93b6b03..5e58c3f 100644 --- a/code/redalert/bigoverlay.h +++ b/code/redalert/bigoverlay.h @@ -17,6 +17,7 @@ struct BigOverlayType_t { class BigOverlay { friend class BigOverlayManager; +friend class DisplayClass; public: BigOverlay(); int GetIndex(void) { return index; } @@ -31,6 +32,10 @@ protected: void SetPosition(COORDINATE position) { this->position = position; } void SetOverlayNum(int overlayNum) { this->overlayNum = overlayNum; } bool IsEnabled(void) { return enabled; } + + int startOverlayCoord; + int numOverlayedCells; + COORDINATE overlayedCells[256]; private: int overlayNum; COORDINATE position; diff --git a/code/redalert/cell.cpp b/code/redalert/cell.cpp index 26df7ff..40cb1aa 100644 --- a/code/redalert/cell.cpp +++ b/code/redalert/cell.cpp @@ -131,6 +131,12 @@ CellClass::CellClass(void) : IsVisibleByPlayerMask(0), CTFFlag(NULL) { + x_screen_pos = 0; + y_screen_pos = 0; + x_world_pos = 0; + y_world_pos = 0; + bigOverlay = NULL; + for (int zone = MZONE_FIRST; zone < MZONE_COUNT; zone++) { Zones[zone] = 0; } @@ -469,6 +475,10 @@ bool CellClass::Is_Clear_To_Build(SpeedType loco) const */ if (ScenarioInit) return(true); + if (bigOverlay != NULL) { + return false; + } + /* ** If there is an object there, then don't allow building. */ @@ -1110,6 +1120,12 @@ void CellClass::Draw_It(int x, int y, bool objects) return; } +// jmarshall - debug mechanism + if (bigOverlay != NULL) { + GL_SetColor(0.35, 0.35, 0.35); + } +// jmarshall end + CellCount++; /* @@ -1166,13 +1182,13 @@ void CellClass::Draw_It(int x, int y, bool objects) */ if (ttype->Get_Image_Data()) { // jmarshall - hd image should always be valid even if loading legacy assets - int xx = x; - int yy = y; - ConvertCoordsToIsometric(xx, yy); - lastRenderX = xx; - lastRenderY = yy; + x_screen_pos = x; + y_screen_pos = y; + ConvertCoordsToIsometric(x_screen_pos, y_screen_pos); + lastRenderX = x_screen_pos; + lastRenderY = y_screen_pos; int ticon = icon; - LogicPage->Draw_Stamp(ttype->Get_HDImage_Data(), icon, xx, yy, NULL, WINDOW_TACTICAL); + LogicPage->Draw_Stamp(ttype->Get_HDImage_Data(), icon, x_screen_pos, y_screen_pos, NULL, WINDOW_TACTICAL); // jmarshall end //if (remap) { // LogicPage->Remap(x+Map.TacPixelX, y+Map.TacPixelY, ICON_PIXEL_W, ICON_PIXEL_H, remap); @@ -3016,6 +3032,10 @@ bool CellClass::Is_Clear_To_Move(SpeedType loco, bool ignoreinfantry, bool ignor return(true); } + if (bigOverlay != NULL) { + return false; + } + /* ** If a zone was specified, then see if the cell is in a legal ** zone to allow movement. diff --git a/code/redalert/cell.h b/code/redalert/cell.h index e609bd3..ea9c9af 100644 --- a/code/redalert/cell.h +++ b/code/redalert/cell.h @@ -177,10 +177,14 @@ class CellClass ObjectClass * Overlapper[6]; #endif + class BigOverlay* bigOverlay; + int visibleFrame; int x_world_pos; int y_world_pos; + int x_screen_pos; + int y_screen_pos; /* ** Per-player view of whether a cell is mapped. One bit for each house type. ST - 8/2/2019 3:00PM diff --git a/code/redalert/display.cpp b/code/redalert/display.cpp index cb013fa..970db9d 100644 --- a/code/redalert/display.cpp +++ b/code/redalert/display.cpp @@ -4742,6 +4742,35 @@ void DisplayClass::All_To_Look(HouseClass *house, bool units_only) } +void DisplayClass::FlagBigOverlayCells(BigOverlay* overlay, int screenx, int screeny) { + int width = overlay->GetImage()->width; + int height = overlay->GetImage()->height; + + overlay->numOverlayedCells = 0; + + for (int i = 0; i < numCachedDisplayCells; i++) { + CellClass* cellptr = cellDisplayCache[i].ptr; + + Rect rect; + + rect.X = cellptr->x_screen_pos - CELL_PIXEL_W; + rect.Y = cellptr->y_screen_pos - height; + rect.X2 = rect.X + width; + rect.Y2 = rect.Y + height; + rect.Width = width; + rect.Height = height; + + if(rect.ContainsPoint(screenx, screeny)) { + if(cellptr->bigOverlay == NULL) + { + cellptr->bigOverlay = overlay; + overlay->overlayedCells[overlay->numOverlayedCells++] = Cell_Coord(cellptr->Cell_Number()); + } + } + } +} + + /* ** Added house parameter for client/server multiplayer. ST - 8/12/2019 11:48AM ** diff --git a/code/redalert/display.h b/code/redalert/display.h index f7ac689..f746b73 100644 --- a/code/redalert/display.h +++ b/code/redalert/display.h @@ -40,6 +40,7 @@ #include "tacticalcoord.h" struct Image_t; +class BigOverlay; // jmarshall - isometric #define ICON_PIXEL_W 48 @@ -151,6 +152,8 @@ class DisplayClass: public MapClass virtual void AI(KeyNumType &input, int x, int y); virtual void Draw_It(bool complete=false); + virtual void FlagBigOverlayCells(BigOverlay* overlay, int screenx, int screeny); + /* ** Added functionality. */ diff --git a/code/redalert/scenario.cpp b/code/redalert/scenario.cpp index 7c67153..f9f4138 100644 --- a/code/redalert/scenario.cpp +++ b/code/redalert/scenario.cpp @@ -2275,7 +2275,6 @@ bool Read_Scenario_INI(char * fname, bool ) Scen.Percent = ini.Get_Int(BASIC, "Percent", Scen.Percent); lightManager.Read_Scenerio_Lights(&ini); - bigOverlayManager.Read_Scenerio(&ini); /* ** Read in the specific information for each of the house types. This creates @@ -2306,6 +2305,8 @@ bool Read_Scenario_INI(char * fname, bool ) Map.Read_INI(ini); Call_Back(); + bigOverlayManager.Read_Scenerio(&ini); + /* ** Assign PlayerPtr by reading the player's house from the INI; ** Must be done before any TechnoClass objects are created. diff --git a/code/redalert/unit.cpp b/code/redalert/unit.cpp index b73f32a..926fa5b 100644 --- a/code/redalert/unit.cpp +++ b/code/redalert/unit.cpp @@ -3161,6 +3161,10 @@ MoveType UnitClass::Can_Enter_Cell(CELL cell, FacingType ) const if ((unsigned)cell >= MAP_CELL_TOTAL) return(MOVE_NO); + if (cellptr->bigOverlay != NULL) { + return MOVE_NO; + } + /* ** Moving off the edge of the map is not allowed unless ** this is a loaner vehicle.