Merge pull request #810 from protocultor/prefweap

Added prefweap command to select weapon by priority
This commit is contained in:
Yamagi 2022-04-13 11:51:33 +02:00 committed by GitHub
commit 6e45f5a66b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 115 additions and 0 deletions

View file

@ -10,6 +10,11 @@ original clients (Vanilla Quake II) commands are still in place.
skipped if it is not a valid weapon classname, you do not own it in skipped if it is not a valid weapon classname, you do not own it in
your inventory or you do not have enough ammo to use it. your inventory or you do not have enough ammo to use it.
* **prefweap <weapons>**: Similar to the previous command, this will
select the first weapon available in the priority list given. Useful
to set a "panic button". E.g. the following will select your best
shotgun: `prefweap weapon_supershotgun weapon_shotgun`.
* **gamemode <mode>**: Provides a convenient way to switch the game mode * **gamemode <mode>**: Provides a convenient way to switch the game mode
between `coop`, `dm` and `sp` without having to set three cvars the between `coop`, `dm` and `sp` without having to set three cvars the
correct way. `?` prints the current mode. correct way. `?` prints the current mode.

View file

@ -1558,6 +1558,112 @@ Cmd_CycleWeap_f(edict_t *ent)
} }
} }
static gitem_t *
preferred_weapon(edict_t *ent)
{
gclient_t *cl;
gitem_t *noammo_fallback;
gitem_t *noweap_fallback;
gitem_t *weap;
gitem_t *ammo;
int i;
int num_weaps;
if (!ent)
{
return NULL;
}
cl = ent->client;
if (!cl)
{
return NULL;
}
num_weaps = gi.argc();
noammo_fallback = NULL;
noweap_fallback = NULL;
/* find the first eligible weapon in the list we can switch to */
for (i = 1; i < num_weaps; i++)
{
weap = FindItemByClassname(gi.argv(i));
if (weap && (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;
}
}
}
/* 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_PrefWeap_f(edict_t *ent)
{
gitem_t *weap;
if (!ent)
{
return;
}
if (gi.argc() <= 1)
{
gi.cprintf(ent, PRINT_HIGH, "Usage: prefweap classname1 classname2 .. classnameN\n");
return;
}
weap = preferred_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 void
ClientCommand(edict_t *ent) ClientCommand(edict_t *ent)
{ {
@ -1710,6 +1816,10 @@ ClientCommand(edict_t *ent)
{ {
Cmd_CycleWeap_f(ent); Cmd_CycleWeap_f(ent);
} }
else if (Q_stricmp(cmd, "prefweap") == 0)
{
Cmd_PrefWeap_f(ent);
}
else /* anything that doesn't match a command will be a chat */ else /* anything that doesn't match a command will be a chat */
{ {
Cmd_Say_f(ent, false, true); Cmd_Say_f(ent, false, true);