Update extra AMXX plugins.

This commit is contained in:
Giegue
2023-04-25 22:32:36 -03:00
parent 2cf22ab66b
commit d00fec91b8
11 changed files with 288 additions and 167 deletions

View File

@@ -57,103 +57,6 @@ Usage of ReHLDS is highly recommended, as you can use the command `rescount` whi
Keeping track of the number of precached content will allow you to maximize the number of monsters you can use without risking going over the limits. Keeping track of the number of precached content will allow you to maximize the number of monsters you can use without risking going over the limits.
## Using MonsterMod on Counter-Strike
Counter-Strike precaches the sounds of all weapons. This means that sounds such as "clip-ins", "clip-outs" are added to the list, taking quite a bit of space in the precache count. Let it be a reminder that our good old Half-Life can only store a maximum of 512 precached resources. Most of these sounds are handled client-side by the models themselves, there is no need for all of them to be kept precached on the server. Only the weapons fire sounds are needed.
MonsterMod does not have an integrated "Unprecacher" to remove those sounds, but you can remove them manually with AMX Mod X, using Fakemeta. Register forward **FM_PrecacheSound** and return **FMRES_SUPERCEDE** on the following sounds:
```
"weapons/ak47_boltpull.wav"
"weapons/ak47_clipin.wav"
"weapons/ak47_clipout.wav"
"weapons/aug_boltpull.wav"
"weapons/aug_boltslap.wav"
"weapons/aug_clipin.wav"
"weapons/aug_clipout.wav"
"weapons/aug_forearm.wav"
"weapons/awp_clipin.wav"
"weapons/awp_clipout.wav"
"weapons/awp_deploy.wav"
"weapons/boltdown.wav"
"weapons/boltpull1.wav"
"weapons/boltup.wav"
"weapons/clipin1.wav"
"weapons/clipout1.wav"
"weapons/de_clipin.wav"
"weapons/de_clipout.wav"
"weapons/de_deploy.wav"
"weapons/elite_clipout.wav"
"weapons/elite_deploy.wav"
"weapons/elite_leftclipin.wav"
"weapons/elite_reloadstart.wav"
"weapons/elite_rightclipin.wav"
"weapons/elite_sliderelease.wav"
"weapons/elite_twirl.wav"
"weapons/famas_boltpull.wav"
"weapons/famas_boltslap.wav"
"weapons/famas_clipin.wav"
"weapons/famas_clipout.wav"
"weapons/famas_forearm.wav"
"weapons/fiveseven_clipin.wav"
"weapons/fiveseven_clipout.wav"
"weapons/fiveseven_slidepull.wav"
"weapons/fiveseven_sliderelease.wav"
"weapons/g3sg1_clipin.wav"
"weapons/g3sg1_clipout.wav"
"weapons/g3sg1_slide.wav"
"weapons/galil_boltpull.wav"
"weapons/galil_clipin.wav"
"weapons/galil_clipout.wav"
"weapons/m4a1_boltpull.wav"
"weapons/m4a1_clipin.wav"
"weapons/m4a1_clipout.wav"
"weapons/m4a1_deploy.wav"
"weapons/m4a1_silencer_off.wav"
"weapons/m4a1_silencer_on.wav"
"weapons/m249_boxin.wav"
"weapons/m249_boxout.wav"
"weapons/m249_chain.wav"
"weapons/m249_coverdown.wav"
"weapons/m249_coverup.wav"
"weapons/mac10_boltpull.wav"
"weapons/mac10_clipin.wav"
"weapons/mac10_clipout.wav"
"weapons/mp5_clipin.wav"
"weapons/mp5_clipout.wav"
"weapons/mp5_slideback.wav"
"weapons/p90_boltpull.wav"
"weapons/p90_clipin.wav"
"weapons/p90_clipout.wav"
"weapons/p90_cliprelease.wav"
"weapons/p228_clipin.wav"
"weapons/p228_clipout.wav"
"weapons/p228_slidepull.wav"
"weapons/p228_sliderelease.wav"
"weapons/scout_bolt.wav"
"weapons/scout_clipin.wav"
"weapons/scout_clipout.wav"
"weapons/sg550_boltpull.wav"
"weapons/sg550_clipin.wav"
"weapons/sg550_clipout.wav"
"weapons/sg552_boltpull.wav"
"weapons/sg552_clipin.wav"
"weapons/sg552_clipout.wav"
"weapons/slideback1.wav"
"weapons/sliderelease1.wav"
"weapons/ump45_boltslap.wav"
"weapons/ump45_clipin.wav"
"weapons/ump45_clipout.wav"
"weapons/usp_clipin.wav"
"weapons/usp_clipout.wav"
"weapons/usp_silencer_off.wav"
"weapons/usp_silencer_on.wav"
"weapons/usp_slideback.wav"
"weapons/usp_sliderelease.wav"
```
Doing this will free **85** sounds from the precache list that you can now use for additional monsters.
## Known Bugs ## Known Bugs
I'm aware that the plugin is far from perfect, and there are a few things that need polishing *-especially the AI-*. I'll try to fix/will be fixing as the project evolves: I'm aware that the plugin is far from perfect, and there are a few things that need polishing *-especially the AI-*. I'll try to fix/will be fixing as the project evolves:

