~ares-developers/ares/gd03

« back to all changes in this revision

Viewing changes to src/Misc/SWTypes/UnitDelivery.cpp

  • Committer: Renegade
  • Date: 2010-05-29 08:12:17 UTC
  • Revision ID: git-v1:0a1bb6321f04d723afe64d1b843dc87b4da783ec
Creating /trunk/src.

git-svn-id: svn://svn.renegadeprojects.com/ares/trunk@622 859b54a9-7a54-0410-aeb3-f8d2f1fa40fd

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "UnitDelivery.h"
 
2
#include "../../Ext/Techno/Body.h"
 
3
 
 
4
void SW_UnitDelivery::LoadFromINI(
 
5
        SWTypeExt::ExtData *pData, SuperWeaponTypeClass *pSW, CCINIClass *pINI)
 
6
{
 
7
        const char * section = pSW->ID;
 
8
 
 
9
        if(!pINI->GetSection(section)) {
 
10
                return;
 
11
        }
 
12
 
 
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);
 
17
                        if(!Type) {
 
18
                                Type = UnitTypeClass::Find(cur);
 
19
                        }
 
20
                        if(!Type) {
 
21
                                Type = AircraftTypeClass::Find(cur);
 
22
                        }
 
23
                        if(!Type) {
 
24
                                Type = BuildingTypeClass::Find(cur);
 
25
                        }
 
26
                        if(Type) {
 
27
                                pData->SW_Deliverables.AddItem(Type);
 
28
                        }
 
29
                }
 
30
        }
 
31
 
 
32
        INI_EX exINI(pINI);
 
33
        pData->SW_DeliverBuildups.Read(&exINI, section, "SW.DeliverBuildups");
 
34
}
 
35
 
 
36
bool SW_UnitDelivery::Launch(SuperClass* pThis, CellStruct* pCoords, byte IsPlayer)
 
37
{
 
38
        this->newStateMachine(150, *pCoords, pThis);
 
39
 
 
40
        Unsorted::CurrentSWType = -1;
 
41
        return 1;
 
42
}
 
43
 
 
44
void UnitDeliveryStateMachine::Update() {
 
45
        switch(this->TimePassed()) {
 
46
        case 1:
 
47
                // play anim
 
48
                break;
 
49
        case 20:
 
50
                this->PlaceUnits();
 
51
                break;
 
52
        case 100:
 
53
                // write message
 
54
                break;
 
55
        };
 
56
}
 
57
 
 
58
// Replaced my own implementation with AlexB's shown below
 
59
 
 
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.
 
65
 
 
66
void UnitDeliveryStateMachine::PlaceUnits() {
 
67
        int unitIdx = 0;
 
68
        SWTypeExt::ExtData *pData = this->FindExtData();
 
69
 
 
70
        if(!pData) {
 
71
                return;
 
72
        }
 
73
 
 
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);
 
78
 
 
79
                if(ItemBuilding && pData->SW_DeliverBuildups) {
 
80
                        ItemBuilding->QueueMission(mission_Construction, false);
 
81
                }
 
82
 
 
83
                int cellIdx = 0;
 
84
                bool Placed = false;
 
85
                do {
 
86
                        CellStruct tmpCell = CellSpread::GetCell(cellIdx) + this->Coords;
 
87
                        if(MapClass::Instance->CellExists(&tmpCell)) {
 
88
                                CellClass *cell = MapClass::Instance->GetCellAt(&tmpCell);
 
89
                                CoordStruct XYZ;
 
90
                                cell->GetCoordsWithBridge(&XYZ);
 
91
 
 
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;
 
97
                                }
 
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();
 
103
                                }
 
104
 
 
105
                                if(validCell) {
 
106
                                        if(Placed = Item->Put(&XYZ, (cellIdx & 7))) {
 
107
                                                if(ItemBuilding) {
 
108
                                                        if (pData->SW_DeliverBuildups) {
 
109
                                                                ItemBuilding->UpdateOwner(this->Super->Owner);
 
110
                                                                ItemBuilding->unknown_bool_6DD = 1;
 
111
                                                        }
 
112
                                                } else {
 
113
                                                        if(Type->BalloonHover || Type->JumpJet) {
 
114
                                                                Item->Scatter(0xB1CFE8, 1, 0);
 
115
                                                        }
 
116
                                                        if(cell->ContainsBridge()) {
 
117
                                                                Item->OnBridge = true;
 
118
                                                        }
 
119
                                                }
 
120
                                        }
 
121
                                }
 
122
                        }
 
123
 
 
124
                        ++cellIdx;
 
125
                        if(cellIdx >= 100) { // 100 cells should be enough for any sane delivery
 
126
                                cellIdx = 0;
 
127
                                if(!Placed) {
 
128
                                        Item->UnInit();
 
129
                                }
 
130
                                break;
 
131
                        }
 
132
                } while(!Placed);
 
133
                ++unitIdx;
 
134
        }
 
135
}