From 7208dbb44f08fbbc9f0f7248dec2aa279f327be5 Mon Sep 17 00:00:00 2001 From: Rafael Barreto Date: Fri, 28 May 2010 19:46:02 +0000 Subject: [PATCH] hudextras, points, protocol, clean up and so on git-svn-id: svn://svn.code.sf.net/p/actiongame/code/trunk/ac@5090 e016b1c5-ed68-44aa-a2f7-31cac88cffde --- source/src/Makefile | 5 +- source/src/clientgame.cpp | 2 +- source/src/clients2c.cpp | 72 +++++++++++++------------ source/src/cube.h | 1 - source/src/entity.h | 7 ++- source/src/extras.h | 3 -- source/src/protocol.cpp | 2 +- source/src/protocol.h | 2 +- source/src/server.cpp | 39 ++++++++++++-- source/src/server.h | 30 +++++++---- source/src/serverchecks.h | 108 +++++++++++++++++++------------------- source/src/tools.h | 25 +++++++++ 12 files changed, 185 insertions(+), 111 deletions(-) delete mode 100644 source/src/extras.h diff --git a/source/src/Makefile b/source/src/Makefile index 033724bd..166c8503 100644 --- a/source/src/Makefile +++ b/source/src/Makefile @@ -204,7 +204,7 @@ clientgame.o: bot/ac_bot.h clients2c.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h clients2c.o: weapon.h entity.h world.h i18n.h command.h vote.h console.h clients2c.o: protos.h bot/bot.h bot/bot_util.h bot/bot_waypoint.h -clients2c.o: bot/ac_bot.h extras.h +clients2c.o: bot/ac_bot.h command.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h command.o: weapon.h entity.h world.h i18n.h command.h vote.h console.h command.o: protos.h @@ -269,7 +269,7 @@ scoreboard.o: protos.h server.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h server.o: weapon.h entity.h world.h i18n.h command.h vote.h console.h server.o: protos.h server.h servercontroller.h serverfiles.h serverevents.h -server.o: serveractions.h serverchecks.h extras.h +server.o: serveractions.h serverchecks.h serverbrowser.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h serverbrowser.o: weapon.h entity.h world.h i18n.h command.h vote.h console.h serverbrowser.o: protos.h @@ -360,7 +360,6 @@ server-standalone.o: cube.h platform.h tools.h geom.h model.h protocol.h server-standalone.o: sound.h weapon.h entity.h world.h i18n.h command.h server-standalone.o: vote.h console.h protos.h server.h servercontroller.h server-standalone.o: serverfiles.h serverevents.h serveractions.h serverchecks.h -server-standalone.o: extras.h serverms-standalone.o: cube.h platform.h tools.h geom.h model.h protocol.h serverms-standalone.o: sound.h weapon.h entity.h world.h i18n.h command.h serverms-standalone.o: vote.h console.h protos.h diff --git a/source/src/clientgame.cpp b/source/src/clientgame.cpp index 6258d6a8..31430ce1 100644 --- a/source/src/clientgame.cpp +++ b/source/src/clientgame.cpp @@ -849,7 +849,7 @@ void startmap(const char *name, bool reset) // called just after a map load if(!reset) return; player1->frags = player1->flagscore = player1->deaths = player1->lifesequence = 0; - loopv(players) if(players[i]) players[i]->frags = players[i]->flagscore = players[i]->deaths = players[i]->lifesequence = 0; + loopv(players) if(players[i]) players[i]->frags = players[i]->flagscore = players[i]->deaths = players[i]->points = players[i]->lifesequence = 0; if(editmode) toggleedit(true); intermission = false; showscores(false); diff --git a/source/src/clients2c.cpp b/source/src/clients2c.cpp index 8b269d1c..e5027802 100644 --- a/source/src/clients2c.cpp +++ b/source/src/clients2c.cpp @@ -227,54 +227,48 @@ bool good_map() VARP(hudextras, 0, 0, 3); -char *stolower(const char *s, char *o) -{ - char *c = (char *)s; int n = 0; - char *r = o; - *o = *c; c++; o++; - while( *c!='\0' && n < 40 ) { - *o = tolower(*c); - n++; o++; c++; - } - *o='\0'; - return r; -} - -char *stoupper(const char *s, char *o) -{ - char *c = (char *)s; int n = 0; - char *r = o; - while( *c!='\0' && n < 40 ) { - *o = toupper(*c); - n++; o++; c++; - } - *o='\0'; - return r; -} - +int teamworkid = -1; void showhudextras(char hudextras, char value){ void (*outf)(const char *s, ...) = (hudextras > 1 ? hudoutf : conoutf); - char *(*spam)(const char *s, char *o) = (hudextras == 2 ? stolower : stoupper); - char o[50]; + char *(*spam)(const char *s, char *o, int max) = (hudextras == 2 ? stolower : stoupper), o[50]; +#define SSPAM(x) spam(x,o,40) switch(value) { case HE_COMBO: - outf("\f2%s",spam("COMBO",o)); break; + outf("\f5%s",SSPAM("Combo")); break; + case HE_MASTERCOMBO: + outf("\f5%s",SSPAM("Mastercombo")); break; + case HE_TEAMWORK: + outf("\f5%s",SSPAM("Teamwork done")); break; case HE_FLAGDEFENDED: - outf("\f2%s",spam("FLAG DEFENDED",o)); break; + outf("\f5%s",SSPAM("You defended the flag")); break; case HE_FLAGCOVERED: - outf("\f2%s",spam("FLAG COVERED",o)); break; + outf("\f5%s",SSPAM("You covered the flag")); break; + case HE_DOUBLEKILL: + outf("\f5%s",SSPAM("Double kill")); break; + case HE_MULTIKILL: + outf("\f5%s",SSPAM("Multi kill")); break; + case HE_MONSTERKILL: + outf("\f5%s",SSPAM("Monster kill")); break; case HE_COVER: - outf("\f2%s",spam("TEAMMATE COVERED",o)); break; + if (teamworkid >= 0) { + playerent *p = getclient(teamworkid); + if (!p || p == player1) teamworkid = -1; + else outf("\f5%s %s",SSPAM("You covered"),p->name); break; + } default: { if (value >= 100) { // beware here! this value is linked to checkteamplay::serverchecks.h value - outf("\f2Replied to %s",players[value-100]->name); + teamworkid = value-100; + playerent *p = getclient(teamworkid); + if (!p || p == player1) teamworkid = -1; + else outf("\f4You replied to %s",p->name); } - else outf("\f2Update your client, NOOB!"); + else outf("\f3Update your client, NOOB!"); break; } } +#undef SSPAM } int lastspawn = 0; @@ -656,6 +650,18 @@ void parsemessages(int cn, playerent *d, ucharbuf &p) break; } + case SV_POINTS: + { + int count = getint(p); + loopi(count){ + int pcn = getint(p), score = getint(p); + playerent *ppl = pcn==getclientnum() ? player1 : getclient(pcn); + if (!ppl) break; + ppl->points = score; + } + break; + } + case SV_RESUME: { loopi(MAXCLIENTS) diff --git a/source/src/cube.h b/source/src/cube.h index 91084b1f..fee839b1 100644 --- a/source/src/cube.h +++ b/source/src/cube.h @@ -12,7 +12,6 @@ #include "world.h" #include "i18n.h" #include "command.h" -#include "extras.h" #ifndef STANDALONE #include "vote.h" diff --git a/source/src/entity.h b/source/src/entity.h index e6888641..b2d50a79 100644 --- a/source/src/entity.h +++ b/source/src/entity.h @@ -43,6 +43,9 @@ struct entity : persistent_entity } }; +/** I did not find better place to put this definition FIXME*/ +enum { HE_COMBO, HE_MASTERCOMBO, HE_COVER, HE_TEAMWORK, HE_FLAGDEFENDED, HE_FLAGCOVERED, HE_DOUBLEKILL, HE_MULTIKILL, HE_MONSTERKILL, HE_NUM }; + enum { GUN_KNIFE = 0, GUN_PISTOL, GUN_RIFLE, GUN_SHOTGUN, GUN_SUBGUN, GUN_SNIPER, GUN_ASSAULT, GUN_GRENADE, GUN_AKIMBO, NUMGUNS }; #define reloadable_gun(g) (g != GUN_KNIFE && g != GUN_GRENADE) @@ -346,7 +349,7 @@ private: public: int clientnum, lastupdate, plag, ping; int lifesequence; // sequence id for each respawn, used in damage test - int frags, flagscore, deaths; + int frags, flagscore, deaths, points; int lastaction, lastmove, lastpain, lastvoicecom; int clientrole; bool attacking; @@ -373,7 +376,7 @@ public: bool ignored, muted; - playerent() : curskin(0), clientnum(-1), lastupdate(0), plag(0), ping(0), lifesequence(0), frags(0), flagscore(0), deaths(0), lastpain(0), lastvoicecom(0), clientrole(CR_DEFAULT), + playerent() : curskin(0), clientnum(-1), lastupdate(0), plag(0), ping(0), lifesequence(0), frags(0), flagscore(0), deaths(0), points(0), lastpain(0), lastvoicecom(0), clientrole(CR_DEFAULT), team(TEAM_SPECT), spectatemode(SM_NONE), followplayercn(FPCN_VOID), eardamagemillis(0), respawnoffset(0), prevweaponsel(NULL), weaponsel(NULL), nextweaponsel(NULL), primweap(NULL), nextprimweap(NULL), lastattackweapon(NULL), smoothmillis(-1), diff --git a/source/src/extras.h b/source/src/extras.h deleted file mode 100644 index fda6d0d2..00000000 --- a/source/src/extras.h +++ /dev/null @@ -1,3 +0,0 @@ - -enum { HE_COMBO, HE_MASTERCOMBO, HE_COVER, HE_TEAMWORK, HE_FLAGDEFENDED, HE_FLAGCOVERED, HE_DOUBLEKILL, HE_MULTIKILL, HE_MONSTERKILL, HE_NUM }; - diff --git a/source/src/protocol.cpp b/source/src/protocol.cpp index f2f1b06e..d67099ef 100644 --- a/source/src/protocol.cpp +++ b/source/src/protocol.cpp @@ -339,7 +339,7 @@ static const int msgsizes[] = // size inclusive message token, 0 f SV_SWITCHNAME, 0, SV_SWITCHSKIN, 0, SV_SWITCHTEAM, 0, SV_CLIENT, 0, SV_EXTENSION, 0, - SV_MAPIDENT, 3, SV_HUDEXTRAS, 1, + SV_MAPIDENT, 3, SV_HUDEXTRAS, 1, SV_POINTS, 0, -1 }; diff --git a/source/src/protocol.h b/source/src/protocol.h index 8f424d48..2e586309 100644 --- a/source/src/protocol.h +++ b/source/src/protocol.h @@ -40,7 +40,7 @@ enum SV_SWITCHNAME, SV_SWITCHSKIN, SV_SWITCHTEAM, SV_CLIENT, SV_EXTENSION, - SV_MAPIDENT, SV_HUDEXTRAS, SV_NUM + SV_MAPIDENT, SV_HUDEXTRAS, SV_POINTS, SV_NUM }; #ifdef _DEBUG diff --git a/source/src/server.cpp b/source/src/server.cpp index 756665a7..e73264cf 100644 --- a/source/src/server.cpp +++ b/source/src/server.cpp @@ -42,7 +42,7 @@ bool custom_servdesc = false; // current game string smapname, nextmapname; int smode = 0, nextgamemode; -static int interm = 0, minremain = 0, gamemillis = 0, gamelimit = 0, lmsitemtype = 0; +static int interm = 0, minremain = 0, gamemillis = 0, gamelimit = 0, lmsitemtype = 0, nextsendscore = 0; mapstats smapstats; vector sents; char *maplayout = NULL, *testlayout = NULL; @@ -1625,7 +1625,7 @@ void resetserver(const char *newname, int newmode, int newtime) arenaround = arenaroundstartmillis = 0; memset(&smapstats, 0, sizeof(smapstats)); - interm = 0; + interm = nextsendscore = 0; if(!laststatus) laststatus = servmillis-61*1000; lastfillup = servmillis; sents.shrink(0); @@ -3157,6 +3157,38 @@ void linequalitystats(int elapsed) } } +void sendscores() +{ + if ( gamemillis < nextsendscore ) return; + int count = 0, list[clientnumber]; + loopv(clients) { + client &c = *clients[i]; + if ( c.type!=ST_TCPIP || !c.isauthed || !c.md.updatedpoints ) continue; + list[count] = i; + count++; + } + nextsendscore = gamemillis + (interm ? 10000 : 500); + if ( !count ) return; + + packetbuf p(MAXTRANS, ENET_PACKET_FLAG_RELIABLE); + putint(p, SV_POINTS); + putint(p,count); + int *v = list; + loopi(count) + { + client &c = *clients[*v]; + putint(p,c.clientnum); putint(p,c.state.points); c.md.updatedpoints = false; + v++; + } + ENetPacket *packet = p.finalize(); + + loopv(clients) + { + sendpacket(i, 1, packet); + } +} + + void serverslice(uint timeout) // main server update, called from cube main loop in sp, or dedicated server loop { static int msend = 0, mrec = 0, csend = 0, crec = 0, mnum = 0, cnum = 0; @@ -3211,7 +3243,7 @@ void serverslice(uint timeout) // main server update, called from cube main lo { loggamestatus("game finished"); if(demorecord) enddemorecord(); - interm = 0; + interm = nextsendscore = 0; //start next game if(nextmapname[0]) startgame(nextmapname, nextgamemode); @@ -3298,6 +3330,7 @@ void serverslice(uint timeout) // main server update, called from cube main lo break; } } + sendscores(); sendworldstate(); } diff --git a/source/src/server.h b/source/src/server.h index ff69d6a2..73dcee77 100644 --- a/source/src/server.h +++ b/source/src/server.h @@ -123,7 +123,7 @@ struct clientstate : playerstate projectilestate<8> grenades; int akimbomillis; bool scoped; - int flagscore, frags, teamkills, deaths, shotdamage, damage; + int flagscore, frags, teamkills, deaths, shotdamage, damage, points; clientstate() : state(CS_DEAD) {} @@ -146,7 +146,7 @@ struct clientstate : playerstate grenades.reset(); akimbomillis = 0; scoped = false; - flagscore = frags = teamkills = deaths = shotdamage = damage = 0; + flagscore = frags = teamkills = deaths = shotdamage = damage = points = 0; respawn(); } @@ -167,7 +167,7 @@ struct savedscore { string name; uint ip; - int frags, flagscore, deaths, teamkills, shotdamage, damage, team; + int frags, flagscore, deaths, teamkills, shotdamage, damage, team, points; bool valid; void save(clientstate &cs, int t) @@ -179,6 +179,7 @@ struct savedscore shotdamage = cs.shotdamage; damage = cs.damage; team = t; + points = cs.points; valid = true; } @@ -190,6 +191,21 @@ struct savedscore cs.teamkills = teamkills; cs.shotdamage = shotdamage; cs.damage = damage; + cs.points = points; + } +}; + +struct medals +{ + int lasthit, lastgun, combohits, combo, combotime, combodamage, ncombos, ncovers, nhs; + int ask, askmillis, linked, linkmillis, linkreason; + bool updatedpoints; + void reset() + { + lasthit = lastgun = combohits = combo = combotime = combodamage = ncombos = ncovers = nhs = 0; + askmillis = linkmillis = 0; + linkreason = linked = ask = -1; + updatedpoints = false; } }; @@ -230,9 +246,7 @@ struct client // server side version of "dynent" type string pwd; int mapcollisions, farpickups; enet_uint32 bottomRTT; - - int points, lasthit, lastgun, combohits, combo, combotime, combodamage, ncombos, ncovers, nhs; - int ask, askmillis, linked, linkmillis, linkreason; + medals md; gameevent &addevent() { @@ -258,9 +272,7 @@ struct client // server side version of "dynent" type lastevent = 0; at3_lastforce = 0; mapcollisions = farpickups = 0; - points = lasthit = lastgun = combohits = combo = combotime = combodamage = ncombos = ncovers = nhs = 0; - askmillis = linkmillis = 0; - linkreason = linked = ask = -1; + md.reset(); } void reset() diff --git a/source/src/serverchecks.h b/source/src/serverchecks.h index 2a4df014..55e6ab89 100644 --- a/source/src/serverchecks.h +++ b/source/src/serverchecks.h @@ -97,49 +97,49 @@ inline int minhits2combo(int gun) void checkcombo (client *target, client *actor, int damage, int gun) { - int diffhittime = servmillis - actor->lasthit; - actor->lasthit = servmillis; + int diffhittime = servmillis - actor->md.lasthit; + actor->md.lasthit = servmillis; if ((gun == GUN_SHOTGUN && gun == GUN_GRENADE) && damage < 20) { - actor->lastgun = gun; + actor->md.lastgun = gun; return; } if ( diffhittime < 750 ) { - if ( gun == actor->lastgun ) { + if ( gun == actor->md.lastgun ) { if ( diffhittime * 2 < guns[gun].attackdelay * 3 ) { - actor->combohits++; - actor->combotime+=diffhittime; - actor->combodamage+=damage; + actor->md.combohits++; + actor->md.combotime+=diffhittime; + actor->md.combodamage+=damage; int mh2c = minhits2combo(gun); - if ( actor->combohits > mh2c && actor->combo < 3 && actor->combohits % mh2c == 1 ) { - actor->combo++; - actor->points += 10; - actor->ncombos++; + if ( actor->md.combohits > mh2c && actor->md.combo < 3 && actor->md.combohits % mh2c == 1 ) { + actor->md.combo++; + actor->state.points += 10; + actor->md.ncombos++; } } } else { switch (gun) { case GUN_KNIFE: case GUN_PISTOL: - if ( guns[actor->lastgun].isauto ) break; + if ( guns[actor->md.lastgun].isauto ) break; case GUN_GRENADE: - actor->combohits++; - actor->combotime+=diffhittime; - actor->combodamage+=damage; - actor->combo++; - actor->points += 10; - actor->ncombos++; + actor->md.combohits++; + actor->md.combotime+=diffhittime; + actor->md.combodamage+=damage; + actor->md.combo++; + actor->state.points += 10; + actor->md.ncombos++; break; } } } else { - actor->combo=0; - actor->combotime=0; - actor->combodamage=0; - actor->combohits=0; + actor->md.combo=0; + actor->md.combotime=0; + actor->md.combodamage=0; + actor->md.combohits=0; } - actor->lastgun = gun; + actor->md.lastgun = gun; } #define COVERDIST 2000 // about 45 cubes @@ -151,7 +151,7 @@ int checkteamrequests(int sender) client *ant = clients[sender]; loopv(clients) { client *prot = clients[i]; - if ( i!=sender && prot->type!=ST_EMPTY && prot->team==ant->team && prot->ask>=0 && prot->askmillis + 5000 > gamemillis ) { + if ( i!=sender && prot->type!=ST_EMPTY && prot->team==ant->team && prot->md.ask>=0 && prot->md.askmillis + 5000 > gamemillis ) { float dist = POW2XY(ant->state.o,prot->state.o); if (dist < bestdist) { bestid = i; @@ -170,8 +170,8 @@ void checkteamplay(int s, int sender) switch(s){ case S_COVERME: case S_STAYTOGETHER: - actor->ask = s; - actor->askmillis = gamemillis; + actor->md.ask = s; + actor->md.askmillis = gamemillis; break; case S_AFFIRMATIVE: case S_ALLRIGHTSIR: @@ -179,9 +179,9 @@ void checkteamplay(int s, int sender) { int id = checkteamrequests(sender); if (id >= 0) { - actor->linked = id; - actor->linkmillis = gamemillis; - actor->linkreason = s; + actor->md.linked = id; + actor->md.linkmillis = gamemillis; + actor->md.linkreason = s; sendf(actor->clientnum, 1, "ri2", SV_HUDEXTRAS, 100+id); } break; @@ -218,8 +218,8 @@ inline void testcover(int msg, int factor, client *actor) { if ( a2c < COVERDIST && c2t < COVERDIST && a2t < COVERDIST ) { sendf(actor->clientnum, 1, "ri2", SV_HUDEXTRAS, msg); - actor->points += factor * clientnumber; - actor->ncovers++; + actor->state.points += factor * clientnumber; /** clientnumber now include the spectators... FIXME */ + actor->md.ncovers++; } } @@ -230,7 +230,7 @@ inline void testcover(int msg, int factor, client *actor) bool validlink (client *actor, int cn) { - return actor->linked >= 0 && actor->linked == cn && gamemillis < actor->linkmillis + 20000 && valid_client(actor->linked); + return actor->md.linked >= 0 && actor->md.linked == cn && gamemillis < actor->md.linkmillis + 20000 && valid_client(actor->md.linked); } /** WIP */ @@ -249,32 +249,32 @@ void checkcover (client *target, client *actor) if ( m_ctf ) { if ( f.state == CTFF_INBASE ) { CALCCOVER(f); - testcover(HE_FLAGDEFENDED, 1, actor); /* Flag defended */ + testcover(HE_FLAGDEFENDED, 1, actor); } if ( of.state == CTFF_STOLEN && actor->clientnum != of.actor_cn ) { covered = true; coverid = of.actor_cn; CALCCOVER(clients[of.actor_cn]->state.o); - testcover(HE_FLAGCOVERED, 2, actor); /* Flag covered */ + testcover(HE_FLAGCOVERED, 2, actor); } } else if ( m_htf ) { if ( f.state == CTFF_DROPPED ) { struct { short x, y; } nf; nf.x = f.pos[0]; nf.y = f.pos[1]; CALCCOVER(nf); - testcover(HE_FLAGDEFENDED, 1, actor); /* Flag defended */ + testcover(HE_FLAGDEFENDED, 1, actor); } if ( f.state == CTFF_STOLEN && actor->clientnum != f.actor_cn ) { covered = true; coverid = f.actor_cn; CALCCOVER(clients[f.actor_cn]->state.o); - testcover(HE_FLAGCOVERED, 3, actor); /* Flag covered */ + testcover(HE_FLAGCOVERED, 3, actor); } } } - if ( !(covered && actor->linked==coverid) && validlink(actor,actor->linked) ) + if ( !(covered && actor->md.linked==coverid) && validlink(actor,actor->md.linked) ) { - CALCCOVER(clients[actor->linked]->state.o); - testcover(HE_COVER, 2, actor); /* covered */ + CALCCOVER(clients[actor->md.linked]->state.o); + testcover(HE_COVER, 2, actor); } } @@ -286,42 +286,42 @@ void checkfrag (client *target, client *actor, int gun, bool gib) { int targethasflag = clienthasflag(target->clientnum); int actorhasflag = clienthasflag(actor->clientnum); - target->points -= 5; + target->state.points -= 5; if(target!=actor) { if(!isteam(target->team, actor->team)) { if (m_teammode) { - if(!m_flags) actor->points += 5 * target->points / 100; - else actor->points += 4 * target->points / 100; + if(!m_flags) actor->state.points += 5 * target->state.points / 100; + else actor->state.points += 4 * target->state.points / 100; checkcover (target, actor); - if ( m_htf && actorhasflag >= 0 ) actor->points += clientnumber; + if ( m_htf && actorhasflag >= 0 ) actor->state.points += clientnumber; if ( targethasflag >= 0 ) { - actor->points += 3 * clientnumber; - if ( m_htf ) target->points -= clientnumber; + actor->state.points += 3 * clientnumber; + if ( m_htf ) target->state.points -= clientnumber; } } - else actor->points += 3 * target->points / 100; + else actor->state.points += 3 * target->state.points / 100; if (gib) { - if ( gun == GUN_GRENADE ) actor->points += 10; + if ( gun == GUN_GRENADE ) actor->state.points += 10; else if ( gun == GUN_SNIPER ) { - actor->points += 15; - actor->nhs++; + actor->state.points += 15; + actor->md.nhs++; } - else if ( gun == GUN_KNIFE ) actor->points += 20; + else if ( gun == GUN_KNIFE ) actor->state.points += 20; } - else actor->points += 10; + else actor->state.points += 10; - if ( actor->combo ) sendf(actor->clientnum, 1, "ri2", SV_HUDEXTRAS, 0); + if ( actor->md.combo ) sendf(actor->clientnum, 1, "ri2", SV_HUDEXTRAS, actor->md.combo > 2 ? HE_MASTERCOMBO : HE_COMBO); } else { if ( targethasflag >= 0 ) { - actor->points -= 2 * clientnumber; + actor->state.points -= 2 * clientnumber; } - else actor->points -= 10; + else actor->state.points -= 10; } } diff --git a/source/src/tools.h b/source/src/tools.h index 6599b4ae..4f142886 100644 --- a/source/src/tools.h +++ b/source/src/tools.h @@ -132,6 +132,31 @@ struct stringformatter //#define s_sprintfdlv(d,last,fmt) string d; { va_list ap; va_start(ap, last); formatstring(d, fmt, ap); va_end(ap); } //#define s_sprintfdv(d,fmt) s_sprintfdlv(d,fmt,fmt) +inline char *stolower(const char *s, char *o, int max) +{ + char *c = (char *)s, *r = o; + int n = 0; max--; + *o = *c; c++; o++; // let the first char untouched + while( *c!='\0' && n < max ) { + *o = tolower(*c); + n++; o++; c++; + } + *o='\0'; + return r; +} + +inline char *stoupper(const char *s, char *o, int max) +{ + char *c = (char *)s, *r = o; + int n = 0; max--; + while( *c!='\0' && n < max ) { + *o = toupper(*c); + n++; o++; c++; + } + *o='\0'; + return r; +} + #define loopv(v) for(int i = 0; i<(v).length(); i++) #define loopvj(v) for(int j = 0; j<(v).length(); j++) #define loopvk(v) for(int k = 0; k<(v).length(); k++)