mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2024-11-26 06:20:48 +00:00
Merge pull request #472 from BjossiAlfreds/cycleweap
Added cycleweap command for generalized xatrix-like weapon switching
This commit is contained in:
commit
e053710dbc
1 changed files with 162 additions and 0 deletions
|
@ -1400,6 +1400,164 @@ Cmd_ListEntities_f(edict_t *ent)
|
|||
}
|
||||
}
|
||||
|
||||
static int
|
||||
get_ammo_usage(gitem_t *weap)
|
||||
{
|
||||
if (!weap)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* handles grenades and tesla which only use 1 ammo per shot */
|
||||
/* have to check this because they don't store their ammo usage in weap->quantity */
|
||||
if (weap->flags & IT_AMMO)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* weapons store their ammo usage in the quantity field */
|
||||
return weap->quantity;
|
||||
}
|
||||
|
||||
static gitem_t *
|
||||
cycle_weapon(edict_t *ent)
|
||||
{
|
||||
gclient_t *cl;
|
||||
gitem_t *noammo_fallback;
|
||||
gitem_t *noweap_fallback;
|
||||
gitem_t *weap;
|
||||
gitem_t *ammo;
|
||||
int i;
|
||||
int start;
|
||||
int num_weaps;
|
||||
|
||||
if (!ent)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cl = ent->client;
|
||||
|
||||
if (!cl)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
num_weaps = gi.argc();
|
||||
|
||||
/* find where we want to start the search for the next eligible weapon */
|
||||
if (cl->pers.weapon)
|
||||
{
|
||||
for (i = 1; i < num_weaps; i++)
|
||||
{
|
||||
if (Q_stricmp(cl->pers.weapon->classname, gi.argv(i)) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
|
||||
if (i >= num_weaps)
|
||||
{
|
||||
i = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
i = 1;
|
||||
}
|
||||
|
||||
start = i;
|
||||
noammo_fallback = NULL;
|
||||
noweap_fallback = NULL;
|
||||
|
||||
/* find the first eligible weapon in the list we can switch to */
|
||||
do
|
||||
{
|
||||
weap = FindItemByClassname(gi.argv(i));
|
||||
|
||||
if (weap && weap != cl->pers.weapon && (weap->flags & IT_WEAPON) && weap->use)
|
||||
{
|
||||
if (cl->pers.inventory[ITEM_INDEX(weap)] > 0)
|
||||
{
|
||||
if (weap->ammo)
|
||||
{
|
||||
ammo = FindItem(weap->ammo);
|
||||
if (ammo)
|
||||
{
|
||||
if (cl->pers.inventory[ITEM_INDEX(ammo)] >= get_ammo_usage(weap))
|
||||
{
|
||||
return weap;
|
||||
}
|
||||
|
||||
if (!noammo_fallback)
|
||||
{
|
||||
noammo_fallback = weap;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return weap;
|
||||
}
|
||||
}
|
||||
else if (!noweap_fallback)
|
||||
{
|
||||
noweap_fallback = weap;
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
|
||||
if (i >= num_weaps)
|
||||
{
|
||||
i = 1;
|
||||
}
|
||||
} while (i != start);
|
||||
|
||||
/* if no weapon was found, the fallbacks will be used for
|
||||
printing the appropriate error message to the console
|
||||
*/
|
||||
|
||||
if (noammo_fallback)
|
||||
{
|
||||
return noammo_fallback;
|
||||
}
|
||||
|
||||
return noweap_fallback;
|
||||
}
|
||||
|
||||
void
|
||||
Cmd_CycleWeap_f(edict_t *ent)
|
||||
{
|
||||
gitem_t *weap;
|
||||
|
||||
if (!ent)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (gi.argc() <= 1)
|
||||
{
|
||||
gi.cprintf(ent, PRINT_HIGH, "Usage: cycleweap classname1 classname2 .. classnameN\n");
|
||||
return;
|
||||
}
|
||||
|
||||
weap = cycle_weapon(ent);
|
||||
if (weap)
|
||||
{
|
||||
if (ent->client->pers.inventory[ITEM_INDEX(weap)] <= 0)
|
||||
{
|
||||
gi.cprintf(ent, PRINT_HIGH, "Out of item: %s\n", weap->pickup_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
weap->use(ent, weap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ClientCommand(edict_t *ent)
|
||||
{
|
||||
|
@ -1548,6 +1706,10 @@ ClientCommand(edict_t *ent)
|
|||
{
|
||||
Cmd_ListEntities_f(ent);
|
||||
}
|
||||
else if (Q_stricmp(cmd, "cycleweap") == 0)
|
||||
{
|
||||
Cmd_CycleWeap_f(ent);
|
||||
}
|
||||
else /* anything that doesn't match a command will be a chat */
|
||||
{
|
||||
Cmd_Say_f(ent, false, true);
|
||||
|
|
Loading…
Reference in a new issue