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 Detection Implemented #235

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
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
@@ -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
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));
}
}