dealEnergyDamageWithinDesiredRange is broken

For test results, bug reports, announcements of new builds etc.

Moderators: another_commander, winston, Getafix

User avatar
Commander McLane
---- E L I T E ----
---- E L I T E ----
Posts: 9520
Joined: Thu Dec 14, 2006 9:08 am
Location: a Hacker Outpost in a moderately remote area
Contact:

dealEnergyDamageWithinDesiredRange is broken

Post by Commander McLane »

I just found out that dealEnergyDamageWithinDesiredRange doesn't work as a scripter would intend it, and probably never has.

To be more precise: usually you would have something like this, if an entity explodes (example taken from liberator_reactorAI in liberator.oxp):

Code: Select all

{
    DETONATE = {
        ENTER = ("commsMessage: Reactor about to go critical", "pauseAI: 3.0"); 
        EXIT = (); 
        UPDATE = (
            "setDesiredRangeTo: 5000", 
            dealEnergyDamageWithinDesiredRange, 
            becomeExplosion
        ); 
    }; 
    GLOBAL = {ENTER = ("pauseAI: 5.0"); EXIT = (); UPDATE = ("setStateTo: DETONATE"); }; 
}
If the Liberator is killed, the ship's reactor is spawned, and goes critical after a few seconds. Then it explodes, and thereby damages nearby ships.

So from the player's perspective the two methods dealEnergyDamageWithinDesiredRange and becomeExplosion belong together. It's the explosion that creates the blast that damages everything around. So far for the idea.

Problem is, it doesn't work, and probably never has. Because it seems the dealEnergyDamageWithinDesiredRange needs some time to actually do damage. But the becomeExplosion is stopping the process before it has actually started. So the dealEnergyDamageWithinDesiredRange is stopped dead in track, before it has done anything. No energy damage is done.

If I take the becomeExplosion out, the energy damage is dealt correctly, it seems in a qbomb-like fashion, starting in the epicentrum and moving outwards (but without the blue sphere). In the example of the Liberator this means that everything within the desired range is dead, because it deals a huge damage.

But of course from the player's perspective, being killed without the reactor actually exploding doesn't make sense.

The bug therefore is that the dealEnergyDamageWithinDesiredRange is not being executed anymore as soon as the becomeExplosion is executed.

I guess that can be fixed, analogous to the Qbomb, which also in the moment it explodes doesn't exist anymore, but still damages its surrounding. So the code of dealEnergyDamageWithinDesiredRange should probably be corrected according to the code of becomeEnergyBlast (without the blue sphere and without automatically removing the sending entity). OR the code of dealEnergyDamageWithinDesiredRange should include an explosion of the sending entity, thereby removing the need for using an extra becomeExplosion.

EDIT: It does seem to work with missiles, however. missileAI basically uses the same dealEnergyDamageWithinDesiredRange and becomeExplosion combination. Perhaps the time in-between is sufficient to deal damage in the very small range of missiles (250 m), but not for a range of 5000 meters?
User avatar
Ramirez
---- E L I T E ----
---- E L I T E ----
Posts: 628
Joined: Mon Nov 07, 2005 9:52 am
Location: London, UK

Post by Ramirez »

