Ares
Classes | Public Types | Static Public Member Functions | Static Public Attributes

TechnoExt Class Reference

#include <src/Ext/Techno/Body.h>

List of all members.

Classes

class  ExtData

Public Types

typedef TechnoClass TT

Static Public Member Functions

static void SpawnSurvivors (FootClass *pThis, TechnoClass *pKiller, bool Select, bool IgnoreDefenses)
static bool EjectSurvivor (FootClass *Survivor, CoordStruct *loc, bool Select)
static void EjectPassengers (FootClass *, signed short)
static void GetPutLocation (CoordStruct const &, CoordStruct &)
static void StopDraining (TechnoClass *Drainer, TechnoClass *Drainee)
 Breaks the link between DrainTarget and DrainingMe.
static bool CreateWithDroppod (FootClass *Object, CoordStruct *XYZ)
static void Destroy (TechnoClass *pTechno, TechnoClass *pKiller=NULL, HouseClass *pKillerHouse=NULL, WarheadTypeClass *pWarhead=NULL)

Static Public Attributes

static Container< TechnoExtExtMap
static hash_map< ObjectClass
*, AlphaShapeClass * > 
AlphaExt
static hash_map< TechnoClass
*, BuildingLightClass * > 
SpotlightExt
static BuildingLightClass * ActiveBuildingLight = NULL
static FireError::Value FiringStateCache = FireError::NotAValue
static bool NeedsRegap = false

Member Typedef Documentation

typedef TechnoClass TechnoExt::TT

Member Function Documentation

bool TechnoExt::CreateWithDroppod ( FootClass *  Object,
CoordStruct *  XYZ 
) [static]
                                                                     {
        auto MyCell = MapClass::Instance->GetCellAt(XYZ);
        if(Object->IsCellOccupied(MyCell, -1, -1, 0, 0)) {
//              Debug::Log("Cell occupied... poof!\n");
                return false;
        } else {
//              Debug::Log("Destinating %s @ {%d, %d, %d}\n", Object->GetType()->ID, XYZ->X, XYZ->Y, XYZ->Z);
                LocomotionClass::ChangeLocomotorTo(Object, &LocomotionClass::CLSIDs::Droppod);
                CoordStruct xyz = *XYZ;
                xyz.Z = 0;
                Object->SetLocation(&xyz);
                Object->SetDestination(MyCell, 1);
                Object->Locomotor->Move_To(*XYZ);
                FacingStruct::Facet Facing = {0, 0, 0};
                Object->Facing.SetFacing(&Facing);
                if(!Object->InLimbo) {
                        Object->See(0, 0);
                        Object->QueueMission(mission_Guard, 0);
                        Object->NextMission();
                        return true;
                }
                //Debug::Log("InLimbo... failed?\n");
                return false;
        }
}
void TechnoExt::Destroy ( TechnoClass *  pTechno,
TechnoClass *  pKiller = NULL,
HouseClass *  pKillerHouse = NULL,
WarheadTypeClass *  pWarhead = NULL 
) [static]
                                                                                                                        {
        if(!pKillerHouse && pKiller) {
                pKillerHouse = pKiller->Owner;
        }

        if(!pWarhead) {
                pWarhead = RulesClass::Instance->C4Warhead;
        }

        int health = pTechno->Health;
        pTechno->ReceiveDamage(&health, 0, pWarhead, pKiller, TRUE, FALSE, pKillerHouse);
}
void TechnoExt::EjectPassengers ( FootClass *  pThis,
signed short  howMany 
) [static]

This function ejects a given number of passengers from the passed transporter.

Parameters:
pThisPointer to the transporter
howManyHow many passengers to eject - pass negative number for "all"
Author:
Renegade
Date:
27.05.2010
                                                                      {
        if(howMany == 0 || !pThis->Passengers.NumPassengers) {
                return;
        }

        short limit = (howMany < 0 || howMany > pThis->Passengers.NumPassengers) ? pThis->Passengers.NumPassengers : howMany;

        for(short i = 0; (i < limit) && pThis->Passengers.FirstPassenger; ++i) {
                CoordStruct destination;
                TechnoExt::GetPutLocation(pThis->Location, destination);

                FootClass *passenger = pThis->RemoveFirstPassenger();
                if(!passenger->Put(&destination, ScenarioClass::Instance->Random.RandomRanged(0, 7))) {
                        passenger->UnInit();
                }
        }
        return;
}
bool TechnoExt::EjectSurvivor ( FootClass *  Survivor,
CoordStruct *  loc,
bool  Select 
) [static]
Parameters:
SurvivorPassenger to eject
locWhere to put the passenger
SelectWhether to select the Passenger afterwards

