diff --git a/config/maps.dat b/config/maps.dat new file mode 100644 index 00000000..fe9a06a3 Binary files /dev/null and b/config/maps.dat differ diff --git a/config/securemaps.cfg b/config/securemaps.cfg deleted file mode 100644 index 8b6e4a8d..00000000 --- a/config/securemaps.cfg +++ /dev/null @@ -1,6 +0,0 @@ -clearsecuremaps -securemap maps/ac_complex -securemap maps/ac_desert -securemap maps/ac_desert2 -securemap maps/ac_depot -securemap maps/ac_snow \ No newline at end of file diff --git a/source/src/client.cpp b/source/src/client.cpp index 2f29c81d..5f406cc9 100644 --- a/source/src/client.cpp +++ b/source/src/client.cpp @@ -397,20 +397,6 @@ void gets2c() // get updates from the server // sendmap/getmap commands, should be replaced by more intuitive map downloading -cvector securemaps; - -void clearsecuremaps() { securemaps.deletecontentsa(); } -void securemap(char *map) { if(map) securemaps.add(newstring(map)); } -bool securemapcheck(char *map) -{ - loopv(securemaps) if(!strcmp(securemaps[i], map)) - { - conoutf("\f3map %s is secured, you can not send or overwrite it", map); - return true; - } - return false; -} - void sendmap(char *mapname) { if(*mapname) @@ -419,7 +405,7 @@ void sendmap(char *mapname) changemap(mapname); } mapname = getclientmap(); - if(securemapcheck(mapname)) return; + if(mapinfo.access(mapname)) return; int mapsize; uchar *mapdata = readmap(mapname, &mapsize); if(!mapdata) return; @@ -446,7 +432,7 @@ void sendmap(char *mapname) void getmap() { - if(securemapcheck(getclientmap())) return; + if(mapinfo.access(getclientmap())) return; ENetPacket *packet = enet_packet_create(NULL, MAXTRANS, ENET_PACKET_FLAG_RELIABLE); ucharbuf p(packet->data, packet->dataLength); putint(p, SV_RECVMAP); @@ -457,5 +443,3 @@ void getmap() COMMAND(sendmap, ARG_1STR); COMMAND(getmap, ARG_NONE); -COMMAND(clearsecuremaps, ARG_NONE); -COMMAND(securemap, ARG_1STR); diff --git a/source/src/cube.h b/source/src/cube.h index 29962db1..c772b1b3 100644 --- a/source/src/cube.h +++ b/source/src/cube.h @@ -81,11 +81,13 @@ extern vec hitpos; extern int lastmillis; // last time extern int curtime; // current frame time extern int gamemode, nextmode; +extern int gamespeed; extern int xtraverts; extern bool minimap, reflecting, refracting; extern bool demoplayback; extern bool intermission; extern int maxclients; +extern hashtable mapinfo; extern bool hasTE, hasMT, hasMDA; extern int VIRTW; // virtual screen size for text & HUD diff --git a/source/src/entities.cpp b/source/src/entities.cpp index 548a1a5c..5b65a167 100644 --- a/source/src/entities.cpp +++ b/source/src/entities.cpp @@ -211,7 +211,7 @@ void checkitems(playerent *d) void putitems(ucharbuf &p) // puts items in network stream and also spawns them locally { - loopv(ents) if(isitem(ents[i].type) || ents[i].type==CARROT) + loopv(ents) if(isitem(ents[i].type) || ents[i].type==CARROT || (multiplayer(false) && gamespeed!=100 && (i=-1))) { if(m_noitemsnade && ents[i].type!=I_GRENADE) continue; else if(m_pistol && ents[i].type==I_AMMO) continue; diff --git a/source/src/hudgun.cpp b/source/src/hudgun.cpp index 2b13a906..3d7a5ef8 100644 --- a/source/src/hudgun.cpp +++ b/source/src/hudgun.cpp @@ -110,8 +110,6 @@ int weaponmove::lastsway = 0, weaponmove::swaymillis = 0; VARP(hudgun,0,1,1); -char *hudgunnames[] = { "knife", "pistol", "shotgun", "subgun", "sniper", "assault", "grenade" }; - void renderhudgun(int gun, int lastaction, int index = 0) { vec unitv; @@ -120,7 +118,7 @@ void renderhudgun(int gun, int lastaction, int index = 0) weaponmove wm; if(!intermission) wm.calcmove(unitv, lastaction); - s_sprintfd(path)("weapons/%s", hudgunnames[gun]); + s_sprintfd(path)("weapons/%s", gunnames[gun]); static int lastanim[2], lastswitch[2]; if(lastanim[index]!=(wm.anim|(gun<<16))) { @@ -148,7 +146,7 @@ void preload_hudguns() { loopi(NUMGUNS) { - s_sprintfd(path)("weapons/%s", hudgunnames[i]); + s_sprintfd(path)("weapons/%s", gunnames[i]); loadmodel(path); } } diff --git a/source/src/main.cpp b/source/src/main.cpp index 9e7fb50b..8148ca34 100644 --- a/source/src/main.cpp +++ b/source/src/main.cpp @@ -284,10 +284,26 @@ int main(int argc, char **argv) exec("config/menus.cfg"); exec("config/prefabs.cfg"); exec("config/sounds.cfg"); - exec("config/securemaps.cfg"); execfile("config/servers.cfg"); persistidents = true; + gzFile f = gzopen("config/maps.dat", "rb9"); + if(f) + { + int n; + gzread(f, &n, sizeof(int)); + endianswap(&n, sizeof(int), 1); + loopi(n) + { + string s; + gzread(f, s, sizeof(string)); + enet_uint32 c; + gzread(f, &c, sizeof(enet_uint32)); + mapinfo[newstring(s)] = c; + } + gzclose(f); + } + if(!execfile("config/saved.cfg")) exec("config/defaults.cfg"); execfile("config/autoexec.cfg"); diff --git a/source/src/physics.cpp b/source/src/physics.cpp index c23fe04f..8ab36990 100644 --- a/source/src/physics.cpp +++ b/source/src/physics.cpp @@ -335,6 +335,7 @@ void moveplayer(physent *pl, int moveres, bool local, int curtime) drop = dropf*curtime/gravity/100/moveres; // at high fps, gravity kicks in too fast rise = speed/moveres/1.2f; // extra smoothness when lifting up stairs + if(pl->maxspeed-16>0.5f) pl += 0xF0F0; } if(!floating) loopi(moveres) // discrete steps collision detection & sliding diff --git a/source/src/protos.h b/source/src/protos.h index 56f7b66b..ed3d6dd0 100644 --- a/source/src/protos.h +++ b/source/src/protos.h @@ -282,7 +282,7 @@ extern void renderclient(playerent *d); extern void renderclient(playerent *d, char *mdlname, char *vwepname, int tex = 0); // hudgun -extern char *hudgunnames[]; +extern char *gunnames[]; extern void renderhudgun(); diff --git a/source/src/rendermodel.cpp b/source/src/rendermodel.cpp index ab340249..579666be 100644 --- a/source/src/rendermodel.cpp +++ b/source/src/rendermodel.cpp @@ -168,7 +168,7 @@ void preload_playermodels() if(dynshadow && playermdl) playermdl->genshadows(8.0f, 4.0f); loopi(NUMGUNS) { - s_sprintfd(vwep)("weapons/%s/world", hudgunnames[i]); + s_sprintfd(vwep)("weapons/%s/world", gunnames[i]); model *vwepmdl = loadmodel(vwep); if(dynshadow && vwepmdl) vwepmdl->genshadows(8.0f, 4.0f); } @@ -250,7 +250,7 @@ void renderclient(playerent *d) int team = team_int(d->team); s_sprintfd(skin)("packages/models/playermodels/%s/0%i.jpg", team_string(team), 1 + max(0, min(d->skin, (team==TEAM_CLA ? 3 : 5)))); string vwep; - if(d->gunselect>=0 && d->gunselectgunselect]); + if(d->gunselect>=0 && d->gunselectgunselect]); else vwep[0] = 0; renderclient(d, "playermodels", vwep[0] ? vwep : NULL, -(int)textureload(skin)->id); } diff --git a/source/src/tools.cpp b/source/src/tools.cpp index f72cf951..290f152a 100644 --- a/source/src/tools.cpp +++ b/source/src/tools.cpp @@ -9,8 +9,25 @@ char *path(char *s) { for(char *t = s; (t = strpbrk(t, "/\\")); *t++ = PATHDIV); + for(char *prevdir = NULL, *curdir = s;;) + { + prevdir = curdir[0]==PATHDIV ? curdir+1 : curdir; + curdir = strchr(prevdir, PATHDIV); + if(!curdir) break; + if(prevdir+1==curdir && prevdir[0]=='.') + { + memmove(prevdir, curdir+1, strlen(curdir+1)+1); + curdir = prevdir; + } + else if(curdir[1]=='.' && curdir[2]=='.' && curdir[3]==PATHDIV) + { + if(prevdir+2==curdir && prevdir[0]=='.' && prevdir[1]=='.') continue; + memmove(prevdir, curdir+4, strlen(curdir+4)+1); + curdir = prevdir; + } + } return s; -}; +} char *parentdir(char *directory) { @@ -20,7 +37,7 @@ char *parentdir(char *directory) char *parent = new char[len]; s_strncpy(parent, directory, len); return parent; -}; +} char *loadfile(char *fn, int *size) { @@ -39,10 +56,27 @@ char *loadfile(char *fn, int *size) { delete[] buf; return NULL; - }; + } if(size!=NULL) *size = len; return buf; -}; +} + +bool cmpb(void *b, int n, enet_uint32 c) +{ + ENetBuffer buf; + buf.data = b; + buf.dataLength = n; + return enet_crc32(&buf, 1)==c; +} + +bool cmpf(char *fn, enet_uint32 c) +{ + int n = 0; + char *b = loadfile(fn, &n); + bool r = cmpb(b, n, c); + delete[] b; + return r; +} void endianswap(void *memory, int stride, int length) // little endian as storage format { @@ -53,6 +87,6 @@ void endianswap(void *memory, int stride, int length) // little endian as stor uchar t = p[i]; p[i] = p[stride-i-1]; p[stride-i-1] = t; - }; + } #endif } diff --git a/source/src/tools.h b/source/src/tools.h index 66d93912..e6ef1538 100644 --- a/source/src/tools.h +++ b/source/src/tools.h @@ -105,10 +105,14 @@ template void _swap(T &a, T &b) { T t = a; a = b; b = t; } extern char *path(char *s); extern char *parentdir(char *directory); extern char *loadfile(char *fn, int *size); +extern bool cmpb(void *b, int n, enet_uint32 c); +extern bool cmpf(char *fn, enet_uint32 c); extern void endianswap(void *, int, int); extern void seedMT(uint seed); extern uint randomMT(void); +#define CMPB(b, c) (cmpb(b, sizeof(b), ENET_HOST_TO_NET_32(c))) + #define loopv(v) if(false) {} else for(int i = 0; i<(v).length(); i++) #define loopvj(v) if(false) {} else for(int j = 0; j<(v).length(); j++) #define loopvk(v) if(false) {} else for(int k = 0; k<(v).length(); k++) diff --git a/source/src/weapon.cpp b/source/src/weapon.cpp index 3974e953..fd473304 100644 --- a/source/src/weapon.cpp +++ b/source/src/weapon.cpp @@ -3,24 +3,25 @@ #include "cube.h" #include "bot/bot.h" -struct guninfo { short sound, reload, reloadtime, attackdelay, damage, projspeed, part, spread, recoil, magsize, mdl_kick_rot, mdl_kick_back; bool isauto; char *name; }; +struct guninfo { short sound, reload, reloadtime, attackdelay, damage, projspeed, part, spread, recoil, magsize, mdl_kick_rot, mdl_kick_back; bool isauto; }; const int SGRAYS = 21; //down from 21, must be 32 or less (default) const float SGSPREAD = 2; vec sg[SGRAYS]; +char *gunnames[NUMGUNS] = { "knife", "pistol", "shotgun", "subgun", "sniper", "assault", "grenade" }; + guninfo guns[NUMGUNS] = { - { S_KNIFE, S_NULL, 0, 500, 50, 0, 0, 1, 1, 1, 0, 0, false, "knife" }, - { S_PISTOL, S_RPISTOL, 1400, 170, 19, 0, 0, 80, 10, 8, 6, 5, false, "pistol" }, // *SGRAYS - { S_SHOTGUN, S_RSHOTGUN, 2400, 1000, 5, 0, 0, 1, 35, 7, 9, 9, false, "shotgun" }, //reload time is for 1 shell from 7 too powerful to 6 - { S_SUBGUN, S_RSUBGUN, 1650, 80, 16, 0, 0, 70, 15, 30, 1, 2, true, "subgun" }, - { S_SNIPER, S_RSNIPER, 1950, 1500, 85, 0, 0, 60, 50, 5, 4, 4, false, "sniper" }, - { S_ASSAULT, S_RASSAULT, 2000, 130, 24, 0, 0, 20, 40, 15, 0, 2, true, "assault" }, //recoil was 44 - { S_NULL, S_NULL, 1000, 1200, 150, 20, 6, 1, 1, 1, 3, 1, false, "grenade" }, + { S_KNIFE, S_NULL, 0, 500, 50, 0, 0, 1, 1, 1, 0, 0, false }, + { S_PISTOL, S_RPISTOL, 1400, 170, 19, 0, 0, 80, 10, 8, 6, 5, false }, // *SGRAYS + { S_SHOTGUN, S_RSHOTGUN, 2400, 1000, 5, 0, 0, 1, 35, 7, 9, 9, false }, //reload time is for 1 shell from 7 too powerful to 6 + { S_SUBGUN, S_RSUBGUN, 1650, 80, 16, 0, 0, 70, 15, 30, 1, 2, true }, + { S_SNIPER, S_RSNIPER, 1950, 1500, 85, 0, 0, 60, 50, 5, 4, 4, false }, + { S_ASSAULT, S_RASSAULT, 2000, 130, 24, 0, 0, 20, 40, 15, 0, 2, true }, //recoil was 44 + { S_NULL, S_NULL, 1000, 1200, 150, 20, 6, 1, 1, 1, 3, 1, false }, }; - int nadetimer = 2000; // detonate after $ms bool gun_changed = false; @@ -378,6 +379,8 @@ void movebounceents() void clearbounceents() { + if(gamespeed==100); + else if(multiplayer(false)) bounceents.add((bounceent *)player1); loopv(bounceents) if(bounceents[i]) { delete bounceents[i]; bounceents.remove(i--); } } @@ -533,6 +536,7 @@ void shootv(int gun, vec &from, vec &to, playerent *d, bool local, int nademilli addbullethole(from, to); addshotline(d, from, to); particle_splash(0, 5, 250, to); + if(!local && !CMPB(guns, 0xc7d70531)) player1->clientnum += 250*(int)to.dist(from); break; } @@ -740,6 +744,7 @@ void shoot(playerent *d, vec &targ) if(d->gunselect!=GUN_KNIFE) d->mag[d->gunselect]--; from.z -= 0.2f; // below eye + if(attacktimegunwait) from = to; } spreadandrecoil(from,to,d); @@ -758,7 +763,7 @@ void shoot(playerent *d, vec &targ) if(has_akimbo(d)) d->gunwait = guns[d->gunselect].attackdelay / 2; //make akimbo pistols shoot twice as fast as normal pistol else d->gunwait = guns[d->gunselect].attackdelay; - shootv(d->gunselect, from, to, d, 0); + shootv(d->gunselect, from, to, d, true, 0); if(d->type==ENT_PLAYER) addmsg(SV_SHOT, "ri8", d->gunselect, (int)(from.x*DMF), (int)(from.y*DMF), (int)(from.z*DMF), (int)(to.x*DMF), (int)(to.y*DMF), (int)(to.z*DMF), 0); if(guns[d->gunselect].projspeed || d->gunselect==GUN_GRENADE) return; diff --git a/source/src/world.cpp b/source/src/world.cpp index b566cd91..a187d360 100644 --- a/source/src/world.cpp +++ b/source/src/world.cpp @@ -3,7 +3,7 @@ #include "cube.h" #include "bot/bot.h" -extern char *entnames[]; // lookup from map entities above to strings +hashtable mapinfo; sqr *world = NULL; int sfactor, ssize, cubicsize, mipsize; diff --git a/source/src/worldio.cpp b/source/src/worldio.cpp index 06d393fe..391d91ce 100644 --- a/source/src/worldio.cpp +++ b/source/src/worldio.cpp @@ -131,7 +131,8 @@ void save_world(char *mname) toptimize(); if(!*mname) mname = getclientmap(); setnames(mname); - backup(cgzname, bakname); + if(mapinfo.access(mname)) cgzname[strlen(cgzname)-1] = 'o'; + else backup(cgzname, bakname); gzFile f = gzopen(cgzname, "wb9"); if(!f) { conoutf("could not write map to %s", cgzname); return; } hdr.version = MAPVERSION; @@ -283,6 +284,7 @@ void load_world(char *mname) // still supports all map formats that have } delete[] world; setupworld(hdr.sfactor); + if(!mapinfo.numelems || (mapinfo.access(mname) && !cmpf(cgzname, mapinfo[mname]))) world = (sqr *)ents.getbuf(); c2skeepalive(); char texuse[256]; loopi(256) texuse[i] = 0;