I think I've got exactly the same combo of variables in the radio-controlled mine in Missiles and Bombs, and I'm pretty sure I could cause myself damage by detonating it when I was too close (I assume we're both on 1.71.2 here). I was always under the impression that dealEnergy was instantaneous and didn't have a q-bomb effect like you describe. The becomeExplosion itself is purely cosmetic and does not cause any damage on its own.

Here's the code I've got:

Code: Select all

{
	ARMED = {
	ENTER = (switchLightsOn, "commsMessage: Weapon armed - press E to detonate."); 
                EXIT = (); 
                UPDATE = (); 
                ECM = ("setStateTo: DETONATE");
                }; 

	DETONATE = {
                ENTER = ("setDesiredRangeTo: 5000.0", dealEnergyDamageWithinDesiredRange, becomeExplosion);
                UPDATE = ();
                EXIT = (); 
                };

    	GLOBAL = {
                ENTER = (switchLightsOff, "pauseAI: 3.0");
                EXIT = (); 
	UPDATE = ("setStateTo: ARMED"); 
                 };
}
It's not identical but I don't see why putting all the explosion commands in the UPDATE part instead of in another state should make any difference - maybe it does?
Download Resistance Commander plus many other exciting OXPs HERE
another_commander
Quite Grand Sub-Admiral
Quite Grand Sub-Admiral
Posts: 6547
Joined: Wed Feb 28, 2007 7:54 am

Post by another_commander »

I have not had the chance to check this yet, but I think Ramirez is right. It probably does make a difference with the commands in the update state. Update is called on every AI update, which quantifies as way too often. But really, you would want the detonation and the damage dealing to happen only once. So the update state is not the ideal place for this kind of action.
User avatar
Commander McLane
---- E L I T E ----
---- E L I T E ----
Posts: 9520
Joined: Thu Dec 14, 2006 9:08 am
Location: a Hacker Outpost in a moderately remote area
Contact:

Post by Commander McLane »

For clarification: Yes, I'm talking about 1.71.2.

Following the advice I've slightly tweaked the reactorAI, putting the dealEnergyDamageWithinDesiredRange in the ENTER-part of yet another state. So it now looks like this:

Code: Select all

{
    DETONATE = {
        ENTER = (
            "setDesiredRangeTo: 5000", 
            dealEnergyDamageWithinDesiredRange, 
            becomeExplosion
        ); 
        EXIT = (); 
        UPDATE = (); 
    }; 
    GLOBAL = {ENTER = ("pauseAI: 5.0"); EXIT = (); UPDATE = ("setStateTo: WARN"); }; 
    WARN = {
        ENTER = ("commsMessage: Reactor about to go critical", "pauseAI: 5.0"); 
        EXIT = (); 
        UPDATE = ("setStateTo: DETONATE"); 
    }; 
}
The result is still the same. No energy damage is dealt, if I'm within 5000 meters of the exploding reactor.

Please get liberator.oxp and try it out. If dealEnergyDamageWithinDesiredRange would work, you would be dead instantly, regardless of your ship. The reactor's weapon_energy is 10.000(!), that should be more than sufficient to kill anything except a station. But there is not even the slightest drop in my shields or energy.

*****

However, some more tests which I have done right now show that the bug probably is somewhere else. Even taking the becomeExplosion completely out didn't deal damage to me, so I was struggling to recreate the circumstances in which I was killed.

But now I was able to get killed again (without becomeExplosion) or come very close to being killed (only a fraction of one energy bar left with becomeExplosion). The culprit seems to be the distance to the reactor.

I have to be very close to the reactor in order to lose energy, much closer than the 5000 meters of desiredRange. Something like 250 meters, or perhaps 400 (it's a little difficult to measure the distance in the moment of the explosion, as I am already too close to see the green box).

So the question to the codemonkeys is now: Is there something in the code of dealEnergyDamageWithinDesiredRange, that lets it ignore the value of setDesiredRangeTo:? Or cuts it at a certain maximum value, which I would estimate to be no larger than about 500 meters, perhaps even less (the 250 of the missiles?).

This would explain the observed behaviour satisfactorily. And the fix would be to make sure that the value set by setDesiredRangeTo: is actually used.
User avatar
Frame
---- E L I T E ----
---- E L I T E ----
Posts: 1477
Joined: Fri Mar 30, 2007 8:32 am
Location: Witchspace

Post by Frame »

looking into this, i have a way to Determine

if desired range is "faulty" or limited

if Weapon Energy is "faulty" or limited...

I simply modify the missile in the shipdata.plist..
and run Oolite with no OXPs (no oxp this is editing of the native ships.plist and missileAI.plist)

On a side note i have a sneaky suspicion that the odd behaviour i have seen from missiles lately might have something todo with it...

That is Missiles explode right after launch, they seem to crash into the missile launching ship, as if they collide with it.. This can easely be misunderstood as if you where hitting the missiles with your lasers...

I have reported it though, since the guidance of missiles should avoid this...

But editing/testing now, will report back in a moment.

Edit: Missile with

Code: Select all

ENTER = ("setDesiredRangeTo: 10000.0", dealEnergyDamageWithinDesiredRange, becomeExplosion); 
does not seem to do you any harm at 8 clicks..

hmm i think the energy dealt is being spread out the further away from the center of the explosion you are the less of damage your craft will take..

Trying with an astronomical number.... like say 100 million, of damage

Edit 2: a 100 million of damage and none taken at all...
range was still 10000, i think was at 2000 kms

Decreasing the range to 1000. that should be 10 clicks... or 10.000 meters..

Edit 3: Seems i misintreped the range thingi, 1000 seems to be 1000 meters... i did manage to kill myself quite a few times when i was under 1000 meters from the craft where at the missile exploded...

Increasing the range to 5000

Edit 4: still i need to be less than 1000 meters to the craft in order to blow up...

1.300 meters = no damage... im starting to think the maximum value for this is about 1000.

Taking a sneak peak at the code... and see if i can get anything usefull from it...

Tadaa

Code: Select all

dealEnergyDamageWithinDesiredRange
{
	NSArray* targets = [UNIVERSE getEntitiesWithinRange:desired_range ofEntity:self];
	if ([targets count] > 0)
	{
		unsigned i;
		for (i = 0; i < [targets count]; i++)
		{
			Entity *e2 = [targets objectAtIndex:i];
			Vector p2 = e2->position;
			double ecr = e2->collision_radius;
			p2.x -= position.x;	p2.y -= position.y;	p2.z -= position.z;
			double d2 = p2.x*p2.x + p2.y*p2.y + p2.z*p2.z - ecr*ecr;
			double damage = weapon_energy*desired_range/d2;
			[e2 takeEnergyDamage:damage from:self becauseOf:[self owner]];
		}
	}
}

This looks confusing ehh, but ill take a shot on what is going on..

e2 is the target(current target in code, it runs through all ships in the area) at least so it looks like...

p2 is the targets posistion
ecr is the targets collision radius
p2.x, p2.y, p2.z is the targets posistion, which gets subtracted from the missile or "entity" or the Reactors posistion..

So if our "missile" is at posistion 0 , 0, 500 and the target is at posistion is 0.0.1000 and our targets collision_radous is 100 meters, and weapon energy is 10000 damage

we got the following

d2: 0*0+ 0*0 +500*500 - 100*100 = 240000

Damage: 10000*500/240000

Thats

Damage: 5000000 / 240000 = 20,8333333333¨ damage


and ofcourse, 20,83 damage is not exactly what we want...

lets take the following assumption then.. standard missile with 4500 damage and explode within 25 meters of the target of 100 meters collision radius, i think

Desiredrange is 250.0 like the missile..

Target 20 meters away gives us

d2: 0.0 * 0.0 + 0.0*0.0 + 20 * 20 - 100*100 = -9600

so

Damage: 4500 * 250 / -9600

Damage: 1125000 / -9600 = -117,1875


That also makes no sense,as a Negative value will be used when The damage is dealt

Energy -= Damage

Minus minus is positive, so actually the energy will be added... :S

Either im absolutely wrong, or this way of calculating the damage is very faulty... or actually supposed to work this way...

The bigger the ship, the less the damage it takes... thats makes sense.. though.. all though i cant see the Cobra MK III being killed by a single missile this way with just standard shields of which im not sure what punishment they are able to absorb..

so i´m altering my example to something i know cant survive a missile

Namely Cobra Mk I with max_energy = 150 and i guees has a collision radius of 70 meters as this is the maximum diemension value read in the model file. i dont know if it uses an average in which case the Collision radius would be about 46 meters.., im trying with 46 meters first...

Example 3.

cobra mk 1

// model size: 70.000 x 15.000 x 55.000

Standard missile...
4500 weapon_damage, distance away at detonation time: 20 meters, desired range 250, collision_radious 46 meters

d2: 0.0 + 0.0 + 20*20 - 46*46 = -1716
damage: 4500*250 / -1716 = -655,5944¨

again we get a negative value, which should in theory give energy not substract it.. But i know this aint happening since the Cobra dies..

since

Code: Select all

energy -= amount;
even if the p2.z is a negative value to start with, it will become positive since minus * minus = positive...

unless the operator "-=" does not work as i presume, that is mathmatical correct. and just subtracts the value as if it where positive..

But I really cant beleive that is the case, and not what i remember from C++ coding...

since using my example, the cobra would get 655¨energy, not loose it, but i know the cobra dies.. so, im baffled...
Last edited by Frame on Sat Jun 07, 2008 3:40 pm, edited 3 times in total.
Bounty Scanner
Number 935
User avatar
Ramirez
---- E L I T E ----
---- E L I T E ----
Posts: 628
Joined: Mon Nov 07, 2005 9:52 am
Location: London, UK

Post by Ramirez »

Just been trying to blow myself up again and it looks like the damage does indeed dissipate with range. At about 4500m I took some slight damage whereas detonating the bomb right next to me destroyed my ship. To guarantee destruction of a player's ship at 5000m you will need to put a high weapon value in as well as a larger effective range.

In the particular case of a reactor blowing up, I would have thought that doing becomeEnergyBlast would be more appropriate anyway, though I accept this doesn't actually answer your question.
Download Resistance Commander plus many other exciting OXPs HERE
User avatar
Frame
---- E L I T E ----
---- E L I T E ----
Posts: 1477
Joined: Fri Mar 30, 2007 8:32 am
Location: Witchspace

Post by Frame »

updated my example..
Bounty Scanner
Number 935
User avatar
Frame
---- E L I T E ----
---- E L I T E ----
Posts: 1477
Joined: Fri Mar 30, 2007 8:32 am
Location: Witchspace

Post by Frame »

ok found where it calculates the collision_radius

did something stupid... i downloaded the source :-S (1.71.2)

anyway here is the code snippet

Code: Select all

- (double) findCollisionRadius
{
    int i;
	double d_squared, result, length_longest_axis, length_shortest_axis;

	result = 0.0;
	if (vertexCount)
		bounding_box_reset_to_vector(&boundingBox,vertices[0]);
	else
		bounding_box_reset(&boundingBox);

    for (i = 0; i < vertexCount; i++)
    {
        d_squared = vertices[i].x*vertices[i].x + vertices[i].y*vertices[i].y + vertices[i].z*vertices[i].z;
        if (d_squared > result)
			result = d_squared;
		bounding_box_add_vector(&boundingBox,vertices[i]);
    }

	length_longest_axis = boundingBox.max.x - boundingBox.min.x;
	if (boundingBox.max.y - boundingBox.min.y > length_longest_axis)
		length_longest_axis = boundingBox.max.y - boundingBox.min.y;
	if (boundingBox.max.z - boundingBox.min.z > length_longest_axis)
		length_longest_axis = boundingBox.max.z - boundingBox.min.z;

	length_shortest_axis = boundingBox.max.x - boundingBox.min.x;
	if (boundingBox.max.y - boundingBox.min.y < length_shortest_axis)
		length_shortest_axis = boundingBox.max.y - boundingBox.min.y;
	if (boundingBox.max.z - boundingBox.min.z < length_shortest_axis)
		length_shortest_axis = boundingBox.max.z - boundingBox.min.z;

	d_squared = (length_longest_axis + length_shortest_axis) * (length_longest_axis + length_shortest_axis) * 0.25; // square of average length
	no_draw_distance = d_squared * NO_DRAW_DISTANCE_FACTOR * NO_DRAW_DISTANCE_FACTOR;	// no longer based on the collision radius

	mass =	(boundingBox.max.x - boundingBox.min.x) * (boundingBox.max.y - boundingBox.min.y) * (boundingBox.max.z - boundingBox.min.z);

	return sqrt(result);
}
as you can see is going to take me while to understand...

reportíng back when i do, if i do ;-)

Edit 1:

okay, it was easier (i think), than i thought.

This bit of what i posted before is what is relevant

Code: Select all

d_squared = vertices[i].x*vertices[i].x + vertices[i].y*vertices[i].y + vertices[i].z*vertices[i].z;
        if (d_squared > result)
			result = d_squared;
and further down

Code: Select all

return sqrt(result);
in "human" terms the the first bit of code calculates the largest squared value for all the vertixes..

and the last bit returns the Square root of these.

doing this, this way, will give you the largest value , that is where the model extends too at maximum..

So for our cobra MK 1,

The vertexes are (I calculated this and found the largest sqaured value)

27.50000, -7.50000, -27.50000

this will give is the largest sqaured value 1568,75

this value is squared so that the collision_radius is

39,607448794387148711891990130119

So lets redo the calculations for a missile that does 4500 weapon damage, and explodes at 20 meters, with the Cobra mk 1 as its target, now that we know its exact collision_radius..

d2 = 400 - 1568,16 = -1168,16

Damage = 4500*250/-1168,16 = -963,05300643747431858649500068484

and again i get a negative number... :S..


Ok, i think this is the culprit...

Damage is simply returned as Negative damage when the player is acted upon with dealenergydamagewithindesired

While it will work if you are very near the explosion within the 250 meters in this example, it will not work at further away objects... that is if you increased the DesiredRange...

I tried with 100.000.000 Weapon_Damage for standard missiles and a Desired Range of 10000, and only if i where at about 600 to 700 meters in most of my test cases did i blow up

increasing the desired_range to something astronomical will not work if the damage returned is negative.

I actually think that the players shields and/or energy bank should get a boost, when reading this code, if they have are in anyway depleted..

because of this codesnippet from the dealenergydamage function (not desired)

Code: Select all


- (void) takeEnergyDamage:(double)amount from:(Entity *)ent becauseOf:(Entity *)other
{
	Vector		rel_pos;
	double		d_forward;
	BOOL		internal_damage = NO;	// base chance

	if (status == STATUS_DEAD)  return;
	if (amount == 0.0)  return;
	
	[[ent retain] autorelease];
	[[other retain] autorelease];
	
	rel_pos = (ent != nil) ? [ent position] : kZeroVector;
	rel_pos = vector_subtract(rel_pos, position);
	
	d_forward = dot_product(rel_pos, v_forward);
	
	[self playShieldHit];

	// firing on an innocent ship is an offence
	if ((other)&&(other->isShip))
	{
		[self broadcastHitByLaserFrom:(ShipEntity*) other];
	}

	if (d_forward >= 0)
	{
		forward_shield -= amount;
		if (forward_shield < 0.0)
		{
			amount = -forward_shield;
			forward_shield = 0.0;
		}
		else
		{
			amount = 0.0;
		}
	}
	else
	{
		aft_shield -= amount;
		if (aft_shield < 0.0)
		{
			amount = -aft_shield;
			aft_shield = 0.0;
		}
		else
		{
			amount = 0.0;
		}
	}

	if (amount > 0.0)
	{
		internal_damage = ((ranrot_rand() & PLAYER_INTERNAL_DAMAGE_FACTOR) < amount);	// base chance of damage to systems
		energy -= amount;
		[self playDirectHit];
		ship_temperature += amount;
	}
	
	if (energy <= 0.0) //use normal ship temperature calculations for heat damage
	{
		if ([other isShip])
		{
			[(ShipEntity *)other noteTargetDestroyed:self];
		}
		
		[self getDestroyedBy:other context:@"energy damage"];
	}
	else
	{
		if (internal_damage)  [self takeInternalDamage];
	}
}
going to test this..

will report back, if/when i observe this...
Bounty Scanner
Number 935
User avatar
Frame
---- E L I T E ----
---- E L I T E ----
Posts: 1477
Joined: Fri Mar 30, 2007 8:32 am
Location: Witchspace

Post by Frame »

Hard to tell if the shields gets a boost, while the ships do not seem to be to happy to deplete my shields... but to finish this off

Code: Select all

double d2 = p2.x*p2.x + p2.y*p2.y + p2.z*p2.z - ecr*ecr;
is the culprit line ecr is Substracted, and if the Squared collision_radius is larger than the Sqaured distance at which the "Missile", "Reactor", it will return a negative value.

I think i know what went on here, when this was written

Somebody thougt that when i now squared the distance i also need to square the collision_radius..

thats a logical thought, but you have to make sure that the value returned is a positive value and nowhere is this taken into account, that the Damage returned from this function could be negative...

The solution ofcourse is to make the value positive again with something like this

Code: Select all

double damage = weapon_energy*desired_range/d2; 
// fix
if(damage < 0) // would be my solution for starters
damage = -damage;//would be my solution for starters
// end of fix
[e2 takeEnergyDamage:damage from:self becauseOf:[self owner]]; 
now i just hope i didnt miss anything... :S :D
Bounty Scanner
Number 935
User avatar
Eric Walch
Slightly Grand Rear Admiral
Slightly Grand Rear Admiral
Posts: 5536
Joined: Sat Jun 16, 2007 3:48 pm
Location: Netherlands

Post by Eric Walch »

is the culprit line ecr is Substracted, and if the Squared collision_radius is larger than the Sqaured distance at which the "Missile", "Reactor", it will return a negative value.
I don't think so. Distance is always larger than collision radius. You calculate with a distance less than the collision radius. But in that case there was already a collision between the objects. The subtraction of the collision radius is there to make sure you are using the distance to the surface and not to the core of the ship.
another_commander
Quite Grand Sub-Admiral
Quite Grand Sub-Admiral
Posts: 6547
Joined: Wed Feb 28, 2007 7:54 am

Post by another_commander »

I am not sure why this is being discussed for so long as a bug. It really behaves the way it was always meant to. In fact, the code in dealEnergyDamageWithinDesiredRange has been unchanged since 1.65.

First of all, the damage is meant to dissipate with distance. Desired range obviously affects this, as in, the bigger desired range is, the more damage is done for a given distance from damage source. However, the function of distance is very important here. It is an inverse square equation, meaning that doubling distance will result in four times less damage. Quadrapling distance will result in 16 times less damage and so on.

The other main factor affecting the resulting damage is the initial weapon_energy. As Frame has pointed out already, the actual equation dealing the damage is
damage = weapon_energy*desired_range/d2, where d2 is the square of distance between the outer surface of the entity taking damage and the entity causing it.

I ran some tests of my own, by booby-trapping the nav buoys. Changed their AI to

Code: Select all

{
    GLOBAL =
	{
        ATTACKED = (setTargetToPrimaryAggressor, broadcastDistressMessage, "setDesiredRangeTo: 25000.0", dealEnergyDamageWithinDesiredRange, becomeExplosion); 
        ENTER = (performIdle); 
        UPDATE = ("pauseAI: 3600"); 
    }; 
}
and experimented with various values of weapon_damage for the buoy in shipdata.plist. What the above does, is basically causing the buoy to detonate and deal some damage all around the moment any entity attacks it.

The results were as expected. I kept the desiredRange to 25000, close to scanner distance and toyed with weapon_damage. By setting it to 50000, I was getting minimal damage if I fired at the buoy immediately after coming to a full stop after launch (that is a distance of approx. 8000m). By getting closer, say 4000m, the damage was significantly higher. With a value of 50000000 for the buoy's weapon_damage, I could get it to instantly kill me by firing from 8000m.

Frame, did you remember to start with Shift after every little change you made to either AI or shipdata?

Commander McLane, even with the updated AI you posted above, you are still executing the dealEnergyDamage on every AI update, since you are calling the detonate state on every update inside the warn state. I would just put everything in the enter state and not worry about the update one at all.
User avatar
Frame
---- E L I T E ----
---- E L I T E ----
Posts: 1477
Joined: Fri Mar 30, 2007 8:32 am
Location: Witchspace

Post by Frame »

Eric Walch wrote:
is the culprit line ecr is Substracted, and if the Squared collision_radius is larger than the Sqaured distance at which the "Missile", "Reactor", it will return a negative value.
I don't think so. Distance is always larger than collision radius. You calculate with a distance less than the collision radius. But in that case there was already a collision between the objects. The subtraction of the collision radius is there to make sure you are using the distance to the surface and not to the core of the ship.
Thank you, kind a figured i must have misunderstood something :oops:

anyway with this in mind
new example

Distance to center of ship is 60
Collision radius is 39.60 (cobra mk1)
Weapon_damage is 4500
Desired range is 250(when missile detonates)

so d2 = 3600 - 1568,16 = 2031,84
Damage = 250*4500/2037,84

so Damage would be = 552,06

now it all makes sense..

Even if i increase either the weapon energy or the desired range the damage should just increase... so the player should take damage. so the error must lie somewhere else.

Well at least i know now what is going on...

Edit: another_commander yeah, i allways do that now(since i forgot, and ahruman told me how to again)

I cant reproduce your results, but i´m using a missile though with a range of 10000 and damage of 100,000,000.00

if i enter these numbers into the equation, with a range of 8000 from player to missile exploding..

8000*8000 - 39.06*39.06 = 64000000 - 1525,6836 = 63998474,3164
so
damage is 100,000,000.00*10.000/63998474,3164
or
1000000000000/63998474,3164

= 15625,37~

Just tested again with a cargo container... now i died...
tested again. this time on a hostile target, and i died again...
and target was over 5000 meters away...

Thats weird, cause i´m pretty sure i held down shift, but i admit that this looks weird, so i might have been pressing the wrong button.. or had a typo somewhere in the plists...

So Commander McLane, you should have the tools to make that reactor kill ;-)
Bounty Scanner
Number 935
User avatar
Commander McLane
---- E L I T E ----
---- E L I T E ----
Posts: 9520
Joined: Thu Dec 14, 2006 9:08 am
Location: a Hacker Outpost in a moderately remote area
Contact:

