Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,13 @@ public FactionManager(FactionsConfigs factionsConfigs) {
* @param event the event that occurred.
* @param <T> the type of event.
*/
public <T extends Enum<T> & ReputationEvent> void reportEvent(Faction instigator, Faction target, T event) {
public <T extends ReputationEvent> 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 {
Expand Down
2 changes: 1 addition & 1 deletion engine/src/main/java/org/destinationsol/game/Rubble.java
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
11 changes: 6 additions & 5 deletions engine/src/main/java/org/destinationsol/game/SolObject.java
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) {

}

Expand Down
5 changes: 3 additions & 2 deletions engine/src/main/java/org/destinationsol/game/StarPort.java
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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!";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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<Faction, Integer> relations;
private final Map<Faction, Float> 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<String, Integer> reputationImpacts;
private final Map<String, Float> reputationImpacts;

/**
* Instantiates a new faction instance.
Expand All @@ -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<ResourceUrn> shipDesigns, Map<String, Integer> reputationImpacts) {
List<ResourceUrn> shipDesigns, Map<String, Float> reputationImpacts) {
this.id = id;
this.name = name;
this.description = description;
Expand Down Expand Up @@ -141,7 +141,7 @@ public List<ResourceUrn> getShipDesigns() {
* @return the change in reputation, if known, otherwise null.
* @param <T> the type of event.
*/
public <T extends Enum<T> & ReputationEvent> Integer getReputationImpact(T event) {
public <T extends ReputationEvent> Float getReputationImpact(T event) {
return reputationImpacts.get(event.toString());
}

Expand All @@ -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;
}
Expand All @@ -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));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<String, Integer> reputationImpacts = new HashMap<>();
Map<String, Float> 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),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
4 changes: 2 additions & 2 deletions engine/src/main/java/org/destinationsol/game/item/Loot.java
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 1 addition & 2 deletions engine/src/main/java/org/destinationsol/game/planet/Sky.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
}
Expand All @@ -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;
}
Expand Down
Loading