More work done on monstermaker in the gs-entbase. Needs a lot of testing.

Finally precaching player-models.
Fixed some crosshair arrangements in Opfor.
This commit is contained in:
Marco Cawthorne 2020-04-01 20:10:31 +02:00
parent af53ab36ef
commit 54e982bc14
11 changed files with 189 additions and 40 deletions

View file

@ -14,50 +14,195 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*QUAKED monstermaker (1 0 0) (-8 -8 -8) (8 8 8)
/*QUAKED monstermaker (1 0 0) (-8 -8 -8) (8 8 8) MMF_STARTON x MMF_NONTOGGLE MMF_MONSTERCLIP
"targetname" Name
"target" Target when triggered.
"killtarget" Target to kill when triggered.
All it does right now is spawn snarks, regardless of what monster you want to
spawn.
"monstertype" Type of monster to spawn, represents their entity classname.
"monstercount" Maximum amount of monsters you want spawned in total.
"delay" Delay between spawns in seconds.
"child_name" Applies this as a 'targetname' to spawned monsters.
"child_alivemax" Maximum amount of spawned monsters that are alive at a time.
The monster maker is the end-all solution to timed/controlled spawning of
monster entities.
When MMF_STARTON is checked, it'll start on automatically.
When MMF_NONTOGGLE is checked, it'll spawn only one monster with each trigger
When MMF_MONSTERCLIP is checked, all spawned monsters will be blocked by
func_monsterclip entities.
*/
class monstermaker : CBaseTrigger
{
string m_strMonster;
void() monstermaker;
virtual void() Trigger;
enumflags {
MMF_STARTON,
MMF_UNUSED1,
MMF_NONTOGGLE,
MMF_MONSTERCLIP
};
void monstermaker::Trigger ( void )
class monstermaker:CBaseTrigger
{
string m_strMonster;
int m_iMonsterSpawned;
int m_iMonsterCount;
float m_flDelay;
int m_iMaxChildren;
int m_iEnabled;
string m_strChildName;
void() monstermaker;
virtual void() Spawner;
virtual void() Trigger;
virtual void() Respawn;
virtual void() TurnOn;
virtual void() TurnOff;
virtual int() GetValue;
};
int
monstermaker::GetValue(void)
{
return m_iEnabled;
}
void
monstermaker::TurnOff(void)
{
think = __NULL__;
nextthink = 0;
m_iEnabled = 0;
}
void
monstermaker::TurnOn(void)
{
think = Spawner;
nextthink = time + m_flDelay;
m_iEnabled = 1;
}
void
monstermaker::Spawner(void)
{
static void monstermaker_spawnunit(void) {
/* these will get overwritten by the monster spawnfunction */
vector neworg = self.origin;
string tname = self.netname;
/* become the classname assigned */
CBaseMonster t = (CBaseMonster)self;
callfunction(self.classname);
/* apply the saved values back */
t.origin = t.m_oldOrigin = neworg;
t.m_strTargetName = tname;
/* spawn anew */
t.Respawn();
}
int c = 0;
/* look and count the buggers that are still around */
for (entity l = world; (l = find(l, ::classname, m_strMonster));) {
if (l.real_owner == this) {
/* may be a corpse? */
if (l.health > 0 && l.movetype == MOVETYPE_WALK) {
c++;
}
}
}
/* too many alive at a time */
if ((c >= m_iMaxChildren) || (m_flDelay == 0 && c >= 1)) {
nextthink = time + m_flDelay;
return;
}
if (isfunction(strcat("spawnfunc_", m_strMonster))) {
entity unit = spawn();
unit.classname = strcat("spawnfunc_", m_strMonster);
unit.netname = m_strChildName;
unit.think = monstermaker_spawnunit;
unit.nextthink = time + 0.1f;
unit.real_owner = this;
dprint(sprintf("^2monstermaker::^3Trigger^7: Spawning %s\n", m_strMonster));
setorigin(unit, origin);
m_iMonsterSpawned++;
if (m_strTarget) {
UseTargets();
}
/* inherit the monsterclip flag */
if (spawnflags & MMF_MONSTERCLIP) {
unit.spawnflags |= MSF_MONSTERCLIP;
}
} else {
print(sprintf("^1monstermaker::^3Trigger^7: cannot call spawnfunction for %s\n", m_strMonster));
}
/* shut off for good when we've spawned all we ever wanted */
if (m_iMonsterSpawned >= m_iMonsterCount) {
think = __NULL__;
return;
}
/* sometimes all we do is just spawn a single monster at a time */
if (spawnflags & MMF_NONTOGGLE) {
TurnOff();
} else {
nextthink = time + m_flDelay;
}
}
void monstermaker :: monstermaker ( void )
void
monstermaker::Trigger(void)
{
if (m_iEnabled)
TurnOff();
else
TurnOn();
}
void
monstermaker::Respawn(void)
{
if (spawnflags & MMF_STARTON) {
TurnOn();
} else {
TurnOff();
}
m_iMonsterSpawned = 0;
}
void
monstermaker::monstermaker(void)
{
CBaseTrigger::CBaseTrigger();
for ( int i = 1; i < ( tokenize( __fullspawndata ) - 1 ); i += 2 ) {
switch ( argv( i ) ) {
for (int i = 1; i < ( tokenize(__fullspawndata) - 1); i += 2) {
switch (argv(i)) {
case "monstertype":
m_strMonster = argv(i+1);
break;
case "monstercount":
m_iMonsterCount = stoi(argv(i+1));
break;
case "child_alivemax":
case "m_imaxlivechildren":
m_iMaxChildren = stoi(argv(i+1));
break;
case "delay":
m_flDelay = stof(argv(i+1));
break;
case "child_name":
case "netname":
m_strChildName = argv(i+1);
netname = __NULL__;
default:
break;
}

View file

@ -203,3 +203,14 @@ void CSEv_PlayerSwitchWeapon_f(float w)
pl.activeweapon = (int)w;
Weapons_Draw();
}
void
Player_Precache(void)
{
searchhandle pm;
pm = search_begin("models/player/*/*.mdl", TRUE, TRUE);
for (int i = 0; i < search_getsize(pm); i++) {
precache_model(search_getfilename(pm, i));
}
search_end(pm);
}

View file

@ -30,16 +30,7 @@ void Game_Worldspawn(void)
precache_model("models/w_weaponbox.mdl");
precache_sound("fvox/flatline.wav");
/* TODO: Scan and precache models/player/.mdl */
precache_model("models/player/barney/barney.mdl");
precache_model("models/player/gman/gman.mdl");
precache_model("models/player/gordon/gordon.mdl");
precache_model("models/player/hgrunt/hgrunt.mdl");
precache_model("models/player/scientist/scientist.mdl");
precache_model("models/player/zombie/zombie.mdl");
precache_model("models/player/helmet/helmet.mdl");
precache_model("models/player/recon/recon.mdl");
precache_model("models/player/robo/robo.mdl");
Player_Precache();
Weapons_Init();
SHData_Parse(mapname);
}

View file

@ -204,3 +204,14 @@ void CSEv_PlayerSwitchWeapon_f(float w)
pl.activeweapon = (int)w;
Weapons_Draw();
}
void
Player_Precache(void)
{
searchhandle pm;
pm = search_begin("models/player/*/*.mdl", TRUE, TRUE);
for (int i = 0; i < search_getsize(pm); i++) {
precache_model(search_getfilename(pm, i));
}
search_end(pm);
}

View file

@ -30,15 +30,7 @@ void Game_Worldspawn(void)
precache_model("models/w_weaponbox.mdl");
precache_sound("fvox/flatline.wav");
/* TODO: Scan and precache models/player/.mdl */
precache_model("models/player/barney/barney.mdl");
precache_model("models/player/gman/gman.mdl");
precache_model("models/player/gordon/gordon.mdl");
precache_model("models/player/hgrunt/hgrunt.mdl");
precache_model("models/player/scientist/scientist.mdl");
precache_model("models/player/zombie/zombie.mdl");
precache_model("models/player/helmet/helmet.mdl");
precache_model("models/player/recon/recon.mdl");
precache_model("models/player/robo/robo.mdl");
Player_Precache();
Weapons_Init();
Player_Precache();
}

View file

@ -286,7 +286,7 @@ w_displacer_hud(void)
vector cross_pos;
vector aicon_pos;
cross_pos = (g_hudres / 2) + [-12,-12];
cross_pos = g_hudmins + (g_hudres / 2) + [-12,-12];
aicon_pos = g_hudmins + [g_hudres[0] - 48, g_hudres[1] - 42];
drawsubpic(

View file

@ -274,7 +274,7 @@ w_eagle_crosshair(void)
lerp = Math_Lerp(18,6, trace_fraction);
jitter[0] = (random(0,2) - 2) * (1 - trace_fraction);
jitter[1] = (random(0,2) - 2) * (1 - trace_fraction);
cross_pos = (g_hudres / 2) + ([-lerp,-lerp] / 2);
cross_pos = g_hudmins + (g_hudres / 2) + ([-lerp,-lerp] / 2);
drawsubpic(
cross_pos + jitter,
[lerp,lerp],
@ -286,7 +286,7 @@ w_eagle_crosshair(void)
DRAWFLAG_ADDITIVE
);
} else {
cross_pos = (g_hudres / 2) + [-12,-12];
cross_pos = g_hudmins + (g_hudres / 2) + [-12,-12];
drawsubpic(
cross_pos,
[24,24],

View file

@ -224,7 +224,7 @@ w_m249_crosshair(void)
vector aicon_pos;
/* crosshair */
cross_pos = (g_hudres / 2) + [-12,-12];
cross_pos = g_hudmins + (g_hudres / 2) + [-12,-12];
drawsubpic(
cross_pos,
[24,24],

View file

@ -218,7 +218,7 @@ w_shockrifle_crosshair(void)
vector aicon_pos;
/* crosshair */
cross_pos = (g_hudres / 2) + [-12,-12];
cross_pos = g_hudmins + (g_hudres / 2) + [-12,-12];
drawsubpic(
cross_pos,
[24,24],

View file

@ -276,7 +276,7 @@ w_sporelauncher_crosshair(void)
vector aicon_pos;
/* crosshair */
cross_pos = (g_hudres / 2) + [-12,-12];
cross_pos = g_hudmins + (g_hudres / 2) + [-12,-12];
drawsubpic(
cross_pos,
[24,24],

View file

@ -108,7 +108,6 @@ void
monster_snark::Respawn(void)
{
netname = "Snark";
classname = "snark";
setmodel(this, "models/w_squeak.mdl");
flags |= FL_MONSTER;
solid = SOLID_BBOX;