View File

@@ -12,14 +12,18 @@ All plugins in this section require AMXX 1.9.0 or greater, they will not work on
Compiled plugins are provided in the `bin` folder for your convenience. However, if you prefer to build the plugins yourself, the source code of all AMXX plugins are located in the `src` folder for compilation. Compiled plugins are provided in the `bin` folder for your convenience. However, if you prefer to build the plugins yourself, the source code of all AMXX plugins are located in the `src` folder for compilation.
#### GoldSrc --> MonsterMod Use Dispatcher #### Use Dispatcher
Because MonsterMod entities are, -quite literally-, just a func_wall with its own logic, trying to trigger any MonsterMod entity from the outside will fail, as it will attempt to use the logic of game's "func_wall" instead of our own. Because MonsterMod entities are, -quite literally-, just a func_wall with its own logic, trying to trigger any MonsterMod entity from the outside will fail, as it will attempt to use the logic of game's "func_wall" instead of our own.
To add salt to injury, Metamod is incapable of hooking use functions, as the pfnUse/DispatchUse methods provided by the API has been deprecated, and no longer work. Leaving AMXX's HamSandwich as the only module that can hook an entity's Use() function.
In normal circunstances, you do not need this plugin. But let's say you have a turret monster, disabled by default, and you gave it a targetname. Even with a name, triggering this turret regardless of the method used will not activate it. In normal circunstances, you do not need this plugin. But let's say you have a turret monster, disabled by default, and you gave it a targetname. Even with a name, triggering this turret regardless of the method used will not activate it.
This plugin redirects the game's func_wall Use() function to MonsterMod, connecting the missing piece and allowing you to trigger MonsterMod entities with your shiny func_button. The same problem occurs from the other side, a MonsterMod entity trying to trigger something will expect said entity to be part of MonsterMod as well.
I can't believe I've done this. *incomprehensible screams* This plugin redirects the game's func_wall Use() function to MonsterMod, as well as bridging Use() calls from MonsterMod back to the game, connecting the missing pieces and allowing you to trigger MonsterMod entities from the game, and game entities from MonsterMod.
#### External TakeDamage
When a MonsterMod entity tries to inflict damage to something, it expects said entity to be either a player or a MonsterMod monster. If something else is to be found, it will deal no damage to it, as it doesn't know how to manage it.
This plugin allows MonsterMod entities to inflict damage to normal game entities, such as breakables.

Binary file not shown.

View File

@@ -6,9 +6,15 @@
public plugin_init() public plugin_init()
{ {
register_plugin( "GAME-MONSTER: Use Dispatcher", "1.0", "Giegue" ); register_plugin( "GAME-MONSTER: Use Dispatcher", "1.1", "Giegue" );
register_cvar( "_glb_use", "1" );
// Game --> MonsterMod
RegisterHam( Ham_Use, "func_wall", "DispatchUse" ); RegisterHam( Ham_Use, "func_wall", "DispatchUse" );
// MonsterMod --> Game
register_srvcmd( "_trigger", "FireTargets" );
} }
public DispatchUse( entity, caller, activator, useType, Float:value ) public DispatchUse( entity, caller, activator, useType, Float:value )
@@ -22,3 +28,30 @@ public DispatchUse( entity, caller, activator, useType, Float:value )
return HAM_IGNORED; return HAM_IGNORED;
} }
public FireTargets()
{
if ( read_argc() == 6 )
{
new entity, caller, activator;
new Float:value;
new useType;
entity = read_argv_int( 1 );
caller = read_argv_int( 2 );
activator = read_argv_int( 3 );
value = read_argv_float( 4 );
useType = read_argv_int( 5 );
// caller and activator can be null, but never allow entity to be null
if ( !is_valid_ent( entity ) )
return;
if ( !is_valid_ent( caller ) )
caller = 0;
if ( !is_valid_ent( activator ) )
activator = 0;
ExecuteHamB( Ham_Use, entity, caller, activator, useType, value );
}
}

