void ReplicatorGob::Deactivate()
{
	TPoint tpt;
	GetTilePosition(&tpt);
	RemoveReplicatorInputPoint(tpt.tx + kdtxReplicatorInput, tpt.ty + kdtyReplicatorInput);
	StructGob::Deactivate();
}
Beispiel #2
0
	void GameMode::Update(std::chrono::system_clock::duration dt)
	{
		// Keyboard input
		for (int keyCode : mKeyboard->GetDownKeys())
		{

		}

		// Mouse input
		WORD x = mMouse->GetX();
		WORD y = mMouse->GetY();
		FG::MouseInput::BUTTON_STATE lButton = mMouse->GetLButtonState();
		FG::MouseInput::BUTTON_STATE rButton = mMouse->GetRButtonState();
		float wheel = mMouse->GetWheelValue();

		if (lButton == FG::MouseInput::BUTTON_DOWN)
		{
			Position tilePos = GetTilePosition(x, y);
			auto tile = mMap->GetTile(tilePos);
			auto units = mMap->GetUnits(tilePos);
			if (tile != nullptr)
			{
				if (units.size() == 0)
				{
					mSelectedUnit = nullptr;

					std::shared_ptr<FieldUnit> unit(new FieldUnit);
					unit->SetUnitType(FieldUnit::FU_CHRONO_MAGE);
					unit->SetTile(tile);
					mMap->AddUnit(unit);
				}
				else
				{
					mSelectedUnit = units[0];
				}
			}
		}

		// Map update
		mMap->ForeachTile([](Tile* tile)
		{
			
		});
		mMap->ForeachUnit([](FieldUnit* unit)
		{
			
		});
	}
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;
        }
void ReplicatorGob::GetInputTilePosition(TPoint *ptpt)
{
	GetTilePosition(ptpt);
	ptpt->tx += kdtxReplicatorInput;
	ptpt->ty += kdtyReplicatorInput;
}