コード例 #1
0
ファイル: Level.cpp プロジェクト: coltor/hostile-takeover
bool Level::LoadState(Stream *pstm)
{
    // Do version handling

    byte nVer = pstm->ReadByte();
    if (nVer != knVerLevelState)
        return false;

    // Get level name

    char szLevel[kcbFilename];
    pstm->ReadString(szLevel, sizeof(szLevel));

    // Load level constants

    if (!Init(szLevel, true)) {
        return false;
    }

    // Check to see if the save game has a different mission revision number than the mission
    // itself. If so, error. This is the case if a game is saved, then the level is revised
    // in M and reloaded.

    dword dwRevision = pstm->ReadDword();
    if (dwRevision != m_dwRevision) {
        HtMessageBox(kfMbWhiteBorder | kfMbClearDib, "Error", "This saved game is based on an older version of this mission!");
        return false;
    }

    // Load gobm state

    if (!ggobm.LoadState(pstm))
        return false;

    // Load fog and galaxite state

    if (!m_pfogm->LoadState(pstm)) {
        return false;
    }
    if (!m_ptrmap->LoadState(pstm)) {
        return false;
    }

    // Load gobs

    int cGobs = pstm->ReadWord();
    while (cGobs-- != 0) {
        // Get gob type

        GobType gt = pstm->ReadByte();
        Gob *pgob = CreateGob(gt);
        if (pgob == NULL) {
            return false;
        }

        if (!pgob->LoadState(pstm)) {
            return false;
        }
    }

    // Load triggers

    if (!m_tgrm.LoadState(pstm)) {
        return false;
    }

    // Load UnitGroups

    if (!m_ugm.LoadState(pstm)) {
        return false;
    }

    return pstm->IsSuccess();
}
コード例 #2
0
ファイル: Level.cpp プロジェクト: coltor/hostile-takeover
bool Level::LoadLevelConstants(const char *pszLevelName, IniReader *pini)
{
    if (!LoadLevelInfo(pszLevelName, pini))
        return false;

    // m_fInitialized is to distinguish between just having the level parameters
    // read and having been initialized enough to require some cleanup.

    m_fInitialized = true;

    // Load map

    Status("Load Tile Map...");
    char szT[kcbFilename];
    if (!pini->GetPropertyValue("General", "TileMap", szT, sizeof(szT))) {
        Assert(false);
        return false;
    }

    Size sizPlayfield;
    ggame.GetPlayfieldSize(&sizPlayfield);
    m_ptmap = LoadTileMap(szT, &sizPlayfield);
    Assert(m_ptmap != NULL);
    if (m_ptmap == NULL) {
        Assert(false);
        return false;
    }

    // Init GobMgr

    Size sizMap;
    m_ptmap->GetMapSize(&sizMap);
    Size sizTile;
    m_ptmap->GetTileSize(&sizTile);
    if (!ggobm.Init(sizMap.cx / sizTile.cx, sizMap.cy / sizTile.cy, kcpgobMax)) {
        Assert(false);
        return false;
    }

    // Load terrain map

    Status("Load Terrain Map...");
    if (!pini->GetPropertyValue("General", "TerrainMap", szT, sizeof(szT))) {
        Assert(false);
        return false;
    }
    m_ptrmap = new TerrainMap;
    if (m_ptrmap == NULL) {
        Assert(false);
        return false;
    }
    if (!m_ptrmap->Init(szT)) {
        Assert(false);
        return false;
    }

    // Create fog map.

    Status("Create Fog Map...");
    m_pfogm = new FogMap;
    if (m_pfogm == NULL) {
        Assert(false);
        return false;
    }
    if (!m_pfogm->Init(&sizTile, &sizMap)) {
        Assert(false);
        return false;
    }

    // Load palette

    if (!pini->GetPropertyValue("General", "Palette", szT, sizeof(szT))) {
        Assert(false);
        return false;
    }
    m_ppal = (Palette *)gpakr.MapFile(szT, &m_fmapPalette);
    if (m_ppal == NULL) {
        Assert(false);
        return false;
    }
    strcat(szT, ".shadowmap");
    m_mpiclriclrShadow = (byte *)gpakr.MapFile(szT, &m_fmapShadowMap);

    // Instantiate an OvermindGob for each Computer Player

    Player *pplr = gplrm.GetNextPlayer(NULL);
    for (; pplr != NULL; pplr = gplrm.GetNextPlayer(pplr)) {
#ifdef STRESS
        // Instantiate an Overmind for the human player if we're running stress

        if (gfStress) {
            if ((pplr->GetFlags() & (kfPlrComputer | kfPlrComputerOvermind)) == kfPlrComputer)
                continue;
        } else {
            if (!(pplr->GetFlags() & kfPlrComputerOvermind))
                continue;
        }
#else
        if (!(pplr->GetFlags() & kfPlrComputerOvermind))
            continue;
#endif

        // Instantiate and initialize an OvermindGob

        OvermindGob *pgobOvermind = (OvermindGob *)CreateGob(kgtOvermind);
        if (pgobOvermind == NULL) {
            Assert(false);
            delete pini;
            return false;
        }

        if (!pgobOvermind->Init(NULL)) {
            Assert(false);
            delete pgobOvermind;
            delete pini;
            return false;
        }

        // Who's your daddy?

        pgobOvermind->SetOwner(pplr);
    }

    // Load the Triggers

    Status("Load Triggers...");
    if (!m_tgrm.Init(pini)) {
        Assert(false);
        return false;
    }

    // Load the UnitGroups

    Status("Load UnitGroups...");
    if (!m_ugm.Init(pini)) {
        Assert(false);
        return false;
    }

    return true;
}
コード例 #3
0
ファイル: Level.cpp プロジェクト: coltor/hostile-takeover
bool Level::LoadLevelVariables(IniReader *pini)
{
    // Load areas

    Status("Load Areas...");
    if (!ggobm.LoadAreas(pini)) {
        return false;
    }

    // Enumerate all Gob descriptions and instantiate in-memory versions

    Status("Load Gobs...");
    char szName[kcbFilename];
    FindProp find;
    while (pini->FindNextProperty(&find, "GameObjects", szName, sizeof(szName))) {
        GobType gt;
        pini->GetPropertyValue(&find, "%d,", &gt);

        Gob *pgob = CreateGob(gt);
        if (pgob == NULL) {
            Assert(false);
            return false;
        }

        // Don't waste space on Gobs that don't need names

        char *pszName;
        if (strcmp("nil", szName) == 0)
            pszName = NULL;
        else
            pszName = szName;

        if (!pgob->Init(pini, &find, pszName)) {
            Assert(false);
            delete pgob;
            return false;
        }

#ifdef STRESS
        if (gfStress) {
            // Make player's units invulnerable

            if (pgob->GetOwner() == gpplrLocal) {
                if (pgob->GetFlags() & kfGobUnit) {
                    UnitGob *punt = (UnitGob *)pgob;
                    punt->SetUnitFlags(punt->GetUnitFlags() | kfUnitInvulnerable);
                }
            }
        }
#endif
    }

    // Enumerate all Galaxite positions and add them to the Fog/Galaxite map

    Status("Load Galaxite...");
    FindProp find2;
    while (pini->FindNextProperty(&find2, "Galaxite", szName, sizeof(szName))) {
        int nGx, tx, ty;
        pini->GetPropertyValue(&find2, "%d,%d,%d", &nGx, &tx, &ty);
        m_pfogm->SetGalaxite(nGx, tx, ty);
    }

// In terrain for the moment (forever?)
#if 0
    // Enumerate all Wall positions and add them to the Fog/Galaxite/Wall map

    Status("Load walls...");
    FindProp find3;
    while (pini->FindNextProperty(&find3, "Walls", szName, sizeof(szName))) {
        int nHealth, tx, ty;
        pini->GetPropertyValue(&find3, "%d,%d,%d", &nHealth, &tx, &ty);
        m_pfogm->SetWallHealth(nHealth, tx, ty);
    }
#endif

    // Instantiate the "CreateAtLevelLoad" UnitGroups

    m_ugm.CreateAtLevelLoadGroups();

    return true;
}
コード例 #4
0
int ReplicatorGob::ProcessStateMachineMessage(State st, Message *pmsg)
{
BeginStateMachine
	OnMsg(kmidPlaySfx)
		gsndm.PlaySfx((Sfx)pmsg->PlaySfx.sfx);

	State(kstIdle)
		OnUpdate
			// If a mobile unit is at either output, ask it to move on

			TPoint tpt;
			GetTilePosition(&tpt);
			Gid gid;

			// Clear left and right output bays
			Player *pplrNeedCredits = NULL;
			bool fJammed = ClearOutputBay(tpt.tx + kdtxReplicatorOutput1, tpt.ty + kdtyReplicatorOutput1, tpt.tx + kdtxReplicatorOutput1 - 1, tpt.ty + kdtyReplicatorOutput1 + 1);
			fJammed = ClearOutputBay(tpt.tx + kdtxReplicatorOutput2, tpt.ty + kdtyReplicatorOutput2, tpt.tx + kdtxReplicatorOutput2 + 1, tpt.ty + kdtyReplicatorOutput2 + 1) || fJammed;

			// If there's nothing clogging the outputs we can consider the input
			if (m_fEnabled && !fJammed) {
				// loop through all the gobs on this tile to find the mobile unit and ignore ourself, or
				// shots flying by
				for (gid = ggobm.GetFirstGid(tpt.tx + kdtxReplicatorInput, tpt.ty + kdtyReplicatorInput); gid != kgidNull; gid = ggobm.GetNextGid(gid)) {
					MobileUnitGob *pmunt = (MobileUnitGob *)ggobm.GetGob(gid);
					if (pmunt == NULL)
						continue;
					if (!(pmunt->GetFlags() & kfGobMobileUnit))
						continue;

					// Something there! If it's ready, clone it.

					if (!(pmunt->GetMobileUnitFlags() & kfMuntAtReplicatorInput))
						continue;

					// At the limit?
// TUNE:
#define kctIntervalLimitNotify 600

					if (!ggobm.IsBelowLimit(knLimitMobileUnit, pmunt->GetOwner())) {
						if (pmunt->GetOwner() == gpplrLocal) {
							static long s_tLastNotify;
							long tCurrent = gtimm.GetTickCount();
							if (abs((int)(s_tLastNotify - tCurrent)) >= kctIntervalLimitNotify) {
								s_tLastNotify = tCurrent;
								ShowAlert(kidsUnitLimitReached);
							}
						}
						continue;
					}

					// Does the player have enough credits to perform the replication?

					MobileUnitConsts *pmuntc = (MobileUnitConsts *)pmunt->GetConsts();
					Player *pplr = pmunt->GetOwner();
					int cCredits = pplr->GetCredits();

					int nCost = pmuntc->GetCost();
					int cReplicationCost = GetReplicationCost(nCost);
					if (cCredits < cReplicationCost) {
						pplrNeedCredits = pplr;
						break; 
					}

					// Take the money!

					pplr->SetCredits(cCredits - cReplicationCost, true);

                    // Remove highlight

                    pmunt->Hilight(false);

					// Start the replicating animation

					m_fReplicating = true;
					m_ifrmLights = -1;

					MobileUnitGob *pmuntClone = (MobileUnitGob *)CreateGob(pmunt->GetType());
					if (pmuntClone != NULL) {
						pmuntClone->Init(WcFromTc(tpt.tx + kdtxReplicatorOutput2), WcFromTc(tpt.ty + kdtyReplicatorOutput2), pmunt->GetOwner(), pmunt->GetHealth(), 0, NULL);

						// Clone acquires the selection state of the original

						if (pmunt->GetFlags() & kfGobSelected)
							pmuntClone->Select(true);

						// Replicated GalaxMiners lose their load of Galaxite
						// UNDONE: if there is more of this special casing go with virtual UnitGob::Replicate()

						if (pmunt->GetType() == kgtGalaxMiner)
							((MinerGob *)pmunt)->SetGalaxiteAmount(0);

						// If this unit is a member of a group add its clone to the group too

						UnitGroup *pug = gsim.GetLevel()->GetUnitGroupMgr()->GetUnitGroup(pmunt->GetId());
						if (pug != NULL)
							pug->AddUnit(pmuntClone, true);
					}

					// Warp the original Unit to the left output port

					TerrainMap *ptrmap = gsim.GetLevel()->GetTerrainMap();
					ptrmap->ClearFlags(tpt.tx + kdtxReplicatorInput, tpt.ty + kdtyReplicatorInput, 1, 1, kbfMobileUnit);
					ptrmap->SetFlags(tpt.tx + kdtxReplicatorOutput1, tpt.ty + kdtyReplicatorOutput1, 1, 1, kbfMobileUnit);
					pmunt->SetPosition(WcFromTc(tpt.tx + kdtxReplicatorOutput1) + kwcTileHalf, WcFromTc(tpt.ty + kdtyReplicatorOutput1) + kwcTileHalf);

					// Clear the bit

					pmunt->SetMobileUnitFlags(pmunt->GetMobileUnitFlags() & ~kfMuntAtReplicatorInput);

					// Let player know the replication process has happened
					// play cool replication sound effect

					gsndm.PlaySfx(ksfxReplicatorBuild);

					// wait a quarter second and let the new unit announce itself

					Sfx sfx = SfxFromCategory(pmuntc->sfxcSelect);
					Message msgT;
					memset(&msgT, 0, sizeof(msgT));
					msgT.mid = kmidPlaySfx;
					msgT.smidSender = m_gid;
					msgT.smidReceiver = m_gid;
					msgT.PlaySfx.sfx = sfx;
					gsmm.SendDelayedMsg(&msgT, 24);

					// Play it again in another quarter of a second to sound cool

					memset(&msgT, 0, sizeof(msgT));
					msgT.mid = kmidPlaySfx;
					msgT.smidSender = m_gid;
					msgT.smidReceiver = m_gid;
					msgT.PlaySfx.sfx = sfx;
					gsmm.SendDelayedMsg(&msgT, 48);
					break;
				}
			}

			if (m_fReplicating) {
				m_ifrmLights++;
				int nStrip = m_pmuntc->panid->GetStripIndex("l 0");
				if (m_ifrmLights / 2 >= m_pmuntc->panid->GetFrameCount(nStrip)) {
					m_ifrmLights = -1;
					m_fReplicating = false;
				}
				MarkRedraw();
			}
			WaitingForCredits(pplrNeedCredits != NULL, false, pplrNeedCredits);
			m_unvl.MinSkip();
			DefUpdate();

#if 0
EndStateMachineInherit(StructGob)
#else
            return knHandled;
        }