Skip to content
Permalink
Browse files

allow symbolic arguments for some commands

* new command "listoptions" lists the argument options for several
  argument types like entities, weapons and teamnames
* "burstshots", "weapon", "magcontent", "magreserve", "fragmessage" and
  "gibmessage" now allow guns to be specified by name
* "addpunct" allows plaintext arguments like "brackets" and "quotes"
* the "team" command now understands numeric teams
* entity types can now be specified by type index number
* removed some lists from the config files (now provided by listoptions)
* added argument completion for several commands
* change nextprimary from integer to string variable

DOCREF listoptions burstshots weapon addpunct
DOCREF fragmessage gibmessage magcontent magreserve
DOCREF nextprimary
  • Loading branch information...
ac-stef committed Feb 21, 2015
1 parent e89b2ea commit 47f71f128895f153a656f54451f31718ed4df90b
@@ -12,66 +12,16 @@ menuitem [Misc settings] [ showmenu Misc ]
menuitem [] -1
menuitem [Reset all settings] [ showmenu [Reset settings] ]

const isprimary [ return (|| (|| (|| (= $arg1 $SNIPER) (= $arg1 $SHOTGUN)) (|| (= $arg1 $AR) (= $arg1 $SMG))) (= $arg1 $CARBINE)) ]

const getcustomprimarydirs [
customprimarydirs = []
loop gcp $NUM_WEAPONS [
if (! (isprimary $gcp)) [ add2list customprimarydirs (addpunct [ ]) ] [
add2list customprimarydirs (at $ALTERNATIVE_WEAPONS (+ (* $gcp 3) 2))
]
]
return $customprimarydirs
]

const loadcustomprimary [
nargs = $numargs
if (> $nargs 0) [
li = $arg1
if (isprimary $li) [
tmp = (getalias (at $WEAPONS $li))
customphud = (format modmdlweap%1 $tmp)
custompwld = (format modmdlvwep%1 $tmp)
if (> $nargs 1) [ // revert to default primary HUD model if any 2nd argument is given
delalias $customphud; delalias $custompwld
] [ // else try loading the custom primary models
cdirlist = (getcustomprimarydirs)
if (listlen $cdirlist) [
dirtotry = (at $cdirlist $li)
if (strlen $dirtotry) [
$customphud = $dirtotry
$custompwld = $dirtotry
]
]
]
]
]
]

const DEFAULT_PRIMARIES ["MTP-57 Assault Rifle" "A-ARD/10 Submachine Gun" "Precision Tech AD-81 Sniper Rifle" "V-19 Combat Shotgun" "TMP-M&A Carbine"]
const DEFAULT_PRALIASES [AR SMG SNIPER SHOTGUN CARBINE]
const DEFAULT_PRMDLDIRS [assault subgun sniper shotgun carbine]

const CUSTOM_PRIMARIES ["AR-15 Assault Rifle" "Mac11 Submachine Gun" "Dragunov SVD Sniper Rifle" "Sawed-off Shotgun" "Marlin Guide Carbine 1895"]
const CUSTOM_PRMDLDIRS [assault2 subgun2 sniper2 shotgun2 carbine2]

newmenu Weapons

menumdl weapons/assault/menu mapmodel 75 12
loop gwm (listlen $DEFAULT_PRIMARIES) [
execute (format [menuitem [%1] [ nextprimary (getalias %2); loadcustomprimary (getalias %2) 0; echo %1 selected ] [ chmenumdl Weapons weapons/%3/menu mapmodel 75 12 ]] (at $DEFAULT_PRIMARIES $gwm) (at $DEFAULT_PRALIASES $gwm) (at $DEFAULT_PRMDLDIRS $gwm))
]
// menuitem [] -1
// menuitem [Alternative weapons...] [ showmenu [Alternative Weapons] ]

// newmenu [Alternative Weapons]

