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:
parent
af53ab36ef
commit
54e982bc14
11 changed files with 189 additions and 40 deletions
|
@ -14,42 +14,173 @@
|
|||
* 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.
|
||||
*/
|
||||
|
||||
enumflags {
|
||||
MMF_STARTON,
|
||||
MMF_UNUSED1,
|
||||
MMF_NONTOGGLE,
|
||||
MMF_MONSTERCLIP
|
||||
};
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
void monstermaker::Trigger ( void )
|
||||
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;
|
||||
}
|
||||
|
||||
void monstermaker :: monstermaker ( void )
|
||||
/* 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::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();
|
||||
|
||||
|
@ -58,6 +189,20 @@ void monstermaker :: monstermaker ( void )
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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],
|
||||
|
|
|
@ -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],
|
||||
|
|
|
@ -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],
|
||||
|
|
|
@ -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],
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue