From 1ef48c8a30ff9328cb3c1b87973cd3a0fbb7f2b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20G=C3=B6ransson?= Date: Tue, 28 May 2013 22:47:25 +0000 Subject: [PATCH] Promod LIVE V2.15 release --- compile.bat | 2 +- compile_fastfile.bat | 2 +- maps/mp/gametypes/_class.gsc | 24 ---- maps/mp/gametypes/_globallogic.gsc | 198 +++++++++++++-------------- maps/mp/gametypes/_quickmessages.gsc | 4 + maps/mp/gametypes/_weapons.gsc | 124 ++++++++++++++++- maps/mp/gametypes/dom.gsc | 2 + maps/mp/gametypes/koth.gsc | 4 + maps/mp/gametypes/sab.gsc | 4 + maps/mp/gametypes/sd.gsc | 4 + pb/promod_iwd_md5.cfg | 2 +- promod/dvarmon.gsc | 8 +- promod/scorebot.gsc | 2 +- promod/servercheck.gsc | 6 +- promod/setvariables.gsc | 2 +- readme.txt | 31 +++-- server.cfg | 2 +- server_setup.txt | 6 +- ui_mp/main.menu | 2 +- ui_mp/scriptmenus/quickpromod.menu | 18 +++ 20 files changed, 286 insertions(+), 161 deletions(-) diff --git a/compile.bat b/compile.bat index 8527877..0975309 100644 --- a/compile.bat +++ b/compile.bat @@ -8,7 +8,7 @@ @echo off -SET mod_name=promodlive214 +SET mod_name=promodlive215 SET work_directory=%~dp0 cd %work_directory% diff --git a/compile_fastfile.bat b/compile_fastfile.bat index ec499b8..4a4eac3 100644 --- a/compile_fastfile.bat +++ b/compile_fastfile.bat @@ -25,7 +25,7 @@ copy mod.csv ..\..\zone_source /Y cd ..\..\bin linker_pc.exe -language english -compress -cleanup mod -verbose -cd ..\mods\promodlive214 +cd ..\mods\promodlive215 copy ..\..\zone\english\mod.ff pause diff --git a/maps/mp/gametypes/_class.gsc b/maps/mp/gametypes/_class.gsc index c428649..edee164 100644 --- a/maps/mp/gametypes/_class.gsc +++ b/maps/mp/gametypes/_class.gsc @@ -246,28 +246,4 @@ setClass( newClass ) { self setClientDvar( "loadout_curclass", newClass ); self.curClass = newClass; -} - -cac_modified_damage( victim, attacker, damage, meansofdeath ) -{ - if( !isdefined( victim) || !isdefined( attacker ) || !isplayer( attacker ) || !isplayer( victim ) ) - return damage; - if( attacker.sessionstate != "playing" || !isdefined( damage ) || !isdefined( meansofdeath ) ) - return damage; - if( meansofdeath == "" ) - return damage; - - final_damage = damage; - - if( isPrimaryDamage( meansofdeath ) ) - final_damage = damage*1.4; - - return int( final_damage ); -} - -isPrimaryDamage( meansofdeath ) -{ - if( meansofdeath == "MOD_RIFLE_BULLET" || meansofdeath == "MOD_PISTOL_BULLET" ) - return true; - return false; } \ No newline at end of file diff --git a/maps/mp/gametypes/_globallogic.gsc b/maps/mp/gametypes/_globallogic.gsc index 6794e22..5ae6619 100644 --- a/maps/mp/gametypes/_globallogic.gsc +++ b/maps/mp/gametypes/_globallogic.gsc @@ -1042,6 +1042,8 @@ endGame( winner, endReasonText ) "ui_hud_hardcore", 1, "cg_drawSpectatorMessages", 0, "g_compassShowEnemies", 0 ); + + player maps\mp\gametypes\_weapons::printStats(); } roundEndWait( level.postRoundTime ); @@ -2996,6 +2998,7 @@ Callback_PlayerDisconnect() self removeDisconnectedPlayerFromPlacement(); self promod\shoutcast::removePlayer(); + self maps\mp\gametypes\_weapons::printStats(); if ( isDefined( self.pers["team"] ) && ( self.pers["team"] == "allies" || self.pers["team"] == "axis" ) ) thread maps\mp\gametypes\_promod::updateClassAvailability( self.pers["team"] ); @@ -3030,24 +3033,18 @@ Callback_PlayerDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, s if ( !isDefined( level.rdyup ) ) level.rdyup = false; - iDamage = maps\mp\gametypes\_class::cac_modified_damage( self, eAttacker, iDamage, sMeansOfDeath ); - self.iDFlags = iDFlags; - self.iDFlagsTime = getTime(); - - if ( getDvarInt("g_knockback") != 1000 || isDefined( game["state"] ) && game["state"] == "postgame" || self.sessionteam == "spectator" || isDefined( game["PROMOD_MATCH_MODE"] ) && game["PROMOD_MATCH_MODE"] == "strat" && isDefined( self.flying ) && self.flying || isDefined( level.bombDefused ) && level.bombDefused || isDefined( level.bombExploded ) && level.bombExploded && self.pers["team"] == game["attackers"] ) + if ( getDvarInt("g_knockback") != 1000 || isDefined( game["state"] ) && game["state"] == "postgame" || self.sessionteam == "spectator" || isDefined( game["PROMOD_MATCH_MODE"] ) && game["PROMOD_MATCH_MODE"] == "strat" && isDefined( self.flying ) && self.flying || isDefined( level.bombDefused ) && level.bombDefused || isDefined( level.bombExploded ) && level.bombExploded && self.pers["team"] == game["attackers"] || isDefined( game["PROMOD_KNIFEROUND"] ) && game["PROMOD_KNIFEROUND"] && sMeansOfDeath != "MOD_MELEE" && sMeansOfDeath != "MOD_FALLING" && !level.rdyup ) return; - prof_begin( "Callback_PlayerDamage flags/tweaks" ); + if( isDefined(eAttacker) && isPlayer(eAttacker) && isPlayer(self) && eAttacker.sessionstate == "playing" && isDefined(iDamage) && isDefined( sMeansOfDeath ) && sMeansOfDeath != "" && (sMeansOfDeath == "MOD_RIFLE_BULLET" || sMeansOfDeath == "MOD_PISTOL_BULLET")) + iDamage = int(iDamage*1.4); + + self.iDFlags = iDFlags; + self.iDFlagsTime = getTime(); if ( level.rdyup && isDefined( eAttacker ) && isPlayer( eAttacker ) && eAttacker != self ) { - if ( !isDefined( eAttacker.ruptally ) ) - { - eAttacker.ruptally = 0; - eAttacker setclientdvar("self_kills", 0); - } - - if ( eAttacker.ruptally < 0 ) + if ( !isDefined( eAttacker.ruptally ) || eAttacker.ruptally < 0 ) { eAttacker.ruptally = 0; eAttacker setclientdvar("self_kills", 0); @@ -3060,15 +3057,12 @@ Callback_PlayerDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, s return; } - if ( isDefined( game["PROMOD_KNIFEROUND"] ) && game["PROMOD_KNIFEROUND"] && sMeansOfDeath != "MOD_MELEE" && sMeansOfDeath != "MOD_FALLING" && !level.rdyup ) - return; - + // bit arrays are interesting, huh? if( !isDefined( vDir ) ) iDFlags |= level.iDFLAGS_NO_KNOCKBACK; - friendly = false; - - if ( (level.teamBased && (self.health == self.maxhealth)) || !isDefined( self.attackers ) ) + // Not sure exactly what happens here, but ok... + if ( level.teamBased && self.health == self.maxhealth || !isDefined( self.attackers ) ) { self.attackers = []; self.attackerData = []; @@ -3085,54 +3079,48 @@ Callback_PlayerDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, s sWeapon = "destructible_car"; } - prof_end( "Callback_PlayerDamage flags/tweaks" ); + friendly = false; + // if level.iDFLAGS_NO_PROTECTION element in iDflags is not 0, this will happen. NO_PROTECTION == 0 could be god-mode if( !(iDFlags & level.iDFLAGS_NO_PROTECTION) ) { - if ( (isSubStr( sMeansOfDeath, "MOD_GRENADE" ) || isSubStr( sMeansOfDeath, "MOD_EXPLOSIVE" ) || isSubStr( sMeansOfDeath, "MOD_PROJECTILE" )) && isDefined( eInflictor ) && game["PROMOD_MATCH_MODE"] != "match" && eInflictor.classname == "grenade" && ( ( self.lastSpawnTime + 3500) > getTime() && distance( eInflictor.origin, self.lastSpawnPoint.origin ) < 250 || !isDefined ( eAttacker.pers["class"] ) ) ) - { - prof_end( "Callback_PlayerDamage player" ); + if ( (isSubStr( sMeansOfDeath, "MOD_GRENADE" ) || isSubStr( sMeansOfDeath, "MOD_EXPLOSIVE" ) || isSubStr( sMeansOfDeath, "MOD_PROJECTILE" )) && isDefined( eInflictor ) && game["PROMOD_MATCH_MODE"] != "match" && eInflictor.classname == "grenade" && ( (self.lastSpawnTime + 3500) > getTime() && distance( eInflictor.origin, self.lastSpawnPoint.origin ) < 250 || !isDefined ( eAttacker.pers["class"] ) ) ) return; - } - if ( level.teamBased && isPlayer( eAttacker ) && (self != eAttacker) && (self.pers["team"] == eAttacker.pers["team"]) ) + if ( level.teamBased && isPlayer( eAttacker ) && self != eAttacker && self.pers["team"] == eAttacker.pers["team"] ) { - prof_begin( "Callback_PlayerDamage player" ); if ( !level.friendlyfire ) return; - else if ( level.friendlyfire == 1 ) - { - if ( iDamage < 1 ) - iDamage = 1; - - self finishPlayerDamageWrapper(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, psOffsetTime); - } - else if ( level.friendlyfire == 2 && isAlive( eAttacker ) ) + if ( level.friendlyfire == 1 || (level.friendlyfire == 2 || level.friendlyfire == 3) && isAlive( eAttacker ) ) { - iDamage = int(iDamage * 0.5); + if( (level.friendlyfire & 2) > 0 ) // 2 or 3 + iDamage = int(iDamage * 0.5); - if(iDamage < 1) + if ( iDamage < 1 ) iDamage = 1; - eAttacker finishPlayerDamageWrapper(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, psOffsetTime); - } - else if ( level.friendlyfire == 3 && isAlive( eAttacker ) ) - { - iDamage = int(iDamage * 0.5); + if( (level.friendlyfire & 1) > 0 ) // 1 or 3 + { + if(!level.rdyup) + { + if(!isDefined(self.pers["friendly_damage_taken"])) + self.pers["friendly_damage_taken"] = 0; + if(!isDefined(eAttacker.pers["friendly_damage_done"])) + eAttacker.pers["friendly_damage_done"] = 0; - if ( iDamage < 1 ) - iDamage = 1; + self.pers["friendly_damage_taken"] += min(iDamage, self.health); + eAttacker.pers["friendly_damage_done"] += min(iDamage, self.health); + } - self finishPlayerDamageWrapper(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, psOffsetTime); - eAttacker finishPlayerDamageWrapper(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, psOffsetTime); + self finishPlayerDamageWrapper(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, psOffsetTime); + } + if( (level.friendlyfire & 2) > 0 ) // 2 or 3 + eAttacker finishPlayerDamageWrapper(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, psOffsetTime); } - friendly = true; } else { - prof_begin( "Callback_PlayerDamage world" ); - if(iDamage < 1) iDamage = 1; @@ -3147,9 +3135,23 @@ Callback_PlayerDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, s self.attackerData[eAttacker.clientid] = true; } - self finishPlayerDamageWrapper(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, psOffsetTime); + if( !level.rdyup && isDefined(eAttacker) && isPlayer(eAttacker) && eAttacker != self ) + { + if(!isDefined(self.pers["hits"])) + self.pers["hits"] = 0; - prof_end( "Callback_PlayerDamage world" ); + eAttacker.pers["hits"]++; + + if(!isDefined(self.pers["damage_taken"])) + self.pers["damage_taken"] = 0; + if(!isDefined(eAttacker.pers["damage_done"])) + eAttacker.pers["damage_done"] = 0; + + self.pers["damage_taken"] += min(iDamage, self.health); + eAttacker.pers["damage_done"] += min(iDamage, self.health); + } + + self finishPlayerDamageWrapper(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, psOffsetTime); } if ( isDefined(eAttacker) && eAttacker != self ) @@ -3157,12 +3159,8 @@ Callback_PlayerDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, s if ( sMeansOfDeath == "MOD_HEAD_SHOT" ) thread dinkNoise(eAttacker, self); - hasBodyArmor = false; - - if ( iDamage > 0 && getDvarInt( "scr_enable_hiticon" ) == 1 ) - eAttacker thread maps\mp\gametypes\_damagefeedback::updateDamageFeedback( hasBodyArmor ); - else if ( iDamage > 0 && getDvarInt( "scr_enable_hiticon" ) == 2 && !(iDFlags & level.iDFLAGS_PENETRATION) ) - eAttacker thread maps\mp\gametypes\_damagefeedback::updateDamageFeedback( hasBodyArmor ); + if ( iDamage > 0 && ( getDvarInt( "scr_enable_hiticon" ) == 1 || getDvarInt( "scr_enable_hiticon" ) == 2 && !(iDFlags & level.iDFLAGS_PENETRATION) ) ) + eAttacker thread maps\mp\gametypes\_damagefeedback::updateDamageFeedback( false ); } self.hasDoneCombat = true; @@ -3171,58 +3169,55 @@ Callback_PlayerDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, s if ( isdefined( eAttacker ) && eAttacker != self && !friendly ) level.useStartSpawns = false; - prof_begin( "Callback_PlayerDamage log" ); - - damagestring = ""; - metrestring = ""; - - if ( isDefined( sHitLoc ) && sHitLoc != "none") + if( level.rdyup || isDefined( game["PROMOD_MATCH_MODE"] ) && game["PROMOD_MATCH_MODE"] == "strat" ) { - if( isSubStr( sHitLoc, "torso_upper" ) ) - damagestring = "upper torso"; - else if( isSubStr( sHitLoc, "torso_lower" ) ) - damagestring = "lower torso"; - else if( isSubStr( sHitLoc, "leg_upper" ) ) - damagestring = "upper leg"; - else if( isSubStr( sHitLoc, "leg_lower" ) ) - damagestring = "lower leg"; - else if( isSubStr( sHitLoc, "arm_upper" ) ) - damagestring = "upper arm"; - else if( isSubStr( sHitLoc, "arm_lower" ) ) - damagestring = "lower arm"; - else if( isSubStr( sHitLoc, "head" ) || isSubStr( sHitLoc, "helmet" ) ) - damagestring = "head"; - else if( isSubStr( sHitLoc, "neck" ) ) - damagestring = "neck"; - else if( isSubStr( sHitLoc, "foot" ) ) - damagestring = "foot"; - else if( isSubStr( sHitLoc, "hand" ) ) - damagestring = "hand"; - - metrestring = distance(self.origin, eAttacker.origin) * 0.0254; - } - - if ( isDefined( eAttacker ) && isPlayer( eAttacker ) ) - { - if ( eAttacker != self && ( level.rdyup || isDefined( game["PROMOD_MATCH_MODE"] ) && game["PROMOD_MATCH_MODE"] == "strat" ) && isDefined( sHitLoc ) ) + if ( isDefined( eAttacker ) && isPlayer( eAttacker ) && isDefined( sHitLoc ) ) { - if ( sHitLoc == "none" ) - { - eAttacker iprintln("You inflicted " + "^2" + iDamage + "^7 damage to " + self.name); - self iprintln(eAttacker.name + " inflicted " + "^1" + iDamage + "^7 damage to you"); - } - else + if ( eAttacker != self ) { - eAttacker iprintln("You inflicted " + "^2" + iDamage + "^7 damage at a distance of " + "^2" + metrestring + "^7 metres in the " + "^2" + damagestring + "^7 to " + self.name); - self iprintln(eAttacker.name + " inflicted " + "^1" + iDamage + "^7 damage at a distance of " + "^1" + metrestring + "^7 metres in the " + "^1" + damagestring + "^7 to you"); + if ( sHitLoc == "none" ) + { + eAttacker iprintln("You inflicted ^2" + iDamage + "^7 damage to " + self.name); + self iprintln(eAttacker.name + " inflicted ^1" + iDamage + "^7 damage to you"); + } + else + { + damagestring = ""; + if( isSubStr( sHitLoc, "torso_upper" ) ) + damagestring = "upper torso"; + else if( isSubStr( sHitLoc, "torso_lower" ) ) + damagestring = "lower torso"; + else if( isSubStr( sHitLoc, "leg_upper" ) ) + damagestring = "upper leg"; + else if( isSubStr( sHitLoc, "leg_lower" ) ) + damagestring = "lower leg"; + else if( isSubStr( sHitLoc, "arm_upper" ) ) + damagestring = "upper arm"; + else if( isSubStr( sHitLoc, "arm_lower" ) ) + damagestring = "lower arm"; + else if( isSubStr( sHitLoc, "head" ) || isSubStr( sHitLoc, "helmet" ) ) + damagestring = "head"; + else if( isSubStr( sHitLoc, "neck" ) ) + damagestring = "neck"; + else if( isSubStr( sHitLoc, "foot" ) ) + damagestring = "foot"; + else if( isSubStr( sHitLoc, "hand" ) ) + damagestring = "hand"; + + metrestring = int(distance(self.origin, eAttacker.origin) * 2.54) / 100; + + eAttacker iprintln("You inflicted ^2" + iDamage + "^7 damage at a distance of ^2" + metrestring + "^7 metres in the ^2" + damagestring + "^7 to " + self.name); + self iprintln(eAttacker.name + " inflicted ^1" + iDamage + "^7 damage at a distance of ^1" + metrestring + "^7 metres in the ^1" + damagestring + "^7 to you"); + } } + else if ( sHitLoc == "none" ) + self iprintln("You inflicted ^1" + iDamage + "^7 damage to yourself"); } - else if ( eAttacker == self && ( level.rdyup || isDefined( game["PROMOD_MATCH_MODE"] ) && game["PROMOD_MATCH_MODE"] == "strat" ) && isDefined( sHitLoc ) && sHitLoc == "none" ) + else if ( sMeansOfDeath == "MOD_FALLING" ) self iprintln("You inflicted ^1" + iDamage + "^7 damage to yourself"); } - else if ( (level.rdyup || isDefined( game["PROMOD_MATCH_MODE"] ) && game["PROMOD_MATCH_MODE"] == "strat") && sMeansOfDeath == "MOD_FALLING" ) - self iprintln("You inflicted ^1" + iDamage + "^7 damage to yourself"); + // Logging into file if( self.sessionstate != "dead" ) { lpattackerteam = ""; @@ -3245,8 +3240,7 @@ Callback_PlayerDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, s logPrint("D;" + self getGuid() + ";" + self getEntityNumber() + ";" + self.pers["team"] + ";" + self.name + ";" + lpattackGuid + ";" + lpattacknum + ";" + lpattackerteam + ";" + lpattackname + ";" + sWeapon + ";" + iDamage + ";" + sMeansOfDeath + ";" + sHitLoc + "\n"); } - prof_end( "Callback_PlayerDamage log" ); - + // Shoutcaster healthbar update self promod\shoutcast::updatePlayer(); } diff --git a/maps/mp/gametypes/_quickmessages.gsc b/maps/mp/gametypes/_quickmessages.gsc index dfb5646..603b4ec 100644 --- a/maps/mp/gametypes/_quickmessages.gsc +++ b/maps/mp/gametypes/_quickmessages.gsc @@ -123,6 +123,10 @@ quickpromod(response) self iprintln("Record reminder has been "+a+"abled"); break; + case "5": + self maps\mp\gametypes\_weapons::printStats(); + break; + case "silencer": if ( self.pers["team"] != "axis" && self.pers["team"] != "allies" || !isDefined( self.pers["class"] ) || !getDvarInt( "attach_allow_" + self.pers["class"] + "_silencer" ) || self.pers[self.pers["class"]]["loadout_primary"] == "mp44" || self.pers["class"] == "sniper" || self.pers["class"] == "demolitions" ) return; diff --git a/maps/mp/gametypes/_weapons.gsc b/maps/mp/gametypes/_weapons.gsc index d69a47e..aa92e93 100644 --- a/maps/mp/gametypes/_weapons.gsc +++ b/maps/mp/gametypes/_weapons.gsc @@ -71,6 +71,122 @@ onPlayerSpawned() self.hasDoneCombat = false; self thread watchWeaponUsage(); self thread watchGrenadeUsage(); + self thread watchGrenadeAmmo(); + + if(!isDefined(self.pers["shots"])) + self.pers["shots"] = 0; + self thread shotCounter(); + } +} + +watchGrenadeAmmo() +{ + self endon("death"); + self endon("disconnect"); + self endon("game_ended"); + + prim = true; + sec = true; + + while(prim || sec) + { + self waittill("grenade_fire"); + + if((isDefined( game["promod_do_readyup"] ) && game["promod_do_readyup"]) || (isDefined( game["PROMOD_MATCH_MODE"] ) && game["PROMOD_MATCH_MODE"] == "strat") || getDvarInt("sv_cheats")) + break; + + wait 0.25; // 5 frames, ought to be enough + + pg = ""; + if(self hasWeapon("frag_grenade_mp")) + pg = "frag_grenade_mp"; + else if(self hasWeapon("frag_grenade_short_mp")) + pg = "frag_grenade_short_mp"; + else + prim = false; + + sg = ""; + if(self hasWeapon("flash_grenade_mp")) + sg = "flash_grenade_mp"; + else if(self hasWeapon("smoke_grenade_mp")) + sg = "smoke_grenade_mp"; + else + sec = false; + + if(prim && pg != "" && self GetAmmoCount(pg) < 1) + { + self TakeWeapon(pg); + prim = false; + } + + if(sec && sg != "" && self GetAmmoCount(sg) < 1) + { + self TakeWeapon(sg); + sec = false; + } + } +} + +shotCounter() +{ + self endon( "death" ); + self endon( "disconnect" ); + level endon ( "game_ended" ); + + for(;;) + { + self waittill("weapon_fired"); + if(!isDefined( level.rdyup ) || !level.rdyup) + self.pers["shots"]++; + } +} + +printStats() +{ + if(isDefined(game["PROMOD_MATCH_MODE"]) && game["PROMOD_MATCH_MODE"] == "match" && isDefined(self.hasDoneCombat) && self.hasDoneCombat && isDefined(level.gameEnded) && !level.gameEnded && (!isDefined( game["promod_do_readyup"] ) || !game["promod_do_readyup"])) + { + self iprintln("Can't display stats. Wait for the round to end."); + } + else + { + if ( !isDefined( self.pers["damage_done"] ) ) + self.pers["damage_done"] = 0; + + if ( !isDefined( self.pers["damage_taken"] ) ) + self.pers["damage_taken"] = 0; + + if ( !isDefined( self.pers["friendly_damage_done"] ) ) + self.pers["friendly_damage_done"] = 0; + + if ( !isDefined( self.pers["friendly_damage_taken"] ) ) + self.pers["friendly_damage_taken"] = 0; + + if ( !isDefined( self.pers["shots"] ) ) + self.pers["shots"] = 0; + + if ( !isDefined( self.pers["hits"] ) ) + self.pers["hits"] = 0; + + // Log, print, reset + if(self.pers["damage_done"] > 0 || self.pers["damage_taken"] > 0 || self.pers["friendly_damage_done"] > 0 || self.pers["friendly_damage_taken"] > 0 || self.pers["shots"] > 0 || self.pers["hits"] > 0) + logPrint("P_A;" + self getGuid() + ";" + self getEntityNumber() + ";" + self.name + ";" + self.pers["shots"] + ";" + self.pers["hits"] + ";" + self.pers["damage_done"] + ";" + self.pers["damage_taken"] + ";" + self.pers["friendly_damage_done"] + ";" + self.pers["friendly_damage_taken"] + "\n"); + + self iprintln("^3" + self.name); + self iprintln("Damage Done: ^2" + self.pers["damage_done"] + "^7 Damage Taken: ^1" + self.pers["damage_taken"]); + if( level.teamBased ) + self iprintln("Friendly Damage Done: ^2" + self.pers["friendly_damage_done"] + "^7 Friendly Damage Taken: ^1" + self.pers["friendly_damage_taken"]); + acc = 0; + if(self.pers["shots"] > 0) // avoid division by 0 + acc = int(self.pers["hits"]/self.pers["shots"]*10000)/100; + self iprintln("Shots Fired: ^2" + self.pers["shots"] + "^7 Shots Hit: ^2" + self.pers["hits"] + "^7 Accuracy: ^1" + acc + " pct"); + + // Reset the stats afterwards + self.pers["damage_done"] = 0; + self.pers["damage_taken"] = 0; + self.pers["friendly_damage_done"] = 0; + self.pers["friendly_damage_taken"] = 0; + self.pers["shots"] = 0; + self.pers["hits"] = 0; } } @@ -143,13 +259,9 @@ watchWeaponUsage() self endon( "death" ); self endon( "disconnect" ); level endon ( "game_ended" ); - level endon ( "grace_period_ending" ); - for ( ;; ) - { - self waittill ( "begin_firing" ); - self.hasDoneCombat = true; - } + self waittill ( "begin_firing" ); + self.hasDoneCombat = true; } watchGrenadeUsage() diff --git a/maps/mp/gametypes/dom.gsc b/maps/mp/gametypes/dom.gsc index 4a750b5..fa81e6e 100644 --- a/maps/mp/gametypes/dom.gsc +++ b/maps/mp/gametypes/dom.gsc @@ -355,6 +355,8 @@ onUse( player ) if ( isDefined( level.scorebot ) && level.scorebot ) game["promod_scorebot_ticker_buffer"] += "captured" + self.label + "" + player.name; + logPrint("P_F;" + player getGuid() + ";" + player getEntityNumber() + ";" + player.name + "\n"); + self maps\mp\gametypes\_gameobjects::setOwnerTeam( team ); self maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "compass_waypoint_capture" + label ); self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_capture" + label ); diff --git a/maps/mp/gametypes/koth.gsc b/maps/mp/gametypes/koth.gsc index 9ae91d5..8de7029 100644 --- a/maps/mp/gametypes/koth.gsc +++ b/maps/mp/gametypes/koth.gsc @@ -413,6 +413,8 @@ onRadioCapture( player ) if ( isDefined( level.scorebot ) && level.scorebot ) game["promod_scorebot_ticker_buffer"] += "hq_captured" + player.name; + + logPrint("P_HQC;" + player getGuid() + ";" + player getEntityNumber() + ";" + player.name + "\n"); } onRadioDestroy( player ) @@ -445,6 +447,8 @@ onRadioDestroy( player ) if ( isDefined( level.scorebot ) && level.scorebot ) game["promod_scorebot_ticker_buffer"] += "hq_destroyed" + player.name; + + logPrint("P_HQD;" + player getGuid() + ";" + player getEntityNumber() + ";" + player.name + "\n"); } DestroyHQAfterTime( time ) diff --git a/maps/mp/gametypes/sab.gsc b/maps/mp/gametypes/sab.gsc index 1eaa881..3a42095 100644 --- a/maps/mp/gametypes/sab.gsc +++ b/maps/mp/gametypes/sab.gsc @@ -465,6 +465,8 @@ onUse( player ) if ( isDefined( level.scorebot ) && level.scorebot ) game["promod_scorebot_ticker_buffer"] += "planted_by" + player.name; + logPrint("P_P;" + player getGuid() + ";" + player getEntityNumber() + ";" + player.name + "\n"); + level.bombOwner = player; level.sabBomb.autoResetTime = undefined; @@ -491,6 +493,8 @@ onUse( player ) if ( isDefined( level.scorebot ) && level.scorebot ) game["promod_scorebot_ticker_buffer"] += "defused_by" + player.name; + logPrint("P_D;" + player getGuid() + ";" + player getEntityNumber() + ";" + player.name + "\n"); + if ( level.inOverTime && isDefined( level.plantingTeamDead ) ) { thread maps\mp\gametypes\_globallogic::endGame( player.pers["team"], game["strings"][level.bombPlantedBy+"_eliminated"] ); diff --git a/maps/mp/gametypes/sd.gsc b/maps/mp/gametypes/sd.gsc index c878740..5bf2001 100644 --- a/maps/mp/gametypes/sd.gsc +++ b/maps/mp/gametypes/sd.gsc @@ -390,6 +390,8 @@ onUsePlantObject( player ) if ( isDefined( level.scorebot ) && level.scorebot ) game["promod_scorebot_ticker_buffer"] += "planted_by" + player.name; + + logPrint("P_P;" + player getGuid() + ";" + player getEntityNumber() + ";" + player.name + "\n"); } } @@ -411,6 +413,8 @@ onUseDefuseObject( player ) if ( isDefined( level.scorebot ) && level.scorebot ) game["promod_scorebot_ticker_buffer"] += "defused_by" + player.name; + + logPrint("P_D;" + player getGuid() + ";" + player getEntityNumber() + ";" + player.name + "\n"); } onDrop( player ) diff --git a/pb/promod_iwd_md5.cfg b/pb/promod_iwd_md5.cfg index d21b577..fbc31b9 100644 --- a/pb/promod_iwd_md5.cfg +++ b/pb/promod_iwd_md5.cfg @@ -1 +1 @@ -pb_sv_md5tool a "" v mods/promodlive214/promodlive214.iwd SZ276308 AT0 LEN2048 B9ABD1ECBB56A5119EACC754CFD430DC \ No newline at end of file +pb_sv_md5tool a "" v mods/promodlive215/promodlive215.iwd SZ276308 AT0 LEN2048 B9ABD1ECBB56A5119EACC754CFD430DC \ No newline at end of file diff --git a/promod/dvarmon.gsc b/promod/dvarmon.gsc index dda5a2c..2fc8892 100644 --- a/promod/dvarmon.gsc +++ b/promod/dvarmon.gsc @@ -22,10 +22,8 @@ main() for( d = 0; d < dvars.size; d++ ) current_values[d] = getDvar(dvars[d]); - for(;;) - { + for(;;wait 0.05) for ( c = 0; c < dvars.size; c++ ) - { if ( getDvar(dvars[c]) != current_values[c] ) { level.dvarmon[level.dvarmon.size] = "^1" + dvars[c] + " ^3" + current_values[c] + " ^1--> ^3" + getDvar(dvars[c]); @@ -38,10 +36,6 @@ main() thread maps\mp\gametypes\_promod::updateClassAvailability( "axis" ); } } - } - - wait 0.05; - } } dvarHistory() diff --git a/promod/scorebot.gsc b/promod/scorebot.gsc index 87ff9ee..8f388b4 100644 --- a/promod/scorebot.gsc +++ b/promod/scorebot.gsc @@ -49,7 +49,7 @@ actionTicker() setDvar( "__promod_defence_score", game["promod_scorebot_defence_ticker_buffer"], true ); setDvar( "__promod_mode", toLower( getDvar( "promod_mode" ) ), true ); setDvar( "__promod_ticker", getDvar( "__promod_ticker" ), true ); - setDvar( "__promod_version", "Promod LIVE V2.14 EU", true ); + setDvar( "__promod_version", "Promod LIVE V2.15 EU", true ); for(;;) { diff --git a/promod/servercheck.gsc b/promod/servercheck.gsc index 12dd2e5..0843bf5 100644 --- a/promod/servercheck.gsc +++ b/promod/servercheck.gsc @@ -76,9 +76,9 @@ errorMessage() if ( (antilag && dedicated == "dedicated LAN server") || (!antilag && dedicated == "dedicated internet server" && !game["PROMOD_PB_OFF"])) iprintlnbold("^1Server Violation^7: Modified Connection"); - if( isDefined( game["PROMOD_MATCH_MODE"] ) && game["PROMOD_MATCH_MODE"] == "match" || toLower( getDvar( "fs_game" ) ) == "mods/promodlive214" ) + if( isDefined( game["PROMOD_MATCH_MODE"] ) && game["PROMOD_MATCH_MODE"] == "match" || toLower( getDvar( "fs_game" ) ) == "mods/promodlive215" ) { - if( toLower(getDvar("fs_game")) != "mods/promodlive214" ) + if( toLower(getDvar("fs_game")) != "mods/promodlive215" ) iprintlnbold("^1Server Violation^7: Invalid fs_game value"); iwdnames = strToK( getDvar( "sv_iwdnames" ), " " ); @@ -109,7 +109,7 @@ errorMessage() iprintlnbold("^1Server Violation^7: Modified Custom IWD File While In Match Mode"); break; - case "promodlive214": + case "promodlive215": if( iwdsums[i] != "1491770436" ) iprintlnbold("^1Server Violation^7: Modified Promod IWD Detected"); iwd_loaded = true; diff --git a/promod/setvariables.gsc b/promod/setvariables.gsc index a711a71..0fb13de 100644 --- a/promod/setvariables.gsc +++ b/promod/setvariables.gsc @@ -32,5 +32,5 @@ main() game["axis_timeout_called"] = 0; game["promod_first_readyup_done"] = 0; - game["PROMOD_VERSION"] = "Promod ^1LIVE ^7V2.14 EU"; + game["PROMOD_VERSION"] = "Promod ^1LIVE ^7V2.15 EU"; } \ No newline at end of file diff --git a/readme.txt b/readme.txt index d8ba2f0..741b77a 100644 --- a/readme.txt +++ b/readme.txt @@ -1,6 +1,6 @@ -Promod LIVE V2.14 EU - README +Promod LIVE V2.15 EU - README http://www.codpromod.com -2011-11-28 +2013-05-29 #codpromod @ QuakeNet Developers: Trivve & Ingram @@ -9,12 +9,12 @@ Manager: abhi Sponsored by FragNet http://www.fragnet.net -Zip-package (promodlive214_eu.zip) contains: +Zip-package (promodlive215_eu.zip) contains: LICENSE -promodlive214\mod.ff -promodlive214\promodlive214.iwd -promodlive214\z_custom_ruleset.iwd +promodlive215\mod.ff +promodlive215\promodlive215.iwd +promodlive215\z_custom_ruleset.iwd pb\stock_iwd_md5.cfg pb\promod_iwd_md5.cfg pb\pbsvuser.cfg @@ -22,6 +22,18 @@ readme.txt server_setup.txt server.cfg +LIVE V2.15: +- Fixed a bug where players could fall silently by holding down a grenade key and not having any grenades in inventory +- Reworked damage logic, no changes in damage values, but minimal performance boost +- Included a reworked version of damage and accuracy statistics (B-4-6), counters will reset after displaying current values +- Included new log prints: + Accuracy and damage: P_A;;;;;;;;; + Bomb plants (SD & SAB): P_P;;; + Bomb defuses (SD & SAB): P_D;;; + Flag captures (DOM): P_F;;; + Headquarters captures (KOTH): P_HQC;;; + Headquarters destroys (KOTH): P_HQD;;; + LIVE V2.14: - Fixed boosting with modified g_knockback value - Game will message all players if any serverside DVars are being modified @@ -119,7 +131,7 @@ Q: What about the hardcore, and support for all gametypes, how do I use them? A: For a complete list of "promod_modes", see below. Q: I want to run my own custom Promod-server with skins etc, how? -A: In order to run your own custom Promod-server you'll need to change the fs_game to anything besides "mods/promodlive214" as well as not using match-modes. You will now be able to modify the Promod IWDs and add additional iwd-files. +A: In order to run your own custom Promod-server you'll need to change the fs_game to anything besides "mods/promodlive215" as well as not using match-modes. You will now be able to modify the Promod IWDs and add additional iwd-files. Q: Can I use this mod as a movie mod? A: Yes, you can! Commands (which are important for movie-making) are only forced on the clients once connected. Demos needs to be loaded using devmap before starting a demo ("devmap mp_crash;disconnect"). @@ -197,6 +209,7 @@ Ticker events: "SOH" "dropped_bomb" "SOH" player_name //sab, sd "SOH" "defused_by" "SOH" player_name //sab, sd "SOH" "bomb_exploded" //sab, sd +"SOH" "planted_by" "SOH" player_name // sab, sd Definitions: @@ -312,8 +325,8 @@ For example map "mp_dahman_b3" contains a file called "mp_dahman_b3.iwd" and the NOTES FOR SERVER-ADMINS AND SERVER-HOSTING COMPANIES -The dvar fs_game "mods/promodlive214" is forced for match-servers and do not rename any files or modify contents of them. -However custom servers with skins etc. must use something else than "mods/promodlive214" for example "mods/promodlive214_custom", it's not restricted and you are free to modify files as well. +The dvar fs_game "mods/promodlive215" is forced for match-servers and do not rename any files or modify contents of them. +However custom servers with skins etc. must use something else than "mods/promodlive215" for example "mods/promodlive215_custom", it's not restricted and you are free to modify files as well. Included with Promod are two PunkBuster MD5 configs, "stock_iwd_md5.cfg" and "promod_iwd_md5.cfg" which you can put in the pb-folder on your server, it contains checksums for the stock IWD-files as well as Promod-IWD for use with PunkBuster MD5 facility to prevent custom skins and other forms of cheating and abusing and can be loaded in-game by typing "\rcon pb_sv_load stock_iwd_md5.cfg" and "\rcon pb_sv_load promod_iwd_md5.cfg". diff --git a/server.cfg b/server.cfg index 56edf47..521e932 100644 --- a/server.cfg +++ b/server.cfg @@ -7,7 +7,7 @@ sets _Email "" sets _Website "" sets _Location "" sets _Irc "" -sets sv_hostname "Another Promod ^1LIVE ^7V2.14 ^7Server is Born" +sets sv_hostname "Another Promod ^1LIVE ^7V2.15 ^7Server is Born" // welcome message, message of the day (motd) seta scr_motd "Please visit us at www.codpromod.com, also visit our IRC channel #codpromod @ QuakeNet" diff --git a/server_setup.txt b/server_setup.txt index 4769692..c6d549e 100644 --- a/server_setup.txt +++ b/server_setup.txt @@ -4,7 +4,7 @@ This is a sample command-line for starting and using Promod LIVE V2 under Windows: - +set dedicated 2 +set net_ip localhost +set net_port 28960 +set sv_punkbuster 1 +set fs_game mods/promodlive214 +exec server.cfg +set rcon_password password +map_rotate + +set dedicated 2 +set net_ip localhost +set net_port 28960 +set sv_punkbuster 1 +set fs_game mods/promodlive215 +exec server.cfg +set rcon_password password +map_rotate dedicated [0-2] (listen, LAN, internet) net_ip [xxx.xxx.xxx.xxx] @@ -13,8 +13,8 @@ net_port [1-65535] (standard is 28960) Make sure you put the server config (server.cfg) in the main-folder or specify correct path to it. Please note that we also define the rcon password to the server here to prevent someone from downloading your config from server and thus view ("hack") your rcon password. -The dvar fs_game "mods/promodlive214" is forced for match-servers and do not rename any files or modify contents of them. -However custom servers with skins etc. must use something else than "mods/promodlive214" for example "mods/promodlive214_custom", it's not restricted and you are free to modify files as well. +The dvar fs_game "mods/promodlive215" is forced for match-servers and do not rename any files or modify contents of them. +However custom servers with skins etc. must use something else than "mods/promodlive215" for example "mods/promodlive215_custom", it's not restricted and you are free to modify files as well. Included with Promod is two PunkBuster MD5 configs, "stock_iwd_md5.cfg" and "promod_iwd_md5.cfg" which you can put in the pb-folder on your server, it contains checksums for the stock IWD-files as well as Promod-IWD for use with PunkBuster MD5 facility to prevent custom skins and other forms of cheating and abusing and can be loaded in-game by typing "\rcon pb_sv_load stock_iwd_md5.cfg" and "\rcon pb_sv_load promod_iwd_md5.cfg". diff --git a/ui_mp/main.menu b/ui_mp/main.menu index 730e811..f7365d1 100644 --- a/ui_mp/main.menu +++ b/ui_mp/main.menu @@ -141,7 +141,7 @@ } itemDef { - text "Current Promod Version: LIVE V2.14 EU" + text "Current Promod Version: LIVE V2.15 EU" style 0 textscale 0.25 textstyle 3 diff --git a/ui_mp/scriptmenus/quickpromod.menu b/ui_mp/scriptmenus/quickpromod.menu index 1d5b0b8..6bdebbb 100644 --- a/ui_mp/scriptmenus/quickpromod.menu +++ b/ui_mp/scriptmenus/quickpromod.menu @@ -101,6 +101,7 @@ } execKey "4" { scriptMenuResponse "killspec"; close quickpromod } + itemDef { name "window" @@ -118,6 +119,23 @@ } execKey "5" { scriptMenuResponse "4"; close quickpromod } + itemDef + { + name "window" + group ingamebox + rect 16 100 0 0 + origin ORIGIN_QUICKMESSAGEWINDOW + forecolor 1 1 1 1 + textfont UI_FONT_NORMAL + textstyle ITEM_TEXTSTYLE_SHADOWED + textscale TEXTSIZE_SMALL + textaligny 8 + text "6. Statistics" + visible 1 + decoration + } + execKey "6" { scriptMenuResponse "5"; close quickpromod } + itemDef { name "window"