Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -20,33 +20,25 @@ public static ArrayList<BiomassBlob> generateBlobs(World world, int minCount, in
int blobCount = random.nextInt(maxCount - minCount) + minCount;
ArrayList<BiomassBlob> biomassBlobs = new ArrayList<>(blobCount);

//Count number of plain tiles. If there is less plain tiles than desired amount of blobs,
//set the desired amount of blobs to the plain tile count
// Count number of plain tiles. If there is less plain tiles than desired amount
// of blobs,
// set the desired amount of blobs to the plain tile count
TileMap m = world.getTileMap();
int plainCount = 0;
for (int y = 0; y < world.getWorldSize(); y++) {
for (int x = 0; x < world.getWorldSize(); x++) {

if (m.getTileIdAt(x, y) == TilePlain.ID) {
plainCount++;
}
}
}
int plainCount = world.getCount(TilePlain.ID);

if (blobCount > plainCount) {
blobCount = plainCount;
}

outerLoop:
for (int i = 0; i < blobCount; i++) {
outerLoop: for (int i = 0; i < blobCount; i++) {

Point p = m.getRandomTile(TilePlain.ID);
if (p != null) {

//Don't block worlds
// Don't block worlds
int counter = 0;
while (p.x == 0 || p.y == 0 || p.x == world.getWorldSize() - 1 || p.y == world.getWorldSize() - 1 ||
world.getGameObjectsAt(p.x, p.y).size() != 0) {
while (p.x == 0 || p.y == 0 || p.x == world.getWorldSize() - 1 || p.y == world.getWorldSize() - 1
|| world.getGameObjectsAt(p.x, p.y).size() != 0) {
p = m.getRandomTile(TilePlain.ID);
counter++;

Expand All @@ -57,7 +49,7 @@ public static ArrayList<BiomassBlob> generateBlobs(World world, int minCount, in

for (BiomassBlob biomassBlob : biomassBlobs) {
if (biomassBlob.getX() == p.x && biomassBlob.getY() == p.y) {
//There is already a blob here
// There is already a blob here
continue outerLoop;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
package net.simon987.pluginradioactivecloud;

import java.util.ArrayList;

import org.bson.Document;
import net.simon987.server.assembly.HardwareModule;
import net.simon987.server.assembly.Status;
import net.simon987.server.game.objects.ControllableUnit;
import net.simon987.server.game.objects.GameObject;
import net.simon987.server.game.objects.Radioactive;

public class RadiationDetector extends HardwareModule {

/**
* Should be unique and same as HWID
*/
public static final int DEFAULT_ADDRESS = 0x000E;

/**
* Hardware ID (Should be unique)
*/
public static final char HWID = 0x000E;

/**
* Radiation Constants
*/
private static final int ALPHA_BLOCKED_VALUE = 5;
private static final int BETA_BLOCKED_VALUE = 2;
private static final int GAMMA_BLOCKED_VALUE = 1;

/**
* Helper class for getTiles
*/
private class Tuple {
public final int x;
public final int y;

public Tuple(int x, int y) {
this.x = x;
this.y = y;
}
}

/**
* Finds the tiles between the two tiles located at the given coordinates. The
* tiles located at the coordinates are not included in the list.
*
* @param x0 x-coordinate of first point
* @param y0 y-coordinate of first point
* @param x1 x-coordinate of second point
* @param y1 y-coordinate of second point
* @return List of tile coordinates. An empty list indicates tiles are next to
* each other.
*/
public ArrayList<Tuple> getTiles(int x0, int y0, int x1, int y1) {

ArrayList<Tuple> ret = new ArrayList<>();
double slope;
if (x1 > x0) {
slope = (y1 - y0) / (double) (x1 - x0);
} else {
slope = (y0 - y1) / (double) (x0 - x1);

// Swap values so that x0 < x1. This preps the following code where y is
// determined by adding a step value (1) to x0 till it reaches x1.
int tmp = x1;
x1 = x0;
x0 = tmp;

tmp = y1;
y1 = y0;
y0 = tmp;
}

// If slope is zero or undefined, return tiles directly along the
// appropriate cardinal direction.
if (x0 == x1) {
int smaller = Math.min(y0, y1);
int larger = Math.max(y0, y1);
System.out.printf("%d %d", smaller, larger);
for (int i = smaller + 1; i < larger; i++) {
ret.add(new Tuple(x0, i));
}
} else if (y0 == y1) {
int smaller = Math.min(x0, x1);
int larger = Math.max(x0, x1);
for (int i = smaller + 1; i < larger; i++) {
ret.add(new Tuple(i, y0));
}
} else {
// Find all coordinates with 0.1 step
int lastX = x0;
int lastY = y0;
for (int i = x0 * 10; i < x1 * 10; i += 1) {
if (i / 10 != lastX || (int) (slope * i / 10) != lastY) {
// Update last values
lastX = i / 10;
lastY = (int) (slope * i / 10);

// Add new values to array
ret.add(new Tuple(lastX, lastY));
}
}
}

return ret;
}

/**
* Finds the Euclidean Distance between two coordinates.
*
* @param x0 x-coordinate of first point
* @param y0 y-coordinate of first point
* @param x1 x-coordinate of second point
* @param y1 y-coordinate of second point
* @return distance between two points
*/
public double getDistanceOfCoords(int x0, int y0, int x1, int y1) {
return Math.sqrt(Math.pow(x1 - x0, 2) + Math.pow(y1 - y0, 2));
}

public RadiationDetector(ControllableUnit unit) {
super(null, unit);
}

public RadiationDetector(Document document, ControllableUnit cubot) {
super(document, cubot);
}

@Override
public void handleInterrupt(Status status) {

// Find all game entities in world
ArrayList<GameObject> entities = new ArrayList<>(unit.getWorld().getGameObjects());

// Check for alpha particles by finding Radioactive entities
int alphaParticles = 0;
int betaParticles = 0;
int gammaParticles = 0;
for (GameObject entity : entities) {
if (entity instanceof Radioactive) {
// Calculate distance between object and cubot
double pathLength = getDistanceOfCoords(unit.getX(), unit.getY(), entity.getX(), entity.getY());
alphaParticles += ((Radioactive) entity).getAlphaCounts(pathLength);
betaParticles += ((Radioactive) entity).getBetaCounts(pathLength);
gammaParticles += ((Radioactive) entity).getGammaCounts(pathLength);

// Get all tiles in between cubot and Radioactive entity
ArrayList<Tuple> tiles = getTiles(unit.getX(), unit.getY(), entity.getX(), entity.getY());
for (Tuple tup : tiles) {
// If intermediary tile is blocked, reduce alphaParticles by 5
if (unit.getWorld().isTileBlocked(tup.x, tup.y)) {
alphaParticles -= ALPHA_BLOCKED_VALUE;
betaParticles -= BETA_BLOCKED_VALUE;
gammaParticles -= GAMMA_BLOCKED_VALUE;
}
}
}
}

// Save Alpha Radioactive Particles to register A
getCpu().getRegisterSet().getRegister("A").setValue(alphaParticles);

// Save Beta Radioactive Particles to register B
getCpu().getRegisterSet().getRegister("B").setValue(betaParticles);

// Save Gamma Radioactive Particles to register C
getCpu().getRegisterSet().getRegister("C").setValue(gammaParticles);
}

@Override
public char getId() {
return HWID;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package net.simon987.pluginradioactivecloud;

import net.simon987.server.game.world.TileMap;
import net.simon987.server.game.world.TilePlain;
import net.simon987.server.game.world.World;
import org.bson.types.ObjectId;

import java.awt.*;
import java.util.ArrayList;
import java.util.Random;

public class RadioactiveWorldUtils {

/**
* Generate a list of radioactive obstacles for a world
*/
public static ArrayList<RadioactiveObstacle> generateRadioactiveObstacles(World world, int minCount, int maxCount) {

Random random = new Random();
int radioactiveObjCount = random.nextInt(maxCount - minCount) + minCount;
ArrayList<RadioactiveObstacle> radioactiveObstacles = new ArrayList<>(radioactiveObjCount);

// Count number of plain tiles. If there is less plain tiles than desired amount
// of radioactive objects, set the desired amount of radioactive objects to the
// plain tile count
TileMap m = world.getTileMap();
int plainCount = world.getCount(TilePlain.ID);

if (radioactiveObjCount > plainCount) {
radioactiveObjCount = plainCount;
}

outerLoop: for (int i = 0; i < radioactiveObjCount; i++) {

Point p = m.getRandomTile(TilePlain.ID);
if (p != null) {

// Don't block worlds
int counter = 0;
while (p.x == 0 || p.y == 0 || p.x == world.getWorldSize() - 1 || p.y == world.getWorldSize() - 1
|| world.getGameObjectsAt(p.x, p.y).size() != 0) {
p = m.getRandomTile(TilePlain.ID);
counter++;

if (counter > 25) {
continue outerLoop;
}
}

for (RadioactiveObstacle radioactiveObstacle : radioactiveObstacles) {
if (radioactiveObstacle.getX() == p.x && radioactiveObstacle.getY() == p.y) {
// There is already a blob here
continue outerLoop;
}
}

RadioactiveObstacle radioactiveObstacle = new RadioactiveObstacle();
radioactiveObstacle.setObjectId(new ObjectId());
radioactiveObstacle.setX(p.x);
radioactiveObstacle.setY(p.y);
radioactiveObstacle.setWorld(world);

radioactiveObstacles.add(radioactiveObstacle);
}
}

return radioactiveObstacles;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package net.simon987.pluginradioactivecloud.event;

import net.simon987.pluginradioactivecloud.RadioactiveObstacle;
import net.simon987.pluginradioactivecloud.RadioactiveWorldUtils;
import net.simon987.server.GameServer;
import net.simon987.server.event.GameEvent;
import net.simon987.server.event.GameEventListener;
import net.simon987.server.event.WorldGenerationEvent;

import java.util.ArrayList;

public class WorldCreationListener implements GameEventListener {
@Override
public Class getListenedEventType() {
return WorldGenerationEvent.class;
}

@Override
public void handle(GameEvent event) {

int minCount = GameServer.INSTANCE.getConfig().getInt("min_radioactive_obstacle_count");
int maxCount = GameServer.INSTANCE.getConfig().getInt("max_radioactive_obstacle_count");

ArrayList<RadioactiveObstacle> radioactiveObstacles = RadioactiveWorldUtils
.generateRadioactiveObstacles(((WorldGenerationEvent) event).getWorld(), minCount, maxCount);

for (RadioactiveObstacle radioactiveObstacle : radioactiveObstacles) {
((WorldGenerationEvent) event).getWorld().addObject(radioactiveObstacle);
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,15 @@

public interface Radioactive {

public default int getAlphaCounts(double distance) {
return (int) (1000 * 1.0 / (distance * distance));
}

public default int getBetaCounts(double distance) {
return (int) (2000 * 1.0 / (distance * distance));
}

public default int getGammaCounts(double distance) {
return (int) (5000 * 1.0 / (distance * distance));
}
}
Loading