Add compatibility with Half-Life.
This commit is contained in:
@@ -193,7 +193,7 @@ Current milestones are separated by "Tiers", which are as follows:
|
||||
- Update source code so it can compile AND run **ON WINDOWS**. **[DONE]**
|
||||
- Implement *-almost-* all Opposing Force monsters. **[DONE]**
|
||||
- Implement *-almost-* all default Sven Co-op monsters. **[DONE]**
|
||||
- Make MonsterMod aware of normal game entities. *-For those who want to use the plugin in vanilla HL.-*
|
||||
- Make MonsterMod aware of normal game entities. *-For those who want to use the plugin in vanilla HL.-* **[DONE]**
|
||||
- Custom model support.
|
||||
|
||||
### Tier 4
|
||||
|
||||
7
aux/README.md
Normal file
7
aux/README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
## Auxiliary Tools
|
||||
|
||||
This folder contains auxiliary tools used to enhance the compatibility and/or interaction of MonsterMod with other mods.
|
||||
|
||||
As these are auxiliary, they aren't needed to enjoy MonsterMod. If you want an extra boost, feel free to install these.
|
||||
|
||||
Once all milestones are completed, the possibility of removing the need for external plugins will be considered. Until then, this has to stay.
|
||||
19
aux/valve/README.md
Normal file
19
aux/valve/README.md
Normal file
@@ -0,0 +1,19 @@
|
||||
## Half-Life (valve)
|
||||
|
||||
Auxiliary Tools to use MonsterMod in the original Half-Life.
|
||||
|
||||
### 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.
|
||||
|
||||
#### Half-Life <--> MonsterMod 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.
|
||||
|
||||
In simple terms, this plugin acts as a "bridge" to help Half-Life and MonsterMod communicate with each other. With this plugin, HL and MM monsters can "see" and interact with each other, and will react accordingly.
|
||||
|
||||
Without this plugin, HL and MM monsters will be "invisible" to each other.
|
||||
BIN
aux/valve/bin/hl_monsterbridge.amxx
Normal file
BIN
aux/valve/bin/hl_monsterbridge.amxx
Normal file
Binary file not shown.
188
aux/valve/src/hl_monsterbridge.sma
Normal file
188
aux/valve/src/hl_monsterbridge.sma
Normal file
@@ -0,0 +1,188 @@
|
||||
#pragma semicolon 1
|
||||
|
||||
#include <amxmodx>
|
||||
#include <engine>
|
||||
#include <hamsandwich>
|
||||
|
||||
// (monster.h from HLSDK) monster to monster relationship types
|
||||
const R_AL = -2; // (ALLY) pals. Good alternative to R_NO when applicable.
|
||||
const R_FR = -1; // (FEAR) will run.
|
||||
const R_NO = 0; // (NO RELATIONSHIP) disregard.
|
||||
const R_DL = 1; // (DISLIKE) will attack.
|
||||
const R_HT = 2; // (HATE) will attack this character instead of any visible DISLIKEd characters.
|
||||
//const R_NM = 3; // (NEMESIS) a monster will ALWAYS attack its nemesis, no matter what.
|
||||
|
||||
new Trie:g_HLDefaultNames;
|
||||
|
||||
public plugin_init()
|
||||
{
|
||||
register_plugin( "HL-MONSTER Bridge", "1.0", "Giegue" );
|
||||
|
||||
RegisterHam( Ham_IRelationship, "monster_alien_controller", "mmIRelationship" );
|
||||
RegisterHam( Ham_IRelationship, "monster_alien_grunt", "mmIRelationship" );
|
||||
RegisterHam( Ham_IRelationship, "monster_alien_slave", "mmIRelationship" );
|
||||
RegisterHam( Ham_IRelationship, "monster_apache", "mmIRelationship" );
|
||||
RegisterHam( Ham_IRelationship, "monster_babycrab", "mmIRelationship" );
|
||||
RegisterHam( Ham_IRelationship, "monster_barnacle", "mmIRelationship" );
|
||||
RegisterHam( Ham_IRelationship, "monster_barney", "mmIRelationship" );
|
||||
RegisterHam( Ham_IRelationship, "monster_bigmomma", "mmIRelationship" );
|
||||
RegisterHam( Ham_IRelationship, "monster_bullchicken", "mmIRelationship" );
|
||||
RegisterHam( Ham_IRelationship, "monster_gargantua", "mmIRelationship" );
|
||||
RegisterHam( Ham_IRelationship, "monster_headcrab", "mmIRelationship" );
|
||||
RegisterHam( Ham_IRelationship, "monster_houndeye", "mmIRelationship" );
|
||||
RegisterHam( Ham_IRelationship, "monster_human_assassin", "mmIRelationship" );
|
||||
RegisterHam( Ham_IRelationship, "monster_human_grunt", "mmIRelationship" );
|
||||
RegisterHam( Ham_IRelationship, "monster_ichthyosaur", "mmIRelationship" );
|
||||
RegisterHam( Ham_IRelationship, "monster_miniturret", "mmIRelationship" );
|
||||
RegisterHam( Ham_IRelationship, "monster_scientist", "mmIRelationship" );
|
||||
RegisterHam( Ham_IRelationship, "monster_sentry", "mmIRelationship" );
|
||||
RegisterHam( Ham_IRelationship, "monster_snark", "mmIRelationship" );
|
||||
RegisterHam( Ham_IRelationship, "monster_turret", "mmIRelationship" );
|
||||
RegisterHam( Ham_IRelationship, "monster_zombie", "mmIRelationship" );
|
||||
|
||||
g_HLDefaultNames = TrieCreate();
|
||||
|
||||
// Better than a nest of if-else if i guess...
|
||||
TrieSetString( g_HLDefaultNames, "monster_headcrab", "Head Crab" );
|
||||
TrieSetString( g_HLDefaultNames, "monster_babycrab", "Baby Head Crab" );
|
||||
TrieSetString( g_HLDefaultNames, "monster_bullchicken", "Bullsquid" );
|
||||
TrieSetString( g_HLDefaultNames, "monster_barnacle", "Barnacle" );
|
||||
TrieSetString( g_HLDefaultNames, "monster_bigmomma", "Big Momma" );
|
||||
TrieSetString( g_HLDefaultNames, "monster_houndeye", "Houndeye" );
|
||||
TrieSetString( g_HLDefaultNames, "monster_alien_slave", "Alien Slave" );
|
||||
TrieSetString( g_HLDefaultNames, "monster_alien_controller", "Alien Controller" );
|
||||
TrieSetString( g_HLDefaultNames, "monster_alien_grunt", "Alien Grunt" );
|
||||
TrieSetString( g_HLDefaultNames, "monster_zombie", "Zombie" );
|
||||
TrieSetString( g_HLDefaultNames, "monster_ichthyosaur", "Ichthyosaur" );
|
||||
TrieSetString( g_HLDefaultNames, "monster_human_grunt", "Human Grunt" );
|
||||
TrieSetString( g_HLDefaultNames, "monster_human_assassin", "Female Assassin" );
|
||||
TrieSetString( g_HLDefaultNames, "monster_barney", "Barney" );
|
||||
TrieSetString( g_HLDefaultNames, "monster_gman", "Goverment Man" );
|
||||
TrieSetString( g_HLDefaultNames, "monster_scientist", "Scientist" );
|
||||
TrieSetString( g_HLDefaultNames, "monster_sentry", "Sentry Turret" );
|
||||
TrieSetString( g_HLDefaultNames, "monster_snark", "Snark" );
|
||||
TrieSetString( g_HLDefaultNames, "monster_miniturret", "Mini-Turret" );
|
||||
TrieSetString( g_HLDefaultNames, "monster_turret", "Turret" );
|
||||
TrieSetString( g_HLDefaultNames, "monster_apache", "Apache" );
|
||||
TrieSetString( g_HLDefaultNames, "monster_osprey", "Osprey Helicopter" );
|
||||
TrieSetString( g_HLDefaultNames, "monster_gargantua", "Gargantua" );
|
||||
TrieSetString( g_HLDefaultNames, "monster_nihilanth", "Nihilanth" );
|
||||
TrieSetString( g_HLDefaultNames, "monster_tentacle"," Tentacle" );
|
||||
|
||||
set_task( 0.3, "hlScan", 0, "", 0, "b" );
|
||||
register_srvcmd( "monster_hurt_entity", "hlTakeDamage" );
|
||||
}
|
||||
public plugin_end()
|
||||
{
|
||||
TrieDestroy( g_HLDefaultNames ); // free the handle
|
||||
}
|
||||
|
||||
public mmIRelationship( entity, other )
|
||||
{
|
||||
new selfClassify, otherClassify;
|
||||
|
||||
selfClassify = entity_get_int( entity, EV_INT_iuser4 );
|
||||
otherClassify = entity_get_int( other, EV_INT_iuser4 );
|
||||
|
||||
if ( entity_get_int( other, EV_INT_flags ) & FL_CLIENT )
|
||||
otherClassify = 2;
|
||||
|
||||
// Get proper relationship
|
||||
SetHamReturnInteger( IRelationshipByClass( selfClassify, otherClassify ) );
|
||||
return HAM_OVERRIDE;
|
||||
}
|
||||
|
||||
public hlScan()
|
||||
{
|
||||
new entity, szClassname[ 33 ], szDisplayname[ 129 ], bool:found;
|
||||
for ( entity = 0; entity < get_global_int( GL_maxEntities ); entity++ )
|
||||
{
|
||||
// Nothing deleted me?
|
||||
if ( is_valid_ent( entity ) )
|
||||
{
|
||||
entity_get_string( entity, EV_SZ_classname, szClassname, charsmax( szClassname ) );
|
||||
if ( equal( szClassname, "monster_", 8 ) )
|
||||
{
|
||||
// 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" ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stock IRelationshipByClass( classEntity, classOther )
|
||||
{
|
||||
if ( classEntity == -1 )
|
||||
classEntity = 0; // CLASS_FORCE_NONE
|
||||
|
||||
new iEnemy[16][16] =
|
||||
{ // NONE MACH PLYR HPASS HMIL AMIL APASS AMONST APREY APRED INSECT PLRALY PBWPN ABWPN RXPIT RXSHK
|
||||
/*NONE*/ { R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO, R_NO, R_NO, R_NO, R_NO },
|
||||
/*MACHINE*/ { R_NO ,R_NO ,R_DL ,R_DL ,R_NO ,R_DL ,R_DL ,R_DL ,R_DL ,R_DL ,R_NO ,R_DL, R_DL, R_DL, R_DL, R_DL },
|
||||
/*PLAYER*/ { R_NO ,R_DL ,R_NO ,R_NO ,R_DL ,R_DL ,R_DL ,R_DL ,R_DL ,R_DL ,R_NO ,R_NO, R_DL, R_DL, R_DL, R_DL },
|
||||
/*HUMANPASSIVE*/{ R_NO ,R_FR ,R_AL ,R_AL ,R_HT ,R_DL ,R_DL ,R_HT ,R_DL ,R_DL ,R_NO ,R_AL, R_NO, R_NO, R_FR, R_FR },
|
||||
/*HUMANMILITAR*/{ R_NO ,R_NO ,R_DL ,R_DL ,R_AL ,R_HT ,R_DL ,R_DL ,R_DL ,R_DL ,R_NO ,R_DL, R_NO, R_NO, R_HT, R_HT },
|
||||
/*ALIENMILITAR*/{ R_NO ,R_DL ,R_DL ,R_DL ,R_HT ,R_AL ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_DL, R_NO, R_NO, R_DL, R_HT },
|
||||
/*ALIENPASSIVE*/{ R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO, R_NO, R_NO, R_NO, R_NO },
|
||||
/*ALIENMONSTER*/{ R_NO ,R_DL ,R_DL ,R_DL ,R_DL ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_DL, R_NO, R_NO, R_NO, R_NO },
|
||||
/*ALIENPREY */{ R_NO ,R_NO ,R_DL ,R_DL ,R_DL ,R_NO ,R_NO ,R_NO ,R_NO ,R_FR ,R_NO ,R_DL, R_NO, R_NO, R_FR, R_NO },
|
||||
/*ALIENPREDATO*/{ R_NO ,R_NO ,R_DL ,R_DL ,R_DL ,R_NO ,R_NO ,R_NO ,R_HT ,R_NO ,R_NO ,R_DL, R_NO, R_NO, R_DL, R_DL },
|
||||
/*INSECT*/ { R_NO ,R_FR ,R_FR ,R_FR ,R_FR ,R_NO ,R_FR ,R_FR ,R_FR ,R_FR ,R_NO ,R_FR, R_NO, R_NO, R_NO, R_NO },
|
||||
/*PLAYERALLY*/ { R_NO ,R_DL ,R_AL ,R_NO ,R_DL ,R_DL ,R_DL ,R_DL ,R_DL ,R_DL ,R_NO ,R_NO, R_NO, R_NO, R_DL, R_DL },
|
||||
/*PBIOWEAPON*/ { R_NO ,R_NO ,R_NO ,R_NO ,R_DL ,R_DL ,R_DL ,R_DL ,R_DL ,R_DL ,R_NO ,R_NO, R_NO, R_DL, R_DL, R_DL },
|
||||
/*ABIOWEAPON*/ { R_NO ,R_NO ,R_DL ,R_DL ,R_DL ,R_AL ,R_NO ,R_DL ,R_DL ,R_NO ,R_NO ,R_DL, R_DL, R_NO, R_DL, R_DL },
|
||||
/*RXPITDRONE*/ { R_NO ,R_DL ,R_DL ,R_DL ,R_DL ,R_DL ,R_DL ,R_NO ,R_DL ,R_DL ,R_NO ,R_DL, R_NO, R_NO, R_AL, R_AL },
|
||||
/*RXSHOCKTRP*/ { R_NO ,R_DL ,R_HT ,R_DL ,R_HT ,R_HT ,R_DL ,R_NO ,R_NO ,R_DL ,R_NO ,R_DL, R_NO, R_NO, R_AL, R_AL }
|
||||
};
|
||||
|
||||
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 );
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user