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

Radioactive Game Object onto Map #236

Draft
wants to merge 11 commits into
base: master
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ 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++) {
Expand All @@ -37,16 +38,15 @@ public static ArrayList<BiomassBlob> generateBlobs(World world, int minCount, in
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 +57,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,77 @@
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 biomass blobs for a world
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RadioactiveObstacle

*/
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 = 0;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This exact code block is used twice, we should extract it into its own function (e.g. WorldUtils.countTiles(int tileId))

for (int y = 0; y < world.getWorldSize(); y++) {
for (int x = 0; x < world.getWorldSize(); x++) {

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

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
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));
}
}