Skip to content

Commit

Permalink
Shadow Walker: Added default 'custom melee weapon'. If no weapons are…
Browse files Browse the repository at this point in the history
… supplied, the Shadow Walker will spawn with a crowbar with a custom model applied.
  • Loading branch information
1upD committed Oct 7, 2018
1 parent 77a3f1d commit 9602325
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 13 deletions.
5 changes: 3 additions & 2 deletions sp/game/mod_episodic/halloween.fgd
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@
//-------------------------------------------------------------------------
@NPCClass base(BaseNPC) studioprop() = npc_shadow_walker : "Shadow Walker"
[
additionalequipment(choices) : "Weapons" : "weapon_crowbar" : "It is recommended that the Shadow Walker be equipped with a melee weapon such as the crowbar or stunstick. The shotgun and Annabelle also work surprisingly well, but firing patterns have not been set up for automatic weapons." =
additionalequipment(choices) : "Weapons" : "0" : "It is recommended that the Shadow Walker be equipped with a melee weapon such as the crowbar or stunstick. The shotgun and Annabelle also work surprisingly well, but firing patterns have not been set up for automatic weapons." =
[
"0" : "Custom Melee Weapon"
"weapon_crowbar" : "Crow Bar"
"weapon_stunstick" : "Stun Stick"
"weapon_shotgun" : "Shotgun"
Expand All @@ -25,10 +26,10 @@
"weapon_ar2" : "AR2"
"weapon_smg1" : "SMG1"
"weapon_alyxgun" : "Alyx Gun"
"0" : "Nothing"
]

model(studio) : "World Model" : "models/monster/subject.mdl" : "You may specify any model for this NPC. However, the NPC was written with standard human animations in mind. Missing animations may cause errors. Be aware the animations of the model you choose will affect the NPC's behavior."
WeaponModel(studio) : "Weapon Model Override" : "models/props_canal/mattpipe.mdl" : "If the Shadow Walker is set to use 'Custom Melee Weapon', you may supply a world model to use. I would recommend using the pipe model, the crowbar model, or the stunstick model."

Health(integer) : "Health" : 75 : "Starting health of the NPC."

Expand Down
77 changes: 66 additions & 11 deletions sp/src/game/server/mod/npc_shadow_walker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "engine/IEngineSound.h"
#include "basehlcombatweapon_shared.h"
#include "ai_squadslot.h"
#include "weapon_crowbar.h"

// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
Expand All @@ -45,7 +46,7 @@ class CNPC_ShadowWalker : public CAI_BaseNPC
virtual int SelectAlertSchedule();
virtual int SelectCombatSchedule();
virtual bool CanPickkUpWeapons() { return true; }
Activity NPC_TranslateActivity(Activity eNewActivity);
Activity NPC_TranslateActivity(Activity eNewActivity);

// Sounds
virtual void PlaySound(string_t soundname, bool optional);
Expand All @@ -56,9 +57,14 @@ class CNPC_ShadowWalker : public CAI_BaseNPC
virtual void FearSound(void) { PlaySound(m_iszFearSound, false); };
virtual void LostEnemySound(void) { PlaySound(m_iszLostEnemySound, false); };
virtual void FoundEnemySound(void) { PlaySound(m_iszFoundEnemySound, false); };

void Activate();
void FixupWeapon();

DECLARE_DATADESC();

string_t m_iszWeaponModelName; // Path/filename of model to override weapon model.

string_t m_iszFearSound; // Path/filename of WAV file to play.
string_t m_iszDeathSound; // Path/filename of WAV file to play.
string_t m_iszIdleSound; // Path/filename of WAV file to play.
Expand Down Expand Up @@ -87,7 +93,8 @@ IMPLEMENT_CUSTOM_AI( npc_citizen,CNPC_ShadowWalker );
//---------------------------------------------------------
// Save/Restore
//---------------------------------------------------------
BEGIN_DATADESC( CNPC_ShadowWalker )
BEGIN_DATADESC(CNPC_ShadowWalker)
DEFINE_KEYFIELD(m_iszWeaponModelName, FIELD_STRING, "WeaponModel"),
DEFINE_KEYFIELD(m_iHealth, FIELD_INTEGER, "Health"),
DEFINE_KEYFIELD(m_iszFearSound, FIELD_SOUNDNAME, "FearSound"),
DEFINE_KEYFIELD(m_iszDeathSound, FIELD_SOUNDNAME, "DeathSound"),
Expand All @@ -112,6 +119,18 @@ void CNPC_ShadowWalker::InitCustomSchedules(void)
INIT_CUSTOM_AI(CNPC_ShadowWalker);
}

