Index: data/mods/public/gui/credits/texts/programming.json
===================================================================
--- data/mods/public/gui/credits/texts/programming.json (revision 18484)
+++ data/mods/public/gui/credits/texts/programming.json (working copy)
@@ -108,6 +108,7 @@
{"nick": "kingadami", "name": "Adam Winsor"},
{"nick": "kingbasil", "name": "Giannis Fafalios"},
{"nick": "lafferjm", "name": "Justin Lafferty"},
+ {"nick": "LeanderH", "name": "Leander Hemelhof"},
{"nick": "leper", "name": "Georg Kilzer"},
{"nick": "LittleDev"},
{"nick": "livingaftermidnight", "name": "Will Dull"},
Index: data/mods/public/simulation/components/Attack.js
===================================================================
--- data/mods/public/simulation/components/Attack.js (revision 18484)
+++ data/mods/public/simulation/components/Attack.js (working copy)
@@ -487,6 +487,7 @@
*/
Attack.prototype.PerformAttack = function(type, target)
{
+ let cmpDamage = Engine.QueryInterface(SYSTEM_ENTITY, IID_Damage);
// If this is a ranged attack, then launch a projectile
if (type == "Ranged")
{
@@ -556,14 +557,27 @@
let playerId = Engine.QueryInterface(this.entity, IID_Ownership).GetOwner();
cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
- cmpTimer.SetTimeout(this.entity, IID_Attack, "MissileHit", timeToTarget * 1000, {
- "type": type,
- "target": target,
- "position": realTargetPosition,
- "direction": missileDirection,
- "projectileId": id,
- "playerId":playerId
- });
+ let data = {
+ "type": type,
+ "attacker": this.entity,
+ "target": target,
+ "strengths": this.GetAttackStrengths(type),
+ "position": realTargetPosition,
+ "direction": missileDirection,
+ "projectileId": id,
+ "playerId": playerId,
+ "multiplier": this.GetAttackBonus(type, target),
+ "isSplash": false
+ }
+ if (this.template.Ranged.Splash)
+ {
+ data.friendlyFire = this.template.Ranged.Splash.FriendlyFire;
+ data.range = this.template.Ranged.Splash.Range;
+ data.shape = this.template.Ranged.Splash.Shape;
+ data.isSplash = true;
+ }
+ cmpDamage.entityOwners.set(this.entity, Engine.QueryInterface(this.entity, IID_Ownership).GetOwner());
+ cmpTimer.SetTimeout(SYSTEM_ENTITY, IID_Damage, "MissileHit", timeToTarget * 1000, data);
}
else if (type == "Capture")
{
@@ -594,7 +608,7 @@
else
{
// Melee attack - hurt the target immediately
- Damage.CauseDamage({
+ cmpDamage.CauseDamage({
"strengths": this.GetAttackStrengths(type),
"target": target,
"attacker": this.entity,
@@ -605,121 +619,6 @@
// TODO: charge attacks (need to design how they work)
};
-Attack.prototype.InterpolatedLocation = function(ent, lateness)
-{
- let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
- let turnLength = cmpTimer.GetLatestTurnLength()/1000;
- let cmpTargetPosition = Engine.QueryInterface(ent, IID_Position);
- if (!cmpTargetPosition || !cmpTargetPosition.IsInWorld()) // TODO: handle dead target properly
- return undefined;
- let curPos = cmpTargetPosition.GetPosition();
- let prevPos = cmpTargetPosition.GetPreviousPosition();
- lateness /= 1000;
- return new Vector3D((curPos.x * (turnLength - lateness) + prevPos.x * lateness) / turnLength,
- 0,
- (curPos.z * (turnLength - lateness) + prevPos.z * lateness) / turnLength);
-};
-
-// Tests whether it point is inside of ent's footprint
-Attack.prototype.testCollision = function(ent, point, lateness)
-{
- let targetPosition = this.InterpolatedLocation(ent, lateness);
- if (!targetPosition)
- return false;
- let cmpFootprint = Engine.QueryInterface(ent, IID_Footprint);
- if (!cmpFootprint)
- return false;
- let targetShape = cmpFootprint.GetShape();
-
- if (!targetShape || !targetPosition)
- return false;
-
- if (targetShape.type === 'circle')
- {
- // Use VectorDistanceSquared and square targetShape.radius to avoid square roots.
- return (targetPosition.horizDistanceTo(point) < (targetShape.radius * targetShape.radius));
- }
- else
- {
- let angle = Engine.QueryInterface(ent, IID_Position).GetRotation().y;
-
- let d = Vector3D.sub(point, targetPosition);
- d = Vector2D.from3D(d).rotate(-angle);
-
- return d.x < Math.abs(targetShape.width/2) && d.y < Math.abs(targetShape.depth/2);
- }
-};
-
-Attack.prototype.MissileHit = function(data, lateness)
-{
- let targetPosition = this.InterpolatedLocation(data.target, lateness);
- if (!targetPosition)
- return;
-
- // Do this first in case the direct hit kills the target
- if (this.template.Ranged.Splash)
- {
- let friendlyFire = this.template.Ranged.Splash.FriendlyFire;
- let splashRadius = this.template.Ranged.Splash.Range;
- let splashShape = this.template.Ranged.Splash.Shape;
- let playersToDamage;
-
- if (friendlyFire == "false")
- {
- let cmpPlayer = QueryPlayerIDInterface(data.playerId);
- playersToDamage = cmpPlayer.GetEnemies();
- }
-
- Damage.CauseSplashDamage({
- "attacker": this.entity,
- "origin": Vector2D.from3D(data.position),
- "radius": splashRadius,
- "shape": splashShape,
- "strengths": this.GetAttackStrengths(data.type),
- "direction": data.direction,
- "playersToDamage": playersToDamage,
- "type": data.type
- });
- }
-
- if (this.testCollision(data.target, data.position, lateness))
- {
- data.attacker = this.entity;
- data.multiplier = this.GetAttackBonus(data.type, data.target);
- data.strengths = this.GetAttackStrengths(data.type);
- // Hit the primary target
- Damage.CauseDamage(data);
-
- // Remove the projectile
- let cmpProjectileManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_ProjectileManager);
- cmpProjectileManager.RemoveProjectile(data.projectileId);
- }
- else
- {
- // If we didn't hit the main target look for nearby units
- let cmpPlayer = QueryPlayerIDInterface(data.playerId);
- let ents = Damage.EntitiesNearPoint(Vector2D.from3D(data.position), targetPosition.horizDistanceTo(data.position) * 2, cmpPlayer.GetEnemies());
-
- for (let i = 0; i < ents.length; ++i)
- {
- if (!this.testCollision(ents[i], data.position, lateness))
- continue;
-
- Damage.CauseDamage({
- "strengths": this.GetAttackStrengths(data.type),
- "target": ents[i],
- "attacker": this.entity,
- "multiplier": this.GetAttackBonus(data.type, ents[i]),
- "type": data.type
- });
-
- // Remove the projectile
- let cmpProjectileManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_ProjectileManager);
- cmpProjectileManager.RemoveProjectile(data.projectileId);
- }
- }
-};
-
Attack.prototype.OnValueModification = function(msg)
{
if (msg.component != "Attack")
Index: data/mods/public/simulation/components/AttackDetection.js
===================================================================
--- data/mods/public/simulation/components/AttackDetection.js (revision 18484)
+++ data/mods/public/simulation/components/AttackDetection.js (working copy)
@@ -63,8 +63,13 @@
if (cmpTargetOwnership.GetOwner() != cmpPlayer.GetPlayerID())
return;
var cmpAttackerOwnership = Engine.QueryInterface(attacker, IID_Ownership);
+ let attackerOwner;
+ if (cmpAttackerOwnership)
+ attackerOwner = cmpAttackerOwnership.GetOwner();
+ else // The attacker is dead, so we use the data stored in the Damage component
+ attackerOwner = Engine.QueryInterface(SYSTEM_ENTITY, IID_Damage).GetDeadEntityOwner(attacker);
// Don't register attacks dealt by myself
- if (cmpAttackerOwnership.GetOwner() == cmpPlayer.GetPlayerID())
+ if (attackerOwner == cmpPlayer.GetPlayerID())
return;
// Since livestock can be attacked/gathered by other players
@@ -122,7 +127,7 @@
"type": "attack",
"target": target,
"players": [cmpPlayer.GetPlayerID()],
- "attacker": cmpAttackerOwnership.GetOwner(),
+ "attacker": attackerOwner,
"targetIsDomesticAnimal": targetIsDomesticAnimal
});
PlaySound("attacked", target);
Index: data/mods/public/simulation/components/Damage.js
===================================================================
--- data/mods/public/simulation/components/Damage.js (nonexistent)
+++ data/mods/public/simulation/components/Damage.js (working copy)
@@ -0,0 +1,277 @@
+function Damage() {}
+
+Damage.prototype.Schema =
+ "";
+
+Damage.prototype.Init = function()
+{
+};
+
+Damage.prototype.entityOwners = new Map();
+
+Damage.prototype.InterpolatedLocation = function(ent, lateness)
+{
+ let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
+ let turnLength = cmpTimer.GetLatestTurnLength()/1000;
+ let cmpTargetPosition = Engine.QueryInterface(ent, IID_Position);
+ if (!cmpTargetPosition || !cmpTargetPosition.IsInWorld()) // TODO: handle dead target properly
+ return undefined;
+ let curPos = cmpTargetPosition.GetPosition();
+ let prevPos = cmpTargetPosition.GetPreviousPosition();
+ lateness /= 1000;
+ return new Vector3D((curPos.x * (turnLength - lateness) + prevPos.x * lateness) / turnLength,
+ 0,
+ (curPos.z * (turnLength - lateness) + prevPos.z * lateness) / turnLength);
+};
+/**
+ * Test if a point is inside of an entities footprint
+ * ent =
+ * point =
+ * lateness =
+ */
+Damage.prototype.TestCollision = function(ent, point, lateness)
+{
+ let targetPosition = this.InterpolatedLocation(ent, lateness);
+ if (!targetPosition)
+ return false;
+ let cmpFootprint = Engine.QueryInterface(ent, IID_Footprint);
+ if (!cmpFootprint)
+ return false;
+ let targetShape = cmpFootprint.GetShape();
+
+ if (!targetShape || !targetPosition)
+ return false;
+
+ if (targetShape.type === 'circle')
+ {
+ // Use VectorDistanceSquared and square targetShape.radius to avoid square roots.
+ return (targetPosition.horizDistanceTo(point) < (targetShape.radius * targetShape.radius));
+ }
+ else
+ {
+ let angle = Engine.QueryInterface(ent, IID_Position).GetRotation().y;
+
+ let d = Vector3D.sub(point, targetPosition);
+ d = Vector2D.from3D(d).rotate(-angle);
+
+ return d.x < Math.abs(targetShape.width/2) && d.y < Math.abs(targetShape.depth/2);
+ }
+};
+
+Damage.prototype.MissileHit = function(data, lateness)
+{
+ let targetPosition = this.InterpolatedLocation(data.target, lateness);
+ if (!targetPosition)
+ return;
+
+ // Do this first in case the direct hit kills the target
+ if (data.isSplash)
+ {
+ let playersToDamage;
+
+ if (!data.friendlyFire)
+ {
+ let cmpPlayer = QueryPlayerIDInterface(data.playerId);
+ playersToDamage = cmpPlayer.GetEnemies();
+ }
+
+ this.CauseSplashDamage({
+ "attacker": data.attacker,
+ "origin": Vector2D.from3D(data.position),
+ "radius": data.radius,
+ "shape": data.shape,
+ "strengths": data.strengths,
+ "direction": data.direction,
+ "playersToDamage": playersToDamage,
+ "type": data.type
+ });
+ }
+
+ if (this.TestCollision(data.target, data.position, lateness))
+ {
+ // Hit the primary target
+ this.CauseDamage(data);
+
+ // Remove the projectile
+ let cmpProjectileManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_ProjectileManager);
+ cmpProjectileManager.RemoveProjectile(data.projectileId);
+ }
+ else
+ {
+ // If we didn't hit the main target look for nearby units
+ let cmpPlayer = QueryPlayerIDInterface(data.playerId);
+ let ents = this.EntitiesNearPoint(Vector2D.from3D(data.position), targetPosition.horizDistanceTo(data.position) * 2, cmpPlayer.GetEnemies());
+
+ for (let i = 0; i < ents.length; ++i)
+ {
+ if (!this.TestCollision(ents[i], data.position, lateness))
+ continue;
+
+ this.CauseDamage({
+ "strengths": data.strengths,
+ "target": ents[i],
+ "attacker": data.attacker,
+ "multiplier": data.multiplier,
+ "type": data.type
+ });
+
+ // Remove the projectile
+ let cmpProjectileManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_ProjectileManager);
+ cmpProjectileManager.RemoveProjectile(data.projectileId);
+ }
+ }
+ let cmpHealth = Engine.QueryInterface(data.attacker, IID_Health);
+ if (cmpHealth && cmpHealth.GetHitpoints() != 0) // Remove killer data if it's still alive.
+ {
+ this.entityOwners.delete(data.attacker);
+ }
+};
+
+/**
+ * Damages units around a given origin.
+ * data.attacker =
+ * data.origin =
+ * data.radius =
+ * data.shape =
+ * data.strengths = {'hack':, 'pierce':, 'crush':}
+ * data.type =
+ * ***Optional Variables***
+ * data.direction =
+ * data.playersToDamage =
+ */
+Damage.prototype.CauseSplashDamage = function(data)
+{
+ // Get nearby entities and define variables
+ var nearEnts = this.EntitiesNearPoint(data.origin, data.radius, data.playersToDamage);
+ var damageMultiplier = 1;
+ // Cycle through all the nearby entities and damage it appropriately based on its distance from the origin.
+ for each (var entity in nearEnts)
+ {
+ var entityPosition = Engine.QueryInterface(entity, IID_Position).GetPosition2D();
+ if(data.shape == 'Circular') // circular effect with quadratic falloff in every direction
+ {
+ var squaredDistanceFromOrigin = data.origin.distanceToSquared(entityPosition);
+ damageMultiplier = 1 - squaredDistanceFromOrigin / (data.radius * data.radius);
+ }
+ else if(data.shape == 'Linear') // linear effect with quadratic falloff in two directions (only used for certain missiles)
+ {
+ // Get position of entity relative to splash origin.
+ var relativePos = entityPosition.sub(data.origin);
+
+ // The width of linear splash is one fifth of the normal splash radius.
+ var width = data.radius/5;
+
+ // Effectivly rotate the axis to align with the missile direction.
+ var parallelDist = relativePos.dot(data.direction); // z axis
+ var perpDist = Math.abs(relativePos.cross(data.direction)); // y axis
+
+ // Check that the unit is within the distance at which it will get damaged.
+ if (parallelDist > -width && perpDist < width) // If in radius, quadratic falloff in both directions
+ damageMultiplier = (data.radius * data.radius - parallelDist * parallelDist) / (data.radius * data.radius)
+ * (width * width - perpDist * perpDist) / (width * width);
+ else
+ damageMultiplier = 0;
+ }
+ else // In case someone calls this function with an invalid shape.
+ {
+ warn("The " + data.shape + " splash damage shape is not implemented!");
+ }
+ // Call CauseDamage which reduces the hitpoints, posts network command, plays sounds....
+ this.CauseDamage({"strengths":data.strengths, "target":entity, "attacker":data.attacker, "multiplier":damageMultiplier, "type":data.type + ".Splash"});
+ }
+};
+
+/**
+ * Causes damage on a given unit
+ * data.strengths = {'hack':, 'pierce':, 'crush':}
+ * data.target =
+ * data.attacker =
+ * data.multiplier =
+ * data.type =
+ */
+Damage.prototype.CauseDamage = function(data)
+{
+ // Check the target can be damaged otherwise don't do anything.
+ var cmpDamageReceiver = Engine.QueryInterface(data.target, IID_DamageReceiver);
+ var cmpHealth = Engine.QueryInterface(data.target, IID_Health);
+ if (!cmpDamageReceiver || !cmpHealth)
+ return;
+
+ // Damage the target
+ var targetState = cmpDamageReceiver.TakeDamage(data.strengths.hack * data.multiplier, data.strengths.pierce * data.multiplier, data.strengths.crush * data.multiplier);
+
+ var cmpPromotion = Engine.QueryInterface(data.attacker, IID_Promotion);
+ var cmpLoot = Engine.QueryInterface(data.target, IID_Loot);
+ if (cmpPromotion && cmpLoot && cmpLoot.GetXp() > 0)
+ cmpPromotion.IncreaseXp(cmpLoot.GetXp() * -targetState.change / cmpHealth.GetMaxHitpoints());
+
+ // If the target was killed run some cleanup
+ if (targetState.killed)
+ this.TargetKilled(data.attacker, data.target);
+
+ // Post the network command (make it work in multiplayer)
+ Engine.PostMessage(data.target, MT_Attacked, {"attacker":data.attacker, "target":data.target, "type":data.type, "damage":-targetState.change});
+
+ // Play attacking sounds
+ PlaySound("attack_impact", data.attacker);
+};
+
+/**
+ * Gets entities near a give point for given players.
+ * origin =
+ * radius =
+ * players =
+ * If players is not included, entities from all players are used.
+ */
+Damage.prototype.EntitiesNearPoint = function(origin, radius, players)
+{
+ // If there is insufficient data return an empty array.
+ if (!origin || !radius)
+ return [];
+
+ // If the players parameter is not specified use all players.
+ if (!players)
+ {
+ var playerEntities = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager).GetAllPlayerEntities();
+ players = [];
+ for each (var entity in playerEntities)
+ players.push(Engine.QueryInterface(entity, IID_Player).GetPlayerID());
+ }
+
+ // Call RangeManager with dummy entity and return the result.
+ var rangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
+ var rangeQuery = rangeManager.ExecuteQueryAroundPos(origin, 0, radius, players, IID_DamageReceiver);
+ return rangeQuery;
+};
+
+/**
+ * Called when some units kills something (another unit, building, animal etc)
+ * killerEntity =
+ * targetEntity =
+ */
+Damage.prototype.TargetKilled = function(killerEntity, targetEntity)
+{
+ // Add to killer statistics.
+ var cmpKillerPlayerStatisticsTracker = QueryOwnerInterface(killerEntity, IID_StatisticsTracker);
+ if (cmpKillerPlayerStatisticsTracker)
+ cmpKillerPlayerStatisticsTracker.KilledEntity(targetEntity);
+ // Add to loser statistics.
+ var cmpTargetPlayerStatisticsTracker = QueryOwnerInterface(targetEntity, IID_StatisticsTracker);
+ if (cmpTargetPlayerStatisticsTracker)
+ cmpTargetPlayerStatisticsTracker.LostEntity(targetEntity);
+
+ // If killer can collect loot, let's try to collect it.
+ var cmpLooter = Engine.QueryInterface(killerEntity, IID_Looter);
+ if (cmpLooter)
+ cmpLooter.Collect(targetEntity);
+};
+
+
+Damage.prototype.GetDeadEntityOwner = function(entityId)
+{
+ var cmpOwner = this.entityOwners.get(entityId);
+ this.entityOwners.delete(entityId);
+ return cmpOwner;
+};
+
+Engine.RegisterSystemComponentType(IID_Damage, "Damage", Damage);
Property changes on: data/mods/public/simulation/components/Damage.js
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Index: data/mods/public/simulation/components/interfaces/Damage.js
===================================================================
--- data/mods/public/simulation/components/interfaces/Damage.js (nonexistent)
+++ data/mods/public/simulation/components/interfaces/Damage.js (working copy)
@@ -0,0 +1 @@
+Engine.RegisterInterface("Damage");
Property changes on: data/mods/public/simulation/components/interfaces/Damage.js
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Index: data/mods/public/simulation/helpers/Damage.js
===================================================================
--- data/mods/public/simulation/helpers/Damage.js (revision 18484)
+++ data/mods/public/simulation/helpers/Damage.js (nonexistent)
@@ -1,144 +0,0 @@
-// Create global Damage object.
-var Damage = {};
-
-/**
- * Damages units around a given origin.
- * data.attacker =
- * data.origin =
- * data.radius =
- * data.shape =
- * data.strengths = {'hack':, 'pierce':, 'crush':}
- * data.type =
- * ***Optional Variables***
- * data.direction =
- * data.playersToDamage =
- */
-Damage.CauseSplashDamage = function(data)
-{
- // Get nearby entities and define variables
- var nearEnts = Damage.EntitiesNearPoint(data.origin, data.radius, data.playersToDamage);
- var damageMultiplier = 1;
- // Cycle through all the nearby entities and damage it appropriately based on its distance from the origin.
- for each (var entity in nearEnts)
- {
- var entityPosition = Engine.QueryInterface(entity, IID_Position).GetPosition2D();
- if(data.shape == 'Circular') // circular effect with quadratic falloff in every direction
- {
- var squaredDistanceFromOrigin = data.origin.distanceToSquared(entityPosition);
- damageMultiplier = 1 - squaredDistanceFromOrigin / (data.radius * data.radius);
- }
- else if(data.shape == 'Linear') // linear effect with quadratic falloff in two directions (only used for certain missiles)
- {
- // Get position of entity relative to splash origin.
- var relativePos = entityPosition.sub(data.origin);
-
- // The width of linear splash is one fifth of the normal splash radius.
- var width = data.radius/5;
-
- // Effectivly rotate the axis to align with the missile direction.
- var parallelDist = relativePos.dot(data.direction); // z axis
- var perpDist = Math.abs(relativePos.cross(data.direction)); // y axis
-
- // Check that the unit is within the distance at which it will get damaged.
- if (parallelDist > -width && perpDist < width) // If in radius, quadratic falloff in both directions
- damageMultiplier = (data.radius * data.radius - parallelDist * parallelDist) / (data.radius * data.radius)
- * (width * width - perpDist * perpDist) / (width * width);
- else
- damageMultiplier = 0;
- }
- else // In case someone calls this function with an invalid shape.
- {
- warn("The " + data.shape + " splash damage shape is not implemented!");
- }
- // Call CauseDamage which reduces the hitpoints, posts network command, plays sounds....
- Damage.CauseDamage({"strengths":data.strengths, "target":entity, "attacker":data.attacker, "multiplier":damageMultiplier, "type":data.type + ".Splash"});
- }
-};
-
-/**
- * Causes damage on a given unit
- * data.strengths = {'hack':, 'pierce':, 'crush':}
- * data.target =
- * data.attacker =
- * data.multiplier =
- * data.type =
- */
-Damage.CauseDamage = function(data)
-{
- // Check the target can be damaged otherwise don't do anything.
- var cmpDamageReceiver = Engine.QueryInterface(data.target, IID_DamageReceiver);
- var cmpHealth = Engine.QueryInterface(data.target, IID_Health);
- if (!cmpDamageReceiver || !cmpHealth)
- return;
-
- // Damage the target
- var targetState = cmpDamageReceiver.TakeDamage(data.strengths.hack * data.multiplier, data.strengths.pierce * data.multiplier, data.strengths.crush * data.multiplier);
-
- var cmpPromotion = Engine.QueryInterface(data.attacker, IID_Promotion);
- var cmpLoot = Engine.QueryInterface(data.target, IID_Loot);
- if (cmpPromotion && cmpLoot && cmpLoot.GetXp() > 0)
- cmpPromotion.IncreaseXp(cmpLoot.GetXp() * -targetState.change / cmpHealth.GetMaxHitpoints());
-
- // If the target was killed run some cleanup
- if (targetState.killed)
- Damage.TargetKilled(data.attacker, data.target);
-
- // Post the network command (make it work in multiplayer)
- Engine.PostMessage(data.target, MT_Attacked, {"attacker":data.attacker, "target":data.target, "type":data.type, "damage":-targetState.change});
-
- // Play attacking sounds
- PlaySound("attack_impact", data.attacker);
-};
-
-/**
- * Gets entities near a give point for given players.
- * origin =
- * radius =
- * players =
- * If players is not included, entities from all players are used.
- */
-Damage.EntitiesNearPoint = function(origin, radius, players)
-{
- // If there is insufficient data return an empty array.
- if (!origin || !radius)
- return [];
-
- // If the players parameter is not specified use all players.
- if (!players)
- {
- var playerEntities = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager).GetAllPlayerEntities();
- players = [];
- for each (var entity in playerEntities)
- players.push(Engine.QueryInterface(entity, IID_Player).GetPlayerID());
- }
-
- // Call RangeManager with dummy entity and return the result.
- var rangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
- var rangeQuery = rangeManager.ExecuteQueryAroundPos(origin, 0, radius, players, IID_DamageReceiver);
- return rangeQuery;
-};
-
-/**
- * Called when some units kills something (another unit, building, animal etc)
- * killerEntity =
- * targetEntity =
- */
-Damage.TargetKilled = function(killerEntity, targetEntity)
-{
- // Add to killer statistics.
- var cmpKillerPlayerStatisticsTracker = QueryOwnerInterface(killerEntity, IID_StatisticsTracker);
- if (cmpKillerPlayerStatisticsTracker)
- cmpKillerPlayerStatisticsTracker.KilledEntity(targetEntity);
- // Add to loser statistics.
- var cmpTargetPlayerStatisticsTracker = QueryOwnerInterface(targetEntity, IID_StatisticsTracker);
- if (cmpTargetPlayerStatisticsTracker)
- cmpTargetPlayerStatisticsTracker.LostEntity(targetEntity);
-
- // If killer can collect loot, let's try to collect it.
- var cmpLooter = Engine.QueryInterface(killerEntity, IID_Looter);
- if (cmpLooter)
- cmpLooter.Collect(targetEntity);
-};
-
-Engine.RegisterGlobal("Damage", Damage);
-
Property changes on: data/mods/public/simulation/helpers/Damage.js
___________________________________________________________________
Deleted: svn:eol-style
## -1 +0,0 ##
-native
\ No newline at end of property