View File

@@ -0,0 +1,42 @@
#pragma semicolon 1
#include <amxmodx>
#include <engine>
#include <hamsandwich>
public plugin_init()
{
register_plugin( "GAME-MONSTER: External TakeDamage", "1.0", "Giegue" );
register_cvar( "_glb_takedamage", "1" );
// MonsterMod --> Game
register_srvcmd( "_takedamage", "TakeDamage" );
}
public TakeDamage()
{
if ( read_argc() == 6 )
{
new victim, inflictor, attacker;
new Float:damage;
new damageBits;
victim = read_argv_int( 1 );
inflictor = read_argv_int( 2 );
attacker = read_argv_int( 3 );
damage = read_argv_float( 4 );
damageBits = read_argv_int( 5 );
// attacker and inflictor can be null, but never allow victim to be null
if ( !is_valid_ent( victim ) )
return;
if ( !is_valid_ent( inflictor ) )
inflictor = 0;
if ( !is_valid_ent( attacker ) )
attacker = 0;
ExecuteHamB( Ham_TakeDamage, victim, inflictor, attacker, damage, damageBits );
}
}

17
extra/cstrike/README.md Normal file
View File

@@ -0,0 +1,17 @@
## Counter-Strike (cstrike)
Auxiliary Tools to use MonsterMod in Counter-Strike.
### AMX Mod X Plugins
#### -A note about AMXX plugins-
All plugins in this section require AMXX 1.9.0 or greater, they will not work on 1.8.2 or older.
Compiled plugins are provided in the `bin` folder for your convenience. However, if you prefer to build the plugins yourself, the source code of all AMXX plugins are located in the `src` folder for compilation.
#### Unprecacher
Counter-Strike precaches the sounds of all weapons. This means that sounds such as "clip-ins", "clip-outs" are added to the list, taking quite a bit of space in the precache count. Let it be a reminder that our good old GoldSrc can only store a maximum of 512 precached resources. Most of these sounds are handled client-side by the models themselves, so there is no need for them to be kept precached on the server. Only the weapons fire sounds are needed.
This plugin removes 85 sounds from the precache list, adding extra space for additional monsters to fit in the map.

Binary file not shown.

View File

