mirror of
https://github.com/spiffcode/hostile-takeover.git
synced 2025-12-23 06:57:23 +00:00
565 lines
16 KiB
C++
565 lines
16 KiB
C++
#include "ht.h"
|
|
#include "wistrings.h"
|
|
|
|
namespace wi {
|
|
|
|
//
|
|
// ReplicatorGob implementation
|
|
//
|
|
|
|
static AnimationData *s_panidActivator = NULL;
|
|
static BuilderConsts gConsts;
|
|
|
|
#if defined(DEBUG_HELPERS)
|
|
char *ReplicatorGob::GetName()
|
|
{
|
|
return "Replicator";
|
|
}
|
|
#endif
|
|
|
|
bool ReplicatorGob::InitClass(IniReader *pini)
|
|
{
|
|
gConsts.gt = kgtReplicator;
|
|
gConsts.ut = kutReplicator;
|
|
|
|
// Sound effects
|
|
gConsts.sfxUnitReady = ksfxReplicatorBuild;
|
|
|
|
#if 0
|
|
gConsts.sfxPowerOn = ksfxReplicatorOn;
|
|
gConsts.sfxPowerOff = ksfxReplicatorOff;
|
|
gConsts.sfxUnitBuildAbort = ksfxReplicatorAbortRecruiting;
|
|
gConsts.sfxUnitReady = ksfxReplicatorUnitReady;
|
|
gConsts.sfxAbortRepair = ksfxReplicatorAbortRepair;
|
|
gConsts.sfxDamaged = ksfxReplicatorDamaged;
|
|
gConsts.sfxDestroyed = ksfxReplicatorDestroyed;
|
|
gConsts.sfxRepair = ksfxReplicatorRepair;
|
|
gConsts.sfxSelect = ksfxReplicatorSelect;
|
|
#endif
|
|
|
|
// Preload the Activator animation data
|
|
|
|
if (s_panidActivator == NULL) {
|
|
s_panidActivator = LoadAnimationData("activator.anir");
|
|
if (s_panidActivator == NULL)
|
|
return false;
|
|
}
|
|
|
|
return StructGob::InitClass(&gConsts, pini);
|
|
}
|
|
|
|
void ReplicatorGob::ExitClass()
|
|
{
|
|
delete s_panidActivator;
|
|
s_panidActivator = NULL;
|
|
|
|
StructGob::ExitClass(&gConsts);
|
|
}
|
|
|
|
ReplicatorGob::ReplicatorGob() : StructGob(&gConsts)
|
|
{
|
|
m_fEnabled = false;
|
|
m_fReplicating = false;
|
|
m_pplrNeedCredits = NULL;
|
|
}
|
|
|
|
bool ReplicatorGob::Init(WCoord wx, WCoord wy, Player *pplr, fix fxHealth, dword ff, const char *pszName)
|
|
{
|
|
if (!StructGob::Init(wx, wy, pplr, fxHealth, ff, pszName))
|
|
return false;
|
|
|
|
// Clear out the Replicator's entrance and exits
|
|
|
|
TerrainMap *ptrmap = gsim.GetLevel()->GetTerrainMap();
|
|
ptrmap->ClearFlags(TcFromWc(m_wx) + kdtxReplicatorInput, TcFromWc(m_wy) + kdtyReplicatorInput, 1, 1, kbfStructure);
|
|
ptrmap->ClearFlags(TcFromWc(m_wx) + kdtxReplicatorOutput1 - 1, TcFromWc(m_wy) + kdtyReplicatorOutput1 + 1, 1, 2, kbfStructure);
|
|
ptrmap->ClearFlags(TcFromWc(m_wx) + kdtxReplicatorOutput2 + 1, TcFromWc(m_wy) + kdtyReplicatorOutput2 + 1, 1, 2, kbfStructure);
|
|
|
|
return true;
|
|
}
|
|
|
|
#define knVerReplicatorGobState 3
|
|
bool ReplicatorGob::LoadState(Stream *pstm)
|
|
{
|
|
byte nVer = pstm->ReadByte();
|
|
if (nVer != knVerReplicatorGobState)
|
|
return false;
|
|
m_fEnabled = pstm->ReadByte() != 0;
|
|
m_fReplicating = pstm->ReadByte() != 0;
|
|
m_ifrmLights = pstm->ReadByte();
|
|
s_cReplicators = pstm->ReadWord();
|
|
pstm->Read(s_atptInput, sizeof(s_atptInput));
|
|
Pid pid = pstm->ReadWord();
|
|
if (pid != kpidNeutral)
|
|
m_pplrNeedCredits = gplrm.GetPlayerFromPid(pid);
|
|
|
|
return StructGob::LoadState(pstm);
|
|
}
|
|
|
|
bool ReplicatorGob::SaveState(Stream *pstm)
|
|
{
|
|
pstm->WriteByte(knVerReplicatorGobState);
|
|
pstm->WriteByte(m_fEnabled);
|
|
pstm->WriteByte(m_fReplicating);
|
|
pstm->WriteByte(m_ifrmLights);
|
|
pstm->WriteWord(s_cReplicators);
|
|
pstm->Write(s_atptInput, sizeof(s_atptInput));
|
|
Pid pid = m_pplrNeedCredits == NULL ? kpidNeutral : m_pplrNeedCredits->GetId();
|
|
pstm->WriteWord(pid);
|
|
|
|
return StructGob::SaveState(pstm);
|
|
}
|
|
|
|
void ReplicatorGob::GetClippingBounds(Rect *prc)
|
|
{
|
|
// Union of the two strips that combine to form the Replicator image
|
|
|
|
m_pstruc->panid->GetBounds(0, 0, prc);
|
|
Rect rcT;
|
|
m_pstruc->panid->GetBounds(1, 0, &rcT);
|
|
prc->Union(&rcT);
|
|
|
|
// If selected, union with that rect
|
|
|
|
if (gwfPerfOptions & kfPerfSelectionBrackets) {
|
|
if (m_ff & kfGobSelected) {
|
|
Rect rcSel;
|
|
rcSel.FromWorldRect(&m_pstruc->wrcUIBounds);
|
|
// rcSel.top -= kcyHealthBar;
|
|
prc->Union(&rcSel);
|
|
}
|
|
}
|
|
|
|
prc->Offset(PcFromUwc(m_wx), PcFromUwc(m_wy));
|
|
}
|
|
|
|
void ReplicatorGob::Draw(DibBitmap *pbm, int xViewOrigin, int yViewOrigin, int nLayer)
|
|
{
|
|
if (nLayer == knLayerDepthSorted) {
|
|
int x = PcFromUwc(m_wx) - xViewOrigin;
|
|
int y = PcFromUwc(m_wy) - yViewOrigin;
|
|
|
|
Side side = m_pplr->GetSide();
|
|
if (m_ff & kfGobDrawFlashed)
|
|
side = (Side)-1;
|
|
|
|
m_ani.SetFrame(0);
|
|
m_ani.SetStrip(m_fEnabled ? 2 : 0);
|
|
m_ani.Draw(pbm, x, y, side);
|
|
m_ani.SetStrip(m_fEnabled ? 3 : 1);
|
|
#if defined(IPHONE) || defined(SDL)
|
|
// When this is scaled up by 1 1/3 (scaling 24 art to 32),
|
|
// the upper right quadrant piece is 55 high, which translates after
|
|
// rounding to 73, yet the lower right quad piece wants to go at
|
|
// location 56 (effectively) which scales to 75, so there is a gap.
|
|
|
|
m_ani.Draw(pbm, x, y - 1, side); // ugly hack
|
|
#else
|
|
m_ani.Draw(pbm, x, y, side);
|
|
#endif
|
|
|
|
if (m_fReplicating) {
|
|
m_ani.SetStrip(m_pmuntc->panid->GetStripIndex("l 0"));
|
|
m_ani.SetFrame(m_ifrmLights / 2);
|
|
m_ani.Draw(pbm, x, y, side);
|
|
}
|
|
|
|
} else if (nLayer == knLayerSelection) {
|
|
if (m_ff & kfGobSelected) {
|
|
Rect rcT;
|
|
rcT.FromWorldRect(&m_puntc->wrcUIBounds);
|
|
rcT.Offset(-xViewOrigin + PcFromWc(m_wx), -yViewOrigin + PcFromWc(m_wy));
|
|
DrawSelectionIndicator(pbm, &rcT, m_fxHealth, m_puntc->GetArmorStrength());
|
|
}
|
|
|
|
} else {
|
|
StructGob::Draw(pbm, xViewOrigin, yViewOrigin, nLayer);
|
|
}
|
|
}
|
|
|
|
void ReplicatorGob::GetInputTilePosition(TPoint *ptpt)
|
|
{
|
|
GetTilePosition(ptpt);
|
|
ptpt->tx += kdtxReplicatorInput;
|
|
ptpt->ty += kdtyReplicatorInput;
|
|
}
|
|
|
|
void ReplicatorGob::Enable(bool fEnable)
|
|
{
|
|
if (m_fEnabled != fEnable) {
|
|
gsndm.PlaySfx(fEnable ? ksfxReplicatorOn : ksfxReplicatorOff);
|
|
m_fEnabled = fEnable;
|
|
MarkRedraw();
|
|
}
|
|
}
|
|
|
|
void ReplicatorGob::Activate()
|
|
{
|
|
TPoint tpt;
|
|
GetTilePosition(&tpt);
|
|
AddReplicatorInputPoint(tpt.tx + kdtxReplicatorInput, tpt.ty + kdtyReplicatorInput);
|
|
StructGob::Activate();
|
|
}
|
|
|
|
void ReplicatorGob::Deactivate()
|
|
{
|
|
TPoint tpt;
|
|
GetTilePosition(&tpt);
|
|
RemoveReplicatorInputPoint(tpt.tx + kdtxReplicatorInput, tpt.ty + kdtyReplicatorInput);
|
|
StructGob::Deactivate();
|
|
}
|
|
|
|
bool ReplicatorGob::ClearOutputBay(TCoord txBay, TCoord tyBay, TCoord txOut, TCoord tyOut)
|
|
{
|
|
for (Gid gid = ggobm.GetFirstGid(txBay, tyBay); gid != kgidNull; gid = ggobm.GetNextGid(gid)) {
|
|
MobileUnitGob *pmunt = (MobileUnitGob *)ggobm.GetGob(gid);
|
|
if (pmunt == NULL)
|
|
continue;
|
|
if (!(pmunt->GetFlags() & kfGobMobileUnit))
|
|
continue;
|
|
|
|
// Don't ask it to move if it is already trying to
|
|
|
|
if (pmunt->IsReadyForCommand() && !pmunt->IsMobile()) {
|
|
Message msgT;
|
|
msgT.mid = kmidMoveCommand;
|
|
msgT.smidSender = m_gid;
|
|
msgT.smidReceiver = pmunt->GetId();
|
|
msgT.MoveCommand.wptTarget.wx = WcFromTc(txOut) + kwcTileHalf;
|
|
msgT.MoveCommand.wptTarget.wy = WcFromTc(tyOut) + kwcTileHalf;
|
|
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 *)pmunt->GetConsts())->GetMoveDistPerUpdate();
|
|
gsmm.SendMsg(&msgT);
|
|
}
|
|
|
|
// Jammed
|
|
|
|
return true;
|
|
}
|
|
|
|
// Maybe a unit is moving into the output bay (i.e., it is jammed)
|
|
|
|
if (!IsTileFree(txBay, tyBay, kbfMobileUnit))
|
|
return true; // jammed
|
|
|
|
// Open
|
|
|
|
return false;
|
|
}
|
|
|
|
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;
|
|
}
|
|
} else {
|
|
return (int)StructGob::ProcessStateMachineMessage(st, pmsg);
|
|
}
|
|
return (int)StructGob::ProcessStateMachineMessage(st, pmsg);
|
|
#endif
|
|
}
|
|
|
|
void ReplicatorGob::WaitingForCredits(bool fNeed, bool fOverride, Player *pplr)
|
|
{
|
|
// we need to be using the unit's player, not our own. Remember so when the unit
|
|
// disappears we can decrement the right player's count
|
|
|
|
if (fNeed) {
|
|
Assert((m_pplrNeedCredits == NULL) || (m_pplrNeedCredits == pplr) || (fOverride));
|
|
if (fOverride)
|
|
pplr = m_pplrNeedCredits;
|
|
else
|
|
m_pplrNeedCredits = pplr;
|
|
} else {
|
|
Assert(pplr == NULL);
|
|
pplr = m_pplrNeedCredits;
|
|
m_pplrNeedCredits = NULL;
|
|
}
|
|
|
|
StructGob::WaitingForCredits(fNeed, fOverride, pplr);
|
|
}
|
|
|
|
|
|
// Replicator input point management
|
|
|
|
int ReplicatorGob::s_cReplicators;
|
|
TPoint ReplicatorGob::s_atptInput[10];
|
|
|
|
void ReplicatorGob::AddReplicatorInputPoint(TCoord tx, TCoord ty)
|
|
{
|
|
Assert(s_cReplicators < ARRAYSIZE(s_atptInput) - 1);
|
|
if (s_cReplicators >= ARRAYSIZE(s_atptInput) - 1)
|
|
return;
|
|
s_atptInput[s_cReplicators].tx = tx;
|
|
s_atptInput[s_cReplicators].ty = ty;
|
|
s_cReplicators++;
|
|
}
|
|
|
|
void ReplicatorGob::RemoveReplicatorInputPoint(TCoord tx, TCoord ty)
|
|
{
|
|
for (int n = 0; n < ARRAYSIZE(s_atptInput); n++) {
|
|
if (s_atptInput[n].tx == tx && s_atptInput[n].ty) {
|
|
memmove(&s_atptInput[n], &s_atptInput[n + 1], (s_cReplicators - n - 1) * ELEMENTSIZE(s_atptInput));
|
|
s_cReplicators--;
|
|
return;
|
|
}
|
|
}
|
|
Assert();
|
|
}
|
|
|
|
//
|
|
// ActivatorGob implementation
|
|
//
|
|
|
|
#if defined(DEBUG_HELPERS)
|
|
char *ActivatorGob::GetName()
|
|
{
|
|
return "Activator";
|
|
}
|
|
#endif
|
|
|
|
bool ActivatorGob::Init(IniReader *pini, FindProp *pfind, const char *pszName)
|
|
{
|
|
int side, tx, ty;
|
|
int cArgs = pini->GetPropertyValue(pfind, "%*d ,%d ,%d ,%d", &side, &tx, &ty);
|
|
if (cArgs < 3) {
|
|
Assert("ActivatorGob requires at least 3 valid initialization parameters");
|
|
return false;
|
|
}
|
|
|
|
// Keep players from building on top of Activators
|
|
|
|
gsim.GetLevel()->GetTerrainMap()->SetFlags(tx, ty, 1, 1, kbfReserved);
|
|
|
|
return AnimGob::Init(WcFromTc(tx), WcFromTc(ty), kfAnmLoop | kfAnmSurfaceDecalLayer, NULL, s_panidActivator, 0, ksmidNull, pszName);
|
|
}
|
|
|
|
#define knVerActivatorGobState 1
|
|
bool ActivatorGob::LoadState(Stream *pstm)
|
|
{
|
|
byte nVer = pstm->ReadByte();
|
|
if (nVer != knVerActivatorGobState)
|
|
return false;
|
|
m_fActivated = pstm->ReadByte() != 0;
|
|
m_ani.Init(s_panidActivator);
|
|
m_ani.LoadState(pstm);
|
|
m_wfAnm = kfAnmLoop | kfAnmSurfaceDecalLayer;
|
|
return AnimGob::LoadState(pstm);
|
|
}
|
|
|
|
bool ActivatorGob::SaveState(Stream *pstm)
|
|
{
|
|
pstm->WriteByte(knVerActivatorGobState);
|
|
pstm->WriteByte(m_fActivated);
|
|
m_ani.SaveState(pstm);
|
|
return AnimGob::SaveState(pstm);
|
|
}
|
|
|
|
bool ActivatorGob::IsSavable()
|
|
{
|
|
// Because AnimGob is not savable, we need to override
|
|
|
|
return true;
|
|
}
|
|
|
|
GobType ActivatorGob::GetType()
|
|
{
|
|
return kgtActivator;
|
|
}
|
|
|
|
int ActivatorGob::ProcessStateMachineMessage(State st, Message *pmsg)
|
|
{
|
|
BeginStateMachine
|
|
OnUpdate
|
|
bool fActivated = false;
|
|
for (Gid gid = ggobm.GetFirstGid(TcFromWc(m_wx), TcFromWc(m_wy)); gid != kgidNull; gid = ggobm.GetNextGid(gid)) {
|
|
MobileUnitGob *pmunt = (MobileUnitGob *)ggobm.GetGob(gid);
|
|
if (pmunt == NULL)
|
|
continue;
|
|
if (!(pmunt->GetFlags() & kfGobMobileUnit))
|
|
continue;
|
|
fActivated = true;
|
|
break;
|
|
}
|
|
|
|
if (fActivated != m_fActivated) {
|
|
m_fActivated = fActivated;
|
|
StartAnimation(&m_ani, fActivated ? 1 : 0, 0, kfAniLoop | kfAnmSurfaceDecalLayer);
|
|
gsndm.PlaySfx(fActivated ? ksfxActivatorOn : ksfxActivatorOff);
|
|
|
|
}
|
|
|
|
// Check every 3 updates for the presence of a MobileUnit on top of the Activator
|
|
|
|
m_unvl.MinSkip(3);
|
|
|
|
return AnimGob::ProcessStateMachineMessage(st, pmsg);
|
|
|
|
#if 0
|
|
EndStateMachineInherit(AnimGob)
|
|
#else
|
|
return knHandled;
|
|
}
|
|
} else {
|
|
return (int)AnimGob::ProcessStateMachineMessage(st, pmsg);
|
|
}
|
|
return (int)AnimGob::ProcessStateMachineMessage(st, pmsg);
|
|
#endif
|
|
}
|
|
|
|
} // namespace wi
|