Newer
Older
CactusServer / src / main / java / cactusServer / entities / Player.java
package cactusServer.entities;

import org.ntlab.radishforandroidstudio.framework.gameMain.OvergroundActor;
import org.ntlab.radishforandroidstudio.framework.model3D.Object3D;
import org.ntlab.radishforandroidstudio.framework.model3D.Position3D;
import org.ntlab.radishforandroidstudio.framework.model3D.Quaternion3D;
import org.ntlab.radishforandroidstudio.java3d.Box;
import org.ntlab.radishforandroidstudio.java3d.Primitive;

import cactusServer.models.CharacterModelManager;
import cactusServer.models.Instances;
import net.arnx.jsonic.JSONHint;

public class Player extends Entity3D {
	private String instanceID;
	private String characterID;
	private String areaURI;
	private Object3D object;
	private Position3D position;
	private Quaternion3D angle;
	private CameraState cameraState;
	private EmoteState emoteState;
	private Primitive prim;
	private long lastUpdateTime = System.nanoTime();
	@JSONHint(ignore = true)
	public static final int UNIQUE_ID_LENGTH = 12;
	@JSONHint(ignore = true)
	public static final long STOP_TIME_LIMIT = (long) (30 * 1e+9);

	private Player() {
		// JSONDecode時の呼び出し用
	}

	public Player(String instanceID, String characterID, CameraState cameraState,
			EmoteState.EmoteType animationClassToStart) {
		setInstanceID(instanceID);
		setCharacterID(characterID);
		if (cameraState != null) {
			setCameraState(cameraState);
		} else {
			setCameraState(new CameraState());
		}
		if (animationClassToStart != null) {
			setAnimationClassToStart(animationClassToStart);
		} else {
			setEmoteState(new EmoteState());
		}
		Character character = getCharacter();
		readCharacterData(character);
		initPlaceable(character.getModelID());
	}

	private void initPlaceable(int modelID) {
		// こんな感じで当該コンストラクタの最後でplaceableの注入を行う
		Object3D body = CharacterModelManager.getInstance().getCharacterModel(modelID).createObject();
		setPlaceable(new OvergroundActor(body, null));
		// 所属するInstanceが持つUniverseにplaceableを配置する
		String[] instanceURISplit = instanceID.split("/"); // ……/instances/{instanceId}
		String instanceId = instanceURISplit[instanceURISplit.length - 1];
		Instances.getInstance().getInstance(instanceId).getUniverse().place(this.getPlaceable());
		setObject(body);
	}

	public String getInstanceID() {
		return instanceID;
	}

	public String getCharacterID() {
		return characterID;
	}

	public String getAreaURI() {
		return areaURI;
	}

	public Position3D getPosition() {
		return position;
	}

	public Quaternion3D getAngle() {
		return angle;
	}

	public CameraState getCameraState() {
		return cameraState;
	}

	public EmoteState getEmoteState() {
		return emoteState;
	}

	@JSONHint(ignore = true)
	public long getLastUpdateTime() {
		return lastUpdateTime;
	}

	public void setInstanceID(String instanceID) {
		this.instanceID = instanceID;
	}

	public void setCharacterID(String characterID) {
		if (characterID.startsWith("\"")) {
			characterID = characterID.substring(1);
		}
		if (characterID.endsWith("\"")) {
			characterID = characterID.substring(0, characterID.length() - 1);
		}
		this.characterID = characterID;
	}

	public void setAreaURI(String areaURI) {
		this.areaURI = areaURI;
	}

	public void setPosition(Position3D position) {
		this.position = position;
	}

	public void setAngle(Quaternion3D angle) {
		this.angle = angle;
	}

	public void setCameraState(CameraState cameraState) {
		this.cameraState = cameraState;
	}

	public void setEmoteState(EmoteState emoteState) {
		this.emoteState = emoteState;
	}

	public void setAnimationClassToStart(EmoteState.EmoteType animationClassToStart) {
		setEmoteState(new EmoteState(animationClassToStart));
	}

	@JSONHint(ignore = true)
	public void setLastUpdateTime(long lastUpdateTime) {
		this.lastUpdateTime = lastUpdateTime;
	}

	public Player update(String characterID, Position3D position, Quaternion3D angle, CameraState cameraState,
			EmoteState.EmoteType animationClassToStart, long lastUpdateTime) {
		setPosition(position);
		setAngle(angle);
		if (!this.characterID.equals(characterID)) {
			changeCharacter(characterID);
		}
		setCameraState(cameraState);
		updateEmoteType(animationClassToStart);
		// updateAreaURI();
		setLastUpdateTime(lastUpdateTime);
		return this;
	}

	private void updateAreaURI() {
		String[] areaURISplit = areaURI.split("/"); // ……/instances/{instanceId}/areas/{areaId}
		int splitSize = areaURISplit.length;
		String instanceId = areaURISplit[splitSize - 3];
		String previousAreaId = areaURISplit[splitSize - 1];
		Instance instance = Instances.getInstance().getInstance(instanceId);
		Area previousArea = instance.getArea(previousAreaId);
		if (!previousArea.isSurroundingPosition(position)) {
			// キャラクターのポジションを用いてどのエリア内にいるかを判定して当該エリアのURIに更新する
			setAreaURI(findAreaURI(instance));
		}
	}

	private String findAreaURI(Instance instance) {
		// キャラクターのポジションを用いてどのエリア内にいるかを判定して当該エリアのURIに更新する
		for (String areaId : instance.getAreas().keySet()) {
			Area area = instance.getArea(areaId);
			if (area.isSurroundingPosition(position)) {
				int subStringEndIndex = areaURI.length() - Area.UNIQUE_ID_LENGTH; // …/{instanceId}/areas/ まで
				return areaURI.substring(0, subStringEndIndex) + areaId;
			}
		}
		return "";
	}

	private void updateEmoteType(EmoteState.EmoteType animationClassToStart) {
		emoteState.setEmoteType(animationClassToStart);
	}

	public void changeCharacter(String characterID) {
		writeCharacterData();
		setCharacterID(characterID);
		Character character = getCharacter();
		readCharacterData(character);
		initPlaceable(character.getModelID());
	}

	public void destroy() {
		writeCharacterData();
		Instance instance = Instances.getInstance().getInstance(instanceID);
		instance.getUniverse().displace(this.getPlaceable());
	}

	private Character getCharacter() {
		return Instances.getInstance().getInstance(instanceID).getCharacter(characterID);
	}

	private void readCharacterData(Character character) {
		setPosition(character.getPosition());
		setAngle(character.getAngle());
		setAreaURI(character.getAreaURI());
	}

	// private void readCharacterData() {
	// Character character = getCharacter();
	// readCharacterData(character);
	// }

	private void writeCharacterData() {
		Character character = getCharacter();
		// if (character == null) return;
		character.update(position, angle, areaURI);
	}
	
	@JSONHint(ignore = true)
	public Object3D getObject() {
		return object;
	}

	public void setObject(Object3D object) {
		this.object = object;
	}

}