hostile-takeover/game/SRInfantry.cpp
2014-07-06 17:47:28 -07:00

220 lines
4.7 KiB
C++

#include "ht.h"
namespace wi {
static MobileUnitConsts gConsts;
#if defined(DEBUG_HELPERS)
char *SRInfantryGob::GetName()
{
return "SRInfantry";
}
#endif
static int s_anFiringStripIndices[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
static int s_anMovingStripIndices[8] = { 17, 18, 19, 20, 21, 22, 23, 24 };
static int s_anIdleStripIndices[8] = { 9, 10, 11, 12, 13, 14, 15, 16 };
bool SRInfantryGob::InitClass(IniReader *pini)
{
gConsts.gt = kgtShortRangeInfantry;
gConsts.ut = kutShortRangeInfantry;
gConsts.wf |= kfUntcNotifyEnemyNearby;
// Initialize the frame indices arrays
gConsts.anFiringStripIndices = s_anFiringStripIndices;
gConsts.anMovingStripIndices = s_anMovingStripIndices;
gConsts.anIdleStripIndices = s_anIdleStripIndices;
// Sound effects
gConsts.sfxFire = ksfxMachineGunInfantryFire;
gConsts.sfxImpact = ksfxNothing;
gConsts.sfxcDestroyed = ksfxcInfantryDestroyed;
gConsts.sfxcSelect = ksfxcMale03Select;
gConsts.sfxcMove = ksfxcMale03Move;
gConsts.sfxcAttack = ksfxcMale03Attack;
return MobileUnitGob::InitClass(&gConsts, pini);
}
void SRInfantryGob::ExitClass()
{
MobileUnitGob::ExitClass(&gConsts);
}
SRInfantryGob::SRInfantryGob() : MobileUnitGob(&gConsts)
{
}
bool SRInfantryGob::Fire(UnitGob *puntTarget, WCoord wx, WCoord wy, WCoord wdx, WCoord wdy)
{
// MobileUnitGob handles rotating towards the target, firing delay,
// and starting the fire animation
if (!MobileUnitGob::Fire(puntTarget, wx, wy, wdx, wdy))
return false;
// Fire off the shot!
WCoord wdxRnd = ((GetRandom() & 7) - 3) * kwcTile16th;
WCoord wdyRnd = ((GetRandom() & 7) - 3) * kwcTile16th;
Point ptSpecial;
m_ani.GetSpecialPoint(&ptSpecial, 1); // frame #1 (second frame) has the firing point
CreateBulletGob(m_wx + WcFromPc(ptSpecial.x), m_wy + WcFromPc(ptSpecial.y), wx + wdxRnd, wy + wdyRnd,
GetDamageTo(puntTarget), m_gid, puntTarget->GetId());
// Play sound
gsndm.PlaySfx(m_pmuntc->sfxFire);
return true;
}
void SRInfantryGob::Idle()
{
// 1/4 of the time we pivot left, 1/4 we pivot right, and 1/2 we play the idle
switch (GetRandom() & 3) {
case 0:
m_dir--;
if (m_dir < 0)
m_dir = 7;
StartAnimation(&m_ani, m_pmuntc->anIdleStripIndices[m_dir], 0, kfAniResetWhenDone);
break;
case 1:
m_dir++;
if (m_dir > 7)
m_dir = 0;
StartAnimation(&m_ani, m_pmuntc->anIdleStripIndices[m_dir], 0, kfAniResetWhenDone);
break;
default:
StartAnimation(&m_ani, m_pmuntc->anIdleStripIndices[m_dir], 0, kfAniResetWhenDone);
break;
}
}
int SRInfantryGob::ProcessStateMachineMessage(State st, Message *pmsg)
{
BeginStateMachine
State(kstDying)
OnEnter
TRect trc;
GetTileRect(&trc);
Deactivate();
// Redraw this part of minimap. It will skip inactive munts
gpmm->RedrawTRect(&trc);
m_ff ^= kfGobLayerDepthSorted | kfGobLayerSurfaceDecal;
gsndm.PlaySfx(SfxFromCategory(m_pmuntc->sfxcDestroyed));
m_ani.Start("die 3", kfAniIgnoreFirstAdvance);
MarkRedraw();
// Remove corpse after 10 seconds
gsmm.SendDelayedMsg(kmidDelete, 1000, m_gid, m_gid);
OnUpdate
AdvanceAnimation(&m_ani);
#if 0
EndStateMachineInherit(MobileUnitGob)
#else
return knHandled;
}
} else {
return (int)MobileUnitGob::ProcessStateMachineMessage(st, pmsg);
}
return (int)MobileUnitGob::ProcessStateMachineMessage(st, pmsg);
#endif
}
#if 0 // Not used anymore
//
// RicochetGob implementation
//
bool RicochetGob::Init(WCoord wx, WCoord wy, word wfAnm, const char *pszAniName, AnimationData *panid,
StateMachineId smidNotify, const char *pszName)
{
if (!AnimGob::Init(wx, wy, wfAnm, pszAniName, panid, GetRandom() % 3, smidNotify, pszName))
return false;
m_fNew = true;
return true;
}
bool RicochetGob::OnStripDone()
{
if (m_fNew) {
m_fNew = false;
SetAnimationStrip(&m_ani, GetRandom() % 3);
return false;
} else {
return true;
}
}
#endif
//
// BulletGob implementation
//
AnimationData *BulletGob::s_panidShot = NULL;
// this will actually create & fire
BulletGob *CreateBulletGob(WCoord wx, WCoord wy, WCoord wxTarget, WCoord wyTarget, int nDamage, Gid gidOwner, Gid gidTarget, bool fEagle)
{
if (!ggobm.IsBelowLimit(knLimitSupport))
return NULL;
BulletGob *pgob = new BulletGob();
Assert(pgob != NULL, "out of memory!");
if (pgob == NULL)
return NULL;
if (!pgob->Init(BulletGob::s_panidShot, wx, wy, wxTarget, wyTarget, nDamage, gidOwner, gidTarget, kwcTile)) {
delete pgob;
return NULL;
}
pgob->Launch();
return pgob;
}
bool BulletGob::InitClass(IniReader *pini)
{
s_panidShot = LoadAnimationData("bullet.anir");
if (s_panidShot == NULL)
return false;
return true;
}
void BulletGob::ExitClass()
{
delete s_panidShot;
s_panidShot = NULL;
}
GobType BulletGob::GetType()
{
return kgtBullet;
}
#if defined(DEBUG_HELPERS)
char *BulletGob::GetName()
{
return "Bullet";
}
#endif
} // namespace wi