diff --git a/Core/GameEngine/Source/GameLogic/AI/AIPathfind.cpp b/Core/GameEngine/Source/GameLogic/AI/AIPathfind.cpp index 180a74eb5bc..49e0bbca25b 100644 --- a/Core/GameEngine/Source/GameLogic/AI/AIPathfind.cpp +++ b/Core/GameEngine/Source/GameLogic/AI/AIPathfind.cpp @@ -5529,12 +5529,12 @@ Bool Pathfinder::adjustDestination(Object *obj, const LocomotorSet& locomotorSet Bool center; getRadiusAndCenter(obj, iRadius, center); ICoord2D cell; - Coord3D adjustDest = *dest; + Coord3D cellDest = *dest; if (!center) { - adjustDest.x += PATHFIND_CELL_SIZE_F/2; - adjustDest.y += PATHFIND_CELL_SIZE_F/2; + cellDest.x += PATHFIND_CELL_SIZE_F/2; + cellDest.y += PATHFIND_CELL_SIZE_F/2; } - worldToCell( &adjustDest, &cell ); + worldToCell( &cellDest, &cell ); PathfindLayerEnum layer = TheTerrainLogic->getLayerForDestination(dest); if (groupDest) { layer = TheTerrainLogic->getLayerForDestination(groupDest); @@ -5543,9 +5543,24 @@ Bool Pathfinder::adjustDestination(Object *obj, const LocomotorSet& locomotorSet Int i = cell.x; Int j = cell.y; // Check the center cell - if (checkForAdjust(obj, locomotorSet, isHuman, i,j, layer, iRadius, center, dest, groupDest)) { +#if RETAIL_COMPATIBLE_PATHFINDING + if (checkForAdjust(obj, locomotorSet, isHuman, i, j, layer, iRadius, center, dest, groupDest)) { + return true; + } +#else + Coord3D adjustDest = *dest; + if (checkForAdjust(obj, locomotorSet, isHuman, i, j, layer, iRadius, center, &adjustDest, groupDest)) { + // TheSuperHackers @bugfix stephanmeesters 15/06/2026 Destination adjustment always snaps to the nearest grid cell + // even when no adjustment is necessary because there are no obstructions. For single units this adjustment + // can be skipped in order to provide more accurate movement, which is especially noticeable for chinooks. + const Bool singleUnit = obj && obj->getGroup() && obj->getGroup()->getCount() == 1; + const Bool useExactDestination = isHuman && singleUnit; + if (!useExactDestination) { + *dest = adjustDest; + } return true; } +#endif // TheSuperHackers @info Expanding counter-clockwise spiral search around center cell C. Each full lap walks right->up->left->down. // After every pair of directions (right+up, then left+down) length of the segment grows by 1. diff --git a/Core/GameEngine/Source/GameNetwork/NetCommandList.cpp b/Core/GameEngine/Source/GameNetwork/NetCommandList.cpp index b6a834c987b..ea5d410ba70 100644 --- a/Core/GameEngine/Source/GameNetwork/NetCommandList.cpp +++ b/Core/GameEngine/Source/GameNetwork/NetCommandList.cpp @@ -122,6 +122,18 @@ void NetCommandList::reset() { m_lastMessageInserted = nullptr; } +static bool isCommandIdNewer(UnsignedShort newVal, UnsignedShort oldVal) +{ +#if RETAIL_COMPATIBLE_NETWORKING + return newVal > oldVal; +#else + // TheSuperHackers @bugfix Caball009 14/06/2026 Ensure messages are sorted + // chronologically by including a command id overflow check. + const UnsignedShort diff = newVal - oldVal; + return diff != 0 && diff < 0x8000; +#endif +} + /** * Insert sorts msg. Assumes that all the previous message inserts were done using this function. * The message is sorted in based first on command type, then player id, and then command id. @@ -151,10 +163,10 @@ NetCommandRef * NetCommandList::addMessage(NetCommandMsg *cmdMsg) { NetCommandRef *theNext = m_lastMessageInserted->getNext(); if ((m_lastMessageInserted->getCommand()->getNetCommandType() == msg->getCommand()->getNetCommandType()) && (m_lastMessageInserted->getCommand()->getPlayerID() == msg->getCommand()->getPlayerID()) && - (m_lastMessageInserted->getCommand()->getID() < msg->getCommand()->getID()) && + isCommandIdNewer(msg->getCommand()->getID(), m_lastMessageInserted->getCommand()->getID()) && ((theNext == nullptr) || ((theNext->getCommand()->getNetCommandType() > msg->getCommand()->getNetCommandType()) || (theNext->getCommand()->getPlayerID() > msg->getCommand()->getPlayerID()) || - (theNext->getCommand()->getID() > msg->getCommand()->getID())))) { + isCommandIdNewer(theNext->getCommand()->getID(), msg->getCommand()->getID())))) { // Make sure this command isn't already in the list. if (isEqualCommandMsg(m_lastMessageInserted->getCommand(), msg->getCommand())) { @@ -275,7 +287,10 @@ NetCommandRef * NetCommandList::addMessage(NetCommandMsg *cmdMsg) { // Find the position within the player's section based on the command ID. // If the command type doesn't require a command ID, sort by whatever it should be sorted by. - while ((tempmsg != nullptr) && (msg->getCommand()->getNetCommandType() == tempmsg->getCommand()->getNetCommandType()) && (msg->getCommand()->getPlayerID() == tempmsg->getCommand()->getPlayerID()) && (msg->getCommand()->getSortNumber() > tempmsg->getCommand()->getSortNumber())) { + while (tempmsg != nullptr + && msg->getCommand()->getNetCommandType() == tempmsg->getCommand()->getNetCommandType() + && msg->getCommand()->getPlayerID() == tempmsg->getCommand()->getPlayerID() + && isCommandIdNewer(msg->getCommand()->getSortNumber(), tempmsg->getCommand()->getSortNumber())) { tempmsg = tempmsg->getNext(); } diff --git a/Core/GameEngine/Source/GameNetwork/Network.cpp b/Core/GameEngine/Source/GameNetwork/Network.cpp index 7e697197fa0..837ff693f6c 100644 --- a/Core/GameEngine/Source/GameNetwork/Network.cpp +++ b/Core/GameEngine/Source/GameNetwork/Network.cpp @@ -53,7 +53,7 @@ #include "GameClient/MessageBox.h" -#if defined(DEBUG_CRC) +#if defined(DEBUG_CRC) && !RETAIL_COMPATIBLE_NETWORKING Int NET_CRC_INTERVAL = 1; #else Int NET_CRC_INTERVAL = 100; diff --git a/Core/GameEngine/Source/GameNetwork/NetworkUtil.cpp b/Core/GameEngine/Source/GameNetwork/NetworkUtil.cpp index 174599cc97c..ab95b52e8ca 100644 --- a/Core/GameEngine/Source/GameNetwork/NetworkUtil.cpp +++ b/Core/GameEngine/Source/GameNetwork/NetworkUtil.cpp @@ -110,10 +110,10 @@ UnsignedInt ResolveIP(AsciiString host) /** * Returns the next network command ID. */ -UnsignedShort GenerateNextCommandID() { - static UnsignedShort commandID = 64000; - ++commandID; - return commandID; +static UnsignedShort s_commandID = 0; +UnsignedShort GenerateNextCommandID() +{ + return s_commandID++; } /** diff --git a/Core/Libraries/Source/WWVegas/WW3D2/textureloader.cpp b/Core/Libraries/Source/WWVegas/WW3D2/textureloader.cpp index 08046b73a16..bea17341348 100644 --- a/Core/Libraries/Source/WWVegas/WW3D2/textureloader.cpp +++ b/Core/Libraries/Source/WWVegas/WW3D2/textureloader.cpp @@ -395,7 +395,7 @@ void TextureLoader::Validate_Texture_Size } unsigned poweroftwodepth = 1; - while (poweroftwodepth< depth) + while (poweroftwodepth < depth) { poweroftwodepth <<= 1; } @@ -413,18 +413,22 @@ void TextureLoader::Validate_Texture_Size poweroftwodepth=dx8caps.MaxVolumeExtent; } - if (poweroftwowidth>poweroftwoheight) + const unsigned maxTextureAspectRatio = dx8caps.MaxTextureAspectRatio; + if (maxTextureAspectRatio != 0) { - while (poweroftwowidth/poweroftwoheight>8) + if (poweroftwowidth>poweroftwoheight) { - poweroftwoheight*=2; + while (poweroftwowidth/poweroftwoheight > maxTextureAspectRatio) + { + poweroftwoheight*=2; + } } - } - else - { - while (poweroftwoheight/poweroftwowidth>8) + else { - poweroftwowidth*=2; + while (poweroftwoheight/poweroftwowidth > maxTextureAspectRatio) + { + poweroftwowidth*=2; + } } } @@ -1349,6 +1353,33 @@ void TextureLoadTaskClass::Apply(bool initialize) D3DTexture = nullptr; } + +static unsigned Get_Requested_Reduction(unsigned width, unsigned height, unsigned mip_count) +{ + // Figure out correct reduction + unsigned reqReduction = WW3D::Get_Texture_Reduction(); + + // Leave only the lowest level + if (reqReduction >= max(mip_count, 1u)) + reqReduction = mip_count-1; + + // Clamp reduction + unsigned curReduction = 0; + unsigned curWidth = width; + unsigned curHeight = height; + unsigned minDim = WW3D::Get_Texture_Min_Dimension(); + + while (curReduction < reqReduction && curWidth > minDim && curHeight > minDim) + { + curWidth >>= 1; + curHeight >>= 1; + curReduction++; + } + + return curReduction; +} + + static bool Get_Texture_Information ( const char* filename, @@ -1368,7 +1399,8 @@ static bool Get_Texture_Information if (compressed) { DDSFileClass dds_file(filename, 0); - if (!dds_file.Is_Available()) return false; + if (!dds_file.Is_Available()) + return false; // Destination size will be the next power of two square from the larger width and height... w = dds_file.Get_Width(0); @@ -1376,24 +1408,8 @@ static bool Get_Texture_Information d = dds_file.Get_Depth(0); format = dds_file.Get_Format(); mip_count = dds_file.Get_Mip_Level_Count(); - //Figure out correct reduction - int reqReduction=WW3D::Get_Texture_Reduction(); //requested reduction - - if (reqReduction >= mip_count) - reqReduction=mip_count-1; //leave only the lowest level - - //Clamp reduction - int curReduction=0; - int curWidth=w; - int curHeight=h; - int minDim=WW3D::Get_Texture_Min_Dimension(); - - while (curReduction < reqReduction && curWidth > minDim && curHeight > minDim) - { curWidth >>=1; //keep dividing - curHeight >>=1; - curReduction++; - } - reduction=curReduction; + reduction = Get_Requested_Reduction(w, h, mip_count); + return true; } @@ -1407,35 +1423,17 @@ static bool Get_Texture_Information WW3DFormat dest_format; Get_WW3D_Format(dest_format,format,bpp,targa); + // Figure out how many mip levels this texture will occupy mip_count = 0; - - //Figure out how many mip levels this texture will occupy for (int i=targa.Header.Width, j=targa.Header.Height; i > 0 && j > 0; i>>=1, j>>=1) mip_count++; - //Figure out correct reduction - int reqReduction=WW3D::Get_Texture_Reduction(); //requested reduction - - if (reqReduction >= mip_count) - reqReduction=mip_count-1; //leave only the lowest level - - //Clamp reduction - int curReduction=0; - int curWidth=targa.Header.Width; - int curHeight=targa.Header.Height; - int minDim=WW3D::Get_Texture_Min_Dimension(); - - while (curReduction < reqReduction && curWidth > minDim && curHeight > minDim) - { curWidth >>=1; //keep dividing - curHeight >>=1; - curReduction++; - } - reduction=curReduction; - // Destination size will be the next power of two square from the larger width and height... w = targa.Header.Width; h = targa.Header.Height; d = 1; + reduction = Get_Requested_Reduction(w, h, mip_count); + return true; } @@ -1448,119 +1446,106 @@ static bool Get_Texture_Information return false; } - w=thumb->Get_Original_Texture_Width() >> reduction; - h=thumb->Get_Original_Texture_Height() >> reduction; - //d=thumb->Get_Original_Texture_Depth() >> reduction; // need to a volume texture support to thumbnails...maybe + w=thumb->Get_Original_Texture_Width(); + h=thumb->Get_Original_Texture_Height(); + d=1; mip_count=thumb->Get_Original_Texture_Mip_Level_Count(); format=thumb->Get_Original_Texture_Format(); + reduction=0; + return true; } -bool TextureLoadTaskClass::Begin_Compressed_Load() +static void Validate_Reduction(const TextureBaseClass* texture, unsigned& reduction, unsigned mip_count) { - if (Texture == nullptr) + if (!texture->Is_Reducible() || texture->MipLevelCount == MIP_LEVELS_1) { - return false; + reduction = 0; } - - if (DX8Wrapper::Get_Current_Caps() == nullptr) + else if (texture->MipLevelCount != MIP_LEVELS_ALL && reduction >= (unsigned)texture->MipLevelCount) { - // GeneralsX @bugfix fbraz 04/05/2026 Skip compressed load when DX8 caps are unavailable in headless execution. - return false; + reduction = (unsigned)texture->MipLevelCount - 1; } - unsigned orig_w,orig_h,orig_d,orig_mip_count,reduction; - WW3DFormat orig_format; - if (!Get_Texture_Information - ( - Texture->Get_Full_Path(), - reduction, - orig_w, - orig_h, - orig_d, - orig_format, - orig_mip_count, - true - ) - ) + if (reduction >= mip_count) { - return false; + reduction = 0; // should not be possible, but check just in case. } +} - // Destination size will be the next power of two square from the larger width and height... - unsigned int width = orig_w; - unsigned int height = orig_h; - TextureLoader::Validate_Texture_Size(width, height,orig_d); - // If the size doesn't match, try and see if texture reduction would help... (mainly for - // cases where loaded texture is larger than hardware limit) - if (width != orig_w || height != orig_h) +// If the size doesn't match, try and see if texture reduction would help... +// (mainly for cases where loaded texture is larger than hardware limit) +static void Apply_Dim_Reduction(unsigned& width, unsigned& height, unsigned& reduction, unsigned mip_count) +{ + unsigned dummy_depth = 1; + + for (unsigned r = reduction; r < mip_count; ++r) { - for (unsigned int i = 1; i < orig_mip_count; ++i) - { - unsigned w=orig_w>>i; - if (w<4) w=4; - unsigned h=orig_h>>i; - if (h<4) h=4; - unsigned tmp_w=w; - unsigned tmp_h=h; + unsigned w = max(width >> r, 4u); + unsigned h = max(height >> r, 4u); + unsigned tmp_w = w; + unsigned tmp_h = h; - TextureLoader::Validate_Texture_Size(w,h,orig_d); + TextureLoader::Validate_Texture_Size(w, h, dummy_depth); - if (w == tmp_w && h == tmp_h) - { - Reduction += i; - width = w; - height = h; - break; - } + if (w == tmp_w && h == tmp_h) + { + width = w; + height = h; + reduction = r; + break; } } +} - Width = width; - Height = height; - Format = Get_Valid_Texture_Format(orig_format, Texture->Is_Compression_Allowed()); - Reduction = reduction; - +// If the size doesn't match, try and see if texture reduction would help... +// (mainly for cases where loaded texture is larger than hardware limit) +static void Apply_Dim_Reduction_With_Depth(unsigned& width, unsigned& height, unsigned& depth, unsigned& reduction, unsigned mip_count) +{ + for (unsigned r = reduction; r < mip_count; ++r) + { + unsigned w = max(width >> r, 4u); + unsigned h = max(height >> r, 4u); + unsigned d = max(depth >> r, 1u); + unsigned tmp_w = w; + unsigned tmp_h = h; + unsigned tmp_d = d; - if (!Texture->Is_Reducible() || Texture->MipLevelCount == MIP_LEVELS_1) - Reduction = 0; //app doesn't want this texture to ever be reduced. - else - //Make sure we don't reduce below the level requested by the app - if (Texture->MipLevelCount != MIP_LEVELS_ALL && (Texture->MipLevelCount - Reduction) < 1) - Reduction = Texture->MipLevelCount - 1; + TextureLoader::Validate_Texture_Size(w, h, d); - //Another sanity check - if (Reduction >= orig_mip_count) - Reduction = 0; //should not be possible to get here, but check just in case. + if (w == tmp_w && h == tmp_h && d == tmp_d) + { + width = w; + height = h; + depth = d; + reduction = r; + break; + } + } +} - unsigned int mip_level_count = Get_Mip_Level_Count(); - int reducedWidth=Width; - int reducedHeight=Height; +static void Apply_Mip_Reduction(unsigned& mip_level_count, unsigned Reduction, unsigned width, unsigned height, unsigned mip_count) +{ // If texture wants all mip levels, take as many as the file contains (not necessarily all) // Otherwise take as many mip levels as the texture wants, not to exceed the count in file... - if (!mip_level_count) + if (mip_level_count == 0) { - reducedWidth >>= Reduction; - reducedHeight >>= Reduction; - mip_level_count = orig_mip_count-Reduction;//dds_file.Get_Mip_Level_Count(); + mip_level_count = mip_count-Reduction; + + // Sanity check to make sure something gets loaded. if (mip_level_count < 1) - mip_level_count = 1; //sanity check to make sure something gets loaded. + mip_level_count = 1; } else { - if (mip_level_count > orig_mip_count) - { //dds_file.Get_Mip_Level_Count()) { - mip_level_count = orig_mip_count;//dds_file.Get_Mip_Level_Count(); - } + if (mip_level_count > mip_count) + mip_level_count = mip_count; - if (Reduction) - { reducedWidth >>= Reduction; - reducedHeight >>= Reduction; - mip_level_count -= Reduction; //reduced requested number by those removed. - } + // Reduce requested number by those removed. + mip_level_count -= Reduction; } // Once more, verify that the mip level count is correct (in case it was changed here it might not @@ -1569,7 +1554,7 @@ bool TextureLoadTaskClass::Begin_Compressed_Load() unsigned int w = 4; unsigned int h = 4; - while (w < Width && h < Height) + while (w < width && h < height) { w += w; h += h; @@ -1577,16 +1562,63 @@ bool TextureLoadTaskClass::Begin_Compressed_Load() } if (mip_level_count > max_mip_level_count) - { mip_level_count = max_mip_level_count; +} + + +bool TextureLoadTaskClass::Begin_Compressed_Load() +{ + if (Texture == nullptr) + { + return false; + } + + if (DX8Wrapper::Get_Current_Caps() == nullptr) + { + // GeneralsX @bugfix fbraz 04/05/2026 Skip compressed load when DX8 caps are unavailable in headless execution. + return false; } + unsigned orig_width,orig_height,orig_depth,orig_mip_count,orig_reduction; + WW3DFormat orig_format; + if (!Get_Texture_Information + ( + Texture->Get_Full_Path(), + orig_reduction, + orig_width, + orig_height, + orig_depth, + orig_format, + orig_mip_count, + true + ) + ) + { + return false; + } + + // Destination size will be the next power of two square from the larger width and height... + Width = orig_width; + Height = orig_height; + TextureLoader::Validate_Texture_Size(Width, Height, orig_depth); + + Format = Get_Valid_Texture_Format(orig_format, Texture->Is_Compression_Allowed()); + + Reduction = orig_reduction; + Validate_Reduction(Texture, Reduction, orig_mip_count); + + unsigned reduced_width = orig_width; + unsigned reduced_height = orig_height; + Apply_Dim_Reduction(reduced_width, reduced_height, Reduction, orig_mip_count); + + Apply_Mip_Reduction(MipLevelCount, Reduction, Width, Height, orig_mip_count); + D3DTexture = DX8Wrapper::_Create_DX8_Texture ( - reducedWidth, - reducedHeight, + reduced_width, + reduced_height, Format, - (MipCountType)mip_level_count, + (MipCountType)MipLevelCount, #ifdef USE_MANAGED_TEXTURES D3DPOOL_MANAGED #else @@ -1600,8 +1632,6 @@ bool TextureLoadTaskClass::Begin_Compressed_Load() return false; } - MipLevelCount = mip_level_count; - return true; } @@ -1612,15 +1642,15 @@ bool TextureLoadTaskClass::Begin_Uncompressed_Load() return false; } - unsigned width,height,depth,orig_mip_count,reduction; + unsigned orig_width,orig_height,orig_depth,orig_mip_count,orig_reduction; WW3DFormat orig_format; if (!Get_Texture_Information ( Texture->Get_Full_Path(), - reduction, - width, - height, - depth, + orig_reduction, + orig_width, + orig_height, + orig_depth, orig_format, orig_mip_count, false @@ -1642,57 +1672,33 @@ bool TextureLoadTaskClass::Begin_Uncompressed_Load() } // Destination size will be the next power of two square from the larger width and height... - unsigned ow = width; - unsigned oh = height; - TextureLoader::Validate_Texture_Size(width, height,depth); - if (width != ow || height != oh) + unsigned ow = orig_width; + unsigned oh = orig_height; + TextureLoader::Validate_Texture_Size(orig_width, orig_height,orig_depth); + if (orig_width != ow || orig_height != oh) { - WWDEBUG_SAY(("Invalid texture size, scaling required. Texture: %s, size: %d x %d -> %d x %d", Texture->Get_Full_Path().str(), ow, oh, width, height)); + WWDEBUG_SAY(("Invalid texture size, scaling required. Texture: %s, size: %d x %d -> %d x %d", Texture->Get_Full_Path().str(), ow, oh, orig_width, orig_height)); } - Width = width; - Height = height; - Reduction = reduction; - - if (!Texture->Is_Reducible() || Texture->MipLevelCount == MIP_LEVELS_1) - Reduction = 0; //app doesn't want this texture to ever be reduced. - else - //Make sure we don't reduce below the level requested by the app - if (Texture->MipLevelCount != MIP_LEVELS_ALL && (Texture->MipLevelCount - Reduction) < 1) - Reduction = Texture->MipLevelCount - 1; - - //Another sanity check - if (Reduction >= orig_mip_count) - Reduction = 0; //should not be possible to get here, but check just in case. + Width = orig_width; + Height = orig_height; + Reduction = 0; if (Format == WW3D_FORMAT_UNKNOWN) { Format=dest_format; - // Format = Get_Valid_Texture_Format(dest_format, false); validated above } else { Format = Get_Valid_Texture_Format(Format, false); } - int reducedWidth=Width; - int reducedHeight=Height; - int reducedMipCount=Texture->MipLevelCount; - - if (Reduction) - { //we don't care about specific levels so reduce them if needed. - reducedWidth >>= Reduction; - reducedHeight >>= Reduction; - if (reducedMipCount != MIP_LEVELS_ALL) - reducedMipCount -= Reduction; - } - D3DTexture = DX8Wrapper::_Create_DX8_Texture ( - reducedWidth, - reducedHeight, + Width, + Height, Format, - (MipCountType)reducedMipCount, + Texture->MipLevelCount, #ifdef USE_MANAGED_TEXTURES D3DPOOL_MANAGED #else @@ -1709,150 +1715,6 @@ bool TextureLoadTaskClass::Begin_Uncompressed_Load() return true; } -/* -bool TextureLoadTaskClass::Begin_Compressed_Load() -{ - DDSFileClass dds_file(Texture->Get_Full_Path(), Get_Reduction()); - if (!dds_file.Is_Available()) { - return false; - } - - // Destination size will be the next power of two square from the larger width and height... - unsigned int width = dds_file.Get_Width(0); - unsigned int height = dds_file.Get_Height(0); - TextureLoader::Validate_Texture_Size(width, height); - - // If the size doesn't match, try and see if texture reduction would help... (mainly for - // cases where loaded texture is larger than hardware limit) - if (width != dds_file.Get_Width(0) || height != dds_file.Get_Height(0)) { - for (unsigned int i = 1; i < dds_file.Get_Mip_Level_Count(); ++i) { - unsigned int w = dds_file.Get_Width(i); - unsigned int h = dds_file.Get_Height(i); - TextureLoader::Validate_Texture_Size(w,h); - - if (w == dds_file.Get_Width(i) && h == dds_file.Get_Height(i)) { - Reduction += i; - width = w; - height = h; - break; - } - } - } - - Width = width; - Height = height; - Format = Get_Valid_Texture_Format(dds_file.Get_Format(), Texture->Is_Compression_Allowed()); - - unsigned int mip_level_count = Get_Mip_Level_Count(); - - // If texture wants all mip levels, take as many as the file contains (not necessarily all) - // Otherwise take as many mip levels as the texture wants, not to exceed the count in file... - if (!mip_level_count) { - mip_level_count = dds_file.Get_Mip_Level_Count(); - } else if (mip_level_count > dds_file.Get_Mip_Level_Count()) { - mip_level_count = dds_file.Get_Mip_Level_Count(); - } - - // Once more, verify that the mip level count is correct (in case it was changed here it might not - // match the size...well actually it doesn't have to match but it can't be bigger than the size) - unsigned int max_mip_level_count = 1; - unsigned int w = 4; - unsigned int h = 4; - - while (w < Width && h < Height) { - w += w; - h += h; - max_mip_level_count++; - } - - if (mip_level_count > max_mip_level_count) { - mip_level_count = max_mip_level_count; - } - - D3DTexture = DX8Wrapper::_Create_DX8_Texture( - Width, - Height, - Format, - (TextureBaseClass::MipCountType)mip_level_count, -#ifdef USE_MANAGED_TEXTURES - D3DPOOL_MANAGED); -#else - D3DPOOL_SYSTEMMEM); -#endif - MipLevelCount = mip_level_count; - return true; -} - - -bool TextureLoadTaskClass::Begin_Uncompressed_Load() -{ - Targa targa; - if (TARGA_ERROR_HANDLER(targa.Open(Texture->Get_Full_Path(), TGA_READMODE), Texture->Get_Full_Path())) { - return false; - } - - unsigned int bpp; - WW3DFormat src_format, dest_format; - Get_WW3D_Format(dest_format,src_format,bpp,targa); - - if ( src_format != WW3D_FORMAT_A8R8G8B8 - && src_format != WW3D_FORMAT_R8G8B8 - && src_format != WW3D_FORMAT_X8R8G8B8) { - WWDEBUG_SAY(("Invalid TGA format used in %s - only 24 and 32 bit formats should be used!", Texture->Get_Full_Path())); - } - - // Destination size will be the next power of two square from the larger width and height... - unsigned width=targa.Header.Width, height=targa.Header.Height; - int ReductionFactor=Get_Reduction(); - int MipLevels=0; - - //Figure out how many mip levels this texture will occupy - for (int i=width, j=height; i > 0 && j > 0; i>>=1, j>>=1) - MipLevels++; - - //Adjust the reduction factor to keep textures above some minimum dimensions - if (MipLevels <= WW3D::Get_Texture_Min_Mip_Levels()) - ReductionFactor=0; - else - { int mipToDrop=MipLevels-WW3D::Get_Texture_Min_Mip_Levels(); - if (ReductionFactor >= mipToDrop) - ReductionFactor=mipToDrop; - } - - width=targa.Header.Width>>ReductionFactor; - height=targa.Header.Height>>ReductionFactor; - unsigned ow = width; - unsigned oh = height; - TextureLoader::Validate_Texture_Size(width, height); - if (width != ow || height != oh) { - WWDEBUG_SAY(("Invalid texture size, scaling required. Texture: %s, size: %d x %d -> %d x %d", Texture->Get_Full_Path(), ow, oh, width, height)); - } - - Width = width; - Height = height; - - // changed because format was being read from previous loading task?! KJM - Format=dest_format; - //if (Format == WW3D_FORMAT_UNKNOWN) { - // Format = Get_Valid_Texture_Format(dest_format, false); - //} else { - // Format = Get_Valid_Texture_Format(Format, false); - //} - - D3DTexture = DX8Wrapper::_Create_DX8_Texture - ( - Width, - Height, - Format, - Texture->MipLevelCount, -#ifdef USE_MANAGED_TEXTURES - D3DPOOL_MANAGED); -#else - D3DPOOL_SYSTEMMEM); -#endif - return true; -} -*/ void TextureLoadTaskClass::Lock_Surfaces() { @@ -1904,7 +1766,7 @@ bool TextureLoadTaskClass::Load_Compressed_Mipmap() { DDSFileClass dds_file(Texture->Get_Full_Path(), Get_Reduction()); - // if we can't load from file, indicate rror. + // if we can't load from file, indicate error. if (!dds_file.Is_Available() || !dds_file.Load()) { return false; @@ -1914,12 +1776,8 @@ bool TextureLoadTaskClass::Load_Compressed_Mipmap() unsigned int width = Get_Width(); unsigned int height = Get_Height(); - if (Reduction) - { for (unsigned int level = 0; level < Reduction; ++level) { - width >>= 1; - height >>= 1; - } - } + width >>= Reduction; + height >>= Reduction; for (unsigned int level = 0; level < Get_Mip_Level_Count(); ++level) { @@ -2296,15 +2154,15 @@ void CubeTextureLoadTaskClass::Unlock_Surfaces() bool CubeTextureLoadTaskClass::Begin_Compressed_Load() { - unsigned orig_w,orig_h,orig_d,orig_mip_count,reduction; + unsigned orig_width,orig_height,orig_depth,orig_mip_count,orig_reduction; WW3DFormat orig_format; if (!Get_Texture_Information ( Texture->Get_Full_Path(), - reduction, - orig_w, - orig_h, - orig_d, + orig_reduction, + orig_width, + orig_height, + orig_depth, orig_format, orig_mip_count, true @@ -2315,76 +2173,27 @@ bool CubeTextureLoadTaskClass::Begin_Compressed_Load() } // Destination size will be the next power of two square from the larger width and height... - unsigned int width = orig_w; - unsigned int height = orig_h; - TextureLoader::Validate_Texture_Size(width, height,orig_d); - - // If the size doesn't match, try and see if texture reduction would help... (mainly for - // cases where loaded texture is larger than hardware limit) - if (width != orig_w || height != orig_h) - { - for (unsigned int i = 1; i < orig_mip_count; ++i) - { - unsigned w=orig_w>>i; - if (w<4) w=4; - unsigned h=orig_h>>i; - if (h<4) h=4; - unsigned tmp_w=w; - unsigned tmp_h=h; - - TextureLoader::Validate_Texture_Size(w,h,orig_d); - - if (w == tmp_w && h == tmp_h) - { - Reduction += i; - width = w; - height = h; - break; - } - } - } - - Width = width; - Height = height; - Format = Get_Valid_Texture_Format(orig_format, Texture->Is_Compression_Allowed()); + Width = orig_width; + Height = orig_height; + TextureLoader::Validate_Texture_Size(Width, Height, orig_depth); - unsigned int mip_level_count = Get_Mip_Level_Count(); + Format = Get_Valid_Texture_Format(orig_format, Texture->Is_Compression_Allowed()); - // If texture wants all mip levels, take as many as the file contains (not necessarily all) - // Otherwise take as many mip levels as the texture wants, not to exceed the count in file... - if (!mip_level_count) - { - mip_level_count = orig_mip_count;//dds_file.Get_Mip_Level_Count(); - } - else if (mip_level_count > orig_mip_count) - {//dds_file.Get_Mip_Level_Count()) { - mip_level_count = orig_mip_count;//dds_file.Get_Mip_Level_Count(); - } - - // Once more, verify that the mip level count is correct (in case it was changed here it might not - // match the size...well actually it doesn't have to match but it can't be bigger than the size) - unsigned int max_mip_level_count = 1; - unsigned int w = 4; - unsigned int h = 4; + Reduction = orig_reduction; + Validate_Reduction(Texture, Reduction, orig_mip_count); - while (w < Width && h < Height) - { - w += w; - h += h; - max_mip_level_count++; - } + unsigned reduced_width = orig_width; + unsigned reduced_height = orig_height; + Apply_Dim_Reduction(reduced_width, reduced_height, Reduction, orig_mip_count); - if (mip_level_count > max_mip_level_count) - { - mip_level_count = max_mip_level_count; - } + Apply_Mip_Reduction(MipLevelCount, Reduction, Width, Height, orig_mip_count); D3DTexture = DX8Wrapper::_Create_DX8_Cube_Texture ( - Width, - Height, + reduced_width, + reduced_height, Format, - (MipCountType)mip_level_count, + (MipCountType)MipLevelCount, #ifdef USE_MANAGED_TEXTURES D3DPOOL_MANAGED #else @@ -2392,21 +2201,20 @@ bool CubeTextureLoadTaskClass::Begin_Compressed_Load() #endif ); - MipLevelCount = mip_level_count; return true; } bool CubeTextureLoadTaskClass::Begin_Uncompressed_Load() { - unsigned width,height,depth,orig_mip_count,reduction; + unsigned orig_width,orig_height,orig_depth,orig_mip_count,orig_reduction; WW3DFormat orig_format; if (!Get_Texture_Information ( Texture->Get_Full_Path(), - reduction, - width, - height, - depth, + orig_reduction, + orig_width, + orig_height, + orig_depth, orig_format, orig_mip_count, false @@ -2428,16 +2236,17 @@ bool CubeTextureLoadTaskClass::Begin_Uncompressed_Load() } // Destination size will be the next power of two square from the larger width and height... - unsigned ow = width; - unsigned oh = height; - TextureLoader::Validate_Texture_Size(width, height,depth); - if (width != ow || height != oh) + unsigned ow = orig_width; + unsigned oh = orig_height; + TextureLoader::Validate_Texture_Size(orig_width, orig_height,orig_depth); + if (orig_width != ow || orig_height != oh) { - WWDEBUG_SAY(("Invalid texture size, scaling required. Texture: %s, size: %d x %d -> %d x %d", Texture->Get_Full_Path().str(), ow, oh, width, height)); + WWDEBUG_SAY(("Invalid texture size, scaling required. Texture: %s, size: %d x %d -> %d x %d", Texture->Get_Full_Path().str(), ow, oh, orig_width, orig_height)); } - Width = width; - Height = height; + Width = orig_width; + Height = orig_height; + Reduction = 0; if (Format == WW3D_FORMAT_UNKNOWN) { @@ -2468,7 +2277,7 @@ bool CubeTextureLoadTaskClass::Load_Compressed_Mipmap() { DDSFileClass dds_file(Texture->Get_Full_Path(), Get_Reduction()); - // if we can't load from file, indicate rror. + // if we can't load from file, indicate error. if (!dds_file.Is_Available() || !dds_file.Load()) { return false; @@ -2480,6 +2289,9 @@ bool CubeTextureLoadTaskClass::Load_Compressed_Mipmap() unsigned int width = Get_Width(); unsigned int height = Get_Height(); + width >>= Reduction; + height >>= Reduction; + for (unsigned int level=0; levelGet_Full_Path(), - reduction, - orig_w, - orig_h, - orig_d, + orig_reduction, + orig_width, + orig_height, + orig_depth, orig_format, orig_mip_count, true @@ -2675,82 +2487,30 @@ bool VolumeTextureLoadTaskClass::Begin_Compressed_Load() } // Destination size will be the next power of two square from the larger width and height... - unsigned int width = orig_w; - unsigned int height = orig_h; - unsigned int depth = orig_d; - TextureLoader::Validate_Texture_Size(width, height, depth); + Width = orig_width; + Height = orig_height; + Depth = orig_depth; + TextureLoader::Validate_Texture_Size(Width, Height, Depth); - // If the size doesn't match, try and see if texture reduction would help... (mainly for - // cases where loaded texture is larger than hardware limit) - if (width != orig_w || height != orig_h || depth != orig_d) - { - for (unsigned int i = 1; i < orig_mip_count; ++i) - { - unsigned w=orig_w>>i; - if (w<4) w=4; - unsigned h=orig_h>>i; - if (h<4) h=4; - unsigned d=orig_d>>i; - if (d<1) d=1; - unsigned tmp_w=w; - unsigned tmp_h=h; - unsigned tmp_d=d; - - TextureLoader::Validate_Texture_Size(w,h,d); - - if (w == tmp_w && h == tmp_h && d== tmp_d) - { - Reduction += i; - width = w; - height = h; - depth = d; - break; - } - } - } + Format = Get_Valid_Texture_Format(orig_format, Texture->Is_Compression_Allowed()); - Width = width; - Height = height; - Depth = depth; - Format = Get_Valid_Texture_Format(orig_format, Texture->Is_Compression_Allowed()); + Reduction = orig_reduction; + Validate_Reduction(Texture, Reduction, orig_mip_count); - unsigned int mip_level_count = Get_Mip_Level_Count(); + unsigned reduced_width = orig_width; + unsigned reduced_height = orig_height; + unsigned reduced_depth = orig_depth; + Apply_Dim_Reduction_With_Depth(reduced_width, reduced_height, reduced_depth, Reduction, orig_mip_count); - // If texture wants all mip levels, take as many as the file contains (not necessarily all) - // Otherwise take as many mip levels as the texture wants, not to exceed the count in file... - if (!mip_level_count) - { - mip_level_count = orig_mip_count;//dds_file.Get_Mip_Level_Count(); - } - else if (mip_level_count > orig_mip_count) - {//dds_file.Get_Mip_Level_Count()) { - mip_level_count = orig_mip_count;//dds_file.Get_Mip_Level_Count(); - } - - // Once more, verify that the mip level count is correct (in case it was changed here it might not - // match the size...well actually it doesn't have to match but it can't be bigger than the size) - unsigned int max_mip_level_count = 1; - unsigned int w = 4; - unsigned int h = 4; - - while (w < Width && h < Height) - { - w += w; - h += h; - max_mip_level_count++; - } - if (mip_level_count > max_mip_level_count) - { - mip_level_count = max_mip_level_count; - } + Apply_Mip_Reduction(MipLevelCount, Reduction, Width, Height, orig_mip_count); D3DTexture = DX8Wrapper::_Create_DX8_Volume_Texture ( - Width, - Height, - Depth, + reduced_width, + reduced_height, + reduced_depth, Format, - (MipCountType)mip_level_count, + (MipCountType)MipLevelCount, #ifdef USE_MANAGED_TEXTURES D3DPOOL_MANAGED #else @@ -2758,21 +2518,20 @@ bool VolumeTextureLoadTaskClass::Begin_Compressed_Load() #endif ); - MipLevelCount = mip_level_count; return true; } bool VolumeTextureLoadTaskClass::Begin_Uncompressed_Load() { - unsigned width,height,depth,orig_mip_count,reduction; + unsigned orig_width,orig_height,orig_depth,orig_mip_count,orig_reduction; WW3DFormat orig_format; if (!Get_Texture_Information ( Texture->Get_Full_Path(), - reduction, - width, - height, - depth, + orig_reduction, + orig_width, + orig_height, + orig_depth, orig_format, orig_mip_count, false @@ -2794,18 +2553,19 @@ bool VolumeTextureLoadTaskClass::Begin_Uncompressed_Load() } // Destination size will be the next power of two square from the larger width and height... - unsigned ow = width; - unsigned oh = height; - unsigned od = depth; - TextureLoader::Validate_Texture_Size(width, height, depth); - if (width != ow || height != oh || depth != od) + unsigned ow = orig_width; + unsigned oh = orig_height; + unsigned od = orig_depth; + TextureLoader::Validate_Texture_Size(orig_width, orig_height, orig_depth); + if (orig_width != ow || orig_height != oh || orig_depth != od) { - WWDEBUG_SAY(("Invalid texture size, scaling required. Texture: %s, size: %d x %d -> %d x %d", Texture->Get_Full_Path().str(), ow, oh, width, height)); + WWDEBUG_SAY(("Invalid texture size, scaling required. Texture: %s, size: %d x %d -> %d x %d", Texture->Get_Full_Path().str(), ow, oh, orig_width, orig_height)); } - Width = width; - Height = height; - Depth = depth; + Width = orig_width; + Height = orig_height; + Depth = orig_depth; + Reduction = 0; if (Format == WW3D_FORMAT_UNKNOWN) { @@ -2837,7 +2597,7 @@ bool VolumeTextureLoadTaskClass::Load_Compressed_Mipmap() { DDSFileClass dds_file(Texture->Get_Full_Path(), Get_Reduction()); - // if we can't load from file, indicate rror. + // if we can't load from file, indicate error. if (!dds_file.Is_Available() || !dds_file.Load()) { return false; @@ -2848,12 +2608,14 @@ bool VolumeTextureLoadTaskClass::Load_Compressed_Mipmap() unsigned int width=Get_Width(); unsigned int height=Get_Height(); - WWASSERT(width && height && depth); + depth >>= Reduction; + width >>= Reduction; + height >>= Reduction; for (unsigned int level=0; level m_cachedCRCs; ///< CRCs we've seen this frame + typedef std::map CachedCRCMap; + CachedCRCMap m_cachedCRCs; ///< CRCs we've seen this frame Bool m_shouldValidateCRCs; ///< Should we validate CRCs this frame? //----------------------------------------------------------------------------------------------- //Bool m_loadingScene; diff --git a/Generals/Code/GameEngine/Include/GameLogic/PolygonTrigger.h b/Generals/Code/GameEngine/Include/GameLogic/PolygonTrigger.h index 5040a409f1b..d3e133834fc 100644 --- a/Generals/Code/GameEngine/Include/GameLogic/PolygonTrigger.h +++ b/Generals/Code/GameEngine/Include/GameLogic/PolygonTrigger.h @@ -125,7 +125,7 @@ class PolygonTrigger : public MemoryPoolObject, Int getID() const {return m_triggerID;} PolygonTrigger *getNext() {return m_nextPolygonTrigger;} const PolygonTrigger *getNext() const {return m_nextPolygonTrigger;} - AsciiString getTriggerName() const {return m_triggerName;} ///< Gets the trigger name. + const AsciiString& getTriggerName() const {return m_triggerName;} ///< Gets the trigger name. Bool pointInTrigger(ICoord3D &point) const; Bool doExportWithScripts() const {return m_exportWithScripts;} void setDoExportWithScripts(Bool val) {m_exportWithScripts = val;} diff --git a/Generals/Code/GameEngine/Include/GameLogic/TerrainLogic.h b/Generals/Code/GameEngine/Include/GameLogic/TerrainLogic.h index 6c16228c569..ad1db103499 100644 --- a/Generals/Code/GameEngine/Include/GameLogic/TerrainLogic.h +++ b/Generals/Code/GameEngine/Include/GameLogic/TerrainLogic.h @@ -112,11 +112,11 @@ class Waypoint : public MemoryPoolObject /// Get the waypoint's position const Coord3D *getLocation() const { return &m_location; } /// Get the waypoint's first path label - AsciiString getPathLabel1() const { return m_pathLabel1; } + const AsciiString& getPathLabel1() const { return m_pathLabel1; } /// Get the waypoint's second path label - AsciiString getPathLabel2() const { return m_pathLabel2; } + const AsciiString& getPathLabel2() const { return m_pathLabel2; } /// Get the waypoint's third path label - AsciiString getPathLabel3() const { return m_pathLabel3; } + const AsciiString& getPathLabel3() const { return m_pathLabel3; } /// Get bi-directionality. Bool getBiDirectional() const { return m_biDirectional; } diff --git a/Generals/Code/GameEngine/Source/Common/CommandLine.cpp b/Generals/Code/GameEngine/Source/Common/CommandLine.cpp index 8d9c203eabf..0a297cf121d 100644 --- a/Generals/Code/GameEngine/Source/Common/CommandLine.cpp +++ b/Generals/Code/GameEngine/Source/Common/CommandLine.cpp @@ -319,7 +319,7 @@ Int parseLogObjectCRCs(char *args[], int argc) //============================================================================= Int parseNetCRCInterval(char *args[], int argc) { -#ifdef DEBUG_CRC +#if defined(DEBUG_CRC) && !RETAIL_COMPATIBLE_NETWORKING if (argc > 1) { NET_CRC_INTERVAL = atoi(args[1]); diff --git a/Generals/Code/GameEngine/Source/GameClient/MessageStream/SelectionXlat.cpp b/Generals/Code/GameEngine/Source/GameClient/MessageStream/SelectionXlat.cpp index 964368235d4..363f11e3356 100644 --- a/Generals/Code/GameEngine/Source/GameClient/MessageStream/SelectionXlat.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/MessageStream/SelectionXlat.cpp @@ -62,7 +62,6 @@ //----------------------------------------------------------------------------- #if defined(RTS_DEBUG) static Bool TheHurtSelectionMode = false; -static Bool TheHandOfGodSelectionMode = false; static Bool TheDebugSelectionMode = false; #endif @@ -270,6 +269,10 @@ SelectionTranslator::SelectionTranslator() m_selectCountMap.clear(); TheSelectionTranslator = this; + +#if defined(RTS_DEBUG) || defined(_ALLOW_DEBUG_CHEATS_IN_RELEASE) + m_HandOfGodSelectionMode = FALSE; +#endif } //----------------------------------------------------------------------------- @@ -637,11 +640,47 @@ GameMessageDisposition SelectionTranslator::translateGameMessage(const GameMessa if (si.newCountMine > 0) { si.selectMine = TRUE; - if (si.newCountMine == 1 && si.newCountMineBuildings == 1) + + // EXACTLY ONE CLICKED OR DRAGGED BUILDING + if ( si.newCountMineBuildings == 1 && si.newCountMine == 1 ) { addToGroup = FALSE; si.selectMineBuildings = TRUE; + } + else if ( si.newCountMineBuildings > 0 )////////////// SO SORRY, I KNOW THIS IS MICKEY MOUSE /////////////////// + { // What we are after here is to allow the drag select to get the building, + // if the other things in the list are going to be ignored anyway + // so we find out whether the other things are not selectible + // this came up with the new AmericaBuildingFireBase, which shows its contained + // but does not let you select them. The selection is propagated to the container + // in new code in SelectionInfo.cpp, in the static addDrawableToList(); + // -Mark Lorenzen, 6/12/03 + Bool onlyTheOneBuildingIsSelectableAnyway = TRUE; + DrawableID buildingID = INVALID_DRAWABLE_ID; + for (DrawableListIt it = drawablesThatWillSelect.begin(); it != drawablesThatWillSelect.end(); ++it) + { + const Drawable *d = *it; + if ( d->isKindOf( KINDOF_STRUCTURE ) ) + {// make sure there is really only the one building in the list, as it may be multiply listed + + if ( buildingID == INVALID_DRAWABLE_ID ) // this is the first building + buildingID = d->getID(); + else if ( buildingID != d->getID() )//oops, more than one building! + onlyTheOneBuildingIsSelectableAnyway = FALSE; + } + else if ( d->isSelectable() ) + onlyTheOneBuildingIsSelectableAnyway = FALSE; + + if ( ! onlyTheOneBuildingIsSelectableAnyway ) + break; + } + if ( onlyTheOneBuildingIsSelectableAnyway ) + { + addToGroup = FALSE; + si.selectMineBuildings = TRUE; + } } + } else if (si.newCountEnemies > 0 && si.newCountCivilians > 0 && si.newCountFriends > 0) { @@ -774,10 +813,15 @@ GameMessageDisposition SelectionTranslator::translateGameMessage(const GameMessa } } + if( newDrawablesSelected > 1 ) + { + localPlayer->getAcademyStats()->recordDragSelection(); + } + if (newDrawablesSelected == 1 && draw) { -#if defined(RTS_DEBUG) - if (TheHandOfGodSelectionMode && draw) +#if defined(RTS_DEBUG) || defined(_ALLOW_DEBUG_CHEATS_IN_RELEASE) + if (m_HandOfGodSelectionMode && draw) { Object* obj = draw->getObject(); if (obj) @@ -789,7 +833,10 @@ GameMessageDisposition SelectionTranslator::translateGameMessage(const GameMessa disp = DESTROY_MESSAGE; break; } - else if (TheHurtSelectionMode && draw) +#endif + +#if defined(RTS_DEBUG) + if (TheHurtSelectionMode && draw) { Object* obj = draw->getObject(); if (obj) @@ -817,8 +864,8 @@ GameMessageDisposition SelectionTranslator::translateGameMessage(const GameMessa break; } } -#endif -#endif +#endif // DEBUG_OBJECT_ID_EXISTS +#endif // RTS_DEBUG } } @@ -877,6 +924,7 @@ GameMessageDisposition SelectionTranslator::translateGameMessage(const GameMessa if( !TheInGameUI->getPreventLeftClickDeselectionInAlternateMouseModeForOneClick() ) { deselectAll(); + m_lastGroupSelGroup = -1; } else { @@ -927,10 +975,10 @@ GameMessageDisposition SelectionTranslator::translateGameMessage(const GameMessa //With a GUI command cancel, we want no other behavior. disp = DESTROY_MESSAGE; TheInGameUI->setScrolling( FALSE ); - } + } else { - //In alternate mouse mode, right click still cancels building placement. + //In alternate mouse mode, right click still cancels building placement. // TheSuperHackers @tweak Stubbjax 08/08/2025 Canceling building placement no longer deselects the builder. if (TheInGameUI->getPendingPlaceSourceObjectID() != INVALID_ID) { @@ -940,12 +988,11 @@ GameMessageDisposition SelectionTranslator::translateGameMessage(const GameMessa TheInGameUI->setScrolling(FALSE); } else if (!TheGlobalData->m_useAlternateMouse) - { + { //No GUI command mode, so deselect everyone if we're in regular mouse mode. - deselectAll(); - m_lastGroupSelGroup = -1; - } - } + deselectAll(); + } + } } break; @@ -1202,9 +1249,26 @@ GameMessageDisposition SelectionTranslator::translateGameMessage(const GameMessa //----------------------------------------------------------------------------------------- case GameMessage::MSG_META_DEMO_TOGGLE_HAND_OF_GOD_MODE: { - TheHandOfGodSelectionMode = !TheHandOfGodSelectionMode; - TheInGameUI->message( L"Hand-Of-God Mode is %s", TheHandOfGodSelectionMode ? L"ON" : L"OFF" ); - disp = DESTROY_MESSAGE; + if ( !TheGameLogic->isInMultiplayerGame() ) + { + m_HandOfGodSelectionMode = !m_HandOfGodSelectionMode; + TheInGameUI->message( L"Meta Hand-Of-God Mode is %s", m_HandOfGodSelectionMode ? L"ON" : L"OFF" ); + disp = DESTROY_MESSAGE; + } + break; + } +#endif + +#if defined(_ALLOW_DEBUG_CHEATS_IN_RELEASE) + //----------------------------------------------------------------------------------------- + case GameMessage::MSG_CHEAT_TOGGLE_HAND_OF_GOD_MODE://NOTICE THE DIFFERENT NAME!!!!!!!!!!!!!!!!!!!!!!!!!!ML + { + if ( !TheGameLogic->isInMultiplayerGame() ) + { + m_HandOfGodSelectionMode = !m_HandOfGodSelectionMode; + TheInGameUI->message( L"Hand-Of-God Mode is %s", m_HandOfGodSelectionMode ? L"ON" : L"OFF" ); + disp = DESTROY_MESSAGE; + } break; } #endif @@ -1213,9 +1277,12 @@ GameMessageDisposition SelectionTranslator::translateGameMessage(const GameMessa //----------------------------------------------------------------------------------------- case GameMessage::MSG_META_DEMO_TOGGLE_HURT_ME_MODE: { - TheHurtSelectionMode = !TheHurtSelectionMode; - TheInGameUI->message( L"Hurt-Me Mode is %s", TheHurtSelectionMode ? L"ON" : L"OFF" ); - disp = DESTROY_MESSAGE; + if ( !TheGameLogic->isInMultiplayerGame() ) + { + TheHurtSelectionMode = !TheHurtSelectionMode; + TheInGameUI->message( L"Hurt-Me Mode is %s", TheHurtSelectionMode ? L"ON" : L"OFF" ); + disp = DESTROY_MESSAGE; + } break; } #endif diff --git a/Generals/Code/GameEngine/Source/GameLogic/AI/AIGuard.cpp b/Generals/Code/GameEngine/Source/GameLogic/AI/AIGuard.cpp index d8caf323f82..e00b82b215d 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/AI/AIGuard.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/AI/AIGuard.cpp @@ -175,7 +175,13 @@ AIGuardMachine::AIGuardMachine( Object *owner ) : // order matters: first state is the default state. // srj sez: I made "return" the start state, so that if ordered to guard a position // that isn't the unit's current position, it moves to that position first. +#if RETAIL_COMPATIBLE_CRC defineState( AI_GUARD_RETURN, newInstance(AIGuardReturnState)( this ), AI_GUARD_IDLE, AI_GUARD_INNER, attackAggressors ); +#else + // TheSuperHackers @bugfix 09/04/2026 The attack aggressors conditions for AI_GUARD_RETURN + // were removed to fix the conflicting movement and fire behavior in guard mode when the unit is under attack. + defineState( AI_GUARD_RETURN, newInstance(AIGuardReturnState)( this ), AI_GUARD_IDLE, AI_GUARD_INNER ); +#endif defineState( AI_GUARD_IDLE, newInstance(AIGuardIdleState)( this ), AI_GUARD_INNER, AI_GUARD_RETURN, attackAggressors ); defineState( AI_GUARD_INNER, newInstance(AIGuardInnerState)( this ), AI_GUARD_OUTER, AI_GUARD_OUTER ); defineState( AI_GUARD_OUTER, newInstance(AIGuardOuterState)( this ), AI_GUARD_GET_CRATE, AI_GUARD_GET_CRATE ); diff --git a/Generals/Code/GameEngine/Source/GameLogic/Map/TerrainLogic.cpp b/Generals/Code/GameEngine/Source/GameLogic/Map/TerrainLogic.cpp index aa5e8887434..1d3e62df570 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Map/TerrainLogic.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Map/TerrainLogic.cpp @@ -1633,7 +1633,7 @@ Bool TerrainLogic::isPurposeOfPath( Waypoint *pWay, AsciiString label ) PolygonTrigger *TerrainLogic::getTriggerAreaByName( AsciiString name ) { for (PolygonTrigger* pTrig = PolygonTrigger::getFirstPolygonTrigger(); pTrig; pTrig = pTrig->getNext()) { - AsciiString trigName = pTrig->getTriggerName(); + const AsciiString& trigName = pTrig->getTriggerName(); if (name == trigName) return pTrig; } diff --git a/Generals/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp b/Generals/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp index 2b83a5b8dc2..0dcad375a34 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp @@ -2369,15 +2369,26 @@ void GameLogic::processCommandList( CommandList *list ) } else { - //DEBUG_LOG(("Comparing %d CRCs on frame %d", m_cachedCRCs.size(), m_frame)); - std::map::const_iterator crcIt = m_cachedCRCs.begin(); - Int validatorCRC = crcIt->second; - //DEBUG_LOG(("Validator CRC from player %d is %8.8X", crcIt->first, validatorCRC)); - while (++crcIt != m_cachedCRCs.end()) + Bool hasReferenceCRC = FALSE; + UnsignedInt referenceCRC = 0; + + for (CachedCRCMap::const_iterator it = m_cachedCRCs.begin(); it != m_cachedCRCs.end(); ++it) { - Int validatedCRC = crcIt->second; - //DEBUG_LOG(("CRC to validate is from player %d: %8.8X", crcIt->first, validatedCRC)); - if (validatorCRC != validatedCRC) + // TheSuperHackers @bugfix Caball009 14/06/2026 Check if player is still connected, + // to avoid spurious mismatches at low CRC intervals, e.g. every frame. + if (!TheNetwork->isPlayerConnected(it->first)) + continue; + + const UnsignedInt crc = it->second; + + if (!hasReferenceCRC) + { + hasReferenceCRC = TRUE; + referenceCRC = crc; + continue; + } + + if (referenceCRC != crc) { DEBUG_CRASH(("CRC mismatch!")); sawCRCMismatch = TRUE; @@ -2390,7 +2401,7 @@ void GameLogic::processCommandList( CommandList *list ) { #ifdef DEBUG_LOGGING DEBUG_LOG(("CRC Mismatch - saw %d CRCs from %d players", m_cachedCRCs.size(), numPlayers)); - for (std::map::const_iterator crcIt = m_cachedCRCs.begin(); crcIt != m_cachedCRCs.end(); ++crcIt) + for (CachedCRCMap::const_iterator crcIt = m_cachedCRCs.begin(); crcIt != m_cachedCRCs.end(); ++crcIt) { Player *player = ThePlayerList->getNthPlayer(crcIt->first); DEBUG_LOG(("CRC from player %d (%ls) = %X", crcIt->first, diff --git a/Generals/Code/Tools/WorldBuilder/src/WaterOptions.cpp b/Generals/Code/Tools/WorldBuilder/src/WaterOptions.cpp index 7c1c0b4db55..9e3d04144d0 100644 --- a/Generals/Code/Tools/WorldBuilder/src/WaterOptions.cpp +++ b/Generals/Code/Tools/WorldBuilder/src/WaterOptions.cpp @@ -162,7 +162,7 @@ void WaterOptions::OnChangeWaterEdit() PolygonTrigger *pTrig; for (pTrig=PolygonTrigger::getFirstPolygonTrigger(); !didMatch && pTrig; pTrig = pTrig->getNext()) { if (pTrig==theTrigger) continue; // don't check against yourself. - AsciiString trigName = pTrig->getTriggerName(); + const AsciiString& trigName = pTrig->getTriggerName(); if (name == trigName) { if (pTrig->isValid()) { didMatch = true; diff --git a/Generals/Code/Tools/WorldBuilder/src/WaypointOptions.cpp b/Generals/Code/Tools/WorldBuilder/src/WaypointOptions.cpp index e6608622f50..4b16a953ab3 100644 --- a/Generals/Code/Tools/WorldBuilder/src/WaypointOptions.cpp +++ b/Generals/Code/Tools/WorldBuilder/src/WaypointOptions.cpp @@ -486,7 +486,7 @@ void WaypointOptions::OnChangeWaypointnameEdit() PolygonTrigger *pTrig; for (pTrig=PolygonTrigger::getFirstPolygonTrigger(); !didMatch && pTrig; pTrig = pTrig->getNext()) { if (pTrig==theTrigger) continue; // don't check against yourself. - AsciiString trigName = pTrig->getTriggerName(); + const AsciiString& trigName = pTrig->getTriggerName(); if (name == trigName) { if (pTrig->isValid()) { didMatch = true; diff --git a/GeneralsMD/Code/GameEngine/Include/GameClient/SelectionXlat.h b/GeneralsMD/Code/GameEngine/Include/GameClient/SelectionXlat.h index bf9900a9f42..cdb6f56698b 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameClient/SelectionXlat.h +++ b/GeneralsMD/Code/GameEngine/Include/GameClient/SelectionXlat.h @@ -58,8 +58,6 @@ class SelectionTranslator : public GameMessageTranslator Bool selectFriends( Drawable *draw, GameMessage *createTeamMsg, Bool dragSelecting ); Bool killThemKillThemAll( Drawable *draw, GameMessage *killThemAllMsg ); - - public: SelectionTranslator(); virtual ~SelectionTranslator() override; diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/GameLogic.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/GameLogic.h index 5a59dbd2abe..60f5fb22e7c 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/GameLogic.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/GameLogic.h @@ -390,7 +390,8 @@ class GameLogic : public SubsystemInterface, public Snapshot // CRC cache system ----------------------------------------------------------------------------- UnsignedInt m_CRC; ///< Cache of previous CRC value - std::map m_cachedCRCs; ///< CRCs we've seen this frame + typedef std::map CachedCRCMap; + CachedCRCMap m_cachedCRCs; ///< CRCs we've seen this frame Bool m_shouldValidateCRCs; ///< Should we validate CRCs this frame? //----------------------------------------------------------------------------------------------- //Bool m_loadingScene; diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/PolygonTrigger.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/PolygonTrigger.h index 499ac57e6c2..d618de16a06 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/PolygonTrigger.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/PolygonTrigger.h @@ -137,7 +137,7 @@ class PolygonTrigger : public MemoryPoolObject, Int getID() const {return m_triggerID;} PolygonTrigger *getNext() {return m_nextPolygonTrigger;} const PolygonTrigger *getNext() const {return m_nextPolygonTrigger;} - AsciiString getTriggerName() const {return m_triggerName;} ///< Gets the trigger name. + const AsciiString& getTriggerName() const {return m_triggerName;} ///< Gets the trigger name. Bool pointInTrigger(ICoord3D &point) const; Bool doExportWithScripts() const {return m_exportWithScripts;} void setDoExportWithScripts(Bool val) {m_exportWithScripts = val;} diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/TerrainLogic.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/TerrainLogic.h index 8ff1964fb6a..90dda7f2411 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/TerrainLogic.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/TerrainLogic.h @@ -112,11 +112,11 @@ class Waypoint : public MemoryPoolObject /// Get the waypoint's position const Coord3D *getLocation() const { return &m_location; } /// Get the waypoint's first path label - AsciiString getPathLabel1() const { return m_pathLabel1; } + const AsciiString& getPathLabel1() const { return m_pathLabel1; } /// Get the waypoint's second path label - AsciiString getPathLabel2() const { return m_pathLabel2; } + const AsciiString& getPathLabel2() const { return m_pathLabel2; } /// Get the waypoint's third path label - AsciiString getPathLabel3() const { return m_pathLabel3; } + const AsciiString& getPathLabel3() const { return m_pathLabel3; } /// Get bi-directionality. Bool getBiDirectional() const { return m_biDirectional; } diff --git a/GeneralsMD/Code/GameEngine/Source/Common/CommandLine.cpp b/GeneralsMD/Code/GameEngine/Source/Common/CommandLine.cpp index 02453d045ab..cd8e7e10eb9 100644 --- a/GeneralsMD/Code/GameEngine/Source/Common/CommandLine.cpp +++ b/GeneralsMD/Code/GameEngine/Source/Common/CommandLine.cpp @@ -321,7 +321,7 @@ Int parseLogObjectCRCs(char *args[], int argc) //============================================================================= Int parseNetCRCInterval(char *args[], int argc) { -#ifdef DEBUG_CRC +#if defined(DEBUG_CRC) && !RETAIL_COMPATIBLE_NETWORKING if (argc > 1) { NET_CRC_INTERVAL = atoi(args[1]); diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/SelectionXlat.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/SelectionXlat.cpp index 203874859b1..caca08f832a 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/SelectionXlat.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/SelectionXlat.cpp @@ -60,12 +60,6 @@ //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -// Lorenzen changed this to a member of SelectionTranslator, providing external access -// name ly in rebuildholeexposedie, where we decide whether to create GLA Holes when hand-of-Godding -//#if defined(RTS_DEBUG) || defined(_ALLOW_DEBUG_CHEATS_IN_RELEASE) -//static Bool TheHandOfGodSelectionMode = false; -//#endif - #if defined(RTS_DEBUG) static Bool TheHurtSelectionMode = false; static Bool TheDebugSelectionMode = false; @@ -826,11 +820,7 @@ GameMessageDisposition SelectionTranslator::translateGameMessage(const GameMessa if (newDrawablesSelected == 1 && draw) { - - -#if defined(RTS_DEBUG) - - +#if defined(RTS_DEBUG) || defined(_ALLOW_DEBUG_CHEATS_IN_RELEASE) if (m_HandOfGodSelectionMode && draw) { Object* obj = draw->getObject(); @@ -843,8 +833,9 @@ GameMessageDisposition SelectionTranslator::translateGameMessage(const GameMessa disp = DESTROY_MESSAGE; break; } - else +#endif +#if defined(RTS_DEBUG) if (TheHurtSelectionMode && draw) { Object* obj = draw->getObject(); @@ -858,7 +849,7 @@ GameMessageDisposition SelectionTranslator::translateGameMessage(const GameMessa break; } - #ifdef DEBUG_OBJECT_ID_EXISTS +#ifdef DEBUG_OBJECT_ID_EXISTS if (TheDebugSelectionMode && draw && draw->getObject()) { if (TheObjectIDToDebug == 0) @@ -873,28 +864,9 @@ GameMessageDisposition SelectionTranslator::translateGameMessage(const GameMessa break; } } - #endif - -#endif - - -#if defined(_ALLOW_DEBUG_CHEATS_IN_RELEASE) - if (m_HandOfGodSelectionMode && draw) - { - Object* obj = draw->getObject(); - if (obj) - { - TheAudio->addAudioEvent(&TheAudio->getMiscAudio()->m_noCanDoSound); - GameMessage* msg = TheMessageStream->appendMessage( GameMessage::MSG_DEBUG_KILL_OBJECT ); - msg->appendObjectIDArgument(obj->getID()); - } - disp = DESTROY_MESSAGE; - break; - } -#endif - - - } +#endif // DEBUG_OBJECT_ID_EXISTS +#endif // RTS_DEBUG + } } if (disp == DESTROY_MESSAGE) diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIGuard.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIGuard.cpp index 82f96191931..4898b8a9dc4 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIGuard.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIGuard.cpp @@ -179,8 +179,15 @@ AIGuardMachine::AIGuardMachine( Object *owner ) : //Kris: Except that guard return is more like an attack move, and will acquire targets while moving there. //This breaks deployAI units because they have to completely unpack before realizing that there is a target in range. //So I'm making AI_GUARD_INNER the first state. +#if RETAIL_COMPATIBLE_CRC defineState( AI_GUARD_INNER, newInstance(AIGuardInnerState)( this ), AI_GUARD_OUTER, AI_GUARD_OUTER, attackAggressors ); defineState( AI_GUARD_RETURN, newInstance(AIGuardReturnState)( this ), AI_GUARD_IDLE, AI_GUARD_INNER, attackAggressors ); +#else + // TheSuperHackers @bugfix 09/04/2026 The attack aggressors conditions for AI_GUARD_INNER and AI_GUARD_RETURN + // were removed to fix the conflicting movement and fire behavior in guard mode when the unit is under attack. + defineState( AI_GUARD_INNER, newInstance(AIGuardInnerState)( this ), AI_GUARD_OUTER, AI_GUARD_OUTER ); + defineState( AI_GUARD_RETURN, newInstance(AIGuardReturnState)( this ), AI_GUARD_IDLE, AI_GUARD_INNER ); +#endif defineState( AI_GUARD_IDLE, newInstance(AIGuardIdleState)( this ), AI_GUARD_INNER, AI_GUARD_RETURN, attackAggressors ); defineState( AI_GUARD_OUTER, newInstance(AIGuardOuterState)( this ), AI_GUARD_GET_CRATE, AI_GUARD_GET_CRATE ); defineState( AI_GUARD_GET_CRATE, newInstance(AIGuardPickUpCrateState)( this ), AI_GUARD_RETURN, AI_GUARD_RETURN ); diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIGuardRetaliate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIGuardRetaliate.cpp index e120a58c4df..0c352c2e145 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIGuardRetaliate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIGuardRetaliate.cpp @@ -184,7 +184,13 @@ AIGuardRetaliateMachine::AIGuardRetaliateMachine( Object *owner ) : // srj sez: I made "return" the start state, so that if ordered to guard a position // that isn't the unit's current position, it moves to that position first. defineState( AI_GUARD_RETALIATE_ATTACK_AGGRESSOR, newInstance(AIGuardRetaliateAttackAggressorState)( this ), AI_GUARD_RETALIATE_RETURN, AI_GUARD_RETALIATE_RETURN ); +#if RETAIL_COMPATIBLE_CRC defineState( AI_GUARD_RETALIATE_RETURN, newInstance(AIGuardRetaliateReturnState)( this ), AI_GUARD_RETALIATE_IDLE, AI_GUARD_RETALIATE_INNER, attackAggressors ); +#else + // TheSuperHackers @bugfix 09/04/2026 The attack aggressors conditions for AI_GUARD_RETALIATE_RETURN + // were removed to fix the conflicting movement and fire behavior in guard mode when the unit is under attack. + defineState( AI_GUARD_RETALIATE_RETURN, newInstance(AIGuardRetaliateReturnState)( this ), AI_GUARD_RETALIATE_IDLE, AI_GUARD_RETALIATE_INNER ); +#endif defineState( AI_GUARD_RETALIATE_IDLE, newInstance(AIGuardRetaliateIdleState)( this ), AI_GUARD_RETALIATE_INNER, EXIT_MACHINE_WITH_SUCCESS, attackAggressors ); defineState( AI_GUARD_RETALIATE_INNER, newInstance(AIGuardRetaliateInnerState)( this ), AI_GUARD_RETALIATE_OUTER, AI_GUARD_RETALIATE_OUTER ); defineState( AI_GUARD_RETALIATE_OUTER, newInstance(AIGuardRetaliateOuterState)( this ), AI_GUARD_RETALIATE_GET_CRATE, AI_GUARD_RETALIATE_GET_CRATE ); diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Map/TerrainLogic.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Map/TerrainLogic.cpp index fdf231db57b..3ebc5b7e386 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Map/TerrainLogic.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Map/TerrainLogic.cpp @@ -1633,7 +1633,7 @@ Bool TerrainLogic::isPurposeOfPath( Waypoint *pWay, AsciiString label ) PolygonTrigger *TerrainLogic::getTriggerAreaByName( AsciiString name ) { for (PolygonTrigger* pTrig = PolygonTrigger::getFirstPolygonTrigger(); pTrig; pTrig = pTrig->getNext()) { - AsciiString trigName = pTrig->getTriggerName(); + const AsciiString& trigName = pTrig->getTriggerName(); if (name == trigName) return pTrig; } diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp index cc7b45f7857..0a2f82be920 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp @@ -2720,15 +2720,26 @@ void GameLogic::processCommandList( CommandList *list ) } else { - //DEBUG_LOG(("Comparing %d CRCs on frame %d", m_cachedCRCs.size(), m_frame)); - std::map::const_iterator crcIt = m_cachedCRCs.begin(); - Int validatorCRC = crcIt->second; - //DEBUG_LOG(("Validator CRC from player %d is %8.8X", crcIt->first, validatorCRC)); - while (++crcIt != m_cachedCRCs.end()) + Bool hasReferenceCRC = FALSE; + UnsignedInt referenceCRC = 0; + + for (CachedCRCMap::const_iterator it = m_cachedCRCs.begin(); it != m_cachedCRCs.end(); ++it) { - Int validatedCRC = crcIt->second; - //DEBUG_LOG(("CRC to validate is from player %d: %8.8X", crcIt->first, validatedCRC)); - if (validatorCRC != validatedCRC) + // TheSuperHackers @bugfix Caball009 14/06/2026 Check if player is still connected, + // to avoid spurious mismatches at low CRC intervals, e.g. every frame. + if (!TheNetwork->isPlayerConnected(it->first)) + continue; + + const UnsignedInt crc = it->second; + + if (!hasReferenceCRC) + { + hasReferenceCRC = TRUE; + referenceCRC = crc; + continue; + } + + if (referenceCRC != crc) { DEBUG_CRASH(("CRC mismatch!")); sawCRCMismatch = TRUE; @@ -2741,7 +2752,7 @@ void GameLogic::processCommandList( CommandList *list ) { #ifdef DEBUG_LOGGING DEBUG_LOG(("CRC Mismatch - saw %d CRCs from %d players", m_cachedCRCs.size(), numPlayers)); - for (std::map::const_iterator crcIt = m_cachedCRCs.begin(); crcIt != m_cachedCRCs.end(); ++crcIt) + for (CachedCRCMap::const_iterator crcIt = m_cachedCRCs.begin(); crcIt != m_cachedCRCs.end(); ++crcIt) { Player *player = ThePlayerList->getNthPlayer(crcIt->first); DEBUG_LOG(("CRC from player %d (%ls) = %X", crcIt->first, diff --git a/GeneralsMD/Code/Tools/WorldBuilder/src/LayersList.cpp b/GeneralsMD/Code/Tools/WorldBuilder/src/LayersList.cpp index c55d2d57f62..f96502efd14 100644 --- a/GeneralsMD/Code/Tools/WorldBuilder/src/LayersList.cpp +++ b/GeneralsMD/Code/Tools/WorldBuilder/src/LayersList.cpp @@ -447,7 +447,7 @@ void LayersList::updateUIFromList() } for (ListPolygonTriggerPtrIt triggerIt = layersIt->polygonTriggersInLayer.begin(); triggerIt != layersIt->polygonTriggersInLayer.end(); ++triggerIt) { - AsciiString uniqueID = (*triggerIt)->getTriggerName(); + const AsciiString& uniqueID = (*triggerIt)->getTriggerName(); pTree->InsertItem(uniqueID.str(), iconToShow, iconToShow, thisBranch); } } @@ -609,7 +609,7 @@ void LayersList::addPolygonTriggerToLayer(IN PolygonTrigger *triggerToAdd, IN Li // only update this object. HTREEITEM hItem = findTreeLayerNamed(layerToAddTo->layerName); if (hItem) { - AsciiString triggerName = triggerToAdd->getTriggerName(); + const AsciiString& triggerName = triggerToAdd->getTriggerName(); int iconToShow = (layerToAddTo->show ? 0 : 1); mTree->InsertItem(triggerName.str(), iconToShow, iconToShow, hItem); } @@ -691,7 +691,7 @@ void LayersList::removePolygonTriggerFromLayer(IN PolygonTrigger *triggerToRemov // only remove this object HTREEITEM layer = findTreeLayerNamed(layerToRemoveFrom->layerName); if (layer) { - AsciiString triggerUID = (*triggerBeingRemove)->getTriggerName(); + const AsciiString& triggerUID = (*triggerBeingRemove)->getTriggerName(); HTREEITEM itemToDelete = findTreeObjectNamed(triggerUID.str(), layer); if (itemToDelete) { mTree->DeleteItem(itemToDelete); @@ -1227,7 +1227,7 @@ Bool LayersList::findAndSelectPolygonTrigger(AsciiString selectedItemAsciiString PolygonTrigger *trigger = PolygonTrigger::getFirstPolygonTrigger(); while (trigger) { - AsciiString triggerName = trigger->getTriggerName(); + const AsciiString& triggerName = trigger->getTriggerName(); if (triggerName.compareNoCase(selectedItemAsciiString) == 0) { // Found it... select this object @@ -1307,7 +1307,7 @@ PolygonTrigger* LayersList::findPolygonTriggerByUID(AsciiString triggerIDToFind) PolygonTrigger *trigger = PolygonTrigger::getFirstPolygonTrigger(); while (trigger) { - AsciiString triggerName = trigger->getTriggerName(); + const AsciiString& triggerName = trigger->getTriggerName(); if (triggerName.compareNoCase(triggerIDToFind) == 0) { return (trigger); diff --git a/GeneralsMD/Code/Tools/WorldBuilder/src/WaterOptions.cpp b/GeneralsMD/Code/Tools/WorldBuilder/src/WaterOptions.cpp index a4c0b4f99fc..04e0f463ea9 100644 --- a/GeneralsMD/Code/Tools/WorldBuilder/src/WaterOptions.cpp +++ b/GeneralsMD/Code/Tools/WorldBuilder/src/WaterOptions.cpp @@ -162,7 +162,7 @@ void WaterOptions::OnChangeWaterEdit() PolygonTrigger *pTrig; for (pTrig=PolygonTrigger::getFirstPolygonTrigger(); !didMatch && pTrig; pTrig = pTrig->getNext()) { if (pTrig==theTrigger) continue; // don't check against yourself. - AsciiString trigName = pTrig->getTriggerName(); + const AsciiString& trigName = pTrig->getTriggerName(); if (name == trigName) { if (pTrig->isValid()) { didMatch = true; diff --git a/GeneralsMD/Code/Tools/WorldBuilder/src/WaypointOptions.cpp b/GeneralsMD/Code/Tools/WorldBuilder/src/WaypointOptions.cpp index 9d6e68800b1..4ce35b40e57 100644 --- a/GeneralsMD/Code/Tools/WorldBuilder/src/WaypointOptions.cpp +++ b/GeneralsMD/Code/Tools/WorldBuilder/src/WaypointOptions.cpp @@ -486,7 +486,7 @@ void WaypointOptions::OnChangeWaypointnameEdit() PolygonTrigger *pTrig; for (pTrig=PolygonTrigger::getFirstPolygonTrigger(); !didMatch && pTrig; pTrig = pTrig->getNext()) { if (pTrig==theTrigger) continue; // don't check against yourself. - AsciiString trigName = pTrig->getTriggerName(); + const AsciiString& trigName = pTrig->getTriggerName(); if (name == trigName) { if (pTrig->isValid()) { didMatch = true;