Todo:
Tag

{
        bool success;
        CoordStruct tmpCoords;
        CellClass * pCell = MapClass::Instance->GetCellAt(loc);
        pCell->GetCoordsWithBridge(&tmpCoords);
        Survivor->OnBridge = pCell->ContainsBridge();

        int floorZ = tmpCoords.Z;
        bool Chuted(false);
        if(loc->Z - floorZ > 208) {
                success = Survivor->SpawnParachuted(loc);
                Chuted = true;
        } else {
                loc->Z = floorZ;
                success = Survivor->Put(loc, ScenarioClass::Instance->Random.RandomRanged(0, 7));
        }
        RET_UNLESS(success);
        Survivor->Transporter = NULL;


        Survivor->LastMapCoords = pCell->MapCoords;
        // don't ask, don't tell (ripped from 0x51A84F)
        if(Chuted) {
                bool scat(Survivor->OnBridge);
                DWORD *flagsOfSomeKind = reinterpret_cast<DWORD *>(pCell->unknown_121 + 3);
                if((flagsOfSomeKind[scat] & 0x1C) == 0x1C) {
                        pCell->ScatterContent(0xA8F200, 1, 1, scat);
                }
        } else {
                Survivor->Scatter(0xB1CFE8, 1, 0);
                Survivor->QueueMission(Survivor->Owner->ControlledByHuman() ? mission_Guard : mission_Hunt, 0);
        }
        Survivor->unknown_bool_690 = Survivor->unknown_bool_691 = false;


        if(Select) {
                Survivor->Select();
        }
        return 1;
}
void TechnoExt::GetPutLocation ( CoordStruct const &  current,
CoordStruct &  target 
) [static]

This function drops the coordinates of an infantry subposition into the target parameter. Could probably work for vehicles as well, though they'd be off-center.