// menumdl weapons/assault2/menu mapmodel 75 12
// loop cwm (listlen $CUSTOM_PRIMARIES) [
// execute (format [menuitem [%1] [ nextprimary (getalias %2); loadcustomprimary (getalias %2); echo %1 selected ] [ chmenumdl [Alternative Weapons] weapons/%3/menu mapmodel 75 12 ]] (at $CUSTOM_PRIMARIES $cwm) (at $DEFAULT_PRALIASES $cwm) (at $CUSTOM_PRMDLDIRS $cwm))
// ]
// menuitem [] -1
// menuitem [Other alternative weapons...] [ showmenu [Alternative Weapon Models] ]
looplist [
assault "MTP-57 Assault Rifle"
subgun "A-ARD/10 Submachine Gun"
sniper "Precision Tech AD-81 Sniper Rifle"
shotgun "V-19 Combat Shotgun"
carbine "TMP-M&A Carbine"
] [ w desc ] [execute (format [menuitem [%2] [nextprimary %1 ; echo %2 selected] [chmenumdl Weapons weapons/%1/menu mapmodel 75 12] ] $w $desc) ]

newmenu CLA

@@ -445,12 +395,12 @@ menuitemslider [Play hit sounds: ] 0 2 "$hitsound" 1 [Off "When server detects h
menuitemcheckbox [Auto weapon reload: ] "$autoreload" [ autoreload $arg1 ]
menuitemcheckbox [Auto switch to akimbo upon pickup: ] "$akimboautoswitch" [ akimboautoswitch $arg1 ]
menuitemslider [Akimbo end action: ] 0 3 "$akimboendaction" 1 ["Switch to knife" "Stay with pistol" "Switch to grenades" "Switch to primary"] [ akimboendaction $arg1 ]
menuitemcheckbox [SMG - Full Auto?] "(= (burstshots $SMG -1) 0)" [ if (= $arg1 0) [ burstshots $SMG (at $default_bursts 0) ] [ burstshots $SMG 0 ]; refreshWSM ]
menuitemcheckbox [AR - Full Auto?] "(= (burstshots $AR -1) 0)" [ if (= $arg1 0) [ burstshots $AR (at $default_bursts 1) ] [ burstshots $AR 0 ]; refreshWSM ]
menuitemcheckbox [Akimbo - Full Auto?] "(= (burstshots $AKIMBO -1) 0)" [ if (= $arg1 0) [ burstshots $AKIMBO (at $default_bursts 2) ] [ burstshots $AKIMBO 0 ]; refreshWSM ]
menuitemslider [SMG - Shots per burst: ] 0 29 "(burstshots $SMG -1)" 1 [] [ burstshots $SMG $arg1; refreshWSM ]
menuitemslider [AR - Shots per burst: ] 0 19 "(burstshots $AR -1)" 1 [] [ burstshots $AR $arg1; refreshWSM ]
menuitemslider [Akimbo - Shots per burst: ] 0 19 "(burstshots $AKIMBO -1)" 1 [] [ burstshots $AKIMBO $arg1; refreshWSM ]
menuitemcheckbox [SMG - Full Auto?] "(= (burstshots SUBGUN -1) 0)" [ if (= $arg1 0) [ burstshots SUBGUN (at $default_bursts 0) ] [ burstshots SUBGUN 0 ]; refreshWSM ]
menuitemcheckbox [AR - Full Auto?] "(= (burstshots ASSAULT -1) 0)" [ if (= $arg1 0) [ burstshots ASSAULT (at $default_bursts 1) ] [ burstshots ASSAULT 0 ]; refreshWSM ]
menuitemcheckbox [Akimbo - Full Auto?] "(= (burstshots AKIMBO -1) 0)" [ if (= $arg1 0) [ burstshots AKIMBO (at $default_bursts 2) ] [ burstshots AKIMBO 0 ]; refreshWSM ]
menuitemslider [SMG - Shots per burst: ] 0 29 "(burstshots SUBGUN -1)" 1 [] [ burstshots SUBGUN $arg1; refreshWSM ]
menuitemslider [AR - Shots per burst: ] 0 19 "(burstshots ASSAULT -1)" 1 [] [ burstshots ASSAULT $arg1; refreshWSM ]
menuitemslider [Akimbo - Shots per burst: ] 0 19 "(burstshots AKIMBO -1)" 1 [] [ burstshots AKIMBO $arg1; refreshWSM ]
if (! (checkalias nickhighlight)) [ nickhighlight = 0 ]
@@ -76,11 +76,17 @@ const run [ exec (concatword config/ $arg1 .cfg) ]
const mapcomplete [complete $arg1 "packages/maps/official packages/maps" cgz]
loop i (listlen (concat $MODES $MODEALIASES)) [ mapcomplete (at (concat $MODES $MODEALIASES) $i) ]
complete demo demos dmo
const entcomplete [ listcomplete $arg1 [light playerstart pistol ammobox grenades health armour akimbo mapmodel ladder ctf-flag sound clip plclip helmet] ]
entcomplete newent; entcomplete clearents; entcomplete closestenttype
// TODO:FIXME change all occurrence of SPECT(ator) to GHOST
listcomplete team [CLA RVSF CLA-SPECT RVSF-SPECT SPECTATOR]
looplist [
listoptions ""
newent ents
clearents ents
closestenttype ents
weapon weapons
burstshots weapons
team teamnames
addpunct punctuations // the command addpunct actually wants the punctuation name as second argument, but we can't do that. sry.
] [ cmd options ] [ listcomplete $cmd (listoptions $options)
]

// Game mode descriptions...
gamemodedesc 0 [Team Deathmatch: Shred the enemy team to pieces!]
@@ -108,20 +114,13 @@ const resetbinds [ run resetbinds; echo (c 3)All binds have been reset to defaul
const changeteam [ if (< (player1 team) 4) [ team (at [RVSF CLA RVSF-SPECT CLA-SPECT] (player1 team)) ] ]
const WEAPONS [KNIFE PISTOL CARBINE SHOTGUN SMG SNIPER AR CPISTOL GRENADES AKIMBO]
const NUM_WEAPONS (listlen $WEAPONS)
const NUM_WEAPONS (listlen (listoptions weapons))
const NUM_MODES (listlen $MODES)
const PUNCTUATION "QUOTES BRACKETS PARENTHESIS _$_ QUOTE PERCENT"
const MAX_CLIENTS 16
const MAX_BOT_MATCH_LENGTH 60
const MAX_ARGS 24
const ENT_NUM_ATTRS 4

loop g (listlen $PUNCTUATION) [ const (at $PUNCTUATION $g) $g ]
// echo (addpunct "hello world" $PARENTHESIS) - output: (hello world)
// echo (addpunct "hello world" $BRACKETS) - output: [hello world]

loop d $NUM_WEAPONS [ const (at $WEAPONS $d) $d ]
const getgunindex [ findlist (listoptions weapons) $arg1 ]
loop r $NUM_MODES [ const (at $MODES $r) (format [votemap %1 %2 %3] $r "$arg1" "$arg2") ]
@@ -158,11 +157,11 @@ const add2bind [ if (! (strstr (keybind $arg1) $arg2)) [ bind $arg1 (form
const hasprimary [ result (= (curweapon) (currentprimary)) ]
const primary [ weapon (currentprimary) ]
const ptoggle [ if (hasprimary) $arg1 primary ] // Toggle between primary/specified weapon
const secondary [ weapon $PISTOL ]
const secondary [ weapon PISTOL ]
const sndtoggle [ ptoggle secondary ]
const melee [ weapon $KNIFE ]
const melee [ weapon KNIFE ]
const knftoggle [ ptoggle melee ]
const grenades [ weapon $GRENADES ]
const grenades [ weapon GRENADES ]
const gndtoggle [ ptoggle grenades ]

const altaction [ (concatword altaction_ (curweapon)) ]
@@ -172,10 +171,10 @@ const checkrange [ result (&& (>=f $arg1 $arg2) (<=f $arg1 $arg3)) ]

loop i $NUM_WEAPONS [ (concatword altaction_ $i) = quicknadethrow ] // Quick nade throw is default
// Use format to define altaction_N aliases from now on, makes for less edits in the future if weapon IDs change. - Bukz
// (format altaction_%1 $KNIFE) = [ if (checkmag (currentprimary)) primary [ if (|| (checkmag $PISTOL) (checkmag $AKIMBO)) secondary [ if (checkmag $GRENADES) grenades ] ] ] // Knife // uncomment to switch to primary/secondary/grenades with MOUSE2 depending on ammo content for each.
(format altaction_%1 $SNIPER) = [ setscope 1; onrelease [ setscope 0 ] ] // Sniper
// (format altaction_%1 $CPISTOL) = [ setburst 1; onrelease [ setburst 0 ] ] // Combat pistol // TODO uncomment when this becomes a priority/testing, for now lets save an unused alias - Bukz
// (format altaction_%1 $GRENADES) = attack // Grenade // with this comment, you throw the nade and the nade is unselected : Brahma
// (format altaction_%1 (getgunindex knife)) = [ if (checkmag (currentprimary)) primary [ if (|| (checkmag PISTOL) (checkmag AKIMBO)) secondary [ if (checkmag GRENADES) grenades ] ] ] // Knife // uncomment to switch to primary/secondary/grenades with MOUSE2 depending on ammo content for each.
(format altaction_%1 (getgunindex sniper)) = [ setscope 1; onrelease [ setscope 0 ] ] // Sniper
// (format altaction_%1 (getgunindex cpistol)) = [ setburst 1; onrelease [ setburst 0 ] ] // Combat pistol // TODO uncomment when this becomes a priority/testing, for now lets save an unused alias - Bukz
// (format altaction_%1 (getgunindex grenades)) = attack // Grenade // with this comment, you throw the nade and the nade is unselected : Brahma

oldsens = $sensitivity

@@ -262,9 +261,11 @@ const quickanswer [ if (>= $lastpm 0) [ saycommand (concat /pm $lastpm []) ] [ s
// For those players who use IRC too much...
const join [ connect $arg1 $arg2 $arg3 ]
const reconnect [ if $numargs [ svpass = $arg1 ] [ svpass = [] ]; if $connected [ svdata = (curserver); afterdisconnect [ connect (at $svdata 0) (at $svdata 1) $svpass ] ] ]

const dlmap [ getmap $arg1 [ sleep 2500 (concat map $arg1) ] ]
const rndmap [ result (at $defaultmaps (rnd (listlen $defaultmaps))) ]
const rrnd [ + (rnd (- $arg2 $arg1)) $arg1 ]

const ++ [ if (checkalias $arg1) [ += $arg1 1 ] ]
const -- [ if (checkalias $arg1) [ -= $arg1 1 ] ]
const ++f [ if (checkalias $arg1) [ +=f $arg1 1 ] ]
@@ -174,10 +174,7 @@ void newname(const char *name)

int teamatoi(const char *name)
{
string uc;
strtoupper(uc, name);
loopi(TEAM_NUM) if(!strcmp(teamnames[i], uc)) return i;
return -1;
return getlistindex(name, teamnames, true, -1);
}

void newteam(char *name)
@@ -815,36 +812,39 @@ bool tryrespawn()
VARP(hitsound, 0, 0, 2);

// client kill messages
void setkillmessage(int gun, bool gib, const char *message)
void setkillmessage(const char *gun, bool gib, const char *message)
{
if(!message || !*message)
int guni = getlistindex(gun, gunnames, true, -1);
if(guni < 0)
{
result(killmessage(gun, gib));
return;
conoutf("invalid gun specified");
}
if(gun < 0 || gun >= NUMGUNS)
else
{
conoutf("invalid gun specified");
return;
if(!message || !*message)
{
result(killmessage(guni, gib));
}
else
{
copystring(killmessages[gib ? 1 : 0][guni], message, sizeof(killmessages[gib ? 1 : 0][guni]));
}
}
copystring(killmessages[gib?1:0][gun], message, sizeof(killmessages[gib?1:0][gun]));
}

COMMANDF(fragmessage, "is", (int *gun, const char *message) { setkillmessage(*gun, false, message); });
COMMANDF(gibmessage, "is", (int *gun, const char *message) { setkillmessage(*gun, true, message); });
COMMANDF(fragmessage, "ss", (const char *gun, const char *message) { setkillmessage(gun, false, message); });
COMMANDF(gibmessage, "ss", (const char *gun, const char *message) { setkillmessage(gun, true, message); });

void burstshots(int gun, int shots)
COMMANDF(burstshots, "si", (char *gun, int *shots)
{
// args are passed as strings to differentiate 2 cases : shots_str == "0" or shots_str is empty (not specified from cubescript).
if(gun >= 0 && gun < NUMGUNS && guns[gun].isauto)
int guni = getlistindex(gun, gunnames, true, -1);
if(guni >= 0 && guns[guni].isauto)
{
if(shots >= 0) burstshotssettings[gun] = min(shots, (guns[gun].magsize-1));
else intret(burstshotssettings[gun]);
if(*shots >= 0) burstshotssettings[guni] = min(*shots, (guns[guni].magsize-1));
else intret(burstshotssettings[guni]);
}
else conoutf(_("invalid gun specified"));
}

COMMANDF(burstshots, "ii", (int *g, int *s) { burstshots(*g, *s); });
});

// damage arriving from the network, monsters, yourself, all ends up here.

@@ -429,7 +429,7 @@ char *parseword(const char *&p, int arg, int &infix) // pa
return s;
}

char *conc(char **w, int n, bool space)
char *conc(const char **w, int n, bool space)
{
int len = space ? max(n-1, 0) : 0;
loopj(n) len += (int)strlen(w[j]);
@@ -585,7 +585,7 @@ char *executeret(const char *p) // all evaluation hap
if(strstr(id->sig, "v")) ((void (__cdecl *)(char **, int))id->fun)(&w[1], numargs-1);
else if(strstr(id->sig, "c") || strstr(id->sig, "w"))
{
char *r = conc(w+1, numargs-1, strstr(id->sig, "c") != NULL);
char *r = conc((const char **)w+1, numargs-1, strstr(id->sig, "c") != NULL);
((void (__cdecl *)(char *))id->fun)(r);
delete[] r;
}
@@ -1204,18 +1204,20 @@ void colora(char *s)
}

// Easily inject a string into various CubeScript punctuations
void addpunct(char *s, int *type)
const char *punctnames[] = { "QUOTES", "BRACKETS", "PARENTHESIS", "_$_", "QUOTE", "PERCENT", "" };

void addpunct(char *s, char *type)
{
switch(*type)
int t = getlistindex(type, punctnames, true, 0);
const char *puncts[] = { "\"%s\"", "[%s]", "(%s)", "$%s", "\"", "%" }, *punct = puncts[t];
if(strchr(punct, 's'))
{
case 1: defformatstring(o1)("[%s]", s); result(o1); break;
case 2: defformatstring(o2)("(%s)", s); result(o2); break;
case 3: defformatstring(o3)("$%s", s); result(o3); break;
case 4: result("\""); break;
case 5: result("%"); break;
default: defformatstring(o4)("\"%s\"", s); result(o4); break;
defformatstring(res)(punct, s);
result(res);
}
else result(punct);
}
COMMAND(addpunct, "ss");

void toLower(char *s) { result(strcaps(s, false)); }
void toUpper(char *s) { result(strcaps(s, true)); }
@@ -1379,7 +1381,6 @@ COMMAND(execute, "s");
COMMAND(at, "si");
COMMANDF(listlen, "s", (char *l) { intret(listlen(l)); });
COMMAND(findlist, "ss");
COMMAND(addpunct, "si");
COMMANDN(tolower, toLower, "s");
COMMANDN(toupper, toUpper, "s");
COMMAND(testchar, "si");
@@ -1670,6 +1671,17 @@ COMMANDN(timestring, timestring_, "");
COMMANDF(getmode, "i", (int *acr) { result(modestr(gamemode, *acr != 0)); });
COMMAND(getscrext, "");

void listoptions(char *s)
{
const char *optionnames[] = { "entities", "ents", "weapons", "teamnames", "teamnames-abbrv", "punctuations", "" };
const char **optionlists[] = { optionnames, entnames + 1, entnames + 1, gunnames, teamnames, teamnames_s, punctnames };
const char **listp = optionlists[getlistindex(s, optionnames, true, -1) + 1];
int num = 0;
while(listp[num] && listp[num][0]) num++;
commandret = conc(listp, num, true);
}
COMMAND(listoptions, "s");

const char *currentserver(int i) // [client version]
{
static string curSRVinfo;
@@ -475,29 +475,24 @@ void setspawn(int i, bool on)
}
}

bool selectnextprimary(int num)
SVARFP(nextprimary, guns[GUN_ASSAULT].modelname,
{
switch(num)
int n = getlistindex(nextprimary, gunnames, true, -1);
switch(n)
{
// case GUN_CPISTOL:
default:
conoutf("\"%s\" is not a valid primary weapon", nextprimary);
n = GUN_ASSAULT;
case GUN_CARBINE:
case GUN_SHOTGUN:
case GUN_SUBGUN:
case GUN_SNIPER:
case GUN_ASSAULT:
player1->setnextprimary(num);
player1->setnextprimary(n);
addmsg(SV_PRIMARYWEAP, "ri", player1->nextprimweap->type);
return true;

default:
conoutf("this is not a valid primary weapon");
return false;
nextprimary = exchangestr(nextprimary, gunnames[player1->nextprimweap->type]);
break;
}
}

VARFP(nextprimary, 0, GUN_ASSAULT, NUMGUNS,
{
if(!selectnextprimary(nextprimary)) selectnextprimary((nextprimary = GUN_ASSAULT));
});

// flag ent actions done by the local player
@@ -18,7 +18,7 @@ enum // static entity types

enum {MAP_IS_BAD, MAP_IS_EDITABLE, MAP_IS_GOOD};

extern const char *entnames[MAXENTTYPES];
extern const char *entnames[];
#define isitem(i) ((i) >= I_CLIPS && (i) <= I_AKIMBO)

struct persistent_entity // map entity
@@ -81,6 +81,7 @@ extern itemstat powerupstats[I_ARMOUR-I_HEALTH+1];

struct guninfo { string modelname; short sound, reload, reloadtime, attackdelay, damage, piercing, projspeed, part, spread, recoil, magsize, mdl_kick_rot, mdl_kick_back, recoilincrease, recoilbase, maxrecoil, recoilbackfade, pushfactor; bool isauto; };
extern guninfo guns[NUMGUNS];
extern const char *gunnames[];

static inline int reloadtime(int gun) { return guns[gun].reloadtime; }
static inline int attackdelay(int gun) { return guns[gun].attackdelay; }
@@ -89,8 +90,8 @@ static inline int magsize(int gun) { return guns[gun].magsize; }
/** roseta stone:
0000, 0001, 0010, 0011, 0100, 0101, 0110 */
enum { TEAM_CLA = 0, TEAM_RVSF, TEAM_CLA_SPECT, TEAM_RVSF_SPECT, TEAM_SPECT, TEAM_NUM, TEAM_ANYACTIVE };
extern const char *teamnames[TEAM_NUM+1];
extern const char *teamnames_s[TEAM_NUM+1];
extern const char *teamnames[];
extern const char *teamnames_s[];

#define TEAM_VOID TEAM_NUM
#define isteam(a,b) (m_teammode && (a) == (b))
@@ -103,7 +104,7 @@ extern const char *teamnames_s[TEAM_NUM+1];
#define team_group(t) ((t) == TEAM_SPECT ? TEAM_SPECT : team_base(t))
#define team_tospec(t) ((t) == TEAM_SPECT ? TEAM_SPECT : team_base(t) + TEAM_CLA_SPECT - TEAM_CLA)
// note: team_isactive and team_base can/should be used to check the limits for arrays of size '2'
static inline const char *team_string(int t, bool abbr = false) { const char **n = abbr ? teamnames_s : teamnames; return team_isvalid(t) ? n[t] : n[TEAM_NUM]; }
static inline const char *team_string(int t, bool abbr = false) { const char **n = abbr ? teamnames_s : teamnames; return team_isvalid(t) ? n[t] : n[TEAM_NUM + 1]; }

enum { ENT_PLAYER = 0, ENT_BOT, ENT_CAMERA, ENT_BOUNCE };
enum { CS_ALIVE = 0, CS_DEAD, CS_SPAWNING, CS_LAGGED, CS_EDITING, CS_SPECTATE };

0 comments on commit 47f71f1

Please sign in to comment.
You can’t perform that action at this time.