1
0
mirror of https://github.com/Rogiel/l2jserver2 synced 2025-12-10 09:22:49 +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:
2011-05-27 02:49:15 -03:00
parent aabe375b49
commit 73f51e53c0
95 changed files with 3079 additions and 1884 deletions

View File

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

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

View File

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

View File

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

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

View File

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

View File

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

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

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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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.

View File

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

View File

@@ -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

View File

@@ -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;