diff --git a/source/src/clientgame.cpp b/source/src/clientgame.cpp index 738b9f00..90063502 100644 --- a/source/src/clientgame.cpp +++ b/source/src/clientgame.cpp @@ -96,11 +96,7 @@ void changeteam(int team, bool respawn) // force team and respawn c2sinit = false; if(m_flags) tryflagdrop(false); filtertext(player1->team, team_string(team), 0, MAXTEAMLEN); - if(respawn) - { - addmsg(SV_CHANGETEAM, "r"); - player1->lastteamchange = lastmillis; - } + if(respawn) addmsg(SV_CHANGETEAM, "r"); } void newteam(char *name) @@ -276,32 +272,48 @@ void moveotherplayers() } } -void checkarenaintermission() + +bool showhudtimer(int maxsecs, int startmillis, const char *msg, bool flash) { - static int lastcnt = -1; - static string s, t; - if(!m_arena || intermission) arenaintermission = 0; - if(!arenaintermission) return; - int cnt = (lastmillis - arenaintermission) / 200; - if(cnt != lastcnt) + static string str = ""; + static int tickstart = 0, curticks = -1, maxticks = -1; + int nextticks = (lastmillis - startmillis) / 200; + if(tickstart!=startmillis || maxticks != 5*maxsecs) { - switch(cnt) + tickstart = startmillis; + maxticks = 5*maxsecs; + curticks = -1; + s_strcpy(str, "\f3"); + } + if(curticks >= maxticks) return false; + nextticks = min(nextticks, maxticks); + while(curticks < nextticks) + { + if(++curticks%5) s_strcat(str, "."); + else { - case 0: - s_strcpy(s, "5"); - hudonlyf(s); - break; - case 25: - hudeditf("fight!"); - break; - default: - if(cnt % 5) strcpy(t, "."); - else s_sprintf(t)("%d", 5 - cnt / 5); - s_strcat(s, t); - hudeditf(s); - break; + s_sprintfd(sec)("%d", maxsecs - (curticks/5)); + s_strcat(str, sec); } - lastcnt = cnt; + } + hudeditf(HUDMSG_TIMER, nextticks < maxticks ? (flash ? str : str+2) : msg); + return true; +} + +int lastspawnattempt = 0; + +void showrespawntimer() +{ + if(intermission) return; + if(m_arena) + { + if(!arenaintermission) return; + showhudtimer(5, arenaintermission, "fight!", lastspawnattempt >= arenaintermission && lastmillis < lastspawnattempt+100); + } + else if(player1->state==CS_DEAD && (!player1->isspectating() || player1->spectatemode==SM_DEATHCAM)) + { + int secs = m_flags ? 5 : 2; + showhudtimer(secs, player1->respawnoffset, "ready!", lastspawnattempt >= arenaintermission && lastmillis < lastspawnattempt+100); } } @@ -345,7 +357,7 @@ void updateworld(int curtime, int lastmillis) // main game update loop movebounceents(); moveotherplayers(); gets2c(); - checkarenaintermission(); + showrespawntimer(); // Added by Rick: let bots think if(m_botmode) BotManager.Think(); @@ -455,14 +467,13 @@ bool tryrespawn() } int respawnmillis = player1->respawnoffset+(m_arena ? 0 : (m_flags ? 5000 : 2000)); - if(player1->lastteamchange) respawnmillis = player1->lastteamchange + 1500; if(lastmillis>respawnmillis) { player1->attacking = false; - player1->lastteamchange = 0; if(m_arena) { - if(!arenaintermission) hudonlyf("waiting for new round to start..."); + if(!arenaintermission) hudeditf(HUDMSG_TIMER, "waiting for new round to start..."); + else lastspawnattempt = lastmillis; return false; } respawnself(); @@ -470,7 +481,8 @@ bool tryrespawn() player1->lastaction -= weapon::weaponchangetime/2; return true; } - else hudonlyf("wait %3.1f seconds to respawn", (respawnmillis-lastmillis)/(float)1000); + else lastspawnattempt = lastmillis; + //else hudonlyf("wait %3.1f seconds to respawn", (respawnmillis-lastmillis)/(float)1000); } return false; } diff --git a/source/src/console.cpp b/source/src/console.cpp index 99f0af0a..5e23f918 100644 --- a/source/src/console.cpp +++ b/source/src/console.cpp @@ -10,7 +10,7 @@ VARP(fullconsize, 0, 40, 100); VARP(consize, 0, 6, 100); VARP(confade, 0, 20, 60); -struct console : consolebuffer +struct console : consolebuffer { int conskip; void setconskip(int n) @@ -28,9 +28,7 @@ struct console : consolebuffer else fullconsole = ++fullconsole % 3; } - void addline(const char *sf) { consolebuffer::addline(sf, totalmillis); } - - vector visible; + void addline(const char *sf) { consolebuffer::addline(sf, totalmillis); } void render() { @@ -74,7 +72,7 @@ struct console : consolebuffer } } - console() : fullconsole(false) {} + console() : consolebuffer(200), fullconsole(false) {} }; console con; @@ -82,6 +80,8 @@ textinputbuffer cmdline; char *cmdaction = NULL, *cmdprompt = NULL; bool saycommandon = false; +VARFP(maxcon, 10, 200, 1000, con.setmaxlines(maxcon)); + void setconskip(int n) { con.setconskip(n); } COMMANDN(conskip, setconskip, ARG_1INT); diff --git a/source/src/console.h b/source/src/console.h index c688f98d..c05dd000 100644 --- a/source/src/console.h +++ b/source/src/console.h @@ -1,19 +1,31 @@ struct cline { char *line; int millis; }; -struct consolebuffer +template struct consolebuffer { - vector conlines; + int maxlines; + vector conlines; - void addline(const char *sf, int millis) // add a line to the console buffer + consolebuffer(int maxlines = 100) : maxlines(maxlines) {} + + LINE &addline(const char *sf, int millis) // add a line to the console buffer { - cline cl; - cl.line = conlines.length()>100 ? conlines.pop().line : newstringbuf(""); // constrain the buffer size + LINE cl; + cl.line = conlines.length()>maxlines ? conlines.pop().line : newstringbuf(""); // constrain the buffer size cl.millis = millis; // for how long to keep line on screen - conlines.insert(0,cl); s_strcpy(cl.line, sf); + return conlines.insert(0, cl); } - virtual ~consolebuffer() {} + void setmaxlines(int numlines) + { + maxlines = numlines; + while(conlines.length() > maxlines) delete[] conlines.pop().line; + } + + virtual ~consolebuffer() + { + while(conlines.length()) delete[] conlines.pop().line; + } virtual void render() = 0; }; diff --git a/source/src/entity.h b/source/src/entity.h index c15e1db8..31759bee 100644 --- a/source/src/entity.h +++ b/source/src/entity.h @@ -338,7 +338,7 @@ struct playerent : dynent, playerstate int skin, nextskin; // skin after respawning int spectatemode, followplayercn; int eardamagemillis; - int respawnoffset, lastteamchange; + int respawnoffset; //virtual float eyeheight const { return (state==CS_DEAD || state==CS_SPECTATE) && spectatemode==SM_FLY ? 1.0f : physent::eyeheight; } bool allowmove() { return state!=CS_DEAD || spectatemode==SM_FLY; } @@ -351,7 +351,7 @@ struct playerent : dynent, playerstate int smoothmillis; playerent() : clientnum(-1), lastupdate(0), plag(0), ping(0), lifesequence(0), frags(0), flagscore(0), deaths(0), lastpain(0), lastvoicecom(0), clientrole(CR_DEFAULT), - skin(0), nextskin(0), spectatemode(SM_NONE), followplayercn(-1), eardamagemillis(0), respawnoffset(0), lastteamchange(0), + skin(0), nextskin(0), spectatemode(SM_NONE), followplayercn(-1), eardamagemillis(0), respawnoffset(0), prevweaponsel(NULL), weaponsel(NULL), nextweaponsel(NULL), primweap(NULL), nextprimweap(NULL), lastattackweapon(NULL), smoothmillis(-1) { diff --git a/source/src/protos.h b/source/src/protos.h index 274080a3..9df7cba6 100644 --- a/source/src/protos.h +++ b/source/src/protos.h @@ -472,11 +472,16 @@ extern bool noteditmode(); extern void pruneundos(int maxremain = 0); // renderhud +enum +{ + HUDMSG_INFO = 0, + HUDMSG_TIMER +}; extern void gl_drawhud(int w, int h, int curfps, int nquads, int curvert, bool underwater); extern void loadingscreen(const char *fmt = NULL, ...); extern void hudoutf(const char *s, ...); extern void hudonlyf(const char *s, ...); -extern void hudeditf(const char *s, ...); +extern void hudeditf(int type, const char *s, ...); extern void show_out_of_renderloop_progress(float bar1, const char *text1, float bar2 = 0, const char *text2 = NULL); extern void updatedmgindicator(vec &attack); diff --git a/source/src/renderhud.cpp b/source/src/renderhud.cpp index 4167619d..6d41f1cf 100644 --- a/source/src/renderhud.cpp +++ b/source/src/renderhud.cpp @@ -260,14 +260,30 @@ void drawradarent(float x, float y, float yaw, int col, int row, float iconsize, } } -struct hudmessages : consolebuffer +struct hudline : cline { - void addline(const char *sf) { consolebuffer::addline(sf, totalmillis); } - void editlastline(const char *sf) + int type; + + hudline() : type(HUDMSG_INFO) {} +}; + +struct hudmessages : consolebuffer +{ + hudmessages() : consolebuffer(20) {} + + void addline(const char *sf) + { + consolebuffer::addline(sf, totalmillis); + } + void editline(int type, const char *sf) { if(!conlines.length()) return; - conlines[0].millis = totalmillis; - s_strcpy(conlines[0].line, sf); + if(conlines.length() && conlines[0].type==type) + { + conlines[0].millis = totalmillis; + s_strcpy(conlines[0].line, sf); + } + else consolebuffer::addline(sf, totalmillis).type = type; } void render() { @@ -290,7 +306,7 @@ void hudoutf(const char *s, ...) { s_sprintfdv(sf, s); hudmsgs.addline(sf); - conoutf(sf); + conoutf("%s", sf); } void hudonlyf(const char *s, ...) @@ -299,10 +315,10 @@ void hudonlyf(const char *s, ...) hudmsgs.addline(sf); } -void hudeditf(const char *s, ...) +void hudeditf(int type, const char *s, ...) { s_sprintfdv(sf, s); - hudmsgs.editlastline(sf); + hudmsgs.editline(type, sf); } bool insideradar(const vec ¢erpos, float radius, const vec &o)