game: Add support 'g_start_item'

Based on:
 * https://github.com/id-Software/quake2-rerelease-dll.git
This commit is contained in:
Denis Pauk 2024-12-18 15:24:24 +02:00
parent fdeabf515c
commit 7a3ebc7e99
10 changed files with 118 additions and 11 deletions

View file

@ -259,6 +259,8 @@ it's `+set busywait 0` (setting the `busywait` cvar) and `-portable`
* **g_itemsbobeffect**: Bob effect of items like in ReRelease. Defaults to `0`.
* **g_start_items**: List of start items on level.
* **g_swap_speed**: Sets the speed of the "changing weapon" animation.
Default is `1`. If set to `2`, it will be double the speed, `3` is
the triple... up until the max of `8`, since there are at least 2

View file

@ -281,7 +281,7 @@ Netchan_Transmit(netchan_t *chan, int length, byte *data)
}
else
{
Com_Printf("Netchan_Transmit: dumped unreliable\n");
Com_Printf("%s: dumped unreliable\n", __func__);
}
/* send the datagram */

View file

@ -4279,7 +4279,7 @@ CTFObserver(edict_t *ent)
ent->client->ps.gunindex = 0;
ent->client->resp.score = 0;
memcpy(userinfo, ent->client->pers.userinfo, sizeof(userinfo));
InitClientPersistant(ent->client);
InitClientPersistant(ent);
ClientUserinfoChanged(ent, userinfo);
gi.linkentity(ent);
CTFOpenJoinMenu(ent);

View file

@ -88,7 +88,7 @@ GetItemByIndex(int index)
}
gitem_t *
FindItemByClassname(char *classname)
FindItemByClassname(const char *classname)
{
int i;
gitem_t *it;
@ -117,7 +117,7 @@ FindItemByClassname(char *classname)
}
gitem_t *
FindItem(char *pickup_name)
FindItem(const char *pickup_name)
{
int i;
gitem_t *it;

View file

@ -104,6 +104,7 @@ cvar_t *g_quick_weap;
cvar_t *g_swap_speed;
cvar_t *g_language;
cvar_t *g_itemsbobeffect;
cvar_t *g_start_items;
cvar_t *g_game;
static void G_RunFrame(void);

View file

@ -1319,6 +1319,15 @@ SP_worldspawn(edict_t *ent)
}
}
if (st.start_items && *st.start_items)
{
level.start_items = st.start_items;
}
else
{
level.start_items = NULL;
}
/* --------------- */
/* help icon for statusbar */

View file

@ -384,6 +384,8 @@ typedef struct
edict_t *disguise_violator;
int disguise_violation_framenum;
char *start_items;
} level_locals_t;
/* spawn_temp_t is only used to hold entity field values that
@ -406,6 +408,7 @@ typedef struct
float pausetime;
char *item;
char *gravity;
char *start_items;
float minyaw;
float maxyaw;
@ -688,6 +691,7 @@ extern cvar_t *g_quick_weap;
extern cvar_t *g_swap_speed;
extern cvar_t *g_language;
extern cvar_t *g_itemsbobeffect;
extern cvar_t *g_start_items;
extern cvar_t *g_game;
/* this is for the count of monsters */
@ -761,8 +765,8 @@ void Cmd_Score_f(edict_t *ent);
void PrecacheItem(gitem_t *it);
void InitItems(void);
void SetItemNames(void);
gitem_t *FindItem(char *pickup_name);
gitem_t *FindItemByClassname(char *classname);
gitem_t *FindItem(const char *pickup_name);
gitem_t *FindItemByClassname(const char *classname);
#define ITEM_INDEX(x) ((x) - itemlist)
@ -958,7 +962,7 @@ edict_t *PlayerTrail_LastSpot(void);
void respawn(edict_t *ent);
void BeginIntermission(edict_t *targ);
void PutClientInServer(edict_t *ent);
void InitClientPersistant(gclient_t *client);
void InitClientPersistant(edict_t *ent);
void InitClientResp(gclient_t *client);
void InitBodyQue(void);
void ClientBeginServerFrame(edict_t *ent);

View file

