package cactusServer.models;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.ntlab.radishforandroidstudio.framework.model3D.CollisionResult;
import org.ntlab.radishforandroidstudio.framework.model3D.Object3D;
import org.ntlab.radishforandroidstudio.framework.model3D.Position3D;
import org.ntlab.radishforandroidstudio.framework.physics.PhysicsUtility;
import org.ntlab.radishforandroidstudio.java3d.Vector3d;
import cactusServer.entities.Bullet;
import cactusServer.entities.Instance;
import cactusServer.entities.MovableObject;
import cactusServer.entities.Player;
import net.arnx.jsonic.JSONHint;
public class CollisionManager {
private static CollisionManager theInstance;
private HashMap<String, Instance> instances;
private ArrayList<CollisionResult> resultList;
private CollisionManager() {
instances = Instances.getInstance().getInstances();
resultList = new ArrayList<CollisionResult>();
}
public static CollisionManager getInstance() {
if (theInstance == null) {
theInstance = new CollisionManager();
}
return theInstance;
}
@JSONHint(ignore = true)
public ArrayList<CollisionResult> getResultList() {
return resultList;
}
public void collisionRun(long interval) {
resultList.clear();
for (String instanceId : instances.keySet()) {
Instance instance = Instances.getInstance().getInstance(instanceId);
instance.getUniverse().update(interval);
collisionPlayersObjects(instanceId, instance);
collisionBulletsAndOthers(instanceId, instance);
}
}
public void collisionPlayersObjects(String instanceId, Instance instance) {
for (MovableObject object : instance.getObjects().values()) {
for (Player player : Instances.getInstance().getPlayers(instanceId).values()) {
collisionMove(object, player);
}
for (MovableObject object2 : instance.getObjects().values()) {
if (!object.equals(object2)) {
collisionMove(object, object2);
}
}
}
}
public void collisionMove(MovableObject object, Player player) {
CollisionResult result;
result = PhysicsUtility.checkCollision(player.getObject(), null, object.getObject(), null);
if (result != null) {
objMove(result, object, false);
}
}
public void collisionMove(MovableObject object1, MovableObject object2) {
CollisionResult result;
result = PhysicsUtility.checkCollision(object1.getObject(), null, object2.getObject(), null);
if (result != null) {
Vector3d vec1 = object1.getVelocity().getVector3d();
Vector3d vec2 = object2.getVelocity().getVector3d();
if (vec1.length() > vec2.length()) {
objMove(result, object1, true);
} else {
objMove(result, object2, true);
}
}
}
private void objMove(CollisionResult result, MovableObject object, boolean negate) {
result.normal.scale(-1);
Vector3d vec = object.getPosition().getVector3d();
if (negate)
result.normal.negate();
vec.add(result.normal);
object.setPosition(new Position3D(vec));
}
private void collisionBulletsAndOthers(String instanceId, Instance instance) {
Iterator<Map.Entry<String, HashMap<String, Bullet>>> playersBulletsEntryIt = instance.getBullets().entrySet()
.iterator();
while (playersBulletsEntryIt.hasNext()) {
Map.Entry<String, HashMap<String, Bullet>> playersBulletsEntry = playersBulletsEntryIt.next();
String bulletOwnerPlayerId = playersBulletsEntry.getKey();
Map<String, Bullet> bulletMap = playersBulletsEntry.getValue();
Iterator<Map.Entry<String, Bullet>> bulletEntryIt = bulletMap.entrySet().iterator();
while (bulletEntryIt.hasNext()) {
Map.Entry<String, Bullet> bulletEntry = bulletEntryIt.next();
String bulletId = bulletEntry.getKey();
Bullet bullet = bulletEntry.getValue();
boolean isRemoved = collisionBulletAndPlayers(instanceId, instance, bulletOwnerPlayerId, bulletId,
bullet, bulletEntryIt);
if (!isRemoved) {
collisionBulletAndObjects(instance, bulletOwnerPlayerId, bulletId, bullet, bulletEntryIt);
}
}
}
}
private boolean collisionBulletAndPlayers(String instanceId, Instance instance, String bulletOwnerPlayerId,
String bulletId, Bullet bullet, Iterator<Map.Entry<String, Bullet>> bulletEntryIt) {
Instances instances = Instances.getInstance();
for (Map.Entry<String, Player> playersEntry : instances.getPlayers(instanceId).entrySet()) {
if (isCollision(bullet, playersEntry.getValue())) {
if (!(playersEntry.getKey().equals(bulletOwnerPlayerId))) {
// Player(自分を除く)と弾が当たった時の処理を書く
}
// Player(自分を含む)に当たった弾を消す
bulletEntryIt.remove();
instance.getUniverse().displace(bullet.getPlaceable());
System.out.println(bulletId + "削除");
return true;
}
}
return false;
}
private boolean collisionBulletAndObjects(Instance instance, String bulletOwnerPlayerId, String bulletId,
Bullet bullet, Iterator<Map.Entry<String, Bullet>> bulletEntryIt) {
for (MovableObject object : instance.getObjects().values()) {
if (isCollision(bullet, object)) {
bulletEntryIt.remove();
instance.getUniverse().displace(bullet.getPlaceable());
System.out.println(bulletId + "削除");
return true;
}
}
return false;
}
private boolean isCollision(Bullet bullet, Player player) {
CollisionResult result;
result = PhysicsUtility.checkCollision((Object3D) (bullet.getPlaceable()), null, player.getObject(), null);
return (result != null);
}
private boolean isCollision(Bullet bullet, MovableObject object) {
CollisionResult result;
result = PhysicsUtility.checkCollision((Object3D) (bullet.getPlaceable()), null, object.getObject(), null);
return (result != null);
}
}