From cf110b5ea0a47a0ca97c96eddb729cb3b222f2b0 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Sat, 13 Aug 2022 15:54:48 +0300 Subject: [PATCH] game: Add spawn on start point It could be used for spawn weapon or opponnent for coop at spawn point. --- doc/050_commands.md | 4 +++ src/client/cl_main.c | 1 + src/game/g_cmds.c | 66 +++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 70 insertions(+), 1 deletion(-) diff --git a/doc/050_commands.md b/doc/050_commands.md index fee62b8b..e01e8e10 100644 --- a/doc/050_commands.md +++ b/doc/050_commands.md @@ -26,11 +26,15 @@ original clients (Vanilla Quake II) commands are still in place. whitespaces. The special class `all` lists the coordinates of all entities. +* **viewpos**: Show player position. + * **teleport **: Teleports the player to the given coordinates. * **spawnentity classname x y z **: Spawn new entity of `classname` at `x y z` coordinates. +* **spawnonstart classname**: Spawn new entity of `classname` at start point. + * **listmaps**: Lists available maps for the player to load. Maps from loaded pak files will be listed first followed by maps placed in the current game's maps folder. diff --git a/src/client/cl_main.c b/src/client/cl_main.c index b1700ce1..4f1565b6 100644 --- a/src/client/cl_main.c +++ b/src/client/cl_main.c @@ -613,6 +613,7 @@ CL_InitLocal(void) Cmd_AddCommand("listentities", NULL); Cmd_AddCommand("teleport", NULL); Cmd_AddCommand("spawnentity", NULL); + Cmd_AddCommand("spawnonstart", NULL); Cmd_AddCommand("cycleweap", NULL); } diff --git a/src/game/g_cmds.c b/src/game/g_cmds.c index f5bc1f6d..52544c63 100644 --- a/src/game/g_cmds.c +++ b/src/game/g_cmds.c @@ -1325,7 +1325,67 @@ Cmd_SpawnEntity_f(edict_t *ent) ED_CallSpawn(ent); } -void +static void +Cmd_SpawnOnStartByClass(const char *classname, const vec3_t origin) +{ + edict_t *opponent = G_Spawn(); + + // set position + opponent->s.origin[0] = origin[0]; + opponent->s.origin[1] = origin[1]; + opponent->s.origin[2] = origin[2]; + // and class + opponent->classname = strdup(classname); + + ED_CallSpawn(opponent); + + gi.dprintf("Spawned entity at %f %f %f\n", + origin[0], origin[1], origin[2]); +} + +static void +Cmd_SpawnOnStart_f(edict_t *ent) +{ + edict_t *cur = NULL; + + if (!ent) + { + return; + } + + if ((deathmatch->value || coop->value) && !sv_cheats->value) + { + gi.cprintf(ent, PRINT_HIGH, + "You must run the server with '+set cheats 1' to enable this command.\n"); + return; + } + + if (gi.argc() != 2) + { + gi.cprintf(ent, PRINT_HIGH, "Usage: spawnonstart classname\n"); + return; + } + + while ((cur = G_Find(cur, FOFS(classname), + "info_player_deathmatch")) != NULL) + { + Cmd_SpawnOnStartByClass(gi.argv(1), cur->s.origin); + } + + while ((cur = G_Find(cur, FOFS(classname), + "info_player_coop")) != NULL) + { + Cmd_SpawnOnStartByClass(gi.argv(1), cur->s.origin); + } + + while ((cur = G_Find(cur, FOFS(classname), + "info_player_start")) != NULL) + { + Cmd_SpawnOnStartByClass(gi.argv(1), cur->s.origin); + } +} + +static void Cmd_ListEntities_f(edict_t *ent) { if ((deathmatch->value || coop->value) && !sv_cheats->value) @@ -1871,6 +1931,10 @@ ClientCommand(edict_t *ent) { Cmd_SpawnEntity_f(ent); } + else if (Q_stricmp(cmd, "spawnonstart") == 0) + { + Cmd_SpawnOnStart_f(ent); + } else if (Q_stricmp(cmd, "listentities") == 0) { Cmd_ListEntities_f(ent);