Skip to content

Commit

Permalink
Improve performance of updating entity radiation (especially when the…
Browse files Browse the repository at this point in the history
…re is no radiation sources in the world)
  • Loading branch information
pupnewfster committed Mar 2, 2024
1 parent 59f9b2d commit 5f6deb9
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 9 deletions.
44 changes: 37 additions & 7 deletions src/main/java/mekanism/common/lib/radiation/RadiationManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,9 @@ public ResourceKey<DamageType> getRadiationDamageTypeKey() {

@Override
public double getRadiationLevel(Entity entity) {
if (radiationTable.isEmpty()) {//Short circuit when the radiation table is empty
return BASELINE;
}
return getRadiationLevel(GlobalPos.of(entity.level().dimension(), entity.blockPosition()));
}

Expand Down Expand Up @@ -199,24 +202,49 @@ public void removeRadiationSource(GlobalPos pos) {

@Override
public double getRadiationLevel(GlobalPos pos) {
if (radiationTable.isEmpty()) {//Short circuit when the radiation table is empty
return BASELINE;
}
return getRadiationLevelAndMaxMagnitude(pos).level();
}

public LevelAndMaxMagnitude getRadiationLevelAndMaxMagnitude(Entity entity) {
if (radiationTable.isEmpty()) {//Short circuit when the radiation table is empty
return LevelAndMaxMagnitude.BASELINE;
}
return getRadiationLevelAndMaxMagnitude(GlobalPos.of(entity.level().dimension(), entity.blockPosition()));
}

public LevelAndMaxMagnitude getRadiationLevelAndMaxMagnitude(GlobalPos pos) {
if (radiationTable.isEmpty()) {//Short circuit when the radiation table is empty
return LevelAndMaxMagnitude.BASELINE;
}
double level = BASELINE;
double maxMagnitude = BASELINE;
Chunk3D center = new Chunk3D(pos);
int radius = MekanismConfig.general.radiationChunkCheckRadius.get();
// we only compute exposure when within the MAX_RANGE bounds
double maxRange = Mth.square(MekanismConfig.general.radiationChunkCheckRadius.get() * 16);
for (Chunk3D chunk : new Chunk3D(pos).expand(MekanismConfig.general.radiationChunkCheckRadius.get())) {
for (Map.Entry<GlobalPos, RadiationSource> entry : radiationTable.row(chunk).entrySet()) {
if (entry.getKey().pos().distSqr(pos.pos()) <= maxRange) {
RadiationSource source = entry.getValue();
level += computeExposure(pos, source);
maxMagnitude = Math.max(maxMagnitude, source.getMagnitude());
double maxRange = Mth.square(radius * 16);
int minX, maxX, minZ, maxZ;
if (radius == 1) {
maxX = minX = center.x;
maxZ = minZ = center.z;
} else {
minX = center.x - radius;
minZ = center.z - radius;
maxX = center.x + radius;
maxZ = center.z + radius;
}
//Note: We inline the logic from Chunk3D#expand to avoid allocating a new hash set each time
for (int i = minX; i <= maxX; i++) {
for (int j = minZ; j <= maxZ; j++) {
Chunk3D chunk = new Chunk3D(center.dimension, i, j);
for (Map.Entry<GlobalPos, RadiationSource> entry : radiationTable.row(chunk).entrySet()) {
if (entry.getKey().pos().distSqr(pos.pos()) <= maxRange) {
RadiationSource source = entry.getValue();
level += computeExposure(pos, source);
maxMagnitude = Math.max(maxMagnitude, source.getMagnitude());
}
}
}
}
Expand Down Expand Up @@ -496,6 +524,8 @@ public void onLivingTick(LivingTickEvent event) {
}

public record LevelAndMaxMagnitude(double level, double maxMagnitude) {

private static final LevelAndMaxMagnitude BASELINE = new LevelAndMaxMagnitude(RadiationManager.BASELINE, RadiationManager.BASELINE);
}

public enum RadiationScale {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,13 @@ public void update() {
if (!entity.isAlive() || entity instanceof Player player && !MekanismUtils.isPlayingMode(player)) {
return;
}
entity.getData(MekanismAttachmentTypes.RADIATION);
double radiation = getRadiation();
if (radiation <= RadiationManager.BASELINE) {
//NO-OP, the entity isn't actually irradiated
return;
}

RandomSource rand = entity.level().getRandom();
double radiation = getRadiation();
double minSeverity = MekanismConfig.general.radiationNegativeEffectsMinSeverity.get();
double severityScale = RadiationScale.getScaledDoseSeverity(radiation);
double chance = minSeverity + rand.nextDouble() * (1 - minSeverity);
Expand Down

0 comments on commit 5f6deb9

Please sign in to comment.