Fully implement spawnflags and entity-specific keyvalues.

This commit is contained in:
Julian
2020-03-17 21:21:03 -03:00
parent 77b35148ec
commit 6869a89463
3 changed files with 55 additions and 24 deletions

View File

@@ -344,10 +344,11 @@ void check_monster_dead(void)
}
bool spawn_monster(int monster_type, Vector origin, Vector angles, int respawn_index)
bool spawn_monster(int monster_type, Vector origin, Vector angles, int respawn_index, int spawnflags, pKVD *keyvalue)
{
int monster_index;
edict_t *monster_pent;
KeyValueData kvd;
if ((monster_index = GetMonsterIndex()) == -1)
{
@@ -429,13 +430,30 @@ bool spawn_monster(int monster_type, Vector origin, Vector angles, int respawn_i
monster_pent->v.origin = origin;
monster_pent->v.angles = angles;
// Since the entity is now linked to the class above,
// it's pev->classname should be, theorically, safe to edit.
// The pev->classname is set in the monster's Spawn() function.
//monster_pent->v.classname = MAKE_STRING("monster_zombie");
// Keyvalue data
if (keyvalue != NULL)
{
for (int index = 0; index < MAX_KEYVALUES; index++)
{
if (strlen(keyvalue[index].key) > 0)
{
kvd.szKeyName = keyvalue[index].key;
kvd.szValue = keyvalue[index].value;
monsters[monster_index].pMonster->KeyValue( &kvd );
}
}
}
monster_pent->v.spawnflags = spawnflags;
monsters[monster_index].pMonster->Spawn();
monster_pent->v.spawnflags = SF_MONSTER_FADECORPSE;
// Reverse fadecorpse behaviour
if ( ( spawnflags & SF_MONSTER_FADECORPSE ) )
monster_pent->v.spawnflags &= ~SF_MONSTER_FADECORPSE;
else
monster_pent->v.spawnflags |= SF_MONSTER_FADECORPSE;
monster_pent->v.fuser4 = monster_pent->v.health; // save the original health
return FALSE;
@@ -447,6 +465,8 @@ void check_respawn(void)
int monster_type;
Vector origin;
Vector angles;
int spawnflags;
pKVD *keyvalue;
if (!monster_spawn->value)
return; // monster_spawn is turned off, retry again later
@@ -464,7 +484,11 @@ void check_respawn(void)
angles = monster_spawnpoint[index].angles;
if (spawn_monster(monster_type, origin, angles, index))
spawnflags = monster_spawnpoint[index].spawnflags;
keyvalue = monster_spawnpoint[index].keyvalue;
if (spawn_monster(monster_type, origin, angles, index, spawnflags, keyvalue))
{
// spawn_monster failed, retry again after delay...
monster_spawnpoint[index].need_to_respawn = TRUE;
@@ -603,6 +627,11 @@ void MonsterCommand(void)
Vector v_src, v_dest;
Vector monster_angle;
// If spawning a turret, add autostart spawnflag. Zero otherwise
int spawnflags = 0;
if (monster_type >= 15 && monster_type <= 17) // Turret, Mini-Turret and Sentry
spawnflags = SF_MONSTER_TURRET_AUTOACTIVATE;
// try to determine the best place to spawn the monster...
view_angle.x = 0; // zero the pitch (level horizontally)
@@ -630,7 +659,7 @@ void MonsterCommand(void)
if (monster_angle.y < 0)
monster_angle.y += 360;
spawn_monster(monster_type, v_src, monster_angle, -1);
spawn_monster(monster_type, v_src, monster_angle, -1, spawnflags, NULL);
return;
}
@@ -658,7 +687,7 @@ void MonsterCommand(void)
if (monster_angle.y < 0)
monster_angle.y += 360;
spawn_monster(monster_type, v_src, monster_angle, -1);
spawn_monster(monster_type, v_src, monster_angle, -1, spawnflags, NULL);
return;
}
@@ -686,7 +715,7 @@ void MonsterCommand(void)
if (monster_angle.y < 0)
monster_angle.y += 360;
spawn_monster(monster_type, v_src, monster_angle, -1);
spawn_monster(monster_type, v_src, monster_angle, -1, spawnflags, NULL);
return;
}
@@ -713,7 +742,7 @@ void MonsterCommand(void)
if (monster_angle.y < 0)
monster_angle.y += 360;
spawn_monster(monster_type, v_src, monster_angle, -1);
spawn_monster(monster_type, v_src, monster_angle, -1, spawnflags, NULL);
return;
}
@@ -740,7 +769,7 @@ void MonsterCommand(void)
if (monster_angle.y < 0)
monster_angle.y += 360;
spawn_monster(monster_type, v_src, monster_angle, -1);
spawn_monster(monster_type, v_src, monster_angle, -1, spawnflags, NULL);
return;
}
@@ -767,7 +796,7 @@ void MonsterCommand(void)
if (monster_angle.y < 0)
monster_angle.y += 360;
spawn_monster(monster_type, v_src, monster_angle, -1);
spawn_monster(monster_type, v_src, monster_angle, -1, spawnflags, NULL);
return;
}

View File

@@ -76,7 +76,7 @@ void scan_monster_cfg(FILE *fp)
{
// Proper start, initialize entity creation
// Temporary variables to store entity data
pKVD *data = (pKVD*)malloc(32*sizeof(*data)); // Entities should not have more than 32 keyvalues
pKVD *data = (pKVD*)malloc(MAX_KEYVALUES*sizeof(*data)); // Entities should not have more than this many keyvalues
int kvd_index = 0;
while (get_input(fp, input))
{
@@ -161,7 +161,7 @@ void scan_monster_cfg(FILE *fp)
if (monster)
{
// The line is a little too long, no?
monster_spawnpoint[monster_spawn_count].keyvalue = (pKVD*)calloc(32, sizeof(*monster_spawnpoint[monster_spawn_count].keyvalue));
monster_spawnpoint[monster_spawn_count].keyvalue = (pKVD*)calloc(MAX_KEYVALUES, sizeof(*monster_spawnpoint[monster_spawn_count].keyvalue));
}
// Done. Let's process the keyvalues.
@@ -230,11 +230,11 @@ void scan_monster_cfg(FILE *fp)
{
if (monster)
{
if (sscanf(data[i].value, "%i", &x) != 1)
if (sscanf(data[i].value, "%f", &x) != 1)
{
LOG_MESSAGE(PLID, "ERROR: invalid spawnflags: %s", input); // print conflictive line
// default to 30 seconds
// default to no spawnflags
LOG_MESSAGE(PLID, "ERROR: entity spawnflags will be set to none (0)");
x = 0;
}
@@ -247,8 +247,8 @@ void scan_monster_cfg(FILE *fp)
// Save it for later
if (monster)
{
strcpy(data[i].key, monster_spawnpoint[monster_spawn_count].keyvalue[i].key);
strcpy(data[i].value, monster_spawnpoint[monster_spawn_count].keyvalue[i].value);
strcpy(monster_spawnpoint[monster_spawn_count].keyvalue[i].key, data[i].key);
strcpy(monster_spawnpoint[monster_spawn_count].keyvalue[i].value, data[i].value);
}
}
}

View File

@@ -11,6 +11,8 @@ typedef struct pKVD
char value[33];
};
#define MAX_KEYVALUES 32
typedef struct
{
char *name;