📄 l1world.java
字号:
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* http://www.gnu.org/copyleft/gpl.html
*/
package l1j.server.server.model;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.logging.Logger;
import l1j.server.Config;
import l1j.server.server.model.Instance.L1NpcInstance;
import l1j.server.server.model.Instance.L1PcInstance;
import l1j.server.server.model.Instance.L1PetInstance;
import l1j.server.server.model.Instance.L1SummonInstance;
import l1j.server.server.model.map.L1Map;
import l1j.server.server.serverpackets.S_SystemMessage;
import l1j.server.server.serverpackets.ServerBasePacket;
import l1j.server.server.templates.L1Npc;
import l1j.server.server.types.Point;
public class L1World {
private static l1j.eric.EricLogger _log = l1j.eric.EricLogger.getLogger2(L1World.class.getName());
private final ConcurrentHashMap<String, L1PcInstance> _allPlayers;
private final ConcurrentHashMap<Integer, L1PetInstance> _allPets;
private final ConcurrentHashMap<Integer, L1SummonInstance> _allSummons;
private final ConcurrentHashMap<Integer, L1Object> _allObjects;
private final ConcurrentHashMap<Integer, L1Object>[] _visibleObjects;
private final CopyOnWriteArrayList<L1War> _allWars;
private final ConcurrentHashMap<String, L1Clan> _allClans;
private int _weather = 4;
private boolean _worldChatEnabled = true;
private boolean _processingContributionTotal = false;
private static final int MAX_MAP_ID = 8105;
private static L1World _instance;
private L1World() {
_allPlayers = new ConcurrentHashMap<String, L1PcInstance>(); // 全てのプレイヤー
_allPets = new ConcurrentHashMap<Integer, L1PetInstance>(); // 全てのペット
_allSummons = new ConcurrentHashMap<Integer, L1SummonInstance>(); // 全てのサモンモンスター
_allObjects = new ConcurrentHashMap<Integer, L1Object>(); // 全てのオブジェクト(L1ItemInstance入り、L1Inventoryはなし)
_visibleObjects = new ConcurrentHashMap[MAX_MAP_ID + 1]; // マップ毎のオブジェクト(L1Inventory入り、L1ItemInstanceはなし)
_allWars = new CopyOnWriteArrayList<L1War>(); // 全ての戦争
_allClans = new ConcurrentHashMap<String, L1Clan>(); // 全てのクラン(Online/Offlineどちらも)
for (int i = 0; i <= MAX_MAP_ID; i++) {
_visibleObjects[i] = new ConcurrentHashMap<Integer, L1Object>();
}
}
public static L1World getInstance() {
if (_instance == null) {
_instance = new L1World();
}
return _instance;
}
/**
* 全ての状態をクリアする。<br>
* デバッグ、テストなどの特殊な目的以外で呼び出してはならない。
*/
public void clear() {
_instance = new L1World();
}
public void storeObject(L1Object object) {
if (object == null) {
throw new NullPointerException();
}
_allObjects.put(object.getId(), object);
if (object instanceof L1PcInstance) {
_allPlayers.put(((L1PcInstance) object).getName(),
(L1PcInstance) object);
}
if (object instanceof L1PetInstance) {
_allPets.put(object.getId(), (L1PetInstance) object);
}
if (object instanceof L1SummonInstance) {
_allSummons.put(object.getId(), (L1SummonInstance) object);
}
}
public void removeObject(L1Object object) {
if (object == null) {
throw new NullPointerException();
}
_allObjects.remove(object.getId());
if (object instanceof L1PcInstance) {
_allPlayers.remove(((L1PcInstance) object).getName());
}
if (object instanceof L1PetInstance) {
_allPets.remove(object.getId());
}
if (object instanceof L1SummonInstance) {
_allSummons.remove(object.getId());
}
}
public L1Object findObject(int oID) {
return _allObjects.get(oID);
}
// _allObjectsのビュー
private Collection<L1Object> _allValues;
public Collection<L1Object> getObject() {
Collection<L1Object> vs = _allValues;
return (vs != null) ? vs : (_allValues = Collections
.unmodifiableCollection(_allObjects.values()));
}
//新增商店捲軸 by eric1300460
public int getObjId(L1Npc npc) {
for(L1Object obj : _allObjects.values()){
if ((obj instanceof L1NpcInstance)
&& ((L1NpcInstance)obj).getNpcTemplate().get_npcId()==npc.get_npcId()) {
return obj.getId();
}
}
return 0;
}
//~新增商店捲軸 by eric1300460
public L1GroundInventory getInventory(int x, int y, short map) {
int inventoryKey = ((x - 30000) * 10000 + (y - 30000)) * -1; // xyのマイナス値をインベントリキーとして使用
Object object = _visibleObjects[map].get(inventoryKey);
if (object == null) {
return new L1GroundInventory(inventoryKey, x, y, map);
} else {
return (L1GroundInventory) object;
}
}
public L1GroundInventory getInventory(L1Location loc) {
return getInventory(loc.getX(), loc.getY(), (short) loc.getMap()
.getId());
}
public void addVisibleObject(L1Object object) {
if (object.getMapId() <= MAX_MAP_ID) {
_visibleObjects[object.getMapId()].put(object.getId(), object);
}
}
public void removeVisibleObject(L1Object object) {
if (object.getMapId() <= MAX_MAP_ID) {
_visibleObjects[object.getMapId()].remove(object.getId());
}
}
public void moveVisibleObject(L1Object object, int newMap) // set_Mapで新しいMapにするまえに呼ぶこと
{
if (object.getMapId() != newMap) {
if (object.getMapId() <= MAX_MAP_ID) {
_visibleObjects[object.getMapId()].remove(object.getId());
}
if (newMap <= MAX_MAP_ID) {
_visibleObjects[newMap].put(object.getId(), object);
}
}
}
private ConcurrentHashMap<Integer, Integer> createLineMap(Point src,
Point target) {
ConcurrentHashMap<Integer, Integer> lineMap = new ConcurrentHashMap<Integer, Integer>();
/*
* http://www2.starcat.ne.jp/~fussy/algo/algo1-1.htmより
*/
int E;
int x;
int y;
int key;
int i;
int x0 = src.getX();
int y0 = src.getY();
int x1 = target.getX();
int y1 = target.getY();
int sx = (x1 > x0) ? 1 : -1;
int dx = (x1 > x0) ? x1 - x0 : x0 - x1;
int sy = (y1 > y0) ? 1 : -1;
int dy = (y1 > y0) ? y1 - y0 : y0 - y1;
x = x0;
y = y0;
/* 傾きが1以下の場合 */
if (dx >= dy) {
E = -dx;
for (i = 0; i <= dx; i++) {
key = (x << 16) + y;
lineMap.put(key, key);
x += sx;
E += 2 * dy;
if (E >= 0) {
y += sy;
E -= 2 * dx;
}
}
/* 傾きが1より大きい場合 */
} else {
E = -dy;
for (i = 0; i <= dy; i++) {
key = (x << 16) + y;
lineMap.put(key, key);
y += sy;
E += 2 * dx;
if (E >= 0) {
x += sx;
E -= 2 * dy;
}
}
}
return lineMap;
}
public ArrayList<L1Object> getVisibleLineObjects(L1Object src,
L1Object target) {
ConcurrentHashMap<Integer, Integer> lineMap = createLineMap(src
.getLocation(), target.getLocation());
int map = target.getMapId();
ArrayList<L1Object> result = new ArrayList<L1Object>();
if (map <= MAX_MAP_ID) {
for (L1Object element : _visibleObjects[map].values()) {
if (element.equals(src)) {
continue;
}
int key = (element.getX() << 16) + element.getY();
if (lineMap.containsKey(key)) {
result.add(element);
}
}
}
return result;
}
public ArrayList<L1Object> getVisibleBoxObjects(L1Object object,
int heading, int width, int height) {
int x = object.getX();
int y = object.getY();
int map = object.getMapId();
L1Location location = object.getLocation();
ArrayList<L1Object> result = new ArrayList<L1Object>();
int headingRotate[] = { 6, 7, 0, 1, 2, 3, 4, 5 };
double cosSita = Math.cos(headingRotate[heading] * Math.PI / 4);
double sinSita = Math.sin(headingRotate[heading] * Math.PI / 4);
if (map <= MAX_MAP_ID) {
for (L1Object element : _visibleObjects[map].values()) {
if (element.equals(object)) {
continue;
}
if (map != element.getMapId()) {
continue;
}
// 同じ座標に重なっている場合は範囲内とする
if (location.isSamePoint(element.getLocation())) {
result.add(element);
continue;
}
int distance = location.getTileLineDistance(element
.getLocation());
// 直線距離が高さ、幅どちらよりも大きい場合、計算するまでもなく範囲外
if (distance > height && distance > width) {
continue;
}
// objectの位置を原点とするための座標補正
int x1 = element.getX() - x;
int y1 = element.getY() - y;
// Z軸回転させ角度を0度にする。
int rotX = (int) Math.round(x1 * cosSita + y1 * sinSita);
int rotY = (int) Math.round(-x1 * sinSita + y1 * cosSita);
int xmin = 0;
int xmax = height;
int ymin = -width;
int ymax = width;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -