/*
* Aphelion
* Copyright (c) 2013 Joris van der Wel
*
* This file is part of Aphelion
*
* Aphelion is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* Aphelion is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Aphelion. If not, see <http://www.gnu.org/licenses/>.
*
* In addition, the following supplemental terms apply, based on section 7 of
* the GNU Affero General Public License (version 3):
* a) Preservation of all legal notices and author attributions
* b) Prohibition of misrepresentation of the origin of this material, and
* modified versions are required to be marked in reasonable ways as
* different from the original version (for example by appending a copyright notice).
*
* Linking this library statically or dynamically with other modules is making a
* combined work based on this library. Thus, the terms and conditions of the
* GNU Affero General Public License cover the whole combination.
*
* As a special exception, the copyright holders of this library give you
* permission to link this library with independent modules to produce an
* executable, regardless of the license terms of these independent modules,
* and to copy and distribute the resulting executable under terms of your
* choice, provided that you also meet, for each linked independent module,
* the terms and conditions of the license of that module. An independent
* module is a module which is not derived from or based on this library.
*
*
*
*/
package aphelion.shared.physics.entities;
import aphelion.shared.gameconfig.ConfigSelection;
import aphelion.shared.gameconfig.GCBoolean;
import aphelion.shared.gameconfig.GCBooleanList;
import aphelion.shared.gameconfig.GCColour;
import aphelion.shared.gameconfig.GCImage;
import aphelion.shared.gameconfig.GCInteger;
import aphelion.shared.gameconfig.GCIntegerList;
import aphelion.shared.gameconfig.GCString;
import aphelion.shared.gameconfig.GCStringList;
import aphelion.shared.net.protobuf.GameOperation;
import aphelion.shared.physics.State;
import aphelion.shared.physics.valueobjects.PhysicsMoveable;
import aphelion.shared.physics.valueobjects.PhysicsPoint;
import aphelion.shared.physics.valueobjects.PhysicsShipPosition;
import aphelion.shared.physics.WEAPON_SLOT;
import aphelion.shared.resource.ResourceDB;
import java.util.Iterator;
/**
* This wrapper makes sure that if an actor gets destroyed
* and re-added because of a time warp, the correct actor will be used.
*
* @author Joris
*/
public class ActorPublicImpl implements ActorPublic
{
Actor privateActor;
final int pid;
private final State state;
public ActorPublicImpl(Actor actor, State state)
{
this.privateActor = actor;
this.pid = actor.pid;
this.state = state;
}
public ActorPublicImpl(int pid, State state)
{
this.privateActor = null;
this.pid = pid;
this.state = state;
}
Actor getActor()
{
if (pid == 0)
{
return null;
}
if (privateActor == null)
{
// might return null
privateActor = state.actors.get(new ActorKey(this.pid));
}
if (privateActor != null)
{
assert privateActor.pid == this.pid;
}
return privateActor;
}
@Override
public boolean hasReference()
{
return getActor() != null;
}
@Override
public boolean isNonExistent()
{
Actor actor = getActor();
if (actor == null)
{
return true;
}
return actor.isNonExistent(state.tick_now);
}
@Override
public boolean isNonExistent(long tick)
{
Actor actor = getActor();
if (actor == null)
{
return true;
}
return actor.isNonExistent(tick);
}
@Override
public int getStateId()
{
return state.id;
}
@Override
public int getPid()
{
return pid;
}
/** Gets the most current position, velocity and rotation for the actor.
* @param pos The object to fill with position, velocity, and rotation
* @return true if the actor exists and pos has been filled
*/
@Override
public boolean getPosition(PhysicsShipPosition pos)
{
Actor actor = getActor();
if (actor == null)
{
pos.unset();
return false; // deleted
}
else
{
pos.set = true;
pos.x = actor.pos.pos.x;
pos.y = actor.pos.pos.y;
pos.x_vel = actor.pos.vel.x;
pos.y_vel = actor.pos.vel.y;
pos.rot = actor.rot.points;
pos.rot_snapped = actor.rot.snapped;
return true;
}
}
/** Gets the historic position and rotation for the actor.
* @param pos The object to fill with position and rotation
* @param tick
* @param lookAtOtherStates
* @return true if the actor exists and pos has been filled
*/
@Override
public boolean getHistoricPosition(PhysicsShipPosition pos, long tick, boolean lookAtOtherStates)
{
Actor actor = getActor();
if (actor == null)
{
pos.unset();
return false; // deleted
}
return actor.getHistoricPosition(pos, tick, lookAtOtherStates);
}
@Override
public PhysicsMoveable getHistoricMovement(long tick, boolean lookAtOtherStates)
{
Actor actor = getActor();
if (actor == null)
{
return null; // deleted
}
return actor.getHistoricMovement(tick, lookAtOtherStates);
}
@Override
public boolean canFireWeapon(WEAPON_SLOT weapon)
{
Actor actor = getActor();
if (actor == null)
{
return false;
}
else
{
return actor.canFireWeapon(weapon, state.tick_now);
}
}
@Override
public int getRadius()
{
Actor actor = getActor();
if (actor == null)
{
return 0;
}
else
{
return actor.radius.get();
}
}
@Override
public void findSpawnPoint(PhysicsPoint result, long tick)
{
Actor actor = getActor();
if (actor == null)
{
result.unset();
}
else
{
actor.findSpawnPoint(result, tick);
}
}
@Override
public int randomRotation(long tick)
{
Actor actor = getActor();
if (actor == null)
{
return 0;
}
else
{
return actor.randomRotation(tick);
}
}
@Override
public GCString getWeaponKey(WEAPON_SLOT slot)
{
Actor actor = getActor();
if (actor == null)
{
return null;
}
else
{
return actor.config.weaponSlots[slot.id].weaponKey;
}
}
@Override
public GCInteger getActorConfigInteger(String name)
{
Actor actor = getActor();
if (actor == null)
{
return null;
}
return actor.config.selection.getInteger(name);
}
@Override
public GCString getActorConfigString(String name)
{
Actor actor = getActor();
if (actor == null)
{
return null;
}
return actor.config.selection.getString(name);
}
@Override
public GCBoolean getActorConfigBoolean(String name)
{
Actor actor = getActor();
if (actor == null)
{
return null;
}
return actor.config.selection.getBoolean(name);
}
@Override
public GCIntegerList getActorConfigIntegerList(String name)
{
Actor actor = getActor();
if (actor == null)
{
return null;
}
return actor.config.selection.getIntegerList(name);
}
@Override
public GCStringList getActorConfigStringList(String name)
{
Actor actor = getActor();
if (actor == null)
{
return null;
}
return actor.config.selection.getStringList(name);
}
@Override
public GCBooleanList getActorConfigBooleanList(String name)
{
Actor actor = getActor();
if (actor == null)
{
return null;
}
return actor.config.selection.getBooleanList(name);
}
@Override
public GCImage getActorConfigImage(String name, ResourceDB db)
{
Actor actor = getActor();
if (actor == null)
{
return null;
}
return actor.config.selection.getImage(name, db);
}
@Override
public GCColour getActorConfigColour(String name)
{
Actor actor = getActor();
if (actor == null)
{
return null;
}
return actor.config.selection.getColour(name);
}
private ConfigSelection getWeaponSelection(String weaponKey)
{
Actor actor = getActor();
if (actor == null)
{
return null;
}
return actor.config.getWeaponConfig(weaponKey).selection;
}
@Override
public GCInteger getActorConfigInteger(String weaponKey, String name)
{
ConfigSelection sel = getWeaponSelection(weaponKey);
if (sel == null)
{
return null;
}
return sel.getInteger(name);
}
@Override
public GCString getActorConfigString(String weaponKey, String name)
{
ConfigSelection sel = getWeaponSelection(weaponKey);
if (sel == null)
{
return null;
}
return sel.getString(name);
}
@Override
public GCBoolean getActorConfigBoolean(String weaponKey, String name)
{
ConfigSelection sel = getWeaponSelection(weaponKey);
if (sel == null)
{
return null;
}
return sel.getBoolean(name);
}
@Override
public GCIntegerList getActorConfigIntegerList(String weaponKey, String name)
{
ConfigSelection sel = getWeaponSelection(weaponKey);
if (sel == null)
{
return null;
}
return sel.getIntegerList(name);
}
@Override
public GCStringList getActorConfigStringList(String weaponKey, String name)
{
ConfigSelection sel = getWeaponSelection(weaponKey);
if (sel == null)
{
return null;
}
return sel.getStringList(name);
}
@Override
public GCBooleanList getActorConfigBooleanList(String weaponKey, String name)
{
ConfigSelection sel = getWeaponSelection(weaponKey);
if (sel == null)
{
return null;
}
return sel.getBooleanList(name);
}
@Override
public GCImage getActorConfigImage(String weaponKey, String name, ResourceDB db)
{
ConfigSelection sel = getWeaponSelection(weaponKey);
if (sel == null)
{
return null;
}
return sel.getImage(name, db);
}
@Override
public GCColour getActorConfigColour(String weaponKey, String name)
{
ConfigSelection sel = getWeaponSelection(weaponKey);
if (sel == null)
{
return null;
}
return sel.getColour(name);
}
@Override
public int getEnergy()
{
Actor actor = getActor();
if (actor == null)
{
return 0;
}
else
{
return actor.energy.get(state.tick_now);
}
}
@Override
public int getEnergy(long tick)
{
Actor actor = getActor();
if (actor == null)
{
return 0;
}
else
{
return actor.energy.get(tick);
}
}
@Override
public boolean isDead()
{
Actor actor = getActor();
if (actor == null)
{
return false;
}
return actor.isDead(state.tick_now);
}
@Override
public boolean isDead(long tick)
{
Actor actor = getActor();
if (actor == null)
{
return false;
}
return actor.isDead(tick);
}
@Override
public long getSeed()
{
Actor actor = getActor();
if (actor == null)
{
return 0;
}
else
{
return actor.seed;
}
}
@Override
public long getSpawnAt()
{
Actor actor = getActor();
if (actor == null)
{
return 0;
}
else
{
return actor.spawnAt_tick;
}
}
@Override
public String getShip()
{
Actor actor = getActor();
if (actor == null)
{
return null;
}
else
{
return actor.ship;
}
}
@Override
public boolean canChangeShip()
{
Actor actor = getActor();
if (actor == null)
{
return false;
}
else
{
if (actor.isNonExistent(state.tick_now) || actor.isDead(state.tick_now))
{
return false;
}
if (actor.energy.get(state.tick_now) < actor.getMaxEnergy())
{
return false;
}
return true;
}
}
@Override
public boolean canBoost()
{
Actor actor = getActor();
if (actor == null)
{
return false;
}
if (actor.isNonExistent(state.tick_now) || actor.isDead(state.tick_now))
{
return false;
}
if (actor.energy.get(state.tick_now-1) < actor.config.boostEnergy.get())
{
return false;
}
return true;
}
@Override
public boolean isEmped()
{
Actor actor = getActor();
if (actor == null)
{
return false;
}
if (actor.isNonExistent(state.tick_now) || actor.isDead(state.tick_now))
{
return false;
}
if (actor.empUntil_tick != null && state.tick_now <= actor.empUntil_tick)
{
return true;
}
return false;
}
@Override
public Iterator<ProjectilePublic> projectileIterator()
{
Actor actor = getActor();
if (actor == null)
{
return null;
}
return (Iterator<ProjectilePublic>) (Object) actor.projectiles.iteratorReadOnly();
}
@Override
public boolean getSync(GameOperation.ActorSync.Builder b)
{
Actor actor = getActor();
if (actor == null)
{
return false;
}
actor.getSync(b);
return true;
}
@Override
public long getCreatedAt()
{
Actor actor = getActor();
if (actor == null)
{
return 0;
}
return actor.createdAt_tick;
}
}