@@ -0,0 +1,126 @@
#pragma semicolon 1
#include <amxmodx>
#include <fakemeta>
// List of sounds that must NOT be precached
new g_SoundList[][64] =
{
"weapons/ak47_boltpull.wav",
"weapons/ak47_clipin.wav",
"weapons/ak47_clipout.wav",
"weapons/aug_boltpull.wav",
"weapons/aug_boltslap.wav",
"weapons/aug_clipin.wav",
"weapons/aug_clipout.wav",
"weapons/aug_forearm.wav",
"weapons/awp_clipin.wav",
"weapons/awp_clipout.wav",
"weapons/awp_deploy.wav",
"weapons/boltdown.wav",
"weapons/boltpull1.wav",
"weapons/boltup.wav",
"weapons/clipin1.wav",
"weapons/clipout1.wav",
"weapons/de_clipin.wav",
"weapons/de_clipout.wav",
"weapons/de_deploy.wav",
"weapons/elite_clipout.wav",
"weapons/elite_deploy.wav",
"weapons/elite_leftclipin.wav",
"weapons/elite_reloadstart.wav",
"weapons/elite_rightclipin.wav",
"weapons/elite_sliderelease.wav",
"weapons/elite_twirl.wav",
"weapons/famas_boltpull.wav",
"weapons/famas_boltslap.wav",
"weapons/famas_clipin.wav",
"weapons/famas_clipout.wav",
"weapons/famas_forearm.wav",
"weapons/fiveseven_clipin.wav",
"weapons/fiveseven_clipout.wav",
"weapons/fiveseven_slidepull.wav",
"weapons/fiveseven_sliderelease.wav",
"weapons/g3sg1_clipin.wav",
"weapons/g3sg1_clipout.wav",
"weapons/g3sg1_slide.wav",
"weapons/galil_boltpull.wav",
"weapons/galil_clipin.wav",
"weapons/galil_clipout.wav",
"weapons/m4a1_boltpull.wav",
"weapons/m4a1_clipin.wav",
"weapons/m4a1_clipout.wav",
"weapons/m4a1_deploy.wav",
"weapons/m4a1_silencer_off.wav",
"weapons/m4a1_silencer_on.wav",
"weapons/m249_boxin.wav",
"weapons/m249_boxout.wav",
"weapons/m249_chain.wav",
"weapons/m249_coverdown.wav",
"weapons/m249_coverup.wav",
"weapons/mac10_boltpull.wav",
"weapons/mac10_clipin.wav",
"weapons/mac10_clipout.wav",
"weapons/mp5_clipin.wav",
"weapons/mp5_clipout.wav",
"weapons/mp5_slideback.wav",
"weapons/p90_boltpull.wav",
"weapons/p90_clipin.wav",
"weapons/p90_clipout.wav",
"weapons/p90_cliprelease.wav",
"weapons/p228_clipin.wav",
"weapons/p228_clipout.wav",
"weapons/p228_slidepull.wav",
"weapons/p228_sliderelease.wav",
"weapons/scout_bolt.wav",
"weapons/scout_clipin.wav",
"weapons/scout_clipout.wav",
"weapons/sg550_boltpull.wav",
"weapons/sg550_clipin.wav",
"weapons/sg550_clipout.wav",
"weapons/sg552_boltpull.wav",
"weapons/sg552_clipin.wav",
"weapons/sg552_clipout.wav",
"weapons/slideback1.wav",
"weapons/sliderelease1.wav",
"weapons/ump45_boltslap.wav",
"weapons/ump45_clipin.wav",
"weapons/ump45_clipout.wav",
"weapons/usp_clipin.wav",
"weapons/usp_clipout.wav",
"weapons/usp_silencer_off.wav",
"weapons/usp_silencer_on.wav",
"weapons/usp_slideback.wav",
"weapons/usp_sliderelease.wav"
};
public plugin_init()
{
register_plugin( "CS-MONSTER: Unprecacher", "1.0", "Giegue" );
}
public plugin_precache()
{
register_forward( FM_PrecacheSound, "fw_PrecacheSound" );
}
public fw_PrecacheSound( const sound[] )
{
static bool:bBlock, i;
bBlock = false;
i = 0;
for ( i = 0; i < sizeof( g_SoundList ); i++ )
{
if (contain( sound, g_SoundList[ i ] ) != -1 )
{
bBlock = true;
break;
}
}
if ( bBlock )
return FMRES_SUPERCEDE;
return FMRES_IGNORED;
}

View File

@@ -10,7 +10,7 @@ All plugins in this section require AMXX 1.9.0 or greater, they will not work on
Compiled plugins are provided in the `bin` folder for your convenience. However, if you prefer to build the plugins yourself, the source code of all AMXX plugins are located in the `src` folder for compilation. Compiled plugins are provided in the `bin` folder for your convenience. However, if you prefer to build the plugins yourself, the source code of all AMXX plugins are located in the `src` folder for compilation.
#### Half-Life <--> MonsterMod Bridge Plugin #### Bridge Plugin
MonsterMod monsters are hacked "func_wall"'s with simulated AI. Because of this, MonsterMod cannot interact with the Half-Life monsters. This issue also happens on the other side: The Half-Life monsters cannot interact with the MonsterMod monsters. MonsterMod monsters are hacked "func_wall"'s with simulated AI. Because of this, MonsterMod cannot interact with the Half-Life monsters. This issue also happens on the other side: The Half-Life monsters cannot interact with the MonsterMod monsters.

View File

