rendered paste bodyIndex: rts/Lua/LuaUnitDefs.cpp===================================================================--- rts/Lua/LuaUnitDefs.cpp (revision 4614)+++ rts/Lua/LuaUnitDefs.cpp (working copy)@@ -768,6 +768,15 @@ ADD_FLOAT("waterline", ud.waterline); ADD_FLOAT("maxWaterDepth", ud.maxWaterDepth); + ADD_FLOAT("flankingBonusMode", ud.flankingBonusMode);+ ADD_FLOAT("flankingBonusMax", ud.flankingBonusMax);+ ADD_FLOAT("flankingBonusMin", ud.flankingBonusMin);+ ADD_FLOAT("flankingBonusMode", ud.flankingBonusMax);+ ADD_FLOAT("flankingBonusDirX", ud.flankingBonusDir.x);+ ADD_FLOAT("flankingBonusDirY", ud.flankingBonusDir.y);+ ADD_FLOAT("flankingBonusDirZ", ud.flankingBonusDir.z);+ ADD_FLOAT("flankingBonusMobilityAdd", ud.flankingBonusMobilityAdd);+ ADD_INT("armorType", ud.armorType); ADD_FLOAT("armoredMultiple", ud.armoredMultiple); Index: rts/Sim/ModInfo.cpp===================================================================--- rts/Sim/ModInfo.cpp (revision 4614)+++ rts/Sim/ModInfo.cpp (working copy)@@ -86,6 +86,28 @@ // We already set the defaults so we should be able to ignore this // Other optional mod rules MUST set their defaults... }+ //Get the flanking bonus default option+ flankingBonusModeDefault = 1;+ try+ {+ TdfParser flankingBonusOptions("gamedata/modrules.tdf");+ flankingBonusModeDefault = atoi(flankingBonusOptions.SGetValueDef("1", "FLANKINGBONUS\\FlankingBonusModeDefault").c_str());+ } catch(content_error) // If the modrules.tdf isnt found+ {+ // We already set the defaults so we should be able to ignore this+ // Other optional mod rules MUST set their defaults...+ }+ //Get the mod's experience multiplier+ experienceMult = 1.0f;+ try+ {+ TdfParser experienceOptions("gamedata/modrules.tdf");+ experienceMult = atoi(experienceOptions.SGetValueDef("1.0", "EXPERIENCE\\ExperienceMult").c_str());+ } catch(content_error) // If the modrules.tdf isnt found+ {+ // We already set the defaults so we should be able to ignore this+ // Other optional mod rules MUST set their defaults...+ } } CModInfo::~CModInfo() {}Index: rts/Sim/ModInfo.h===================================================================--- rts/Sim/ModInfo.h (revision 4614)+++ rts/Sim/ModInfo.h (working copy)@@ -32,6 +32,9 @@ int fireAtKilled; //1 = units fire at enemies running Killed() script, 0 = units ignore such enemies int fireAtCrashing; //1 = units fire at crashing aircrafts, 0 = units ignore crashing aircrafts + int flankingBonusModeDefault; //0=no flanking bonus; 1=global coords, mobile; 2=unit coords, mobile; 3=unit coords, locked+ float experienceMult; //normally 1.0, 0.0 disables units getting automatice experience from attacks+ }; extern CModInfo *modInfo;Index: rts/Sim/Units/COB/CobInstance.cpp===================================================================--- rts/Sim/Units/COB/CobInstance.cpp (revision 4614)+++ rts/Sim/Units/COB/CobInstance.cpp (working copy)@@ -12,6 +12,7 @@ #include "Map/Ground.h" #include "Rendering/UnitModels/3DOParser.h" #include "Rendering/UnitModels/s3oParser.h"+#include "Sim/Misc/LosHandler.h" #include "Sim/Misc/RadarHandler.h" #include "Sim/MoveTypes/MoveType.h" #include "Sim/Projectiles/ExplosionGenerator.h"@@ -98,8 +99,15 @@ #define CURRENT_FUEL 93 // set or get #define TRANSPORT_ID 94 // get #define SHIELD_POWER 95 // set or get+#define PLAY_SOUND 96 // get, so multiple args can be passed+#define PLAY_SOUND_LOCATION 97 // get, so multiple args can be passed+#define ALPHA_THRESHOLD 98 // set or get #define COB_ID 100 // get-#define ALPHA_THRESHOLD 103 // set or get+#define FLANK_B_MODE 101 // set or get+#define FLANK_B_DIR 102 // set or get, set is through get for multiple args+#define FLANK_B_MOBILITY_ADD 103 // set or get+#define FLANK_B_MAX_DAMAGE 104 // set or get+#define FLANK_B_MIN_DAMAGE 105 // set or get // * NOTE: [LUA0 - LUA9] are defined in CobThread.cpp as [110 - 119] @@ -1125,6 +1133,48 @@ case ALPHA_THRESHOLD: { return int(unit->alphaThreshold * 255); }+ case PLAY_SOUND:+ switch(p3) {+ case 0:+ if (!loshandler->InAirLos(unit->pos,gu->myAllyTeam)) {return 0;}+ break;+ case 1:+ if (!(unit->losStatus[gu->myAllyTeam] & LOS_INLOS)) {return 0;}+ break;+ case 2:+ if (!(unit->losStatus[gu->myAllyTeam] & (LOS_INLOS | LOS_INRADAR))) {return 0;}+ break;+ case 3:+ break;+ case 4:+ if (unit->allyteam != gu->myAllyTeam) {return 0;}+ break;+ case 5:+ if (unit->team != gu->myTeam) {return 0;}+ break;+ case 6:+ if (unit->allyteam == gu->myAllyTeam) {return 0;}+ break;+ }+ logOutput.Print("Playing %i %i %i", p1, p2, script.sounds[p1]);+ if (p4 == 0) {+ sound->PlaySample(script.sounds[p1], unit->pos, p2);+ }else{+ sound->PlaySample(script.sounds[p1], p2);+ }+ return 0;+ case PLAY_SOUND_LOCATION: {+ float3 soundloc;+ soundloc.x = UNPACKX(p3);+ soundloc.y = UNPACKZ(p3);+ if (p3 == 0) {+ soundloc.z = ground->GetHeight(UNPACKX(p3), UNPACKZ(p3));+ }else{+ soundloc.z = float(p4)/COBSCALE;+ }+ sound->PlaySample(script.sounds[p1], soundloc, float(p2)/COBSCALE);+ return 0;+ } case COB_ID: { if (p1 == 0) { return unit->unitDef->cobID;@@ -1133,6 +1183,25 @@ return (u == NULL) ? -1 : u->unitDef->cobID; } }+ case FLANK_B_MODE:+ return unit->flankingBonusMode;+ case FLANK_B_DIR:+ switch(p1){+ case -2: unit->flankingBonusDir=float3(p2/(float)COBSCALE,p3/(float)COBSCALE,p4/(float)COBSCALE);+ case 1: return int(unit->flankingBonusDir.x * COBSCALE);+ case 2: return int(unit->flankingBonusDir.y * COBSCALE);+ case 3: return int(unit->flankingBonusDir.z * COBSCALE);+ case 11: unit->flankingBonusDir.x=(p2/(float)COBSCALE); return p2;+ case 12: unit->flankingBonusDir.y=(p2/(float)COBSCALE); return p2;+ case 13: unit->flankingBonusDir.z=(p2/(float)COBSCALE); return p2;+ default: return(-1);+ }+ case FLANK_B_MOBILITY_ADD:+ return int(unit->flankingBonusMobilityAdd * COBSCALE);+ case FLANK_B_MAX_DAMAGE:+ return int((unit->flankingBonusAvgDamage + unit->flankingBonusDifDamage) * COBSCALE);+ case FLANK_B_MIN_DAMAGE:+ return int((unit->flankingBonusAvgDamage - unit->flankingBonusDifDamage) * COBSCALE); default: logOutput.Print("CobError: Unknown get constant %d (params = %d %d %d %d)", val, p1, p2, p3, p4);@@ -1339,6 +1408,22 @@ unit->alphaThreshold = float(param) / 255.0f; break; }+ case FLANK_B_MODE:+ unit->flankingBonusMode=param;+ break;+ case FLANK_B_DIR:+ break;+ case FLANK_B_MOBILITY_ADD:+ unit->flankingBonusMobilityAdd=(param/(float)COBSCALE);+ break;+ case FLANK_B_MAX_DAMAGE:+ unit->flankingBonusAvgDamage=(param/(float)COBSCALE+(unit->flankingBonusAvgDamage - unit->flankingBonusDifDamage))*0.5f;+ unit->flankingBonusDifDamage=(param/(float)COBSCALE-(unit->flankingBonusAvgDamage - unit->flankingBonusDifDamage))*0.5f;+ break;+ case FLANK_B_MIN_DAMAGE:+ unit->flankingBonusAvgDamage=((unit->flankingBonusAvgDamage + unit->flankingBonusDifDamage)+param/(float)COBSCALE)*0.5f;+ unit->flankingBonusDifDamage=((unit->flankingBonusAvgDamage + unit->flankingBonusDifDamage)-param/(float)COBSCALE)*0.5f;+ break; default: { logOutput.Print("CobError: Unknown set constant %d", val); }Index: rts/Sim/Units/Unit.cpp===================================================================--- rts/Sim/Units/Unit.cpp (revision 4614)+++ rts/Sim/Units/Unit.cpp (working copy)@@ -37,6 +37,7 @@ #include "Sim/Misc/QuadField.h" #include "Sim/Misc/RadarHandler.h" #include "Sim/Misc/Wind.h"+#include "Sim/ModInfo.h" #include "Sim/MoveTypes/AirMoveType.h" #include "Sim/MoveTypes/MoveType.h" #include "Sim/MoveTypes/ScriptMoveType.h"@@ -124,8 +125,12 @@ userAttackPos(0,0,0), crashing(false), cob(0),- bonusShieldDir(1,0,0),- bonusShieldSaved(10),+ flankingBonusMode(0),+ flankingBonusDir(1,0,0),+ flankingBonusAvgDamage(1.4f),+ flankingBonusDifDamage(.5f),+ flankingBonusMobility(10),+ flankingBonusMobilityAdd(.01), group(0), lastDamage(-100), lastFireWeapon(0),@@ -429,7 +434,7 @@ } recentDamage*=0.9f;- bonusShieldSaved+=0.005f;+ flankingBonusMobility+=flankingBonusMobilityAdd; if(stunned) return;@@ -629,7 +634,6 @@ } } - bonusShieldSaved += 0.05f; residualImpulse *= 0.6f; if (scriptCloak >= 3) {@@ -743,22 +747,33 @@ float damage=damages[armorType]; - if(damage<0){-// logOutput.Print("Negative damage");- return;+ if(damage>0){+ if(attacker){+ SetLastAttacker(attacker);+ if (flankingBonusMode) {+ float3 adir=attacker->pos-pos;+ adir.Normalize();+ if (flankingBonusMode == 1) { //mode 1 = global coordinates, mobile+ flankingBonusDir+=adir*flankingBonusMobility;+ flankingBonusDir.Normalize();+ flankingBonusMobility=0;+ damage*=flankingBonusAvgDamage-adir.dot(flankingBonusDir)*flankingBonusDifDamage;+ }else{+ float3 adirRelative;+ adirRelative.x = adir.dot(rightdir);+ adirRelative.y = adir.dot(updir);+ adirRelative.z = adir.dot(frontdir);+ if (flankingBonusMode == 2) { //mode 2 = unit coordinates, mobile+ flankingBonusDir += adirRelative * flankingBonusMobility;+ flankingBonusDir.Normalize();+ flankingBonusMobility=0;+ } //modes 2 and 3 both use this; 3 is unit coordinates, immobile+ damage*=flankingBonusAvgDamage-adirRelative.dot(flankingBonusDir)*flankingBonusDifDamage;+ }+ }+ } } - if(attacker){- SetLastAttacker(attacker);- float3 adir=attacker->pos-pos;- adir.Normalize();- bonusShieldDir+=adir*bonusShieldSaved; //not the best way to do it(but fast)- bonusShieldDir.Normalize();-// logOutput.Print("shield mult %f %f %i %i", 2-adir.dot(bonusShieldDir),bonusShieldSaved,id,attacker->id);- bonusShieldSaved=0;- damage*=1.4f-adir.dot(bonusShieldDir)*0.5f;- }- damage*=curArmorMultiple; float3 hitDir = impulse;@@ -788,56 +803,73 @@ restTime=0; - float experienceMod=1;+ float experienceMod;+ experienceMod = modInfo->experienceMult; - if(damages.paralyzeDamageTime){- paralyzeDamage+=damage;- experienceMod=0.1f; //reduce experience for paralyzers- if(health-paralyzeDamage<0){- if(stunned)- experienceMod=0; //dont get any experience for paralyzing paralyzed enemy- stunned=true;- if(paralyzeDamage>health+(maxHealth*0.025f*damages.paralyzeDamageTime)){- paralyzeDamage=health+(maxHealth*0.025f*damages.paralyzeDamageTime);+ if(damages.paralyzeDamageTime) {+ if (damages.paralyzeDamageTime > 0) {+ if (paralyzeDamage > health) {+ if(paralyzeDamage < health + (maxHealth*0.025f*damages.paralyzeDamageTime)) {+ //make sure the weapon can do any paralysis damage before adding it; can't just do the min or a weak paralysis weapon could undo a strong one+ paralyzeDamage = min((paralyzeDamage + damage), (health + (maxHealth*0.025f*damages.paralyzeDamageTime)));+ experienceMod *= 0.0f; //no experience for extra paralysis+ }+ }else{+ paralyzeDamage+=damage;+ experienceMod *= 0.1f; //reduce experience for paralyzers+ if (paralyzeDamage < health) {+ stunned = false;+ } }+ }else{+ if (paralyzeDamage == 0) {+ experienceMod *= 0.0f; //no experience when not healing+ }else{+ paralyzeDamage = max(0.0f, paralyzeDamage + damage);+ experienceMod *= 0.1f;+ } } } else {- // Dont log overkill damage (so dguns/nukes etc dont inflate values)- float statsdamage = std::min(health, damage);- if (attacker)- gs->Team(attacker->team)->currentStats.damageDealt += statsdamage;- gs->Team(team)->currentStats.damageReceived += statsdamage;+ if (damage > 0) {+ // Dont log overkill damage (so dguns/nukes etc dont inflate values)+ float statsdamage = std::min(health, damage);+ if (attacker)+ gs->Team(attacker->team)->currentStats.damageDealt += statsdamage;+ gs->Team(team)->currentStats.damageReceived += statsdamage;+ } health-=damage; }- recentDamage+=damage; - if(attacker!=0 && !gs->Ally(allyteam,attacker->allyteam)){-// logOutput.Print("%s has %f/%f h attacker %s do %f d",tooltip.c_str(),health,maxHealth,attacker->tooltip.c_str(),damage);- attacker->experience+=0.1f*power/attacker->power*(damage+min(0.f,health))/maxHealth*experienceMod;- attacker->ExperienceChange();- ENTER_UNSYNCED;- if (((!unitDef->isCommander && uh->lastDamageWarning+100<gs->frameNum) ||- (unitDef->isCommander && uh->lastCmdDamageWarning+100<gs->frameNum))- && (team == gu->myTeam) && !camera->InView(midPos,radius+50) && !gu->spectatingFullView) {- logOutput.Print("%s is being attacked",unitDef->humanName.c_str());- logOutput.SetLastMsgPos(pos);+ if (damage > 0) {+ recentDamage+=damage;+ if(attacker!=0 && !gs->Ally(allyteam,attacker->allyteam)){+// logOutput.Print("%s has %f/%f h attacker %s do %f d",tooltip.c_str(),health,maxHealth,attacker->tooltip.c_str(),damage);+ attacker->experience+=0.1f*power/attacker->power*(damage+min(0.f,health))/maxHealth*experienceMod;+ attacker->ExperienceChange();+ ENTER_UNSYNCED;+ if (((!unitDef->isCommander && uh->lastDamageWarning+100<gs->frameNum) ||+ (unitDef->isCommander && uh->lastCmdDamageWarning+100<gs->frameNum))+ && (team == gu->myTeam) && !camera->InView(midPos,radius+50) && !gu->spectatingFullView) {+ logOutput.Print("%s is being attacked",unitDef->humanName.c_str());+ logOutput.SetLastMsgPos(pos); - if (unitDef->isCommander || uh->lastDamageWarning + 150 < gs->frameNum) {- int soundIdx = unitDef->sounds.underattack.getRandomIdx();- if (soundIdx >= 0) {- sound->PlaySample(- unitDef->sounds.underattack.getID(soundIdx),- unitDef->isCommander? 4: 2);+ if (unitDef->isCommander || uh->lastDamageWarning + 150 < gs->frameNum) {+ int soundIdx = unitDef->sounds.underattack.getRandomIdx();+ if (soundIdx >= 0) {+ sound->PlaySample(+ unitDef->sounds.underattack.getID(soundIdx),+ unitDef->isCommander? 4: 2);+ } }- } - minimap->AddNotification(pos,float3(1,0.3f,0.3f),unitDef->isCommander? 1: 0.5f); //todo: make compatible with new gui+ minimap->AddNotification(pos,float3(1,0.3f,0.3f),unitDef->isCommander? 1: 0.5f); //todo: make compatible with new gui - uh->lastDamageWarning=gs->frameNum;- if(unitDef->isCommander)- uh->lastCmdDamageWarning=gs->frameNum;+ uh->lastDamageWarning=gs->frameNum;+ if(unitDef->isCommander)+ uh->lastCmdDamageWarning=gs->frameNum;+ }+ ENTER_SYNCED; }- ENTER_SYNCED; } luaCallIns.UnitDamaged(this, attacker, damage, !!damages.paralyzeDamageTime);@@ -2275,8 +2307,12 @@ CR_MEMBER(falling), CR_MEMBER(fallSpeed), - CR_MEMBER(bonusShieldDir),- CR_MEMBER(bonusShieldSaved),+ CR_MEMBER(flankingBonusMode),+ CR_MEMBER(flankingBonusDir),+ CR_MEMBER(flankingBonusAvgDamage),+ CR_MEMBER(flankingBonusDifDamage),+ CR_MEMBER(flankingBonusMobility),+ CR_MEMBER(flankingBonusMobilityAdd), CR_MEMBER(armoredState), CR_MEMBER(armoredMultiple),Index: rts/Sim/Units/Unit.h===================================================================--- rts/Sim/Units/Unit.h (revision 4614)+++ rts/Sim/Units/Unit.h (working copy)@@ -293,8 +293,12 @@ bool falling; //for units being dropped from transports (parachute drops) float fallSpeed; - float3 bonusShieldDir; //units takes less damage when attacked from this dir (encourage flanking fire)- float bonusShieldSaved; //how much the bonus shield can turn upon an attack(zeroed when attacked, slowly increase)+ int flankingBonusMode; //0=no flanking bonus; 1=global coords, mobile; 2=unit coords, mobile; 3=unit coords, locked+ float3 flankingBonusDir; //units takes less damage when attacked from this dir (encourage flanking fire)+ float flankingBonusMobility; //how much the lowest damage direction of the flanking bonus can turn upon an attack (zeroed when attacked, slowly increases)+ float flankingBonusMobilityAdd; //how much ability of the flanking bonus direction to move builds up each frame+ float flankingBonusAvgDamage; //average factor to multiply damage by+ float flankingBonusDifDamage; //(max damage - min damage)/2 bool armoredState; float armoredMultiple;Index: rts/Sim/Units/UnitDef.h===================================================================--- rts/Sim/Units/UnitDef.h (revision 4614)+++ rts/Sim/Units/UnitDef.h (working copy)@@ -173,6 +173,12 @@ float armoredMultiple; int armorType; + int flankingBonusMode; //0=no flanking bonus; 1=global coords, mobile; 2=unit coords, mobile; 3=unit coords, locked+ float3 flankingBonusDir; //units takes less damage when attacked from this dir (encourage flanking fire)+ float flankingBonusMax; //damage factor for the least protected direction+ float flankingBonusMin; //damage factor for the most protected direction+ float flankingBonusMobilityAdd; //how much the ability of the flanking bonus direction to move builds up each frame+ UnitModelDef model; float collisionSphereScale; float3 collisionSphereOffset;Index: rts/Sim/Units/UnitDefHandler.cpp===================================================================--- rts/Sim/Units/UnitDefHandler.cpp (revision 4614)+++ rts/Sim/Units/UnitDefHandler.cpp (working copy)@@ -20,6 +20,7 @@ #include "Sim/Misc/CategoryHandler.h" #include "Sim/Misc/DamageArrayHandler.h" #include "Sim/Misc/SensorHandler.h"+#include "Sim/ModInfo.h" #include "Sim/Projectiles/ExplosionGenerator.h" #include "Sim/Weapons/WeaponDefHandler.h" #include "System/LogOutput.h"@@ -305,10 +306,18 @@ ud.captureSpeed = udTable.GetFloat("captureSpeed", ud.buildSpeed); ud.terraformSpeed = udTable.GetFloat("terraformSpeed", ud.buildSpeed); + ud.flankingBonusMode = udTable.GetFloat("flankingBonusMode", modInfo->flankingBonusModeDefault);+ ud.flankingBonusMax = udTable.GetFloat("flankingBonusMax", 1.9);+ ud.flankingBonusMin = udTable.GetFloat("flankingBonusMin", .9);+ ud.flankingBonusDir = udTable.GetFloat3("flankingBonusDir", float3(0.0f, 0.0f, 1.0f));+ ud.flankingBonusMobilityAdd = udTable.GetFloat("flankingBonusMobilityAdd", 0.01f);+ ud.armoredMultiple = udTable.GetFloat("damageModifier", 1.0f); ud.armorType=damageArrayHandler->GetTypeFromName(ud.name); // logOutput.Print("unit %s has armor %i",ud.name.c_str(),ud.armorType); ++ ud.radarRadius = udTable.GetInt("radarDistance", 0); ud.sonarRadius = udTable.GetInt("sonarDistance", 0); ud.jammerRadius = udTable.GetInt("radarDistanceJam", 0);Index: rts/Sim/Units/UnitLoader.cpp===================================================================--- rts/Sim/Units/UnitLoader.cpp (revision 4614)+++ rts/Sim/Units/UnitLoader.cpp (working copy)@@ -151,6 +151,12 @@ unit->armorType=ud->armorType; unit->floatOnWater = ud->floater || (ud->movedata && ((ud->movedata->moveType == MoveData::Hover_Move) || (ud->movedata->moveType == MoveData::Ship_Move))); unit->maxSpeed = ud->speed/30.0;+ unit->flankingBonusMode = ud->flankingBonusMode;+ unit->flankingBonusDir = ud->flankingBonusDir;+ unit->flankingBonusMobility = ud->flankingBonusMobilityAdd * 1000;+ unit->flankingBonusMobilityAdd = ud->flankingBonusMobilityAdd;+ unit->flankingBonusAvgDamage = (ud->flankingBonusMax + ud->flankingBonusMin) * 0.5f;+ unit->flankingBonusDifDamage = (ud->flankingBonusMax - ud->flankingBonusMin) * 0.5f; if(ud->highTrajectoryType==1) unit->useHighTrajectory=true;