package net.sf.robocode.battle.peer;
import static java.lang.Math.max;
import static java.lang.Math.min;
import static robocode.util.Utils.normalAbsoluteAngle;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import net.sf.robocode.battle.Battle;
import net.sf.robocode.host.RobotStatics;
import net.sf.robocode.peer.BulletCommand;
import net.sf.robocode.peer.BulletStatus;
import net.sf.robocode.peer.ProjectileCommand;
import net.sf.robocode.peer.BulletStatus;
import robocode.BattleRules;
import robocode.Rules;
public class RobotPeerWeaponSystem extends RobotPeerEngine {
protected final StringBuilder proxyText = new StringBuilder(1024);
protected RobotStatics statics;
protected BattleRules battleRules;
protected double radarHeading;
protected double gunHeading;
protected double gunHeat;
protected AtomicReference<List<BulletStatus>> projectileUpdates = new AtomicReference<List<BulletStatus>>(
new ArrayList<BulletStatus>());
protected boolean turnedRadarWithGun;
protected final StringBuilder battleText = new StringBuilder(1024);
public double getGunHeading() {
return gunHeading;
}
public double getGunHeat() {
return gunHeat;
}
public int getGunColor() {
return commands.get().getGunColor();
}
public int getBulletColor() {
return commands.get().getProjectileColor();
}
public RobotPeerWeaponSystem(Battle battle){
super(battle);
}
protected void fire(List<ProjectileCommand> projectileCommands) {
BulletPeer newProjectile = null;
for (ProjectileCommand projCmd : projectileCommands) {
if (Double.isNaN(projCmd.getPower())) {
println("SYSTEM: You cannot call fire(NaN)");
continue;
}
if (gunHeat > 0 || energy == 0) {
return;
}
//newProjectile = projCmd.execute(this);
double firePower = min(
energy,
min(max(projCmd.getPower(), Rules.MIN_BULLET_POWER),
Rules.MAX_BULLET_POWER));
updateEnergy(-firePower);
gunHeat += Rules.getGunHeat(firePower);
if (projCmd instanceof BulletCommand) {
newProjectile = new BulletPeer((RobotPeer) this, battleRules, projCmd.getId());
}
newProjectile.setPower(firePower);
if (!turnedRadarWithGun || !projCmd.isFireAssistValid()
|| statics.isAdvancedRobot()) {
newProjectile.setHeading(gunHeading);
} else {
newProjectile.setHeading(projCmd.getFireAssistAngle());
}
newProjectile.setX(x);
newProjectile.setY(y);
}
// there is only last bullet in one turn
if (newProjectile != null) {
// newBullet.update(robots, bullets);
battle.addBullet(newProjectile);
}
}
public void setGunHeat(double heat) {
this.gunHeat = heat;
}
public BattleRules getBattleRules() {
return this.battleRules;
}
public void drainEnergy() {
setEnergy(0, true);
isEnergyDrained = true;
}
public void addBulletStatus(BulletStatus projectileStatus) {
if (isAlive()) {
projectileUpdates.get().add(projectileStatus);
}
}
public void println(String s) {
synchronized (proxyText) {
battleText.append(s);
battleText.append("\n");
}
}
protected void updateGunHeading() {
if (currentCommands.getGunTurnRemaining() > 0) {
if (currentCommands.getGunTurnRemaining() < Rules.GUN_TURN_RATE_RADIANS) {
gunHeading += currentCommands.getGunTurnRemaining();
radarHeading += currentCommands.getGunTurnRemaining();
if (currentCommands.isAdjustRadarForGunTurn()) {
currentCommands.setRadarTurnRemaining(
currentCommands.getRadarTurnRemaining() - currentCommands.getGunTurnRemaining());
}
currentCommands.setGunTurnRemaining(0);
} else {
gunHeading += Rules.GUN_TURN_RATE_RADIANS;
radarHeading += Rules.GUN_TURN_RATE_RADIANS;
currentCommands.setGunTurnRemaining(currentCommands.getGunTurnRemaining() - Rules.GUN_TURN_RATE_RADIANS);
if (currentCommands.isAdjustRadarForGunTurn()) {
currentCommands.setRadarTurnRemaining(
currentCommands.getRadarTurnRemaining() - Rules.GUN_TURN_RATE_RADIANS);
}
}
} else if (currentCommands.getGunTurnRemaining() < 0) {
if (currentCommands.getGunTurnRemaining() > -Rules.GUN_TURN_RATE_RADIANS) {
gunHeading += currentCommands.getGunTurnRemaining();
radarHeading += currentCommands.getGunTurnRemaining();
if (currentCommands.isAdjustRadarForGunTurn()) {
currentCommands.setRadarTurnRemaining(
currentCommands.getRadarTurnRemaining() - currentCommands.getGunTurnRemaining());
}
currentCommands.setGunTurnRemaining(0);
} else {
gunHeading -= Rules.GUN_TURN_RATE_RADIANS;
radarHeading -= Rules.GUN_TURN_RATE_RADIANS;
currentCommands.setGunTurnRemaining(currentCommands.getGunTurnRemaining() + Rules.GUN_TURN_RATE_RADIANS);
if (currentCommands.isAdjustRadarForGunTurn()) {
currentCommands.setRadarTurnRemaining(
currentCommands.getRadarTurnRemaining() + Rules.GUN_TURN_RATE_RADIANS);
}
}
}
gunHeading = normalAbsoluteAngle(gunHeading);
}
protected void updateGunHeat() {
gunHeat -= battleRules.getGunCoolingRate();
if (gunHeat < 0) {
gunHeat = 0;
}
}
}