diff --git a/engine/src/main/java/org/destinationsol/game/FactionManager.java b/engine/src/main/java/org/destinationsol/game/FactionManager.java index 053aef310..3345fccf2 100644 --- a/engine/src/main/java/org/destinationsol/game/FactionManager.java +++ b/engine/src/main/java/org/destinationsol/game/FactionManager.java @@ -69,13 +69,13 @@ public FactionManager(FactionsConfigs factionsConfigs) { * @param event the event that occurred. * @param the type of event. */ - public & ReputationEvent> void reportEvent(Faction instigator, Faction target, T event) { + public void reportEvent(Faction instigator, Faction target, T event) { // TODO: Add support for custom event handlers. // Some examples: // - A pacifist faction is offended by any attacks made by a faction, regardless of the target. // - A merchant faction may randomly give a free bonus when buying items. // - A protective faction may dispatch a fleet to intercept the attacker if one of their ships is attacked. - Integer targetReputationImpact = target.getReputationImpact(event); + Float targetReputationImpact = target.getReputationImpact(event); if (targetReputationImpact != null) { target.setRelation(instigator, target.getRelation(instigator) + targetReputationImpact); } else { diff --git a/engine/src/main/java/org/destinationsol/game/Rubble.java b/engine/src/main/java/org/destinationsol/game/Rubble.java index 741ca163f..f4187d417 100644 --- a/engine/src/main/java/org/destinationsol/game/Rubble.java +++ b/engine/src/main/java/org/destinationsol/game/Rubble.java @@ -101,7 +101,7 @@ public void onRemove(SolGame game) { } @Override - public void receiveDmg(float dmg, SolGame game, Vector2 position, DmgType dmgType) { + public void receiveDmg(float dmg, SolGame game, Vector2 position, DmgType dmgType, SolObject instigator) { } @Override diff --git a/engine/src/main/java/org/destinationsol/game/SolObject.java b/engine/src/main/java/org/destinationsol/game/SolObject.java index 40d7a64e5..e8242af8f 100644 --- a/engine/src/main/java/org/destinationsol/game/SolObject.java +++ b/engine/src/main/java/org/destinationsol/game/SolObject.java @@ -80,12 +80,13 @@ public interface SolObject { * no health pool or should be otherwise indestructible, or invincible against some types of damage, this method can * be freely left blank. * - * @param dmg Damage the object receives. - * @param game Game this object belongs to. - * @param position Position the object was hit at, if hit by point-based damage. Null if not applicable, such as fire. - * @param dmgType Type of the damage object receives. + * @param dmg Damage the object receives. + * @param game Game this object belongs to. + * @param position Position the object was hit at, if hit by point-based damage. Null if not applicable, such as fire. + * @param dmgType Type of the damage object receives. + * @param instigator Object that damaged this object. */ - void receiveDmg(float dmg, SolGame game, @Nullable Vector2 position, DmgType dmgType); + void receiveDmg(float dmg, SolGame game, @Nullable Vector2 position, DmgType dmgType, @Nullable SolObject instigator); /** * Denotes whether this object is affected by gravity. diff --git a/engine/src/main/java/org/destinationsol/game/SolObjectEntityWrapper.java b/engine/src/main/java/org/destinationsol/game/SolObjectEntityWrapper.java index 3da60fd4f..55dbd2224 100644 --- a/engine/src/main/java/org/destinationsol/game/SolObjectEntityWrapper.java +++ b/engine/src/main/java/org/destinationsol/game/SolObjectEntityWrapper.java @@ -62,7 +62,7 @@ public void onRemove(SolGame game) { } @Override - public void receiveDmg(float dmg, SolGame game, Vector2 position, DmgType dmgType) { + public void receiveDmg(float dmg, SolGame game, Vector2 position, DmgType dmgType, SolObject instigator) { } diff --git a/engine/src/main/java/org/destinationsol/game/StarPort.java b/engine/src/main/java/org/destinationsol/game/StarPort.java index 021c05412..63308362d 100644 --- a/engine/src/main/java/org/destinationsol/game/StarPort.java +++ b/engine/src/main/java/org/destinationsol/game/StarPort.java @@ -156,8 +156,9 @@ public void onRemove(SolGame game) { } @Override - public void receiveDmg(float dmg, SolGame game, Vector2 position, DmgType dmgType) { + public void receiveDmg(float dmg, SolGame game, Vector2 position, DmgType dmgType, SolObject instigator) { game.getContext().get(SpecialSounds.class).playHit(game, this, position, dmgType); + // TODO: Reduce reputation with the origin planet's owning faction when planet ownership is implemented. } @Override @@ -436,7 +437,7 @@ public void onRemove(SolGame game) { } @Override - public void receiveDmg(float dmg, SolGame game, Vector2 position, DmgType dmgType) { + public void receiveDmg(float dmg, SolGame game, Vector2 position, DmgType dmgType, SolObject instigator) { game.getContext().get(SpecialSounds.class).playHit(game, this, position, dmgType); } diff --git a/engine/src/main/java/org/destinationsol/game/asteroid/Asteroid.java b/engine/src/main/java/org/destinationsol/game/asteroid/Asteroid.java index 28abd7736..817838591 100644 --- a/engine/src/main/java/org/destinationsol/game/asteroid/Asteroid.java +++ b/engine/src/main/java/org/destinationsol/game/asteroid/Asteroid.java @@ -112,7 +112,7 @@ public void handleContact(SolObject other, float absImpulse, SolGame game, Vecto } else { dmg = absImpulse / mass / DUR; } - receiveDmg(dmg, game, collPos, DmgType.CRASH); + receiveDmg(dmg, game, collPos, DmgType.CRASH, null); } @Override @@ -149,7 +149,7 @@ private boolean updateInAtm(SolGame game) { } float dmg = body.getLinearVelocity().len() * SPD_TO_ATM_DMG * game.getTimeStep(); - receiveDmg(dmg, game, null, DmgType.FIRE); + receiveDmg(dmg, game, null, DmgType.FIRE, null); return true; } @@ -215,7 +215,7 @@ private void throwLoot(SolGame game, SolItem item) { } @Override - public void receiveDmg(float dmg, SolGame game, Vector2 position, DmgType dmgType) { + public void receiveDmg(float dmg, SolGame game, Vector2 position, DmgType dmgType, SolObject instigator) { life -= dmg; game.getContext().get(SpecialSounds.class).playHit(game, this, position, dmgType); } diff --git a/engine/src/main/java/org/destinationsol/game/console/commands/DieCommandHandler.java b/engine/src/main/java/org/destinationsol/game/console/commands/DieCommandHandler.java index 231ec3ece..30b7d3300 100644 --- a/engine/src/main/java/org/destinationsol/game/console/commands/DieCommandHandler.java +++ b/engine/src/main/java/org/destinationsol/game/console/commands/DieCommandHandler.java @@ -38,7 +38,7 @@ public String die(@Game SolGame game) throws CommandExecutionException { if (!hero.isAlive()) { throw new CommandExecutionException("Hero is already dead!"); } - hero.getShip().receivePiercingDmg(hero.getHull().getHullConfig().getMaxLife() + 1f, game, hero.getPosition(), DmgType.CRASH); + hero.getShip().receivePiercingDmg(hero.getHull().getHullConfig().getMaxLife() + 1f, game, hero.getPosition(), DmgType.CRASH, null); return "Hero killed!"; } } diff --git a/engine/src/main/java/org/destinationsol/game/drawables/DrawableObject.java b/engine/src/main/java/org/destinationsol/game/drawables/DrawableObject.java index aaf486d4c..431ad1e5d 100644 --- a/engine/src/main/java/org/destinationsol/game/drawables/DrawableObject.java +++ b/engine/src/main/java/org/destinationsol/game/drawables/DrawableObject.java @@ -116,7 +116,7 @@ public void onRemove(SolGame game) { } @Override - public void receiveDmg(float dmg, SolGame game, Vector2 position, DmgType dmgType) { + public void receiveDmg(float dmg, SolGame game, Vector2 position, DmgType dmgType, SolObject instigator) { } @Override diff --git a/engine/src/main/java/org/destinationsol/game/faction/DamageInflictedReputationEvent.java b/engine/src/main/java/org/destinationsol/game/faction/DamageInflictedReputationEvent.java new file mode 100644 index 000000000..707a07690 --- /dev/null +++ b/engine/src/main/java/org/destinationsol/game/faction/DamageInflictedReputationEvent.java @@ -0,0 +1,47 @@ +/* + * Copyright 2026 The Terasology Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.destinationsol.game.faction; + +/** + * A reputation-affecting event raised when a ship (or projectile fired by a ship) causes damage to another. + */ +public class DamageInflictedReputationEvent implements ReputationEvent { + // This constant is calculated based on backwards compatibility with the old "1 hit = -1 reputation" logic, + // assuming a normal bullet clip that deals 1.6 units of damage (same as the Heavy Machine Gun at the time). + public static final float DAMAGE_REPUTATION_MODIFIER = 1.0f / 1.6f; + private final float damageTaken; + + public DamageInflictedReputationEvent(float damageTaken) { + this.damageTaken = damageTaken; + } + + /** + * Returns the quantity of damage caused by the instigator. + * @return the quantity of damage caused by the instigator. + */ + public float getDamageTaken() { + return damageTaken; + } + + /** + * {@inheritDoc} + */ + @Override + public float getDefaultReputationImpact() { + return -(damageTaken * DAMAGE_REPUTATION_MODIFIER); + } +} diff --git a/engine/src/main/java/org/destinationsol/game/faction/DefaultReputationEvent.java b/engine/src/main/java/org/destinationsol/game/faction/DefaultReputationEvent.java index 6cdade7e3..909531586 100644 --- a/engine/src/main/java/org/destinationsol/game/faction/DefaultReputationEvent.java +++ b/engine/src/main/java/org/destinationsol/game/faction/DefaultReputationEvent.java @@ -48,7 +48,7 @@ public enum DefaultReputationEvent implements ReputationEvent { * @return the default impact on reputation this event will have in absence of a faction-specific value. */ @Override - public int getDefaultReputationImpact() { + public float getDefaultReputationImpact() { return defaultReputationImpact; } } diff --git a/engine/src/main/java/org/destinationsol/game/faction/Faction.java b/engine/src/main/java/org/destinationsol/game/faction/Faction.java index b321be654..dd71abdc1 100644 --- a/engine/src/main/java/org/destinationsol/game/faction/Faction.java +++ b/engine/src/main/java/org/destinationsol/game/faction/Faction.java @@ -61,17 +61,17 @@ public class Faction { /** * The default standing that this faction has towards unknown factions. */ - private final int defaultDisposition; + private final float defaultDisposition; /** * The relations held between this faction and other factions. */ - private final Map relations; + private final Map relations; /** * The impact that certain events will have on relations with another faction if they instigate a given event. * (For example, hitting the ship with a projectile loses reputation, having a negative impact.) * @see DefaultReputationEvent */ - private final Map reputationImpacts; + private final Map reputationImpacts; /** * Instantiates a new faction instance. @@ -84,7 +84,7 @@ public class Faction { * @param reputationImpacts the impact certain events should have on relationships between this faction and others. */ public Faction(ResourceUrn id, String name, String description, Color colour, int defaultDisposition, - List shipDesigns, Map reputationImpacts) { + List shipDesigns, Map reputationImpacts) { this.id = id; this.name = name; this.description = description; @@ -141,7 +141,7 @@ public List getShipDesigns() { * @return the change in reputation, if known, otherwise null. * @param the type of event. */ - public & ReputationEvent> Integer getReputationImpact(T event) { + public Float getReputationImpact(T event) { return reputationImpacts.get(event.toString()); } @@ -159,7 +159,7 @@ public boolean isAwareOf(Faction faction) { * @param faction the faction to check. * @return the reputation value held with this faction. */ - public int getRelation(Faction faction) { + public float getRelation(Faction faction) { if (faction == this) { return MAX_REPUTATION; } @@ -171,7 +171,7 @@ public int getRelation(Faction faction) { * @param faction the faction to assign reputation with. * @param disposition the overall disposition of this faction towards the other. */ - public void setRelation(Faction faction, int disposition) { + public void setRelation(Faction faction, float disposition) { if (faction != this) { relations.put(faction, Math.clamp(MIN_REPUTATION, MAX_REPUTATION, disposition)); } diff --git a/engine/src/main/java/org/destinationsol/game/faction/FactionConfig.java b/engine/src/main/java/org/destinationsol/game/faction/FactionConfig.java index 9b2c48b75..21be68af4 100644 --- a/engine/src/main/java/org/destinationsol/game/faction/FactionConfig.java +++ b/engine/src/main/java/org/destinationsol/game/faction/FactionConfig.java @@ -37,7 +37,7 @@ public static Faction load(ResourceUrn id, JSONObject jsonObject) { for (int designNo = 0; designNo < shipDesignsArray.length(); designNo++) { shipDesigns.add(new ResourceUrn(shipDesignsArray.getString(designNo))); } - Map reputationImpacts = new HashMap<>(); + Map reputationImpacts = new HashMap<>(); return new Faction(id, jsonObject.getString("name"), jsonObject.getString("description"), new org.terasology.nui.Color(gdxColour.r, gdxColour.g, gdxColour.b, gdxColour.a), diff --git a/engine/src/main/java/org/destinationsol/game/faction/FactionsConfigs.java b/engine/src/main/java/org/destinationsol/game/faction/FactionsConfigs.java index 0921bc7a0..a2e9c0c2a 100644 --- a/engine/src/main/java/org/destinationsol/game/faction/FactionsConfigs.java +++ b/engine/src/main/java/org/destinationsol/game/faction/FactionsConfigs.java @@ -75,15 +75,15 @@ public FactionsConfigs(AssetHelper assetHelper) { } else if (!faction.isAwareOf(otherFaction) && otherFaction.isAwareOf(faction)) { faction.setRelation(otherFaction, otherFaction.getRelation(faction)); } else { - int factionRelation = faction.getRelation(otherFaction); - int otherFactionRelation = otherFaction.getRelation(faction); + float factionRelation = faction.getRelation(otherFaction); + float otherFactionRelation = otherFaction.getRelation(faction); // The simplified rules of uncertain Destination Sol diplomacy: // - If both are friendly, the stronger positivity will prevail. // - If both are hostile, the stronger hostility will prevail. // - If your enemy is hostile to you, you must be hostile to your enemy. // - Neutrality is considered friendly. - int relation = (factionRelation >= 0 && otherFactionRelation >= 0) ? + float relation = (factionRelation >= 0 && otherFactionRelation >= 0) ? Math.max(factionRelation, otherFactionRelation) : Math.min(factionRelation, otherFactionRelation); faction.setRelation(otherFaction, relation); diff --git a/engine/src/main/java/org/destinationsol/game/faction/ReputationEvent.java b/engine/src/main/java/org/destinationsol/game/faction/ReputationEvent.java index 248694d2f..6e7acbd31 100644 --- a/engine/src/main/java/org/destinationsol/game/faction/ReputationEvent.java +++ b/engine/src/main/java/org/destinationsol/game/faction/ReputationEvent.java @@ -30,5 +30,5 @@ public interface ReputationEvent { * Returns the default impact on reputation this event will have in absence of a faction-specific value. * @return the default impact on reputation this event will have in absence of a faction-specific value. */ - int getDefaultReputationImpact(); + float getDefaultReputationImpact(); } diff --git a/engine/src/main/java/org/destinationsol/game/item/Loot.java b/engine/src/main/java/org/destinationsol/game/item/Loot.java index ee1cc7d3d..3c12c4ec6 100644 --- a/engine/src/main/java/org/destinationsol/game/item/Loot.java +++ b/engine/src/main/java/org/destinationsol/game/item/Loot.java @@ -117,7 +117,7 @@ public void onRemove(SolGame game) { } @Override - public void receiveDmg(float dmg, SolGame game, Vector2 position, DmgType dmgType) { + public void receiveDmg(float dmg, SolGame game, Vector2 position, DmgType dmgType, SolObject instigator) { life -= dmg; game.getContext().get(SpecialSounds.class).playHit(game, this, position, dmgType); } @@ -164,7 +164,7 @@ public Vector2 getVelocity() { public void handleContact(SolObject other, float absImpulse, SolGame game, Vector2 collPos) { float dmg = absImpulse / mass / DURABILITY; - receiveDmg((int) dmg, game, collPos, DmgType.CRASH); + receiveDmg((int) dmg, game, collPos, DmgType.CRASH, null); } @Override diff --git a/engine/src/main/java/org/destinationsol/game/maze/MazeTileObject.java b/engine/src/main/java/org/destinationsol/game/maze/MazeTileObject.java index 8dd5d2675..3e022637c 100644 --- a/engine/src/main/java/org/destinationsol/game/maze/MazeTileObject.java +++ b/engine/src/main/java/org/destinationsol/game/maze/MazeTileObject.java @@ -72,7 +72,7 @@ public void onRemove(SolGame game) { } @Override - public void receiveDmg(float dmg, SolGame game, Vector2 position, DmgType dmgType) { + public void receiveDmg(float dmg, SolGame game, Vector2 position, DmgType dmgType, SolObject instigator) { game.getContext().get(SpecialSounds.class).playHit(game, this, position, dmgType); } diff --git a/engine/src/main/java/org/destinationsol/game/particle/LightObject.java b/engine/src/main/java/org/destinationsol/game/particle/LightObject.java index 92f5db65d..d4e769ead 100644 --- a/engine/src/main/java/org/destinationsol/game/particle/LightObject.java +++ b/engine/src/main/java/org/destinationsol/game/particle/LightObject.java @@ -57,7 +57,7 @@ public void onRemove(SolGame game) { } @Override - public void receiveDmg(float dmg, SolGame game, Vector2 position, DmgType dmgType) { + public void receiveDmg(float dmg, SolGame game, Vector2 position, DmgType dmgType, SolObject instigator) { } @Override diff --git a/engine/src/main/java/org/destinationsol/game/planet/PlanetSprites.java b/engine/src/main/java/org/destinationsol/game/planet/PlanetSprites.java index a3758006c..fa4b7767e 100644 --- a/engine/src/main/java/org/destinationsol/game/planet/PlanetSprites.java +++ b/engine/src/main/java/org/destinationsol/game/planet/PlanetSprites.java @@ -69,7 +69,7 @@ public void onRemove(SolGame game) { } @Override - public void receiveDmg(float dmg, SolGame game, Vector2 position, DmgType dmgType) { + public void receiveDmg(float dmg, SolGame game, Vector2 position, DmgType dmgType, SolObject instigator) { } @Override diff --git a/engine/src/main/java/org/destinationsol/game/planet/Sky.java b/engine/src/main/java/org/destinationsol/game/planet/Sky.java index 7cee3f908..192c7e14a 100644 --- a/engine/src/main/java/org/destinationsol/game/planet/Sky.java +++ b/engine/src/main/java/org/destinationsol/game/planet/Sky.java @@ -17,7 +17,6 @@ import com.badlogic.gdx.math.Vector2; import org.destinationsol.Const; -import org.destinationsol.assets.Assets; import org.destinationsol.common.SolColor; import org.destinationsol.common.SolMath; import org.destinationsol.game.ColorSpan; @@ -122,7 +121,7 @@ public void onRemove(SolGame game) { } @Override - public void receiveDmg(float dmg, SolGame game, Vector2 position, DmgType dmgType) { + public void receiveDmg(float dmg, SolGame game, Vector2 position, DmgType dmgType, SolObject instigator) { } @Override diff --git a/engine/src/main/java/org/destinationsol/game/planet/SunSingleton.java b/engine/src/main/java/org/destinationsol/game/planet/SunSingleton.java index 784edd962..d567a8778 100644 --- a/engine/src/main/java/org/destinationsol/game/planet/SunSingleton.java +++ b/engine/src/main/java/org/destinationsol/game/planet/SunSingleton.java @@ -71,6 +71,6 @@ public void doDmg(SolGame game, SolObject obj, float toSys) { if (SUN_HOT_RAD < toSys) { return; } - obj.receiveDmg(dmg, game, null, DmgType.FIRE); + obj.receiveDmg(dmg, game, null, DmgType.FIRE, null); } } diff --git a/engine/src/main/java/org/destinationsol/game/planet/TileObject.java b/engine/src/main/java/org/destinationsol/game/planet/TileObject.java index a00d14674..e049c11e5 100644 --- a/engine/src/main/java/org/destinationsol/game/planet/TileObject.java +++ b/engine/src/main/java/org/destinationsol/game/planet/TileObject.java @@ -98,7 +98,7 @@ public void onRemove(SolGame game) { } @Override - public void receiveDmg(float dmg, SolGame game, Vector2 position, DmgType dmgType) { + public void receiveDmg(float dmg, SolGame game, Vector2 position, DmgType dmgType, SolObject instigator) { game.getContext().get(SpecialSounds.class).playHit(game, this, position, dmgType); } diff --git a/engine/src/main/java/org/destinationsol/game/projectile/Projectile.java b/engine/src/main/java/org/destinationsol/game/projectile/Projectile.java index cbc8f8c55..6493ba69b 100644 --- a/engine/src/main/java/org/destinationsol/game/projectile/Projectile.java +++ b/engine/src/main/java/org/destinationsol/game/projectile/Projectile.java @@ -34,7 +34,6 @@ import org.destinationsol.game.drawables.Drawable; import org.destinationsol.game.drawables.DrawableLevel; import org.destinationsol.game.drawables.SpriteManager; -import org.destinationsol.game.faction.DefaultReputationEvent; import org.destinationsol.game.faction.Faction; import org.destinationsol.game.item.Shield; import org.destinationsol.game.particle.DSParticleEmitter; @@ -162,10 +161,10 @@ public void update(SolGame game) { if (!wasDamageDealt) { if (config.aoeRadius >= 0) { //If AoE is enabled for this Projectile, damage all within the radius. game.getObjectManager().doToAllCloserThan(config.aoeRadius, this, (SolObject obj) -> - obj.receiveDmg(config.dmg, game, body.getPosition(), config.dmgType) + obj.receiveDmg(config.dmg, game, body.getPosition(), config.dmgType, ship) ); } else { - obstacle.receiveDmg(config.dmg, game, body.getPosition(), config.dmgType); + obstacle.receiveDmg(config.dmg, game, body.getPosition(), config.dmgType, ship); } } if (config.density > 0) { @@ -216,9 +215,6 @@ private void collided(SolGame game) { if (config.collisionEffectBackground != null) { game.getPartMan().blinks(position, game, config.collisionEffectBackground.size); } - if (ship.getPilot().isPlayer() && obstacle instanceof SolShip) { - game.getFactionMan().reportEvent(ship.getFaction(), ((SolShip) obstacle).getFaction(), DefaultReputationEvent.DAMAGED_SHIP); - } game.getSoundManager().play(game, config.collisionSound, null, this); } @@ -241,7 +237,7 @@ public void onRemove(SolGame game) { } @Override - public void receiveDmg(float dmg, SolGame game, Vector2 position, DmgType dmgType) { + public void receiveDmg(float dmg, SolGame game, Vector2 position, DmgType dmgType, SolObject instigator) { if (config.density > 0) { return; } diff --git a/engine/src/main/java/org/destinationsol/game/ship/SolShip.java b/engine/src/main/java/org/destinationsol/game/ship/SolShip.java index c556a8dc4..1cbe4a663 100644 --- a/engine/src/main/java/org/destinationsol/game/ship/SolShip.java +++ b/engine/src/main/java/org/destinationsol/game/ship/SolShip.java @@ -16,7 +16,6 @@ package org.destinationsol.game.ship; -import com.badlogic.gdx.Gdx; import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.physics.box2d.Body; @@ -31,6 +30,8 @@ import org.destinationsol.game.SolGame; import org.destinationsol.game.SolObject; import org.destinationsol.game.drawables.Drawable; +import org.destinationsol.game.faction.DamageInflictedReputationEvent; +import org.destinationsol.game.faction.DefaultReputationEvent; import org.destinationsol.game.faction.Faction; import org.destinationsol.game.gun.GunMount; import org.destinationsol.game.input.Pilot; @@ -147,7 +148,7 @@ public void handleContact(SolObject other, float absImpulse, if (myHull.config.getType() != HullConfig.Type.STATION) { float dmg = absImpulse / myHull.getMass() / myHull.config.getDurability(); dmg *= BASE_DUR_MOD; - receiveDmg((int) dmg, game, collPos, DmgType.CRASH); + receiveDmg((int) dmg, game, collPos, DmgType.CRASH, null); } } @@ -411,7 +412,7 @@ private void throwLoot(SolGame game, SolItem item, boolean onDeath) { } @Override - public void receiveDmg(float dmg, SolGame game, Vector2 position, DmgType dmgType) { + public void receiveDmg(float dmg, SolGame game, Vector2 position, DmgType dmgType, SolObject instigator) { Hero hero = game.getHero(); if (dmg <= 0 || (hero.isInvincible() && hero.getShip() == this)) { return; @@ -426,26 +427,34 @@ public void receiveDmg(float dmg, SolGame game, Vector2 position, DmgType dmgTyp } dmg *= (1 - myArmor.getPerc()); } - getHitWith(dmg, game, position, dmgType); + getHitWith(dmg, game, position, dmgType, instigator); } /** - * Like {{@link #receiveDmg(float, SolGame, Vector2, DmgType)} but shield and armor are ignored, the damage goes straight to the hull + * Like {{@link SolObject#receiveDmg(float, SolGame, Vector2, DmgType, SolObject)} but shield and armor are ignored, the damage goes straight to the hull */ - public void receivePiercingDmg(float dmg, SolGame game, Vector2 position, DmgType dmgType) { + public void receivePiercingDmg(float dmg, SolGame game, Vector2 position, DmgType dmgType, SolObject instigator) { if (dmg <= 0) { return; } - getHitWith(dmg, game, position, dmgType); + getHitWith(dmg, game, position, dmgType, instigator); } - private void getHitWith(float dmg, SolGame game, Vector2 position, DmgType dmgType) { + private void getHitWith(float dmg, SolGame game, Vector2 position, DmgType dmgType, SolObject instigator) { playHitSound(game, position, dmgType); + if (instigator instanceof SolShip) { + game.getFactionMan().reportEvent(((SolShip) instigator).getFaction(), getFaction(), new DamageInflictedReputationEvent(dmg)); + } + boolean wasAlive = myHull.life > 0; myHull.life -= dmg; if (wasAlive && myHull.life <= 0) { + if (instigator instanceof SolShip) { + game.getFactionMan().reportEvent(((SolShip) instigator).getFaction(), getFaction(), DefaultReputationEvent.DESTROYED_SHIP); + } + onDeath(game); Vector2 shipPos = getPosition(); game.getSpecialEffects().explodeShip(game, shipPos, myHull.config.getSize()); diff --git a/engine/src/main/java/org/destinationsol/game/ship/UnShield.java b/engine/src/main/java/org/destinationsol/game/ship/UnShield.java index 798ec55a8..205e433b1 100644 --- a/engine/src/main/java/org/destinationsol/game/ship/UnShield.java +++ b/engine/src/main/java/org/destinationsol/game/ship/UnShield.java @@ -84,7 +84,7 @@ public boolean update(SolGame game, SolShip owner, boolean tryToUse) { if (shieldLife < amount) { amount = shieldLife; } - oShip.receiveDmg(amount, game, ownerPos, DmgType.ENERGY); + oShip.receiveDmg(amount, game, ownerPos, DmgType.ENERGY, owner); } DSParticleEmitter src = new DSParticleEmitter(config.cc.effect, MAX_RADIUS, DrawableLevel.PART_BG_0, new Vector2(), true, game, ownerPos, Vector2.Zero, 0); game.getPartMan().finish(game, src, ownerPos); diff --git a/engine/src/main/java/org/destinationsol/game/tutorial/steps/wrapper/TrackedSolObjectWrapper.java b/engine/src/main/java/org/destinationsol/game/tutorial/steps/wrapper/TrackedSolObjectWrapper.java index ac51cb88b..95a0bb416 100644 --- a/engine/src/main/java/org/destinationsol/game/tutorial/steps/wrapper/TrackedSolObjectWrapper.java +++ b/engine/src/main/java/org/destinationsol/game/tutorial/steps/wrapper/TrackedSolObjectWrapper.java @@ -58,8 +58,8 @@ public void onRemove(SolGame game) { } @Override - public void receiveDmg(float dmg, SolGame game, Vector2 position, DmgType dmgType) { - trackedSolObject.receiveDmg(dmg, game, position, dmgType); + public void receiveDmg(float dmg, SolGame game, Vector2 position, DmgType dmgType, SolObject instigator) { + trackedSolObject.receiveDmg(dmg, game, position, dmgType, instigator); } @Override diff --git a/engine/src/main/java/org/destinationsol/ui/Waypoint.java b/engine/src/main/java/org/destinationsol/ui/Waypoint.java index 13e40560d..eff283c19 100644 --- a/engine/src/main/java/org/destinationsol/ui/Waypoint.java +++ b/engine/src/main/java/org/destinationsol/ui/Waypoint.java @@ -57,7 +57,7 @@ public void onRemove(SolGame game) { } @Override - public void receiveDmg(float dmg, SolGame game, Vector2 position, DmgType dmgType) { + public void receiveDmg(float dmg, SolGame game, Vector2 position, DmgType dmgType, SolObject instigator) { } diff --git a/engine/src/test/java/org/destinationsol/game/RubbleTest.java b/engine/src/test/java/org/destinationsol/game/RubbleTest.java index 257acbdd4..9bcbacdd2 100644 --- a/engine/src/test/java/org/destinationsol/game/RubbleTest.java +++ b/engine/src/test/java/org/destinationsol/game/RubbleTest.java @@ -137,7 +137,7 @@ public void onRemove() { @Test public void receiveDmg() { // Rubbles have no health, and thus receiveDamage() just should not crash - RUBBLE_CONSTANT.receiveDmg(100, game, null, DmgType.BULLET); + RUBBLE_CONSTANT.receiveDmg(100, game, null, DmgType.BULLET, null); } @Test