1
0
mirror of https://github.com/Rogiel/l2jserver2 synced 2025-12-09 08:52:51 +00:00

Character broadcast working

Signed-off-by: Rogiel <rogiel@rogiel.com>
This commit is contained in:
2011-05-22 21:32:55 -03:00
parent 49a8513ec5
commit 98feb1ecce
148 changed files with 2309 additions and 597 deletions

View File

@@ -16,27 +16,19 @@
*/
package com.l2jserver;
import com.google.inject.Injector;
import com.l2jserver.model.id.object.provider.NPCIDProvider;
import com.l2jserver.model.id.template.NPCTemplateID;
import com.l2jserver.model.id.template.provider.NPCTemplateIDProvider;
import com.l2jserver.model.world.NPC;
import com.l2jserver.service.ServiceManager;
import com.l2jserver.service.cache.CacheService;
import com.l2jserver.service.configuration.ConfigurationService;
import com.l2jserver.service.database.DatabaseService;
import com.l2jserver.service.game.character.CharacterService;
import com.l2jserver.service.game.chat.ChatService;
import com.l2jserver.service.game.npc.NPCService;
import com.l2jserver.service.game.pathing.PathingService;
import com.l2jserver.service.game.scripting.ScriptingService;
import com.l2jserver.service.game.spawn.AlreadySpawnedServiceException;
import com.l2jserver.service.game.spawn.SpawnPointNotFoundServiceException;
import com.l2jserver.service.game.spawn.SpawnService;
import com.l2jserver.service.game.template.TemplateService;
import com.l2jserver.service.game.world.WorldIDService;
import com.l2jserver.service.network.NetworkService;
import com.l2jserver.service.network.keygen.BlowfishKeygenService;
import com.l2jserver.util.dimensional.Point;
public class L2JGameServerMain {
/**
@@ -65,7 +57,10 @@ public class L2JGameServerMain {
serviceManager.start(BlowfishKeygenService.class);
serviceManager.start(NetworkService.class);
staticSpawn(server.getInjector());
// spawn
serviceManager.get(NPCService.class).spawnAll();
// staticSpawn(server.getInjector());
} catch (Exception e) {
System.out.println("GameServer could not be started!");
e.printStackTrace();
@@ -74,44 +69,44 @@ public class L2JGameServerMain {
// Thread.sleep(60 * 60 * 1000);
}
/**
* This method does an static spawn for an object
*
* @throws AlreadySpawnedServiceException
* @throws SpawnPointNotFoundServiceException
*/
private static void staticSpawn(Injector injector)
throws SpawnPointNotFoundServiceException,
AlreadySpawnedServiceException {
final NPCTemplateIDProvider templateProvider = injector
.getInstance(NPCTemplateIDProvider.class);
final NPCIDProvider provider = injector
.getInstance(NPCIDProvider.class);
final SpawnService spawnService = injector
.getInstance(SpawnService.class);
final NPCTemplateID id = templateProvider.createID(12077);
final NPC npc = id.getTemplate().create();
npc.setID(provider.createID());
// close to char spawn
npc.setPoint(Point.fromXYZ(-71301, 258259, -3134));
spawnService.spawn(npc, null);
// close spawn gatekepper
final NPCTemplateID gid = templateProvider.createID(30006);
final NPC gatekeeper = gid.getTemplate().create();
gatekeeper.setID(provider.createID());
gatekeeper.setPoint(Point.fromXYZ(-71301, 258559, -3134));
spawnService.spawn(gatekeeper, null);
// spawn tamil - orc village
final NPCTemplateID tamilId = templateProvider.createID(30576);
final NPC tamil = tamilId.getTemplate().create();
tamil.setID(provider.createID());
tamil.setPoint(Point.fromXYZ(-45264, -112512, -240));
spawnService.spawn(tamil, null);
}
//
// /**
// * This method does an static spawn for an object
// *
// * @throws AlreadySpawnedServiceException
// * @throws SpawnPointNotFoundServiceException
// */
// private static void staticSpawn(Injector injector)
// throws SpawnPointNotFoundServiceException,
// AlreadySpawnedServiceException {
// final NPCTemplateIDProvider templateProvider = injector
// .getInstance(NPCTemplateIDProvider.class);
// final NPCIDProvider provider = injector
// .getInstance(NPCIDProvider.class);
// final SpawnService spawnService = injector
// .getInstance(SpawnService.class);
//
// final NPCTemplateID id = templateProvider.createID(12077);
// final NPC npc = id.getTemplate().create();
//
// npc.setID(provider.createID());
// // close to char spawn
// npc.setPoint(Point.fromXYZ(-71301, 258259, -3134));
//
// spawnService.spawn(npc, null);
//
// // close spawn gatekepper
// final NPCTemplateID gid = templateProvider.createID(30006);
// final NPC gatekeeper = gid.getTemplate().create();
// gatekeeper.setID(provider.createID());
// gatekeeper.setPoint(Point.fromXYZ(-71301, 258559, -3134));
// spawnService.spawn(gatekeeper, null);
//
// // spawn tamil - orc village
// final NPCTemplateID tamilId = templateProvider.createID(30576);
// final NPC tamil = tamilId.getTemplate().create();
// tamil.setID(provider.createID());
// tamil.setPoint(Point.fromXYZ(-45264, -112512, -240));
// spawnService.spawn(tamil, null);
// }
}

View File

