Add monster_male_assassin.

This commit is contained in:
Julian
2020-06-09 18:21:51 -03:00
parent 769ec8852f
commit bf607621b3
12 changed files with 380 additions and 6 deletions

View File

@@ -28,3 +28,4 @@
//monster_miniturret
//monster_sentry
//monster_gonome
//monster_male_assassin

View File

@@ -2,6 +2,7 @@
//
// Install this file to your mod's base directory.
// ORIGINAL HALF-LIFE MONSTERS
// Alien Grunt
@@ -86,6 +87,7 @@ sk_miniturret_health 40
// Sentry Turret
sk_sentry_health 40
// OPPOSING FORCE MONSTERS
// Gonome
@@ -94,9 +96,14 @@ sk_gonome_dmg_one_slash 20
sk_gonome_dmg_guts 10
sk_gonome_dmg_one_bite 14
// Male Assassin
sk_massassin_health 50
sk_massassin_kick 25
// MONSTER WEAPON DAMAGE
sk_9mm_bullet 5
sk_9mmAR_bullet 4
sk_9mmAR_grenade 100
sk_12mm_bullet 10
sk_762_bullet 100

View File

@@ -30,6 +30,7 @@ OBJ = \
hornet.o \
houndeye.o \
islave.o \
massn.o \
monster_api.o \
monster_config.o \
monsters.o \

View File

@@ -1311,4 +1311,24 @@ protected:
bool m_playedAttackSound;
};
//=========================================================
// Male Assassin
//=========================================================
class CMMassn : public CMHGrunt
{
public:
int Classify(void);
void HandleAnimEvent(MonsterEvent_t *pEvent);
void Sniperrifle(void);
BOOL FOkToSpeak(void);
void Spawn( void );
void Precache( void );
void DeathSound(void);
void PainSound(void);
void IdleSound(void);
};
#endif // BASEMONSTER_H

View File

@@ -1360,6 +1360,7 @@ void CMBaseEntity::FireBullets(ULONG cShots, Vector vecSrc, Vector vecDirShootin
case BULLET_MONSTER_MP5:
case BULLET_MONSTER_9MM:
case BULLET_MONSTER_12MM:
case BULLET_MONSTER_762:
default:
MESSAGE_BEGIN( MSG_PAS, SVC_TEMPENTITY, vecTracerSrc );
WRITE_BYTE( TE_TRACER );
@@ -1403,7 +1404,7 @@ void CMBaseEntity::FireBullets(ULONG cShots, Vector vecSrc, Vector vecDirShootin
break;
case BULLET_MONSTER_12MM:
case BULLET_MONSTER_12MM:
UTIL_TraceAttack(pPlayer, pevAttacker, gSkillData.monDmg12MM, vecDir, &tr, DMG_BULLET);
if ( !tracer )
{
@@ -1411,7 +1412,14 @@ void CMBaseEntity::FireBullets(ULONG cShots, Vector vecSrc, Vector vecDirShootin
DecalGunshot( &tr, iBulletType );
}
break;
case BULLET_MONSTER_762:
UTIL_TraceAttack(pPlayer, pevAttacker, gSkillData.monDmg762, vecDir, &tr, DMG_BULLET);
TEXTURETYPE_PlaySound(&tr, vecSrc, vecEnd, iBulletType);
DecalGunshot( &tr, iBulletType );
break;
case BULLET_NONE: // FIX
UTIL_TraceAttack(pPlayer, pevAttacker, 50, vecDir, &tr, DMG_CLUB);
TEXTURETYPE_PlaySound(&tr, vecSrc, vecEnd, iBulletType);

View File

@@ -153,6 +153,7 @@ monster_type_t monster_types[]=
"monster_miniturret", FALSE,
"monster_sentry", FALSE,
"monster_gonome", FALSE, // Opposing Force Monsters
"monster_male_assassin", FALSE,
"info_node", FALSE, // Nodes
"info_node_air", FALSE,
"", FALSE
@@ -621,6 +622,7 @@ bool spawn_monster(int monster_type, Vector origin, Vector angles, int respawn_i
case 16: monsters[monster_index].pMonster = CreateClassPtr((CMMiniTurret *)NULL); break;
case 17: monsters[monster_index].pMonster = CreateClassPtr((CMSentry *)NULL); break;
case 18: monsters[monster_index].pMonster = CreateClassPtr((CMGonome *)NULL); break;
case 19: monsters[monster_index].pMonster = CreateClassPtr((CMMassn *)NULL); break;
}
if (monsters[monster_index].pMonster == NULL)
@@ -1297,6 +1299,7 @@ void mmServerActivate( edict_t *pEdictList, int edictCount, int clientMax )
CMMiniTurret miniturret;
CMSentry sentry;
CMGonome gonome;
CMMassn massn;
g_psv_gravity = CVAR_GET_POINTER( "sv_gravity" );
@@ -1333,6 +1336,7 @@ void mmServerActivate( edict_t *pEdictList, int edictCount, int clientMax )
case 16: miniturret.Precache(); break;
case 17: sentry.Precache(); break;
case 18: gonome.Precache(); break;
case 19: massn.Precache(); break;
}
}
}

