1
#include "UnitDelivery.h"
2
#include "../../Ext/Techno/Body.h"
4
void SW_UnitDelivery::LoadFromINI(
5
SWTypeExt::ExtData *pData, SuperWeaponTypeClass *pSW, CCINIClass *pINI)
7
const char * section = pSW->ID;
9
if(!pINI->GetSection(section)) {
13
if(pINI->ReadString(section, "SW.Deliver", "", Ares::readBuffer, Ares::readLength)) {
14
pData->SW_Deliverables.Clear();
15
for(char *cur = strtok(Ares::readBuffer, ","); cur && *cur; cur = strtok(NULL, ",")) {
16
TechnoTypeClass * Type = InfantryTypeClass::Find(cur);
18
Type = UnitTypeClass::Find(cur);
21
Type = AircraftTypeClass::Find(cur);
24
Type = BuildingTypeClass::Find(cur);
27
pData->SW_Deliverables.AddItem(Type);
33
pData->SW_DeliverBuildups.Read(&exINI, section, "SW.DeliverBuildups");
36
bool SW_UnitDelivery::Launch(SuperClass* pThis, CellStruct* pCoords, byte IsPlayer)
38
this->newStateMachine(150, *pCoords, pThis);
40
Unsorted::CurrentSWType = -1;
44
void UnitDeliveryStateMachine::Update() {
45
switch(this->TimePassed()) {
58
// Replaced my own implementation with AlexB's shown below
60
//This function doesn't skip any placeable items, no matter how
61
//they are ordered. Infantry is grouped. Units are moved to the
62
//center as close as they can. There is an additional fix for a
63
//glitch: previously, even if a unit could be placed, it would
64
//have been unloaded again, when it was at index 100.
66
void UnitDeliveryStateMachine::PlaceUnits() {
68
SWTypeExt::ExtData *pData = this->FindExtData();
74
while(unitIdx < pData->SW_Deliverables.Count) {
75
TechnoTypeClass * Type = pData->SW_Deliverables[unitIdx];
76
TechnoClass * Item = generic_cast<TechnoClass *>(Type->CreateObject(this->Super->Owner));
77
BuildingClass * ItemBuilding = specific_cast<BuildingClass *>(Item);
79
if(ItemBuilding && pData->SW_DeliverBuildups) {
80
ItemBuilding->QueueMission(mission_Construction, false);
86
CellStruct tmpCell = CellSpread::GetCell(cellIdx) + this->Coords;
87
if(MapClass::Instance->CellExists(&tmpCell)) {
88
CellClass *cell = MapClass::Instance->GetCellAt(&tmpCell);
90
cell->GetCoordsWithBridge(&XYZ);
92
bool validCell = true;
93
if(cell->OverlayTypeIndex != -1) {
94
// disallow placing on rocks, rubble and walls
95
OverlayTypeClass *Overlay = OverlayTypeClass::Array->GetItem(cell->OverlayTypeIndex);
96
validCell = !Overlay->Wall && !Overlay->IsARock && !Overlay->IsRubble;
98
if(AircraftClass * ItemAircraft = specific_cast<AircraftClass *>(Item)) {
99
// for aircraft: cell must be empty: non-water, non-cliff, non-shore, non-anything
100
validCell &= !cell->GetContent() && !cell->Tile_Is_Cliff()
101
&& !cell->Tile_Is_DestroyableCliff() && !cell->Tile_Is_Shore()
102
&& !cell->Tile_Is_Water() && !cell->ContainsBridge();
106
if(Placed = Item->Put(&XYZ, (cellIdx & 7))) {
108
if (pData->SW_DeliverBuildups) {
109
ItemBuilding->UpdateOwner(this->Super->Owner);
110
ItemBuilding->unknown_bool_6DD = 1;
113
if(Type->BalloonHover || Type->JumpJet) {
114
Item->Scatter(0xB1CFE8, 1, 0);
116
if(cell->ContainsBridge()) {
117
Item->OnBridge = true;
125
if(cellIdx >= 100) { // 100 cells should be enough for any sane delivery