Fully implement spawnflags and entity-specific keyvalues.
This commit is contained in:
@@ -344,11 +344,12 @@ 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;
|
int monster_index;
|
||||||
edict_t *monster_pent;
|
edict_t *monster_pent;
|
||||||
|
KeyValueData kvd;
|
||||||
|
|
||||||
if ((monster_index = GetMonsterIndex()) == -1)
|
if ((monster_index = GetMonsterIndex()) == -1)
|
||||||
{
|
{
|
||||||
//META_CONS("[MONSTER] ERROR: No FREE Monster edicts!");
|
//META_CONS("[MONSTER] ERROR: No FREE Monster edicts!");
|
||||||
@@ -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.origin = origin;
|
||||||
monster_pent->v.angles = angles;
|
monster_pent->v.angles = angles;
|
||||||
|
|
||||||
// Since the entity is now linked to the class above,
|
// Keyvalue data
|
||||||
// it's pev->classname should be, theorically, safe to edit.
|
if (keyvalue != NULL)
|
||||||
// The pev->classname is set in the monster's Spawn() function.
|
{
|
||||||
//monster_pent->v.classname = MAKE_STRING("monster_zombie");
|
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();
|
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
|
monster_pent->v.fuser4 = monster_pent->v.health; // save the original health
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -447,7 +465,9 @@ void check_respawn(void)
|
|||||||
int monster_type;
|
int monster_type;
|
||||||
Vector origin;
|
Vector origin;
|
||||||
Vector angles;
|
Vector angles;
|
||||||
|
int spawnflags;
|
||||||
|
pKVD *keyvalue;
|
||||||
|
|
||||||
if (!monster_spawn->value)
|
if (!monster_spawn->value)
|
||||||
return; // monster_spawn is turned off, retry again later
|
return; // monster_spawn is turned off, retry again later
|
||||||
|
|
||||||
@@ -463,8 +483,12 @@ void check_respawn(void)
|
|||||||
origin = monster_spawnpoint[index].origin;
|
origin = monster_spawnpoint[index].origin;
|
||||||
|
|
||||||
angles = monster_spawnpoint[index].angles;
|
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...
|
// spawn_monster failed, retry again after delay...
|
||||||
monster_spawnpoint[index].need_to_respawn = TRUE;
|
monster_spawnpoint[index].need_to_respawn = TRUE;
|
||||||
@@ -602,7 +626,12 @@ void MonsterCommand(void)
|
|||||||
Vector view_angle = pPlayer->v.v_angle;
|
Vector view_angle = pPlayer->v.v_angle;
|
||||||
Vector v_src, v_dest;
|
Vector v_src, v_dest;
|
||||||
Vector monster_angle;
|
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...
|
// try to determine the best place to spawn the monster...
|
||||||
|
|
||||||
view_angle.x = 0; // zero the pitch (level horizontally)
|
view_angle.x = 0; // zero the pitch (level horizontally)
|
||||||
@@ -630,7 +659,7 @@ void MonsterCommand(void)
|
|||||||
if (monster_angle.y < 0)
|
if (monster_angle.y < 0)
|
||||||
monster_angle.y += 360;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
@@ -658,7 +687,7 @@ void MonsterCommand(void)
|
|||||||
if (monster_angle.y < 0)
|
if (monster_angle.y < 0)
|
||||||
monster_angle.y += 360;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
@@ -686,7 +715,7 @@ void MonsterCommand(void)
|
|||||||
if (monster_angle.y < 0)
|
if (monster_angle.y < 0)
|
||||||
monster_angle.y += 360;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
@@ -713,7 +742,7 @@ void MonsterCommand(void)
|
|||||||
if (monster_angle.y < 0)
|
if (monster_angle.y < 0)
|
||||||
monster_angle.y += 360;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
@@ -740,7 +769,7 @@ void MonsterCommand(void)
|
|||||||
if (monster_angle.y < 0)
|
if (monster_angle.y < 0)
|
||||||
monster_angle.y += 360;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
@@ -767,7 +796,7 @@ void MonsterCommand(void)
|
|||||||
if (monster_angle.y < 0)
|
if (monster_angle.y < 0)
|
||||||
monster_angle.y += 360;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ void scan_monster_cfg(FILE *fp)
|
|||||||
{
|
{
|
||||||
// Proper start, initialize entity creation
|
// Proper start, initialize entity creation
|
||||||
// Temporary variables to store entity data
|
// 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;
|
int kvd_index = 0;
|
||||||
while (get_input(fp, input))
|
while (get_input(fp, input))
|
||||||
{
|
{
|
||||||
@@ -161,7 +161,7 @@ void scan_monster_cfg(FILE *fp)
|
|||||||
if (monster)
|
if (monster)
|
||||||
{
|
{
|
||||||
// The line is a little too long, no?
|
// 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.
|
// Done. Let's process the keyvalues.
|
||||||
@@ -230,11 +230,11 @@ void scan_monster_cfg(FILE *fp)
|
|||||||
{
|
{
|
||||||
if (monster)
|
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
|
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)");
|
LOG_MESSAGE(PLID, "ERROR: entity spawnflags will be set to none (0)");
|
||||||
x = 0;
|
x = 0;
|
||||||
}
|
}
|
||||||
@@ -247,8 +247,8 @@ void scan_monster_cfg(FILE *fp)
|
|||||||
// Save it for later
|
// Save it for later
|
||||||
if (monster)
|
if (monster)
|
||||||
{
|
{
|
||||||
strcpy(data[i].key, monster_spawnpoint[monster_spawn_count].keyvalue[i].key);
|
strcpy(monster_spawnpoint[monster_spawn_count].keyvalue[i].key, data[i].key);
|
||||||
strcpy(data[i].value, monster_spawnpoint[monster_spawn_count].keyvalue[i].value);
|
strcpy(monster_spawnpoint[monster_spawn_count].keyvalue[i].value, data[i].value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ typedef struct pKVD
|
|||||||
char value[33];
|
char value[33];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define MAX_KEYVALUES 32
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
char *name;
|
char *name;
|
||||||
|
|||||||
Reference in New Issue
Block a user