diff --git a/config/menus_settings.cfg b/config/menus_settings.cfg index d1184625..02d31365 100644 --- a/config/menus_settings.cfg +++ b/config/menus_settings.cfg @@ -17,6 +17,7 @@ menuitem "A-ARD/10 Submachine Gun" "nextprimary 4;echo A-ARD/10 Submachin menuitem "Precision Tech AD-81 Sniper Rifle" "nextprimary 5;echo Precision Tech AD-81 Sniper Rifle selected" "chmenumdl Weapons weapons/sniper/menu mapmodel 75 12" menuitem "V-19 Combat Shotgun" "nextprimary 3;echo V-19 Combat Shotgun selected" "chmenumdl Weapons weapons/shotgun/menu mapmodel 75 12" menuitem "TMP-M&A Carbine" "nextprimary 2;echo TMP-M&A Carbine selected" "chmenumdl Weapons weapons/rifle/menu mapmodel 75 12" +menuitem "Combat Pistol" "nextprimary 7;echo Combat Pistol selected" "chmenumdl Weapons weapons/cpistol/menu mapmodel 75 12" newmenu CLA diff --git a/config/scripts.cfg b/config/scripts.cfg index 3d10e76f..cf2c15fc 100644 --- a/config/scripts.cfg +++ b/config/scripts.cfg @@ -105,23 +105,24 @@ alias ktf [ votemap 15 $arg1 ] alias primary [ weapon (currentprimary) ] alias secondary [ weapon 1 ] alias melee [ weapon 0 ] -alias grenades [ weapon 7 ] +alias grenades [ weapon 8 ] alias altaction [ (concatword altaction_ (curweapon)) ] alias quicknadethrow_old [ - if (> (magcontent 7) 0) [ + if (> (magcontent 8) 0) [ if (!= (curweapon) 7) [grenades] attack ] onrelease [ sleep 1 [ if (= (curweapon) 7) [weapon (prevweapon)] ] ] ] -loop i 9 [ alias (concatword altaction_ $i) quicknadethrow ] // Quick nade throw is default +loop i 10 [ alias (concatword altaction_ $i) quicknadethrow ] // Quick nade throw is default alias altaction_5 [ setscope 1; onrelease [ setscope 0 ] ] // Sniper -//alias altaction_7 [ attack ] // Grenade // with this comment, you throw the nade and the nade is unselected : Brahma +alias altaction_7 [ setburst 1; onrelease [ setburst 0 ] ] // Combat pistol +//alias altaction_8 [ attack ] // Grenade // with this comment, you throw the nade and the nade is unselected : Brahma alias oldsens $sensitivity diff --git a/config/servercmdline.txt b/config/servercmdline.txt index 92d26286..f337a319 100644 --- a/config/servercmdline.txt +++ b/config/servercmdline.txt @@ -57,6 +57,7 @@ // r revert existing map to older revision // d delete map (default: no one can) // default: CRU (lowercase: any user is allowed to do it; uppercase: admin role is required) +// -Z // sendmap/incoming limit in MB (default = 10MB) // -I // serverinfo text filename prefix, default config/serverinfo // -O // MOTD text filename prefix, default config/motd diff --git a/source/src/clientgame.cpp b/source/src/clientgame.cpp index af4788a9..76a17bcc 100644 --- a/source/src/clientgame.cpp +++ b/source/src/clientgame.cpp @@ -253,6 +253,7 @@ void deathstate(playerent *pl) { if(showscoresondeath) showscores(true); setscope(false); + setburst(false); if(editmode) toggleedit(true); damageblend(-1); if(pl->team == TEAM_SPECT) spectate(SM_FLY); @@ -273,6 +274,7 @@ void spawnstate(playerent *d) // reset player state not persistent if(d==player1) { setscope(false); + setburst(false); } } @@ -570,6 +572,7 @@ void respawnself() { showscores(false); setscope(false); + setburst(false); lasthit = 0; spawnplayer(player1); player1->lifesequence++; diff --git a/source/src/clients2c.cpp b/source/src/clients2c.cpp index 51c21661..b8658866 100644 --- a/source/src/clients2c.cpp +++ b/source/src/clients2c.cpp @@ -555,6 +555,7 @@ void parsemessages(int cn, playerent *d, ucharbuf &p) if(editmode) toggleedit(true); showscores(false); setscope(false); + setburst(false); player1->respawn(); player1->lifesequence = getint(p); player1->health = getint(p); diff --git a/source/src/console.cpp b/source/src/console.cpp index 1513bd92..f85b1d28 100644 --- a/source/src/console.cpp +++ b/source/src/console.cpp @@ -250,7 +250,8 @@ COMMAND(onrelease, ARG_1STR); void saycommand(char *init) // turns input to the command line on or off { SDL_EnableUNICODE(saycommandon = (init!=NULL)); - setscope(false); + setscope(false); + setburst(false); if(!editmode) keyrepeat(saycommandon); copystring(cmdline.buf, init ? init : ">"); // ALL cmdline.buf[0] ARE flag-chars ! ">" is for talk - the previous "no flag-char" item DELETEA(cmdaction); diff --git a/source/src/entities.cpp b/source/src/entities.cpp index baf247d3..d3184b84 100644 --- a/source/src/entities.cpp +++ b/source/src/entities.cpp @@ -170,8 +170,8 @@ void pickupeffects(int n, playerent *d) switch(e.type) { case I_AKIMBO: w = d->weapons[GUN_AKIMBO]; break; - case I_CLIPS: w = d->weapons[GUN_PISTOL]; break; - case I_AMMO: w = d->primweap; break; + case I_CLIPS: if (d->gunselect == GUN_CPISTOL) w = d->weapons[GUN_CPISTOL]; else w = d->weapons[GUN_PISTOL]; break; + case I_AMMO: if (d->primary != GUN_CPISTOL) w = d->primweap; break; case I_GRENADE: w = d->weapons[GUN_GRENADE]; break; } if(w) w->onammopicked(); @@ -318,6 +318,7 @@ bool selectnextprimary(int num) { switch(num) { + case GUN_CPISTOL: case GUN_RIFLE: case GUN_SHOTGUN: case GUN_SUBGUN: @@ -345,14 +346,14 @@ int flagdropmillis = 0; void flagpickup(int fln) { if(flagdropmillis && flagdropmillis>lastmillis) return; - flaginfo &f = flaginfos[fln]; + flaginfo &f = flaginfos[fln]; int action = f.state == CTFF_INBASE ? FA_STEAL : FA_PICKUP; - f.flagent->spawned = false; - f.state = CTFF_STOLEN; - f.actor = player1; // do this although we don't know if we picked the flag to avoid getting it after a possible respawn - f.actor_cn = getclientnum(); - f.ack = false; - addmsg(SV_FLAGACTION, "rii", action, f.team); + f.flagent->spawned = false; + f.state = CTFF_STOLEN; + f.actor = player1; // do this although we don't know if we picked the flag to avoid getting it after a possible respawn + f.actor_cn = getclientnum(); + f.ack = false; + addmsg(SV_FLAGACTION, "rii", action, f.team); } void tryflagdrop(bool manual) diff --git a/source/src/entity.h b/source/src/entity.h index 9e8bac5f..3758c04c 100644 --- a/source/src/entity.h +++ b/source/src/entity.h @@ -43,7 +43,7 @@ struct entity : persistent_entity } }; -enum { GUN_KNIFE = 0, GUN_PISTOL, GUN_RIFLE, GUN_SHOTGUN, GUN_SUBGUN, GUN_SNIPER, GUN_ASSAULT, GUN_GRENADE, GUN_AKIMBO, NUMGUNS }; +enum { GUN_KNIFE = 0, GUN_PISTOL, GUN_RIFLE, 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 SGRAYS 21 @@ -237,14 +237,14 @@ public: { switch(type) { - case I_CLIPS: return ammostats[GUN_PISTOL]; - case I_AMMO: return ammostats[primary]; + case I_CLIPS: { /*if (gunselect == GUN_CPISTOL) return ammostats[GUN_CPISTOL]; else*/ return ammostats[GUN_PISTOL]; } + case I_AMMO: { /*if (primary != GUN_CPISTOL)*/ return ammostats[primary]; /*else return *(itemstat *)0;*/ } case I_GRENADE: return ammostats[GUN_GRENADE]; case I_AKIMBO: return ammostats[GUN_AKIMBO]; case I_HEALTH: - case I_HELMET: - case I_ARMOUR: - return powerupstats[type-I_HEALTH]; + case I_HELMET: + case I_ARMOUR: + return powerupstats[type-I_HEALTH]; default: return *(itemstat *)0; } @@ -254,8 +254,8 @@ public: { switch(type) { - case I_CLIPS: return ammo[akimbo ? GUN_AKIMBO : GUN_PISTOL]weaponsel->type, r = 0; - if(c==GUN_AKIMBO) c = GUN_PISTOL; // same icon for akimb & pistol + 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->mag && p->weaponsel->type != GUN_KNIFE && p->weaponsel->type != GUN_GRENADE)); diff --git a/source/src/server.h b/source/src/server.h index 1feb757c..44ab3d67 100644 --- a/source/src/server.h +++ b/source/src/server.h @@ -421,6 +421,7 @@ itemstat ammostats[NUMGUNS] = {60, 90, 90, S_ITEMAMMO}, //subgun {10, 20, 15, S_ITEMAMMO}, //sniper {40, 60, 60, S_ITEMAMMO}, //assault + {12, 24, 50, S_ITEMAMMO}, //pistol {1, 0, 3, S_ITEMAMMO}, //grenade {72, 0, 72, S_ITEMAKIMBO} //akimbo }; @@ -441,6 +442,7 @@ guninfo guns[NUMGUNS] = { "subgun", S_SUBGUN, S_RSUBGUN, 1650, 80, 15, 0, 0, 40, 15, 30, 1, 2, 4, 15, 40, 175, 1, true }, { "sniper", S_SNIPER, S_RSNIPER, 1950, 1500, 80, 0, 0, 60, 50, 5, 4, 4, 10, 85, 85, 100, 1, false }, { "assault", S_ASSAULT, S_RASSAULT, 2000, 120, 24, 0, 0, 20, 40, 20, 0, 2, 2, 18, 50, 125, 1, true }, + { "cpistol", S_PISTOL, S_RPISTOL, 1400, 80, 19, 0, 0, 35, 10, 8, 6, 5, 6, 35, 58, 125, 1, false }, // temporary { "grenade", S_NULL, S_NULL, 1000, 650, 200, 20, 6, 1, 1, 1, 3, 1, 0, 0, 0, 0, 3, false }, { "pistol", S_PISTOL, S_RAKIMBO, 1400, 80, 19, 0, 0, 45, 10, 16, 6, 5, 8, 10, 18, 150, 1, true }, }; diff --git a/source/src/weapon.cpp b/source/src/weapon.cpp index 2673434d..87ff1a8a 100644 --- a/source/src/weapon.cpp +++ b/source/src/weapon.cpp @@ -16,13 +16,13 @@ void updatelastaction(playerent *d) void checkweaponswitch() { - if(!player1->weaponchanging) return; + if(!player1->weaponchanging) return; int timeprogress = lastmillis-player1->weaponchanging; if(timeprogress>weapon::weaponchangetime) - { + { addmsg(SV_WEAPCHANGE, "ri", player1->weaponsel->type); - player1->weaponchanging = 0; - } + player1->weaponchanging = 0; + } else if(timeprogress>weapon::weaponchangetime/2) { player1->weaponsel = player1->nextweaponsel; @@ -707,6 +707,7 @@ void weapon::equipplayer(playerent *pl) pl->weapons[GUN_GRENADE] = new grenades(pl); pl->weapons[GUN_KNIFE] = new knife(pl); pl->weapons[GUN_PISTOL] = new pistol(pl); + pl->weapons[GUN_CPISTOL] = new cpistol(pl); pl->weapons[GUN_RIFLE] = new rifle(pl); pl->weapons[GUN_SHOTGUN] = new shotgun(pl); pl->weapons[GUN_SNIPER] = new sniperrifle(pl); @@ -1143,6 +1144,83 @@ int assaultrifle::dynspread() { return shots > 3 ? info.spread * 3 : info.spread float assaultrifle::dynrecoil() { return info.recoil + (rnd(8)*-0.01f); } bool assaultrifle::selectable() { return weapon::selectable() && !m_noprimary && this == owner->primweap; } +// combat pistol + +cpistol::cpistol(playerent *owner) : gun(owner, GUN_CPISTOL), bursting(false) {} +bool cpistol::selectable() { return weapon::selectable() && !m_noprimary && this == owner->primweap; } +void cpistol::setburst(bool enable) +{ + if(this == owner->weaponsel && !reloading && owner->state == CS_ALIVE) + { + bursting = enable; + } +} + +void setburst(bool enable) +{ + if(player1->weaponsel->type != GUN_CPISTOL) return; + if(intermission) return; + cpistol *cp = (cpistol *)player1->weaponsel; + cp->setburst(enable); +} + +COMMAND(setburst, ARG_1INT); + +bool cpistol::attack(vec &targ) // modded from gun::attack // FIXME +{ + int attackmillis = lastmillis-owner->lastaction; + if(timebalance < gunwait) attackmillis += timebalance; + if(attackmillisattacking) + { + shots = 0; + checkautoreload(); + return false; + } + + updatelastaction(owner); + if(!mag) + { + audiomgr.playsoundc(S_NOAMMO); + gunwait += 250; + owner->lastattackweapon = NULL; + shots = 0; + checkautoreload(); + return false; + } + + owner->lastattackweapon = this; + shots++; + + if(!bursting || shots > 2) owner->attacking = false; + + vec from = owner->o; + vec to = targ; + from.z -= weaponbeloweye; + + attackphysics(from, to); + + hits.setsize(0); + raydamage(from, to, owner); + attackfx(from, to, 0); + + if ( shots > 2 ) + { + gunwait = 500; + shots = 0; + } + else + { + gunwait = info.attackdelay; + } + mag--; + + sendshoot(from, to); + return true; +} // pistol diff --git a/source/src/weapon.h b/source/src/weapon.h index 31092be5..174adc07 100644 --- a/source/src/weapon.h +++ b/source/src/weapon.h @@ -142,6 +142,14 @@ struct assaultrifle : gun bool selectable(); }; +struct cpistol : gun +{ + bool bursting; + cpistol(playerent *owner); + bool attack(vec &targ); + bool selectable(); + void setburst(bool enable); +}; struct pistol : gun {