@@ -44,24 +44,24 @@ public class ActorMovementPacket extends AbstractServerPacket {
/**
* The source target
*/
private Coordinate target;
private Coordinate source;
public ActorMovementPacket(Actor actor, Coordinate target) {
public ActorMovementPacket(Actor actor, Coordinate source) {
super(OPCODE);
this.actor = actor;
this.target = target;
this.source = source;
}
@Override
public void write(Lineage2Connection conn, ChannelBuffer buffer) {
buffer.writeInt(actor.getID().getID());
// target
buffer.writeInt(target.getX());
buffer.writeInt(target.getY());
buffer.writeInt(target.getZ());
// source
buffer.writeInt(source.getX());
buffer.writeInt(source.getY());
buffer.writeInt(source.getZ());
// target
buffer.writeInt(actor.getPoint().getX());
buffer.writeInt(actor.getPoint().getY());
buffer.writeInt(actor.getPoint().getZ());

View File

@@ -0,0 +1,263 @@
/*
* 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.net.packet.server;
import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.BELT;
import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.CHEST;
import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.CLOAK;
import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.DECORATION_1;
import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.DECORATION_2;
import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.DECORATION_3;
import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.DECORATION_4;
import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.DECORATION_5;
import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.DECORATION_6;
import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.FEET;
import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.GLOVES;
import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.HAIR1;
import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.HAIR2;
import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.HEAD;
import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.LEFT_BRACELET;
import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.LEFT_HAND;
import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.LEGS;
import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.RIGHT_BRACELET;
import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.RIGHT_HAND;
import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.UNDERWEAR;
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.Sex;
import com.l2jserver.model.world.Item;
import com.l2jserver.model.world.L2Character;
import com.l2jserver.model.world.L2Character.CharacterMoveType;
import com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll;
import com.l2jserver.util.BufferUtils;
/**
* This packet sends to the client an actor information about an actor
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class CharacterInformationBroadcastPacket extends AbstractServerPacket {
/**
* The packet OPCODE
*/
public static final int OPCODE = 0x31;
private final L2Character character;
public CharacterInformationBroadcastPacket(L2Character character) {
super(OPCODE);
this.character = character;
}
@Override
public void write(Lineage2Connection conn, ChannelBuffer buffer) {
buffer.writeInt(character.getPoint().getX());
buffer.writeInt(character.getPoint().getY());
buffer.writeInt(character.getPoint().getZ());
buffer.writeInt(0x00); // unk
buffer.writeInt(character.getID().getID());
BufferUtils.writeString(buffer, character.getName());
buffer.writeInt(character.getRace().id);
buffer.writeInt(character.getSex().option);
buffer.writeInt(character.getCharacterClass().id);
writePaperdollItemID(buffer, character, UNDERWEAR);
// writePaperdollItemID(buffer, character, RIGHT_EAR);
// writePaperdollItemID(buffer, character, LEFT_EAR);
// writePaperdollItemID(buffer, character, NECK);
// writePaperdollItemID(buffer, character, RIGHT_FINGER);
// writePaperdollItemID(buffer, character, LEFT_FINGER);
writePaperdollItemID(buffer, character, HEAD);
writePaperdollItemID(buffer, character, RIGHT_HAND);
writePaperdollItemID(buffer, character, LEFT_HAND);
writePaperdollItemID(buffer, character, GLOVES);
writePaperdollItemID(buffer, character, CHEST);
writePaperdollItemID(buffer, character, LEGS);
writePaperdollItemID(buffer, character, FEET);
writePaperdollItemID(buffer, character, CLOAK);
writePaperdollItemID(buffer, character, RIGHT_HAND);
writePaperdollItemID(buffer, character, HAIR1);
writePaperdollItemID(buffer, character, HAIR2);
writePaperdollItemID(buffer, character, RIGHT_BRACELET);
writePaperdollItemID(buffer, character, LEFT_BRACELET);
writePaperdollItemID(buffer, character, DECORATION_1);
writePaperdollItemID(buffer, character, DECORATION_2);
writePaperdollItemID(buffer, character, DECORATION_3);
writePaperdollItemID(buffer, character, DECORATION_4);
writePaperdollItemID(buffer, character, DECORATION_5);
writePaperdollItemID(buffer, character, DECORATION_6);
writePaperdollItemID(buffer, character, BELT);
writePaperdollAugumentID(buffer, character, UNDERWEAR);
// writePaperdollAugumentID(buffer, character, RIGHT_EAR);
// writePaperdollAugumentID(buffer, character, LEFT_EAR);
// writePaperdollAugumentID(buffer, character, NECK);
// writePaperdollAugumentID(buffer, character, RIGHT_FINGER);
// writePaperdollAugumentID(buffer, character, LEFT_FINGER);
writePaperdollAugumentID(buffer, character, HEAD);
writePaperdollAugumentID(buffer, character, RIGHT_HAND);
writePaperdollAugumentID(buffer, character, LEFT_HAND);
writePaperdollAugumentID(buffer, character, GLOVES);
writePaperdollAugumentID(buffer, character, CHEST);
writePaperdollAugumentID(buffer, character, LEGS);
writePaperdollAugumentID(buffer, character, FEET);
writePaperdollAugumentID(buffer, character, CLOAK);
writePaperdollAugumentID(buffer, character, RIGHT_HAND);
writePaperdollAugumentID(buffer, character, HAIR1);
writePaperdollAugumentID(buffer, character, HAIR2);
writePaperdollAugumentID(buffer, character, RIGHT_BRACELET);
writePaperdollAugumentID(buffer, character, LEFT_BRACELET);
writePaperdollAugumentID(buffer, character, DECORATION_1);
writePaperdollAugumentID(buffer, character, DECORATION_2);
writePaperdollAugumentID(buffer, character, DECORATION_3);
writePaperdollAugumentID(buffer, character, DECORATION_4);
writePaperdollAugumentID(buffer, character, DECORATION_5);
writePaperdollAugumentID(buffer, character, DECORATION_6);
writePaperdollAugumentID(buffer, character, BELT);
buffer.writeInt(0x00); // unk
buffer.writeInt(0x01); // unk
// end of t1 new h's
buffer.writeInt(0x00); // pvp flag
buffer.writeInt(0x00); // karma
buffer.writeInt(character.getAttributes().getCastSpeed());
buffer.writeInt(character.getAttributes().getAttackSpeed());
buffer.writeInt(0x00); // unk
buffer.writeInt((int) character.getAttributes().getMoveSpeed());
buffer.writeInt((int) character.getAttributes().getMoveSpeed());
buffer.writeInt((int) character.getAttributes().getMoveSpeed());
buffer.writeInt((int) character.getAttributes().getMoveSpeed());
buffer.writeInt((int) character.getAttributes().getMoveSpeed());
buffer.writeInt((int) character.getAttributes().getMoveSpeed());
buffer.writeInt((int) character.getAttributes().getMoveSpeed());
buffer.writeInt((int) character.getAttributes().getMoveSpeed());
buffer.writeDouble(0x01); // move speed multiplier
buffer.writeDouble(0x01); // attack speed multiplier
if (character.getSex() == Sex.MALE) {
buffer.writeDouble(character.getTemplate().getMaleCollisionRadius());
buffer.writeDouble(character.getTemplate().getMaleCollisionHeight());
} else {
buffer.writeDouble(character.getTemplate()
.getFemaleCollisionRadius());
buffer.writeDouble(character.getTemplate()
.getFemaleCollisionHeight());
}
buffer.writeInt(character.getAppearance().getHairStyle().option);
buffer.writeInt(character.getAppearance().getHairColor().option);
buffer.writeInt(character.getAppearance().getFace().option);
BufferUtils.writeString(buffer, "TODO"); // TODO title
// dont send those 4 if using cursed weapon
buffer.writeInt(0); // clan id
buffer.writeInt(0); // crest id
buffer.writeInt(0); // ally id
buffer.writeInt(0); // ally crest id
buffer.writeByte(0x01); // sitting
buffer.writeByte((character.getMoveType() == CharacterMoveType.RUN ? 0x01
: 0x00));
buffer.writeByte(0x00); // is in combat
buffer.writeByte(0x00); // alike dead
buffer.writeByte(0x00); // invisible = 1 visible =0
// 1-on Strider, 2-on Wyvern,
// 3-on Great Wolf, 0-no mount
buffer.writeByte(0x00);
buffer.writeByte(0x00); // 1 - sellshop
// writeH(_activeChar.getCubics().size());
// for (int id : _activeChar.getCubics().keySet())
// writeH(id);
buffer.writeShort(0x00); // cubics size
buffer.writeByte(0x00); // in party match room
buffer.writeInt(0x00); // abnormal
buffer.writeByte(0x00); // flying mounted
// recom have
buffer.writeShort(0x00); // Blue value for name (0 =
// white, 255 = pure blue)
buffer.writeInt(1000000); // mount npc
buffer.writeInt(character.getCharacterClass().id);
buffer.writeInt(0x00); // ?
buffer.writeByte(0x00); // enchant effect
buffer.writeByte(0x00); // team circle around feet 1= Blue, 2 = red
buffer.writeInt(0x00); // clan crest large id
buffer.writeByte(0x00); // is noble - Symbol on char menu
// ctrl+I
buffer.writeByte(0x00); // Hero Aura
// (Cant be undone by setting back to 0)
buffer.writeByte(0x00); // 0x01: Fishing Mode
buffer.writeInt(0x00); // fish x
buffer.writeInt(0x00);// fish y
buffer.writeInt(0x00); // fish z
buffer.writeInt(character.getAppearance().getNameColor().toInteger());
buffer.writeInt((int) character.getPoint().getAngle());
buffer.writeInt(0x00); // pledge class
buffer.writeInt(0x00); // pledge type
buffer.writeInt(character.getAppearance().getTitleColor().toInteger());
buffer.writeInt(0x00); // cursed weapon id
buffer.writeInt(0x00); // clan reputation
// T1
buffer.writeInt(0x00); // transformation id
buffer.writeInt(0x00); // agathion id
// T2
buffer.writeInt(0x01); // unk
// T2.3
buffer.writeInt(0x00); // special effect
}
private void writePaperdollItemID(ChannelBuffer buffer,
L2Character character, InventoryPaperdoll paperdoll) {
final Item item = character.getInventory().getItem(paperdoll);
int id = 0;
if (item != null)
id = item.getTemplateID().getID();
buffer.writeInt(id);
}
private void writePaperdollAugumentID(ChannelBuffer buffer,
L2Character character, InventoryPaperdoll paperdoll) {
buffer.writeInt(0x00);
}
}

View File

@@ -48,6 +48,7 @@ import com.l2jserver.game.net.Lineage2Connection;
import com.l2jserver.game.net.packet.AbstractServerPacket;
import com.l2jserver.model.world.Item;
import com.l2jserver.model.world.L2Character;
import com.l2jserver.model.world.Actor.Sex;
import com.l2jserver.model.world.actor.ActorExperience;
import com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll;
import com.l2jserver.util.BufferUtils;
@@ -233,9 +234,16 @@ public class CharacterInformationPacket extends AbstractServerPacket {
// writeF(_activeChar.getCollisionRadius());
// writeF(_activeChar.getCollisionHeight());
// }
buffer.writeDouble(9.0); // collision radius
buffer.writeDouble(23.0); // collision heigth
if (character.getSex() == Sex.MALE) {
buffer.writeDouble(character.getTemplate().getMaleCollisionRadius());
buffer.writeDouble(character.getTemplate().getMaleCollisionHeight());
} else {
buffer.writeDouble(character.getTemplate()
.getFemaleCollisionRadius());
buffer.writeDouble(character.getTemplate()
.getFemaleCollisionHeight());
}
buffer.writeInt(character.getAppearance().getHairStyle().option);
buffer.writeInt(character.getAppearance().getHairColor().option);
buffer.writeInt(character.getAppearance().getFace().option);
@@ -299,9 +307,7 @@ public class CharacterInformationPacket extends AbstractServerPacket {
// new c5
// is running
buffer.writeByte(0x00); // changes the Speed
// display on Status
// Window
buffer.writeByte(character.getMoveType().id);
// pledge class
buffer.writeInt(0x00); // changes the text above

View File

@@ -21,12 +21,12 @@ import org.jboss.netty.buffer.ChannelBuffer;
import com.l2jserver.game.net.Lineage2Connection;
import com.l2jserver.game.net.packet.AbstractServerPacket;
import com.l2jserver.model.template.NPCTemplate;
import com.l2jserver.model.world.L2Character;
import com.l2jserver.model.world.NPC;
import com.l2jserver.util.BufferUtils;
/**
* This packet sends to the client an actor information about an actor (except
* players)
* This packet sends to the client an actor information about an actor
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
@@ -49,7 +49,12 @@ public class NPCInformationPacket extends AbstractServerPacket {
buffer.writeInt(npc.getID().getID());
buffer.writeInt(template.getID().getID() + 1000000); // npctype id
buffer.writeInt((template.isAttackable() ? 0x01 : 0x00));
if (npc instanceof NPC) {
buffer.writeInt((((NPCTemplate) template).isAttackable() ? 0x01
: 0x00));
} else {
buffer.writeInt(0x01);
}
buffer.writeInt(npc.getPoint().getX());
buffer.writeInt(npc.getPoint().getY());
buffer.writeInt(npc.getPoint().getZ());
@@ -77,8 +82,8 @@ public class NPCInformationPacket extends AbstractServerPacket {
buffer.writeByte(0x00); // is in combat
buffer.writeByte(0x00); // is like dead (faking)
buffer.writeByte(0x00); // 0=teleported 1=default 2=summoned
BufferUtils.writeString(buffer, template.getName());
BufferUtils.writeString(buffer, template.getTitle());
BufferUtils.writeString(buffer, ((NPCTemplate) template).getName());
BufferUtils.writeString(buffer, ((NPCTemplate) template).getTitle());
buffer.writeInt(0x00); // Title color 0=client default
buffer.writeInt(0x00); // pvp flag
buffer.writeInt(0x00); // karma

View File

@@ -0,0 +1,52 @@
/*
* 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.net.packet.server;
import org.jboss.netty.buffer.ChannelBuffer;
import com.l2jserver.game.net.Lineage2Connection;
import com.l2jserver.game.net.packet.AbstractServerPacket;
import com.l2jserver.model.world.PositionableObject;
/**
* This packet informs the client that an certain object has disappeared from
* his sight or from the world.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class ObjectRemove extends AbstractServerPacket {
/**
* The packet OPCODE
*/
public static final int OPCODE = 0x08;
/**
* The Object
*/
private final PositionableObject object;
public ObjectRemove(PositionableObject object) {
super(OPCODE);
this.object = object;
}
@Override
public void write(Lineage2Connection conn, ChannelBuffer buffer) {
buffer.writeInt(object.getID().getID());
buffer.writeInt(0x00);
}
}

View File

@@ -24,11 +24,16 @@ import com.l2jserver.model.id.ID;
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class AbstractModel<T extends ID<?>> implements Model<T> {
public abstract class AbstractModel<T extends ID<?>> implements Model<T> {
/**
* The object id
*/
protected T id;
/**
* The database state. True inidicates that the object is on database, false
* indicates it must be inserted.
*/
protected boolean inDatabase;
@Override
public T getID() {
@@ -65,4 +70,14 @@ public class AbstractModel<T extends ID<?>> implements Model<T> {
return false;
return true;
}
@Override
public boolean isInDatabase() {
return inDatabase;
}
@Override
public void setIsInDatabase(boolean state) {
inDatabase = state;
}
}

View File

@@ -33,4 +33,15 @@ public interface Model<T extends ID<?>> {
* the object ID to set
*/
void setID(T ID);
/**
* @return true if object is already inserted in the database
*/
boolean isInDatabase();
/**
* @param state
* the database state
*/
void setIsInDatabase(boolean state);
}

View File

@@ -1,74 +0,0 @@
/*
* 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.model.game;
import com.l2jserver.model.id.template.NPCTemplateID;
import com.l2jserver.model.template.NPCTemplate;
import com.l2jserver.util.dimensional.Point;
/**
* This class represents an spawn instance of a NPC or Monster
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class Spawn {
/**
* The NPC template id
*/
private NPCTemplateID npcTemplateID;
/**
* The NPC spawn point
*/
private Point point;
/**
* @return the npcTemplate ID
*/
public NPCTemplateID getNPCTemplateID() {
return npcTemplateID;
}
/**
* @return the npcTemplate
*/
public NPCTemplate getNPCTemplate() {
return npcTemplateID.getTemplate();
}
/**
* @param npcTemplateID
* the npcTemplate ID to set
*/
public void setNPCTemplateID(NPCTemplateID npcTemplateID) {
this.npcTemplateID = npcTemplateID;
}
/**
* @return the point
*/
public Point getPoint() {
return point;
}
/**
* @param point
* the point to set
*/
public void setPoint(Point point) {
this.point = point;
}
}

View File

@@ -41,6 +41,18 @@ public abstract class ActorTemplate<T extends Actor> extends
* The actor race
*/
protected final Race race;
/**
* The movement speed multiplier
*/
protected double movementSpeedMultiplier = 1.0;
/**
* The attack speed multiplier
*/
protected double attackSpeedMultiplier = 1.0;
protected int maxHp;
/**
* The base attributes instance
*/
@@ -219,6 +231,27 @@ public abstract class ActorTemplate<T extends Actor> extends
return attributes.canCraft();
}
/**
* @return the movementSpeedMultiplier
*/
public double getMovementSpeedMultiplier() {
return movementSpeedMultiplier;
}
/**
* @return the attackSpeedMultiplier
*/
public double getAttackSpeedMultiplier() {
return attackSpeedMultiplier;
}
/**
* @return the max hp
*/
public int getMaxHP() {
return maxHp;
}
/**
* Defines the attributes of an character
*

View File

@@ -43,6 +43,23 @@ public abstract class CharacterTemplate extends ActorTemplate<L2Character> {
FIST;
}
/**
* The collision radius for male instances
*/
protected double maleCollisionRadius = 0;
/**
* The collision height for male instances
*/
protected double maleCollisionHeight = 0;
/**
* The collision radius for female instances
*/
protected double femaleCollisionRadius = 0;
/**
* The collision height for female instances
*/
protected double femaleCollisionHeight = 0;
protected CharacterTemplate(CharacterTemplateID id,
CharacterClass characterClass, Point spawnLocation) {
super(id, characterClass.race);
@@ -52,7 +69,7 @@ public abstract class CharacterTemplate extends ActorTemplate<L2Character> {
@Override
public L2Character createInstance() {
final L2Character character = new L2Character(attributes);
final L2Character character = new L2Character(this.getID(), attributes);
character.setRace(race);
character.setCharacterClass(characterClass);
@@ -74,6 +91,34 @@ public abstract class CharacterTemplate extends ActorTemplate<L2Character> {
public Point getSpawnLocation() {
return spawnLocation;
}
/**
* @return the male collision radius
*/
public double getMaleCollisionRadius() {
return maleCollisionRadius;
}
/**
* @return the male collision height
*/
public double getMaleCollisionHeight() {
return maleCollisionHeight;
}
/**
* @return the female collision radius
*/
public double getFemaleCollisionRadius() {
return femaleCollisionRadius;
}
/**
* @return the female collision height
*/
public double getFemaleCollisionHeight() {
return femaleCollisionHeight;
}
@Override
public CharacterTemplateID getID() {

View File

@@ -71,15 +71,6 @@ public abstract class NPCTemplate extends ActorTemplate<NPC> implements
*/
protected boolean attackable = false;
/**
* The movement speed multiplier
*/
protected double movementSpeedMultiplier = 1.0;
/**
* The attack speed multiplier
*/
protected double attackSpeedMultiplier = 1.0;
/**
* The collision radius
*/
@@ -89,8 +80,6 @@ public abstract class NPCTemplate extends ActorTemplate<NPC> implements
*/
protected double collisionHeight = 0;
protected int maxHp;
protected NPCTemplate(NPCTemplateID id) {
super(id, null);
}
@@ -132,8 +121,8 @@ public abstract class NPCTemplate extends ActorTemplate<NPC> implements
* the action arguments
* @throws L2Exception
*/
protected void talk(NPC npc, L2Character character, Lineage2Connection conn,
String... args) throws L2Exception {
protected void talk(NPC npc, L2Character character,
Lineage2Connection conn, String... args) throws L2Exception {
if (args.length == 0 || (args.length >= 1 && args[0].equals("Chat"))) {
String name = "";
if (args.length == 2)
@@ -192,40 +181,19 @@ public abstract class NPCTemplate extends ActorTemplate<NPC> implements
}
/**
* @return the movementSpeedMultiplier
*/
public double getMovementSpeedMultiplier() {
return movementSpeedMultiplier;
}
/**
* @return the attackSpeedMultiplier
*/
public double getAttackSpeedMultiplier() {
return attackSpeedMultiplier;
}
/**
* @return the collisionRadius
* @return the collision radius
*/
public double getCollisionRadius() {
return collisionRadius;
}
/**
* @return the collisionHeight
* @return the collision height
*/
public double getCollisionHeight() {
return collisionHeight;
}
/**
* @return the maxHp
*/
public int getMaxHP() {
return maxHp;
}
/**
* @return the race
*/

View File

@@ -77,6 +77,15 @@ public class TeleporterNPCTemplate extends NPCTemplate {
public static final Coordinate CAVE_OF_TRIALS = Coordinate.fromXYZ(9340,
-112509, -2536);
public static final Coordinate DARK_FOREST = Coordinate.fromXYZ(-22224,
14168, -3232);
public static final Coordinate SPIDER_NEST = Coordinate.fromXYZ(-61095,
75104, -3352);
public static final Coordinate SWAMPLAND = Coordinate.fromXYZ(-21966,
40544, -3192);
public static final Coordinate NEUTRAL_ZONE = Coordinate.fromXYZ(-10612,
75881, -3592);
@Inject
protected SpawnService spawnService;

View File

@@ -17,9 +17,10 @@
package com.l2jserver.model.world;
import com.l2jserver.model.id.object.ActorID;
import com.l2jserver.model.id.template.ActorTemplateID;
import com.l2jserver.model.template.ActorTemplate;
import com.l2jserver.model.world.actor.ActorEffects;
import com.l2jserver.model.world.actor.ActorSkillContainer;
import com.l2jserver.util.dimensional.Coordinate;
import com.l2jserver.util.dimensional.Point;
/**
@@ -28,6 +29,8 @@ import com.l2jserver.util.dimensional.Point;
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public abstract class Actor extends PositionableObject {
protected ActorTemplateID<?> templateID;
/**
* The actor race
*/
@@ -117,6 +120,10 @@ public abstract class Actor extends PositionableObject {
*/
protected final ActorSkillContainer skills = new ActorSkillContainer(this);
public Actor(ActorTemplateID<?> templateID) {
this.templateID = templateID;
}
public int getHP() {
return hp;
}
@@ -174,6 +181,20 @@ public abstract class Actor extends PositionableObject {
return skills;
}
/**
* @return the templateID
*/
public ActorTemplateID<?> getTemplateID() {
return templateID;
}
/**
* @return the template
*/
public ActorTemplate<?> getTemplate() {
return templateID.getTemplate();
}
@Override
public ActorID<?> getID() {
return (ActorID<?>) super.getID();

View File

@@ -21,8 +21,6 @@ import com.l2jserver.model.id.template.ItemTemplateID;
import com.l2jserver.model.template.ItemTemplate;
import com.l2jserver.model.world.character.CharacterInventory.InventoryLocation;
import com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll;
import com.l2jserver.util.dimensional.Coordinate;
import com.l2jserver.util.dimensional.Point;
/**
* This class represents an {@link Item} in the Lineage II World. The item can
@@ -37,10 +35,13 @@ import com.l2jserver.util.dimensional.Point;
* <li><b>Equipped by the {@link L2Character character}</b>: <tt>location</tt>
* is {@link InventoryLocation#PAPERDOLL}, <tt>paperdoll</tt> is not null and
* <tt>coordinate</tt> is null.</li>
* <li><b>Dropped on the ground</b>: <tt>location</li> and <tt>paperdoll</tt>
* <li><b>Dropped on the ground</b>: <tt>location</tt></li> and <tt>paperdoll</tt>
* are null, <tt>coordinate</tt> is not null and represents the dropping
* location.
* </ul>
* <p>
* Please note that {@link PositionableObject} values are only set if the object
* is dropped on the ground.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
@@ -62,10 +63,6 @@ public class Item extends PositionableObject {
* Paperdoll slot for this item
*/
private InventoryPaperdoll paperdoll;
/**
* Drop coordinate of this item
*/
private Coordinate coordinate;
/**
* Count of items
@@ -144,12 +141,4 @@ public class Item extends PositionableObject {
public void setOwnerID(CharacterID ownerID) {
this.ownerID = ownerID;
}
public Point getPoint() {
return null;
}
public void setPoint(Point point) {
}
}

View File

@@ -23,6 +23,7 @@ import com.l2jserver.model.id.object.ActorID;
import com.l2jserver.model.id.object.CharacterID;
import com.l2jserver.model.id.object.ClanID;
import com.l2jserver.model.id.object.PetID;
import com.l2jserver.model.id.template.CharacterTemplateID;
import com.l2jserver.model.template.CharacterTemplate;
import com.l2jserver.model.world.actor.ActorAttributes;
import com.l2jserver.model.world.character.CharacterAppearance;
@@ -138,7 +139,9 @@ public class L2Character extends Player {
* @param baseAttributes
* the base attribute for this character
*/
public L2Character(CharacterTemplate.ActorBaseAttributes baseAttributes) {
public L2Character(CharacterTemplateID templateID,
CharacterTemplate.ActorBaseAttributes baseAttributes) {
super(templateID);
this.baseAttributes = baseAttributes;
this.attributes = new CharacterCalculatedAttributes(this);
}
@@ -369,6 +372,16 @@ public class L2Character extends Player {
return shortcuts;
}
@Override
public CharacterTemplateID getTemplateID() {
return (CharacterTemplateID) super.getTemplateID();
}
@Override
public CharacterTemplate getTemplate() {
return (CharacterTemplate) super.getTemplate();
}
@Override
public CharacterID getID() {
return (CharacterID) super.getID();

View File

@@ -30,11 +30,6 @@ import com.l2jserver.service.game.ai.AIScript;
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class NPC extends Actor {
/**
* The NPC template ID
*/
private final NPCTemplateID templateID;
/**
* Creates a new instance
*
@@ -42,21 +37,21 @@ public class NPC extends Actor {
* the {@link NPC} {@link TemplateID}
*/
public NPC(NPCTemplateID templateID) {
this.templateID = templateID;
super(templateID);
}
/**
* @return the NPC template ID
*/
public NPCTemplateID getTemplateID() {
return templateID;
return (NPCTemplateID) templateID;
}
/**
* @return the NPC template
*/
public NPCTemplate getTemplate() {
return templateID.getTemplate();
return (NPCTemplate) templateID.getTemplate();
}
@Override

View File

@@ -18,6 +18,7 @@ package com.l2jserver.model.world;
import com.l2jserver.model.id.object.CharacterID;
import com.l2jserver.model.id.object.ItemID;
import com.l2jserver.model.id.template.ActorTemplateID;
/**
* This class represents an Pet in the Lineage II World
@@ -34,6 +35,10 @@ public class Pet extends Player {
*/
private ItemID itemID;
public Pet(ActorTemplateID<?> templateID) {
super(templateID);
}
/**
* @return the owner ID
*/

View File

@@ -16,6 +16,8 @@
*/
package com.l2jserver.model.world;
import com.l2jserver.model.id.template.ActorTemplateID;
/**
* {@link Player} is any object that can be controlled by the player. The most
* common implementation is {@link L2Character}.
@@ -23,5 +25,7 @@ package com.l2jserver.model.world;
* @author Rogiel
*/
public abstract class Player extends Actor {
public Player(ActorTemplateID<?> templateID) {
super(templateID);
}
}

View File

@@ -20,10 +20,15 @@ import com.l2jserver.util.dimensional.Coordinate;
import com.l2jserver.util.dimensional.Point;
/**
* @author <a href="http://www.rogiel.com">Rogiel</a>
* This is an abstract object that objects that can be placed in world should
* extend.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public abstract class PositionableObject extends AbstractObject {
/**
* The point this object is currently in
*/
private Point point;
/**

View File

@@ -34,7 +34,7 @@ public class CharacterMoveEvent implements CharacterEvent {
*/
private final L2Character character;
/**
* The new point of the character
* The old point of the character
*/
private final Point point;
@@ -44,7 +44,7 @@ public class CharacterMoveEvent implements CharacterEvent {
* @param character
* the character
* @param point
* the character point
* the character point before moving
*/
public CharacterMoveEvent(L2Character character, Point point) {
this.character = character;
@@ -52,7 +52,7 @@ public class CharacterMoveEvent implements CharacterEvent {
}
/**
* @return the new point
* @return the old point
*/
public Point getPoint() {
return point;

View File

@@ -57,6 +57,10 @@ public class ServiceManager {
}
logger = LoggerFactory.getLogger(ServiceManager.class);
}
public <T extends Service> T get(Class<T> serviceClass) {
return injector.getInstance(serviceClass);
}
public <T extends Service> T start(Class<T> serviceClass)
throws ServiceStartException {

View File

@@ -54,9 +54,10 @@ public class Log4JLoggingService extends AbstractService implements
rootLogger.setLevel(Level.WARN);
rootLogger.addAppender(new ConsoleAppender(layout, "System.err"));
l2jLogger.setLevel(Level.DEBUG);
scriptLogger.setLevel(Level.DEBUG);
l2jLogger.setLevel(Level.INFO);
scriptLogger.setLevel(Level.INFO);
nettyLogger.setLevel(Level.DEBUG);
Logger.getLogger("com.l2jserver.model.id.object.allocator").setLevel(Level.WARN);
}
@Override

View File

@@ -329,7 +329,9 @@ public class MySQLDatabaseService extends AbstractService implements
final List<T> list = CollectionFactory.newList();
final ResultSet rs = st.getResultSet();
while (rs.next()) {
list.add(mapper().map(rs));
final T obj = mapper().map(rs);
if (obj != null)
list.add(obj);
}
return list;
}

View File

@@ -23,6 +23,7 @@ import com.l2jserver.game.net.Lineage2Connection;
import com.l2jserver.game.net.SystemMessage;
import com.l2jserver.game.net.packet.server.ActorChatMessagePacket;
import com.l2jserver.game.net.packet.server.ActorMovementPacket;
import com.l2jserver.game.net.packet.server.CharacterInformationBroadcastPacket;
import com.l2jserver.game.net.packet.server.CharacterInformationExtraPacket;
import com.l2jserver.game.net.packet.server.CharacterInformationPacket;
import com.l2jserver.game.net.packet.server.CharacterInventoryPacket;
@@ -30,6 +31,7 @@ import com.l2jserver.game.net.packet.server.CharacterMovementTypePacket;
import com.l2jserver.game.net.packet.server.CharacterTargetSelectedPacket;
import com.l2jserver.game.net.packet.server.GameGuardQueryPacket;
import com.l2jserver.game.net.packet.server.NPCInformationPacket;
import com.l2jserver.game.net.packet.server.ObjectRemove;
import com.l2jserver.model.id.object.CharacterID;
import com.l2jserver.model.template.NPCTemplate;
import com.l2jserver.model.world.Actor;
@@ -50,6 +52,7 @@ import com.l2jserver.model.world.character.event.CharacterTargetSelectedEvent;
import com.l2jserver.model.world.character.event.CharacterWalkingEvent;
import com.l2jserver.model.world.npc.event.NPCSpawnEvent;
import com.l2jserver.model.world.player.event.PlayerTeleportedEvent;
import com.l2jserver.model.world.player.event.PlayerTeleportingEvent;
import com.l2jserver.service.AbstractService;
import com.l2jserver.service.AbstractService.Depends;
import com.l2jserver.service.game.chat.ChatChannel;
@@ -65,7 +68,9 @@ import com.l2jserver.service.game.world.event.FilteredWorldListener;
import com.l2jserver.service.game.world.event.WorldEvent;
import com.l2jserver.service.game.world.event.WorldEventDispatcher;
import com.l2jserver.service.game.world.event.WorldListener;
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;
@@ -133,7 +138,7 @@ public class CharacterServiceImpl extends AbstractService implements
return;
itemDao.loadInventory(character);
character.setOnline(true);
// chat listener
@@ -158,9 +163,10 @@ public class CharacterServiceImpl extends AbstractService implements
// this listener will be filtered so that only interesting events are
// dispatched, once a event arrives will be possible to check check if
// the given event will be broadcasted or not
// TODO this should not be here, it should be i world service or a newly
// TODO this should not be here, it should be in world service or a
// newly
// created broadcast service.
final WorldListener broadcastListener = new FilteredWorldListener<PositionableObject>(
final WorldListener neighboorListener = new FilteredWorldListener<PositionableObject>(
new KnownListFilter(character)) {
@Override
protected boolean dispatch(WorldEvent e, PositionableObject object) {
@@ -168,29 +174,64 @@ public class CharacterServiceImpl extends AbstractService implements
conn.write(new NPCInformationPacket((NPC) object));
} else if (e instanceof CharacterMoveEvent) {
final CharacterMoveEvent evt = (CharacterMoveEvent) e;
if (object.equals(character))
return true;
conn.write(new ActorMovementPacket((L2Character) object,
evt.getPoint().getCoordinate()));
} else if (e instanceof PlayerTeleportedEvent
|| e instanceof CharacterEnterWorldEvent) {
// TODO this should not be here!
for (final PositionableObject o : worldService
.iterable(new KnownListFilter(character))) {
if (o instanceof NPC) {
conn.write(new NPCInformationPacket((NPC) o));
}
if (object instanceof NPC) {
conn.write(new NPCInformationPacket((NPC) object));
} else if (object instanceof L2Character) {
conn.write(new CharacterInformationBroadcastPacket(
(L2Character) object));
}
} else if (e instanceof CharacterWalkingEvent
|| e instanceof CharacterRunningEvent) {
} else if (e instanceof PlayerTeleportingEvent
|| e instanceof CharacterLeaveWorldEvent) {
// object is not out of sight
conn.write(new ObjectRemove(object));
} else if (e instanceof CharacterWalkingEvent) {
conn.write(new CharacterMovementTypePacket(
((CharacterWalkingEvent) e).getCharacter()));
} else if (e instanceof CharacterRunningEvent) {
conn.write(new CharacterMovementTypePacket(
((CharacterRunningEvent) e).getCharacter()));
}
// keep listener alive
return true;
}
};
eventDispatcher.addListener(broadcastListener);
eventDispatcher.addListener(neighboorListener);
final WorldListener sendPacketListener = new FilteredWorldListener<WorldObject>(
new IDFilter(character.getID())) {
@Override
protected boolean dispatch(WorldEvent e, WorldObject object) {
if (e instanceof CharacterMoveEvent) {
final CharacterMoveEvent evt = (CharacterMoveEvent) e;
// process update known list
for (final WorldObject o : worldService
.iterable(new KnownListUpdateFilter(character, evt
.getPoint()))) {
if (o instanceof NPC) {
conn.write(new NPCInformationPacket((NPC) o));
} else if (o instanceof L2Character) {
conn.write(new CharacterInformationBroadcastPacket(
(L2Character) o));
}
}
} else if (e instanceof PlayerTeleportedEvent
|| e instanceof CharacterEnterWorldEvent) {
broadcast(conn, character);
} else if (e instanceof CharacterWalkingEvent) {
conn.write(new CharacterMovementTypePacket(
((CharacterWalkingEvent) e).getCharacter()));
} else if (e instanceof CharacterRunningEvent) {
conn.write(new CharacterMovementTypePacket(
((CharacterRunningEvent) e).getCharacter()));
}
// keep listener alive
return true;
}
};
eventDispatcher.addListener(sendPacketListener);
// leave world event
eventDispatcher.addListener(id, new CharacterListener() {
@@ -206,7 +247,8 @@ public class CharacterServiceImpl extends AbstractService implements
tradeChatListener);
// remove broadcast listener
eventDispatcher.removeListener(broadcastListener);
eventDispatcher.removeListener(neighboorListener);
eventDispatcher.removeListener(sendPacketListener);
// we can kill this listener now
return false;
@@ -236,22 +278,29 @@ public class CharacterServiceImpl extends AbstractService implements
// we can ignore this one
}
// broadcast knownlist -- trashy implementation
// TODO should be moved to world service or a newly created broadcast
// service, whichever fits the purpose
for (final WorldObject o : worldService.iterable(new KnownListFilter(
character))) {
if (o instanceof NPC) {
conn.write(new NPCInformationPacket((NPC) o));
}
}
// dispatch enter world event
eventDispatcher.dispatch(new CharacterEnterWorldEvent(character));
broadcast(conn, character);
// spawn the player -- this will also dispatch a spawn event
// here the object is registered in the world
spawnService.spawn(character, null);
// dispatch enter world event
eventDispatcher.dispatch(new CharacterEnterWorldEvent(character));
}
// broadcast knownlist -- trashy implementation
// TODO should be moved to world service or a newly created broadcast
// service, whichever fits the purpose
private void broadcast(Lineage2Connection conn, L2Character character) {
for (final WorldObject o : worldService.iterable(new KnownListFilter(
character))) {
if (o instanceof NPC) {
conn.write(new NPCInformationPacket((NPC) o));
} else if (o instanceof L2Character) {
conn.write(new CharacterInformationBroadcastPacket(
(L2Character) o));
}
}
}
@Override
@@ -303,7 +352,8 @@ public class CharacterServiceImpl extends AbstractService implements
@Override
public void attack(L2Character character, Actor target)
throws CannotSetTargetServiceException, ActorIsNotAttackableServiceException {
throws CannotSetTargetServiceException,
ActorIsNotAttackableServiceException {
Preconditions.checkNotNull(character, "character");
Preconditions.checkNotNull(target, "target");
final CharacterID id = character.getID();
@@ -388,9 +438,10 @@ public class CharacterServiceImpl extends AbstractService implements
// ignore while teleporting, for some reason the client sends a
// validation just before teleport packet
return;
final Point old = character.getPoint();
character.setPoint(point);
character.setState(CharacterState.MOVING);
eventDispatcher.dispatch(new CharacterMoveEvent(character, point));
eventDispatcher.dispatch(new CharacterMoveEvent(character, old));
}
@Override

View File

@@ -16,11 +16,15 @@
*/
package com.l2jserver.service.game.npc;
import java.util.List;
import com.l2jserver.game.net.packet.client.CharacterActionPacket.CharacterAction;
import com.l2jserver.model.template.NPCTemplate;
import com.l2jserver.model.world.L2Character;
import com.l2jserver.model.world.NPC;
import com.l2jserver.service.Service;
import com.l2jserver.service.game.spawn.AlreadySpawnedServiceException;
import com.l2jserver.service.game.spawn.SpawnPointNotFoundServiceException;
/**
* This service manages {@link NPC} instances
@@ -56,6 +60,17 @@ public interface NPCService extends Service {
void action(NPC npc, L2Character character, String... args)
throws ActionServiceException;
/**
* Load from database and spawn all {@link NPC NPCs} instances
*
* @throws AlreadySpawnedServiceException
* if one of the NPCs is already spawned
* @throws SpawnPointNotFoundServiceException
* if one of the NPCs does not have an spawn point defined
*/
List<NPC> spawnAll() throws SpawnPointNotFoundServiceException,
AlreadySpawnedServiceException;
/**
* Attacks an given NPC, if possible.
*

View File

@@ -16,12 +16,19 @@
*/
package com.l2jserver.service.game.npc;
import java.util.List;
import com.google.common.base.Preconditions;
import com.google.inject.Inject;
import com.l2jserver.db.dao.NPCDAO;
import com.l2jserver.game.net.packet.client.CharacterActionPacket.CharacterAction;
import com.l2jserver.model.template.NPCTemplate;
import com.l2jserver.model.world.L2Character;
import com.l2jserver.model.world.NPC;
import com.l2jserver.service.AbstractService;
import com.l2jserver.service.game.spawn.AlreadySpawnedServiceException;
import com.l2jserver.service.game.spawn.SpawnPointNotFoundServiceException;
import com.l2jserver.service.game.spawn.SpawnService;
import com.l2jserver.util.exception.L2Exception;
/**
@@ -30,6 +37,22 @@ import com.l2jserver.util.exception.L2Exception;
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class NPCServiceImpl extends AbstractService implements NPCService {
/**
* The {@link SpawnService} used to spawn the {@link NPC} instances
*/
private final SpawnService spawnService;
/**
* The {@link NPCDAO}
*/
private final NPCDAO npcDao;
@Inject
public NPCServiceImpl(SpawnService spawnService, NPCDAO npcDao) {
this.spawnService = spawnService;
this.npcDao = npcDao;
}
@Override
public void action(NPC npc, L2Character character, CharacterAction action)
throws ActionServiceException {
@@ -61,6 +84,16 @@ public class NPCServiceImpl extends AbstractService implements NPCService {
}
}
@Override
public List<NPC> spawnAll() throws SpawnPointNotFoundServiceException,
AlreadySpawnedServiceException {
final List<NPC> npcs = npcDao.loadAll();
for (final NPC npc : npcs) {
spawnService.spawn(npc, null);
}
return null;
}
@Override
public void attack(NPC npc, L2Character attacker)
throws NotAttackableNPCServiceException {

View File

@@ -27,6 +27,7 @@ import com.google.common.base.Preconditions;
import com.google.inject.Inject;
import com.l2jserver.db.dao.CharacterDAO;
import com.l2jserver.db.dao.ItemDAO;
import com.l2jserver.db.dao.NPCDAO;
import com.l2jserver.model.id.ID;
import com.l2jserver.model.id.ObjectID;
import com.l2jserver.model.id.object.allocator.IDAllocator;
@@ -64,6 +65,10 @@ public class CachedWorldIDService extends AbstractService implements
* The {@link ItemDAO}
*/
private final ItemDAO itemDao;
/**
* The {@link NPCDAO}
*/
private final NPCDAO npcDao;
/**
* The ID cache
@@ -77,11 +82,12 @@ public class CachedWorldIDService extends AbstractService implements
@Inject
public CachedWorldIDService(CacheService cacheService,
IDAllocator allocator, CharacterDAO characterDao, ItemDAO itemDao) {
IDAllocator allocator, CharacterDAO characterDao, ItemDAO itemDao, NPCDAO npcDao) {
this.cacheService = cacheService;
this.allocator = allocator;
this.characterDao = characterDao;
this.itemDao = itemDao;
this.npcDao = npcDao;
}
@Override
@@ -99,6 +105,7 @@ public class CachedWorldIDService extends AbstractService implements
public void load() {
load(characterDao.listIDs());
load(itemDao.listIDs());
//load(npcDao.listIDs());
loaded = true;
}

View File

@@ -39,7 +39,7 @@ public abstract class FilteredWorldListener<T extends WorldObject> implements
@SuppressWarnings("unchecked")
public boolean dispatch(WorldEvent e) {
if (!filter.accept((T) e.getObject()))
return false;
return true;
return dispatch(e, (T) e.getObject());
}

View File

@@ -21,6 +21,7 @@ import java.util.Queue;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
@@ -63,32 +64,35 @@ public class WorldEventDispatcherImpl implements WorldEventDispatcher {
/**
* The events pending dispatch
*/
private Queue<EventContainer> events = CollectionFactory
.newConcurrentQueue();
private Queue<EventContainer> events = new ArrayBlockingQueue<EventContainer>(
100 * 1000);
public void start() {
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
final TimerTask task = new TimerTask() {
@Override
public void run() {
final EventContainer event = events.poll();
if (event == null)
return;
try {
// set state
event.future.running = true;
event.future.complete = false;
EventContainer event;
while ((event = events.poll()) != null) {
try {
log.debug("Dispatching event {}", event.event);
// dispatch
if (doDispatch(event))
// the set will update state
event.future.set(event.event);
} catch (Throwable t) {
event.future.setException(t);
log.warn("Exception in WorldEventDispatcher thread", t);
// set state
event.future.running = true;
event.future.complete = false;
// dispatch
if (doDispatch(event))
// the set will update state
event.future.set(event.event);
} catch (Throwable t) {
event.future.setException(t);
log.warn("Exception in WorldEventDispatcher thread", t);
}
}
}
}, 0, 50);
};
timer.scheduleAtFixedRate(task, 0, 50);
}
@Override
@@ -97,6 +101,9 @@ public class WorldEventDispatcherImpl implements WorldEventDispatcher {
log.debug("Queing dispatch for event {}", event);
final WorldEventFutureImpl<E> future = new WorldEventFutureImpl<E>();
events.add(new EventContainer(event, future));
// final WorldEventFutureImpl<E> future = new WorldEventFutureImpl<E>();
// final EventContainer c = new EventContainer(event, future);
// doDispatch(c);
return future;
}
@@ -107,12 +114,24 @@ public class WorldEventDispatcherImpl implements WorldEventDispatcher {
* the event
* @return true if dispatch was not canceled
*/
public boolean doDispatch(EventContainer event) {
log.debug("Dispatching event {}", event);
public synchronized boolean doDispatch(EventContainer event) {
final ObjectID<?>[] objects = event.event.getDispatchableObjects();
for (ObjectID<?> obj : objects) {
if (obj == null)
continue;
for (final WorldListener listener : globalListeners) {
if (event.future.isCancelled())
return false;
try {
if (!listener.dispatch(event.event))
// remove listener if return value is false
globalListeners.remove(listener);
} catch (Throwable t) {
log.warn("Exception in listener", t);
// always remove any listener that throws an exception
globalListeners.remove(listener);
}
}
final Set<WorldListener> listeners = getListeners(obj);
for (final WorldListener listener : listeners) {
if (event.future.isCancelled())
@@ -200,10 +219,7 @@ public class WorldEventDispatcherImpl implements WorldEventDispatcher {
set = CollectionFactory.newSet();
listeners.put(id, set);
}
final Set<WorldListener> union = CollectionFactory.newSet();
union.addAll(set);
union.addAll(globalListeners);
return union;
return set;
}
public void stop() {

View File

@@ -60,6 +60,6 @@ public class ExcludeFilter<O extends WorldObject> implements
@Override
public boolean accept(O object) {
return objects.contains(object);
return !objects.contains(object);
}
}

View File

@@ -19,6 +19,7 @@ package com.l2jserver.service.game.world.filter.impl;
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.ExcludeFilter;
/**
* This filter will only accept {@link WorldObject} which are in vision of
@@ -32,6 +33,7 @@ public class KnownListFilter extends AndFilter<PositionableObject> {
@SuppressWarnings("unchecked")
public KnownListFilter(PositionableObject object) {
super(new InstanceFilter<PositionableObject>(PositionableObject.class),
new RangeFilter(object, KNOWNLIST_RANGE));
new RangeFilter(object, KNOWNLIST_RANGE),
new ExcludeFilter<PositionableObject>(object));
}
}

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.service.game.world.filter.impl;
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;
/**
* This filter will only accept {@link WorldObject} which are in vision of
* another object.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class KnownListUpdateFilter extends AndFilter<PositionableObject> {
public static final int KNOWNLIST_RANGE = 2000;
@SuppressWarnings("unchecked")
public KnownListUpdateFilter(PositionableObject object, Point old) {
super(new KnownListFilter(object), new NotFilter<PositionableObject>(
new RangePointFilter(old, KNOWNLIST_RANGE)));
}
}

View File

@@ -0,0 +1,60 @@
/*
* 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.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;
/**
* Filter objects that are in the <tt>range</tt> of <tt>coordinate</tt>
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class RangePointFilter implements WorldObjectFilter<PositionableObject> {
/**
* The coordinate point
*/
private final Point point;
/**
* The desired maximum distance of the object
*/
private final int range;
/**
* Creates a new instance
*
* @param objcect
* the positionable object as center point for range search
* @param range
* the desired maximum distance of the object
*/
public RangePointFilter(final Point point, final int range) {
Preconditions.checkNotNull(point, "point");
Preconditions.checkState(range >= 0, "range < 0");
this.point = point;
this.range = range;
}
@Override
public boolean accept(PositionableObject other) {
if (other == null)
return false;
return other.getPosition().getDistance(point.getCoordinate()) <= range;
}
}

View File

@@ -19,6 +19,7 @@ package com.l2jserver.util.factory;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Set;
import java.util.WeakHashMap;
@@ -69,6 +70,17 @@ public class CollectionFactory {
return new ConcurrentLinkedQueue<T>();
}
/**
* Creates a new priority queue of type <tt>T</tt>
*
* @param <T>
* the type
* @return the created queue
*/
public static final <T> PriorityQueue<T> newPriorityQueue() {
return new PriorityQueue<T>();
}
/**
* Creates a new map.
*