mirror of
https://github.com/spiffcode/hostile-takeover.git
synced 2025-12-16 12:08:36 +00:00
217 lines
6.4 KiB
C++
217 lines
6.4 KiB
C++
#include "ht.h"
|
|
|
|
namespace wi {
|
|
|
|
//
|
|
// MobileUnitBuilderGob implementation
|
|
// base gob for VTS and HRC
|
|
//
|
|
|
|
#if defined(DEBUG_HELPERS)
|
|
char *MobileUnitBuilderGob::GetName()
|
|
{
|
|
return "MobileUnitBuilder";
|
|
}
|
|
#endif
|
|
|
|
MobileUnitBuilderGob::MobileUnitBuilderGob(MobileUnitBuilderConsts *pmubc) : BuilderGob(pmubc)
|
|
{
|
|
m_puntc->wf |= kfUntcNotifyPowerLowHigh;
|
|
}
|
|
|
|
void MobileUnitBuilderGob::Draw(DibBitmap *pbm, int xViewOrigin, int yViewOrigin, int nLayer)
|
|
{
|
|
// UNDONE: rethink this
|
|
bool fUpgraded = (m_pplr->GetUpgrades() & ((MobileUnitBuilderConsts *)m_puntc)->fUpgrade) != 0;
|
|
if (fUpgraded)
|
|
SetAnimationStrip(&m_ani, m_ani.GetStrip() + 3);
|
|
|
|
BuilderGob::Draw(pbm, xViewOrigin, yViewOrigin, nLayer);
|
|
|
|
if ((nLayer == knLayerDepthSorted) && ((m_pplr->GetUpgrades() & ((MobileUnitBuilderConsts *)m_puntc)->fUpgradeInProgress) != 0))
|
|
BuilderGob::DrawUpgradeEffect(pbm, xViewOrigin, yViewOrigin);
|
|
|
|
if (fUpgraded)
|
|
SetAnimationStrip(&m_ani, m_ani.GetStrip() - 3);
|
|
}
|
|
|
|
void MobileUnitBuilderGob::InitMenu(Form *pfrm)
|
|
{
|
|
Control *pctl = pfrm->GetControlPtr(kidcBuild);
|
|
pctl->Enable((m_pplr->GetUpgrades() & ((MobileUnitBuilderConsts *)m_pmuntc)->fUpgradeInProgress) != ((MobileUnitBuilderConsts *)m_puntc)->fUpgradeInProgress);
|
|
|
|
BuilderGob::InitMenu(pfrm);
|
|
}
|
|
|
|
void MobileUnitBuilderGob::OnMenuItemSelected(int idc)
|
|
{
|
|
switch (idc) {
|
|
case kidcBuild:
|
|
gpmfrmm->AddForm(((MobileUnitBuilderConsts *)m_puntc)->pfrmBuild);
|
|
((MobileUnitBuilderConsts *)m_puntc)->pfrmBuild->SetOwner(this);
|
|
((MobileUnitBuilderConsts *)m_puntc)->pfrmBuild->DoModal();
|
|
gpmfrmm->RemoveForm(((MobileUnitBuilderConsts *)m_puntc)->pfrmBuild);
|
|
break;
|
|
|
|
default:
|
|
BuilderGob::OnMenuItemSelected(idc);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void MobileUnitBuilderGob::Takeover(Player *pplr)
|
|
{
|
|
// new owner gets to keep upgrades
|
|
|
|
pplr->SetUpgrades(pplr->GetUpgrades() | (m_pplr->GetUpgrades() & ((MobileUnitBuilderConsts *)m_puntc)->fUpgrade));
|
|
BuilderGob::Takeover(pplr);
|
|
}
|
|
|
|
void MobileUnitBuilderGob::Deactivate()
|
|
{
|
|
BuilderGob::Deactivate();
|
|
if (m_pmubc->pfrmBuild != NULL && m_pmubc->pfrmBuild->GetOwner() == this)
|
|
m_pmubc->pfrmBuild->EndForm();
|
|
}
|
|
|
|
int MobileUnitBuilderGob::ProcessStateMachineMessage(State st, Message *pmsg)
|
|
{
|
|
BeginStateMachine
|
|
OnEnter
|
|
SetState(kstIdle);
|
|
|
|
OnMsg(kmidBuildOtherCommand)
|
|
// Counts will already have been checked in the order UI. However since
|
|
// the order is queued, the UI only guesses if it is possible to build
|
|
// based on current state when the button is pressed. Here we make a
|
|
// bedrock decision. This ensures the limits are enforced and that the
|
|
// same decision gets made on all clients in a multiplayer game.
|
|
|
|
if (ggobm.IsBelowLimit(knLimitMobileUnit, m_pplr))
|
|
Build(pmsg->BuildOtherCommand.ut);
|
|
|
|
OnMsg(kmidAbortBuildOtherCommand)
|
|
// UNDONE: deal with queuing?
|
|
|
|
AbortBuild(true, pmsg->AbortBuildOtherCommand.ut);
|
|
|
|
OnMsg(kmidSelfDestructCommand)
|
|
// override and call abort build here so we can tell it to refund the
|
|
// value. AbortBuild is also in BuilderGob::Deactivate but will do
|
|
// nothing if called a 2nd time, and there it wouldnt refund if we left
|
|
// it
|
|
|
|
AbortBuild(true);
|
|
SelfDestruct();
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
State(kstIdle)
|
|
OnMsg(kmidUpgradeComplete)
|
|
// Redraw to get rid of the upgrade graphics
|
|
|
|
m_ff &= ~kfGobBeingUpgraded;
|
|
MarkRedraw();
|
|
|
|
OnMsg(kmidBeingUpgraded)
|
|
// Wake up so the animation can occur
|
|
|
|
m_ff |= kfGobBeingUpgraded;
|
|
m_unvl.MinSkip();
|
|
|
|
OnUpdate
|
|
// Invalidate if upgrading is occuring so that this gob can draw the upgrade
|
|
// effect.
|
|
|
|
if (m_pplr->GetUpgrades() & ((MobileUnitBuilderConsts *)m_puntc)->fUpgradeInProgress) {
|
|
// Smallest interval so we can keep invalidating ourselves while being upgraded
|
|
|
|
MarkRedraw();
|
|
m_unvl.MinSkip();
|
|
}
|
|
|
|
return BuilderGob::ProcessStateMachineMessage(st, pmsg);
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
State(kstBuildOtherCompleting)
|
|
OnEnter
|
|
// init built Gob
|
|
{
|
|
UnitGob *puntBuild = GetBuiltGob();
|
|
if (puntBuild != NULL) {
|
|
WPoint wpt;
|
|
FindInitPosition(&wpt);
|
|
puntBuild->Init(wpt.wx, wpt.wy, m_pplr, 0, 0, NULL);
|
|
|
|
// If this is a Bullpup built by a human player send it off to mine.
|
|
|
|
if (!(m_pplr->GetFlags() & kfPlrComputer) && puntBuild->GetType() == kgtGalaxMiner) {
|
|
SendMineCommand(puntBuild->GetId(), kwxInvalid, 0);
|
|
|
|
} else {
|
|
#ifdef RALLY_POINTS
|
|
/*
|
|
UNDONE: issues with rally points
|
|
- rally point needs to be visible when the Builder is selected (e.g., flag)
|
|
- units are vulnerable along the way. Need to attack-move (respond to being hit, then continue to rally point)
|
|
- can't set rally point on the Replicator
|
|
x need to know when to send a unit to the rally point (e.g., it's not at the default value)
|
|
x units force others out of the way to get to the rally point
|
|
*/
|
|
// If the rally point is not at the default, send the new unit there
|
|
|
|
if (m_tptRally.tx != ktxInvalid) {
|
|
Message msgT;
|
|
msgT.mid = kmidMoveCommand;
|
|
msgT.smidSender = m_gid;
|
|
msgT.smidReceiver = puntBuild->GetId();
|
|
FindNearestFreeTile(m_tptRally.tx, m_tptRally.ty, &msgT.MoveCommand.wptTarget);
|
|
msgT.MoveCommand.gidTarget = kgidNull;
|
|
msgT.MoveCommand.wptTargetCenter.wx = msgT.MoveCommand.wptTarget.wx;
|
|
msgT.MoveCommand.wptTargetCenter.wy = msgT.MoveCommand.wptTarget.wy;
|
|
msgT.MoveCommand.tcTargetRadius = 0;
|
|
msgT.MoveCommand.wcMoveDistPerUpdate = ((MobileUnitConsts *)puntBuild->GetConsts())->GetMoveDistPerUpdate();
|
|
gsmm.SendMsg(&msgT);
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
// Notify the BuildMgr that this Unit is complete
|
|
|
|
gsim.GetBuildMgr()->OnBuilt(puntBuild, this);
|
|
((MobileUnitBuilderConsts *)m_puntc)->pfrmBuild->OnUnitCompleted(this, puntBuild->GetUnitType());
|
|
ClearBuiltGob();
|
|
}
|
|
SetState(kstIdle);
|
|
|
|
// These are here to keep the message from routing up to BuilderGob's message handler
|
|
OnUpdate
|
|
OnExit
|
|
|
|
#if 0
|
|
EndStateMachineInherit(BuilderGob)
|
|
#else
|
|
return knHandled;
|
|
}
|
|
} else {
|
|
return (int)BuilderGob::ProcessStateMachineMessage(st, pmsg);
|
|
}
|
|
return (int)BuilderGob::ProcessStateMachineMessage(st, pmsg);
|
|
#endif
|
|
}
|
|
|
|
void MobileUnitBuilderGob::DefUpdate()
|
|
{
|
|
// give the build form a chance to show progress
|
|
|
|
((MobileUnitBuilderConsts *)m_puntc)->pfrmBuild->DefUpdate(this, IsBuildInProgress());
|
|
|
|
// and continue with the normal idle processing
|
|
|
|
BuilderGob::DefUpdate();
|
|
}
|
|
|
|
} // namespace wi
|