mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2025-03-22 10:52:09 +00:00
game: Add support 'g_start_item'
Based on: * https://github.com/id-Software/quake2-rerelease-dll.git
This commit is contained in:
parent
fdeabf515c
commit
7a3ebc7e99
10 changed files with 118 additions and 11 deletions
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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},
|
||||
|
|
Loading…
Reference in a new issue