mirror of
https://github.com/Rogiel/l2jserver2
synced 2025-12-06 23:42:55 +00:00
Base AI, new Cache system, DAO changes and better geometry handling
Signed-off-by: Rogiel <rogiel@rogiel.com>
This commit is contained in:
@@ -18,7 +18,7 @@ package com.l2jserver;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Module;
|
||||
import com.l2jserver.db.dao.H2DAOModule;
|
||||
import com.l2jserver.db.H2DAOModule;
|
||||
import com.l2jserver.model.id.provider.IDProviderModule;
|
||||
import com.l2jserver.service.ServiceModule;
|
||||
|
||||
|
||||
40
src/main/java/com/l2jserver/Installer.java
Normal file
40
src/main/java/com/l2jserver/Installer.java
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* This file is part of l2jserver <l2jserver.com>.
|
||||
*
|
||||
* l2jserver 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver;
|
||||
|
||||
import com.l2jserver.service.ServiceManager;
|
||||
import com.l2jserver.service.database.DatabaseService;
|
||||
|
||||
/**
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*
|
||||
*/
|
||||
public class Installer {
|
||||
public static void main(String[] args) {
|
||||
final L2JGameServer server = new L2JGameServer();
|
||||
try {
|
||||
final ServiceManager serviceManager = server.getInjector()
|
||||
.getInstance(ServiceManager.class);
|
||||
|
||||
serviceManager.start(DatabaseService.class).install();
|
||||
} catch (Exception e) {
|
||||
System.out.println("GameServer could not be installed!");
|
||||
e.printStackTrace();
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,16 +23,20 @@ package com.l2jserver.game;
|
||||
*/
|
||||
public enum ProtocolVersion {
|
||||
/**
|
||||
* Release version
|
||||
* The Release version, this is acctually a pseudo version. It never really
|
||||
* existed.
|
||||
*/
|
||||
RELEASE(0),
|
||||
|
||||
/**
|
||||
* Freya(216)
|
||||
* The Interlude(200) version
|
||||
*/
|
||||
INTERLUDE(200, RELEASE),
|
||||
/**
|
||||
* The Freya(216) version
|
||||
*/
|
||||
FREYA(216, RELEASE),
|
||||
/**
|
||||
* High5(268)
|
||||
* The High5(268) version
|
||||
*/
|
||||
HIGH5(268, FREYA);
|
||||
|
||||
|
||||
39
src/main/java/com/l2jserver/game/ai/AI.java
Normal file
39
src/main/java/com/l2jserver/game/ai/AI.java
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* This file is part of l2jserver <l2jserver.com>.
|
||||
*
|
||||
* l2jserver 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.game.ai;
|
||||
|
||||
import com.l2jserver.game.ai.desires.Desire;
|
||||
import com.l2jserver.game.ai.desires.DesireQueue;
|
||||
import com.l2jserver.model.world.Actor;
|
||||
|
||||
/**
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
* @param <T>
|
||||
* the {@link Actor} type for this {@link AI}
|
||||
*/
|
||||
public abstract class AI<T extends Actor> {
|
||||
protected DesireQueue desireQueue = new DesireQueue();
|
||||
protected final T creature;
|
||||
|
||||
protected AI(T creature) {
|
||||
this.creature = creature;
|
||||
}
|
||||
|
||||
protected void handleDesire(Desire desire) {
|
||||
desire.handleDesire(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* This file is part of l2jserver <l2jserver.com>.
|
||||
*
|
||||
* l2jserver 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.game.ai.desires;
|
||||
|
||||
/**
|
||||
* This class implements basic functionality common for each desire
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
* @see com.l2jserver.game.ai.desires.Desire
|
||||
* @see com.l2jserver.game.ai.desires.DesireQueue
|
||||
* @see com.l2jserver.game.ai.AI
|
||||
* @see com.l2jserver.game.ai.AI#handleDesire(Desire)
|
||||
*/
|
||||
public abstract class AbstractDesire implements Desire {
|
||||
|
||||
/**
|
||||
* Desire power. It's used to calculate what npc whants to do most of all.
|
||||
*/
|
||||
protected int desirePower;
|
||||
|
||||
/**
|
||||
* Creates new desire. By design any desire should have desire power. So
|
||||
* constructor accepts basic amout.
|
||||
*
|
||||
* @param desirePower
|
||||
* basic amount of desirePower
|
||||
*/
|
||||
protected AbstractDesire(int desirePower) {
|
||||
this.desirePower = desirePower;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this desire with another, used by
|
||||
* {@link com.l2jserver.game.ai.desires.DesireQueue} to keep track of desire
|
||||
* priorities.
|
||||
*
|
||||
* @param o
|
||||
* desire to compare with
|
||||
* @return result of desire comparation
|
||||
*/
|
||||
@Override
|
||||
public int compareTo(Desire o) {
|
||||
return o.getDesirePower() - getDesirePower();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDesirePower() {
|
||||
return desirePower;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void increaseDesirePower(int desirePower) {
|
||||
this.desirePower = this.desirePower + desirePower;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void reduceDesirePower(int desirePower) {
|
||||
this.desirePower = this.desirePower - desirePower;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* This file is part of l2jserver <l2jserver.com>.
|
||||
*
|
||||
* l2jserver 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.game.ai.desires;
|
||||
|
||||
import com.l2jserver.game.ai.AI;
|
||||
import com.l2jserver.model.world.Actor;
|
||||
|
||||
/**
|
||||
* This class indicates that character wants to attack somebody
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public final class AttackDesire extends AbstractDesire {
|
||||
/**
|
||||
* Target of this desire
|
||||
*/
|
||||
protected final Actor target;
|
||||
|
||||
/**
|
||||
* Creates new attack desire, target can't be changed
|
||||
*
|
||||
* @param target
|
||||
* whom to attack
|
||||
* @param desirePower
|
||||
* initial attack power
|
||||
*/
|
||||
protected AttackDesire(Actor target, int desirePower) {
|
||||
super(desirePower);
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleDesire(AI<?> ai) {
|
||||
// TODO: Implement
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
if (!(o instanceof AttackDesire))
|
||||
return false;
|
||||
|
||||
AttackDesire that = (AttackDesire) o;
|
||||
|
||||
return target.equals(that.target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return target.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns target of this desire
|
||||
*
|
||||
* @return target of this desire
|
||||
*/
|
||||
public Actor getTarget() {
|
||||
return target;
|
||||
}
|
||||
}
|
||||
93
src/main/java/com/l2jserver/game/ai/desires/Desire.java
Normal file
93
src/main/java/com/l2jserver/game/ai/desires/Desire.java
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* This file is part of l2jserver <l2jserver.com>.
|
||||
*
|
||||
* l2jserver 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.game.ai.desires;
|
||||
|
||||
import com.l2jserver.game.ai.AI;
|
||||
|
||||
/**
|
||||
* This interface represents basic desire functions.<br>
|
||||
* Each desire should implement {@link #handleDesire(com.l2jserver.game.ai.AI)}
|
||||
* method with default behavior.<br>
|
||||
* AI can override {@link com.l2jserver.game.ai.AI#handleDesire(Desire)} to
|
||||
* implement custom behavior of desire.<br>
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
* @see com.l2jserver.game.ai.AI
|
||||
* @see com.l2jserver.game.ai.AI#handleDesire(Desire)
|
||||
* @see com.l2jserver.game.ai.desires.AbstractDesire
|
||||
*/
|
||||
public interface Desire extends Comparable<Desire> {
|
||||
/**
|
||||
* Invokes default desire action. AI can override invocation of this method
|
||||
* to handle desire in it's own way
|
||||
*
|
||||
* @param ai
|
||||
* actor that is doing this desire
|
||||
*/
|
||||
void handleDesire(AI<?> ai);
|
||||
|
||||
/**
|
||||
* Returns hashcode for this object, must be overrided by child
|
||||
*
|
||||
* @return hashcode for this object
|
||||
*/
|
||||
int hashCode();
|
||||
|
||||
/**
|
||||
* Compares this Desire with another object, must overriden by child
|
||||
*
|
||||
* @param obj
|
||||
* another object to compare with
|
||||
* @return result of object comparation
|
||||
*/
|
||||
boolean equals(Object obj);
|
||||
|
||||
/**
|
||||
* Returns desire power of this object
|
||||
*
|
||||
* @return desire power of the object
|
||||
*/
|
||||
int getDesirePower();
|
||||
|
||||
/**
|
||||
* Adds desire power to this desire, this call is synchronized.<br>
|
||||
* <br>
|
||||
* <b>WARNING!!! Changing desire power after adding it to queue will not
|
||||
* affect it's position, you have to call
|
||||
* {@link com.l2jserver.game.ai.desires.DesireQueue#addDesire(Desire)}
|
||||
* passing this instance as argument</b>
|
||||
*
|
||||
* @param desirePower
|
||||
* amount of desirePower to add
|
||||
* @see DesireQueue#addDesire(Desire)
|
||||
*/
|
||||
void increaseDesirePower(int desirePower);
|
||||
|
||||
/**
|
||||
* Reduces desire power by give amount.<br>
|
||||
* <br>
|
||||
* <b>WARNING!!! Changing desire power after adding it to queue will not
|
||||
* affect it's position, you have to call
|
||||
* {@link com.l2jserver.game.ai.desires.DesireQueue#addDesire(Desire)}
|
||||
* passing this instance as argument</b>
|
||||
*
|
||||
* @param desirePower
|
||||
* amount of desirePower to substract
|
||||
* @see DesireQueue#addDesire(Desire)
|
||||
*/
|
||||
void reduceDesirePower(int desirePower);
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* This file is part of l2jserver <l2jserver.com>.
|
||||
*
|
||||
* l2jserver 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.game.ai.desires;
|
||||
|
||||
/**
|
||||
* This class represents simple filter for desire iterations.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public interface DesireIteratorFilter {
|
||||
/**
|
||||
* This method is called each time for every desire that is in the queue.<br>
|
||||
* <br> {@link java.util.ConcurrentModificationException} will be thrown by
|
||||
* {@link com.l2jserver.game.ai.desires.DesireQueue#iterateDesires(DesireIteratorHandler, DesireIteratorFilter[])}
|
||||
* if any of the following methods will be called from here:
|
||||
* <ul>
|
||||
* <li>{@link com.l2jserver.game.ai.desires.DesireQueue#addDesire(Desire)}</li>
|
||||
* <li>{@link com.l2jserver.game.ai.desires.DesireQueue#poll()}</li>
|
||||
* <li>
|
||||
* {@link com.l2jserver.game.ai.desires.DesireQueue#removeDesire(Desire)}</li>
|
||||
* </ul>
|
||||
* <p/>
|
||||
* However {@link com.l2jserver.game.ai.desires.DesireQueue#clear()} can be
|
||||
* called.
|
||||
*
|
||||
* @param desire
|
||||
* current element of iteration that is beeing filtered
|
||||
* @return true if this filter accepted desire, false otherwise
|
||||
*/
|
||||
public boolean isOk(Desire desire);
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* This file is part of l2jserver <l2jserver.com>.
|
||||
*
|
||||
* l2jserver 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.game.ai.desires;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* This class is designed to be a helper class for desires.<br>
|
||||
* Direct access to desire list is not allowed, however this interface can be
|
||||
* used for iteration.<br>
|
||||
* <br>
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
* @see com.l2jserver.game.ai.desires.DesireIteratorFilter
|
||||
* @see com.l2jserver.game.ai.desires.DesireQueue#iterateDesires(DesireIteratorHandler,
|
||||
* DesireIteratorFilter[])
|
||||
*/
|
||||
public interface DesireIteratorHandler {
|
||||
/**
|
||||
* This method is called each time for every desire that is in the queue.<br>
|
||||
* Remove of desire must be handeled by <b>iterator.remove();</b><br>
|
||||
* <br> {@link java.util.ConcurrentModificationException} will be thrown by
|
||||
* {@link com.l2jserver.game.ai.desires.DesireQueue#iterateDesires(DesireIteratorHandler, DesireIteratorFilter[])}
|
||||
* if any of the following methods will be called from here:
|
||||
* <ul>
|
||||
* <li>{@link com.l2jserver.game.ai.desires.DesireQueue#addDesire(Desire)}</li>
|
||||
* <li>{@link com.l2jserver.game.ai.desires.DesireQueue#poll()}</li>
|
||||
* <li>
|
||||
* {@link com.l2jserver.game.ai.desires.DesireQueue#removeDesire(Desire)}</li>
|
||||
* </ul>
|
||||
* <p/>
|
||||
* However {@link com.l2jserver.game.ai.desires.DesireQueue#clear()} can be
|
||||
* called.
|
||||
*
|
||||
* @param desire
|
||||
* current element of iteration
|
||||
* @param iterator
|
||||
* iterator object
|
||||
*/
|
||||
public void next(Desire desire, Iterator<Desire> iterator);
|
||||
}
|
||||
212
src/main/java/com/l2jserver/game/ai/desires/DesireQueue.java
Normal file
212
src/main/java/com/l2jserver/game/ai/desires/DesireQueue.java
Normal file
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
* This file is part of l2jserver <l2jserver.com>.
|
||||
*
|
||||
* l2jserver 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.game.ai.desires;
|
||||
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.Iterator;
|
||||
import java.util.PriorityQueue;
|
||||
|
||||
/**
|
||||
* This class represents desire queue, it's thread-safe. Desires can be added
|
||||
* and removed. If desire is added - previous desires will be checked, if same
|
||||
* desire found then desire previous one will be removed from the queue
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
* @see com.l2jserver.game.ai.desires.Desire
|
||||
* @see com.l2jserver.game.ai.desires.AbstractDesire
|
||||
*/
|
||||
public class DesireQueue {
|
||||
/**
|
||||
* Prioritized Queue of desires, lazy initialization.
|
||||
*/
|
||||
protected PriorityQueue<Desire> queue;
|
||||
|
||||
/**
|
||||
* Returns first element of this queue not removing it. Returns null if
|
||||
* there is no elements.
|
||||
*
|
||||
* @return first element or null
|
||||
*/
|
||||
public synchronized Desire peek() {
|
||||
return queue != null ? queue.peek() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes first element from the desires list and removes it. Returns null
|
||||
* if there are no elements.
|
||||
*
|
||||
* @return first element from the desires list or null.
|
||||
*/
|
||||
public synchronized Desire poll() {
|
||||
if (queue != null) {
|
||||
return queue.poll();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds desire to the queue.
|
||||
* <p/>
|
||||
* <p/>
|
||||
* When adding object this method checks first for the same object by
|
||||
* {@link AbstractDesire#equals(Object)}, if such object found, next actions
|
||||
* will be done:<br>
|
||||
* <br>
|
||||
* 1). Remove old desire instance from the list.<br>
|
||||
* 2). Check if those desires are same instances by "==".<br>
|
||||
* 3). If they are not the same instances, add desire power from old
|
||||
* instance to new instance, if they are - do nothing.<br>
|
||||
* <br>
|
||||
* After all add new desire instance to the list.
|
||||
*
|
||||
* @param desire
|
||||
* desire instance to add
|
||||
*/
|
||||
public synchronized void addDesire(Desire desire) {
|
||||
// Lazy initialization of desire queue
|
||||
if (queue == null) {
|
||||
queue = new PriorityQueue<Desire>();
|
||||
}
|
||||
|
||||
// Iterate over the list to find similar desires
|
||||
Iterator<Desire> iterator = queue.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Desire iterated = iterator.next();
|
||||
|
||||
// Find similar desires by #equals method, they can be different
|
||||
// instances.
|
||||
if (desire.equals(iterated)) {
|
||||
// Remove the old desire from the list
|
||||
iterator.remove();
|
||||
|
||||
// If current desire instance was not at the list - increase
|
||||
// it's power by the value of another instance power
|
||||
// and after that add it to the list
|
||||
if (desire != iterated) {
|
||||
desire.increaseDesirePower(iterated.getDesirePower());
|
||||
}
|
||||
|
||||
// Break iteration, desire list can't contain two same desires
|
||||
break;
|
||||
}
|
||||
}
|
||||
// finally add desire to the list
|
||||
queue.add(desire);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes desire from this desireQueue. If desire was removed successfully
|
||||
* this method return true, false otherwise
|
||||
*
|
||||
* @param desire
|
||||
* what desire to remove
|
||||
* @return result of desire removal
|
||||
*/
|
||||
public synchronized boolean removeDesire(Desire desire) {
|
||||
return queue != null && queue.remove(desire);
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates over desires, you have to provide iteration handler and
|
||||
* optionally filters.<br>
|
||||
* <br>
|
||||
* Handlers and filters can't call following methods:
|
||||
* <ul>
|
||||
* <li>{@link #addDesire(Desire)}</li>
|
||||
* <li>{@link #poll()}</li>
|
||||
* <li>{@link #removeDesire(Desire)}</li>
|
||||
* </ul>
|
||||
* <p/>
|
||||
* However, method {@link #clear() can be called}.
|
||||
*
|
||||
* @param handler
|
||||
* DesireIterationhandler that will be called on the iteration
|
||||
* @param filters
|
||||
* optional filters that will prevent passing unneeded desires to
|
||||
* the handler
|
||||
* @throws java.util.ConcurrentModificationException
|
||||
* only if called handler or filter modified this queue
|
||||
* @see com.l2jserver.game.ai.desires.DesireIteratorFilter
|
||||
* @see com.l2jserver.game.ai.desires.DesireIteratorFilter#isOk(Desire)
|
||||
* @see com.l2jserver.game.ai.desires.DesireIteratorHandler
|
||||
* @see com.l2jserver.game.ai.desires.DesireIteratorHandler#next(Desire ,
|
||||
* java.util.Iterator)
|
||||
*/
|
||||
public synchronized void iterateDesires(DesireIteratorHandler handler,
|
||||
DesireIteratorFilter... filters)
|
||||
throws ConcurrentModificationException {
|
||||
|
||||
if (queue == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Iterator<Desire> iterator = queue.iterator();
|
||||
outer: while (iterator.hasNext()) {
|
||||
Desire desire = iterator.next();
|
||||
|
||||
if (filters != null && filters.length > 0) {
|
||||
for (DesireIteratorFilter filter : filters) {
|
||||
if (!filter.isOk(desire)) {
|
||||
continue outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handler.next(desire, iterator);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this desire list contains same desire. Desires are
|
||||
* compared by {@link AbstractDesire#equals(Object)} method.
|
||||
*
|
||||
* @param desire
|
||||
* what desire to search
|
||||
* @return true if there is equal desire, false in other case.
|
||||
*/
|
||||
public synchronized boolean contains(Desire desire) {
|
||||
return queue.contains(desire);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this NPC has no any desires added
|
||||
*
|
||||
* @return true if this NPC has no any desires added
|
||||
*/
|
||||
public synchronized boolean isEmpty() {
|
||||
return queue == null || queue.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all desires
|
||||
*/
|
||||
public synchronized void clear() {
|
||||
if (queue != null) {
|
||||
queue.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns size of the desire list
|
||||
*
|
||||
* @return size of remaining desires
|
||||
*/
|
||||
public synchronized int size() {
|
||||
return queue == null ? 0 : queue.size();
|
||||
}
|
||||
}
|
||||
83
src/main/java/com/l2jserver/game/ai/desires/MoveDesire.java
Normal file
83
src/main/java/com/l2jserver/game/ai/desires/MoveDesire.java
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* This file is part of l2jserver <l2jserver.com>.
|
||||
*
|
||||
* l2jserver 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.game.ai.desires;
|
||||
|
||||
import com.l2jserver.game.ai.AI;
|
||||
import com.l2jserver.model.world.Actor;
|
||||
import com.l2jserver.util.geometry.Point3D;
|
||||
|
||||
/**
|
||||
* This class indicates that {@link Actor} wants to move somewhere
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public final class MoveDesire extends AbstractDesire {
|
||||
/**
|
||||
* Target of this desire
|
||||
*/
|
||||
protected final Point3D point;
|
||||
|
||||
/**
|
||||
* Creates new move desire. Target can't be changed
|
||||
*
|
||||
* @param point
|
||||
* where to move
|
||||
* @param desirePower
|
||||
* initial attack power
|
||||
*/
|
||||
protected MoveDesire(Point3D point, int desirePower) {
|
||||
super(desirePower);
|
||||
this.point = point;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleDesire(AI<?> ai) {
|
||||
// TODO: Implement
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
if (!(o instanceof MoveDesire))
|
||||
return false;
|
||||
|
||||
MoveDesire that = (MoveDesire) o;
|
||||
|
||||
return point.equals(that.point);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return point.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns target of this desire
|
||||
*
|
||||
* @return target of this desire
|
||||
*/
|
||||
public Point3D getTarget() {
|
||||
return point;
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,7 @@ import com.l2jserver.service.game.spawn.CharacterAlreadyTeleportingServiceExcept
|
||||
import com.l2jserver.service.game.spawn.NotSpawnedServiceException;
|
||||
import com.l2jserver.service.game.spawn.SpawnService;
|
||||
import com.l2jserver.util.BufferUtils;
|
||||
import com.l2jserver.util.dimensional.Coordinate;
|
||||
import com.l2jserver.util.geometry.Coordinate;
|
||||
|
||||
/**
|
||||
* Executes an administrator action
|
||||
|
||||
@@ -27,7 +27,7 @@ import com.l2jserver.model.id.object.provider.ObjectIDResolver;
|
||||
import com.l2jserver.model.world.NPC;
|
||||
import com.l2jserver.service.game.npc.ActionServiceException;
|
||||
import com.l2jserver.service.game.npc.NPCService;
|
||||
import com.l2jserver.util.dimensional.Coordinate;
|
||||
import com.l2jserver.util.geometry.Coordinate;
|
||||
|
||||
/**
|
||||
* Executes an action from an character to an NPC
|
||||
|
||||
@@ -33,7 +33,7 @@ import com.l2jserver.service.game.character.ActorIsNotAttackableServiceException
|
||||
import com.l2jserver.service.game.character.CannotSetTargetServiceException;
|
||||
import com.l2jserver.service.game.character.CharacterService;
|
||||
import com.l2jserver.service.game.npc.NotAttackableNPCServiceException;
|
||||
import com.l2jserver.util.dimensional.Coordinate;
|
||||
import com.l2jserver.util.geometry.Coordinate;
|
||||
|
||||
/**
|
||||
* Completes the creation of an character. Creates the object, inserts into the
|
||||
|
||||
@@ -26,7 +26,7 @@ import com.l2jserver.game.net.packet.AbstractClientPacket;
|
||||
import com.l2jserver.game.net.packet.server.CharacterStopMovePacket;
|
||||
import com.l2jserver.model.world.L2Character;
|
||||
import com.l2jserver.service.game.character.CharacterService;
|
||||
import com.l2jserver.util.dimensional.Coordinate;
|
||||
import com.l2jserver.util.geometry.Coordinate;
|
||||
|
||||
/**
|
||||
* This packet notifies the server which character the player has chosen to use.
|
||||
|
||||
@@ -22,7 +22,7 @@ import com.google.inject.Inject;
|
||||
import com.l2jserver.game.net.Lineage2Connection;
|
||||
import com.l2jserver.game.net.packet.AbstractClientPacket;
|
||||
import com.l2jserver.service.game.character.CharacterService;
|
||||
import com.l2jserver.util.dimensional.Point;
|
||||
import com.l2jserver.util.geometry.Point3D;
|
||||
|
||||
/**
|
||||
* This packet notifies the server which character the player has chosen to use.
|
||||
@@ -40,7 +40,7 @@ public class CharacterValidatePositionPacket extends AbstractClientPacket {
|
||||
*/
|
||||
private final CharacterService charService;
|
||||
|
||||
private Point point;
|
||||
private Point3D point;
|
||||
@SuppressWarnings("unused")
|
||||
private int extra; // vehicle id
|
||||
|
||||
@@ -51,7 +51,7 @@ public class CharacterValidatePositionPacket extends AbstractClientPacket {
|
||||
|
||||
@Override
|
||||
public void read(Lineage2Connection conn, ChannelBuffer buffer) {
|
||||
point = Point.fromXYZA(buffer.readInt(), buffer.readInt(),
|
||||
point = Point3D.fromXYZA(buffer.readInt(), buffer.readInt(),
|
||||
buffer.readInt(), buffer.readInt());
|
||||
extra = buffer.readInt();
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ import org.jboss.netty.buffer.ChannelBuffer;
|
||||
import com.l2jserver.game.net.Lineage2Connection;
|
||||
import com.l2jserver.game.net.packet.AbstractServerPacket;
|
||||
import com.l2jserver.model.world.Actor;
|
||||
import com.l2jserver.util.dimensional.Coordinate;
|
||||
import com.l2jserver.util.geometry.Coordinate;
|
||||
|
||||
/**
|
||||
* This packet notifies the client that the character is moving to an certain
|
||||
|
||||
@@ -22,7 +22,7 @@ import com.l2jserver.game.net.Lineage2Connection;
|
||||
import com.l2jserver.game.net.packet.AbstractServerPacket;
|
||||
import com.l2jserver.game.net.packet.server.CharacterCreateFailPacket.Reason;
|
||||
import com.l2jserver.model.world.L2Character;
|
||||
import com.l2jserver.util.dimensional.Point;
|
||||
import com.l2jserver.util.geometry.Point3D;
|
||||
|
||||
/**
|
||||
* This packet notifies the client that the chosen character has been
|
||||
@@ -44,9 +44,9 @@ public class CharacterTeleportPacket extends AbstractServerPacket {
|
||||
/**
|
||||
* The teleportation point
|
||||
*/
|
||||
private final Point point;
|
||||
private final Point3D point;
|
||||
|
||||
public CharacterTeleportPacket(L2Character character, Point point) {
|
||||
public CharacterTeleportPacket(L2Character character, Point3D point) {
|
||||
super(OPCODE);
|
||||
this.character = character;
|
||||
this.point = point;
|
||||
|
||||
@@ -28,7 +28,7 @@ import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
|
||||
import com.l2jserver.model.id.template.ItemTemplateID;
|
||||
import com.l2jserver.model.id.template.TeleportationTemplateID;
|
||||
import com.l2jserver.util.dimensional.Coordinate;
|
||||
import com.l2jserver.util.geometry.Coordinate;
|
||||
import com.l2jserver.util.jaxb.CoordinateAdapter;
|
||||
import com.l2jserver.util.jaxb.ItemTemplateIDAdapter;
|
||||
import com.l2jserver.util.jaxb.TeleportationTemplateIDAdapter;
|
||||
|
||||
@@ -31,7 +31,7 @@ import com.l2jserver.model.world.character.CharacterFriendList;
|
||||
import com.l2jserver.model.world.character.CharacterInventory;
|
||||
import com.l2jserver.model.world.character.CharacterShortcutContainer;
|
||||
import com.l2jserver.model.world.character.CharacterStats;
|
||||
import com.l2jserver.util.dimensional.Point;
|
||||
import com.l2jserver.util.geometry.Point3D;
|
||||
|
||||
/**
|
||||
* This class represents a playable character in Lineage II world.
|
||||
@@ -179,7 +179,7 @@ public class L2Character extends Player {
|
||||
/**
|
||||
* The point the player is moving, teleporting etc...
|
||||
*/
|
||||
private transient Point targetLocation;
|
||||
private transient Point3D targetLocation;
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
@@ -502,7 +502,7 @@ public class L2Character extends Player {
|
||||
/**
|
||||
* @return the targetLocation
|
||||
*/
|
||||
public Point getTargetLocation() {
|
||||
public Point3D getTargetLocation() {
|
||||
return targetLocation;
|
||||
}
|
||||
|
||||
@@ -510,7 +510,7 @@ public class L2Character extends Player {
|
||||
* @param targetLocation
|
||||
* the targetLocation to set
|
||||
*/
|
||||
public void setTargetLocation(Point targetLocation) {
|
||||
public void setTargetLocation(Point3D targetLocation) {
|
||||
this.targetLocation = targetLocation;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
*/
|
||||
package com.l2jserver.model.world;
|
||||
|
||||
import com.l2jserver.util.dimensional.Coordinate;
|
||||
import com.l2jserver.util.dimensional.Point;
|
||||
import com.l2jserver.util.geometry.Coordinate;
|
||||
import com.l2jserver.util.geometry.Point3D;
|
||||
|
||||
/**
|
||||
* This is an abstract object that objects that can be placed in world should
|
||||
@@ -29,12 +29,12 @@ public abstract class PositionableObject extends AbstractObject {
|
||||
/**
|
||||
* The point this object is currently in
|
||||
*/
|
||||
private Point point;
|
||||
private Point3D point;
|
||||
|
||||
/**
|
||||
* @return the coordinate point
|
||||
*/
|
||||
public Point getPoint() {
|
||||
public Point3D getPoint() {
|
||||
return point;
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ public abstract class PositionableObject extends AbstractObject {
|
||||
* @param point
|
||||
* the coordinate point to set
|
||||
*/
|
||||
public void setPoint(Point point) {
|
||||
public void setPoint(Point3D point) {
|
||||
this.point = point;
|
||||
}
|
||||
|
||||
@@ -51,6 +51,6 @@ public abstract class PositionableObject extends AbstractObject {
|
||||
}
|
||||
|
||||
public void setPosition(Coordinate coord) {
|
||||
this.point = new Point(coord, (point != null ? point.getAngle() : 0));
|
||||
this.point = new Point3D(coord, (point != null ? point.getAngle() : 0));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ import com.l2jserver.model.id.ObjectID;
|
||||
import com.l2jserver.model.world.Actor;
|
||||
import com.l2jserver.model.world.WorldObject;
|
||||
import com.l2jserver.model.world.event.SpawnEvent;
|
||||
import com.l2jserver.util.dimensional.Point;
|
||||
import com.l2jserver.util.geometry.Point3D;
|
||||
|
||||
/**
|
||||
* Event dispatcher once an actor has spawned in the world
|
||||
@@ -35,7 +35,7 @@ public class ActorSpawnEvent implements ActorEvent, SpawnEvent {
|
||||
/**
|
||||
* The spawning point
|
||||
*/
|
||||
private final Point point;
|
||||
private final Point3D point;
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
@@ -45,7 +45,7 @@ public class ActorSpawnEvent implements ActorEvent, SpawnEvent {
|
||||
* @param point
|
||||
* the spawn point
|
||||
*/
|
||||
public ActorSpawnEvent(Actor actor, Point point) {
|
||||
public ActorSpawnEvent(Actor actor, Point3D point) {
|
||||
this.actor = actor;
|
||||
this.point = point;
|
||||
}
|
||||
@@ -61,7 +61,7 @@ public class ActorSpawnEvent implements ActorEvent, SpawnEvent {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Point getPoint() {
|
||||
public Point3D getPoint() {
|
||||
return point;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ import com.l2jserver.model.world.Actor;
|
||||
import com.l2jserver.model.world.L2Character;
|
||||
import com.l2jserver.model.world.Player;
|
||||
import com.l2jserver.model.world.WorldObject;
|
||||
import com.l2jserver.util.dimensional.Point;
|
||||
import com.l2jserver.util.geometry.Point3D;
|
||||
|
||||
/**
|
||||
* Event triggered once a character moves
|
||||
@@ -36,7 +36,7 @@ public class CharacterMoveEvent implements CharacterEvent {
|
||||
/**
|
||||
* The old point of the character
|
||||
*/
|
||||
private final Point point;
|
||||
private final Point3D point;
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
@@ -46,7 +46,7 @@ public class CharacterMoveEvent implements CharacterEvent {
|
||||
* @param point
|
||||
* the character point before moving
|
||||
*/
|
||||
public CharacterMoveEvent(L2Character character, Point point) {
|
||||
public CharacterMoveEvent(L2Character character, Point3D point) {
|
||||
this.character = character;
|
||||
this.point = point;
|
||||
}
|
||||
@@ -54,7 +54,7 @@ public class CharacterMoveEvent implements CharacterEvent {
|
||||
/**
|
||||
* @return the old point
|
||||
*/
|
||||
public Point getPoint() {
|
||||
public Point3D getPoint() {
|
||||
return point;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ import com.l2jserver.model.world.Actor;
|
||||
import com.l2jserver.model.world.L2Character;
|
||||
import com.l2jserver.model.world.Player;
|
||||
import com.l2jserver.model.world.WorldObject;
|
||||
import com.l2jserver.util.dimensional.Point;
|
||||
import com.l2jserver.util.geometry.Point3D;
|
||||
|
||||
/**
|
||||
* Event triggered once a character moves
|
||||
@@ -36,7 +36,7 @@ public class CharacterStopMoveEvent implements CharacterEvent {
|
||||
/**
|
||||
* The new point of the character
|
||||
*/
|
||||
private final Point point;
|
||||
private final Point3D point;
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
@@ -46,7 +46,7 @@ public class CharacterStopMoveEvent implements CharacterEvent {
|
||||
* @param point
|
||||
* the character point
|
||||
*/
|
||||
public CharacterStopMoveEvent(L2Character character, Point point) {
|
||||
public CharacterStopMoveEvent(L2Character character, Point3D point) {
|
||||
this.character = character;
|
||||
this.point = point;
|
||||
}
|
||||
@@ -54,7 +54,7 @@ public class CharacterStopMoveEvent implements CharacterEvent {
|
||||
/**
|
||||
* @return the point
|
||||
*/
|
||||
public Point getPoint() {
|
||||
public Point3D getPoint() {
|
||||
return point;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
package com.l2jserver.model.world.event;
|
||||
|
||||
import com.l2jserver.service.game.world.event.WorldEvent;
|
||||
import com.l2jserver.util.dimensional.Point;
|
||||
import com.l2jserver.util.geometry.Point3D;
|
||||
|
||||
/**
|
||||
* Event for objects spawning
|
||||
@@ -28,5 +28,5 @@ public interface SpawnEvent extends WorldEvent {
|
||||
/**
|
||||
* @return the spawning point
|
||||
*/
|
||||
Point getPoint();
|
||||
Point3D getPoint();
|
||||
}
|
||||
@@ -18,7 +18,7 @@ package com.l2jserver.model.world.npc.event;
|
||||
|
||||
import com.l2jserver.model.world.NPC;
|
||||
import com.l2jserver.model.world.actor.event.ActorSpawnEvent;
|
||||
import com.l2jserver.util.dimensional.Point;
|
||||
import com.l2jserver.util.geometry.Point3D;
|
||||
|
||||
/**
|
||||
* Event dispatched once a {@link NPC} has spawned in the world.
|
||||
@@ -32,7 +32,7 @@ public class NPCSpawnEvent extends ActorSpawnEvent implements NPCEvent {
|
||||
* @param point
|
||||
* the spawn point
|
||||
*/
|
||||
public NPCSpawnEvent(NPC npc, Point point) {
|
||||
public NPCSpawnEvent(NPC npc, Point3D point) {
|
||||
super(npc, point);
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ package com.l2jserver.model.world.player.event;
|
||||
|
||||
import com.l2jserver.model.world.Player;
|
||||
import com.l2jserver.model.world.actor.event.ActorSpawnEvent;
|
||||
import com.l2jserver.util.dimensional.Point;
|
||||
import com.l2jserver.util.geometry.Point3D;
|
||||
|
||||
/**
|
||||
* Event dispatcher once an player has spawned in the world
|
||||
@@ -32,7 +32,7 @@ public class PlayerSpawnEvent extends ActorSpawnEvent implements PlayerEvent {
|
||||
* @param point
|
||||
* the spawn point
|
||||
*/
|
||||
public PlayerSpawnEvent(Player player, Point point) {
|
||||
public PlayerSpawnEvent(Player player, Point3D point) {
|
||||
super(player, point);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
package com.l2jserver.model.world.player.event;
|
||||
|
||||
import com.l2jserver.model.world.Player;
|
||||
import com.l2jserver.util.dimensional.Point;
|
||||
import com.l2jserver.util.geometry.Point3D;
|
||||
|
||||
/**
|
||||
* Event dispatched once an player has completed its teleportation to another
|
||||
@@ -34,7 +34,7 @@ public class PlayerTeleportedEvent extends PlayerSpawnEvent {
|
||||
* @param point
|
||||
* the teleport point
|
||||
*/
|
||||
public PlayerTeleportedEvent(Player player, Point point) {
|
||||
public PlayerTeleportedEvent(Player player, Point3D point) {
|
||||
super(player, point);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ import com.l2jserver.model.id.ObjectID;
|
||||
import com.l2jserver.model.world.Actor;
|
||||
import com.l2jserver.model.world.Player;
|
||||
import com.l2jserver.model.world.WorldObject;
|
||||
import com.l2jserver.util.dimensional.Point;
|
||||
import com.l2jserver.util.geometry.Point3D;
|
||||
|
||||
/**
|
||||
* Event dispatched once an player has started his teleported to another
|
||||
@@ -30,7 +30,7 @@ import com.l2jserver.util.dimensional.Point;
|
||||
*/
|
||||
public class PlayerTeleportingEvent implements PlayerEvent {
|
||||
private final Player player;
|
||||
private final Point point;
|
||||
private final Point3D point;
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
@@ -40,7 +40,7 @@ public class PlayerTeleportingEvent implements PlayerEvent {
|
||||
* @param point
|
||||
* the teleport point
|
||||
*/
|
||||
public PlayerTeleportingEvent(Player player, Point point) {
|
||||
public PlayerTeleportingEvent(Player player, Point3D point) {
|
||||
this.player = player;
|
||||
this.point = point;
|
||||
}
|
||||
@@ -65,7 +65,7 @@ public class PlayerTeleportingEvent implements PlayerEvent {
|
||||
*
|
||||
* @return the teleported point
|
||||
*/
|
||||
public Point getPoint() {
|
||||
public Point3D getPoint() {
|
||||
return point;
|
||||
}
|
||||
|
||||
|
||||
113
src/main/java/com/l2jserver/service/cache/AbstractReferenceCache.java
vendored
Normal file
113
src/main/java/com/l2jserver/service/cache/AbstractReferenceCache.java
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* This file is part of l2jserver <l2jserver.com>.
|
||||
*
|
||||
* l2jserver 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.service.cache;
|
||||
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.ReferenceQueue;
|
||||
import java.util.Map;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.l2jserver.service.cache.SoftCacheService.SoftCache;
|
||||
import com.l2jserver.util.factory.CollectionFactory;
|
||||
import com.sun.beans.WeakCache;
|
||||
|
||||
/**
|
||||
* Base class for {@link WeakCache} and {@link SoftCache}
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*
|
||||
* @param <K>
|
||||
* the key type
|
||||
* @param <V>
|
||||
* the value type
|
||||
*/
|
||||
abstract class AbstractReferenceCache<K, V> implements Cache<K, V> {
|
||||
protected final Logger log = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
/**
|
||||
* The cache name
|
||||
*/
|
||||
protected final String cacheName;
|
||||
|
||||
/**
|
||||
* Map storing references to cached objects
|
||||
*/
|
||||
protected final Map<K, Reference<V>> cacheMap = CollectionFactory.newMap();
|
||||
/**
|
||||
* The reference queue
|
||||
*/
|
||||
protected final ReferenceQueue<V> refQueue = CollectionFactory
|
||||
.newReferenceQueue();
|
||||
|
||||
/**
|
||||
* @param cacheName
|
||||
* the cache name
|
||||
*/
|
||||
protected AbstractReferenceCache(String cacheName) {
|
||||
this.cacheName = cacheName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put(K key, V value) {
|
||||
cleanQueue();
|
||||
|
||||
Reference<V> entry = newReference(key, value, refQueue);
|
||||
cacheMap.put(key, entry);
|
||||
|
||||
log.debug("{}: added for key: {}", cacheName, key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public V get(K key) {
|
||||
cleanQueue();
|
||||
|
||||
Reference<V> reference = cacheMap.get(key);
|
||||
if (reference == null)
|
||||
return null;
|
||||
|
||||
V res = reference.get();
|
||||
if (res != null)
|
||||
log.debug("{}: obtained for key: {}", cacheName, key);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(K key) {
|
||||
cleanQueue();
|
||||
return cacheMap.containsKey(key);
|
||||
}
|
||||
|
||||
protected abstract void cleanQueue();
|
||||
|
||||
@Override
|
||||
public void remove(K key) {
|
||||
cacheMap.remove(key);
|
||||
log.debug("{}: removed for key: {}", cacheName, key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
cacheMap.clear();
|
||||
log.debug("{}: cleared", cacheName);
|
||||
}
|
||||
|
||||
protected abstract Reference<V> newReference(K key, V value,
|
||||
ReferenceQueue<V> queue);
|
||||
}
|
||||
64
src/main/java/com/l2jserver/service/cache/Cache.java
vendored
Normal file
64
src/main/java/com/l2jserver/service/cache/Cache.java
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* This file is part of l2jserver <l2jserver.com>.
|
||||
*
|
||||
* l2jserver 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.service.cache;
|
||||
|
||||
/**
|
||||
* This interface represents a Map structure for cache usage.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public interface Cache<K, V> {
|
||||
/**
|
||||
* Adds a pair <key,value> to cache.<br>
|
||||
* <br>
|
||||
*
|
||||
* <font color='red'><b>NOTICE:</b> </font> if there is already a value with
|
||||
* given id in the map, {@link IllegalArgumentException} will be thrown.
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
void put(K key, V value);
|
||||
|
||||
/**
|
||||
* Returns cached value correlated to given key.
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
V get(K key);
|
||||
|
||||
/**
|
||||
* Checks whether this map contains a value related to given key.
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
boolean contains(K key);
|
||||
|
||||
/**
|
||||
* Removes an entry from the map, that has given key.
|
||||
*
|
||||
* @param key
|
||||
*/
|
||||
void remove(K key);
|
||||
|
||||
/**
|
||||
* Clears this cache
|
||||
*/
|
||||
void clear();
|
||||
}
|
||||
@@ -16,8 +16,6 @@
|
||||
*/
|
||||
package com.l2jserver.service.cache;
|
||||
|
||||
import net.sf.ehcache.Cache;
|
||||
|
||||
import com.l2jserver.service.Service;
|
||||
|
||||
/**
|
||||
@@ -31,7 +29,6 @@ import com.l2jserver.service.Service;
|
||||
* {@link IgnoreCaching}
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*
|
||||
*/
|
||||
public interface CacheService extends Service {
|
||||
/**
|
||||
@@ -50,39 +47,60 @@ public interface CacheService extends Service {
|
||||
|
||||
/**
|
||||
* Creates a new cache with default configurations. Eviction mode is LRU
|
||||
* (Last Recently Used). If you wish more customization, you should manually
|
||||
* create the cache and register it using {@link #register(Cache)}.
|
||||
* (Last Recently Used). The size is only a guarantee that you can store
|
||||
* <b>at least</b> <tt>n</tt> items.
|
||||
*
|
||||
* @param <K>
|
||||
* the cache key type
|
||||
* @param <V>
|
||||
* the cache value type
|
||||
* @param name
|
||||
* the cache name
|
||||
* @size the maximum cache size
|
||||
* @return the created cache
|
||||
*/
|
||||
Cache createCache(String name, int size);
|
||||
<K, V> Cache<K, V> createCache(String name, int size);
|
||||
|
||||
/**
|
||||
* Creates a new eternal cache with default configurations. An eternal cache
|
||||
* is guaranteed to never automatically expire items. The size is only a
|
||||
* guarantee that you can store <b>at least</b> <tt>n</tt> items.
|
||||
*
|
||||
* @param <K>
|
||||
* the cache key type
|
||||
* @param <V>
|
||||
* the cache value type
|
||||
* @param name
|
||||
* the cache name
|
||||
* @size the maximum cache size
|
||||
* @return the created cache
|
||||
*/
|
||||
<K, V> Cache<K, V> createEternalCache(String name, int size);
|
||||
|
||||
/**
|
||||
* Creates a new cache with default configurations. The default cache size
|
||||
* is 200.
|
||||
* is 200. The size is only a guarantee that you can store <b>at least</b>
|
||||
* 200 items.
|
||||
*
|
||||
* @param <K>
|
||||
* the cache key type
|
||||
* @param <V>
|
||||
* the cache value type
|
||||
* @param name
|
||||
* the cache name
|
||||
* @return the created cache
|
||||
*/
|
||||
Cache createCache(String name);
|
||||
<K, V> Cache<K, V> createCache(String name);
|
||||
|
||||
/**
|
||||
* Registers a new cache
|
||||
* Disposes the cache. Once the cache is disposed it cannot be used anymore.
|
||||
*
|
||||
* @param <K>
|
||||
* the cache key type
|
||||
* @param <V>
|
||||
* the cache value type
|
||||
* @param cache
|
||||
* the cache
|
||||
*/
|
||||
void register(Cache cache);
|
||||
|
||||
/**
|
||||
* Unregisters an already registered cache
|
||||
*
|
||||
* @param cache
|
||||
* the cache
|
||||
*/
|
||||
void unregister(Cache cache);
|
||||
<K, V> void dispose(Cache<K, V> cache);
|
||||
}
|
||||
|
||||
@@ -20,9 +20,7 @@ import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.Arrays;
|
||||
|
||||
import net.sf.ehcache.Cache;
|
||||
import net.sf.ehcache.CacheManager;
|
||||
import net.sf.ehcache.Element;
|
||||
import net.sf.ehcache.config.CacheConfiguration;
|
||||
@@ -48,7 +46,7 @@ public class EhCacheService extends AbstractService implements CacheService {
|
||||
/**
|
||||
* The interface cache
|
||||
*/
|
||||
private Cache interfaceCache;
|
||||
private Cache<MethodInvocation, Object> interfaceCache;
|
||||
|
||||
@Override
|
||||
protected void doStart() throws ServiceStartException {
|
||||
@@ -76,10 +74,7 @@ public class EhCacheService extends AbstractService implements CacheService {
|
||||
return method.invoke(instance, args);
|
||||
final MethodInvocation invocation = new MethodInvocation(
|
||||
method, args);
|
||||
Element element = interfaceCache.get(invocation);
|
||||
if (element == null)
|
||||
return doInvoke(invocation, proxy, method, args);
|
||||
Object result = element.getObjectValue();
|
||||
Object result = interfaceCache.get(invocation);
|
||||
if (result == null)
|
||||
return doInvoke(invocation, proxy, method, args);
|
||||
return result;
|
||||
@@ -90,43 +85,94 @@ public class EhCacheService extends AbstractService implements CacheService {
|
||||
throws IllegalArgumentException,
|
||||
IllegalAccessException, InvocationTargetException {
|
||||
Object result = method.invoke(instance, args);
|
||||
interfaceCache.put(new Element(invocation, result));
|
||||
interfaceCache.put(invocation, result);
|
||||
return result;
|
||||
}
|
||||
});
|
||||
return proxy;
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public Cache createCache(String name, int size) {
|
||||
// Preconditions.checkNotNull(name, "name");
|
||||
// Preconditions.checkArgument(size > 0, "size <= 0");
|
||||
//
|
||||
// Cache cache = new Cache(new CacheConfiguration(name, size)
|
||||
// .memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.LRU)
|
||||
// .overflowToDisk(true).eternal(false).timeToLiveSeconds(60)
|
||||
// .timeToIdleSeconds(30).diskPersistent(false)
|
||||
// .diskExpiryThreadIntervalSeconds(0));
|
||||
// register(cache);
|
||||
// return cache;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public Cache createCache(String name) {
|
||||
// Preconditions.checkNotNull(name, "name");
|
||||
// return createCache(name, 200);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void register(Cache cache) {
|
||||
// Preconditions.checkNotNull(cache, "cache");
|
||||
// manager.addCache(cache);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void unregister(Cache cache) {
|
||||
// Preconditions.checkNotNull(cache, "cache");
|
||||
// manager.removeCache(cache.getName());
|
||||
// }
|
||||
|
||||
@Override
|
||||
public Cache createCache(String name, int size) {
|
||||
public <K, V> Cache<K, V> createCache(String name, int size) {
|
||||
Preconditions.checkNotNull(name, "name");
|
||||
Preconditions.checkArgument(size > 0, "size <= 0");
|
||||
|
||||
Cache cache = new Cache(new CacheConfiguration(name, size)
|
||||
.memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.LRU)
|
||||
.overflowToDisk(true).eternal(false).timeToLiveSeconds(60)
|
||||
.timeToIdleSeconds(30).diskPersistent(false)
|
||||
.diskExpiryThreadIntervalSeconds(0));
|
||||
register(cache);
|
||||
return cache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cache createCache(String name) {
|
||||
Preconditions.checkNotNull(name, "name");
|
||||
return createCache(name, 200);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(Cache cache) {
|
||||
Preconditions.checkNotNull(cache, "cache");
|
||||
net.sf.ehcache.Cache cache = new net.sf.ehcache.Cache(
|
||||
new CacheConfiguration(name, size)
|
||||
.memoryStoreEvictionPolicy(
|
||||
MemoryStoreEvictionPolicy.LRU)
|
||||
.overflowToDisk(true).eternal(false)
|
||||
.timeToLiveSeconds(60).timeToIdleSeconds(30)
|
||||
.diskPersistent(false)
|
||||
.diskExpiryThreadIntervalSeconds(0));
|
||||
manager.addCache(cache);
|
||||
return new EhCacheFacade<K, V>(cache);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregister(Cache cache) {
|
||||
Preconditions.checkNotNull(cache, "cache");
|
||||
manager.removeCache(cache.getName());
|
||||
public <K, V> Cache<K, V> createEternalCache(String name, int size) {
|
||||
Preconditions.checkNotNull(name, "name");
|
||||
Preconditions.checkArgument(size > 0, "size <= 0");
|
||||
|
||||
net.sf.ehcache.Cache cache = new net.sf.ehcache.Cache(
|
||||
new CacheConfiguration(name, size)
|
||||
.memoryStoreEvictionPolicy(
|
||||
MemoryStoreEvictionPolicy.LRU)
|
||||
.overflowToDisk(true).eternal(true)
|
||||
.diskExpiryThreadIntervalSeconds(0));
|
||||
manager.addCache(cache);
|
||||
return new EhCacheFacade<K, V>(cache);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, V> Cache<K, V> createCache(String name) {
|
||||
net.sf.ehcache.Cache cache = new net.sf.ehcache.Cache(
|
||||
new CacheConfiguration(name, 200)
|
||||
.memoryStoreEvictionPolicy(
|
||||
MemoryStoreEvictionPolicy.LRU)
|
||||
.overflowToDisk(true).eternal(true)
|
||||
.diskExpiryThreadIntervalSeconds(0));
|
||||
manager.addCache(cache);
|
||||
return new EhCacheFacade<K, V>(cache);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, V> void dispose(Cache<K, V> cache) {
|
||||
if (cache instanceof EhCacheFacade) {
|
||||
manager.removeCache(((EhCacheFacade<K, V>) cache).cache.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -136,42 +182,40 @@ public class EhCacheService extends AbstractService implements CacheService {
|
||||
interfaceCache = null;
|
||||
}
|
||||
|
||||
private static class MethodInvocation {
|
||||
private final Method method;
|
||||
private final Object[] args;
|
||||
private class EhCacheFacade<K, V> implements Cache<K, V> {
|
||||
private final net.sf.ehcache.Cache cache;
|
||||
|
||||
public MethodInvocation(Method method, Object[] args) {
|
||||
this.method = method;
|
||||
this.args = args;
|
||||
public EhCacheFacade(net.sf.ehcache.Cache cache) {
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + Arrays.hashCode(args);
|
||||
result = prime * result
|
||||
+ ((method == null) ? 0 : method.hashCode());
|
||||
return result;
|
||||
public void put(K key, V value) {
|
||||
cache.put(new Element(key, value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
MethodInvocation other = (MethodInvocation) obj;
|
||||
if (!Arrays.equals(args, other.args))
|
||||
return false;
|
||||
if (method == null) {
|
||||
if (other.method != null)
|
||||
return false;
|
||||
} else if (!method.equals(other.method))
|
||||
return false;
|
||||
return true;
|
||||
@SuppressWarnings("unchecked")
|
||||
public V get(K key) {
|
||||
final Element element = cache.get(key);
|
||||
if (element == null)
|
||||
return null;
|
||||
return (V) element.getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(K key) {
|
||||
return cache.get(key) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(K key) {
|
||||
cache.remove(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
cache.removeAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
87
src/main/java/com/l2jserver/service/cache/EternalCache.java
vendored
Normal file
87
src/main/java/com/l2jserver/service/cache/EternalCache.java
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* This file is part of l2jserver <l2jserver.com>.
|
||||
*
|
||||
* l2jserver 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.service.cache;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.l2jserver.util.factory.CollectionFactory;
|
||||
|
||||
/**
|
||||
* Cache class for an eternal cache
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*
|
||||
* @param <K>
|
||||
* the key type
|
||||
* @param <V>
|
||||
* the value type
|
||||
*/
|
||||
class EternalCache<K, V> implements Cache<K, V> {
|
||||
protected final Logger log = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
/**
|
||||
* The cache name
|
||||
*/
|
||||
protected final String cacheName;
|
||||
|
||||
/**
|
||||
* Map storing references to cached objects
|
||||
*/
|
||||
protected final Map<K, V> cacheMap = CollectionFactory.newMap();
|
||||
|
||||
/**
|
||||
* @param cacheName
|
||||
* the cache name
|
||||
*/
|
||||
protected EternalCache(String cacheName) {
|
||||
this.cacheName = cacheName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put(K key, V value) {
|
||||
cacheMap.put(key, value);
|
||||
log.debug("{}: added for key: {}", cacheName, key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public V get(K key) {
|
||||
V obj = cacheMap.get(key);
|
||||
if (obj != null)
|
||||
log.debug("{}: obtained for key: {}", cacheName, key);
|
||||
return obj;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(K key) {
|
||||
return cacheMap.containsKey(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(K key) {
|
||||
cacheMap.remove(key);
|
||||
log.debug("{}: removed for key: {}", cacheName, key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
cacheMap.clear();
|
||||
log.debug("{}: cleared", cacheName);
|
||||
}
|
||||
}
|
||||
69
src/main/java/com/l2jserver/service/cache/MethodInvocation.java
vendored
Normal file
69
src/main/java/com/l2jserver/service/cache/MethodInvocation.java
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* This file is part of l2jserver <l2jserver.com>.
|
||||
*
|
||||
* l2jserver 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.service.cache;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Simple class used to store method invocations for the proxied cache.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
class MethodInvocation {
|
||||
/**
|
||||
* The invoked method
|
||||
*/
|
||||
private final Method method;
|
||||
/**
|
||||
* The invocation arguments
|
||||
*/
|
||||
private final Object[] args;
|
||||
|
||||
public MethodInvocation(Method method, Object[] args) {
|
||||
this.method = method;
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + Arrays.hashCode(args);
|
||||
result = prime * result + ((method == null) ? 0 : method.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
MethodInvocation other = (MethodInvocation) obj;
|
||||
if (!Arrays.equals(args, other.args))
|
||||
return false;
|
||||
if (method == null) {
|
||||
if (other.method != null)
|
||||
return false;
|
||||
} else if (!method.equals(other.method))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
164
src/main/java/com/l2jserver/service/cache/SoftCacheService.java
vendored
Normal file
164
src/main/java/com/l2jserver/service/cache/SoftCacheService.java
vendored
Normal file
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* This file is part of l2jserver <l2jserver.com>.
|
||||
*
|
||||
* l2jserver 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.service.cache;
|
||||
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.ReferenceQueue;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.l2jserver.service.AbstractService;
|
||||
import com.l2jserver.service.ServiceStartException;
|
||||
import com.l2jserver.service.ServiceStopException;
|
||||
|
||||
/**
|
||||
* This {@link Cache} service implementation uses a {@link SoftReference} to
|
||||
* store values.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class SoftCacheService extends AbstractService implements CacheService {
|
||||
/**
|
||||
* The interface cache
|
||||
*/
|
||||
private Cache<MethodInvocation, Object> interfaceCache;
|
||||
|
||||
@Override
|
||||
protected void doStart() throws ServiceStartException {
|
||||
interfaceCache = createCache("interface-cache");
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Cacheable> T decorate(final Class<T> interfaceType,
|
||||
final T instance) {
|
||||
Preconditions.checkNotNull(interfaceType, "interfaceType");
|
||||
Preconditions.checkNotNull(instance, "instance");
|
||||
|
||||
if (!interfaceType.isInterface())
|
||||
return null;
|
||||
@SuppressWarnings("unchecked")
|
||||
final T proxy = (T) Proxy.newProxyInstance(this.getClass()
|
||||
.getClassLoader(), new Class[] { interfaceType },
|
||||
new InvocationHandler() {
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method,
|
||||
Object[] args) throws Throwable {
|
||||
if (method.isAnnotationPresent(IgnoreCaching.class))
|
||||
return method.invoke(instance, args);
|
||||
final MethodInvocation invocation = new MethodInvocation(
|
||||
method, args);
|
||||
Object result = interfaceCache.get(invocation);
|
||||
if (result == null)
|
||||
return doInvoke(invocation, proxy, method, args);
|
||||
return result;
|
||||
}
|
||||
|
||||
private Object doInvoke(MethodInvocation invocation,
|
||||
Object proxy, Method method, Object[] args)
|
||||
throws IllegalArgumentException,
|
||||
IllegalAccessException, InvocationTargetException {
|
||||
Object result = method.invoke(instance, args);
|
||||
interfaceCache.put(invocation, result);
|
||||
return result;
|
||||
}
|
||||
});
|
||||
return proxy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, V> Cache<K, V> createCache(String name, int size) {
|
||||
return new SoftCache<K, V>(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, V> Cache<K, V> createEternalCache(String name, int size) {
|
||||
return new EternalCache<K, V>(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, V> Cache<K, V> createCache(String name) {
|
||||
return new SoftCache<K, V>(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, V> void dispose(Cache<K, V> cache) {
|
||||
cache.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doStop() throws ServiceStopException {
|
||||
dispose(interfaceCache);
|
||||
interfaceCache = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class is a simple map implementation for cache usage.<br>
|
||||
* <br>
|
||||
* Value may be stored in map really long, but it for sure will be removed
|
||||
* if there is low memory (and of course there isn't any strong reference to
|
||||
* value object)
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class SoftCache<K, V> extends AbstractReferenceCache<K, V> implements
|
||||
Cache<K, V> {
|
||||
/**
|
||||
* This class is a {@link SoftReference} with additional responsibility
|
||||
* of holding key object
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
private class SoftEntry extends SoftReference<V> {
|
||||
private K key;
|
||||
|
||||
SoftEntry(K key, V referent, ReferenceQueue<? super V> q) {
|
||||
super(referent, q);
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
K getKey() {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
public SoftCache(String cacheName) {
|
||||
super(cacheName);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
protected synchronized void cleanQueue() {
|
||||
SoftEntry en = null;
|
||||
while ((en = (SoftEntry) refQueue.poll()) != null) {
|
||||
K key = en.getKey();
|
||||
if (log.isDebugEnabled())
|
||||
log.debug("{} : cleaned up {} for key: {}", cacheName, key);
|
||||
cacheMap.remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Reference<V> newReference(K key, V value,
|
||||
ReferenceQueue<V> vReferenceQueue) {
|
||||
return new SoftEntry(key, value, vReferenceQueue);
|
||||
}
|
||||
}
|
||||
}
|
||||
164
src/main/java/com/l2jserver/service/cache/WeakCacheService.java
vendored
Normal file
164
src/main/java/com/l2jserver/service/cache/WeakCacheService.java
vendored
Normal file
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* This file is part of l2jserver <l2jserver.com>.
|
||||
*
|
||||
* l2jserver 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.service.cache;
|
||||
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.ReferenceQueue;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.l2jserver.service.AbstractService;
|
||||
import com.l2jserver.service.ServiceStartException;
|
||||
import com.l2jserver.service.ServiceStopException;
|
||||
|
||||
/**
|
||||
* This {@link Cache} service implementation uses a {@link SoftReference} to
|
||||
* store values.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class WeakCacheService extends AbstractService implements CacheService {
|
||||
/**
|
||||
* The interface cache
|
||||
*/
|
||||
private Cache<MethodInvocation, Object> interfaceCache;
|
||||
|
||||
@Override
|
||||
protected void doStart() throws ServiceStartException {
|
||||
interfaceCache = createCache("interface-cache");
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Cacheable> T decorate(final Class<T> interfaceType,
|
||||
final T instance) {
|
||||
Preconditions.checkNotNull(interfaceType, "interfaceType");
|
||||
Preconditions.checkNotNull(instance, "instance");
|
||||
|
||||
if (!interfaceType.isInterface())
|
||||
return null;
|
||||
@SuppressWarnings("unchecked")
|
||||
final T proxy = (T) Proxy.newProxyInstance(this.getClass()
|
||||
.getClassLoader(), new Class[] { interfaceType },
|
||||
new InvocationHandler() {
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method,
|
||||
Object[] args) throws Throwable {
|
||||
if (method.isAnnotationPresent(IgnoreCaching.class))
|
||||
return method.invoke(instance, args);
|
||||
final MethodInvocation invocation = new MethodInvocation(
|
||||
method, args);
|
||||
Object result = interfaceCache.get(invocation);
|
||||
if (result == null)
|
||||
return doInvoke(invocation, proxy, method, args);
|
||||
return result;
|
||||
}
|
||||
|
||||
private Object doInvoke(MethodInvocation invocation,
|
||||
Object proxy, Method method, Object[] args)
|
||||
throws IllegalArgumentException,
|
||||
IllegalAccessException, InvocationTargetException {
|
||||
Object result = method.invoke(instance, args);
|
||||
interfaceCache.put(invocation, result);
|
||||
return result;
|
||||
}
|
||||
});
|
||||
return proxy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, V> Cache<K, V> createCache(String name, int size) {
|
||||
return new WeakCache<K, V>(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, V> Cache<K, V> createEternalCache(String name, int size) {
|
||||
return new EternalCache<K, V>(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, V> Cache<K, V> createCache(String name) {
|
||||
return new WeakCache<K, V>(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, V> void dispose(Cache<K, V> cache) {
|
||||
cache.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doStop() throws ServiceStopException {
|
||||
dispose(interfaceCache);
|
||||
interfaceCache = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class is a simple map implementation for cache usage.<br>
|
||||
* <br>
|
||||
* Values from the map will be removed after the first garbage collector run
|
||||
* if there isn't any strong reference to the value object.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
private class WeakCache<K, V> extends AbstractReferenceCache<K, V>
|
||||
implements Cache<K, V> {
|
||||
/**
|
||||
* This class is a {@link WeakReference} with additional responsibility
|
||||
* of holding key object
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
private class Entry extends WeakReference<V> {
|
||||
private K key;
|
||||
|
||||
Entry(K key, V referent, ReferenceQueue<? super V> q) {
|
||||
super(referent, q);
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
K getKey() {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
WeakCache(String cacheName) {
|
||||
super(cacheName);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
protected synchronized void cleanQueue() {
|
||||
Entry en = null;
|
||||
while ((en = (Entry) refQueue.poll()) != null) {
|
||||
K key = en.getKey();
|
||||
if (log.isDebugEnabled())
|
||||
log.debug("{}: cleaned up for key: {}", cacheName, key);
|
||||
cacheMap.remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Reference<V> newReference(K key, V value,
|
||||
ReferenceQueue<V> vReferenceQueue) {
|
||||
return new Entry(key, value, vReferenceQueue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -28,11 +28,6 @@ import java.util.List;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import net.sf.ehcache.Cache;
|
||||
import net.sf.ehcache.Element;
|
||||
import net.sf.ehcache.config.CacheConfiguration;
|
||||
import net.sf.ehcache.store.MemoryStoreEvictionPolicy;
|
||||
|
||||
import org.apache.commons.dbcp.ConnectionFactory;
|
||||
import org.apache.commons.dbcp.DriverManagerConnectionFactory;
|
||||
import org.apache.commons.dbcp.PoolableConnectionFactory;
|
||||
@@ -53,6 +48,7 @@ import com.l2jserver.service.AbstractService;
|
||||
import com.l2jserver.service.AbstractService.Depends;
|
||||
import com.l2jserver.service.ServiceStartException;
|
||||
import com.l2jserver.service.ServiceStopException;
|
||||
import com.l2jserver.service.cache.Cache;
|
||||
import com.l2jserver.service.cache.CacheService;
|
||||
import com.l2jserver.service.configuration.ConfigurationService;
|
||||
import com.l2jserver.service.core.LoggingService;
|
||||
@@ -105,7 +101,7 @@ public class JDBCDatabaseService extends AbstractService implements
|
||||
/**
|
||||
* An cache object
|
||||
*/
|
||||
private Cache objectCache;
|
||||
private Cache<Object, Object> objectCache;
|
||||
|
||||
@Inject
|
||||
public JDBCDatabaseService(ConfigurationService configService,
|
||||
@@ -125,12 +121,8 @@ public class JDBCDatabaseService extends AbstractService implements
|
||||
|
||||
// cache must be large enough for all world objects, to avoid
|
||||
// duplication... this would endanger non-persistent states
|
||||
objectCache = new Cache(new CacheConfiguration("database-service",
|
||||
IDAllocator.ALLOCABLE_IDS)
|
||||
.memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.LRU)
|
||||
.overflowToDisk(true).eternal(true).diskPersistent(false)
|
||||
.diskExpiryThreadIntervalSeconds(0));
|
||||
cacheService.register(objectCache);
|
||||
objectCache = cacheService.createEternalCache("database-service",
|
||||
IDAllocator.ALLOCABLE_IDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -186,21 +178,18 @@ public class JDBCDatabaseService extends AbstractService implements
|
||||
|
||||
public Object getCachedObject(Object id) {
|
||||
Preconditions.checkNotNull(id, "id");
|
||||
final Element element = objectCache.get(id);
|
||||
if (element == null)
|
||||
return null;
|
||||
return element.getObjectValue();
|
||||
return objectCache.get(id);
|
||||
}
|
||||
|
||||
public boolean hasCachedObject(Object id) {
|
||||
Preconditions.checkNotNull(id, "id");
|
||||
return objectCache.get(id) != null;
|
||||
return objectCache.contains(id);
|
||||
}
|
||||
|
||||
public void updateCache(Object key, Object value) {
|
||||
Preconditions.checkNotNull(key, "key");
|
||||
Preconditions.checkNotNull(value, "value");
|
||||
objectCache.put(new Element(key, value));
|
||||
objectCache.put(key, value);
|
||||
}
|
||||
|
||||
public void removeCache(Object key) {
|
||||
@@ -210,8 +199,7 @@ public class JDBCDatabaseService extends AbstractService implements
|
||||
|
||||
@Override
|
||||
protected void doStop() throws ServiceStopException {
|
||||
if (objectCache != null)
|
||||
objectCache.dispose();
|
||||
cacheService.dispose(objectCache);
|
||||
objectCache = null;
|
||||
|
||||
try {
|
||||
|
||||
@@ -18,7 +18,7 @@ package com.l2jserver.service.game.ai;
|
||||
|
||||
import com.l2jserver.model.world.Actor;
|
||||
import com.l2jserver.service.Service;
|
||||
import com.l2jserver.util.dimensional.Coordinate;
|
||||
import com.l2jserver.util.geometry.Coordinate;
|
||||
|
||||
/**
|
||||
* This service executes AI operations
|
||||
|
||||
@@ -27,7 +27,7 @@ import com.l2jserver.service.game.template.TemplateService;
|
||||
import com.l2jserver.service.game.world.WorldService;
|
||||
import com.l2jserver.service.game.world.event.WorldEventDispatcher;
|
||||
import com.l2jserver.service.network.NetworkService;
|
||||
import com.l2jserver.util.dimensional.Coordinate;
|
||||
import com.l2jserver.util.geometry.Coordinate;
|
||||
|
||||
/**
|
||||
* Default implementation for {@link AIService}.
|
||||
|
||||
@@ -18,7 +18,7 @@ package com.l2jserver.service.game.ai.script;
|
||||
|
||||
import com.l2jserver.model.world.PositionableObject;
|
||||
import com.l2jserver.service.game.ai.AIScript;
|
||||
import com.l2jserver.util.dimensional.Coordinate;
|
||||
import com.l2jserver.util.geometry.Coordinate;
|
||||
|
||||
/**
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a
|
||||
|
||||
@@ -23,8 +23,8 @@ import com.l2jserver.service.game.npc.NotAttackableNPCServiceException;
|
||||
import com.l2jserver.service.game.spawn.AlreadySpawnedServiceException;
|
||||
import com.l2jserver.service.game.spawn.NotSpawnedServiceException;
|
||||
import com.l2jserver.service.game.spawn.SpawnPointNotFoundServiceException;
|
||||
import com.l2jserver.util.dimensional.Coordinate;
|
||||
import com.l2jserver.util.dimensional.Point;
|
||||
import com.l2jserver.util.geometry.Coordinate;
|
||||
import com.l2jserver.util.geometry.Point3D;
|
||||
|
||||
/**
|
||||
* This service manages {@link L2Character} instances
|
||||
@@ -132,7 +132,7 @@ public interface CharacterService extends Service {
|
||||
* @param point
|
||||
* the validated point
|
||||
*/
|
||||
void validate(L2Character character, Point point);
|
||||
void validate(L2Character character, Point3D point);
|
||||
|
||||
/**
|
||||
* Called when received the validation of the position of an character
|
||||
@@ -142,7 +142,7 @@ public interface CharacterService extends Service {
|
||||
* @param point
|
||||
* the validated point
|
||||
*/
|
||||
void receivedValidation(L2Character character, Point point);
|
||||
void receivedValidation(L2Character character, Point3D point);
|
||||
|
||||
/**
|
||||
* Set the character to walking mode
|
||||
|
||||
@@ -74,8 +74,8 @@ import com.l2jserver.service.game.world.filter.impl.IDFilter;
|
||||
import com.l2jserver.service.game.world.filter.impl.KnownListFilter;
|
||||
import com.l2jserver.service.game.world.filter.impl.KnownListUpdateFilter;
|
||||
import com.l2jserver.service.network.NetworkService;
|
||||
import com.l2jserver.util.dimensional.Coordinate;
|
||||
import com.l2jserver.util.dimensional.Point;
|
||||
import com.l2jserver.util.geometry.Coordinate;
|
||||
import com.l2jserver.util.geometry.Point3D;
|
||||
|
||||
/**
|
||||
* Default implementation for {@link CharacterService}.
|
||||
@@ -417,21 +417,21 @@ public class CharacterServiceImpl extends AbstractService implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate(L2Character character, Point point) {
|
||||
public void validate(L2Character character, Point3D point) {
|
||||
Preconditions.checkNotNull(character, "character");
|
||||
Preconditions.checkNotNull(point, "point");
|
||||
// TODO implement position validation
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receivedValidation(L2Character character, Point point) {
|
||||
public void receivedValidation(L2Character character, Point3D point) {
|
||||
Preconditions.checkNotNull(character, "character");
|
||||
Preconditions.checkNotNull(point, "point");
|
||||
if (character.isTeleporting())
|
||||
// ignore while teleporting, for some reason the client sends a
|
||||
// validation just before teleport packet
|
||||
return;
|
||||
final Point old = character.getPoint();
|
||||
final Point3D old = character.getPoint();
|
||||
character.setPoint(point);
|
||||
eventDispatcher.dispatch(new CharacterMoveEvent(character, old));
|
||||
|
||||
|
||||
@@ -37,8 +37,8 @@ import com.l2jserver.service.game.character.CharacterService;
|
||||
import com.l2jserver.service.game.world.WorldService;
|
||||
import com.l2jserver.service.game.world.event.TypedWorldListener;
|
||||
import com.l2jserver.service.game.world.event.WorldEventDispatcher;
|
||||
import com.l2jserver.util.dimensional.Coordinate;
|
||||
import com.l2jserver.util.dimensional.Point;
|
||||
import com.l2jserver.util.geometry.Coordinate;
|
||||
import com.l2jserver.util.geometry.Point3D;
|
||||
|
||||
/**
|
||||
* <h1>This implementation does not validate pathing!</h1>
|
||||
@@ -97,7 +97,7 @@ public class MapperPathingService extends AbstractService implements
|
||||
CharacterMoveEvent.class) {
|
||||
@Override
|
||||
protected boolean dispatch(CharacterMoveEvent e) {
|
||||
final Point point = e.getPoint();
|
||||
final Point3D point = e.getPoint();
|
||||
final CoordinateStruct struct = CoordinateStruct
|
||||
.fromCoordinate(point.getCoordinate());
|
||||
try {
|
||||
|
||||
@@ -24,8 +24,8 @@ import com.l2jserver.model.world.event.SpawnEvent;
|
||||
import com.l2jserver.model.world.player.event.PlayerTeleportedEvent;
|
||||
import com.l2jserver.model.world.player.event.PlayerTeleportingEvent;
|
||||
import com.l2jserver.service.Service;
|
||||
import com.l2jserver.util.dimensional.Coordinate;
|
||||
import com.l2jserver.util.dimensional.Point;
|
||||
import com.l2jserver.util.geometry.Coordinate;
|
||||
import com.l2jserver.util.geometry.Point3D;
|
||||
|
||||
/**
|
||||
* This service is responsible for spawning monsters, npcs and players.
|
||||
@@ -50,7 +50,7 @@ public interface SpawnService extends Service {
|
||||
* @throws AlreadySpawnedServiceException
|
||||
* if the object is already spawned in the world
|
||||
*/
|
||||
void spawn(PositionableObject object, Point point)
|
||||
void spawn(PositionableObject object, Point3D point)
|
||||
throws SpawnPointNotFoundServiceException,
|
||||
AlreadySpawnedServiceException;
|
||||
|
||||
|
||||
@@ -37,8 +37,8 @@ import com.l2jserver.service.AbstractService.Depends;
|
||||
import com.l2jserver.service.game.world.WorldService;
|
||||
import com.l2jserver.service.game.world.event.WorldEventDispatcher;
|
||||
import com.l2jserver.service.network.NetworkService;
|
||||
import com.l2jserver.util.dimensional.Coordinate;
|
||||
import com.l2jserver.util.dimensional.Point;
|
||||
import com.l2jserver.util.geometry.Coordinate;
|
||||
import com.l2jserver.util.geometry.Point3D;
|
||||
|
||||
/**
|
||||
* Default implementation for {@link SpawnService}
|
||||
@@ -69,7 +69,7 @@ public class SpawnServiceImpl extends AbstractService implements SpawnService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void spawn(PositionableObject object, Point point)
|
||||
public void spawn(PositionableObject object, Point3D point)
|
||||
throws SpawnPointNotFoundServiceException {
|
||||
Preconditions.checkNotNull(object, "object");
|
||||
// sanitize
|
||||
|
||||
@@ -96,11 +96,6 @@ public class ScriptTemplateService extends AbstractService implements
|
||||
// TODO templates.remove(t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
context.reload();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doStop() throws ServiceStopException {
|
||||
if (context.isInitialized())
|
||||
|
||||
@@ -31,9 +31,4 @@ public interface TemplateService extends Service {
|
||||
* @return the template
|
||||
*/
|
||||
<T extends Template<?>> T getTemplate(TemplateID<T, ?> id);
|
||||
|
||||
/**
|
||||
* Reload the template list.
|
||||
*/
|
||||
void reload();
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ package com.l2jserver.service.game.template;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.JAXBException;
|
||||
@@ -46,22 +45,25 @@ import com.l2jserver.service.AbstractService;
|
||||
import com.l2jserver.service.AbstractService.Depends;
|
||||
import com.l2jserver.service.ServiceStartException;
|
||||
import com.l2jserver.service.ServiceStopException;
|
||||
import com.l2jserver.service.cache.Cache;
|
||||
import com.l2jserver.service.cache.CacheService;
|
||||
import com.l2jserver.service.configuration.ConfigurationService;
|
||||
import com.l2jserver.service.core.LoggingService;
|
||||
import com.l2jserver.service.core.vfs.VFSService;
|
||||
import com.l2jserver.util.factory.CollectionFactory;
|
||||
import com.l2jserver.util.jaxb.CharacterTemplateIDAdapter;
|
||||
import com.l2jserver.util.jaxb.ItemTemplateIDAdapter;
|
||||
import com.l2jserver.util.jaxb.NPCTemplateIDAdapter;
|
||||
import com.l2jserver.util.jaxb.TeleportationTemplateIDAdapter;
|
||||
import com.l2jserver.util.vfs.ExtensionFileSelector;
|
||||
|
||||
@Depends({ LoggingService.class, VFSService.class, ConfigurationService.class })
|
||||
@Depends({ LoggingService.class, VFSService.class, CacheService.class,
|
||||
ConfigurationService.class })
|
||||
public class XMLTemplateService extends AbstractService implements
|
||||
TemplateService {
|
||||
private final Logger log = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
private final VFSService vfsService;
|
||||
private final CacheService cacheService;
|
||||
|
||||
private final XMLTemplateServiceConfiguration config;
|
||||
private final NPCTemplateIDAdapter npcTemplateIdAdapter;
|
||||
@@ -73,16 +75,17 @@ public class XMLTemplateService extends AbstractService implements
|
||||
private Unmarshaller unmarshaller;
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
private Map<TemplateID, Template> templates = CollectionFactory.newMap();
|
||||
private Cache<TemplateID, Template> templates;
|
||||
|
||||
@Inject
|
||||
public XMLTemplateService(final VFSService vfsService,
|
||||
ConfigurationService configService,
|
||||
CacheService cacheService, ConfigurationService configService,
|
||||
NPCTemplateIDAdapter npcTemplateIdAdapter,
|
||||
ItemTemplateIDAdapter itemTemplateIdAdapter,
|
||||
CharacterTemplateIDAdapter charIdTemplateAdapter,
|
||||
TeleportationTemplateIDAdapter teleportationIdTemplateAdapter) {
|
||||
this.vfsService = vfsService;
|
||||
this.cacheService = cacheService;
|
||||
this.config = configService.get(XMLTemplateServiceConfiguration.class);
|
||||
this.npcTemplateIdAdapter = npcTemplateIdAdapter;
|
||||
this.itemTemplateIdAdapter = itemTemplateIdAdapter;
|
||||
@@ -92,6 +95,7 @@ public class XMLTemplateService extends AbstractService implements
|
||||
|
||||
@Override
|
||||
protected void doStart() throws ServiceStartException {
|
||||
templates = cacheService.createEternalCache("templates", 100 * 1000);
|
||||
try {
|
||||
log.debug("Creating JAXBContext instance");
|
||||
context = JAXBContext.newInstance(CharacterTemplate.class,
|
||||
@@ -112,9 +116,9 @@ public class XMLTemplateService extends AbstractService implements
|
||||
|
||||
final FileObject root = vfsService.resolve(config
|
||||
.getTemplateDirectory());
|
||||
|
||||
|
||||
log.info("Scanning {} for XML templates", root);
|
||||
|
||||
|
||||
FileObject[] files = root.findFiles(ExtensionFileSelector
|
||||
.ext("xml"));
|
||||
|
||||
@@ -167,15 +171,10 @@ public class XMLTemplateService extends AbstractService implements
|
||||
templates.remove(template.getID());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doStop() throws ServiceStopException {
|
||||
templates.clear();
|
||||
cacheService.dispose(templates);
|
||||
templates = null;
|
||||
unmarshaller = null;
|
||||
context = null;
|
||||
}
|
||||
|
||||
@@ -18,11 +18,6 @@ package com.l2jserver.service.game.world;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import net.sf.ehcache.Cache;
|
||||
import net.sf.ehcache.Element;
|
||||
import net.sf.ehcache.config.CacheConfiguration;
|
||||
import net.sf.ehcache.store.MemoryStoreEvictionPolicy;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.inject.Inject;
|
||||
import com.l2jserver.db.dao.CharacterDAO;
|
||||
@@ -35,6 +30,7 @@ import com.l2jserver.service.AbstractService;
|
||||
import com.l2jserver.service.AbstractService.Depends;
|
||||
import com.l2jserver.service.ServiceStartException;
|
||||
import com.l2jserver.service.ServiceStopException;
|
||||
import com.l2jserver.service.cache.Cache;
|
||||
import com.l2jserver.service.cache.CacheService;
|
||||
import com.l2jserver.service.database.DatabaseService;
|
||||
|
||||
@@ -73,7 +69,7 @@ public class CachedWorldIDService extends AbstractService implements
|
||||
/**
|
||||
* The ID cache
|
||||
*/
|
||||
private Cache cache;
|
||||
private Cache<Integer, ObjectID<?>> cache;
|
||||
|
||||
/**
|
||||
* The loaded state
|
||||
@@ -94,12 +90,8 @@ public class CachedWorldIDService extends AbstractService implements
|
||||
@Override
|
||||
protected void doStart() throws ServiceStartException {
|
||||
// we allocate an cache which can fit all ids
|
||||
cache = new Cache(new CacheConfiguration("id-cache",
|
||||
IDAllocator.ALLOCABLE_IDS)
|
||||
.memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.LRU)
|
||||
.overflowToDisk(true).eternal(true).diskPersistent(false)
|
||||
.diskExpiryThreadIntervalSeconds(0));
|
||||
cacheService.register(cache);
|
||||
cache = cacheService.createEternalCache("id-cache",
|
||||
IDAllocator.ALLOCABLE_IDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -112,7 +104,7 @@ public class CachedWorldIDService extends AbstractService implements
|
||||
|
||||
@Override
|
||||
public void unload() {
|
||||
cache.removeAll();
|
||||
cache.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -137,17 +129,13 @@ public class CachedWorldIDService extends AbstractService implements
|
||||
// ignore resolving before all IDs are loaded
|
||||
return null;
|
||||
}
|
||||
|
||||
final Element element = cache.get(id);
|
||||
if (element == null)
|
||||
return null;
|
||||
return (I) element.getObjectValue();
|
||||
return (I) cache.get(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <I extends ObjectID<?>> void add(I id) {
|
||||
Preconditions.checkNotNull(id, "id");
|
||||
cache.put(new Element(id.getID(), id));
|
||||
cache.put(id.getID(), id);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -158,7 +146,7 @@ public class CachedWorldIDService extends AbstractService implements
|
||||
|
||||
@Override
|
||||
protected void doStop() throws ServiceStopException {
|
||||
cacheService.unregister(cache);
|
||||
cacheService.dispose(cache);
|
||||
cache = null;
|
||||
allocator.clear();
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ import com.l2jserver.model.world.PositionableObject;
|
||||
import com.l2jserver.model.world.WorldObject;
|
||||
import com.l2jserver.service.game.world.filter.AndFilter;
|
||||
import com.l2jserver.service.game.world.filter.NotFilter;
|
||||
import com.l2jserver.util.dimensional.Point;
|
||||
import com.l2jserver.util.geometry.Point3D;
|
||||
|
||||
/**
|
||||
* This filter will only accept {@link WorldObject} which are in vision of
|
||||
@@ -32,7 +32,7 @@ public class KnownListUpdateFilter extends AndFilter<PositionableObject> {
|
||||
public static final int KNOWNLIST_RANGE = 2000;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public KnownListUpdateFilter(PositionableObject object, Point old) {
|
||||
public KnownListUpdateFilter(PositionableObject object, Point3D old) {
|
||||
super(new KnownListFilter(object), new NotFilter<PositionableObject>(
|
||||
new RangePointFilter(old, KNOWNLIST_RANGE)));
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ package com.l2jserver.service.game.world.filter.impl;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.l2jserver.model.world.PositionableObject;
|
||||
import com.l2jserver.service.game.world.filter.WorldObjectFilter;
|
||||
import com.l2jserver.util.dimensional.Point;
|
||||
import com.l2jserver.util.geometry.Point3D;
|
||||
|
||||
/**
|
||||
* Filter objects that are in the <tt>range</tt> of <tt>coordinate</tt>
|
||||
@@ -30,7 +30,7 @@ public class RangePointFilter implements WorldObjectFilter<PositionableObject> {
|
||||
/**
|
||||
* The coordinate point
|
||||
*/
|
||||
private final Point point;
|
||||
private final Point3D point;
|
||||
/**
|
||||
* The desired maximum distance of the object
|
||||
*/
|
||||
@@ -44,7 +44,7 @@ public class RangePointFilter implements WorldObjectFilter<PositionableObject> {
|
||||
* @param range
|
||||
* the desired maximum distance of the object
|
||||
*/
|
||||
public RangePointFilter(final Point point, final int range) {
|
||||
public RangePointFilter(final Point3D point, final int range) {
|
||||
Preconditions.checkNotNull(point, "point");
|
||||
Preconditions.checkState(range >= 0, "range < 0");
|
||||
this.point = point;
|
||||
|
||||
211
src/main/java/com/l2jserver/util/MathUtil.java
Normal file
211
src/main/java/com/l2jserver/util/MathUtil.java
Normal file
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
* This file is part of l2jserver <l2jserver.com>.
|
||||
*
|
||||
* l2jserver 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.util;
|
||||
|
||||
import com.l2jserver.util.geometry.Point;
|
||||
import com.l2jserver.util.geometry.Point3D;
|
||||
|
||||
/**
|
||||
* Class with basic math.<br>
|
||||
* Thanks to:
|
||||
* <ul>
|
||||
* <li>http://geom-java.sourceforge.net/</li>
|
||||
* <li>
|
||||
* http://local.wasp.uwa.edu.au/~pbourke/geometry/pointline/DistancePoint.java</li>
|
||||
* </ul>
|
||||
* <br>
|
||||
* <br>
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class MathUtil {
|
||||
/**
|
||||
* Returns distance between two 2D points
|
||||
*
|
||||
* @param point1
|
||||
* first point
|
||||
* @param point2
|
||||
* second point
|
||||
* @return distance between points
|
||||
*/
|
||||
public static double getDistance(Point point1, Point point2) {
|
||||
return getDistance(point1.x, point1.y, point2.x, point2.y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns distance between two sets of coords
|
||||
*
|
||||
* @param x1
|
||||
* first x coord
|
||||
* @param y1
|
||||
* first y coord
|
||||
* @param x2
|
||||
* second x coord
|
||||
* @param y2
|
||||
* second y coord
|
||||
* @return distance between sets of coords
|
||||
*/
|
||||
public static double getDistance(int x1, int y1, int x2, int y2) {
|
||||
// using long to avoid possible overflows when multiplying
|
||||
long dx = x2 - x1;
|
||||
long dy = y2 - y1;
|
||||
|
||||
// return Math.hypot(x2 - x1, y2 - y1); // Extremely slow
|
||||
// return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)); // 20 times faster
|
||||
// than hypot
|
||||
return Math.sqrt(dx * dx + dy * dy); // 10 times faster then previous
|
||||
// line
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns distance between two 3D points
|
||||
*
|
||||
* @param point1
|
||||
* first point
|
||||
* @param point2
|
||||
* second point
|
||||
* @return distance between points
|
||||
*/
|
||||
public static double getDistance(Point3D point1, Point3D point2) {
|
||||
return getDistance(point1.getX(), point1.getY(), point1.getZ(),
|
||||
point2.getX(), point2.getY(), point2.getZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns distance between 3D set of coords
|
||||
*
|
||||
* @param x1
|
||||
* first x coord
|
||||
* @param y1
|
||||
* first y coord
|
||||
* @param z1
|
||||
* first z coord
|
||||
* @param x2
|
||||
* second x coord
|
||||
* @param y2
|
||||
* second y coord
|
||||
* @param z2
|
||||
* second z coord
|
||||
* @return distance between coords
|
||||
*/
|
||||
public static double getDistance(float x1, float y1, float z1, float x2,
|
||||
float y2, float z2) {
|
||||
float dx = x1 - x2;
|
||||
float dy = y1 - y2;
|
||||
float dz = z1 - z2;
|
||||
|
||||
// We should avoid Math.pow or Math.hypot due to performance reasons
|
||||
return Math.sqrt(dx * dx + dy * dy + dz * dz);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns closest point on segment to point
|
||||
*
|
||||
* @param ss
|
||||
* segment start point
|
||||
* @param se
|
||||
* segment end point
|
||||
* @param p
|
||||
* point to found closest point on segment
|
||||
* @return closest point on segment to p
|
||||
*/
|
||||
public static Point getClosestPointOnSegment(Point ss, Point se, Point p) {
|
||||
return getClosestPointOnSegment(ss.x, ss.y, se.x, se.y, p.x, p.y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns closest point on segment to point
|
||||
*
|
||||
* @param sx1
|
||||
* segment x coord 1
|
||||
* @param sy1
|
||||
* segment y coord 1
|
||||
* @param sx2
|
||||
* segment x coord 2
|
||||
* @param sy2
|
||||
* segment y coord 2
|
||||
* @param px
|
||||
* point x coord
|
||||
* @param py
|
||||
* point y coord
|
||||
* @return closets point on segment to point
|
||||
*/
|
||||
public static Point getClosestPointOnSegment(int sx1, int sy1, int sx2,
|
||||
int sy2, int px, int py) {
|
||||
double xDelta = sx2 - sx1;
|
||||
double yDelta = sy2 - sy1;
|
||||
|
||||
if ((xDelta == 0) && (yDelta == 0)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Segment start equals segment end");
|
||||
}
|
||||
|
||||
double u = ((px - sx1) * xDelta + (py - sy1) * yDelta)
|
||||
/ (xDelta * xDelta + yDelta * yDelta);
|
||||
|
||||
final Point closestPoint;
|
||||
if (u < 0) {
|
||||
closestPoint = new Point(sx1, sy1);
|
||||
} else if (u > 1) {
|
||||
closestPoint = new Point(sx2, sy2);
|
||||
} else {
|
||||
closestPoint = new Point((int) Math.round(sx1 + u * xDelta),
|
||||
(int) Math.round(sy1 + u * yDelta));
|
||||
}
|
||||
|
||||
return closestPoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns distance to segment
|
||||
*
|
||||
* @param ss
|
||||
* segment start point
|
||||
* @param se
|
||||
* segment end point
|
||||
* @param p
|
||||
* point to found closest point on segment
|
||||
* @return distance to segment
|
||||
*/
|
||||
public static double getDistanceToSegment(Point ss, Point se, Point p) {
|
||||
return getDistanceToSegment(ss.x, ss.y, se.x, se.y, p.x, p.y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns distance to segment
|
||||
*
|
||||
* @param sx1
|
||||
* segment x coord 1
|
||||
* @param sy1
|
||||
* segment y coord 1
|
||||
* @param sx2
|
||||
* segment x coord 2
|
||||
* @param sy2
|
||||
* segment y coord 2
|
||||
* @param px
|
||||
* point x coord
|
||||
* @param py
|
||||
* point y coord
|
||||
* @return distance to segment
|
||||
*/
|
||||
public static double getDistanceToSegment(int sx1, int sy1, int sx2,
|
||||
int sy2, int px, int py) {
|
||||
Point closestPoint = getClosestPointOnSegment(sx1, sy1, sx2, sy2, px,
|
||||
py);
|
||||
return getDistance(closestPoint.x, closestPoint.y, px, py);
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
package com.l2jserver.util.factory;
|
||||
|
||||
import java.lang.ref.ReferenceQueue;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -81,6 +82,15 @@ public class CollectionFactory {
|
||||
return new PriorityQueue<T>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new reference queue of type <tt>T</tt>
|
||||
*
|
||||
* @return the created queue
|
||||
*/
|
||||
public static final <T> ReferenceQueue<T> newReferenceQueue() {
|
||||
return new ReferenceQueue<T>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new map.
|
||||
*
|
||||
|
||||
125
src/main/java/com/l2jserver/util/geometry/AbstractArea.java
Normal file
125
src/main/java/com/l2jserver/util/geometry/AbstractArea.java
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* This file is part of l2jserver <l2jserver.com>.
|
||||
*
|
||||
* l2jserver 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.util.geometry;
|
||||
|
||||
/**
|
||||
* Class with basic method implementation for areas.<br>
|
||||
* If possible it should be subclassed. <br>
|
||||
* In other case {@link Area} should be implemented directly
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public abstract class AbstractArea implements Area {
|
||||
/**
|
||||
* Minimal z of area
|
||||
*/
|
||||
private final int minZ;
|
||||
|
||||
/**
|
||||
* Maximal Z of area
|
||||
*/
|
||||
private final int maxZ;
|
||||
|
||||
/**
|
||||
* Creates new AbstractArea with min and max z
|
||||
*
|
||||
* @param minZ
|
||||
* min z
|
||||
* @param maxZ
|
||||
* max z
|
||||
*/
|
||||
protected AbstractArea(int minZ, int maxZ) {
|
||||
if (minZ > maxZ) {
|
||||
throw new IllegalArgumentException("minZ(" + minZ + ") > maxZ("
|
||||
+ maxZ + ")");
|
||||
}
|
||||
this.minZ = minZ;
|
||||
this.maxZ = maxZ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInside2D(Point point) {
|
||||
return isInside2D(point.x, point.y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInside3D(Point3D point) {
|
||||
return isInside3D(point.getX(), point.getY(), point.getZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInside3D(int x, int y, int z) {
|
||||
return isInsideZ(z) && isInside2D(x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInsideZ(Point3D point) {
|
||||
return isInsideZ(point.getZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInsideZ(int z) {
|
||||
return z >= getMinZ() && z <= getMaxZ();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDistance2D(Point point) {
|
||||
return getDistance2D(point.x, point.y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDistance3D(Point3D point) {
|
||||
return getDistance3D(point.getX(), point.getY(), point.getZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Point getClosestPoint(Point point) {
|
||||
return getClosestPoint(point.x, point.y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Point3D getClosestPoint(Point3D point) {
|
||||
return getClosestPoint(point.getX(), point.getY(), point.getZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Point3D getClosestPoint(int x, int y, int z) {
|
||||
Point closest2d = getClosestPoint(x, y);
|
||||
|
||||
int zCoord;
|
||||
|
||||
if (isInsideZ(z)) {
|
||||
zCoord = z;
|
||||
} else if (z < getMinZ()) {
|
||||
zCoord = getMinZ();
|
||||
} else {
|
||||
zCoord = getMaxZ();
|
||||
}
|
||||
|
||||
return new Point3D(closest2d.x, closest2d.y, zCoord);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinZ() {
|
||||
return minZ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxZ() {
|
||||
return maxZ;
|
||||
}
|
||||
}
|
||||
196
src/main/java/com/l2jserver/util/geometry/Area.java
Normal file
196
src/main/java/com/l2jserver/util/geometry/Area.java
Normal file
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* This file is part of l2jserver <l2jserver.com>.
|
||||
*
|
||||
* l2jserver 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.util.geometry;
|
||||
|
||||
/**
|
||||
* Basic interface for all areas.<br>
|
||||
* It should be implemented in different ways for performance reasons.<br>
|
||||
* For instance, we don't need complex math for squares or circles, but we need
|
||||
* it for more complex polygons.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public interface Area {
|
||||
/**
|
||||
* Returns true if point is inside area ignoring z value
|
||||
*
|
||||
* @param point
|
||||
* point to check
|
||||
* @return point is inside or not
|
||||
*/
|
||||
boolean isInside2D(Point point);
|
||||
|
||||
/**
|
||||
* Returns true if coords are inside area ignoring z value
|
||||
*
|
||||
* @param x
|
||||
* x coord
|
||||
* @param y
|
||||
* y coord
|
||||
* @return coords are inside or not
|
||||
*/
|
||||
boolean isInside2D(int x, int y);
|
||||
|
||||
/**
|
||||
* Returns true if point is inside area
|
||||
*
|
||||
* @param point
|
||||
* point to check
|
||||
* @return true if point is inside
|
||||
*/
|
||||
boolean isInside3D(Point3D point);
|
||||
|
||||
/**
|
||||
* Returns true if coors are inside area
|
||||
*
|
||||
* @param x
|
||||
* x coord
|
||||
* @param y
|
||||
* y coord
|
||||
* @param z
|
||||
* z coord
|
||||
* @return true if coords are inside
|
||||
*/
|
||||
boolean isInside3D(int x, int y, int z);
|
||||
|
||||
/**
|
||||
* Checks if z coord is insize
|
||||
*
|
||||
* @param point
|
||||
* point to check
|
||||
* @return is z inside or not
|
||||
*/
|
||||
boolean isInsideZ(Point3D point);
|
||||
|
||||
/**
|
||||
* Checks is z coord is inside
|
||||
*
|
||||
* @param z
|
||||
* z coord
|
||||
* @return is z inside or not
|
||||
*/
|
||||
boolean isInsideZ(int z);
|
||||
|
||||
/**
|
||||
* Returns distance from point to closest point of this area ignoring z.<br>
|
||||
* Returns 0 if point is inside area.
|
||||
*
|
||||
* @param point
|
||||
* point to calculate distance from
|
||||
* @return distance or 0 if is inside area
|
||||
*/
|
||||
double getDistance2D(Point point);
|
||||
|
||||
/**
|
||||
* Returns distance from point to closest point of this area ignoring z.<br>
|
||||
* Returns 0 point is inside area.
|
||||
*
|
||||
* @param x
|
||||
* x coord
|
||||
* @param y
|
||||
* y coord
|
||||
* @return distance or 0 if is inside area
|
||||
*/
|
||||
double getDistance2D(int x, int y);
|
||||
|
||||
/**
|
||||
* Returns distance from point to this area.<br>
|
||||
* Returns 0 if is inside.
|
||||
*
|
||||
* @param point
|
||||
* point to check
|
||||
* @return distance or 0 if is inside
|
||||
*/
|
||||
double getDistance3D(Point3D point);
|
||||
|
||||
/**
|
||||
* Returns distance from coords to this area
|
||||
*
|
||||
* @param x
|
||||
* x coord
|
||||
* @param y
|
||||
* y coord
|
||||
* @param z
|
||||
* z coord
|
||||
* @return distance or 0 if is inside
|
||||
*/
|
||||
double getDistance3D(int x, int y, int z);
|
||||
|
||||
/**
|
||||
* Returns closest point of area to given point.<br>
|
||||
* Returns point with coords = point arg if is inside
|
||||
*
|
||||
* @param point
|
||||
* point to check
|
||||
* @return closest point
|
||||
*/
|
||||
Point getClosestPoint(Point point);
|
||||
|
||||
/**
|
||||
* Returns closest point of area to given coords.<br>
|
||||
* Returns point with coords x and y if coords are inside
|
||||
*
|
||||
* @param x
|
||||
* x coord
|
||||
* @param y
|
||||
* y coord
|
||||
* @return closest point
|
||||
*/
|
||||
Point getClosestPoint(int x, int y);
|
||||
|
||||
/**
|
||||
* Returns closest point of area to given point.<br>
|
||||
* Works exactly like {@link #getClosestPoint(int, int)} if
|
||||
* {@link #isInsideZ(int)} returns true.<br>
|
||||
* In other case closest z edge is set as z coord.
|
||||
*
|
||||
* @param point
|
||||
* point to check
|
||||
* @return closest point of area to point
|
||||
*/
|
||||
Point3D getClosestPoint(Point3D point);
|
||||
|
||||
/**
|
||||
* Returns closest point of area to given coords.<br>
|
||||
* Works exactly like {@link #getClosestPoint(int, int)} if
|
||||
* {@link #isInsideZ(int)} returns true.<br>
|
||||
* In other case closest z edge is set as z coord.
|
||||
*
|
||||
* @param x
|
||||
* x coord
|
||||
* @param y
|
||||
* y coord
|
||||
* @param z
|
||||
* z coord
|
||||
* @return closest point of area to point
|
||||
*/
|
||||
Point3D getClosestPoint(int x, int y, int z);
|
||||
|
||||
/**
|
||||
* Return minimal z of this area
|
||||
*
|
||||
* @return minimal z of this area
|
||||
*/
|
||||
int getMinZ();
|
||||
|
||||
/**
|
||||
* Returns maximal z of this area
|
||||
*
|
||||
* @return maximal z of this area
|
||||
*/
|
||||
int getMaxZ();
|
||||
}
|
||||
@@ -14,7 +14,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with l2jserver. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.util.dimensional;
|
||||
package com.l2jserver.util.geometry;
|
||||
|
||||
import org.apache.commons.math.geometry.Vector3D;
|
||||
|
||||
@@ -91,7 +91,7 @@ public class Coordinate {
|
||||
return "Coordinate [" + vector + "]";
|
||||
}
|
||||
|
||||
public Point toPoint() {
|
||||
return new Point(this, 0);
|
||||
public Point3D toPoint() {
|
||||
return new Point3D(this, 0);
|
||||
}
|
||||
}
|
||||
122
src/main/java/com/l2jserver/util/geometry/CylinderArea.java
Normal file
122
src/main/java/com/l2jserver/util/geometry/CylinderArea.java
Normal file
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* This file is part of l2jserver <l2jserver.com>.
|
||||
*
|
||||
* l2jserver 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.util.geometry;
|
||||
|
||||
import com.l2jserver.util.MathUtil;
|
||||
|
||||
/**
|
||||
* This class implements cylinder area
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class CylinderArea extends AbstractArea {
|
||||
/**
|
||||
* Center of cylinder
|
||||
*/
|
||||
private final int centerX;
|
||||
/**
|
||||
* Center of cylinder
|
||||
*/
|
||||
private final int centerY;
|
||||
/**
|
||||
* Cylinder radius
|
||||
*/
|
||||
private final int radius;
|
||||
|
||||
/**
|
||||
* Creates new cylinder with given radius
|
||||
*
|
||||
* @param center
|
||||
* center of the circle
|
||||
* @param radius
|
||||
* radius of the circle
|
||||
* @param minZ
|
||||
* min z
|
||||
* @param maxZ
|
||||
* max z
|
||||
*/
|
||||
public CylinderArea(Point center, int radius, int minZ, int maxZ) {
|
||||
this(center.x, center.y, radius, minZ, maxZ);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new cylider with given radius
|
||||
*
|
||||
* @param x
|
||||
* center coord
|
||||
* @param y
|
||||
* center coord
|
||||
* @param radius
|
||||
* radius of the circle
|
||||
* @param minZ
|
||||
* min z
|
||||
* @param maxZ
|
||||
* max z
|
||||
*/
|
||||
public CylinderArea(int x, int y, int radius, int minZ, int maxZ) {
|
||||
super(minZ, maxZ);
|
||||
this.centerX = x;
|
||||
this.centerY = y;
|
||||
this.radius = radius;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInside2D(int x, int y) {
|
||||
return MathUtil.getDistance(centerX, centerY, x, y) < radius;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDistance2D(int x, int y) {
|
||||
if (isInside2D(x, y)) {
|
||||
return 0;
|
||||
} else {
|
||||
return Math.abs(MathUtil.getDistance(centerX, centerY, x, y)
|
||||
- radius);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDistance3D(int x, int y, int z) {
|
||||
if (isInside3D(x, y, z)) {
|
||||
return 0;
|
||||
} else if (isInsideZ(z)) {
|
||||
return getDistance2D(x, y);
|
||||
} else {
|
||||
if (z < getMinZ()) {
|
||||
return MathUtil.getDistance(centerX, centerY, getMinZ(), x, y,
|
||||
z);
|
||||
} else {
|
||||
return MathUtil.getDistance(centerX, centerY, getMaxZ(), x, y,
|
||||
z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Point getClosestPoint(int x, int y) {
|
||||
if (isInside2D(x, y)) {
|
||||
return new Point(x, y);
|
||||
} else {
|
||||
int vX = x - this.centerX;
|
||||
int vY = y - this.centerY;
|
||||
double magV = MathUtil.getDistance(centerX, centerY, x, y);
|
||||
double pointX = centerX + vX / magV * radius;
|
||||
double pointY = centerY + vY / magV * radius;
|
||||
return new Point((int) Math.round(pointX), (int) Math.round(pointY));
|
||||
}
|
||||
}
|
||||
}
|
||||
50
src/main/java/com/l2jserver/util/geometry/Point.java
Normal file
50
src/main/java/com/l2jserver/util/geometry/Point.java
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* This file is part of l2jserver <l2jserver.com>.
|
||||
*
|
||||
* l2jserver 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.util.geometry;
|
||||
|
||||
/**
|
||||
* An two dimensional point
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class Point {
|
||||
/**
|
||||
* The X axis
|
||||
*/
|
||||
public final int x;
|
||||
/**
|
||||
* The Y axis
|
||||
*/
|
||||
public final int y;
|
||||
|
||||
/**
|
||||
* Creates a new two dimensional point
|
||||
*
|
||||
* @param x
|
||||
* the x axis
|
||||
* @param y
|
||||
* the y axis
|
||||
*/
|
||||
public Point(int x, int y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public static final Point fromXY(int x, int y) {
|
||||
return new Point(x, y);
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with l2jserver. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.util.dimensional;
|
||||
package com.l2jserver.util.geometry;
|
||||
|
||||
/**
|
||||
* An point is composed of an Coordinate and an angle. The angle represents the
|
||||
@@ -22,7 +22,7 @@ package com.l2jserver.util.dimensional;
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class Point {
|
||||
public class Point3D {
|
||||
/**
|
||||
* The point coordinate
|
||||
*/
|
||||
@@ -40,14 +40,28 @@ public class Point {
|
||||
* @param angle
|
||||
* the angle
|
||||
*/
|
||||
public Point(Coordinate coordinate, double angle) {
|
||||
public Point3D(Coordinate coordinate, double angle) {
|
||||
this.coordinate = coordinate;
|
||||
this.angle = angle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new point with 3 axis
|
||||
*
|
||||
* @param x
|
||||
* the x axis
|
||||
* @param y
|
||||
* the y axis
|
||||
* @param z
|
||||
* the z axis
|
||||
*/
|
||||
public Point3D(int x, int y, int z) {
|
||||
this(new Coordinate(x, y, z), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the x
|
||||
* @see com.l2jserver.util.dimensional.Coordinate#getX()
|
||||
* @see com.l2jserver.util.geometry.Coordinate#getX()
|
||||
*/
|
||||
public int getX() {
|
||||
return coordinate.getX();
|
||||
@@ -55,7 +69,7 @@ public class Point {
|
||||
|
||||
/**
|
||||
* @return the y
|
||||
* @see com.l2jserver.util.dimensional.Coordinate#getY()
|
||||
* @see com.l2jserver.util.geometry.Coordinate#getY()
|
||||
*/
|
||||
public int getY() {
|
||||
return coordinate.getY();
|
||||
@@ -63,7 +77,7 @@ public class Point {
|
||||
|
||||
/**
|
||||
* @return the z
|
||||
* @see com.l2jserver.util.dimensional.Coordinate#getZ()
|
||||
* @see com.l2jserver.util.geometry.Coordinate#getZ()
|
||||
*/
|
||||
public int getZ() {
|
||||
return coordinate.getZ();
|
||||
@@ -73,7 +87,7 @@ public class Point {
|
||||
* @param other
|
||||
* the other coordinate
|
||||
* @return the distance
|
||||
* @see com.l2jserver.util.dimensional.Coordinate#getDistance(com.l2jserver.util.dimensional.Coordinate)
|
||||
* @see com.l2jserver.util.geometry.Coordinate#getDistance(com.l2jserver.util.geometry.Coordinate)
|
||||
*/
|
||||
public double getDistance(Coordinate other) {
|
||||
return coordinate.getDistance(other);
|
||||
@@ -83,9 +97,9 @@ public class Point {
|
||||
* @param other
|
||||
* the other point
|
||||
* @return the distance
|
||||
* @see com.l2jserver.util.dimensional.Coordinate#getDistance(com.l2jserver.util.dimensional.Coordinate)
|
||||
* @see com.l2jserver.util.geometry.Coordinate#getDistance(com.l2jserver.util.geometry.Coordinate)
|
||||
*/
|
||||
public double getDistance(Point other) {
|
||||
public double getDistance(Point3D other) {
|
||||
return coordinate.getDistance(other.coordinate);
|
||||
}
|
||||
|
||||
@@ -114,10 +128,10 @@ public class Point {
|
||||
* the z point
|
||||
* @param angle
|
||||
* the angle
|
||||
* @return the new {@link Point} object created
|
||||
* @return the new {@link Point3D} object created
|
||||
*/
|
||||
public static Point fromXYZA(int x, int y, int z, double angle) {
|
||||
return new Point(Coordinate.fromXYZ(x, y, z), angle);
|
||||
public static Point3D fromXYZA(int x, int y, int z, double angle) {
|
||||
return new Point3D(Coordinate.fromXYZ(x, y, z), angle);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -129,9 +143,9 @@ public class Point {
|
||||
* the y point
|
||||
* @param z
|
||||
* the z point
|
||||
* @return the new {@link Point} object created
|
||||
* @return the new {@link Point3D} object created
|
||||
*/
|
||||
public static Point fromXYZ(int x, int y, int z) {
|
||||
public static Point3D fromXYZ(int x, int y, int z) {
|
||||
return fromXYZA(x, y, z, 0);
|
||||
}
|
||||
}
|
||||
155
src/main/java/com/l2jserver/util/geometry/PolygonArea.java
Normal file
155
src/main/java/com/l2jserver/util/geometry/PolygonArea.java
Normal file
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* This file is part of l2jserver <l2jserver.com>.
|
||||
*
|
||||
* l2jserver 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.util.geometry;
|
||||
|
||||
import java.awt.Polygon;
|
||||
import java.util.Collection;
|
||||
|
||||
import com.l2jserver.util.MathUtil;
|
||||
|
||||
/**
|
||||
* Area of free form
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class PolygonArea extends AbstractArea {
|
||||
/**
|
||||
* Collection of x points
|
||||
*/
|
||||
private final int[] xPoints;
|
||||
|
||||
/**
|
||||
* Collection of y points
|
||||
*/
|
||||
private final int[] yPoints;
|
||||
|
||||
/**
|
||||
* Polygon used to calculate isInside()
|
||||
*/
|
||||
private final Polygon poly;
|
||||
|
||||
/**
|
||||
* Creates new area from given points
|
||||
*
|
||||
* @param points
|
||||
* list of points
|
||||
* @param zMin
|
||||
* minimal z
|
||||
* @param zMax
|
||||
* maximal z
|
||||
*/
|
||||
public PolygonArea(Collection<Point> points, int zMin, int zMax) {
|
||||
this(points.toArray(new Point[points.size()]), zMin, zMax);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new area from given points
|
||||
*
|
||||
* @param points
|
||||
* list of points
|
||||
* @param zMin
|
||||
* minimal z
|
||||
* @param zMax
|
||||
* maximal z
|
||||
*/
|
||||
public PolygonArea(Point[] points, int zMin, int zMax) {
|
||||
super(zMin, zMax);
|
||||
|
||||
if (points.length < 3) {
|
||||
throw new IllegalArgumentException(
|
||||
"Not enough points, needed at least 3 but got "
|
||||
+ points.length);
|
||||
}
|
||||
|
||||
this.xPoints = new int[points.length];
|
||||
this.yPoints = new int[points.length];
|
||||
|
||||
Polygon polygon = new Polygon();
|
||||
for (int i = 0, n = points.length; i < n; i++) {
|
||||
Point p = points[i];
|
||||
polygon.addPoint(p.x, p.y);
|
||||
xPoints[i] = p.x;
|
||||
yPoints[i] = p.y;
|
||||
}
|
||||
this.poly = polygon;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInside2D(int x, int y) {
|
||||
return poly.contains(x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDistance2D(int x, int y) {
|
||||
if (isInside2D(x, y)) {
|
||||
return 0;
|
||||
} else {
|
||||
Point cp = getClosestPoint(x, y);
|
||||
return MathUtil.getDistance(cp.x, cp.y, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDistance3D(int x, int y, int z) {
|
||||
if (isInside3D(x, y, z)) {
|
||||
return 0;
|
||||
} else if (isInsideZ(z)) {
|
||||
return getDistance2D(x, y);
|
||||
} else {
|
||||
Point3D cp = getClosestPoint(x, y, z);
|
||||
return MathUtil.getDistance(cp.getX(), cp.getY(), cp.getZ(), x, y,
|
||||
z);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Point getClosestPoint(int x, int y) {
|
||||
|
||||
Point closestPoint = null;
|
||||
double closestDistance = 0;
|
||||
|
||||
for (int i = 0; i < xPoints.length; i++) {
|
||||
int nextIndex = i + 1;
|
||||
if (nextIndex == xPoints.length) {
|
||||
nextIndex = 0;
|
||||
}
|
||||
|
||||
int p1x = xPoints[i];
|
||||
int p1y = yPoints[i];
|
||||
int p2x = xPoints[nextIndex];
|
||||
int p2y = yPoints[nextIndex];
|
||||
|
||||
Point point = MathUtil.getClosestPointOnSegment(p1x, p1y, p2x, p2y,
|
||||
x, y);
|
||||
|
||||
if (closestPoint == null) {
|
||||
closestPoint = point;
|
||||
closestDistance = MathUtil.getDistance(closestPoint.x,
|
||||
closestPoint.y, x, y);
|
||||
} else {
|
||||
double newDistance = MathUtil.getDistance(point.x, point.y, x,
|
||||
y);
|
||||
if (newDistance < closestDistance) {
|
||||
closestPoint = point;
|
||||
closestDistance = newDistance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return closestPoint;
|
||||
}
|
||||
}
|
||||
177
src/main/java/com/l2jserver/util/geometry/RectangleArea.java
Normal file
177
src/main/java/com/l2jserver/util/geometry/RectangleArea.java
Normal file
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* This file is part of l2jserver <l2jserver.com>.
|
||||
*
|
||||
* l2jserver 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.util.geometry;
|
||||
|
||||
import java.awt.Rectangle;
|
||||
|
||||
import com.l2jserver.util.MathUtil;
|
||||
|
||||
/**
|
||||
* Rectangle area, most wide spread in the game
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class RectangleArea extends AbstractArea {
|
||||
/**
|
||||
* Min x point
|
||||
*/
|
||||
private final int minX;
|
||||
|
||||
/**
|
||||
* Max x point
|
||||
*/
|
||||
private final int maxX;
|
||||
|
||||
/**
|
||||
* Min y point
|
||||
*/
|
||||
private final int minY;
|
||||
|
||||
/**
|
||||
* Max y point
|
||||
*/
|
||||
private final int maxY;
|
||||
|
||||
/**
|
||||
* Creates new area from given points. Point order doesn't matter
|
||||
*
|
||||
* @param p1
|
||||
* point
|
||||
* @param p2
|
||||
* point
|
||||
* @param p3
|
||||
* point
|
||||
* @param p4
|
||||
* point
|
||||
* @param minZ
|
||||
* minimal z
|
||||
* @param maxZ
|
||||
* maximal z
|
||||
*/
|
||||
public RectangleArea(Point p1, Point p2, Point p3, Point p4, int minZ,
|
||||
int maxZ) {
|
||||
super(minZ, maxZ);
|
||||
|
||||
// we should use a better way to do this
|
||||
Rectangle r = new Rectangle();
|
||||
r.add(new java.awt.Point(p1.x, p1.y));
|
||||
r.add(new java.awt.Point(p2.x, p2.y));
|
||||
r.add(new java.awt.Point(p3.x, p3.y));
|
||||
r.add(new java.awt.Point(p4.x, p4.y));
|
||||
|
||||
minX = (int) r.getMinX();
|
||||
maxX = (int) r.getMaxX();
|
||||
minY = (int) r.getMinY();
|
||||
maxY = (int) r.getMaxY();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new are from given coords
|
||||
*
|
||||
* @param minX
|
||||
* mimal x point
|
||||
* @param minY
|
||||
* minimal y point
|
||||
* @param maxX
|
||||
* maximal x point
|
||||
* @param maxY
|
||||
* maximal y point
|
||||
* @param minZ
|
||||
* minimal z point
|
||||
* @param maxZ
|
||||
* maximal z point
|
||||
*/
|
||||
public RectangleArea(int minX, int minY, int maxX, int maxY, int minZ,
|
||||
int maxZ) {
|
||||
super(minZ, maxZ);
|
||||
this.minX = minX;
|
||||
this.maxX = maxX;
|
||||
this.minY = minY;
|
||||
this.maxY = maxY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInside2D(int x, int y) {
|
||||
return x >= minX && x <= maxX && y >= minY && y <= maxY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDistance2D(int x, int y) {
|
||||
if (isInside2D(x, y)) {
|
||||
return 0;
|
||||
} else {
|
||||
Point cp = getClosestPoint(x, y);
|
||||
return MathUtil.getDistance(x, y, cp.x, cp.y);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDistance3D(int x, int y, int z) {
|
||||
if (isInside3D(x, y, z)) {
|
||||
return 0;
|
||||
} else if (isInsideZ(z)) {
|
||||
return getDistance2D(x, y);
|
||||
} else {
|
||||
Point3D cp = getClosestPoint(x, y, z);
|
||||
return MathUtil.getDistance(x, y, z, cp.getX(), cp.getY(),
|
||||
cp.getZ());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Point getClosestPoint(int x, int y) {
|
||||
|
||||
if (isInside2D(x, y)) {
|
||||
return new Point(x, y);
|
||||
} else {
|
||||
// bottom edge
|
||||
Point closestPoint = MathUtil.getClosestPointOnSegment(minX, minY,
|
||||
maxX, minY, x, y);
|
||||
double distance = MathUtil.getDistance(x, y, closestPoint.x,
|
||||
closestPoint.y);
|
||||
|
||||
// top edge
|
||||
Point cp = MathUtil.getClosestPointOnSegment(minX, maxY, maxX,
|
||||
maxY, x, y);
|
||||
double d = MathUtil.getDistance(x, y, cp.x, cp.y);
|
||||
if (d < distance) {
|
||||
closestPoint = cp;
|
||||
distance = d;
|
||||
}
|
||||
|
||||
// left edge
|
||||
cp = MathUtil
|
||||
.getClosestPointOnSegment(minX, minY, minX, maxY, x, y);
|
||||
d = MathUtil.getDistance(x, y, cp.x, cp.y);
|
||||
if (d < distance) {
|
||||
closestPoint = cp;
|
||||
distance = d;
|
||||
}
|
||||
|
||||
// Right edge
|
||||
cp = MathUtil
|
||||
.getClosestPointOnSegment(maxX, minY, maxX, maxY, x, y);
|
||||
d = MathUtil.getDistance(x, y, cp.x, cp.y);
|
||||
if (d < distance) {
|
||||
closestPoint = cp;
|
||||
// distance = d;
|
||||
}
|
||||
|
||||
return closestPoint;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,7 @@ package com.l2jserver.util.jaxb;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.adapters.XmlAdapter;
|
||||
|
||||
import com.l2jserver.util.dimensional.Coordinate;
|
||||
import com.l2jserver.util.geometry.Coordinate;
|
||||
import com.l2jserver.util.jaxb.CoordinateAdapter.CoordinateElement;
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user