Here´s the
qc file:
[quote]
/*
QC script generated by Half-Life MDL Decompiler 1.2
2003, Kratisto. Based on code from Valve's HL SDK.
monster_trolley.mdl
Original internal name:
"C:\DevZWC20\Elementos\Modelos v2.0\Elementos Reloader\monster_trtè "
*/
$modelname "monster_trolley.mdl"
$cd ".\"
$cdtexture ".\"
$scale 1.0
$cliptotextures
$bbox 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
$cbox 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
$eyeposition 0.000000 0.000000 0.000000
//reference mesh(es)
$body "body" "reference"
$texrendermode "trolley.bmp" "masked"
$texrendermode "carreta.bmp" "masked"
// 37 hit box(es)
$hbox 0 "Bip01 Pelvis" -11.515389 -9.690666 -1.395845 2.593500 2.622000 12.946850
$hbox 0 "Bip01 L Thigh" -1.463000 -1.330000 0.000000 1.130500 3.030500 6.451018
$hbox 0 "Bip01 L Calf" -1.102000 -1.035500 0.000000 1.453500 1.520000 5.381332
$hbox 0 "Bip01 L Foot" -2.118500 -1.387000 -0.646000 0.456000 0.589000 2.405057
$hbox 0 "Bip01 R Thigh" -1.320500 -1.168500 0.000000 1.377500 1.472500 6.453395
$hbox 0 "Bip01 R Calf" -1.092500 -1.083000 0.000000 1.472500 1.463000 5.352680
$hbox 0 "Bip01 R Foot" -2.137500 -1.406000 -0.627000 0.437000 0.608000 2.413388
$hbox 0 "Bip01 Spine" -2.004500 -2.033000 -2.148197 2.679000 2.622000 0.370500
$hbox 0 "Bip01 Spine1" -2.603000 -2.517500 -0.323000 2.517500 2.593500 4.674000
$hbox 0 "Bip01 Neck" -0.921500 -0.970822 -0.489736 0.998358 0.950000 1.634000
$hbox 0 "Bip01 L UpperArm" -0.817000 -0.969000 0.000000 0.921500 1.130500 3.098885
$hbox 0 "Bip01 L Forearm" -0.598500 -0.798000 -0.038000 0.684000 0.655500 4.953762
$hbox 0 "Bip01 R UpperArm" -0.864500 -1.007000 -0.161500 0.902500 1.035500 2.877933
$hbox 0 "Bip01 R Forearm" -0.589000 -0.655500 -0.047500 0.731500 0.750500 4.959755
$hbox 0 "Bip01 Head" -1.681500 -1.197000 -0.608000 1.225500 1.729000 2.565000
$hbox 0 "Bip01 L Foot1" -0.940500 -1.159000 -0.123500 0.589000 0.579500 1.140000
$hbox 0 "Bip01 R Foot1" -1.054500 -0.997500 -0.114000 0.560500 0.636500 1.159000
$hbox 0 "Bip01 Bolsa" -2.166000 -2.071000 -1.225500 2.156500 2.365500 1.814500
$hbox 0 "Bip01 Carro" -11.970000 -11.922500 -30.731306 10.867999 10.944000 2.631500
$hbox 0 "Bip01 Soporte_Izq_2" -2.365500 -0.446500 -1.415500 1.035500 1.054500 1.653000
$hbox 0 "Bip01 Soporte_D_2" -2.346500 -0.427500 -1.434500 1.045000 1.149500 1.624500
$hbox 0 "Bip01 Rueda" -2.669500 -2.660000 -2.840500 2.859500 2.802500 2.840500
$hbox 0 "Bip01 Fuelle A 1 " -2.983000 -4.389000 -0.475000 2.726500 4.655000 15.028999
$hbox 0 "Bip01 Fuelle A 2" -2.365500 -5.177500 -0.418000 2.565000 5.320000 15.095500
$hbox 0 "Bip01 Fuelle A 3" -1.596000 -4.959000 -0.228000 1.757500 4.826000 15.285500
$hbox 0 "Bip01 Fuelle A 4" -1.358500 -5.405500 -0.304000 1.406000 5.491000 15.219000
$hbox 0 "Bip01 Fuelle A 5" -0.940500 -5.149000 -0.237500 1.102000 4.968500 15.276000
$hbox 0 "Bip01 Bandeja" -8.749500 -8.702000 -4.560000 8.284000 8.170000 1.843000
$hbox 0 "Bip 01 BandejaRecarga D" -5.899500 -5.396000 -2.080500 4.598000 1.415500 4.607500
$hbox 0 "Bip01 AmmoBox D" -5.291500 -4.265500 -4.778500 5.453000 4.218000 4.655000
$hbox 0 "Bip 01 BandejaRecarga I" -5.709500 0.000000 -2.213500 5.842500 3.714500 4.664500
$hbox 0 "Bip01 Ammobox I" -5.377000 -3.315500 -4.826000 5.500500 3.363000 4.617000
$hbox 0 "Bip01 Fuelle P1" -1.605500 -5.434000 -0.465500 1.567500 5.405500 15.057500
$hbox 0 "Bip01 Fuelle P2" -1.045000 -5.092000 -0.313500 1.254000 4.997000 15.190499
$hbox 0 "Bip01 Fuelle P3" -0.912000 -5.453000 -0.304000 1.045000 5.481500 15.219000
$hbox 0 "Bip01 Fuelle P4" -0.684000 -5.054000 -0.247000 0.855000 5.016000 15.256999
$hbox 0 "Bip01 Fuelle P5" -0.617500 -5.453000 -0.294500 0.722000 5.481500 15.228500
// 14 animation sequence(s)
$sequence "idle1" "idle1" fps 5 loop ACT_IDLE 4
$sequence "turnleft" "turnleft" fps 20 ACT_TURN_LEFT 1
$sequence "turnright" "turnright" fps 20 ACT_TURN_RIGHT 1
$sequence "flinchsmall" "flinchsmall" fps 12 ACT_SMALL_FLINCH 5
$sequence "flinch" "flinch" fps 12 ACT_SMALL_FLINCH 1
$sequence "bigflinch" "bigflinch" fps 12 ACT_BIG_FLINCH 1
$sequence "attack1" "attack1" fps 8 ACT_MELEE_ATTACK1 5 { event 1 25 }
$sequence "run" "run" LX fps 50 loop ACT_WALK 1 {
{ event 1004 2 "common/npc_step1.wav" }
{ event 1004 12 "common/npc_step3.wav" }
{ event 1004 22 "common/npc_step2.wav" }
{ event 1004 29 "common/npc_step4.wav" }
{ event 1004 29 "common/npc_step1.wav" }
{ event 1004 29 "common/npc_step3.wav" }
}
$sequence "laflinch" "laflinch" fps 12 ACT_FLINCH_LEFTARM 1
$sequence "raflinch" "raflinch" fps 12 ACT_FLINCH_RIGHTARM 1
$sequence "llflinch" "llflinch" fps 12 ACT_FLINCH_LEFTLEG 1
$sequence "rlflinch" "rlflinch" fps 12 ACT_FLINCH_RIGHTLEG 1
$sequence "diesimple" "diesimple" X fps 20 ACT_DIESIMPLE 1 { event 2001 13 }
$sequence "deadidle" "deadidle" fps 1 loop
// End of QC script.
[/quote]
And the
cpp file:
[quote]
/***
*
* Copyright (c) 1996-2002, 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.
*
****/
//=========================================================
// TROLLEY-RELOADER : Los tÃos de la carretilla
// Based on the zombie character from HL
// 6-Julio-2015
//=========================================================
#include "extdll.h"
#include "util.h"
#include "cbase.h"
#include "monsters.h"
#include "squadmonster.h"
#include "weapons.h"
#include "effects.h"
#include "game.h"
//=========================================================
// Monster's Anim Events Go Here
//=========================================================
#define TROLL_AE_ATTACK_RIGHT 0x01
#define TROLL_FLINCH_DELAY 0 // at most one flinch every n secs
//======================================================
// Monster BASIC stuff
//======================================================
class CTrolley : public CBaseMonster
{
public:
void Spawn( void );
void Precache( void );
void SetYawSpeed ( void );
// void AttackSounds( void );
void PainSound( void );
// void DeathSounds( void );
// void IdleSound( void );
// void AlertSound( void );
void HandleAnimEvent( MonsterEvent_t *pEvent );
Vector Center( void );
Vector BodyTarget( const Vector &posSrc );
int IRelationship( CBaseEntity *pTarget );
int Classify ( void );
int IgnoreConditions( void );
int CTrolley :: GiveAmmo( int iCount, char *szName, int iMax );// ZWC ARM 8-7-2015
int TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType );
BOOL CheckMeleeAttack1( float flDot, float flDist );
virtual float GetDamageAmount( void ) { return 0;} //return gSkillData.headcrabDmgBite; }
virtual int GetVoicePitch( void ) { return 100; }
virtual float GetSoundVolue( void ) { return 1.0; }
// static const char *pAttackSounds[];
// static const char *pIdleSounds[];
// static const char *pAlertSounds[];
static const char *pPainSounds[];
static const char *pAttackHitSounds[];
static const char *pAttackMissSounds[];
// static const char *pDeathSounds[];
// static const char *pBiteSounds[];
//==============================================================================================================
// ARM: Declaración de la Función TraceAttack, el tiempo de ejecución de las animaciones "flinch", la función
// de ignorar condiciones, la descripcion de datos ESTATICOS ( m_SaveData ) y la función que disuelve los
// cuerpos al morir.
//==============================================================================================================
void TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType );
float m_flNextFlinch;
static TYPEDESCRIPTION m_SaveData[];
void BecomeDead( void );
};
const char *CTrolley::pAttackHitSounds[] =
{
"kid/reloadok1.wav",
"kid/reloadok2.wav",
"kid/reloadok3.wav",
};
const char *CTrolley::pAttackMissSounds[] =
{
"kid/reloadfail1.wav",
"kid/reloadfail2.wav",
};
/*
const char *CTrolley::pAttackSounds[] =
{
"kid/enroute1.wav",
"kid/enroute2.wav",
};
const char *CTrolley::pIdleSounds[] =
{
"kid/idle1.wav",
"kid/idle2.wav",
"kid/idle3.wav",
"kid/idle4.wav",
};
const char *CTrolley::pAlertSounds[] =
{
"kid/alert10.wav",
"kid/alert20.wav",
"kid/alert30.wav",
};
*/
const char *CTrolley::pPainSounds[] =
{
"kid/pain1.wav",
"kid/pain2.wav",
};
/*
const char *CTrolley::pBiteSounds[] =
{
"kid/clash.wav",
};
const char *CTrolley::pDeathSounds[] =
{
"kid/die1.wav",
"kid/die2.wav",
};
*/
LINK_ENTITY_TO_CLASS( monster_trolley, CTrolley );
//=========================================================
// CheckMeleeAttack1 osea Recargar a las APU
//=========================================================
BOOL CTrolley::CheckMeleeAttack1( float flDot, float flDist )
{
// ALERT(at_aiconsole, "CheckMelee(%f, %f)\n", flDot, flDist);
if (flDot >= 0.7)
{
if (flDist <= 50)
return TRUE;
}
return FALSE;
}
//=========================================================
//==========================================================
// Relationship
//==========================================================
int CTrolley::IRelationship( CBaseEntity *pTarget )
{
if ( pTarget->ammo_9mm < 100 && FClassnameIs ( pTarget->pev, "player" ) )
{
return R_NM;
}
if ( pTarget->ammo_9mm > 100 )
{
return R_AL;
}
if (FBitSet(pTarget->pev->flags, FL_FAKECLIENT))
{
return R_AL;
}
return CBaseMonster::IRelationship( pTarget );
}
//===========================================================
//=========================================================
// Classify - indicates this monster's place in the
// relationship table.
//=========================================================
int CTrolley :: Classify ( void )
{
return CLASS_PLAYER_ALLY;
}
//=========================================================
// Center - returns the real center of the trolley guy.The
// bounding box is much larger than the actual creature so
// this is needed for targeting
//=========================================================
Vector CTrolley :: Center ( void )
{
return Vector( pev->origin.x, pev->origin.y, pev->origin.z + 6 );
}
Vector CTrolley :: BodyTarget( const Vector &posSrc )
{
return Center( );
}
//=========================================================
// SetYawSpeed - allows each sequence to have a different
// turn rate associated with it.
//=========================================================
void CTrolley :: SetYawSpeed ( void )
{
int ys;
switch ( m_Activity )
{
case ACT_IDLE:
ys = 60;
break;
//case ACT_RUN:
case ACT_WALK:
ys = 90;
break;
case ACT_TURN_LEFT:
case ACT_TURN_RIGHT:
ys = 180;
break;
default:
ys = 45;
break;
}
pev->yaw_speed = ys;
}
int CTrolley :: TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType )
{
// Drone take 15% damage from normal attacks
if ( bitsDamageType == DMG_BULLET || DMG_BLAST || DMG_SHOCK )
{
// Vector vecDir = pev->origin - (pevInflictor->absmin + pevInflictor->absmax) * 0.5;
// vecDir = vecDir.Normalize();
// float flForce = DamageForce( flDamage );
// pev->velocity = pev->velocity + vecDir * flForce;
flDamage *= 0;
}
if ( bitsDamageType == DMG_SLASH )
{
// Vector vecDir = pev->origin - (pevInflictor->absmin + pevInflictor->absmax) * 0.5;
// vecDir = vecDir.Normalize();
// float flForce = DamageForce( flDamage );
// pev->velocity = pev->velocity + vecDir * flForce;
flDamage *= 0.1;
}
// Old code has this "HACK" warning.
if ( IsAlive() )
PainSound();
return CBaseMonster::TakeDamage( pevInflictor, pevAttacker, flDamage, bitsDamageType );
}
void CTrolley :: PainSound( void )
{
int pitch = 95 + RANDOM_LONG(0,9);
if (RANDOM_LONG(0,5) < 2)
EMIT_SOUND_DYN ( ENT(pev), CHAN_VOICE, pPainSounds[ RANDOM_LONG(0,ARRAYSIZE(pPainSounds)-1) ], 1.0, ATTN_NORM, 0, pitch );
}
/*
void CTrolley :: AlertSound( void )
{
int pitch = 95 + RANDOM_LONG(0,9);
EMIT_SOUND_DYN ( ENT(pev), CHAN_VOICE, pAlertSounds[ RANDOM_LONG(0,ARRAYSIZE(pAlertSounds)-1) ], 1.0, ATTN_NORM, 0, pitch );
}
void CTrolley :: IdleSound( void )
{
int pitch = 95 + RANDOM_LONG(0,9);
// Play a random idle sound
EMIT_SOUND_DYN ( ENT(pev), CHAN_VOICE, pIdleSounds[ RANDOM_LONG(0,ARRAYSIZE(pIdleSounds)-1) ], 1.0, ATTN_NORM, 0, 100 + RANDOM_LONG(-5,5) );
}
void CTrolley :: AttackSounds( void )
{
// Play a random attack sound
EMIT_SOUND_DYN ( ENT(pev), CHAN_VOICE, pAttackSounds[ RANDOM_LONG(0,ARRAYSIZE(pAttackSounds)-1) ], 1.0, ATTN_NORM, 0, 100 + RANDOM_LONG(-5,5) );
}
*/
//========================================================
// Zion's Corpses' Fade Function
//========================================================
void CTrolley::BecomeDead( void )
{
//if ( ShouldFadeOnDeath() )
// {
// this monster was created by a monstermaker... fade the corpse out.
SUB_StartFadeOut();
// }
//==================================================
//Intento de que no pete el sistema ARM: 26-1-2016
//==================================================
CBaseEntity *pOwner = CBaseEntity::Instance(pev->owner);
if ( pOwner )
{
pOwner->DeathNotice( pev );
}
UTIL_Remove( this );
UpdateOnRemove();//NUevo. Sacado de GitHub 19-10-2016 (c)Solokiller
//======================================================
}
//=========================================================
// HandleAnimEvent - catches the monster-specific messages
// that occur when tagged animation frames are played.
//=========================================================
void CTrolley :: HandleAnimEvent( MonsterEvent_t *pEvent )
{
switch( pEvent->event )
{
case TROLL_AE_ATTACK_RIGHT:
{
//ALERT( at_console, "RELOAD!!\n" );
CBaseEntity *pHurt = CheckTraceHullAttack( 0, -25, DMG_SLASH );// Si el segndo numero es negativo TE DA ESO DE SALUD
if ( pHurt )
{
EMIT_SOUND_DYN ( ENT(pev), CHAN_WEAPON, pAttackHitSounds[ RANDOM_LONG(0,ARRAYSIZE(pAttackHitSounds)-1) ], 1.0, ATTN_NORM, 0, 100 + RANDOM_LONG(-5,5) );
GiveAmmo(600, "9mm",600);//
}
else // Play a random attack miss sound
EMIT_SOUND_DYN ( ENT(pev), CHAN_WEAPON, pAttackMissSounds[ RANDOM_LONG(0,ARRAYSIZE(pAttackMissSounds)-1) ], 1.0, ATTN_NORM, 0, 100 + RANDOM_LONG(-5,5) );
// if (RANDOM_LONG(0,1))
// AttackSounds();
pev->nextthink = gpGlobals->time + 5;//7-7-2015
}
break;
default:
CBaseMonster::HandleAnimEvent( pEvent );
break;
}
}
//=========================================================
// Spawn
//=========================================================
void CTrolley :: Spawn()
{
Precache( );
SET_MODEL(ENT(pev), "models/monster_trolley.mdl");
UTIL_SetSize( pev, Vector( -32, -32, 0 ), Vector( 32, 32, 64 ) );//Será del tamaño del houndeye o del bullsquid ás o menos,,,
pev->solid = SOLID_BBOX;//SOLID_SLIDEBOX;
pev->movetype = MOVETYPE_STEP;
m_bloodColor = DONT_BLEED;
pev->health = 50;
pev->view_ofs = VEC_VIEW;// position of the eyes relative to monster's origin.
m_flFieldOfView = VIEW_FIELD_FULL;// indicates the width of this monster's forward view cone ( as a dotproduct result )
m_MonsterState = MONSTERSTATE_HUNT;//MONSTERSTATE_NONE;
m_afCapability = bits_CAP_DOORS_GROUP;
MonsterInit();
SetModelCollisionBox ();
}
//=========================================================
// Precache - precaches all resources this monster needs
//=========================================================
void CTrolley :: Precache()
{
int i;
PRECACHE_MODEL("models/monster_trolley.mdl");
for ( i = 0; i < ARRAYSIZE( pAttackHitSounds ); i++ )
PRECACHE_SOUND((char *)pAttackHitSounds[i]);
for ( i = 0; i < ARRAYSIZE( pAttackMissSounds ); i++ )
PRECACHE_SOUND((char *)pAttackMissSounds[i]);
for ( i = 0; i < ARRAYSIZE( pPainSounds ); i++ )
PRECACHE_SOUND((char *)pPainSounds[i]);
}
void CTrolley::TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType )
{
bitsDamageType &= DMG_GENERIC;
if ( bitsDamageType == 0)
{
if ( pev->dmgtime != gpGlobals->time || (RANDOM_LONG(0,100) < 20) )
{
Vector vecBlood = (ptr->vecEndPos - pev->origin).Normalize( );
}
flDamage *= 1.5;
}
CBaseMonster::TraceAttack( pevAttacker, flDamage, vecDir, ptr, bitsDamageType );
}
//===============================================================
// 6 Julio 2015
//===============================================================
int CTrolley :: GiveAmmo( int iCount, char *szName, int iMax )
{
CBaseEntity *pPlayer;
pPlayer = UTIL_FindEntityByClassname( NULL, "player" );
if (pPlayer->ammo_9mm <= 100)//limite de munición para que te recargue
{
pPlayer->GiveAmmo(600,"9mm",600);
return TRUE;
}
return FALSE;
}
//=========================================================================
// Trolley AI specific Schedules ¿comentar para que SIEMPRE recargue?
//=========================================================================
int CTrolley::IgnoreConditions ( void )
{
int iIgnore = CBaseMonster::IgnoreConditions();
if ((m_Activity == ACT_MELEE_ATTACK1) || (m_Activity == ACT_MELEE_ATTACK1))
{
#if 0
if (pev->health < 20)
iIgnore |= (bits_COND_LIGHT_DAMAGE|bits_COND_HEAVY_DAMAGE);
else
#endif
if (m_flNextFlinch >= gpGlobals->time)
iIgnore |= (bits_COND_LIGHT_DAMAGE|bits_COND_HEAVY_DAMAGE);
}
if ((m_Activity == ACT_SMALL_FLINCH) || (m_Activity == ACT_BIG_FLINCH))
{
if (m_flNextFlinch < gpGlobals->time)
m_flNextFlinch = gpGlobals->time + TROLL_FLINCH_DELAY;
}
return iIgnore;
}
//=================================================================================
// Fin del Trolley
//=================================================================================