Parameters:
currentThe current position of the transporter, the starting point to look from
targetA CoordStruct to save the finally computed position to
Author:
Renegade
Date:
27.05.2010
                                                                              {
        // this whole thing does not at all account for cells which are completely occupied.
        CoordStruct tmpLoc = current;
        CellStruct tmpCoords = CellSpread::GetCell(ScenarioClass::Instance->Random.RandomRanged(0, 7));

        tmpLoc.X += tmpCoords.X * 128;
        tmpLoc.Y += tmpCoords.Y * 128;

        CellClass * tmpCell = MapClass::Instance->GetCellAt(&tmpLoc);

        tmpCell->FindInfantrySubposition(&target, &tmpLoc, 0, 0, 0);

        target.Z = current.Z;
        return;
}
void TechnoExt::SpawnSurvivors ( FootClass *  pThis,
TechnoClass *  pKiller,
bool  Select,
bool  IgnoreDefenses 
) [static]
{
        TechnoTypeClass *Type = pThis->GetTechnoType();

        HouseClass *pOwner = pThis->Owner;
        TechnoTypeExt::ExtData *pData = TechnoTypeExt::ExtMap.Find(Type);
        TechnoExt::ExtData *pSelfData = TechnoExt::ExtMap.Find(pThis);
//      RETZ_UNLESS(pData->Survivors_PilotChance || pData->Survivors_PassengerChance);
        RETZ_UNLESS(!pSelfData->Survivors_Done);

        CoordStruct loc = pThis->Location;

        int chance = pData->Survivors_PilotChance.BindTo(pThis)->Get();
        // remove check for Crewed if it is accounted for outside of this function
        // checks if Crewed=yes is set and there is a chance pilots survive, and, if yes...
        // ...attempts to spawn one Survivors_PilotCount times

        if(Type->Crewed && chance && !IgnoreDefenses) {
                for(int i = 0; i < pData->Survivors_PilotCount; ++i) {
                        if(ScenarioClass::Instance->Random.RandomRanged(1, 100) <= chance) {
                                signed int idx = pOwner->SideIndex;
                                auto Pilots = &pData->Survivors_Pilots;
                                if(Pilots->ValidIndex(idx)) {
                                        if(InfantryTypeClass *PilotType = Pilots->GetItem(idx)) {
                                                InfantryClass *Pilot = reinterpret_cast<InfantryClass *>(PilotType->CreateObject(pOwner));
                                                // HouseClass::CreateParadrop does this when building passengers for a paradrop... it might be a wise thing to mimic!
                                                Pilot->Remove();

                                                Pilot->Health = (PilotType->Strength / 2);
                                                Pilot->Veterancy.Veterancy = pThis->Veterancy.Veterancy;
                                                CoordStruct destLoc, tmpLoc = loc;
                                                CellStruct tmpCoords = CellSpread::GetCell(ScenarioClass::Instance->Random.RandomRanged(0, 7));

                                                tmpLoc.X += tmpCoords.X * 144;
                                                tmpLoc.Y += tmpCoords.Y * 144;

                                                CellClass * tmpCell = MapClass::Instance->GetCellAt(&tmpLoc);

                                                tmpCell->FindInfantrySubposition(&destLoc, &tmpLoc, 0, 0, 0);

                                                destLoc.Z = loc.Z;

                                                if(!TechnoExt::EjectSurvivor(Pilot, &destLoc, Select)) {
                                                        Pilot->RegisterDestruction(pKiller); //(TechnoClass *)R->get_StackVar32(0x54));
                                                        GAME_DEALLOC(Pilot);
                                                }
                                        }
                                }
                        }
                }
        }

        chance = pData->Survivors_PassengerChance.BindTo(pThis)->Get();

        while(pThis->Passengers.FirstPassenger) {
                bool toDelete = 1;
                FootClass *passenger = pThis->RemoveFirstPassenger();
                bool toSpawn = false;
                if(chance > 0) {
                        toSpawn = ScenarioClass::Instance->Random.RandomRanged(1, 100) <= chance;
                } else if(chance == -1 && pThis->WhatAmI() == abs_Unit) {
                        int occupation = passenger->IsCellOccupied(pThis->GetCell(), -1, -1, 0, 1);
                        toSpawn = (occupation == 0 || occupation == 2);
                }
                if(toSpawn && !IgnoreDefenses) {
                        CoordStruct destLoc, tmpLoc = loc;
                        CellStruct tmpCoords = CellSpread::GetCell(ScenarioClass::Instance->Random.RandomRanged(0, 7));

                        tmpLoc.X += tmpCoords.X * 128;
                        tmpLoc.Y += tmpCoords.Y * 128;

                        CellClass * tmpCell = MapClass::Instance->GetCellAt(&tmpLoc);

                        tmpCell->FindInfantrySubposition(&destLoc, &tmpLoc, 0, 0, 0);

                        destLoc.Z = loc.Z;

                        toDelete = !TechnoExt::EjectSurvivor(passenger, &destLoc, Select);
                }
                if(toDelete) {
                        passenger->RegisterDestruction(pKiller); //(TechnoClass *)R->get_StackVar32(0x54));
                        passenger->UnInit();
                }
        }

        pSelfData->Survivors_Done = 1;
}
void TechnoExt::StopDraining ( TechnoClass *  Drainer,
TechnoClass *  Drainee 
) [static]

Breaks the link between DrainTarget and DrainingMe.

The links between the drainer and its victim are removed and the draining animation is no longer played.

Parameters:
DrainerThe Techno that drains power or credits.
DraineeThe Techno that power or credits get gets drained from.
Author:
AlexB
Date:
2010-04-27
                                                                       {
        // fill the gaps
        if(Drainer && !Drainee)
                Drainee = Drainer->DrainTarget;

        if(!Drainer && Drainee)
                Drainer = Drainee->DrainingMe;

        // sanity check, then end draining.
        if(Drainer && Drainee) {
                // stop the animation.
                if (Drainer->DrainAnim) {
                        Drainer->DrainAnim->UnInit();
                        Drainer->DrainAnim = NULL;
                }

                // remove links.
                Drainee->DrainingMe = NULL;
                Drainer->DrainTarget = NULL;

                // tell the game to recheck the drained
                // player's tech level.
                if (Drainee->Owner) {
                        Drainee->Owner->ShouldRecheckTechTree = true;
                }
        }
}

Member Data Documentation

BuildingLightClass * TechnoExt::ActiveBuildingLight = NULL [static]
FireError::Value TechnoExt::FiringStateCache = FireError::NotAValue [static]
bool TechnoExt::NeedsRegap = false [static]

The documentation for this class was generated from the following files:
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines