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