Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds the "Underground" layer to the tactical display Next and Prev search. #787

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 114 additions & 0 deletions src/extensions/display/displayext_hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include "buildingtypeext.h"
#include "house.h"
#include "housetype.h"
#include "layer.h"
#include "session.h"
#include "sessionext.h"
#include "wwmouse.h"
Expand All @@ -49,6 +50,116 @@
#include "hooker_macros.h"


/**
* A fake class for implementing new member functions which allow
* access to the "this" pointer of the intended class.
*
* @note: This must not contain a constructor or destructor!
* @note: All functions must be prefixed with "_" to prevent accidental virtualization.
*/
class DisplayClassExt final : public DisplayClass
{
public:
ObjectClass * _Next_Object(ObjectClass * object) const;
ObjectClass * _Prev_Object(ObjectClass * object) const;
};


/**
* Reimplementation of DisplayClass::Next_Object.
*
* Searches for next object on display.
*
* @author: 06/20/1994 JLB - Red Alert source code.
* CCHyper - Adjustments for Tiberian Sun.
*/
ObjectClass * DisplayClassExt::_Next_Object(ObjectClass * object) const
{
static const LayerType _layers[] = {

/**
* #issue-785
*
* Adds underground layer to display search.
*/
LAYER_UNDERGROUND,

LAYER_GROUND, LAYER_AIR, LAYER_TOP,
};

ObjectClass * firstobj = nullptr;
bool foundmatch = false;

if (object == nullptr) {
foundmatch = true;
}
for (int index = 0; index < ARRAY_SIZE(_layers); ++index) {
LayerType layer = _layers[index];

for (unsigned uindex = 0; uindex < (unsigned)Layer[layer].Count(); uindex++) {
ObjectClass * obj = Layer[layer][uindex];

/**
* Verify that the object can be selected by and is owned by the player.
*/
if (obj != nullptr && obj->Is_Players_Army()) {
if (firstobj == nullptr) firstobj = obj;
if (foundmatch) return obj;
if (object == obj) foundmatch = true;
}
}
}
return firstobj;
}


/**
* Reimplementation of DisplayClass::Next_Object.
*
* Searches for the previous object on the map.
*
* @author: 08/24/1995 JLB - Red Alert source code.
* CCHyper - Adjustments for Tiberian Sun.
*/
ObjectClass * DisplayClassExt::_Prev_Object(ObjectClass * object) const
{
static const LayerType _layers[] = {
LAYER_TOP, LAYER_AIR, LAYER_GROUND,

/**
* #issue-785
*
* Adds underground layer to display search.
*/
LAYER_UNDERGROUND,
};

ObjectClass * firstobj = nullptr;
bool foundmatch = false;

if (object == nullptr) {
foundmatch = true;
}
for (int index = 0; index < ARRAY_SIZE(_layers); ++index) {
LayerType layer = _layers[index];

for (int uindex = Layer[layer].Count()-1; uindex >= 0; uindex--) {
ObjectClass * obj = Layer[layer][uindex];

/**
* Verify that the object can be selected by and is owned by the player.
*/
if (obj != nullptr && obj->Is_Players_Army()) {
if (firstobj == nullptr) firstobj = obj;
if (foundmatch) return obj;
if (object == obj) foundmatch = true;
}
}
}
return firstobj;
}


/**
* #issue-171
*
Expand Down Expand Up @@ -270,4 +381,7 @@ void DisplayClassExtension_Hooks()
Patch_Dword(0x0047A0B5+1, ISOMAPPACK_BUFF_WIDTH);
Patch_Dword(0x0047A0BA+1, ISOMAPPACK_BUFF_HEIGHT);
Patch_Dword(0x0047A0C8+1, ISOMAPPACK_BUFF_WIDTH*ISOMAPPACK_BUFF_HEIGHT*sizeof(unsigned short));

Patch_Jump(0x00477390, &DisplayClassExt::_Next_Object);
Patch_Jump(0x00477430, &DisplayClassExt::_Prev_Object);
}
Loading