package com.lyndir.omicron.api; import static com.lyndir.omicron.api.Security.*; import com.lyndir.omicron.api.error.NotAuthenticatedException; import java.util.Optional; import com.google.common.base.*; import com.google.common.collect.*; import com.lyndir.lhunath.opal.system.util.*; import com.lyndir.omicron.api.util.Maybe; import com.lyndir.omicron.api.util.Maybool; import java.util.stream.Stream; import javax.annotation.Nonnull; public class PlayerController extends MetaObject implements IPlayerController { private final Player player; private GameController gameController; PlayerController(@Nonnull final Player player) { this.player = player; } @Override public Player getPlayer() { return player; } void setGameController(final GameController gameController) { Preconditions.checkState( this.gameController == null, "This player has already been added to a game!" ); this.gameController = gameController; // Key-less players immediately set themselves ready to start the game. if (player.isKeyLess()) gameController.setReady( getPlayer() ); } @Override public GameController getGameController() { return Preconditions.checkNotNull( gameController, "This player has not yet been added to a game!" ); } /** * @see #playerObjectsObservable() * @see IGameObject#getLocation() * @see IGameObject#canObserve(GameObservable) */ @Override public Maybool canObserve(@Nonnull final GameObservable observable) throws NotAuthenticatedException { if (observable instanceof GameObject && playerObjectsObservable().anyMatch( object -> object == observable )) return Maybool.yes(); if (observable instanceof Tile && playerObjectsObservable().map( GameObject::getLocation ) .anyMatch( tile -> tile.isPresent() && tile.get() == observable )) return Maybool.yes(); // Observable is not owned by us, check if any of our objects can see it. return playerObjectsObservable().map( gameObject -> gameObject.canObserve( observable ) ) .filter( Maybool::isTrue ) .findFirst() .orElse( Maybool.no() ); } /** * @see #playerObjectsObservable() * @see IGameObject#observableTiles() */ @Nonnull @Override public Stream<? extends ITile> observableTiles() throws NotAuthenticatedException { return playerObjectsObservable().flatMap( IGameObject::observableTiles ); } /** * @see #playerObjectsObservableBy(GameObserver) */ @Override public Stream<GameObject> playerObjectsObservable() throws NotAuthenticatedException { if (isGod() || getPlayer().isCurrentPlayer()) return getPlayer().getObjects().stream(); return playerObjectsObservableBy( currentPlayer() ); } /** * @see GameObserver#canObserve(GameObservable) */ @Override public Stream<GameObject> playerObjectsObservableBy(final GameObserver observer) { return getPlayer().getObjects().stream().filter( gameObject -> observer.canObserve( gameObject ).isTrue() ); } @Override public Maybe<GameObject> getObject(final int objectId) throws NotAuthenticatedException { Optional<GameObject> object = getPlayer().getObject( objectId ); if (isGod() || getPlayer().isCurrentPlayer()) if (object.isPresent()) return Maybe.of( object.get() ); else return Maybe.empty(); if (object.isPresent()) if (currentPlayer().canObserve( object.get() ).isTrue()) return Maybe.of( object.get() ); else return Maybe.unknown(); return Maybe.unknown(); } void removeObject(final IGameObject gameObject) { getPlayer().removeObject( gameObject ); } protected void onReset() { for (final GameObject gameObject : ImmutableList.copyOf( getPlayer().getObjects() )) gameObject.getController().onReset(); } protected void onNewTurn() { for (final GameObject gameObject : ImmutableList.copyOf( getPlayer().getObjects() )) gameObject.getController().onNewTurn(); if (getPlayer().isKeyLess()) gameController.setReady( getPlayer() ); } void fireReset() { onReset(); } void fireNewTurn() { onNewTurn(); } }