void ReplicatorGob::Deactivate() { TPoint tpt; GetTilePosition(&tpt); RemoveReplicatorInputPoint(tpt.tx + kdtxReplicatorInput, tpt.ty + kdtyReplicatorInput); StructGob::Deactivate(); }
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; }