package org.ntlab.SproutServer.battles;
import framework.model3D.Placeable;
import framework.model3D.Position3D;
import framework.physics.PhysicsUtility;
import framework.physics.Velocity3D;
import net.arnx.jsonic.JSONHint;
import org.ntlab.SproutServer.rooms.Member;
import org.ntlab.SproutServer.rooms.Room;
import javax.vecmath.Vector3d;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
* チーム
*
* @author matsumoto_k
*/
public class Team {
private HashMap<Integer, Player> playerMap = new HashMap<>(); // チームのプレイヤー情報
private HashMap<Integer, Bullet> bullets = new HashMap<>(); // チームの弾の情報
private HashMap<Integer, Magic> magics = new HashMap<>(); // チームの魔法の情報
private int bulletId = 0; // 弾を判別するID
private int magicId = 0;
private boolean result; // 勝敗
public Team(Room room) {
playerMap = new HashMap<>();
for (Member member : room.getMemberList().values()) {
/**
* e.getKey : userId
*/
playerMap.put(member.getUserId(), new Player(member.getUserId(), member.getMemberId()));
}
}
public HashMap<Integer, Player> getPlayerMap() {
return playerMap;
}
public void setPlayerMap(HashMap<Integer, Player> playerMap) {
this.playerMap = playerMap;
}
public boolean isResult() {
return result;
}
public void setResult(boolean result) {
this.result = result;
}
public HashMap<Integer, Bullet> getBullets() {
return bullets;
}
public HashMap<Integer, Magic> getMagics() {
return magics;
}
/**
* userIdによってプレイヤーを取得
*
* @param userId 取得するプレイヤーのuserId
* @return プレイヤー
*/
public Player findPlayerById(int userId) {
return playerMap.get(userId);
}
/**
* チーム内の生存者の数を取得する
*
* @return 生存者の数
*/
@JSONHint(ignore = true)
public int getAliveCount() {
int count = 0;
for (Player player : playerMap.values()) {
if (player.isAlive())
count++;
}
return count;
}
/**
* チーム内のプレイヤーが全員死亡しているか取得
*
* @return 全員死亡している:true, 一人でも生きている:false
*/
@JSONHint(ignore = true)
public boolean isAllPlayerDead() {
if (getAliveCount() == 0)
return true;
return false;
}
/**
* 自クラスの武器と他のチームのプレイヤーの衝突したオブジェクトを取得する
*
* @param enemyTeam 判定させるチーム
* @return colliedObjects 衝突したオブジェクト
*/
public ArrayList<Placeable> getColliedObjects(Team enemyTeam) {
ArrayList<Placeable> colliedObjects = new ArrayList<>();
/* 弾 */
for (Iterator<Bullet> bulletIterator = bullets.values().iterator(); bulletIterator.hasNext(); ) {
Bullet bullet = bulletIterator.next();
if (!bullet.isAlive()) {
colliedObjects.add(bullet.getActor());
bulletIterator.remove();
continue;
}
for (Player player : enemyTeam.getPlayerMap().values()) {
/* 自チームの弾と他のチームのプレイヤーが衝突した時 */
if (checkCollision(bullet, player)) {
/* 他のチームのプレイヤーにダメージを与える */
player.setDamage(bullet.getAttack());
/* 弾は取り除く */
colliedObjects.add(bullet.getActor());
bulletIterator.remove();
}
}
}
/* 魔法 */
for (Iterator<Magic> magicIterator = magics.values().iterator(); magicIterator.hasNext(); ) {
Magic magic = magicIterator.next();
if (!magic.isAlive()) {
colliedObjects.add(magic.getActor());
magicIterator.remove();
continue;
}
for (Player player : enemyTeam.getPlayerMap().values()) {
/* 自チームの弾と他のチームのプレイヤーが衝突した時 */
if (checkCollision(magic, player)) {
/* 他のチームのプレイヤーにダメージを与える */
player.setDamage(magic.getAttack());
/* 弾は取り除く */
colliedObjects.add(magic.getActor());
magicIterator.remove();
}
}
}
return colliedObjects;
}
/**
* 自クラスの武器と他のチームのプレイヤーの衝突したオブジェクトを取得する
*
* @param enemyPlayer 敵プレイヤー
* @return 衝突したオブジェクト
*/
public ArrayList<Placeable> getColliedObjects(Player enemyPlayer) {
ArrayList<Placeable> obj = new ArrayList<>();
/* 弾 */
for (Iterator<Bullet> bulletIterator = bullets.values().iterator(); bulletIterator.hasNext(); ) {
Bullet bullet = bulletIterator.next();
if (!bullet.isAlive()) {
obj.add(bullet.getActor());
bulletIterator.remove();
continue;
}
if (checkCollision(bullet, enemyPlayer)) {
/* 他のチームのプレイヤーにダメージを与える */
enemyPlayer.setDamage(bullet.getAttack());
/* 弾は取り除く */
obj.add(bullet.getActor());
bulletIterator.remove();
}
}
/* 魔法 */
for (Iterator<Magic> magicIterator = magics.values().iterator(); magicIterator.hasNext(); ) {
Magic magic = magicIterator.next();
if (!magic.isAlive()) {
obj.add(magic.getActor());
magicIterator.remove();
continue;
}
if (checkCollision(magic, enemyPlayer)) {
/* 他のチームのプレイヤーにダメージを与える */
enemyPlayer.setDamage(magic.getAttack());
/* 弾は取り除く */
obj.add(magic.getActor());
magicIterator.remove();
}
}
return obj;
}
/**
* プレイヤーと武器の衝突判定
*
* @param weapon
* @param player 他のチームのプレイヤー
* @return
*/
public boolean checkCollision(Weapon weapon, Player player) {
return PhysicsUtility.checkCollision(weapon.getBody(), null, player.getBody(), null) != null;
}
/**
* チーム内のプレイヤーとの衝突判定
*
* @param player 判定するプレイヤー
* @param playerId 判定するプレイヤーid
* @return 衝突している時はtrue, していない時はfalse
*/
public boolean checkCollision(Player player, int playerId) {
for (Map.Entry<Integer, Player> entry : playerMap.entrySet()) {
/* idがplayerと違う時 */
if (entry.getKey() != playerId) {
if (player.checkCollision(entry.getValue()))
return true;
}
}
return false;
}
/**
* プレイヤーの弾を作成する
*
* @param position3D 弾の位置
* @param vector3d 弾の向き
* @param velocity3D 弾の速度
* @return
*/
public Bullet createBullet(Position3D position3D, Vector3d vector3d, Velocity3D velocity3D) {
Bullet bullet = new Bullet(position3D, vector3d, velocity3D);
bullets.put(bulletId, bullet);
bulletId++;
return bullet;
}
/**
* プレイヤーの魔法を作成する
*
* @param position3D 魔法の位置
* @param vector3d 魔法の向き
* @param velocity3D 魔法の速度
* @return
*/
public Magic createMagic(Position3D position3D, Vector3d vector3d, Velocity3D velocity3D) {
Magic magic = new Magic(position3D, vector3d, velocity3D);
magics.put(magicId, magic);
magicId++;
return magic;
}
}