@@ -14,9 +14,11 @@ const R_HT = 2; // (HATE) will attack this character instead of any visible DISL
new Trie:g_HLDefaultNames; new Trie:g_HLDefaultNames;
const bits_MEMORY_NAMED = ( 1 << 2 );
public plugin_init() public plugin_init()
{ {
register_plugin( "HL-MONSTER Bridge", "1.1", "Giegue" ); register_plugin( "HL-MONSTER Bridge", "1.2", "Giegue" );
RegisterHam( Ham_IRelationship, "monster_alien_controller", "mmIRelationship" ); RegisterHam( Ham_IRelationship, "monster_alien_controller", "mmIRelationship" );
RegisterHam( Ham_IRelationship, "monster_alien_grunt", "mmIRelationship" ); RegisterHam( Ham_IRelationship, "monster_alien_grunt", "mmIRelationship" );
@@ -69,8 +71,32 @@ public plugin_init()
TrieSetString( g_HLDefaultNames, "monster_nihilanth", "Nihilanth" ); TrieSetString( g_HLDefaultNames, "monster_nihilanth", "Nihilanth" );
TrieSetString( g_HLDefaultNames, "monster_tentacle", "Tentacle" ); TrieSetString( g_HLDefaultNames, "monster_tentacle", "Tentacle" );
set_task( 0.3, "hlScan", 0, "", 0, "b" ); // HACK: since Ham_Spawn won't work, this should do as an alternative
register_srvcmd( "monster_hurt_entity", "hlTakeDamage" ); RegisterHam( Ham_SetObjectCollisionBox, "monster_headcrab", "hlSpawn", 1 );
RegisterHam( Ham_SetObjectCollisionBox, "monster_babycrab", "hlSpawn", 1 );
RegisterHam( Ham_SetObjectCollisionBox, "monster_bullchicken", "hlSpawn", 1 );
RegisterHam( Ham_SetObjectCollisionBox, "monster_barnacle", "hlSpawn", 1 );
RegisterHam( Ham_SetObjectCollisionBox, "monster_bigmomma", "hlSpawn", 1 );
RegisterHam( Ham_SetObjectCollisionBox, "monster_houndeye", "hlSpawn", 1 );
RegisterHam( Ham_SetObjectCollisionBox, "monster_alien_slave", "hlSpawn", 1 );
RegisterHam( Ham_SetObjectCollisionBox, "monster_alien_controller", "hlSpawn", 1 );
RegisterHam( Ham_SetObjectCollisionBox, "monster_alien_grunt", "hlSpawn", 1 );
RegisterHam( Ham_SetObjectCollisionBox, "monster_zombie", "hlSpawn", 1 );
RegisterHam( Ham_SetObjectCollisionBox, "monster_ichthyosaur", "hlSpawn", 1 );
RegisterHam( Ham_SetObjectCollisionBox, "monster_human_grunt", "hlSpawn", 1 );
RegisterHam( Ham_SetObjectCollisionBox, "monster_human_assassin", "hlSpawn", 1 );
RegisterHam( Ham_SetObjectCollisionBox, "monster_barney", "hlSpawn", 1 );
RegisterHam( Ham_SetObjectCollisionBox, "monster_gman", "hlSpawn", 1 );
RegisterHam( Ham_SetObjectCollisionBox, "monster_scientist", "hlSpawn", 1 );
RegisterHam( Ham_SetObjectCollisionBox, "monster_sentry", "hlSpawn", 1 );
RegisterHam( Ham_SetObjectCollisionBox, "monster_snark", "hlSpawn", 1 );
RegisterHam( Ham_SetObjectCollisionBox, "monster_miniturret", "hlSpawn", 1 );
RegisterHam( Ham_SetObjectCollisionBox, "monster_turret", "hlSpawn", 1 );
RegisterHam( Ham_SetObjectCollisionBox, "monster_apache", "hlSpawn", 1 );
RegisterHam( Ham_SetObjectCollisionBox, "monster_osprey", "hlSpawn", 1 );
RegisterHam( Ham_SetObjectCollisionBox, "monster_gargantua", "hlSpawn", 1 );
RegisterHam( Ham_SetObjectCollisionBox, "monster_nihilanth", "hlSpawn", 1 );
RegisterHam( Ham_SetObjectCollisionBox, "monster_tentacle", "hlSpawn", 1 );
RegisterHam( Ham_Killed, "player", "PlayerKilled", 1 ); RegisterHam( Ham_Killed, "player", "PlayerKilled", 1 );
} }
@@ -94,43 +120,40 @@ public mmIRelationship( entity, other )
return HAM_OVERRIDE; return HAM_OVERRIDE;
} }
public hlScan() public hlSpawn( entity )
{ {
new entity, szClassname[ 33 ], szDisplayname[ 129 ], bool:found; // Why is it called 3 times? Restrict this to only once
for ( entity = 0; entity < get_global_int( GL_maxEntities ); entity++ ) if ( !( entity_get_int( entity, EV_INT_impulse ) & bits_MEMORY_NAMED ) )
{ {
// Nothing deleted me? // Classify not overriden?
if ( is_valid_ent( entity ) ) if ( !entity_get_int( entity, EV_INT_iuser4 ) )
{ {
entity_get_string( entity, EV_SZ_classname, szClassname, charsmax( szClassname ) ); // Set default
if ( equal( szClassname, "monster_", 8 ) ) entity_set_int( entity, EV_INT_iuser4, ExecuteHam( Ham_Classify, entity ) );
{
// Classify not overriden?
if ( !entity_get_int( entity, EV_INT_iuser4 ) )
{
// Set default
entity_set_int( entity, EV_INT_iuser4, ExecuteHam( Ham_Classify, entity ) );
}
// Blood color not overriden?
if ( !entity_get_int( entity, EV_INT_iuser3 ) )
{
// Set default
entity_set_int( entity, EV_INT_iuser3, ExecuteHam( Ham_BloodColor, entity ) );
}
// No name set?
entity_get_string( entity, EV_SZ_netname, szDisplayname, charsmax( szDisplayname ) );
if ( !strlen( szDisplayname ) )
{
// Find a default name
found = TrieGetString( g_HLDefaultNames, szClassname, szDisplayname, charsmax( szDisplayname ) );
// Use this name
entity_set_string( entity, EV_SZ_netname, ( found ? szDisplayname : "Monster" ) );
}
}
} }
// Blood color not overriden?
if ( !entity_get_int( entity, EV_INT_iuser3 ) )
{
// Set default
entity_set_int( entity, EV_INT_iuser3, ExecuteHam( Ham_BloodColor, entity ) );
}
// No name set?
new szDisplayname[ 129 ];
entity_get_string( entity, EV_SZ_netname, szDisplayname, charsmax( szDisplayname ) );
if ( !strlen( szDisplayname ) )
{
// Find a default name
new szClassname[ 33 ], bool:found;
entity_get_string( entity, EV_SZ_classname, szClassname, charsmax( szClassname ) );
found = TrieGetString( g_HLDefaultNames, szClassname, szDisplayname, charsmax( szDisplayname ) );
// Use this name
entity_set_string( entity, EV_SZ_netname, ( found ? szDisplayname : "Monster" ) );
}
entity_set_int( entity, EV_INT_impulse, entity_get_int( entity, EV_INT_impulse ) | bits_MEMORY_NAMED );
} }
} }
@@ -162,33 +185,6 @@ stock IRelationshipByClass( classEntity, classOther )
return iEnemy[ classEntity ][ classOther ]; return iEnemy[ classEntity ][ classOther ];
} }
public hlTakeDamage()
{
if ( read_argc() == 6 )
{
new victim, inflictor, attacker;
new Float:damage;
new damageBits;
victim = read_argv_int( 1 );
inflictor = read_argv_int( 2 );
attacker = read_argv_int( 3 );
damage = read_argv_float( 4 );
damageBits = read_argv_int( 5 );
// attacker and inflictor can be null, but never allow victim to be null
if ( !is_valid_ent( victim ) )
return;
if ( !is_valid_ent( inflictor ) )
inflictor = 0;
if ( !is_valid_ent( attacker ) )
attacker = 0;
ExecuteHamB( Ham_TakeDamage, victim, inflictor, attacker, damage, damageBits );
}
}
public PlayerKilled( victim, attacker, shouldgib ) public PlayerKilled( victim, attacker, shouldgib )
{ {
// don't obstruct monstermod // don't obstruct monstermod