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

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.ntlab.radishforandroidstudio.framework.model3D.Position3D;
import org.ntlab.radishforandroidstudio.framework.model3D.Quaternion3D;

import cactusServer.models.Instances;
import cactusServer.utils.RandomStringGenerator;
import net.arnx.jsonic.JSONHint;

public class Character extends Entity {
	private String accountURI;
	private String areaURI;
	private String name;
	private Position3D position;
	private Quaternion3D angle;
	private String modelID;

	private HashMap<String, Item> itemMap = new HashMap<>();
	@JSONHint(ignore = true)
	public static final int UNIQUE_ID_LENGTH = 12;

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

	public Character(String instanceId, String accountURI, String name, Position3D position, Quaternion3D angle,
			String modelID) {
		setAccountURI(accountURI);
		setName(name);
		setPosition(position);
		setAngle(angle);
		setModelID(modelID);
		initAreaURI(instanceId);
	}

	public String getAccountURI() {
		return accountURI;
	}

	public String getName() {
		return name;
	}

	public Position3D getPosition() {
		return position;
	}

	public Quaternion3D getAngle() {
		return angle;
	}

	public String getModelID() {
		return modelID;
	}

	public String getAreaURI() {
		return areaURI;
	}

	@JSONHint(ignore = true)
	public Item getItem(String itemId) {
		return itemMap.get(itemId);
	}

	@JSONHint(ignore = true)
	public List<Item> getItems() {
		return new ArrayList<Item>(itemMap.values());
	}

	public void setAccountURI(String accountURI) {
		this.accountURI = accountURI;
	}

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

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

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

	public void setModelID(String modelID) {
		this.modelID = modelID;
	}

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

	public AddressedEntity createItem(String name, int amount) {
		Item item = new Item(name, amount);
		if (!hasItem(item)) {
			String id = RandomStringGenerator.generateUniqueString(Item.UNIQUE_ID_LENGTH,
					RandomStringGenerator.ALPHA_NUMERIC, itemMap.keySet());
			itemMap.put(id, item);
			return new IDAddressedEntity(id, item);
		}
		return null;
	}

	public boolean hasItem(Item item) {
		for (Item value : itemMap.values()) {
			if (value.equals(item)) {
				return true;
			}
		}
		return false;
	}

	public Item changeAmountOfItem(String itemId, int amountOfChange) {
		Item item = itemMap.get(itemId).changeAmount(amountOfChange);
		if (item.isEmpty()) {
			destroyItem(itemId);
		}
		return item;
	}

	private void initAreaURI(String instanceId) {
		Instance instance = Instances.getInstance().getInstance(instanceId);
		setAreaURI(findAreaURI(instance));
	}

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

	public void update(Position3D position, Quaternion3D angle, String modelID, String areaURI) {
		setPosition(position);
		setAngle(angle);
		if (modelID != null) {
			setModelID(modelID);
		}
		if (areaURI != null) {
			setAreaURI(areaURI);
		} else {
			updateAreaURI();
		}
	}

	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));
		}
	}

	public Item destroyItem(String itemId) {
		return itemMap.remove(itemId);
	}
}