View File

@@ -663,7 +663,9 @@ void CMHGrunt :: Shoot ( void )
pev->effects |= EF_MUZZLEFLASH;
m_cAmmoLoaded--;// take away a bullet!
// BUG - For some reason that still eludes me, grunts are completely unable to reload their weapons.
// As a temporary fix, give them infinite ammo. It will look bad I know... I gotta find a solution. -Giegue
//m_cAmmoLoaded--;// take away a bullet!
Vector angDir = UTIL_VecToAngles( vecShootDir );
SetBlending( 0, angDir.x );
@@ -690,7 +692,9 @@ void CMHGrunt :: Shotgun ( void )
pev->effects |= EF_MUZZLEFLASH;
m_cAmmoLoaded--;// take away a bullet!
// BUG - For some reason that still eludes me, grunts are completely unable to reload their weapons.
// As a temporary fix, give them infinite ammo. It will look bad I know... I gotta find a solution. -Giegue
//m_cAmmoLoaded--;// take away a bullet!
Vector angDir = UTIL_VecToAngles( vecShootDir );
SetBlending( 0, angDir.x );

302
src/dlls/massn.cpp Normal file
View File

@@ -0,0 +1,302 @@
// HUGE thanks to DrBeef for his hlsdk-xash3d-opfor repository!
/***
*
* Copyright (c) 1996-2001, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* This source code contains proprietary and confidential information of
* Valve LLC and its suppliers. Access to this code is restricted to
* persons who have executed a written SDK license with Valve. Any access,
* use or distribution of this code by or to any unlicensed person is illegal.
*
****/
//=========================================================
// Black Ops - Male Assassin
//=========================================================
#include "extdll.h"
#include "plane.h"
#include "util.h"
#include "cmbase.h"
#include "cmbasemonster.h"
#include "monsters.h"
#include "schedule.h"
#include "animation.h"
#include "weapons.h"
#include "cmtalkmonster.h"
#include "effects.h"
#include "customentity.h"
//=========================================================
// monster-specific DEFINE's
//=========================================================
#define MASSN_CLIP_SIZE 36 // how many bullets in a clip? - NOTE: 3 round burst sound, so keep as 3 * x!
// Weapon flags
#define MASSN_9MMAR (1 << 0)
#define MASSN_HANDGRENADE (1 << 1)
#define MASSN_GRENADELAUNCHER (1 << 2)
#define MASSN_SNIPERRIFLE (1 << 3)
// Body groups.
#define HEAD_GROUP 1
#define GUN_GROUP 2
// Head values
#define HEAD_WHITE 0
#define HEAD_BLACK 1
#define HEAD_GOGGLES 2
// Gun values
#define GUN_MP5 0
#define GUN_SNIPERRIFLE 1
#define GUN_NONE 2
//=========================================================
// Monster's Anim Events Go Here
//=========================================================
#define MASSN_AE_KICK ( 3 )
#define MASSN_AE_BURST1 ( 4 )
#define MASSN_AE_CAUGHT_ENEMY ( 10 ) // grunt established sight with an enemy (player only) that had previously eluded the squad.
#define MASSN_AE_DROP_GUN ( 11 ) // grunt (probably dead) is dropping his mp5.
//=========================================================
// Override a few behaviours to make this grunt silent
//=========================================================
BOOL CMMassn::FOkToSpeak(void)
{
return FALSE;
}
void CMMassn::IdleSound(void)
{
}
void CMMassn::PainSound(void)
{
}
void CMMassn::DeathSound(void)
{
}
//=========================================================
// Classify - indicates this monster's place in the
// relationship table.
//=========================================================
int CMMassn::Classify(void)
{
if ( m_iClassifyOverride == -1 ) // helper
return CLASS_NONE;
else if ( m_iClassifyOverride > 0 )
return m_iClassifyOverride; // override
return CLASS_HUMAN_MILITARY;
}
//=========================================================
// Shoot
//=========================================================
void CMMassn::Sniperrifle(void)
{
if (m_hEnemy == 0)
{
return;
}
Vector vecShootOrigin = GetGunPosition();
Vector vecShootDir = ShootAtEnemy(vecShootOrigin);
UTIL_MakeVectors(pev->angles);
Vector vecShellVelocity = gpGlobals->v_right * RANDOM_FLOAT(40, 90) + gpGlobals->v_up * RANDOM_FLOAT(75, 200) + gpGlobals->v_forward * RANDOM_FLOAT(-40, 40);
EjectBrass(vecShootOrigin - vecShootDir * 24, vecShellVelocity, pev->angles.y, m_iBrassShell, TE_BOUNCE_SHELL);
FireBullets(1, vecShootOrigin, vecShootDir, VECTOR_CONE_1DEGREES, 2048, BULLET_MONSTER_762, 0); // shoot +-7.5 degrees
pev->effects |= EF_MUZZLEFLASH;
// BUG - For some reason that still eludes me, grunts are completely unable to reload their weapons.
// As a temporary fix, give them infinite ammo. It will look bad I know... I gotta find a solution. -Giegue
//m_cAmmoLoaded--;// take away a bullet!
Vector angDir = UTIL_VecToAngles(vecShootDir);
SetBlending(0, angDir.x);
}
//=========================================================
// HandleAnimEvent - catches the monster-specific messages
// that occur when tagged animation frames are played.
//=========================================================
void CMMassn::HandleAnimEvent(MonsterEvent_t *pEvent)
{
Vector vecShootDir;
Vector vecShootOrigin;
switch (pEvent->event)
{
case MASSN_AE_DROP_GUN:
{
Vector vecGunPos;
Vector vecGunAngles;
GetAttachment(0, vecGunPos, vecGunAngles);
// switch to body group with no gun.
SetBodygroup(GUN_GROUP, GUN_NONE);
}
break;
case MASSN_AE_BURST1:
{
if (FBitSet(pev->weapons, MASSN_9MMAR))
{
Shoot();
// the first round of the three round burst plays the sound and puts a sound in the world sound list.
if (RANDOM_LONG(0, 1))
{
EMIT_SOUND(ENT(pev), CHAN_WEAPON, "hgrunt/gr_mgun1.wav", 1, ATTN_NORM);
}
else
{
EMIT_SOUND(ENT(pev), CHAN_WEAPON, "hgrunt/gr_mgun2.wav", 1, ATTN_NORM);
}
}
else if (FBitSet(pev->weapons, MASSN_SNIPERRIFLE))
{
Sniperrifle();
EMIT_SOUND(ENT(pev), CHAN_WEAPON, "weapons/sniper_fire.wav", 1, ATTN_NORM);
}
}
break;
case MASSN_AE_KICK:
{
edict_t *pHurt = Kick();
if (pHurt)
{
// SOUND HERE!
UTIL_MakeVectors(pev->angles);
pHurt->v.punchangle.x = 15;
pHurt->v.velocity = pHurt->v.velocity + gpGlobals->v_forward * 100 + gpGlobals->v_up * 50;
if (UTIL_IsPlayer(pHurt))
UTIL_TakeDamage( pHurt, pev, pev, gSkillData.massnDmgKick, DMG_CLUB );
else if (pHurt->v.euser4 != NULL)
{
CMBaseMonster *pMonster = GetClassPtr((CMBaseMonster *)VARS(pHurt));
pMonster->TakeDamage( pev, pev, gSkillData.massnDmgKick, DMG_CLUB );
}
}
}
break;
case MASSN_AE_CAUGHT_ENEMY:
break;
default:
CMHGrunt::HandleAnimEvent(pEvent);
break;
}
}
//=========================================================
// Spawn
//=========================================================
void CMMassn::Spawn()
{
Precache();
SET_MODEL(ENT(pev), "models/massn.mdl");
UTIL_SetSize(pev, VEC_HUMAN_HULL_MIN, VEC_HUMAN_HULL_MAX);
pev->solid = SOLID_SLIDEBOX;
pev->movetype = MOVETYPE_STEP;
m_bloodColor = BLOOD_COLOR_RED;
pev->effects = 0;
pev->health = gSkillData.massnHealth;
m_flFieldOfView = 0.2;// indicates the width of this monster's forward view cone ( as a dotproduct result )
m_MonsterState = MONSTERSTATE_NONE;
m_flNextGrenadeCheck = gpGlobals->time + 1;
m_flNextPainTime = gpGlobals->time;
m_iSentence = -1;
//m_afCapability = bits_CAP_SQUAD | bits_CAP_TURN_HEAD | bits_CAP_DOORS_GROUP;
m_afCapability = bits_CAP_TURN_HEAD | bits_CAP_DOORS_GROUP;
//m_fEnemyEluded = FALSE;
m_fFirstEncounter = TRUE;// this is true when the grunt spawns, because he hasn't encountered an enemy yet.
m_HackedGunPos = Vector(0, 0, 55);
if (pev->weapons == 0)
{
// initialize to original values
pev->weapons = MASSN_9MMAR | MASSN_HANDGRENADE;
// pev->weapons = HGRUNT_SHOTGUN;
// pev->weapons = HGRUNT_9MMAR | HGRUNT_GRENADELAUNCHER;
}
if (FBitSet(pev->weapons, MASSN_SNIPERRIFLE))
{
SetBodygroup(GUN_GROUP, GUN_SNIPERRIFLE);
m_cClipSize = 5;
}
else
{
m_cClipSize = MASSN_CLIP_SIZE;
}
m_cAmmoLoaded = m_cClipSize;
if (RANDOM_LONG(0, 99) < 80)
pev->skin = 0; // light skin
else
pev->skin = 1; // dark skin
CMTalkMonster::g_talkWaitTime = 0;
MonsterInit();
pev->classname = MAKE_STRING( "monster_male_assassin" );
if ( strlen( STRING( m_szMonsterName ) ) == 0 )
{
// default name
m_szMonsterName = MAKE_STRING( "Male Assassin" );
}
}
//=========================================================
// Precache - precaches all resources this monster needs
//=========================================================
void CMMassn::Precache()
{
PRECACHE_MODEL("models/massn.mdl");
PRECACHE_SOUND("hgrunt/gr_mgun1.wav");
PRECACHE_SOUND("hgrunt/gr_mgun2.wav");
PRECACHE_SOUND("hgrunt/gr_reload1.wav");
PRECACHE_SOUND("weapons/glauncher.wav");
PRECACHE_SOUND("weapons/sniper_bolt1.wav");
PRECACHE_SOUND("weapons/sniper_fire.wav");
PRECACHE_SOUND("zombie/claw_miss2.wav");// because we use the basemonster SWIPE animation event
// get voice pitch
if (RANDOM_LONG(0, 1))
m_voicePitch = 109 + RANDOM_LONG(0, 7);
else
m_voicePitch = 100;
m_iBrassShell = PRECACHE_MODEL("models/shell.mdl");// brass shell
}

View File

@@ -76,10 +76,13 @@ skill_cfg_t skill_cfg[] = {
{"sk_gonome_dmg_guts", &gSkillData.gonomeDmgGuts},
{"sk_gonome_dmg_one_slash", &gSkillData.gonomeDmgOneSlash},
{"sk_gonome_dmg_one_bite", &gSkillData.gonomeDmgOneBite},
{"sk_massassin_health", &gSkillData.massnHealth},
{"sk_massassin_kick", &gSkillData.massnDmgKick},
{"sk_12mm_bullet", &gSkillData.monDmg9MM},
{"sk_9mmAR_bullet", &gSkillData.monDmgMP5},
{"sk_9mm_bullet", &gSkillData.monDmg12MM},
{"sk_9mmAR_grenade", &gSkillData.monDmgM203Grenade},
{"sk_762_bullet", &gSkillData.monDmg762},
{"sk_hornet_dmg", &gSkillData.monDmgHornet},
{"", NULL}
};
@@ -222,12 +225,17 @@ void monster_skill_init(void)
gSkillData.gonomeDmgOneSlash = 20.0f;
gSkillData.gonomeDmgOneBite = 14.0f;
// Male Assassin
gSkillData.massnHealth = 50.0f;
gSkillData.massnDmgKick = 25.0f;
// MONSTER WEAPONS
gSkillData.monDmg9MM = 5.0f;
gSkillData.monDmgMP5 = 4.0f;
gSkillData.monDmg12MM = 10.0f;
gSkillData.monDmgM203Grenade = 100.0f;
gSkillData.monDmg762 = 100.0f;
// HORNET
gSkillData.monDmgHornet = 5.0f;