Post by Commander McLane »

another_commander wrote:
I am not sure why this is being discussed for so long as a bug. It really behaves the way it was always meant to. In fact, the code in dealEnergyDamageWithinDesiredRange has been unchanged since 1.65.

First of all, the damage is meant to dissipate with distance. Desired range obviously affects this, as in, the bigger desired range is, the more damage is done for a given distance from damage source. ... The other main factor affecting the resulting damage is the initial weapon_energy. As Frame has pointed out already, the actual equation dealing the damage is
damage = weapon_energy*desired_range/d2, where d2 is the square of distance between the outer surface of the entity taking damage and the entity causing it.
Thanks for the clarifications. As per PM, I now think that dealEnergyDamageWithinDesiredRange is not buggy as such. But it is working differently than I had expected (and I guess this is true for other scripters as well). So I would now say that the method-name dealEnergyDamageWithinDesiredRange is misleading.

Because it doesn't actually deal a damage within the desired range. What it does is to deal energy damage from the epicentre of the dealing energy, to an amount rapidly decreasing with distance from the epicentre. But the desired_range is by no means the distance up to which damage is dealt. Instead it is merely an adjustment-factor for weapon_energy.

So - if I understand correctly - it makes no difference whether you set weapon_energy 1000000 and desired_range 1, or weapon_energy 1 and desired_range 1000000. Both will affect a ship that is at 100 meters from the epicentre in exactly the same way: dealing a damage of 1 x 1000000 / 100^2 = 1000000 / 10000 = 100. Although in the first case this is way higher than the desired_range. And according to the use of setDesiredRangeTo: in all other cases of its use, nothing should be done outside the specified range. And the name dealEnergyDamageWithinDesiredRange also suggests that nothing will be done outside the desired_range, but something will be done anywhere inside the desired_range. That's why I call the method-name misleading.

EDIT: No, wrong, because of this:

Code: Select all

targets = [UNIVERSE getEntitiesWithinRange:desired_range ofEntity:self];
So indeed only entities within desired_range will be affected. But still it is misleading that you have to define a huge desired_range, in order to achieve an actual effect in only a fraction of that range.

(An example: I want an entity to deal damage on explosion. But this entity has only a weapon_energy of 15. I can't raise this value, or the lasers of the entity would become ridiculously powerful. So, in order to deal a damage that will be felt even 5000 meters away, I have to set desired_range to something like 80 million(!). 15 x 80000000 / 5000^2 = 48. Not very intuitive.)
User avatar
Svengali
Commander
Commander
Posts: 2370
Joined: Sat Oct 20, 2007 2:52 pm

Post by Svengali »

Commander McLane wrote:
But it is working differently than I had expected (and I guess this is true for other scripters as well). So I would now say that the method-name dealEnergyDamageWithinDesiredRange is misleading.
No. I'm using it for the honeypods and expected exactly that it is related to the distance - and it works very well.
Commander McLane wrote:
But still it is misleading that you have to define a huge desired_range, in order to achieve an actual effect in only a fraction of that range.
Maybe the calculation could be slightly changed to avoid these huge numbers. Just as suggestion.

@McL: Now we know how this is calculated, so no prob anymore :-)
User avatar
Frame
---- E L I T E ----
---- E L I T E ----
Posts: 1477
Joined: Fri Mar 30, 2007 8:32 am
Location: Witchspace

gree submit dammit

Post by Frame »

Well maybe an addition for 1.72

dealEqualEnergyDamageWithinDesiredRange

Thought about

dealConstantEnergyDamageWithinDesiredRange

but that would be misleading for new people., as if it where something that kept delivering Damage..

Allthough for Coders/scripters it would make perfect sense...
Bounty Scanner
Number 935
Post Reply