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

import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;

import org.ntlab.radishforandroidstudio.framework.model3D.BaseObject3D;
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.framework.model3D.Universe;
import org.ntlab.radishforandroidstudio.framework.physics.AngularVelocity3D;
import org.ntlab.radishforandroidstudio.framework.physics.Ground;
import org.ntlab.radishforandroidstudio.framework.physics.Velocity3D;
import org.ntlab.radishforandroidstudio.java3d.Appearance;
import org.ntlab.radishforandroidstudio.java3d.IndexedTriangleArray;
import org.ntlab.radishforandroidstudio.java3d.Material;
import org.ntlab.radishforandroidstudio.java3d.Point3d;
import org.ntlab.radishforandroidstudio.java3d.Vector3f;

import cactusServer.entities.Entity;
import cactusServer.entities.MovableObject;
import cactusServer.entities.Area.Allowed;
import cactusServer.entities.MovableObject.Attribute;
import cactusServer.models.StageModelManager;
import cactusServer.utils.RandomStringGenerator;
import cactusServer.entities.Character;
import net.arnx.jsonic.JSONHint;

/**
 * インスタンス
 * 
 * @author r-isitani
 *
 */
public class Instance extends Entity {
	private String name;
	private State state;
	private int stageID;

	private Universe universe;
	private Ground stage;
	private HashMap<String, Area> areaMap = new HashMap<>();
	private HashMap<String, MovableObject> objMap = new HashMap<>();
	private HashMap<String, Character> characterMap = new HashMap<>();
	private HashMap<String, HashMap<String, Bullet>> bulletMap = new HashMap<>();
	@JSONHint(ignore = true)
	public static final int UNIQUE_ID_LENGTH = 12;

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

	public Instance(String name, int stageID) {
		setName(name);
		setState(Instance.State.AVAILABLE);
		setStageID(stageID);
		initUniverse();
	}

	private void initUniverse() {
		universe = new Universe();
		/*
		// ステージの3Dデータを読み込み配置する
		Object3D stageObj = StageModelManager.getInstance().getStage(stageID).createObject();
		stage = new Ground(stageObj);
		universe.place(stage);
		*/
		
		
		IndexedTriangleArray groundGeometry = new IndexedTriangleArray(4,
                IndexedTriangleArray.COORDINATES | IndexedTriangleArray.NORMALS, 6);
        groundGeometry.setCoordinate(0, new Point3d(-20.0, -1.0, -20.0));
        groundGeometry.setCoordinate(1, new Point3d(20.0, -1.0, -20.0));
        groundGeometry.setCoordinate(2, new Point3d(20.0, -1.0, 20.0));
        groundGeometry.setCoordinate(3, new Point3d(-20.0, -1.0, 20.0));
        groundGeometry.setNormal(0, new Vector3f(0.0f, 1.0f, 0.0f));
        groundGeometry.setNormal(1, new Vector3f(0.0f, 1.0f, 0.0f));
        groundGeometry.setNormal(2, new Vector3f(0.0f, 1.0f, 0.0f));
        groundGeometry.setNormal(3, new Vector3f(0.0f, 1.0f, 0.0f));
        groundGeometry.setCoordinateIndices(0, new int[]{0, 3, 2});
        groundGeometry.setCoordinateIndices(3, new int[]{0, 2, 1});
        Appearance ap2 = new Appearance();
        Material m2 = new Material();
        m2.setDiffuseColor(0.5f, 1.0f, 0.2f);
        ap2.setMaterial(m2);
        Ground ground = new Ground(new BaseObject3D(groundGeometry, ap2));
        universe.place(ground);
        
	}

	public String getName() {
		return name;
	}

	public State getState() {
		return state;
	}

	public int getStageID() {
		return stageID;
	}

	@JSONHint(ignore = true)
	public Universe getUniverse() {
		return universe;
	}

	@JSONHint(ignore = true)
	public HashMap<String, Area> getAreas() {
		return areaMap;
	}

	public Area getArea(String areaId) {
		return areaMap.get(areaId);
	}

	@JSONHint(ignore = true)
	public HashMap<String, MovableObject> getObjects() {
		return objMap;
	}

	public MovableObject getObject(String objId) {
		return objMap.get(objId);
	}

	@JSONHint(ignore = true)
	public HashMap<String, Character> getCharacters() {
		return characterMap;
	}

	public HashMap<String, Character> getCharacters(String accountID) {
		if (accountID == null || accountID.isEmpty()) {
			return getCharacters();
		}
		HashMap<String, Character> returnedMap = new HashMap<>();
		for (String id : characterMap.keySet()) {
			Character character = characterMap.get(id);
			String[] splitedAccountURI = character.getAccountURI().split("/");
			if (splitedAccountURI[splitedAccountURI.length - 1].equals(accountID)) {
				returnedMap.put(id, character);
			}
		}
		return returnedMap;
	}

