/*******************************************************************************
* Copyright (c) 2001, 2010 Mathew A. Nelson and Robocode contributors
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://robocode.sourceforge.net/license/epl-v10.html
*
* Contributors:
* Mathew A. Nelson
* - Initial API and implementation
* Flemming N. Larsen
* - Updated Javadocs
*******************************************************************************/
package robocode;
import net.sf.robocode.security.IHiddenBulletHelper;
import net.sf.robocode.serialization.ISerializableHelper;
import net.sf.robocode.serialization.RbSerializer;
import java.io.Serializable;
import java.nio.ByteBuffer;
/**
* Represents a bullet. This is returned from {@link Robot#fireBullet(double)}
* and {@link AdvancedRobot#setFireBullet(double)}, and all the bullet-related
* events.
*
* @author Mathew A. Nelson (original)
* @see Robot#fireBullet(double)
* @see AdvancedRobot#setFireBullet(double)
* @see BulletHitEvent
* @see BulletMissedEvent
* @see BulletHitBulletEvent
*/
public class Bullet implements Serializable {
private static final long serialVersionUID = 1L;
private final double headingRadians;
private double x;
private double y;
private final double power;
private final String ownerName;
private String victimName;
private boolean isActive;
private final int bulletId;
/**
* Called by the game to create a new {@code Bullet} object
*
* @param heading the heading of the bullet, in radians.
* @param x the starting X position of the bullet.
* @param y the starting Y position of the bullet.
* @param power the power of the bullet.
* @param ownerName the name of the owner robot that owns the bullet.
* @param victimName the name of the robot hit by the bullet.
* @param isActive {@code true} if the bullet still moves; {@code false} otherwise.
* @param bulletId unique id of bullet for owner robot.
*/
public Bullet(double heading, double x, double y, double power, String ownerName, String victimName, boolean isActive, int bulletId) {
this.headingRadians = heading;
this.bulletId = bulletId;
this.x = x;
this.y = y;
this.power = power;
this.ownerName = ownerName;
this.victimName = victimName;
this.isActive = isActive;
}
/**
* Returns the direction the bullet is/was heading, in degrees
* (0 <= getHeading() < 360). This is not relative to the direction you are
* facing.
*
* @return the direction the bullet is/was heading, in degrees
*/
public double getHeading() {
return Math.toDegrees(headingRadians);
}
/**
* Returns the direction the bullet is/was heading, in radians
* (0 <= getHeadingRadians() < 2 * Math.PI). This is not relative to the
* direction you are facing.
*
* @return the direction the bullet is/was heading, in radians
*/
public double getHeadingRadians() {
return headingRadians;
}
/**
* Returns the name of the robot that fired this bullet.
*
* @return the name of the robot that fired this bullet
*/
public String getName() {
return ownerName;
}
/**
* Returns the power of this bullet.
* <p/>
* The bullet will do (4 * power) damage if it hits another robot.
* If power is greater than 1, it will do an additional 2 * (power - 1)
* damage. You will get (3 * power) back if you hit the other robot.
*
* @return the power of the bullet
*/
public double getPower() {
return power;
}
/**
* Returns the velocity of this bullet. The velocity of the bullet is
* constant once it has been fired.
*
* @return the velocity of the bullet
*/
public double getVelocity() {
return Rules.getBulletSpeed(power);
}
/**
* Returns the name of the robot that this bullet hit, or {@code null} if
* the bullet has not hit a robot.
*
* @return the name of the robot that this bullet hit, or {@code null} if
* the bullet has not hit a robot.
*/
public String getVictim() {
return victimName;
}
/**
* Returns the X position of the bullet.
*
* @return the X position of the bullet
*/
public double getX() {
return x;
}
/**
* Returns the Y position of the bullet.
*
* @return the Y position of the bullet
*/
public double getY() {
return y;
}
/**
* Checks if this bullet is still active on the battlefield.
*
* @return {@code true} if the bullet is still active on the battlefield;
* {@code false} otherwise
*/
public boolean isActive() {
return isActive;
}
/**
* Updates this bullet based on the specified bullet status.
*
* @param x the new X position of the bullet .
* @param y the new Y position of the bullet.
* @param victimName the name if the victim that has been hit by this bullet.
* @param isActive {@code true} if the bullet still moves; {@code false} otherwise.
*/
// this method is invisible on RobotAPI
private void update(double x, double y, String victimName, boolean isActive) {
this.x = x;
this.y = y;
this.victimName = victimName;
this.isActive = isActive;
}
// this method is invisible on RobotAPI
/**
* @return unique id of bullet for owner robot
*/
int getBulletId() {
return bulletId;
}
/**
* Creates a hidden bullet helper for accessing hidden methods on this object.
*
* @return a hidden bullet helper.
*/
// this method is invisible on RobotAPI
static IHiddenBulletHelper createHiddenHelper() {
return new HiddenBulletHelper();
}
/**
* Creates a hidden bullet helper for accessing hidden methods on this object.
*
* @return a hidden bullet helper.
*/
// this class is invisible on RobotAPI
static ISerializableHelper createHiddenSerializer() {
return new HiddenBulletHelper();
}
// this class is invisible on RobotAPI
private static class HiddenBulletHelper implements IHiddenBulletHelper, ISerializableHelper {
public void update(Bullet bullet, double x, double y, String victimName, boolean isActive) {
bullet.update(x, y, victimName, isActive);
}
public int sizeOf(RbSerializer serializer, Object object) {
Bullet obj = (Bullet) object;
return RbSerializer.SIZEOF_TYPEINFO + 4 * RbSerializer.SIZEOF_DOUBLE + serializer.sizeOf(obj.ownerName)
+ serializer.sizeOf(obj.victimName) + RbSerializer.SIZEOF_BOOL;
}
public void serialize(RbSerializer serializer, ByteBuffer buffer, Object object) {
Bullet obj = (Bullet) object;
serializer.serialize(buffer, obj.headingRadians);
serializer.serialize(buffer, obj.x);
serializer.serialize(buffer, obj.y);
serializer.serialize(buffer, obj.power);
serializer.serialize(buffer, obj.ownerName);
serializer.serialize(buffer, obj.victimName);
serializer.serialize(buffer, obj.isActive);
}
public Object deserialize(RbSerializer serializer, ByteBuffer buffer) {
double headingRadians = buffer.getDouble();
double x = buffer.getDouble();
double y = buffer.getDouble();
double power = buffer.getDouble();
String ownerName = serializer.deserializeString(buffer);
String victimName = serializer.deserializeString(buffer);
boolean isActive = serializer.deserializeBoolean(buffer);
return new Bullet(headingRadians, x, y, power, ownerName, victimName, isActive, -1);
}
}
}