diff --git a/config/scripts.cfg b/config/scripts.cfg index aa945a17..abcdbced 100644 --- a/config/scripts.cfg +++ b/config/scripts.cfg @@ -118,15 +118,15 @@ loop g (listlen $PUNCTUATION) [ const (at $PUNCTUATION $g) $g ] loop d $NUM_WEAPONS [ const (at $WEAPONS $d) $d ] -loop r $NUM_MODES [ const (at $MODES $r) (format "if (= $arg1 -1) [ result %1 ] [ votemap %1 %2 ]" $r (addpunct arg1 $_$_)) ] -// ktf ac_mines - calls a vote for keep the flag ac_mines -// echo (ktf -1) - returns 15 +loop r $NUM_MODES [ const (at $MODES $r) (format "votemap %1 %2 %3" $r "$arg1" "$arg2") ] + +const modenum [ f = -1; loop i $NUM_MODES [ if (strcmp (at $MODES $i) $arg1) [f = $i; break] ]; result $f] // Mode/map-setting aliases. -const votemap [ mode $arg1; map $arg2 ] +const votemap [ mode $arg1; map $arg2 $arg3 ] -const lms [ votemap (surv -1) $arg1 ] -const vip [ votemap (htf -1) $arg1 ] +const lms [ votemap (surv -1) $arg1 $arg2 ] +const vip [ votemap (htf -1) $arg1 $arg2 ] // Helper aliases for (c) - easy color insertion. (e.g. echo (red)Hello (blue)world! (white)My fov today is: (orange) $fov) loop k 10 [ const (at "green blue yellow red gray white dbrown dred purple orange" $k) (format "if (= $arg1 -1) [ result %1 ] [ result %2 ]" $k (addpunct (concat c $k) 2)) ] @@ -255,7 +255,7 @@ const addOnQuit [ add2alias onQuit $arg1 ] const check2init [ if (! (checkalias $arg1)) [ $arg1 = $arg2 ] ] // only overwrites an alias if it doesn't exist const check2initlist [ loop cll (listlen $arg1) [ check2init (at $arg1 $cll) $arg2 ] ] // check2inits multiple aliases const forceinit [ loop fil (listlen $arg1) [ (at $arg1 $fil) = $arg2 ] ] // forcibly overwrites multiple aliases -const checkinit [ if (! (checkalias $arg1)) [ $arg1 = "" ]; if (> $numargs 1) [ if (! (strstr (getalias $arg1) $arg2)) [ add2alias $arg1 $arg2 ] ] ] // ensures the initialization of an alias, optionally ensures the alias contains string $arg2 +const checkinit [ if (! (checkalias $arg1)) [ $arg1 = "" ]; if (> $numargs 1) [ if (! (strstr (getalias $arg1) $arg2)) [ add2alias $arg1 $arg2 ] ] ] // ensures the initialization of an alias, optionally ensures the alias contains string $arg2 const aliasinit [ loop ail (listlen $arg1) [ checkinit (at $arg1 $ail) $arg2 ] ] // checkinits multiple aliases const add2list [ if (strcmp "" (getalias $arg1)) [ $arg1 = $arg2 ] [ $arg1 = (concat (getalias $arg1) $arg2) ] ] // works exactly like concat, use as a shortcut to: alias = (concat $alias "some string") const add2bind [ if (! (strstr (keybind $arg1) $arg2)) [ bind $arg1 (format "%1; %2" (keybind $arg1) $arg2) ] ] // works exactly like add2alias except for used with keybinds diff --git a/docs/reference.xml b/docs/reference.xml index 1952feab..826e4a4d 100644 --- a/docs/reference.xml +++ b/docs/reference.xml @@ -6440,101 +6440,8 @@ Output:
- - - - - - - - - Starts a map with the mode "Co-op edit" - - See the co-op edit section in page 4 of the map editing guide for more information. - - - - - - - - - - - - - Starts a map with the mode "Capture the Flag" - - - - - - - - - - - - Starts a map with the mode "Deathmatch" - - - - - - - - - - - - Starts a map with the mode "Hunt the Flag" - - - - - - - - - - - - Starts a map with the mode "Keep the Flag" - - - - - - - - - - - - Starts a map with the mode "Last Man Standing" - - - - - - - - - - - - Starts a map with the mode "Last Swiss Standing" - - - - - - - - - - - Sets the gameplay mode to N for the next map loaded. + + Sets the gameplay mode to N for the next map loaded. @@ -6557,43 +6464,133 @@ Output: - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + You will need to define mode before loading the map or it will stay as the last mode played. There are many aliases for you to use instead of remembering the numeric mapping. - - - + + + - - set the length of matches against bots - - The first argument "M" needs to be 1 for setting the FFA-timeout or 2 for the Team-Mode-timeout. - + - - + + + + + + + Starts a map with the mode "Co-op edit" + + See the co-op edit section in page 4 of the map editing guide for more information. + + + + + + + + + + + + + + Starts a map with the mode "Capture the Flag" + + + + + + + + + + + + + Starts a map with the mode "Deathmatch" + + + + + + + + + + + + + Starts a map with the mode "Hunt the Flag" + + + + + + + + + + + + + Starts a map with the mode "Keep the Flag" + + + + + + + + + + + + + Starts a map with the mode "Last Man Standing" + + + + + + + + + + + + + Starts a map with the mode "Last Swiss Standing" + + + + + + + + @@ -6605,7 +6602,8 @@ Output: - + + @@ -6618,6 +6616,7 @@ Output: + @@ -6630,6 +6629,7 @@ Output: + @@ -6642,6 +6642,7 @@ Output: + @@ -6654,6 +6655,7 @@ Output: + @@ -6666,6 +6668,7 @@ Output: + @@ -6678,6 +6681,7 @@ Output: + diff --git a/source/src/clientgame.cpp b/source/src/clientgame.cpp index 9dfc0b69..56e2b65f 100644 --- a/source/src/clientgame.cpp +++ b/source/src/clientgame.cpp @@ -16,35 +16,6 @@ void mode(int n) } COMMAND(mode, ARG_1INT); -void setbottimeout(int m, int t) -{ - if(m==1 || m==2) - { - if(t>0 && t<61) - { - switch(m) - { - case 1: - { - extern int botmatch_dm_minremain; - botmatch_dm_minremain = t; - break; - } - case 2: - { - extern int botmatch_tm_minremain; - botmatch_tm_minremain = t; - break; - } - default: break; - } - } - else conoutf(_("%c3Error: %c5valid range for time is 1-60"), CC, CC); - } - else conoutf(_("%c3Error: %c5mode needs to be 1 for FFA or 2 for team modes"), CC, CC); -} -COMMAND(setbottimeout, ARG_2INT); - bool intermission = false; int arenaintermission = 0; struct serverstate servstate = { 0 }; @@ -1368,9 +1339,9 @@ void flagmsg(int flag, int message, int actor, int flagtime) void dropflag() { tryflagdrop(true); } COMMAND(dropflag, ARG_NONE); -char *votestring(int type, const char *arg1, const char *arg2) +char *votestring(int type, const char *arg1, const char *arg2, const char *arg3) { - const char *msgs[] = { "kick player %s, reason: %s", "ban player %s, reason: %s", "remove all bans", "set mastermode to %s", "%s autoteam", "force player %s to the enemy team", "give admin to player %s", "load map %s in mode %s%s", "%s demo recording for the next match", "stop demo recording", "clear all demos", "set server description to '%s'", "shuffle teams"}; + const char *msgs[] = { "kick player %s, reason: %s", "ban player %s, reason: %s", "remove all bans", "set mastermode to %s", "%s autoteam", "force player %s to the enemy team", "give admin to player %s", (arg3 && arg3[0]) ? "load map %s in mode %s%s for %s minutes" : "load map %s in mode %s%s", "%s demo recording for the next match", "stop demo recording", "clear all demos", "set server description to '%s'", "shuffle teams"}; const char *msg = msgs[type]; char *out = newstring(MAXSTRLEN); out[MAXSTRLEN] = '\0'; @@ -1406,11 +1377,11 @@ char *votestring(int type, const char *arg1, const char *arg2) int n = atoi(arg2); if ( n >= GMODE_NUM ) { - formatstring(out)(msg, arg1, modestr(n-GMODE_NUM, modeacronyms > 0)," (in the next game)"); + formatstring(out)(msg, arg1, modestr(n-GMODE_NUM, modeacronyms > 0)," (in the next game)", arg3); } else { - formatstring(out)(msg, arg1, modestr(n, modeacronyms > 0),""); + formatstring(out)(msg, arg1, modestr(n, modeacronyms > 0), "", arg3); } break; } @@ -1424,14 +1395,14 @@ char *votestring(int type, const char *arg1, const char *arg2) return out; } -votedisplayinfo *newvotedisplayinfo(playerent *owner, int type, const char *arg1, const char *arg2) +votedisplayinfo *newvotedisplayinfo(playerent *owner, int type, const char *arg1, const char *arg2, const char *arg3) { if(type < 0 || type >= SA_NUM) return NULL; votedisplayinfo *v = new votedisplayinfo(); v->owner = owner; v->type = type; v->millis = totalmillis + (30+10)*1000; - char *votedesc = votestring(type, arg1, arg2); + char *votedesc = votestring(type, arg1, arg2, arg3); copystring(v->desc, votedesc); DELETEA(votedesc); return v; @@ -1439,10 +1410,10 @@ votedisplayinfo *newvotedisplayinfo(playerent *owner, int type, const char *arg1 votedisplayinfo *curvote = NULL, *calledvote = NULL; -void callvote(int type, const char *arg1, const char *arg2) +void callvote(int type, const char *arg1, const char *arg2, const char *arg3) { if(calledvote) return; - votedisplayinfo *v = newvotedisplayinfo(player1, type, arg1, arg2); + votedisplayinfo *v = newvotedisplayinfo(player1, type, arg1, arg2, arg3); if(v) { calledvote = v; @@ -1459,6 +1430,7 @@ void callvote(int type, const char *arg1, const char *arg2) case SA_MAP: sendstring(arg1, p); putint(p, nextmode); + putint(p, atoi(arg3)); break; case SA_SERVERDESC: sendstring(arg1, p); @@ -1492,9 +1464,7 @@ void scallvote(char *type, const char *arg1, const char *arg2) { case SA_MAP: // FIXME { - string n; - itoa(n, nextmode); - callvote(t, arg1, n); + callvote(t, arg1, "", arg2); // nextmode is implicit arg2 break; } case SA_KICK: @@ -1593,10 +1563,8 @@ void setnext(char *arg1, char *arg2) } if ( !strcmp(arg1,modestrings[i]) ) { - string n; - itoa(n, i+GMODE_NUM); nextmode=i+GMODE_NUM; - callvote(SA_MAP, arg2, n); + callvote(SA_MAP, arg2, "-1"); return; } } @@ -1612,6 +1580,7 @@ void gonext(char *arg1) putint(p, SA_MAP); sendstring("+1", p); putint(p, atoi(arg1)); + putint(p, -1); sendpackettoserv(1, p.finalize()); } COMMAND(gonext, ARG_1STR); diff --git a/source/src/clients2c.cpp b/source/src/clients2c.cpp index 8babc5d5..93dea183 100644 --- a/source/src/clients2c.cpp +++ b/source/src/clients2c.cpp @@ -1219,7 +1219,8 @@ void parsemessages(int cn, playerent *d, ucharbuf &p, bool demo = false) getstring(text, p); filtertext(text, text); itoa(a, getint(p)); - v = newvotedisplayinfo(d, type, text, a); + defformatstring(t)("%d", getint(p)); + v = newvotedisplayinfo(d, type, text, a, t); break; case SA_KICK: case SA_BAN: diff --git a/source/src/protos.h b/source/src/protos.h index ef119178..358f3ac2 100644 --- a/source/src/protos.h +++ b/source/src/protos.h @@ -398,7 +398,7 @@ extern playerent *newclient(int cn); extern void timeupdate(int milliscur, int millismax); // was (int timeremain); extern void respawnself(); extern void setskin(playerent *pl, int skin, int team = -1); -extern void callvote(int type, const char *arg1 = NULL, const char *arg2 = NULL); +extern void callvote(int type, const char *arg1 = NULL, const char *arg2 = NULL, const char *arg3 = NULL); extern void addsleep(int msec, const char *cmd, bool persist = false); extern void resetsleep(bool force = false); //game mode extras @@ -433,7 +433,7 @@ struct votedisplayinfo votedisplayinfo() : owner(NULL), result(VOTE_NEUTRAL), millis(0), localplayervoted(false) { loopi(VOTE_NUM) stats[i] = VOTE_NEUTRAL; } }; -extern votedisplayinfo *newvotedisplayinfo(playerent *owner, int type, const char *arg1, const char *arg2); +extern votedisplayinfo *newvotedisplayinfo(playerent *owner, int type, const char *arg1, const char *arg2, const char *arg3 = ""); extern void callvotesuc(); extern void callvoteerr(int e); extern void displayvote(votedisplayinfo *v); @@ -863,7 +863,7 @@ extern bool valid_client(int cn); extern void extinfo_cnbuf(ucharbuf &p, int cn); extern void extinfo_statsbuf(ucharbuf &p, int pid, int bpos, ENetSocket &pongsock, ENetAddress &addr, ENetBuffer &buf, int len, int *csend); extern void extinfo_teamscorebuf(ucharbuf &p); -extern char *votestring(int type, char *arg1, char *arg2); +extern char *votestring(int type, char *arg1, char *arg2, char *arg3); extern int wizardmain(int argc, char **argv); // demo diff --git a/source/src/server.cpp b/source/src/server.cpp index 52de708e..0759cc3d 100644 --- a/source/src/server.cpp +++ b/source/src/server.cpp @@ -55,8 +55,6 @@ vector sents; char *maplayout = NULL, *testlayout = NULL; int maplayout_factor, testlayout_factor, maplayoutssize; servermapbuffer mapbuffer; -int botmatch_dm_minremain = 10; // deathmatch -int botmatch_tm_minremain = 15; // teammode // cmod char *global_name; @@ -1868,7 +1866,7 @@ void resetserver(const char *newname, int newmode, int newtime) smode = newmode; copystring(smapname, newname); - minremain = newtime >= 0 ? newtime : (m_botmode ? (m_teammode ? botmatch_tm_minremain : botmatch_dm_minremain) : (m_teammode ? 15 : 10)); + minremain = newtime > 0 ? newtime : (m_teammode ? 15 : 10); gamemillis = 0; gamelimit = minremain*60000; arenaround = arenaroundstartmillis = 0; @@ -2070,7 +2068,7 @@ void sendserveropinfo(int receiver) struct voteinfo { int boot; - int owner, callmillis, result, num, type; + int owner, callmillis, result, num1, num2, type; char text[MAXTRANS]; serveraction *action; bool gonext; @@ -2114,7 +2112,7 @@ struct voteinfo bool min_time = servmillis - callmillis > 10*1000; #define yes_condition ((min_time && stats[VOTE_YES] - stats[VOTE_NO] > 0.34f*total && totalclients > 4) || stats[VOTE_YES] > requiredcount*total) #define no_condition (forceend || !valid_client(owner) || stats[VOTE_NO] >= stats[VOTE_YES]+stats[VOTE_NEUTRAL] || adminvote == VOTE_NO) -#define boot_condition (!boot || (boot && valid_client(num) && clients[num]->peer->address.host == host)) +#define boot_condition (!boot || (boot && valid_client(num1) && clients[num1]->peer->address.host == host)) if( (yes_condition || admin || adminvote == VOTE_YES) && boot_condition ) end(VOTE_YES); else if( no_condition || (min_time && !boot_condition)) end(VOTE_NO); else return; @@ -2183,7 +2181,7 @@ bool scallvote(voteinfo *v, ENetPacket *msg) // true if a regular vote was calle else if( v->action->role > c->role ) error = VOTEE_PERMISSION; else if( !(area & v->action->area) ) error = VOTEE_AREA; else if( curvote && curvote->result==VOTE_NEUTRAL ) error = VOTEE_CUR; - else if( v->type == SA_MAP && v->num >= GMODE_NUM && map_queued ) error = VOTEE_NEXT; + else if( v->type == SA_MAP && v->num1 >= GMODE_NUM && map_queued ) error = VOTEE_NEXT; else if( c->role == CR_DEFAULT && v->action->isdisabled() ) error = VOTEE_DISABLED; else if( (c->lastvotecall && servmillis - c->lastvotecall < 60*1000 && c->role != CR_ADMIN && numclients()>1) || c->nvotes > 3 ) error = VOTEE_MAX; else if( ( ( v->boot == 1 && c->role < roleconf('w') ) || ( v->boot == 2 && c->role < roleconf('X') ) ) @@ -2202,7 +2200,7 @@ bool scallvote(voteinfo *v, ENetPacket *msg) // true if a regular vote was calle } else { - if ( v->type == SA_MAP && v->num >= GMODE_NUM ) map_queued = true; + if ( v->type == SA_MAP && v->num1 >= GMODE_NUM ) map_queued = true; if (!v->gonext) sendpacket(-1, 1, msg, v->owner); // FIXME in fact, all votes should go to the server, registered, and then go back to the clients else callvotepacket (-1, v); // also, no vote should exclude the caller... these would provide many code advantages/facilities scallvotesuc(v); // but we cannot change the vote system now for compatibility issues... so, TODO @@ -2230,12 +2228,13 @@ void callvotepacket (int cn, voteinfo *v = curvote) { case SA_KICK: case SA_BAN: - putint(q, v->num); + putint(q, v->num1); sendstring(v->text, q); break; case SA_MAP: sendstring(v->text, q); - putint(q, v->num); + putint(q, v->num1); + putint(q, v->num2); break; case SA_SERVERDESC: sendstring(v->text, q); @@ -2247,7 +2246,7 @@ void callvotepacket (int cn, voteinfo *v = curvote) case SA_SHUFFLETEAMS: break; default: - putint(q, v->num); + putint(q, v->num1); break; } sendpacket(cn, 1, q.finalize()); @@ -3380,7 +3379,9 @@ void process(ENetPacket *packet, int sender, int chan) { getstring(text, p); filtertext(text, text); - int mode = getint(p); + int mode = getint(p), time = getint(p); + if(time <= 0) time = -1; + time = min(time, 60); vi->gonext = text[0]=='+' && text[1]=='1'; if (vi->gonext) { @@ -3389,27 +3390,28 @@ void process(ENetPacket *packet, int sender, int chan) if(c) { strcpy(vi->text,c->mapname); - mode = vi->num = c->mode; + mode = vi->num1 = c->mode; } else fatal("unable to get next map in maprot"); } else { strncpy(vi->text,text,MAXTRANS-1); - vi->num = mode; + vi->num1 = mode; + vi->num2 = time; } int qmode = (mode >= GMODE_NUM ? mode - GMODE_NUM : mode); if(mode==GMODE_DEMO) vi->action = new demoplayaction(newstring(text)); else { char *vmap = newstring(vi->text ? behindpath(vi->text) : ""); - vi->action = new mapaction(vmap, qmode, sender, qmode!=mode); + vi->action = new mapaction(vmap, qmode, time, sender, qmode!=mode); } break; } case SA_KICK: { - vi->num = cn2boot = getint(p); + vi->num1 = cn2boot = getint(p); getstring(text, p); strncpy(vi->text,text,128); filtertext(text, text); @@ -3420,7 +3422,7 @@ void process(ENetPacket *packet, int sender, int chan) } case SA_BAN: { - vi->num = cn2boot = getint(p); + vi->num1 = cn2boot = getint(p); getstring(text, p); strncpy(vi->text,text,128); filtertext(text, text); @@ -3433,28 +3435,28 @@ void process(ENetPacket *packet, int sender, int chan) vi->action = new removebansaction(); break; case SA_MASTERMODE: - vi->action = new mastermodeaction(vi->num = getint(p)); + vi->action = new mastermodeaction(vi->num1 = getint(p)); break; case SA_AUTOTEAM: - vi->action = new autoteamaction((vi->num = getint(p)) > 0); + vi->action = new autoteamaction((vi->num1 = getint(p)) > 0); break; case SA_SHUFFLETEAMS: vi->action = new shuffleteamaction(); break; case SA_FORCETEAM: - vi->action = new forceteamaction((vi->num = getint(p)), sender); + vi->action = new forceteamaction((vi->num1 = getint(p)), sender); break; case SA_GIVEADMIN: - vi->action = new giveadminaction(vi->num = getint(p)); + vi->action = new giveadminaction(vi->num1 = getint(p)); break; case SA_RECORDDEMO: - vi->action = new recorddemoaction((vi->num = getint(p))!=0); + vi->action = new recorddemoaction((vi->num1 = getint(p))!=0); break; case SA_STOPDEMO: // compatibility break; case SA_CLEARDEMOS: - vi->action = new cleardemosaction(vi->num = getint(p)); + vi->action = new cleardemosaction(vi->num1 = getint(p)); break; case SA_SERVERDESC: getstring(text, p); diff --git a/source/src/serveractions.h b/source/src/serveractions.h index 00a6fced..9371ed6f 100644 --- a/source/src/serveractions.h +++ b/source/src/serveractions.h @@ -36,7 +36,7 @@ void kick_abuser(int cn, int &cmillis, int &count, int limit) struct mapaction : serveraction { char *map; - int mode; + int mode, time; bool mapok, queue; void perform() { @@ -53,12 +53,12 @@ struct mapaction : serveraction } else { - startgame(map, mode); + startgame(map, mode, time); } } bool isvalid() { return serveraction::isvalid() && mode != GMODE_DEMO && map[0] && mapok && !(isdedicated && !m_mp(mode)); } bool isdisabled() { return maprot.current() && !maprot.current()->vote; } - mapaction(char *map, int mode, int caller, bool q) : map(map), mode(mode), queue(q) + mapaction(char *map, int mode, int time, int caller, bool q) : map(map), mode(mode), time(time), queue(q) { if(isdedicated) {