@ -1244,16 +1244,85 @@ player_die(edict_t *self, edict_t *inflictor, edict_t *attacker,
/* ======================================================================= */
static void
Player_GiveStartItems(edict_t *ent, const char *ptr)
{
if (!ptr || !*ptr)
{
return;
}
while (*ptr)
{
char buffer[MAX_QPATH + 1] = {0};
const char *buffer_end = NULL, *item_name = NULL;
char *curr_buf;
buffer_end = strchr(ptr, ';');
if (!buffer_end)
{
buffer_end = ptr + strlen(ptr);
}
strncpy(buffer, ptr, Q_min(MAX_QPATH, buffer_end - ptr));
curr_buf = buffer;
item_name = COM_Parse(&curr_buf);
if (item_name)
{
gitem_t *item;
item = FindItemByClassname(item_name);
if (!item || !item->pickup)
{
gi.dprintf("%s: Invalid g_start_item entry: %s\n", __func__, item_name);
}
else
{
edict_t *dummy;
int count = 1;
if (*curr_buf)
{
count = atoi(COM_Parse(&curr_buf));
}
if (count == 0)
{
ent->client->pers.inventory[ITEM_INDEX(item)] = 0;
continue;
}
dummy = G_Spawn();
dummy->item = item;
dummy->count = count;
dummy->spawnflags |= DROPPED_PLAYER_ITEM;
item->pickup(dummy, ent);
G_FreeEdict(dummy);
}
}
/* skip end of section */
ptr = buffer_end;
if (*ptr == ';')
{
ptr ++;
}
}
}
/*
* This is only called when the game first
* initializes in single player, but is called
* after each death and level change in deathmatch
*/
void
InitClientPersistant(gclient_t *client)
InitClientPersistant(edict_t *ent)
{
gclient_t *client;
gitem_t *item;
client = ent->client;
if (!client)
{
return;
@ -1292,6 +1361,26 @@ InitClientPersistant(gclient_t *client)
/* Default chasecam to off */
client->pers.chasetoggle = 0;
/* start items */
if (*g_start_items->string)
{
if ((deathmatch->value || coop->value) && !sv_cheats->value)
{
gi.cprintf(ent, PRINT_HIGH,
"You must run the server with '+set cheats 1' to enable 'g_start_items'.\n");
return;
}
else
{
Player_GiveStartItems(ent, g_start_items->string);
}
}
if (level.start_items && *level.start_items)
{
Player_GiveStartItems(ent, level.start_items);
}
}
void
@ -2142,7 +2231,7 @@ PutClientInServer(edict_t *ent)
resp = client->resp;
memcpy(userinfo, client->pers.userinfo, sizeof(userinfo));
InitClientPersistant(client);
InitClientPersistant(ent);
ClientUserinfoChanged(ent, userinfo);
}
else if (coop->value)
@ -2188,7 +2277,7 @@ PutClientInServer(edict_t *ent)
if (client->pers.health <= 0)
{
InitClientPersistant(client);
InitClientPersistant(ent);
}
client->resp = resp;
@ -2638,7 +2727,7 @@ ClientConnect(edict_t *ent, char *userinfo)
if (!game.autosaved || !ent->client->pers.weapon)
{
InitClientPersistant(ent->client);
InitClientPersistant(ent);
}
}

View file

@ -266,6 +266,7 @@ InitGame(void)
g_language = gi.cvar("g_language", "english", CVAR_ARCHIVE);
g_itemsbobeffect = gi.cvar("g_itemsbobeffect", "0", CVAR_ARCHIVE);
g_game = gi.cvar("game", "", 0);
g_start_items = gi.cvar("g_start_items", "", 0);
/* initilize localization */
LocalizationInit();

View file

@ -106,6 +106,7 @@
{"item", STOFS(item), F_LRAWSTRING, FFL_SPAWNTEMP},
{"item", FOFS(item), F_ITEM},
{"gravity", STOFS(gravity), F_LRAWSTRING, FFL_SPAWNTEMP},
{"start_items", STOFS(start_items), F_LRAWSTRING, FFL_SPAWNTEMP},
{"sky", STOFS(sky), F_LRAWSTRING, FFL_SPAWNTEMP},
{"skyrotate", STOFS(skyrotate), F_FLOAT, FFL_SPAWNTEMP},
{"skyautorotate", STOFS(skyautorotate), F_INT, FFL_SPAWNTEMP},