Skip to content

Instantly share code, notes, and snippets.

@sigsegv-mvm
Created April 8, 2017 00:56
Show Gist options
  • Save sigsegv-mvm/a6d5414132c4a00386f7ddc497ea1351 to your computer and use it in GitHub Desktop.
Save sigsegv-mvm/a6d5414132c4a00386f7ddc497ea1351 to your computer and use it in GitHub Desktop.
Full reverse assembly of class CHeadlessHatmanBody
// CHeadlessHatmanBody
// Full RE by sigsegv on 20170407
// Based on TF2 version 20151007a
// sizeof: 0x20
class CHeadlessHatmanBody : public IBody
{
public:
CHeadlessHatmanBody(INextBot *pNextBot) : IBody(pNextBot) {}
virtual ~CHeadlessHatmanBody() {}
virtual void Update() override;
virtual bool StartActivity(Activity iActivity, unsigned int nActivityType) override;
virtual Activity GetActivity() const override { return this->m_iActivity; }
virtual bool IsActivity(Activity iActivity) const override { return (iActivity == this->m_iActivity); }
virtual unsigned int GetSolidMask() const override { return (MASK_NPCSOLID | MASK_PLAYERSOLID); }
private:
Activity m_iActivity = ACT_INVALID; // +0x0014
int m_iPoseMoveX = -1; // +0x0018
int m_iPoseMoveY = -1; // +0x001c
};
void CHeadlessHatmanBody::Update()
{
auto pHatman = static_cast<CHeadlessHatman *>(this->GetBot()->GetEntity());
if (this->m_iPoseMoveX < 0) {
this->m_iPoseMoveX = pHatman->LookupPoseParameter(pHatman->GetModelPtr(), "move_x");
}
if (this->m_iPoseMoveY < 0) {
this->m_iPoseMoveY = pHatman->LookupPoseParameter(pHatman->GetModelPtr(), "move_y");
}
float flNextBotGroundSpeed = this->GetLocomotionInterface()->GetGroundSpeed();
if (flNextBotGroundSpeed < 0.01f) {
if (this->m_iPoseMoveX >= 0) {
pHatman->SetPoseParameter(pHatman->GetModelPtr(), this->m_iPoseMoveX, 0.0f);
}
if (this->m_iPoseMoveY >= 0) {
pHatman->SetPoseParameter(pHatman->GetModelPtr(), this->m_iPoseMoveY, 0.0f);
}
} else {
Vector vecFwd, vecRight, vecUp;
pHatman->GetVectors(&vecFwd, &vecRight, &vecUp);
const Vector& vecMotion = this->GetBot()->GetLocomotionInterface()->GetGroundMotionVector();
if (this->m_iPoseMoveX >= 0) {
pHatman->SetPoseParameter(pHatman->GetModelPtr(), this->m_iPoseMoveX, DotProduct(vecMotion, vecFwd));
}
if (this->m_iPoseMoveY >= 0) {
pHatman->SetPoseParameter(pHatman->GetModelPtr(), this->m_iPoseMoveY, DotProduct(vecMotion, vecRight));
}
}
// this if statement is here to avoid dividing by zero; as a side-effect,
// m_flPlaybackRate will not be set to zero if m_flGroundSpeed is zero
if (pHatman->m_flGroundSpeed != 0.0f) {
pHatman->SetPlaybackRate(clamp((flNextBotGroundSpeed / pHatman->m_flGroundSpeed), -4.0f, 12.0f));
}
pHatman->StudioFrameAdvance();
pHatman->DispatchAnimEvents(pHatman);
}
bool CHeadlessHatmanBody::StartActivity(Activity iActivity, unsigned int nActivityType)
{
auto pHatman = static_cast<CHeadlessHatman *>(this->GetBot()->GetEntity());
int nSequence = pHatman->SelectWeightedSequence();
if (nSequence == 0) return false;
this->m_iActivity = iActivity;
pHatman->SetSequence(nSequence);
pHatman->SetPlaybackRate(1.0f);
pHatman->SetCycle(0.0f);
pHatman->ResetSequenceInfo();
return true;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment