Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace the lamps' mob-killing logic with mob-blocking logic. #898

Draft
wants to merge 1 commit into
base: develop
Choose a base branch
from
Draft
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
8 changes: 4 additions & 4 deletions src/main/java/mods/eln/Eln.java
Original file line number Diff line number Diff line change
Expand Up @@ -295,8 +295,7 @@ public class Eln {
public double fuelHeatFurnacePowerFactor = 1;
public int autominerRange = 10;

public boolean killMonstersAroundLamps;
public int killMonstersAroundLampsRange;
public int blockMonstersAroundLampsRange;

double stdBatteryHalfLife = 2 * Utils.minecraftDay;
double batteryCapacityFactor = 1.;
Expand All @@ -311,6 +310,7 @@ public class Eln {

public static double maxSoundDistance = 16;
private double cablePowerFactor;
private int lampMonsterBlockRange = 8;

@EventHandler
public void preInit(FMLPreInitializationEvent event) {
Expand Down Expand Up @@ -389,6 +389,7 @@ public void preInit(FMLPreInitializationEvent event) {
fuelGeneratorPowerFactor = config.get("balancing", "fuelGeneratorPowerFactor", 1).getDouble(1);
fuelHeatFurnacePowerFactor = config.get("balancing", "fuelHeatFurnacePowerFactor", 1.0).getDouble();
autominerRange = config.get("balancing", "autominerRange", 10, "Maximum horizontal distance from autominer that will be mined").getInt(10);
lampMonsterBlockRange = config.get("balancing", "lampMonsterBlockRange", 8, "Maximum distance for which lamps block monster spawning", 0, 32768).getInt();

Other.ElnToIc2ConversionRatio = config.get("balancing", "ElnToIndustrialCraftConversionRatio", 1.0 / 3.0).getDouble(1.0 / 3.0);
Other.ElnToOcConversionRatio = config.get("balancing", "ElnToOpenComputerConversionRatio", 1.0 / 3.0 / 2.5).getDouble(1.0 / 3.0 / 2.5);
Expand All @@ -405,8 +406,7 @@ public void preInit(FMLPreInitializationEvent event) {
replicatorPop = config.get("entity", "replicatorPop", true).getBoolean(true);
ReplicatorPopProcess.popPerSecondPerPlayer = config.get("entity", "replicatorPopWhenThunderPerSecond", 1.0 / 120).getDouble(1.0 / 120);
replicatorRegistrationId = config.get("entity", "replicatorId", -1).getInt(-1);
killMonstersAroundLamps = config.get("entity", "killMonstersAroundLamps", true).getBoolean(true);
killMonstersAroundLampsRange = config.get("entity", "killMonstersAroundLampsRange", 9).getInt(9);
blockMonstersAroundLampsRange = config.get("entity", "blockMonstersAroundLampsRange", 12).getInt(12);

forceOreRegen = config.get("mapGenerate", "forceOreRegen", false).getBoolean(false);
genCopper = config.get("mapGenerate", "copper", true).getBoolean(true);
Expand Down
61 changes: 61 additions & 0 deletions src/main/java/mods/eln/eventhandlers/MonsterEventHandler.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package mods.eln.eventhandlers

import mods.eln.entity.ReplicatorEntity
import mods.eln.misc.Coordonate
import mods.eln.misc.OctoTree
import net.minecraft.entity.boss.EntityWither
import net.minecraftforge.event.entity.EntityJoinWorldEvent
import kotlin.math.roundToInt

/**
* This is not an efficient way to do anything.
*
* The octree is a good start. It's fine in terms of CPU use, more or less, but that memory use scares me and is
* also entirely pointless. I'll have to find (or invent) a better algorithm. Though, the octree implementation
* supports clusterization so... maybe that's at least partially fine?
*
* It's also far too easy to imagine this counter getting desynced from reality.
* Although it seems to be working so far.
*/

object MonsterEventHandler {
private val trees: MutableMap<Int, OctoTree<Int>> = HashMap()

fun onSpawn(event: EntityJoinWorldEvent) {
val entity = event.entity
if (entity is ReplicatorEntity || entity is EntityWither) {
return
}
val x = entity.posX.roundToInt() + 32768
val y = entity.posY.roundToInt() + 32768
val z = entity.posZ.roundToInt() + 32768
if (trees[entity.dimension]?.get(x, y, z) ?: 0 > 0) {
event.isCanceled = true
}
}

private fun doCube(center: Coordonate, range: Int, f: (Int) -> Int) {
if (range <= 0) return
val xOffset = center.x + 32768
val yOffset = center.y + 32768
val zOffset = center.z + 32768
val tree = trees.getOrPut(center.dimention) { OctoTree(16) }
for (x in (xOffset - range)..(xOffset + range)) {
for (y in (yOffset - range)..(yOffset + range)) {
for (z in (zOffset - range)..(zOffset + range)) {
tree.set(x, y, z, f(tree.get(x, y, z) ?: 0))
}
}
}
}

fun registerMonsterBlock(coord: Coordonate, range: Int) {
println("Registering block at $coord - $range")
doCube(coord, range) { it + 1 }
}

fun unregisterMonsterBlock(coord: Coordonate, range: Int) {
println("Unregistering block at $coord - $range")
doCube(coord, range) { Math.max(0, it - 1) }
}
}
141 changes: 141 additions & 0 deletions src/main/java/mods/eln/misc/ocTree.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
package mods.eln.misc

// Licensed under Apache 2.0
// Copyright JetBrains, 2017

class OctoTree<T>(val depth: Int) {

private var root: Node<T>? = null
private var actual = false

//-------------------------------------------------------------------------//

fun get(x: Int, y: Int, z: Int): T? {
var dep = depth
var iter = root
while (true) {
if (iter == null) return null
else if (iter is Node.Leaf) return iter.value

iter = (iter as Node.Branch<T>).nodes[number(x, y, z, --dep)]
}
}

//-------------------------------------------------------------------------//

fun set(x: Int, y: Int, z: Int, value: T) {
if (root == null) root = Node.Branch()
if (root!!.set(x, y, z, value, depth - 1)) {
root = Node.Leaf(value)
}
actual = false
}

//-------------------------------------------------------------------------//

override fun toString(): String = root.toString()

//-------------------------------------------------------------------------//

sealed class Node<T> {

abstract fun set(x: Int, y: Int, z: Int, value: T, depth: Int): Boolean

//---------------------------------------------------------------------//

class Leaf<T>(var value: T) : Node<T>() {

override fun set(x: Int, y: Int, z: Int, value: T, depth: Int): Boolean {
throw UnsupportedOperationException("set on Leaf element")
}

override fun toString(): String = "L{$value}"
}

//---------------------------------------------------------------------//

class Branch<T>() : Node<T>() {

constructor(value: T, exclude: Int) : this() {

var i = 0
while (i < 8) {
if (i != exclude) {
nodes[i] = Leaf(value)
}
i++
}
}

private fun canClusterize(value: T): Boolean {
var i = 0
while (i < 8) {
val w = nodes[i]
if (w == null || w !is Leaf || value != w.value) {
return false
}
i++
}
return true
}

override fun set(x: Int, y: Int, z: Int, value: T, depth: Int): Boolean {
val branchIndex = number(x, y, z, depth)
val node = nodes[branchIndex]
when (node) {
null -> {
if (depth == 0) {
nodes[branchIndex] = Leaf(value)
return canClusterize(value)
} else {
nodes[branchIndex] = Branch()
}
}
is Leaf<T> -> {
if (node.value == value) {
return false
} else if (depth == 0) {
node.value = value
return canClusterize(value)
}
nodes[branchIndex] = Branch(node.value, number(x, y, z, depth - 1))
}
}

if (nodes[branchIndex]!!.set(x, y, z, value, depth - 1)) {
nodes[branchIndex] = Leaf(value)
return canClusterize(value)
}
return false
}

val nodes = arrayOfNulls<Node<T>>(8)
override fun toString(): String = nodes.joinToString(prefix = "[", postfix = "]")
}
}
//-------------------------------------------------------------------------//

companion object {
fun number(x: Int, y: Int, z: Int, depth: Int): Int {
val mask = 1 shl depth
if (x and mask != 0) {
if (y and mask != 0) {
if (z and mask != 0)
return 7
return 6
}
if (z and mask != 0)
return 5
return 4
}
if (y and mask != 0) {
if (z and mask != 0)
return 3
return 2
}
if (z and mask != 0)
return 1
return 0
}
}
}
26 changes: 0 additions & 26 deletions src/main/java/mods/eln/server/ConsoleListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ public class ConsoleListener extends CommandBase {
private final String cmdNameStr_newWind = "newWind";
private final String cmdNameStr_regenOre = "regenOre";
private final String cmdNameStr_generateLangFileTemplate = "generateLangFileTemplate";
private final String cmdNameStr_killMonstersAroundLamps = "killMonstersAroundLamps";

private final String strOffsetL0 = " ";
private final String strOffsetL1 = " ";
Expand All @@ -50,7 +49,6 @@ public ConsoleListener() {
cmdVisibleList.add(cmdNameStr_newWind);
cmdVisibleList.add(cmdNameStr_regenOre);
cmdVisibleList.add(cmdNameStr_generateLangFileTemplate);
cmdVisibleList.add(cmdNameStr_killMonstersAroundLamps);
java.util.Collections.sort(cmdVisibleList);
}

Expand Down Expand Up @@ -214,24 +212,9 @@ public void processCommand(ICommandSender ics, String[] astring) {
cprint(ics, Color.COLOR_DARK_CYAN + "ELN > " + Color.COLOR_DARK_YELLOW + cmdNameStr_generateLangFileTemplate);
cprint(ics, strOffsetL0 + "New language system parses source code, see here how to generate language " +
"files: https://github.com/Electrical-Age/ElectricalAge");
} else if (cmd.equalsIgnoreCase(cmdNameStr_killMonstersAroundLamps)) {
cprint(ics, Color.COLOR_DARK_CYAN + "ELN > " + Color.COLOR_DARK_YELLOW + cmdNameStr_killMonstersAroundLamps);
if (!checkArgCount(ics, astring, 1))
return;
ConsoleArg<Boolean> arg0 = getArgBool(ics, astring[1]);
if (!arg0.valid)
return;
Eln.instance.killMonstersAroundLamps = arg0.value;
cprint(ics, strOffsetL0 + "Avoid monsters spawning around lamps : " + Color.COLOR_DARK_GREEN + boolToStr(arg0.value));
cprint(ics, strOffsetL0 + "Warning: Command effective to this game instance only.");
} else {
cprint(ics, Color.COLOR_DARK_CYAN + "ELN > " + Color.COLOR_DARK_RED + "Error: Unknown command.");
}

return;

//Eln.simulator.setSimplify(!astring[1].equals("0"));
//Eln.simulator.pleaseCrash = true;
}

private boolean checkArgCount(ICommandSender ics, String[] args, int exceptedArgc) {
Expand Down Expand Up @@ -343,15 +326,6 @@ private void commandMan(ICommandSender ics, String cmd) {
cprint(ics, strOffsetL0 + "Parameters :");
cprint(ics, strOffsetL1 + "@0:string : full file path.");
cprint(ics, "");
} else if (cmd.equalsIgnoreCase(cmdNameStr_killMonstersAroundLamps)) {
cprint(ics, strOffsetL0 + "When set, monsters don't spawn around the lamps (default).");
cprint(ics, strOffsetL0 + "When clear, leaving lights on in dark zones is recommended...");
cprint(ics, strOffsetL0 + "Effective only during this game instance.");
cprint(ics, strOffsetL0 + "(See \"Eln.cfg\" for permanent effect.)");
cprint(ics, "");
cprint(ics, strOffsetL0 + "Parameters :");
cprint(ics, strOffsetL1 + "@0:bool : Enable/disable.");
cprint(ics, "");
} else {
cprint(ics, Color.COLOR_DARK_RED + strOffsetL0 + "Error : Unknown/Undocumented command.");
}
Expand Down
8 changes: 7 additions & 1 deletion src/main/java/mods/eln/server/ServerEventListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,20 @@
import cpw.mods.fml.common.gameevent.TickEvent.Phase;
import cpw.mods.fml.common.gameevent.TickEvent.ServerTickEvent;
import mods.eln.Eln;
import mods.eln.eventhandlers.MonsterEventHandler;
import mods.eln.item.electricalitem.TreeCapitation;
import mods.eln.misc.Coordonate;
import mods.eln.misc.Utils;
import mods.eln.node.NodeManager;
import net.minecraft.entity.EntityCreature;
import net.minecraft.entity.effect.EntityLightningBolt;
import net.minecraft.entity.monster.EntityMob;
import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.entity.EntityEvent.EntityConstructing;
import net.minecraftforge.event.entity.EntityJoinWorldEvent;
import net.minecraftforge.event.world.WorldEvent;
import net.minecraftforge.event.world.WorldEvent.Load;
import net.minecraftforge.event.world.WorldEvent.Save;
Expand Down Expand Up @@ -46,9 +50,11 @@ public void tick(ServerTickEvent event) {
}

@SubscribeEvent
public void onNewEntity(EntityConstructing event) {
public void onNewEntity(EntityJoinWorldEvent event) {
if (event.entity instanceof EntityLightningBolt) {
lightningListNext.add((EntityLightningBolt) event.entity);
} else if (event.entity instanceof EntityMob) {
MonsterEventHandler.INSTANCE.onSpawn(event);
}
}

Expand Down
56 changes: 0 additions & 56 deletions src/main/java/mods/eln/sim/MonsterPopFreeProcess.java

This file was deleted.

Loading