//-----------------------------------------------------------------------------
// Purpose: Inner class for default weapon
// TODO: Merge this with the Matt weapon in npc_citizen
//-----------------------------------------------------------------------------
class CWeaponCustomMelee : public CWeaponCrowbar
{
DECLARE_CLASS(CWeaponCustomMelee, CWeaponCrowbar);

const char *GetWorldModel() const { return GetModelName().ToCStr(); }
void SetPickupTouch(void) { /* do nothing */ }
};

//-----------------------------------------------------------------------------
// Purpose:
//
Expand All @@ -125,14 +144,18 @@ void CNPC_ShadowWalker::Precache( void )
SetModelName(MAKE_STRING("models/monster/subject.mdl"));
}

if (&m_iszWeaponModelName && m_iszWeaponModelName != MAKE_STRING("")) {
PrecacheModel(STRING(m_iszWeaponModelName));
}

PrecacheModel(STRING(GetModelName()));
PrecacheNPCSoundScript(&m_iszFearSound, MAKE_STRING("NPC_Shadow_Walker.Fear"));
PrecacheNPCSoundScript(&m_iszIdleSound, MAKE_STRING("NPC_Shadow_Walker.Idle"));
PrecacheNPCSoundScript(&m_iszAlertSound, MAKE_STRING("NPC_Shadow_Walker.Alert"));
PrecacheNPCSoundScript(&m_iszPainSound, MAKE_STRING("NPC_Shadow_Walker.Pain"));
PrecacheNPCSoundScript(&m_iszLostEnemySound, MAKE_STRING("NPC_Shadow_Walker.LostEnemy"));
PrecacheNPCSoundScript(&m_iszFoundEnemySound, MAKE_STRING("NPC_Shadow_Walker.FoundEnemy"));
PrecacheNPCSoundScript(&m_iszDeathSound, MAKE_STRING("NPC_Shadow_Walker.Death"));
PrecacheNPCSoundScript(&m_iszFearSound, MAKE_STRING("NPC_ShadowWalker.Fear"));
PrecacheNPCSoundScript(&m_iszIdleSound, MAKE_STRING("NPC_ShadowWalker.Idle"));
PrecacheNPCSoundScript(&m_iszAlertSound, MAKE_STRING("NPC_ShadowWalker.Alert"));
PrecacheNPCSoundScript(&m_iszPainSound, MAKE_STRING("NPC_ShadowWalker.Pain"));
PrecacheNPCSoundScript(&m_iszLostEnemySound, MAKE_STRING("NPC_ShadowWalker.LostEnemy"));
PrecacheNPCSoundScript(&m_iszFoundEnemySound, MAKE_STRING("NPC_ShadowWalker.FoundEnemy"));
PrecacheNPCSoundScript(&m_iszDeathSound, MAKE_STRING("NPC_ShadowWalker.Death"));

m_bWanderToggle = false;

Expand Down Expand Up @@ -187,6 +210,40 @@ void CNPC_ShadowWalker::Spawn( void )
NPCInit();
}

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void CNPC_ShadowWalker::FixupWeapon()
{
// If no weapons supplied, give a crowbar
CBaseCombatWeapon *pWeapon = GetActiveWeapon();
if (pWeapon == NULL) {
pWeapon = (CBaseCombatWeapon *)CREATE_UNSAVED_ENTITY(CWeaponCustomMelee, "weapon_crowbar");

// Apply weapon model override
if (&m_iszWeaponModelName && m_iszWeaponModelName != MAKE_STRING("")) {
pWeapon->SetModel(STRING(m_iszWeaponModelName));
}
else {
pWeapon->SetModel("models/props_canal/mattpipe.mdl");
}

DispatchSpawn(pWeapon);
Weapon_Equip(pWeapon);
}


}

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------

void CNPC_ShadowWalker::Activate()
{
BaseClass::Activate();
FixupWeapon();
}


//-----------------------------------------------------------------------------
// Purpose: Choose a schedule after schedule failed
//-----------------------------------------------------------------------------
Expand Down Expand Up @@ -464,8 +521,6 @@ bool CNPC_ShadowWalker::HasRangedWeapon()
Activity CNPC_ShadowWalker::NPC_TranslateActivity(Activity activity)
{
switch (activity) {
case ACT_MELEE_ATTACK1:
return ACT_MELEE_ATTACK_SWING;
case ACT_RUN_AIM_SHOTGUN:
return ACT_RUN_AIM_RIFLE;
case ACT_WALK_AIM_SHOTGUN:
Expand Down

0 comments on commit 9602325

Please sign in to comment.