	public Character getCharacter(String characterId) {
		return characterMap.get(characterId);
	}

	@JSONHint(ignore = true)
	public HashMap<String, HashMap<String, Bullet>> getBullets() {
		return bulletMap;
	}

	public void setName(String name) {
		this.name = name;
	}

	public void setState(State state) {
		this.state = state;
	}

	public void setStageID(int stageURI) {
		this.stageID = stageURI;
	}

	public HashMap<String, Area> createArea(String name, Plain[] region, HashSet<Allowed> permissions) {
		String id = RandomStringGenerator.generateUniqueString(Area.UNIQUE_ID_LENGTH,
				RandomStringGenerator.ALPHA_NUMERIC, areaMap.keySet());
		Area area = new Area(name, region, permissions);
		areaMap.put(id, area);
		HashMap<String, Area> returnedMap = new HashMap<>();
		returnedMap.put(id, area);
		return returnedMap;
	}

	public HashMap<String, MovableObject> createObject(Position3D position, Velocity3D velocity,
			AngularVelocity3D angularVelocity, Quaternion3D angle, Attribute attribute, int modelID) {
		String id = RandomStringGenerator.generateUniqueString(MovableObject.UNIQUE_ID_LENGTH,
				RandomStringGenerator.ALPHA_NUMERIC, objMap.keySet());
		MovableObject object = new MovableObject(position, velocity, angularVelocity, angle, attribute, modelID);
		objMap.put(id, object);
		universe.place(object.getPlaceable());
		HashMap<String, MovableObject> returnedMap = new HashMap<>();
		returnedMap.put(id, object);
		return returnedMap;
	}

	public HashMap<String, Character> createCharacter(String instanceId, String accountURI, String name,
			Position3D position, Quaternion3D angle, int modelID) {
		String id = RandomStringGenerator.generateUniqueString(Character.UNIQUE_ID_LENGTH,
				RandomStringGenerator.ALPHA_NUMERIC, characterMap.keySet());
		Character character = new Character(instanceId, accountURI, name, position, angle, modelID);
		characterMap.put(id, character);
		HashMap<String, Character> returnedMap = new HashMap<>();
		returnedMap.put(id, character);
		return returnedMap;
	}

	public HashMap<String, Bullet> createBullet(String playerID, String bulletID, Position3D position,
			Quaternion3D angle) {
		if (!bulletMap.containsKey(playerID)) {
			bulletMap.put(playerID, new HashMap<String, Bullet>());
		}
		HashMap<String, Bullet> map = bulletMap.get(playerID);
		Bullet bullet = new Bullet(playerID, position, angle);
		map.put(bulletID, bullet);
		universe.place(bullet.getPlaceable());
		return map;
	}

	public Instance update(Instance.State state) {
		setState(state);
		return this;
	}

	public Character updateCharacter(String characterId, Position3D position, Quaternion3D angle, int modelID) {
		Character character = characterMap.get(characterId);
		if (character != null) {
			character.update(position, angle, modelID);
		}
		return character;
	}

	public Bullet updateBullet(String playerId, String bulletId, Position3D position, Quaternion3D angle) {
		HashMap<String, Bullet> map = bulletMap.get(playerId);
		if (map != null) {
			Bullet bullet = map.get(bulletId);
			if (bullet != null) {
				bullet.update(position, angle);
			}
			return bullet;
		}
		return null;
	}

	public Character destroyCharacter(String characterId) {
		return characterMap.remove(characterId);
	}

	public Area destroyArea(String areaId) {
		return areaMap.remove(areaId);
	}

	public MovableObject destroyObject(String objId) {
		return objMap.remove(objId);
	}

	public Bullet destroyBullet(String playerId, String bulletId) {
		HashMap<String, Bullet> map = bulletMap.get(playerId);
		if (map != null) {
			Bullet removedBullet = map.remove(bulletId);
			universe.displace(removedBullet.getPlaceable());
			return removedBullet;
		}
		return null;
	}
	
	public void removeDeadBullets() {
		Iterator<HashMap<String, Bullet>> playersBulletsIt = bulletMap.values().iterator();
		while (playersBulletsIt.hasNext()) {
			Map<String, Bullet> playersBullets = playersBulletsIt.next();
			Iterator<Map.Entry<String, Bullet>> bulletEntryIt = playersBullets.entrySet().iterator();
			while (bulletEntryIt.hasNext()) {
				Map.Entry<String, Bullet> bulletEntry = bulletEntryIt.next();
				Bullet bullet = bulletEntry.getValue();
				if (!bullet.isAlive()) {
					String bulletId = bulletEntry.getKey();
					bulletEntryIt.remove();
					universe.displace(bullet.getPlaceable());
					System.out.println(bulletId + "削除");
				}
			}
		}
	}

	public static enum State {
		AVAILABLE, MAINTENANCE;
	}
}