diff --git a/source/src/clients2c.cpp b/source/src/clients2c.cpp index 9b217105..6d048569 100644 --- a/source/src/clients2c.cpp +++ b/source/src/clients2c.cpp @@ -313,6 +313,16 @@ VARP(hudextras, 0, 0, 3); int teamworkid = -1; +char *strcaps(const char *s, bool on) +{ + static string r; + char *o = r; + if(on) while(*s && o < &r[sizeof(r)-1]) *o++ = toupper(*s++); + else while(*s && o < &r[sizeof(r)-1]) *o++ = tolower(*s++); + *o = '\0'; + return r; +} + void showhudextras(char hudextras, char value){ void (*outf)(const char *s, ...) = (hudextras > 1 ? hudoutf : conoutf); bool caps = hudextras < 3 ? false : true; @@ -699,7 +709,7 @@ void parsemessages(int cn, playerent *d, ucharbuf &p, bool demo = false) vec from, to; loopk(3) to[k] = getint(p)/DMF; playerent *s = getclient(scn); - if(!s || !weapon::valid(gun)) break; + if(!s || !valid_weapon(gun)) break; loopk(3) from[k] = s->o.v[k]; if(gun==GUN_SHOTGUN) createrays(from, to); s->lastaction = lastmillis; diff --git a/source/src/entity.h b/source/src/entity.h index f80af4e5..855ee009 100644 --- a/source/src/entity.h +++ b/source/src/entity.h @@ -54,7 +54,8 @@ struct entity : persistent_entity }; enum { GUN_KNIFE = 0, GUN_PISTOL, GUN_CARBINE, GUN_SHOTGUN, GUN_SUBGUN, GUN_SNIPER, GUN_ASSAULT, GUN_CPISTOL, GUN_GRENADE, GUN_AKIMBO, NUMGUNS }; -#define reloadable_gun(g) (g != GUN_KNIFE && g != GUN_GRENADE) +#define valid_weapon(g) ((g) >= GUN_KNIFE && (g) < NUMGUNS) +#define reloadable_gun(g) ((g) != GUN_KNIFE && (g) != GUN_GRENADE) #define SGRAYS 21 #define SGDMGTOTAL 90 @@ -82,7 +83,7 @@ struct itemstat { int add, start, max, sound; }; extern itemstat ammostats[NUMGUNS]; 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; }; +struct guninfo { char modelname[23], title[42]; 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[]; @@ -489,7 +490,7 @@ public: void hitpush(int damage, const vec &dir, playerent *actor, int gun) { - if(gun<0 || gun>NUMGUNS) return; + if(!valid_weapon(gun)) return; vec push(dir); push.mul(damage/100.0f*guns[gun].pushfactor); vel.add(push); diff --git a/source/src/jpegenc.h b/source/src/jpegenc.h index 94a05e80..7ed4de9a 100644 --- a/source/src/jpegenc.h +++ b/source/src/jpegenc.h @@ -5,12 +5,11 @@ // Based on work by Cristian Cuturicu // http://www.wotsit.org/download.asp?f=jpeg&sc=335837440 -typedef unsigned char BYTE; -typedef signed char SBYTE; -typedef signed short int SWORD; -typedef unsigned short int WORD; -typedef unsigned long int DWORD; -typedef signed long int SDWORD; +typedef uint8_t BYTE; +typedef int8_t SBYTE; +typedef int16_t SWORD; +typedef uint16_t WORD; +typedef int32_t SDWORD; typedef struct { BYTE length; WORD value;} bitstring; diff --git a/source/src/renderhud.cpp b/source/src/renderhud.cpp index 79826437..0486d97f 100644 --- a/source/src/renderhud.cpp +++ b/source/src/renderhud.cpp @@ -332,8 +332,7 @@ void drawequipicons(playerent *p) if(c==GUN_AKIMBO || c==GUN_CPISTOL) c = GUN_PISTOL; // same icon for akimb & pistol if(c>3) { c -= 4; r = 1; } - if(p->weaponsel && p->weaponsel->type>=GUN_KNIFE && p->weaponsel->typeweaponsel && valid_weapon(p->weaponsel->type)) drawequipicon(HUDPOS_WEAPON*2, 1650, c, r); glEnable(GL_BLEND); } @@ -1051,7 +1050,7 @@ void gl_drawhud(int w, int h, int curfps, int nquads, int curvert, bool underwat pushfont("huddigits"); draw_textf("%d", HUDPOS_HEALTH + HUDPOS_NUMBERSPACING, 823, p->health); if(p->armour) draw_textf("%d", HUDPOS_ARMOUR + HUDPOS_NUMBERSPACING, 823, p->armour); - if(p->weaponsel && p->weaponsel->type>=GUN_KNIFE && p->weaponsel->typeweaponsel && valid_weapon(p->weaponsel->type)) { glMatrixMode(GL_MODELVIEW); if (p->weaponsel->type!=GUN_GRENADE) p->weaponsel->renderstats(); diff --git a/source/src/server.cpp b/source/src/server.cpp index 5e905c9c..7542b2a4 100644 --- a/source/src/server.cpp +++ b/source/src/server.cpp @@ -3105,7 +3105,7 @@ void process(ENetPacket *packet, int sender, int chan) case SV_WEAPCHANGE: { int gunselect = getint(p); - if(gunselect<0 || gunselect>=NUMGUNS || gunselect == GUN_CPISTOL) break; + if(!valid_weapon(gunselect) || gunselect == GUN_CPISTOL) break; if(!m_demo && !m_coop) checkweapon(type,gunselect); cl->state.gunselect = gunselect; QUEUE_MSG; @@ -3115,7 +3115,7 @@ void process(ENetPacket *packet, int sender, int chan) case SV_PRIMARYWEAP: { int nextprimary = getint(p); - if (nextprimary < 0 || nextprimary >= NUMGUNS) break; + if(!valid_weapon(nextprimary)) break; cl->state.nextprimary = nextprimary; break; } @@ -3204,7 +3204,7 @@ void process(ENetPacket *packet, int sender, int chan) { int ls = getint(p), gunselect = getint(p); if((cl->state.state!=CS_ALIVE && cl->state.state!=CS_DEAD && cl->state.state!=CS_SPECTATE) || - ls!=cl->state.lifesequence || cl->state.lastspawn<0 || gunselect<0 || gunselect>=NUMGUNS || gunselect == GUN_CPISTOL) break; + ls!=cl->state.lifesequence || cl->state.lastspawn<0 || !valid_weapon(gunselect) || gunselect == GUN_CPISTOL) break; cl->state.lastspawn = -1; cl->state.spawn = gamemillis; cl->autospawn = false; diff --git a/source/src/server.h b/source/src/server.h index 5bc76f62..350b7b66 100644 --- a/source/src/server.h +++ b/source/src/server.h @@ -525,18 +525,18 @@ guninfo guns[NUMGUNS] = //mKR: mdl_kick_rot && mKB: mdl_kick_back //reI: recoilincrease && reB: recoilbase && reM: maxrecoil && reF: recoilbackfade //pFX: pushfactor - //modelname reload attackdelay piercing part recoil mKR reI reM pFX - // sound reloadtime damage projspeed spread magsize mKB reB reF isauto - { "knife", S_KNIFE, S_NULL, 0, 500, 50, 100, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, false }, - { "pistol", S_PISTOL, S_RPISTOL, 1400, 160, 18, 0, 0, 0, 53, 10, 10, 6, 5, 6, 35, 58, 125, 1, false }, - { "carbine", S_CARBINE, S_RCARBINE, 1800, 720, 60, 40, 0, 0, 10, 60, 10, 4, 4, 10, 60, 60, 150, 1, false }, - { "shotgun", S_SHOTGUN, S_RSHOTGUN, 2400, 880, 1, 0, 0, 0, 1, 35, 7, 9, 9, 10, 140, 140, 125, 1, false }, // CAUTION dmg only sane for server! - { "subgun", S_SUBGUN, S_RSUBGUN, 1650, 80, 16, 0, 0, 0, 45, 15, 30, 1, 2, 5, 25, 50, 188, 1, true }, - { "sniper", S_SNIPER, S_RSNIPER, 1950, 1500, 82, 25, 0, 0, 50, 50, 5, 4, 4, 10, 85, 85, 100, 1, false }, - { "assault", S_ASSAULT, S_RASSAULT, 2000, 120, 22, 0, 0, 0, 18, 30, 20, 0, 2, 3, 25, 50, 115, 1, true }, - { "cpistol", S_PISTOL, S_RPISTOL, 1400, 120, 19, 0, 0, 0, 35, 10, 15, 6, 5, 6, 35, 50, 125, 1, false }, // temporary - { "grenade", S_NULL, S_NULL, 1000, 650, 200, 0, 20, 6, 1, 1, 1, 3, 1, 0, 0, 0, 0, 3, false }, - { "pistol", S_PISTOL, S_RAKIMBO, 1400, 80, 19, 0, 0, 0, 50, 10, 20, 6, 5, 4, 15, 25, 115, 1, true }, + //modelname sound reloadtime damage projspeed spread magsize mKB reB reF isauto + // title reload attackdelay piercing part recoil mKR reI reM pFX + { "knife", "Knife", S_KNIFE, S_NULL, 0, 500, 50, 100, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, false }, + { "pistol", "Pistol", S_PISTOL, S_RPISTOL, 1400, 160, 18, 0, 0, 0, 53, 10, 10, 6, 5, 6, 35, 58, 125, 1, false }, + { "carbine", "TMP-M&A CB", S_CARBINE, S_RCARBINE, 1800, 720, 60, 40, 0, 0, 10, 60, 10, 4, 4, 10, 60, 60, 150, 1, false }, + { "shotgun", "V-19 CS", S_SHOTGUN, S_RSHOTGUN, 2400, 880, 1, 0, 0, 0, 1, 35, 7, 9, 9, 10, 140, 140, 125, 1, false }, // CAUTION dmg only sane for server! + { "subgun", "A-ARD/10 SMG", S_SUBGUN, S_RSUBGUN, 1650, 80, 16, 0, 0, 0, 45, 15, 30, 1, 2, 5, 25, 50, 188, 1, true }, + { "sniper", "AD-81 SR", S_SNIPER, S_RSNIPER, 1950, 1500, 82, 25, 0, 0, 50, 50, 5, 4, 4, 10, 85, 85, 100, 1, false }, + { "assault", "MTP-57 AR", S_ASSAULT, S_RASSAULT, 2000, 120, 22, 0, 0, 0, 18, 30, 20, 0, 2, 3, 25, 50, 115, 1, true }, + { "cpistol", "nop", S_PISTOL, S_RPISTOL, 1400, 120, 19, 0, 0, 0, 35, 10, 15, 6, 5, 6, 35, 50, 125, 1, false }, // temporary + { "grenade", "Grenades", S_NULL, S_NULL, 1000, 650, 200, 0, 20, 6, 1, 1, 1, 3, 1, 0, 0, 0, 0, 3, false }, + { "pistol", "Akimbo", S_PISTOL, S_RAKIMBO, 1400, 80, 19, 0, 0, 0, 50, 10, 20, 6, 5, 4, 15, 25, 115, 1, true }, }; const char *gunnames[NUMGUNS + 1]; diff --git a/source/src/serverevents.h b/source/src/serverevents.h index 8a250faf..aabaea4f 100644 --- a/source/src/serverevents.h +++ b/source/src/serverevents.h @@ -38,7 +38,7 @@ void processevent(client *c, shotevent &e) clientstate &gs = c->state; int wait = e.millis - gs.lastshot; if(!gs.isalive(gamemillis) || - e.gun=NUMGUNS || + !valid_weapon(e.gun) || waitstate; if(!gs.isalive(gamemillis) || - e.gun=NUMGUNS || + !valid_weapon(e.gun) || !reloadable_gun(e.gun) || gs.ammo[e.gun]<=0) return; diff --git a/source/src/serverfiles.h b/source/src/serverfiles.h index 53ae799d..32f07e8e 100644 --- a/source/src/serverfiles.h +++ b/source/src/serverfiles.h @@ -1140,6 +1140,50 @@ struct servernickblacklist : serverconfigfile }; #define FORBIDDENSIZE 15 + +bool issimilar (char s, char d) +{ + s = tolower(s); d = tolower(d); + if ( s == d ) return true; + switch (d) + { + case 'a': if ( s == '@' || s == '4' ) return true; break; + case 'c': if ( s == 'k' ) return true; break; + case 'e': if ( s == '3' ) return true; break; + case 'i': if ( s == '!' || s == '1' ) return true; break; + case 'o': if ( s == '0' ) return true; break; + case 's': if ( s == '$' || s == '5' ) return true; break; + case 't': if ( s == '7' ) return true; break; + case 'u': if ( s == '#' ) return true; break; + } + return false; +} + +bool findpattern (char *s, char *d) // returns true if there is more than 80% of similarity +{ + int len, hit = 0; + if (!d || (len = strlen(d)) < 1) return false; + char *dp = d, *s_end = s + strlen(s); + while (s != s_end) + { + if ( *s == ' ' ) // spaces separate words + { + if ( !issimilar(*(s+1),*dp) ) { dp = d; hit = 0; } // d e t e c t i t + } + else if ( issimilar(*s,*dp) ) { dp++; hit++; } // hit! + else if ( hit > 0 ) // this is not a pair, but there is a previous pattern + { + if (*s == '.' || *s == *(s-1) || issimilar(*(s+1),*dp) ); // separator or typo (do nothing) + else if ( issimilar(*(s+1),*(dp+1)) || *s == '*' ) dp++; // wild card or typo + else hit--; // maybe this is nothing + } + else dp = d; // nothing here + s++; // walk on the string + if ( hit && 5 * hit > 4 * len ) return true; // found it! + } + return false; +} + struct serverforbiddenlist : serverconfigfile { int num; diff --git a/source/src/tools.h b/source/src/tools.h index c902703a..0dce463a 100644 --- a/source/src/tools.h +++ b/source/src/tools.h @@ -135,34 +135,6 @@ struct stringformatter #define defformatstring(d) string d; formatstring(d) #define defvformatstring(d,last,fmt) string d; { va_list ap; va_start(ap, last); vformatstring(d, fmt, ap); va_end(ap); } -inline char *strcaps(const char *s, bool on) -{ - static string r; - char *o = r; - if(on) while(*s && o < &r[sizeof(r)-1]) *o++ = toupper(*s++); - else while(*s && o < &r[sizeof(r)-1]) *o++ = tolower(*s++); - *o = '\0'; - return r; -} - -inline bool issimilar (char s, char d) -{ - s = tolower(s); d = tolower(d); - if ( s == d ) return true; - switch (d) - { - case 'a': if ( s == '@' || s == '4' ) return true; break; - case 'c': if ( s == 'k' ) return true; break; - case 'e': if ( s == '3' ) return true; break; - case 'i': if ( s == '!' || s == '1' ) return true; break; - case 'o': if ( s == '0' ) return true; break; - case 's': if ( s == '$' || s == '5' ) return true; break; - case 't': if ( s == '7' ) return true; break; - case 'u': if ( s == '#' ) return true; break; - } - return false; -} - #define MAXMAPNAMELEN 64 inline bool validmapname(const char *s) { @@ -192,31 +164,6 @@ inline bool validmapname(const char *s) return true; } -inline bool findpattern (char *s, char *d) // returns true if there is more than 80% of similarity -{ - int len, hit = 0; - if (!d || (len = strlen(d)) < 1) return false; - char *dp = d, *s_end = s + strlen(s); - while (s != s_end) - { - if ( *s == ' ' ) // spaces separate words - { - if ( !issimilar(*(s+1),*dp) ) { dp = d; hit = 0; } // d e t e c t i t - } - else if ( issimilar(*s,*dp) ) { dp++; hit++; } // hit! - else if ( hit > 0 ) // this is not a pair, but there is a previous pattern - { - if (*s == '.' || *s == *(s-1) || issimilar(*(s+1),*dp) ); // separator or typo (do nothing) - else if ( issimilar(*(s+1),*(dp+1)) || *s == '*' ) dp++; // wild card or typo - else hit--; // maybe this is nothing - } - else dp = d; // nothing here - s++; // walk on the string - if ( hit && 5 * hit > 4 * len ) return true; // found it! - } - return false; -} - #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++) diff --git a/source/src/weapon.cpp b/source/src/weapon.cpp index d370ec5d..461546e2 100644 --- a/source/src/weapon.cpp +++ b/source/src/weapon.cpp @@ -678,38 +678,14 @@ void raydamage(vec &from, vec &to, playerent *d) } } -const char *weapstr(unsigned int i) -{ - switch (i) - { - case GUN_AKIMBO: - return "Akimbo"; - case GUN_PISTOL: - return "Pistol"; - case GUN_ASSAULT: - return "MTP-57 AR"; - case GUN_SUBGUN: - return "A-ARD/10 SMG"; - case GUN_SNIPER: - return "AD-81 SR"; - case GUN_SHOTGUN: - return "V-19 CS"; - case GUN_KNIFE: - return "Knife"; - case GUN_CARBINE: - return "TMP-M&A CB"; - case GUN_GRENADE: - return "Grenades"; - } - return "x"; -} +const char *weapstr(int i) { return valid_weapon(i) ? guns[i].title : "x"; } VARP(accuracy,0,0,1); void r_accuracy(int h) { int i = player1->weaponsel->type; - if(accuracy && i >= 0 && i < NUMGUNS && i != GUN_CPISTOL) + if(accuracy && valid_weapon(i) && i != GUN_CPISTOL) { int x_offset = 2 * HUDPOS_X_BOTTOMLEFT, y_offset = 2 * (h - 1.75 * FONTH); string line; @@ -928,8 +904,6 @@ void weapon::equipplayer(playerent *pl) pl->setnextprimary(GUN_ASSAULT); } -bool weapon::valid(int id) { return id>=0 && id