View File

@@ -92,12 +92,16 @@ struct skilldata_t
float gonomeDmgOneSlash;
float gonomeDmgOneBite;
float massnHealth;
float massnDmgKick;
// weapons shared by monsters
float monDmg9MM;
float monDmgMP5;
float monDmg12MM;
float monDmgM203Grenade;
float monDmg762;
float monDmgHornet;
};

View File

@@ -136,6 +136,19 @@ void DecalGunshot( TraceResult *pTrace, int iBulletType )
switch( iBulletType )
{
case BULLET_PLAYER_CROWBAR:
{
// wall decal
UTIL_DecalTrace( pTrace, DamageDecal( pEntity, DMG_CLUB ) );
break;
}
default:
{
// smoke and decal
UTIL_GunshotDecalTrace( pTrace, DamageDecal( pEntity, DMG_BULLET ) );
break;
}
/* why the duplicate case?
case BULLET_PLAYER_9MM:
case BULLET_MONSTER_9MM:
case BULLET_PLAYER_MP5:
@@ -154,6 +167,7 @@ void DecalGunshot( TraceResult *pTrace, int iBulletType )
// wall decal
UTIL_DecalTrace( pTrace, DamageDecal( pEntity, DMG_CLUB ) );
break;
*/
}
}
}

View File

@@ -177,6 +177,7 @@ typedef enum
BULLET_MONSTER_9MM,
BULLET_MONSTER_MP5,
BULLET_MONSTER_12MM,
BULLET_MONSTER_762,
} Bullet;