Ares
|
#include "Body.h"
#include "../BuildingType/Body.h"
#include "../Techno/Body.h"
#include "../../Misc/Network.h"
#include <SpecificStructures.h>
#include <ScenarioClass.h>
#include <InfantryClass.h>
#include <CellClass.h>
#include <cmath>
Functions | |
DEFINE_HOOK (457D58, BuildingClass_CanBeOccupied_SpecificOccupiers, 6) | |
DEFINE_HOOK (441F12, BuildingClass_Destroy_RubbleYell, 6) | |
DEFINE_HOOK (441F2C, BuildingClass_Destroy_KickOutOfRubble, 5) | |
DEFINE_HOOK (44725F, BuildingClass_GetCursorOverObject_TargetABuilding, 5) | |
DEFINE_HOOK (443414, BuildingClass_ClickedAction, 6) | |
DEFINE_HOOK (4494D2, BuildingClass_IsSellable, 6) | |
DEFINE_HOOK (52297F, InfantryClass_GarrisonBuilding_OccupierEntered, 5) | |
DEFINE_HOOK (4586CA, BuildingClass_KillOccupiers_EachOccupierKilled, 6) | |
DEFINE_HOOK (4581CD, BuildingClass_UnloadOccupants_AllOccupantsHaveLeft, 6) | |
DEFINE_HOOK (458729, BuildingClass_KillOccupiers_AllOccupantsKilled, 6) | |
DEFINE_HOOK (448401, BuildingClass_ChangeOwnership_TrenchEVA, 6) |
DEFINE_HOOK | ( | 457D58 | , |
BuildingClass_CanBeOccupied_SpecificOccupiers | , | ||
6 | |||
) |
{ GET(BuildingClass *, pThis, ESI); GET(InfantryClass *, pInf, EDI); BuildingTypeExt::ExtData* pBuildTypeExt = BuildingTypeExt::ExtMap.Find(pThis->Type); bool can_occupy = false; if(pInf->Type->Occupier) { bool isFull = (pThis->GetOccupantCount() == pThis->Type->MaxNumberOccupants); bool isEmpty = (pThis->GetOccupantCount() == 0); // yes, yes, !pThis->GetOccupantCount() - leave it this way for semantics :P bool isIneligible = (pThis->IsRedHP() || pInf->IsMindControlled()); bool isNeutral = pThis->Owner->IsNeutral(); bool isRaidable = (pBuildTypeExt->BunkerRaidable && isEmpty); // if it's not empty, it cannot be raided anymore, 'cause it already was bool sameOwner = (pThis->Owner == pInf->Owner); bool allowedOccupier = pBuildTypeExt->CanBeOccupiedBy(pInf); if(!isFull && !isIneligible && allowedOccupier) { /* The building switches owners after the first occupant enters, so this check should not interfere with the player who captured it, only prevent others from entering it while it's occupied. (Bug #699) */ can_occupy = sameOwner ? true : (isNeutral || isRaidable); } } /* // original code replaced by this hook if(pInf->Occupier) { if ( pThis->Owner != pInf->Owner && !pThis->Owner->Country->MultiplayPassive || pThis->GetOccupantCount() == pThis->BuildingType->MaxNumberOccupants || pThis->IsRedHP() || pInf->IsMindControlled() ) return 0; } return 1; */ return can_occupy ? 0x457DD5 : 0x457DA3; }
DEFINE_HOOK | ( | 448401 | , |
BuildingClass_ChangeOwnership_TrenchEVA | , | ||
6 | |||
) |
{ GET(BuildingClass *, pBld, ESI); GET(HouseClass *, pNewOwner, EBX); enum wasHandled { Yes = 0x44848F, No = 0} Handled = No; BuildingExt::ExtData* bldExt = BuildingExt::ExtMap.Find(pBld); if(bldExt->ignoreNextEVA) { Handled = Yes; bldExt->ignoreNextEVA = false; } return Handled; }
DEFINE_HOOK | ( | 458729 | , |
BuildingClass_KillOccupiers_AllOccupantsKilled | , | ||
6 | |||
) |
{ GET(BuildingClass *, pBld, ESI); BuildingExt::ExtData* buildingExtData = BuildingExt::ExtMap.Find(pBld); buildingExtData->evalRaidStatus(); return 0; }
DEFINE_HOOK | ( | 4581CD | , |
BuildingClass_UnloadOccupants_AllOccupantsHaveLeft | , | ||
6 | |||
) |
{ GET(BuildingClass *, pBld, ESI); BuildingExt::ExtData* buildingExtData = BuildingExt::ExtMap.Find(pBld); buildingExtData->evalRaidStatus(); return 0; }
DEFINE_HOOK | ( | 4586CA | , |
BuildingClass_KillOccupiers_EachOccupierKilled | , | ||
6 | |||
) |
{ GET(BuildingClass *, pBld, ESI); GET(int, idxOccupant, EDI); // I don't think anyone ever actually tested Assaulter=yes with raiding, putting this here 'cause it's likely needed BuildingExt::ExtData* buildingExtData = BuildingExt::ExtMap.Find(pBld); buildingExtData->evalRaidStatus(); return 0; }
DEFINE_HOOK | ( | 52297F | , |
InfantryClass_GarrisonBuilding_OccupierEntered | , | ||
5 | |||
) |
{ GET(InfantryClass *, pInf, ESI); GET(BuildingClass *, pBld, EBP); BuildingExt::ExtData* buildingExtData = BuildingExt::ExtMap.Find(pBld); TechnoExt::ExtData* infExtData = TechnoExt::ExtMap.Find(pInf); infExtData->GarrisonedIn = pBld; // if building and owner are from different players, and the building is not in raided state // change the building's owner and mark it as raided // but only if that's even necessary - no need to raid urban combat buildings. // 27.11.2010 changed to include fix for #1305 bool differentOwners = (pBld->Owner != pInf->Owner); bool ucBuilding = (pBld->Owner->IsNeutral() && (pBld->GetTechnoType()->TechLevel == -1)); if(differentOwners && !ucBuilding && !buildingExtData->isCurrentlyRaided) { buildingExtData->OwnerBeforeRaid = pBld->Owner; buildingExtData->isCurrentlyRaided = true; pBld->SetOwningHouse(pInf->Owner); } return 0; }
DEFINE_HOOK | ( | 4494D2 | , |
BuildingClass_IsSellable | , | ||
6 | |||
) |
{ GET(BuildingClass *, B, ESI); BuildingExt::ExtData* curBuildExt = BuildingExt::ExtMap.Find(B); enum SellValues {FORCE_SELLABLE, FORCE_UNSELLABLE, DECIDE_NORMALLY} sellTreatment; sellTreatment = DECIDE_NORMALLY; // default if(curBuildExt->isCurrentlyRaided) { sellTreatment = FORCE_UNSELLABLE; // enemy shouldn't be able to sell "borrowed" buildings } switch(sellTreatment) { case FORCE_SELLABLE: return 0x449532; case FORCE_UNSELLABLE: return 0x449536; case DECIDE_NORMALLY: default: return 0; } }
DEFINE_HOOK | ( | 443414 | , |
BuildingClass_ClickedAction | , | ||
6 | |||
) |
{ GET(eAction, Action, EAX); GET(BuildingClass *, pThis, ECX); GET_STACK(ObjectClass *, pTarget, 0x8); if(Action == act_Enter) { if(BuildingClass *pTargetBuilding = specific_cast<BuildingClass *>(pTarget)) { CoordStruct XYZ; pTargetBuilding->GetCoords(&XYZ); CellStruct tgt = { short(XYZ.X / 256), short(XYZ.Y / 256) }; AresNetEvent::Handlers::RaiseTrenchRedirectClick(pThis, &tgt); R->EAX(1); return 0x44344D; } } return 0; }
DEFINE_HOOK | ( | 44725F | , |
BuildingClass_GetCursorOverObject_TargetABuilding | , | ||
5 | |||
) |
{ GET(BuildingClass *, pThis, ESI); GET(TechnoClass *, T, EBP); // not decided on UI handling yet if(T->WhatAmI() == abs_Building) { BuildingClass* targetBuilding = specific_cast<BuildingClass *>(T); BuildingExt::ExtData* curBuildExt = BuildingExt::ExtMap.Find(pThis); if(curBuildExt->canTraverseTo(targetBuilding)) { //show entry cursor, hooked up to traversal logic in Misc/Network.cpp -> AresNetEvent::Handlers::RespondToTrenchRedirectClick R->EAX<eAction>(act_Enter); return 0x447273; } } return 0; }
DEFINE_HOOK | ( | 441F2C | , |
BuildingClass_Destroy_KickOutOfRubble | , | ||
5 | |||
) |
{ GET(BuildingClass*, pBld, ESI); // find out whether this destroyed building would turn into rubble if(BuildingTypeExt::ExtData *pTData = BuildingTypeExt::ExtMap.Find(pBld->Type)) { if(pTData->RubbleDestroyed) { if(BuildingExt::ExtData *pData = BuildingExt::ExtMap.Find(pBld)) { // this is not the rubble, but the old intact building. // since we force the same foundation this is no problem. pData->KickOutOfRubble(); } } } return 0; }
DEFINE_HOOK | ( | 441F12 | , |
BuildingClass_Destroy_RubbleYell | , | ||
6 | |||
) |
{ GET(BuildingClass *, pThis, ESI); BuildingExt::ExtData* BuildingAresData = BuildingExt::ExtMap.Find(pThis); BuildingTypeExt::ExtData* destrBuildTE = BuildingTypeExt::ExtMap.Find(pThis->Type); // If this object has a rubble building set, turn if(destrBuildTE->RubbleDestroyed) { ++Unsorted::IKnowWhatImDoing; BuildingAresData->RubbleYell(); --Unsorted::IKnowWhatImDoing; } return 0; }