2025-07-21 13:15 CEST

View Issue Details Jump to Notes ]
IDProjectCategoryView StatusLast Update
0000565Spring engineGeneralpublic2007-08-09 00:15
Reporterimbaczek 
Assigned Toimbaczek 
PrioritynormalSeveritymajorReproducibilityalways
StatusresolvedResolutionfixed 
Product Version 
Target VersionFixed in Version 
Summary0000565: [patch] cannons shoot closer the higher they get built, not the other way around
Descriptionthe topic says it all. to test, build a guardian on a hill and in the valley of small divide and see which one is able to shoot farther.
Additional Informationalso included is heightMod, which was present in 74b3, but disappeared in revision 3741.
TagsNo tags attached.
Checked infolog.txt for Errors
Attached Files
  • patch file icon fix_cannon_range.patch (1,497 bytes) 2007-07-21 00:00 -
    Index: rts/Sim/Weapons/Cannon.cpp
    ===================================================================
    --- rts/Sim/Weapons/Cannon.cpp	(revision 4053)
    +++ rts/Sim/Weapons/Cannon.cpp	(working copy)
    @@ -238,6 +238,7 @@
     float CCannon::GetRange2D(float yDiff) const
     {
     	float root1 = 1 + 2*gs->gravity*yDiff/(projectileSpeed*projectileSpeed);
    +	logOutput << "root1 " << root1 << "dH " << yDiff << "\n";
     	if(root1 < 0){
     		return 0;
     	} else {
    Index: rts/Sim/Weapons/Weapon.cpp
    ===================================================================
    --- rts/Sim/Weapons/Weapon.cpp	(revision 4053)
    +++ rts/Sim/Weapons/Weapon.cpp	(working copy)
    @@ -550,7 +550,7 @@
     		return false;
     
     	float3 dif=pos-weaponPos;
    -	float heightDiff;
    +	float heightDiff; // negative when target below owner
     
     	if (targetBorder != 0 && unit) {
     		float3 diff(dif);
    @@ -564,16 +564,16 @@
     			//logOutput << "outside\n";
     		}
     		//geometricObjects->AddLine(weaponMuzzlePos, weaponMuzzlePos+dif, 3, 0, 16);
    -		heightDiff = owner->pos.y - (weaponPos.y + dif.y);
    +		heightDiff = (weaponPos.y + dif.y) - owner->pos.y;
     	} else {
    -		heightDiff = owner->pos.y - pos.y;
    +		heightDiff = pos.y - owner->pos.y;
     	}
     
     	float r;
     	if (!unit || cylinderTargetting < 0.01) {
    -		r=GetRange2D(heightDiff);
    +		r=GetRange2D(heightDiff*heightMod);
     	} else {
    -		if (cylinderTargetting * unit->radius > heightDiff) {
    +		if (cylinderTargetting * unit->radius > fabs(heightDiff)*heightMod) {
     			r = GetRange2D(0);
     		} else {
     			r = 0;
    
    patch file icon fix_cannon_range.patch (1,497 bytes) 2007-07-21 00:00 +
  • patch file icon fix_cannon_range_v2.patch (2,084 bytes) 2007-07-21 11:21 -
    Index: rts/Sim/Weapons/Weapon.cpp
    ===================================================================
    --- rts/Sim/Weapons/Weapon.cpp	(revision 4053)
    +++ rts/Sim/Weapons/Weapon.cpp	(working copy)
    @@ -25,6 +25,7 @@
     #include "Sim/MoveTypes/TAAirMoveType.h"
     #include "creg/STL_List.h"
     #include "mmgr.h"
    +#include "float3.h"
     
     CR_BIND_DERIVED(CWeapon, CObject, (NULL));
     
    @@ -550,7 +551,7 @@
     		return false;
     
     	float3 dif=pos-weaponPos;
    -	float heightDiff;
    +	float heightDiff; // negative when target below owner
     
     	if (targetBorder != 0 && unit) {
     		float3 diff(dif);
    @@ -564,16 +565,16 @@
     			//logOutput << "outside\n";
     		}
     		//geometricObjects->AddLine(weaponMuzzlePos, weaponMuzzlePos+dif, 3, 0, 16);
    -		heightDiff = owner->pos.y - (weaponPos.y + dif.y);
    +		heightDiff = (weaponPos.y + dif.y) - owner->pos.y;
     	} else {
    -		heightDiff = owner->pos.y - pos.y;
    +		heightDiff = pos.y - owner->pos.y;
     	}
     
     	float r;
     	if (!unit || cylinderTargetting < 0.01) {
    -		r=GetRange2D(heightDiff);
    +		r=GetRange2D(heightDiff*heightMod);
     	} else {
    -		if (cylinderTargetting * unit->radius > heightDiff) {
    +		if (cylinderTargetting * unit->radius > fabs(heightDiff)*heightMod) {
     			r = GetRange2D(0);
     		} else {
     			r = 0;
    Index: rts/Sim/Weapons/WeaponDefHandler.cpp
    ===================================================================
    --- rts/Sim/Weapons/WeaponDefHandler.cpp	(revision 4053)
    +++ rts/Sim/Weapons/WeaponDefHandler.cpp	(working copy)
    @@ -325,9 +325,14 @@
     	sunparser->GetDef(weaponDefs[id].visuals.pulseSpeed, "1", weaponname + "\\pulseSpeed");
     	sunparser->GetDef(weaponDefs[id].largeBeamLaser, "0", weaponname + "\\largeBeamLaser");
     
    -	weaponDefs[id].heightmod = 0.2f;
    -	if(weaponDefs[id].type == "Cannon")
    -		weaponDefs[id].heightmod = 0.8f;
    +	std::string hmod = sunparser->SGetValueDef("", weaponname+"\\heightmod");
    +	if (hmod == "") {
    +		weaponDefs[id].heightmod = 0.2f;
    +		if(weaponDefs[id].type == "Cannon")
    +			weaponDefs[id].heightmod = 0.8f;
    +	} else {
    +		weaponDefs[id].heightmod = atof(hmod.c_str());
    +	}
     
     	weaponDefs[id].supplycost = 0.0f;
     
    
    patch file icon fix_cannon_range_v2.patch (2,084 bytes) 2007-07-21 11:21 +
  • patch file icon more_fixes_to_weapons.patch (1,550 bytes) 2007-07-25 19:14 -
    Index: rts/Rendering/GL/glExtra.cpp
    ===================================================================
    --- rts/Rendering/GL/glExtra.cpp	(revision 4092)
    +++ rts/Rendering/GL/glExtra.cpp	(working copy)
    @@ -55,7 +55,7 @@
     		pos.y = ground->GetHeight(pos.x, pos.z);
     		float heightDiff = (pos.y - center.y)/2;
     		rad -= heightDiff * slope;
    -		float adjRadius = weapon ? weapon->GetRange2D(heightDiff) : rad;
    +		float adjRadius = weapon ? weapon->GetRange2D(heightDiff*weapon->heightMod) : rad;
     		float adjustment = rad/2;
     		float ydiff = 0;
     		int j;
    @@ -72,7 +72,7 @@
     			ydiff = fabs(pos.y - newY);
     			pos.y = newY;
     			heightDiff = (pos.y - center.y);
    -			adjRadius = weapon ? weapon->GetRange2D(heightDiff) : rad;
    +			adjRadius = weapon ? weapon->GetRange2D(heightDiff*weapon->heightMod) : rad;
     		}
     		pos.x = center.x + (sinR * adjRadius);
     		pos.z = center.z + (cosR * adjRadius);
    Index: rts/Sim/Weapons/WeaponDefHandler.cpp
    ===================================================================
    --- rts/Sim/Weapons/WeaponDefHandler.cpp	(revision 4092)
    +++ rts/Sim/Weapons/WeaponDefHandler.cpp	(working copy)
    @@ -327,9 +327,12 @@
     
     	std::string hmod = sunparser->SGetValueDef("", weaponname+"\\heightmod");
     	if (hmod == "") {
    -		weaponDefs[id].heightmod = 0.2f;
     		if(weaponDefs[id].type == "Cannon")
     			weaponDefs[id].heightmod = 0.8f;
    +		else if (weaponDefs[id].type == "BeamLaser")
    +			weaponDefs[id].heightmod = 1.0f;
    +		else
    +			weaponDefs[id].heightmod = 0.2f;
     	} else {
     		weaponDefs[id].heightmod = atof(hmod.c_str());
     	}
    
    patch file icon more_fixes_to_weapons.patch (1,550 bytes) 2007-07-25 19:14 +
  • patch file icon more_cannon_range_tweaks.patch (6,037 bytes) 2007-08-06 19:17 -
    Index: rts/Lua/LuaWeaponDefs.cpp
    ===================================================================
    --- rts/Lua/LuaWeaponDefs.cpp	(revision 4143)
    +++ rts/Lua/LuaWeaponDefs.cpp	(working copy)
    @@ -549,6 +549,7 @@
     	ADD_FLOAT("targetBorder", wd.targetBorder);
     	ADD_FLOAT("cylinderTargetting", wd.cylinderTargetting);
     	ADD_FLOAT("minIntensity", wd.minIntensity);
    +	ADD_FLOAT("heightBoostFactor", wd.heightBoostFactor);
     
     //	CExplosionGenerator *explosionGenerator;
     
    Index: rts/Sim/Units/UnitLoader.cpp
    ===================================================================
    --- rts/Sim/Units/UnitLoader.cpp	(revision 4143)
    +++ rts/Sim/Units/UnitLoader.cpp	(working copy)
    @@ -466,6 +466,7 @@
     	weapon->targetBorder = weapondef->targetBorder;
     	weapon->cylinderTargetting = weapondef->cylinderTargetting;
     	weapon->minIntensity = weapondef->minIntensity;
    +	weapon->heightBoostFactor = weapondef->heightBoostFactor;
     	weapon->collisionFlags = weapondef->collisionFlags;
     	weapon->Init();
     
    Index: rts/Sim/Weapons/Cannon.cpp
    ===================================================================
    --- rts/Sim/Weapons/Cannon.cpp	(revision 4143)
    +++ rts/Sim/Weapons/Cannon.cpp	(working copy)
    @@ -26,6 +26,7 @@
     	CR_MEMBER(minPredict),
     	CR_MEMBER(highTrajectory),
     	CR_MEMBER(selfExplode),
    +	CR_MEMBER(rangeFactor),
     	CR_RESERVED(16)
     	));
     
    @@ -37,6 +38,7 @@
     : CWeapon(owner)
     {
     	highTrajectory=false;
    +	rangeFactor = 1;
     }
     
     void CCannon::Init(void)
    @@ -48,6 +50,18 @@
     		maxPredict=projectileSpeed*1.41f/-gs->gravity;
     	}
     	CWeapon::Init();
    +
    +	// initialize range factor
    +	rangeFactor = 1;
    +	rangeFactor = (float)range/GetRange2D(0);
    +	// do not extend range if the modder specified speed too low
    +	// for the projectile to reach specified range
    +	if (rangeFactor > 1.f)
    +		rangeFactor = 1.f;
    +	// some magical (but working) equations
    +	// TODO find something better?
    +	if (heightBoostFactor < 0.f)
    +		heightBoostFactor = (2.f - rangeFactor)/sqrt(rangeFactor);
     }
     
     CCannon::~CCannon()
    @@ -237,10 +251,18 @@
     
     float CCannon::GetRange2D(float yDiff) const
     {
    -	float root1 = 1 + 2*gs->gravity*yDiff/(projectileSpeed*projectileSpeed);
    +	const float factor = 0.7071067f; // sin pi/4 == cos pi/4
    +	const float speed2d = projectileSpeed*factor; // speed in one direction in max-range case
    +	const float speed2dSq = speed2d*speed2d;
    +
    +	if (yDiff < 0)
    +		// smooth a bit but keep working with short range units
    +		yDiff *= heightBoostFactor * min(1.f, -yDiff/min(200.f, range*0.5f));
    +
    +	float root1 = speed2dSq + 2*gs->gravity*yDiff;
     	if(root1 < 0){
     		return 0;
     	} else {
    -		return range * sqrt(root1);
    +		return rangeFactor*(speed2dSq + speed2d*sqrt(root1))/(-gs->gravity);
     	}
     }
    Index: rts/Sim/Weapons/Cannon.h
    ===================================================================
    --- rts/Sim/Weapons/Cannon.h	(revision 4143)
    +++ rts/Sim/Weapons/Cannon.h	(working copy)
    @@ -7,9 +7,12 @@
     
     #include "Weapon.h"
     
    -class CCannon : public CWeapon  
    +class CCannon : public CWeapon
     {
     	CR_DECLARE(CCannon);
    +protected:
    +	float rangeFactor;	/// this is used to keep range true to range tag
    +
     public:
     	CCannon(CUnit* owner);
     	virtual ~CCannon();
    Index: rts/Sim/Weapons/Weapon.cpp
    ===================================================================
    --- rts/Sim/Weapons/Weapon.cpp	(revision 4143)
    +++ rts/Sim/Weapons/Weapon.cpp	(working copy)
    @@ -87,6 +87,7 @@
     	CR_MEMBER(targetBorder),
     	CR_MEMBER(cylinderTargetting),
     	CR_MEMBER(minIntensity),
    +	CR_MEMBER(heightBoostFactor),
     	CR_MEMBER(collisionFlags),
     	CR_MEMBER(fuelUsage),
     	CR_MEMBER(weaponNum),
    @@ -159,6 +160,7 @@
     	targetBorder(0.f),
     	cylinderTargetting(0.f),
     	minIntensity(0.f),
    +	heightBoostFactor(-1.f),
     	collisionFlags(0),
     	fuelUsage(0)
     {
    Index: rts/Sim/Weapons/Weapon.h
    ===================================================================
    --- rts/Sim/Weapons/Weapon.h	(revision 4143)
    +++ rts/Sim/Weapons/Weapon.h	(working copy)
    @@ -129,6 +129,7 @@
     	float targetBorder;  // if nonzero, targetting units will TryTarget at the edge of collision sphere (radius*tag value, [-1;1]) instead of its centre
     	float cylinderTargetting;	//if greater than 0, range will be checked in a cylinder (height=unitradius*cylinderTargetting) instead of a sphere
     	float minIntensity;	// for beamlasers - always hit with some minimum intensity (a damage coeffcient normally dependent on distance). do not confuse with intensity tag, it's completely unrelated.
    +	float heightBoostFactor;	//controls cannon range height boost. default: -1 -- automatically calculate a more or less sane value
     
     	unsigned int collisionFlags;
     
    Index: rts/Sim/Weapons/WeaponDefHandler.cpp
    ===================================================================
    --- rts/Sim/Weapons/WeaponDefHandler.cpp	(revision 4143)
    +++ rts/Sim/Weapons/WeaponDefHandler.cpp	(working copy)
    @@ -383,6 +383,8 @@
     		weaponDefs[id].visuals.colorMap = CColorMap::LoadFromDefString(colormap);
     	}
     
    +	sunparser->GetDef(weaponDefs[id].heightBoostFactor, "-1", weaponname + "\\HeightBoostFactor");
    +
     	//get some weapon specific defaults
     	if(weaponDefs[id].type=="Cannon"){
     		//CExplosiveProjectile
    Index: rts/Sim/Weapons/WeaponDefHandler.h
    ===================================================================
    --- rts/Sim/Weapons/WeaponDefHandler.h	(revision 4143)
    +++ rts/Sim/Weapons/WeaponDefHandler.h	(working copy)
    @@ -178,6 +178,7 @@
     	float targetBorder;		//if nonzero, targetting units will TryTarget at the edge of collision sphere (radius*tag value, [-1;1]) instead of its centre
     	float cylinderTargetting;	//if greater than 0, range will be checked in a cylinder (height=unitradius*cylinderTargetting) instead of a sphere
     	float minIntensity;		// for beamlasers - always hit with some minimum intensity (a damage coeffcient normally dependent on distance). do not confuse with intensity tag, it's completely unrelated.
    +	float heightBoostFactor;	//controls cannon range height boost. default: -1 -- automatically calculate a more or less sane value
     
     	unsigned int collisionFlags;
     
    
    patch file icon more_cannon_range_tweaks.patch (6,037 bytes) 2007-08-06 19:17 +

-Relationships
has duplicate 0000563resolvedimbaczek Weapons cannot have height-based range boost in 75b1 
has duplicate 0000537resolvedimbaczek Range of projectile weapons not affected by height 
+Relationships

-Notes

~0001026

imbaczek (reporter)

oops don't commit the cannon.cpp part, it's just logging.

~0001027

imbaczek (reporter)

a better version:

- fixed cannons not able to shoot as far from high ground as they should
- fixed infinite lower cylinder when cylindertargetting is active
- reintroduced heightMod to TryTarget
- added heightMod tag (height difference is multiplied by this value before checking range), default 0.8 for Cannon weapon type, 0.2 for everything else (i.e. stays as it was)

~0001032

imbaczek (reporter)

some more fixes:
- beamlasers have heightmod=1 by default (used to be 0.2) so they use pure spherical targeting now
- fixes in glBallisticCircle (use heightmod also in drawing range circles.)

~0001039

Auswaschbar (reporter)

Commited to trunk.

Big Thanks

~0001049

imbaczek (reporter)

more_cannon_range_tweaks.patch:
- added heightBoostFactor - a float tag that gives control of cannon height range boost (more than 1 means increased range, 0 means the cannon has fixed range regardless of height difference to target. default is a magic value calculated on weapon init, based on range tag and theoretical max range.)
- changed Cannon::GetRange2D so it uses something closer to real-world physics.

~0001055

imbaczek (reporter)

commited additional tweaks (my first, wee) with some more changes to trunk, r4164.
+Notes

-Issue History
Date Modified Username Field Change
2007-07-21 00:00 imbaczek New Issue
2007-07-21 00:00 imbaczek File Added: fix_cannon_range.patch
2007-07-21 01:22 imbaczek Note Added: 0001026
2007-07-21 11:21 imbaczek File Added: fix_cannon_range_v2.patch
2007-07-21 11:21 imbaczek Note Added: 0001027
2007-07-25 19:14 imbaczek File Added: more_fixes_to_weapons.patch
2007-07-25 19:16 imbaczek Note Added: 0001032
2007-08-02 14:50 Auswaschbar Note Added: 0001039
2007-08-06 19:17 imbaczek File Added: more_cannon_range_tweaks.patch
2007-08-06 19:23 imbaczek Note Added: 0001049
2007-08-09 00:08 imbaczek Status new => assigned
2007-08-09 00:08 imbaczek Assigned To => imbaczek
2007-08-09 00:14 imbaczek Note Added: 0001055
2007-08-09 00:15 imbaczek Status assigned => resolved
2007-08-09 00:15 imbaczek Resolution open => fixed
2007-08-09 00:16 imbaczek Relationship added has duplicate 0000563
2007-08-09 00:17 imbaczek Relationship added has duplicate 0000537
+Issue History