1
0
mirror of https://github.com/Rogiel/l2jserver2 synced 2025-12-06 07:32:46 +00:00

Implements item pick up

This commit is contained in:
2011-12-15 12:31:47 -02:00
parent 48b6d60007
commit 352735c8c9
20 changed files with 948 additions and 54 deletions

View File

@@ -302,12 +302,15 @@ public abstract class AbstractJDBCDatabaseService extends AbstractService
new Runnable() { new Runnable() {
@Override @Override
public void run() { public void run() {
try {
log.debug("Auto save task started"); log.debug("Auto save task started");
int objects = 0; int objects = 0;
for (final Model<?> object : objectCache) { for (final Model<?> object : objectCache) {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
final DataAccessObject<Model<?>, ?> dao = (DataAccessObject<Model<?>, ?>) daoResolver final DataAccessObject<Model<?>, ?> dao = (DataAccessObject<Model<?>, ?>) daoResolver
.getDAO(object.getClass()); .getDAO(object.getClass());
if (dao == null)
continue;
if (dao.save(object)) { if (dao.save(object)) {
objects++; objects++;
} }
@@ -315,6 +318,9 @@ public abstract class AbstractJDBCDatabaseService extends AbstractService
log.info( log.info(
"{} objects have been saved by the auto save task", "{} objects have been saved by the auto save task",
objects); objects);
} catch (Exception e) {
log.error("Error occured in save thread", e);
}
} }
}); });
} }
@@ -609,8 +615,11 @@ public abstract class AbstractJDBCDatabaseService extends AbstractService
log.debug("Mapper {} returned a null row", mapper); log.debug("Mapper {} returned a null row", mapper);
continue; continue;
} }
if (obj instanceof Model) if (obj instanceof Model) {
if (((Model<?>) obj).getObjectDesire() == ObjectDesire.INSERT) {
((Model<?>) obj).setObjectDesire(ObjectDesire.NONE); ((Model<?>) obj).setObjectDesire(ObjectDesire.NONE);
}
}
log.debug("Mapper {} returned {}", mapper, obj); log.debug("Mapper {} returned {}", mapper, obj);
list.add(obj); list.add(obj);
} }
@@ -685,8 +694,11 @@ public abstract class AbstractJDBCDatabaseService extends AbstractService
while (rs.next()) { while (rs.next()) {
log.debug("Mapping row {} with {}", rs, mapper); log.debug("Mapping row {} with {}", rs, mapper);
final T object = mapper.map(rs); final T object = mapper.map(rs);
if (object instanceof Model) if (object instanceof Model) {
if (((Model<?>) object).getObjectDesire() == ObjectDesire.INSERT) {
((Model<?>) object).setObjectDesire(ObjectDesire.NONE); ((Model<?>) object).setObjectDesire(ObjectDesire.NONE);
}
}
log.debug("Mapper {} returned {}", mapper, object); log.debug("Mapper {} returned {}", mapper, object);
return object; return object;
} }

View File

@@ -27,6 +27,9 @@ import com.l2jserver.game.net.codec.Lineage2PacketReader;
import com.l2jserver.game.net.codec.Lineage2PacketWriter; import com.l2jserver.game.net.codec.Lineage2PacketWriter;
import com.l2jserver.game.net.packet.ServerPacket; import com.l2jserver.game.net.packet.ServerPacket;
import com.l2jserver.game.net.packet.server.SM_ACTION_FAILED; import com.l2jserver.game.net.packet.server.SM_ACTION_FAILED;
import com.l2jserver.game.net.packet.server.SM_CHAR_INVENTORY;
import com.l2jserver.game.net.packet.server.SM_CHAR_INVENTORY_UPDATE;
import com.l2jserver.game.net.packet.server.SM_CHAR_INVENTORY_UPDATE.InventoryUpdateType;
import com.l2jserver.game.net.packet.server.SM_COMMUNITY_HTML; import com.l2jserver.game.net.packet.server.SM_COMMUNITY_HTML;
import com.l2jserver.game.net.packet.server.SM_HTML; import com.l2jserver.game.net.packet.server.SM_HTML;
import com.l2jserver.game.net.packet.server.SM_SYSTEM_MESSAGE; import com.l2jserver.game.net.packet.server.SM_SYSTEM_MESSAGE;
@@ -321,6 +324,57 @@ public class Lineage2Client {
return write(new SM_COMMUNITY_HTML(template)); return write(new SM_COMMUNITY_HTML(template));
} }
/**
* Sends the whole user inventory to the client. This is a very bandwidth
* consuming process and should be avoided.
*
* @return the {@link ChannelFuture} that will be notified once the packet
* has been written.
*/
public ChannelFuture sendInventoryUpdate() {
return write(new SM_CHAR_INVENTORY(characterID.getObject()
.getInventory()));
}
/**
* Removes <code>items</code> from the game client UI.
*
* @param items
* the list of items to be removed
* @return the {@link ChannelFuture} that will be notified once the packet
* has been written.
*/
public ChannelFuture removeInventoryItems(Item... items) {
return write(new SM_CHAR_INVENTORY_UPDATE(InventoryUpdateType.REMOVE,
items));
}
/**
* Updates <code>items</code> in the game client UI.
*
* @param items
* the list of items to be updated
* @return the {@link ChannelFuture} that will be notified once the packet
* has been written.
*/
public ChannelFuture updateInventoryItems(Item... items) {
return write(new SM_CHAR_INVENTORY_UPDATE(InventoryUpdateType.UPDATE,
items));
}
/**
* Adds <code>items</code> in the game client UI.
*
* @param items
* the list of items to be added
* @return the {@link ChannelFuture} that will be notified once the packet
* has been written.
*/
public ChannelFuture addInventoryItems(Item... items) {
return write(new SM_CHAR_INVENTORY_UPDATE(InventoryUpdateType.ADD,
items));
}
/** /**
* Broadcast a packet to all characters in this character knownlist. * Broadcast a packet to all characters in this character knownlist.
* <p> * <p>

View File

@@ -20,14 +20,20 @@ import org.jboss.netty.buffer.ChannelBuffer;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.l2jserver.game.net.Lineage2Client; import com.l2jserver.game.net.Lineage2Client;
import com.l2jserver.game.net.SystemMessage;
import com.l2jserver.game.net.packet.AbstractClientPacket; import com.l2jserver.game.net.packet.AbstractClientPacket;
import com.l2jserver.model.id.ObjectID; import com.l2jserver.model.id.ObjectID;
import com.l2jserver.model.id.object.ItemID;
import com.l2jserver.model.id.object.NPCID; import com.l2jserver.model.id.object.NPCID;
import com.l2jserver.model.id.object.provider.ObjectIDResolver; import com.l2jserver.model.id.object.provider.ObjectIDResolver;
import com.l2jserver.model.world.Item;
import com.l2jserver.model.world.NPC; import com.l2jserver.model.world.NPC;
import com.l2jserver.service.game.character.CannotSetTargetServiceException; import com.l2jserver.service.game.character.CannotSetTargetServiceException;
import com.l2jserver.service.game.item.ItemNotOnGroundServiceException;
import com.l2jserver.service.game.item.ItemService;
import com.l2jserver.service.game.npc.ActionServiceException; import com.l2jserver.service.game.npc.ActionServiceException;
import com.l2jserver.service.game.npc.NPCService; import com.l2jserver.service.game.npc.NPCService;
import com.l2jserver.service.game.spawn.NotSpawnedServiceException;
import com.l2jserver.util.geometry.Coordinate; import com.l2jserver.util.geometry.Coordinate;
/** /**
@@ -41,18 +47,37 @@ public class CM_CHAR_ACTION extends AbstractClientPacket {
*/ */
public static final int OPCODE = 0x1f; public static final int OPCODE = 0x1f;
/**
* The {@link ObjectID} resolver
*/
private final ObjectIDResolver idResolver; private final ObjectIDResolver idResolver;
/**
* The {@link NPC} Service
*/
private final NPCService npcService; private final NPCService npcService;
/**
* The {@link Item} Service
*/
private final ItemService itemService;
/**
* The object id
*/
private int objectId; private int objectId;
@SuppressWarnings("unused") @SuppressWarnings("unused")
private Coordinate origin; private Coordinate origin;
/**
* The character action type (aka mouse button)
*/
private CharacterAction action; private CharacterAction action;
public enum CharacterAction { public enum CharacterAction {
/**
* If the player has clicked with the left mouse button.
*/
CLICK(0), CLICK(0),
/** /**
* This is the right click action. * If the player has clicked with the right mouse button.
*/ */
RIGHT_CLICK(1); RIGHT_CLICK(1);
@@ -71,9 +96,11 @@ public class CM_CHAR_ACTION extends AbstractClientPacket {
} }
@Inject @Inject
public CM_CHAR_ACTION(ObjectIDResolver idResolver, NPCService npcService) { public CM_CHAR_ACTION(ObjectIDResolver idResolver, NPCService npcService,
ItemService itemService) {
this.idResolver = idResolver; this.idResolver = idResolver;
this.npcService = npcService; this.npcService = npcService;
this.itemService = itemService;
} }
@Override @Override
@@ -86,13 +113,9 @@ public class CM_CHAR_ACTION extends AbstractClientPacket {
@Override @Override
public void process(final Lineage2Client conn) { public void process(final Lineage2Client conn) {
// since this is an erasure type, this is safe. final ObjectID<?> id = idResolver.resolve(objectId);
final ObjectID<NPC> id = idResolver.resolve(objectId); if (id instanceof NPCID) {
if (!(id instanceof NPCID)) { final NPC npc = ((NPCID) id).getObject();
conn.sendActionFailed();
return;
}
final NPC npc = id.getObject();
try { try {
npcService.action(npc, conn.getCharacter(), action); npcService.action(npc, conn.getCharacter(), action);
} catch (ActionServiceException e) { } catch (ActionServiceException e) {
@@ -100,5 +123,29 @@ public class CM_CHAR_ACTION extends AbstractClientPacket {
} catch (CannotSetTargetServiceException e) { } catch (CannotSetTargetServiceException e) {
conn.sendActionFailed(); conn.sendActionFailed();
} }
} else if (id instanceof ItemID) {
final Item item = ((ItemID) id).getObject();
try {
final Item stackItem = itemService.action(item,
conn.getCharacter(), action);
if (stackItem.equals(item)) { // adds
conn.addInventoryItems(stackItem);
} else { // update only
conn.updateInventoryItems(stackItem);
}
conn.sendSystemMessage(SystemMessage.YOU_PICKED_UP_S1_S2, Long
.toString(item.getCount()), item.getTemplate()
.getName());
conn.sendActionFailed();
} catch (ItemNotOnGroundServiceException
| NotSpawnedServiceException e) {
conn.sendSystemMessage(SystemMessage.FAILED_TO_PICKUP_S1, item
.getTemplate().getName());
conn.sendActionFailed();
}
} else {
conn.sendActionFailed();
return;
}
} }
} }

View File

@@ -22,7 +22,7 @@ import com.l2jserver.game.net.Lineage2Client;
import com.l2jserver.game.net.packet.AbstractServerPacket; import com.l2jserver.game.net.packet.AbstractServerPacket;
import com.l2jserver.model.world.Item; import com.l2jserver.model.world.Item;
import com.l2jserver.model.world.character.CharacterInventory; import com.l2jserver.model.world.character.CharacterInventory;
import com.l2jserver.model.world.character.CharacterInventory.InventoryLocation; import com.l2jserver.model.world.character.CharacterInventory.ItemLocation;
/** /**
* This packet send the inventory to the client * This packet send the inventory to the client
@@ -58,7 +58,7 @@ public class SM_CHAR_INVENTORY extends AbstractServerPacket {
// TODO implement real item slot // TODO implement real item slot
int slot = 0; int slot = 0;
for (Item item : inventory) { for (Item item : inventory) {
if (item.getLocation() == InventoryLocation.WAREHOUSE if (item.getLocation() == ItemLocation.WAREHOUSE
|| item.getLocation() == null) { || item.getLocation() == null) {
continue; continue;
} }
@@ -69,7 +69,7 @@ public class SM_CHAR_INVENTORY extends AbstractServerPacket {
buffer.writeLong(item.getCount()); // count buffer.writeLong(item.getCount()); // count
buffer.writeShort(0x00); // item type2 buffer.writeShort(0x00); // item type2
buffer.writeShort(0x00); // item type3 buffer.writeShort(0x00); // item type3
buffer.writeShort((item.getLocation() == InventoryLocation.PAPERDOLL ? 0x01 buffer.writeShort((item.getLocation() == ItemLocation.PAPERDOLL ? 0x01
: 0x00)); // equiped? : 0x00)); // equiped?
buffer.writeInt((item.getPaperdoll() != null ? item.getPaperdoll().id buffer.writeInt((item.getPaperdoll() != null ? item.getPaperdoll().id
: 0)); // body part : 0)); // body part

View File

@@ -0,0 +1,226 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 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.
*
* l2jserver2 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 l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.server;
import java.util.Map;
import java.util.Map.Entry;
import org.jboss.netty.buffer.ChannelBuffer;
import com.l2jserver.game.net.Lineage2Client;
import com.l2jserver.game.net.packet.AbstractServerPacket;
import com.l2jserver.model.world.Item;
import com.l2jserver.model.world.character.CharacterInventory.ItemLocation;
import com.l2jserver.util.factory.CollectionFactory;
/**
* This packet send the inventory to the client
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class SM_CHAR_INVENTORY_UPDATE extends AbstractServerPacket {
/**
* The packet OPCODE
*/
public static final int OPCODE = 0x21;
/**
* List of items to be updated in the client
*/
private final Map<Item, InventoryUpdateType> items = CollectionFactory
.newMap();
/**
* The type of operation to be performed.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public enum InventoryUpdateType {
/**
* Flags the item to be added to the inventory list
*/
ADD(1),
/**
* Flags the item to be updated in the inventory list
*/
UPDATE(2),
/**
* Flags the item to be removed in the inventory list
*/
REMOVE(3);
/**
* The operation ID
*/
public final int id;
/**
* @param id
* the operation ID
*/
private InventoryUpdateType(int id) {
this.id = id;
}
}
/**
* Creates an empty instance. Items can be added, removed or update using
* {@link #add(Item)}, {@link #remove(Item)} and {@link #update(Item)}.
*/
public SM_CHAR_INVENTORY_UPDATE() {
super(OPCODE);
}
/**
* Creates a new instance with several items performing
* {@link InventoryUpdateType} <code>type</code> operation.
*
* @param type
* the operation type
* @param items
* the items
*/
public SM_CHAR_INVENTORY_UPDATE(InventoryUpdateType type, Item... items) {
super(OPCODE);
switch (type) {
case ADD:
add(items);
break;
case REMOVE:
remove(items);
break;
case UPDATE:
update(items);
break;
}
}
@Override
public void write(Lineage2Client conn, ChannelBuffer buffer) {
buffer.writeShort(items.size()); // item count
for (Entry<Item, InventoryUpdateType> e : items.entrySet()) {
final Item item = e.getKey();
final InventoryUpdateType type = e.getValue();
buffer.writeShort(type.id); // change type
buffer.writeInt(item.getID().getID()); // obj id
buffer.writeInt(item.getTemplateID().getID()); // item id
buffer.writeInt(0x00); // loc slot
buffer.writeLong(item.getCount()); // count
buffer.writeShort(0x00); // item type2
buffer.writeShort(0x00); // item type3
buffer.writeShort((item.getLocation() == ItemLocation.PAPERDOLL ? 0x01
: 0x00)); // equiped?
buffer.writeInt((item.getPaperdoll() != null ? item.getPaperdoll().id
: 0)); // body part
buffer.writeShort(127); // enchant level
// race tickets
buffer.writeShort(0x00); // item type4 (custom type 2)
buffer.writeInt(0x00); // augument
buffer.writeInt(0x00); // mana
buffer.writeInt(-9999); // time
buffer.writeShort(0x00); // attack element type
buffer.writeShort(0x00); // attack element power
for (byte i = 0; i < 6; i++) {
buffer.writeShort(0x00); // element def attrib
}
// Enchant Effects
buffer.writeShort(0x00);
buffer.writeShort(0x00);
buffer.writeShort(0x00);
}
}
/**
* Removes a single item
*
* @param item
* the item to be removed
* @return this instance
*/
public SM_CHAR_INVENTORY_UPDATE remove(Item item) {
items.put(item, InventoryUpdateType.REMOVE);
return this;
}
/**
* Removes several items
*
* @param items
* the items to be removed
* @return this instance
*/
public SM_CHAR_INVENTORY_UPDATE remove(Item... items) {
for (final Item item : items) {
remove(item);
}
return this;
}
/**
* Adds a single item
*
* @param item
* the item to be added
* @return this instance
*/
public SM_CHAR_INVENTORY_UPDATE add(Item item) {
items.put(item, InventoryUpdateType.ADD);
return this;
}
/**
* Adds several items
*
* @param items
* the item to be added
* @return this instance
*/
public SM_CHAR_INVENTORY_UPDATE add(Item... items) {
for (final Item item : items) {
add(item);
}
return this;
}
/**
* Updates a single item
*
* @param item
* the item to be updated
* @return this instance
*/
public SM_CHAR_INVENTORY_UPDATE update(Item item) {
items.put(item, InventoryUpdateType.UPDATE);
return this;
}
/**
* Updates several items
*
* @param items
* the item to be updated
* @return this instance
*/
public SM_CHAR_INVENTORY_UPDATE update(Item... items) {
for (final Item item : items) {
update(item);
}
return this;
}
}

View File

@@ -19,7 +19,7 @@ package com.l2jserver.model.world;
import com.l2jserver.model.id.object.CharacterID; import com.l2jserver.model.id.object.CharacterID;
import com.l2jserver.model.id.template.ItemTemplateID; import com.l2jserver.model.id.template.ItemTemplateID;
import com.l2jserver.model.template.item.ItemTemplate; import com.l2jserver.model.template.item.ItemTemplate;
import com.l2jserver.model.world.character.CharacterInventory.InventoryLocation; import com.l2jserver.model.world.character.CharacterInventory.ItemLocation;
import com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll; import com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll;
/** /**
@@ -27,13 +27,13 @@ import com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll
* be: * be:
* <ul> * <ul>
* <li><b>In the {@link L2Character character} inventory</b>: <tt>location</tt> * <li><b>In the {@link L2Character character} inventory</b>: <tt>location</tt>
* is {@link InventoryLocation#INVENTORY}, <tt>coordinate</tt> and * is {@link ItemLocation#INVENTORY}, <tt>coordinate</tt> and
* <tt>paperdoll</tt> are null.</li> * <tt>paperdoll</tt> are null.</li>
* <li><b>In the {@link L2Character character} warehouse</b>: <tt>location</tt> * <li><b>In the {@link L2Character character} warehouse</b>: <tt>location</tt>
* is {@link InventoryLocation#WAREHOUSE}, <tt>coordinate</tt> and * is {@link ItemLocation#WAREHOUSE}, <tt>coordinate</tt> and
* <tt>paperdoll</tt> are null.</li> * <tt>paperdoll</tt> are null.</li>
* <li><b>Equipped by the {@link L2Character character}</b>: <tt>location</tt> * <li><b>Equipped by the {@link L2Character character}</b>: <tt>location</tt>
* is {@link InventoryLocation#PAPERDOLL}, <tt>paperdoll</tt> is not null and * is {@link ItemLocation#PAPERDOLL}, <tt>paperdoll</tt> is not null and
* <tt>coordinate</tt> is null.</li> * <tt>coordinate</tt> is null.</li>
* <li><b>Dropped on the ground</b>: <tt>location</tt></li> and * <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 * <tt>paperdoll</tt> are null, <tt>coordinate</tt> is not null and represents
@@ -58,7 +58,7 @@ public class Item extends PositionableObject {
/** /**
* Inventory location of this item * Inventory location of this item
*/ */
private InventoryLocation location; private ItemLocation location;
/** /**
* Paperdoll slot for this item * Paperdoll slot for this item
*/ */
@@ -96,7 +96,7 @@ public class Item extends PositionableObject {
/** /**
* @return the location * @return the location
*/ */
public InventoryLocation getLocation() { public ItemLocation getLocation() {
return location; return location;
} }
@@ -104,10 +104,10 @@ public class Item extends PositionableObject {
* @param location * @param location
* the location to set * the location to set
*/ */
public void setLocation(InventoryLocation location) { public void setLocation(ItemLocation location) {
desireUpdate(); desireUpdate();
this.location = location; this.location = location;
if (location != InventoryLocation.PAPERDOLL) if (location != ItemLocation.PAPERDOLL)
this.paperdoll = null; this.paperdoll = null;
} }

View File

@@ -36,7 +36,7 @@ public interface TemporalEffect extends Effect {
* @author <a href="http://www.rogiel.com">Rogiel</a> * @author <a href="http://www.rogiel.com">Rogiel</a>
*/ */
public enum TemporalEffectAction { public enum TemporalEffectAction {
CANCEL; CANCEL, CONTINUE;
} }
/** /**

View File

@@ -16,10 +16,12 @@
*/ */
package com.l2jserver.model.world.character; package com.l2jserver.model.world.character;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Iterator; import java.util.Iterator;
import java.util.Set; import java.util.Set;
import com.l2jserver.model.id.object.ItemID;
import com.l2jserver.model.world.Item; import com.l2jserver.model.world.Item;
import com.l2jserver.model.world.L2Character; import com.l2jserver.model.world.L2Character;
import com.l2jserver.util.factory.CollectionFactory; import com.l2jserver.util.factory.CollectionFactory;
@@ -50,6 +52,48 @@ public class CharacterInventory implements Iterable<Item> {
this.character = character; this.character = character;
} }
/**
* Adds an item to the player inventory.
*
* @param item
* the item
*/
public void add(Item item) {
items.add(item);
}
/**
* Removes the item from the players inventory.
*
* @param item
* the item to be removed
* @return the item if it was successfully removed or <code>null</code> if
* the item was not removed.
*/
public Item remove(Item item) {
if (items.remove(item))
return item;
return null;
}
/**
* Removes all items from the given {@link ItemID}
*
* @param itemID
* the {@link ItemID}
* @return an array of all items removed. Can never be <code>null</code>.
*/
public Item[] remove(ItemID itemID) {
final ArrayList<Item> removedItems = new ArrayList<Item>();
for (final Item item : items) {
if (item.getID().equals(itemID)) {
items.remove(item);
removedItems.add(item);
}
}
return removedItems.toArray(new Item[removedItems.size()]);
}
/** /**
* Get the item in the given <tt>paperdoll</tt> slot * Get the item in the given <tt>paperdoll</tt> slot
* *
@@ -105,7 +149,7 @@ public class CharacterInventory implements Iterable<Item> {
* *
* @author <a href="http://www.rogiel.com">Rogiel</a> * @author <a href="http://www.rogiel.com">Rogiel</a>
*/ */
public enum InventoryLocation { public enum ItemLocation {
/** /**
* The item is dropped on the ground * The item is dropped on the ground
*/ */
@@ -125,7 +169,7 @@ public class CharacterInventory implements Iterable<Item> {
} }
/** /**
* {@link InventoryLocation#PAPERDOLL Paperdoll} slots for items * {@link ItemLocation#PAPERDOLL Paperdoll} slots for items
* *
* @author <a href="http://www.rogiel.com">Rogiel</a> * @author <a href="http://www.rogiel.com">Rogiel</a>
*/ */

View File

@@ -19,6 +19,7 @@ package com.l2jserver.model.world.character;
import com.l2jserver.model.template.item.ItemTemplate; import com.l2jserver.model.template.item.ItemTemplate;
import com.l2jserver.model.world.L2Character; import com.l2jserver.model.world.L2Character;
import com.l2jserver.model.world.actor.calculator.ActorCalculator; import com.l2jserver.model.world.actor.calculator.ActorCalculator;
import com.l2jserver.model.world.actor.calculator.ActorCalculatorContext;
import com.l2jserver.model.world.actor.stat.ActorStats; import com.l2jserver.model.world.actor.stat.ActorStats;
import com.l2jserver.model.world.actor.stat.StatType; import com.l2jserver.model.world.actor.stat.StatType;
import com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll; import com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll;
@@ -50,6 +51,7 @@ import com.l2jserver.model.world.character.calculator.base.CharacterBaseRunSpeed
import com.l2jserver.model.world.character.calculator.base.CharacterBaseStrengthCalculator; import com.l2jserver.model.world.character.calculator.base.CharacterBaseStrengthCalculator;
import com.l2jserver.model.world.character.calculator.base.CharacterBaseWalkSpeedCalculator; import com.l2jserver.model.world.character.calculator.base.CharacterBaseWalkSpeedCalculator;
import com.l2jserver.model.world.character.calculator.base.CharacterBaseWitnessCalculator; import com.l2jserver.model.world.character.calculator.base.CharacterBaseWitnessCalculator;
import com.l2jserver.util.calculator.Calculator;
/** /**
* This class is responsible for calculating the real character stats. The real * This class is responsible for calculating the real character stats. The real
@@ -263,7 +265,7 @@ public class CharacterStats extends ActorStats<CharacterCalculatorContext> {
/** /**
* The character calculator * The character calculator
*/ */
private static final CharacterCalculator calculator = new CharacterCalculator(); private final CharacterCalculator calculator = new CharacterCalculator();
/** /**
* Creates a new {@link CharacterStats} and adds default calculators * Creates a new {@link CharacterStats} and adds default calculators
@@ -289,6 +291,24 @@ public class CharacterStats extends ActorStats<CharacterCalculatorContext> {
return (int) calc(StatType.MAX_CP); return (int) calc(StatType.MAX_CP);
} }
/**
* Adds an formula to the character calculator
*
* @param formula
* the formula
*/
public void addMaxCP(Calculator<ActorCalculatorContext, StatType> formula) {
calculator.add(formula);
}
/**
* Reset the calculator to its default state
*/
public void resetMaxCP() {
calculator.remove(BASE_CP_FORMULA);
calculator.add(BASE_CP_FORMULA);
}
/** /**
* @return the calculated maximum load * @return the calculated maximum load
*/ */
@@ -296,6 +316,24 @@ public class CharacterStats extends ActorStats<CharacterCalculatorContext> {
return (int) calc(StatType.MAX_LOAD); return (int) calc(StatType.MAX_LOAD);
} }
/**
* Adds an formula to the character calculator
*
* @param formula
* the formula
*/
public void addMaximumLoad(Calculator<ActorCalculatorContext, StatType> formula) {
calculator.add(formula);
}
/**
* Reset the calculator to its default state
*/
public void resetMaximumLoad() {
calculator.remove(BASE_CP_FORMULA);
calculator.add(BASE_CP_FORMULA);
}
/** /**
* Setups the default formulas * Setups the default formulas
*/ */

View File

@@ -0,0 +1,84 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 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.
*
* l2jserver2 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 l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.model.world.item;
import com.l2jserver.model.id.ObjectID;
import com.l2jserver.model.world.Actor;
import com.l2jserver.model.world.Item;
import com.l2jserver.model.world.L2Character;
import com.l2jserver.model.world.Player;
import com.l2jserver.model.world.WorldObject;
import com.l2jserver.model.world.character.event.CharacterEvent;
/**
* Event dispatched once an {@link Item} has been picked up on the ground.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class ItemPickUpEvent implements ItemEvent, CharacterEvent {
/**
* The pickupping character
*/
private final L2Character character;
/**
* The item picked up
*/
private final Item item;
/**
* Creates a new instance of this event
*
* @param character
* the picking up character
* @param item
* the picked up item
*/
public ItemPickUpEvent(L2Character character, Item item) {
this.character = character;
this.item = item;
}
@Override
public WorldObject getObject() {
return item;
}
@Override
public L2Character getCharacter() {
return character;
}
@Override
public Player getPlayer() {
return character;
}
@Override
public Item getItem() {
return item;
}
@Override
public Actor getActor() {
return character;
}
@Override
public ObjectID<?>[] getDispatchableObjects() {
return new ObjectID<?>[] { item.getID() };
}
}

View File

@@ -19,6 +19,7 @@ package com.l2jserver.service.database.jdbc;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Types;
import java.util.List; import java.util.List;
import org.slf4j.Logger; import org.slf4j.Logger;
@@ -36,8 +37,8 @@ import com.l2jserver.model.template.item.ItemTemplate;
import com.l2jserver.model.world.Item; import com.l2jserver.model.world.Item;
import com.l2jserver.model.world.L2Character; import com.l2jserver.model.world.L2Character;
import com.l2jserver.model.world.character.CharacterInventory; import com.l2jserver.model.world.character.CharacterInventory;
import com.l2jserver.model.world.character.CharacterInventory.InventoryLocation;
import com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll; import com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll;
import com.l2jserver.model.world.character.CharacterInventory.ItemLocation;
import com.l2jserver.service.database.AbstractJDBCDatabaseService.CachedMapper; import com.l2jserver.service.database.AbstractJDBCDatabaseService.CachedMapper;
import com.l2jserver.service.database.AbstractJDBCDatabaseService.InsertUpdateQuery; import com.l2jserver.service.database.AbstractJDBCDatabaseService.InsertUpdateQuery;
import com.l2jserver.service.database.AbstractJDBCDatabaseService.Mapper; import com.l2jserver.service.database.AbstractJDBCDatabaseService.Mapper;
@@ -129,7 +130,8 @@ public abstract class JDBCItemDAO extends AbstractJDBCDAO<Item, ItemID>
.getInt(TEMPLATE_ID)); .getInt(TEMPLATE_ID));
final ItemTemplate template = templateId.getTemplate(); final ItemTemplate template = templateId.getTemplate();
if (template == null) { if (template == null) {
log.warn("No template found for {} while loading {}", templateId, id); log.warn("No template found for {} while loading {}",
templateId, id);
return null; return null;
} }
final Item item = template.create(); final Item item = template.create();
@@ -138,8 +140,7 @@ public abstract class JDBCItemDAO extends AbstractJDBCDAO<Item, ItemID>
if (rs.getObject(CHAR_ID) != null) if (rs.getObject(CHAR_ID) != null)
item.setOwnerID(charIdFactory.resolveID(rs.getInt(CHAR_ID))); item.setOwnerID(charIdFactory.resolveID(rs.getInt(CHAR_ID)));
if (rs.getObject(LOCATION) != null) if (rs.getObject(LOCATION) != null)
item.setLocation(InventoryLocation.valueOf(rs item.setLocation(ItemLocation.valueOf(rs.getString(LOCATION)));
.getString(LOCATION)));
if (rs.getObject(PAPERDOLL) != null) if (rs.getObject(PAPERDOLL) != null)
item.setPaperdoll(InventoryPaperdoll.valueOf(rs item.setPaperdoll(InventoryPaperdoll.valueOf(rs
.getString(PAPERDOLL))); .getString(PAPERDOLL)));
@@ -211,7 +212,7 @@ public abstract class JDBCItemDAO extends AbstractJDBCDAO<Item, ItemID>
@Override @Override
protected void parametize(PreparedStatement st) throws SQLException { protected void parametize(PreparedStatement st) throws SQLException {
st.setString(1, InventoryLocation.GROUND.name()); st.setString(1, ItemLocation.GROUND.name());
} }
@Override @Override
@@ -244,7 +245,56 @@ public abstract class JDBCItemDAO extends AbstractJDBCDAO<Item, ItemID>
@Override @Override
public boolean update(Item item) { public boolean update(Item item) {
return false; // public static final String ITEM_ID = "item_id";
// public static final String TEMPLATE_ID = "template_id";
// public static final String CHAR_ID = JDBCCharacterDAO.CHAR_ID;
//
// public static final String LOCATION = "location";
// public static final String PAPERDOLL = "paperdoll";
// public static final String COUNT = "count";
// public static final String COORD_X = "coord_x";
// public static final String COORD_Y = "coord_y";
// public static final String COORD_Z = "coord_z";
return database.query(new InsertUpdateQuery<Item>(item) {
@Override
protected String query() {
return "UPDATE `" + TABLE + "` SET `" + CHAR_ID + "` = ?,`"
+ LOCATION + "` = ?,`" + PAPERDOLL + "` = ?,`" + COUNT
+ "` = ?,`" + COORD_X + "` = ?,`" + COORD_Y + "` = ?,`"
+ COORD_Z + "` = ? WHERE `" + ITEM_ID + "` = ?";
}
@Override
protected void parametize(PreparedStatement st, Item item)
throws SQLException {
int i = 1;
// SET
if (item.getOwnerID() != null) {
st.setInt(i++, item.getOwnerID().getID());
} else {
st.setNull(i++, Types.INTEGER);
}
st.setString(i++, item.getLocation().name());
st.setString(i++, (item.getPaperdoll() != null ? item
.getPaperdoll().name() : null));
st.setLong(i++, item.getCount());
if (item.getPoint() != null) {
st.setInt(i++, item.getPoint().getX());
st.setInt(i++, item.getPoint().getY());
st.setInt(i++, item.getPoint().getZ());
} else {
st.setInt(i++, 0);
st.setInt(i++, 0);
st.setInt(i++, 0);
}
// WHERE
st.setInt(i++, item.getID().getID());
}
}) > 0;
} }
@Override @Override

View File

@@ -63,8 +63,10 @@ public class SimpleEffectService extends AbstractService implements
@Override @Override
protected void doStart() throws ServiceStartException { protected void doStart() throws ServiceStartException {
pool = threadService.createThreadPool("EffectService", 20); final int threads = Runtime.getRuntime().availableProcessors();
for (int i = 0; i < 20; i++) {
pool = threadService.createThreadPool("EffectService", threads);
for (int i = 0; i < threads; i++) {
pool.async(10, TimeUnit.MILLISECONDS, 10, new Runnable() { pool.async(10, TimeUnit.MILLISECONDS, 10, new Runnable() {
@Override @Override
public void run() { public void run() {

View File

@@ -0,0 +1,59 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 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.
*
* l2jserver2 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 l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.service.game.item;
/**
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class ItemAlreadyOnGroundServiceException extends ItemServiceException {
/**
* Java Serialization API ID
*/
private static final long serialVersionUID = 1L;
/**
* Creates a new instance
*/
public ItemAlreadyOnGroundServiceException() {
}
/**
* @param message
* the message
* @param cause
* the cause
*/
public ItemAlreadyOnGroundServiceException(String message, Throwable cause) {
super(message, cause);
}
/**
* @param message
* the message
*/
public ItemAlreadyOnGroundServiceException(String message) {
super(message);
}
/**
* @param cause
* the cause
*/
public ItemAlreadyOnGroundServiceException(Throwable cause) {
super(cause);
}
}

View File

@@ -0,0 +1,59 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 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.
*
* l2jserver2 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 l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.service.game.item;
/**
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class ItemNotOnGroundServiceException extends ItemServiceException {
/**
* Java Serialization API ID
*/
private static final long serialVersionUID = 1L;
/**
* Creates a new instance
*/
public ItemNotOnGroundServiceException() {
}
/**
* @param message
* the message
* @param cause
* the cause
*/
public ItemNotOnGroundServiceException(String message, Throwable cause) {
super(message, cause);
}
/**
* @param message
* the message
*/
public ItemNotOnGroundServiceException(String message) {
super(message);
}
/**
* @param cause
* the cause
*/
public ItemNotOnGroundServiceException(Throwable cause) {
super(cause);
}
}

View File

@@ -16,7 +16,17 @@
*/ */
package com.l2jserver.service.game.item; package com.l2jserver.service.game.item;
import com.l2jserver.game.net.packet.client.CM_CHAR_ACTION.CharacterAction;
import com.l2jserver.model.world.Actor;
import com.l2jserver.model.world.Item;
import com.l2jserver.model.world.L2Character;
import com.l2jserver.service.Service; import com.l2jserver.service.Service;
import com.l2jserver.service.game.spawn.AlreadySpawnedServiceException;
import com.l2jserver.service.game.spawn.NotSpawnedServiceException;
import com.l2jserver.service.game.spawn.SpawnPointNotFoundServiceException;
import com.l2jserver.service.game.spawn.SpawnService;
import com.l2jserver.service.game.world.WorldService;
import com.l2jserver.util.geometry.Point3D;
/** /**
* This service handles item management. Drop and pick up, create and destroy. * This service handles item management. Drop and pick up, create and destroy.
@@ -24,5 +34,60 @@ import com.l2jserver.service.Service;
* @author <a href="http://www.rogiel.com">Rogiel</a> * @author <a href="http://www.rogiel.com">Rogiel</a>
*/ */
public interface ItemService extends Service { public interface ItemService extends Service {
/**
* Executes an action for an Item.
*
* @param item
* the item
* @param character
* the character issuing the action
* @param action
* the action type
* @return <code>item</code> or another instance if the item was stacked.
* @throws ItemNotOnGroundServiceException
* if the item is not on ground at the moment
* @throws NotSpawnedServiceException
* if the item is not registered with {@link SpawnService}
*/
Item action(Item item, L2Character character, CharacterAction action)
throws ItemNotOnGroundServiceException, NotSpawnedServiceException;
/**
* Picks up an dropped item and places it into another players inventory
*
* @param item
* the item
* @param character
* the character
* @return <code>item</code> or another instance if the item was stacked.
* @throws ItemNotOnGroundServiceException
* if the item is not on ground at the moment
* @throws NotSpawnedServiceException
* if the item is not registered with {@link SpawnService}
*/
Item pickUp(Item item, L2Character character)
throws ItemNotOnGroundServiceException, NotSpawnedServiceException;
/**
* Drops an item on the ground. If <code>actor</code> is not
* <code>null</code> he is flagged as the dropper actor.
*
* @param item
* the item
* @param point
* the drop point. Can be <code>null</code> if
* {@link Item#getPoint()} is set.
* @param actor
* the dropping actor. Can be <code>null</code>.
* @throws ItemAlreadyOnGroundServiceException
* if the item is already dropped
* @throws AlreadySpawnedServiceException
* if the item is already spawned in the {@link WorldService}
* @throws SpawnPointNotFoundServiceException
* if <code>point</code> was <code>null</code> and
* {@link Item#getPoint()} was not set.
*/
void drop(Item item, Point3D point, Actor actor)
throws ItemAlreadyOnGroundServiceException,
AlreadySpawnedServiceException, SpawnPointNotFoundServiceException;
} }

View File

@@ -0,0 +1,68 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 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.
*
* l2jserver2 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 l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.service.game.item;
import com.l2jserver.service.ServiceException;
/**
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class ItemServiceException extends ServiceException {
/**
* The Java Serialization API serial
*/
private static final long serialVersionUID = 1L;
/**
* Creates a new instance of this exception
*/
public ItemServiceException() {
super();
}
/**
* Creates a new instance of this exception
*
* @param message
* the message
* @param cause
* the root cause
*/
public ItemServiceException(String message, Throwable cause) {
super(message, cause);
}
/**
* Creates a new instance of this exception
*
* @param message
* the message
*/
public ItemServiceException(String message) {
super(message);
}
/**
* Creates a new instance of this exception
*
* @param cause
* the root cause
*/
public ItemServiceException(Throwable cause) {
super(cause);
}
}

View File

@@ -19,16 +19,25 @@ package com.l2jserver.service.game.item;
import java.util.List; import java.util.List;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.l2jserver.game.net.packet.client.CM_CHAR_ACTION.CharacterAction;
import com.l2jserver.model.dao.ItemDAO; import com.l2jserver.model.dao.ItemDAO;
import com.l2jserver.model.world.Actor;
import com.l2jserver.model.world.Item; import com.l2jserver.model.world.Item;
import com.l2jserver.model.world.L2Character;
import com.l2jserver.model.world.character.CharacterInventory.ItemLocation;
import com.l2jserver.model.world.item.ItemPickUpEvent;
import com.l2jserver.service.AbstractService; import com.l2jserver.service.AbstractService;
import com.l2jserver.service.AbstractService.Depends; import com.l2jserver.service.AbstractService.Depends;
import com.l2jserver.service.ServiceStartException; import com.l2jserver.service.ServiceStartException;
import com.l2jserver.service.ServiceStopException; import com.l2jserver.service.ServiceStopException;
import com.l2jserver.service.database.DatabaseService; import com.l2jserver.service.database.DatabaseService;
import com.l2jserver.service.game.spawn.AlreadySpawnedServiceException; import com.l2jserver.service.game.spawn.AlreadySpawnedServiceException;
import com.l2jserver.service.game.spawn.NotSpawnedServiceException;
import com.l2jserver.service.game.spawn.SpawnPointNotFoundServiceException; import com.l2jserver.service.game.spawn.SpawnPointNotFoundServiceException;
import com.l2jserver.service.game.spawn.SpawnService; import com.l2jserver.service.game.spawn.SpawnService;
import com.l2jserver.service.game.world.WorldService;
import com.l2jserver.service.game.world.event.WorldEventDispatcher;
import com.l2jserver.util.geometry.Point3D;
/** /**
* @author <a href="http://www.rogiel.com">Rogiel</a> * @author <a href="http://www.rogiel.com">Rogiel</a>
@@ -43,6 +52,10 @@ public class ItemServiceImpl extends AbstractService implements ItemService {
* The Spawn Service * The Spawn Service
*/ */
private final SpawnService spawnService; private final SpawnService spawnService;
/**
* The {@link WorldService} event dispatcher
*/
private final WorldEventDispatcher eventDispatcher;
/** /**
* All items on the ground persisted to the database * All items on the ground persisted to the database
@@ -54,11 +67,15 @@ public class ItemServiceImpl extends AbstractService implements ItemService {
* the item DAO * the item DAO
* @param spawnService * @param spawnService
* the spawn service * the spawn service
* @param eventDispatcher
* the world service event dispatcher
*/ */
@Inject @Inject
private ItemServiceImpl(ItemDAO itemDao, SpawnService spawnService) { private ItemServiceImpl(ItemDAO itemDao, SpawnService spawnService,
WorldEventDispatcher eventDispatcher) {
this.itemDao = itemDao; this.itemDao = itemDao;
this.spawnService = spawnService; this.spawnService = spawnService;
this.eventDispatcher = eventDispatcher;
} }
@Override @Override
@@ -75,8 +92,64 @@ public class ItemServiceImpl extends AbstractService implements ItemService {
} }
} }
@Override
public Item action(Item item, L2Character character, CharacterAction action)
throws ItemNotOnGroundServiceException, NotSpawnedServiceException {
switch (action) {
case CLICK:
return pickUp(item, character);
case RIGHT_CLICK:
return item;
}
return item;
}
@Override
public Item pickUp(Item item, L2Character character)
throws ItemNotOnGroundServiceException, NotSpawnedServiceException {
synchronized (item) {
if (item.getLocation() != ItemLocation.GROUND)
throw new ItemNotOnGroundServiceException();
item.setLocation(ItemLocation.INVENTORY);
item.setPaperdoll(null);
item.setOwnerID(character.getID());
character.getInventory().add(item);
items.remove(item);
spawnService.unspawn(item);
eventDispatcher.dispatch(new ItemPickUpEvent(character, item));
return item;
}
}
@Override
public void drop(Item item, Point3D point, Actor actor)
throws SpawnPointNotFoundServiceException,
ItemAlreadyOnGroundServiceException, AlreadySpawnedServiceException {
synchronized (item) {
if (item.getLocation() == ItemLocation.GROUND)
throw new AlreadySpawnedServiceException();
item.setLocation(ItemLocation.GROUND);
item.setPaperdoll(null);
// point will be set here
spawnService.spawn(item, point);
items.add(item);
}
}
@Override @Override
protected void doStop() throws ServiceStopException { protected void doStop() throws ServiceStopException {
super.doStop(); try {
for (final Item item : items) {
spawnService.unspawn(item);
}
} catch (NotSpawnedServiceException e) {
throw new ServiceStopException("Item is not spawned anymore", e);
}
} }
} }

View File

@@ -56,6 +56,8 @@ public class RangeFilter implements WorldObjectFilter<PositionableObject> {
public boolean accept(PositionableObject other) { public boolean accept(PositionableObject other) {
if (other == null) if (other == null)
return false; return false;
if(other.getPoint() == null)
return false;
final double dx = FastMath.abs(object.getPoint().getX() final double dx = FastMath.abs(object.getPoint().getX()
- other.getPoint().getX()); - other.getPoint().getX());

View File

@@ -46,6 +46,7 @@ import com.l2jserver.model.world.character.event.CharacterLeaveWorldEvent;
import com.l2jserver.model.world.character.event.CharacterMoveEvent; import com.l2jserver.model.world.character.event.CharacterMoveEvent;
import com.l2jserver.model.world.character.event.CharacterRunningEvent; import com.l2jserver.model.world.character.event.CharacterRunningEvent;
import com.l2jserver.model.world.character.event.CharacterWalkingEvent; import com.l2jserver.model.world.character.event.CharacterWalkingEvent;
import com.l2jserver.model.world.item.ItemPickUpEvent;
import com.l2jserver.model.world.npc.event.NPCSpawnEvent; import com.l2jserver.model.world.npc.event.NPCSpawnEvent;
import com.l2jserver.model.world.player.event.PlayerTeleportedEvent; import com.l2jserver.model.world.player.event.PlayerTeleportedEvent;
import com.l2jserver.service.AbstractService; import com.l2jserver.service.AbstractService;
@@ -125,8 +126,10 @@ public class BroadcastServiceImpl extends AbstractService implements
broadcast(conn, e.getObject()); broadcast(conn, e.getObject());
} else if (e instanceof ActorTeleportingEvent } else if (e instanceof ActorTeleportingEvent
|| e instanceof CharacterLeaveWorldEvent || e instanceof CharacterLeaveWorldEvent
|| e instanceof ActorUnspawnEvent) { || e instanceof ActorUnspawnEvent
|| e instanceof ItemPickUpEvent) {
// object is now out of sight // object is now out of sight
//FIXME pick up animation is not happening
conn.write(new SM_OBJECT_REMOVE(object)); conn.write(new SM_OBJECT_REMOVE(object));
} else if (e instanceof CharacterWalkingEvent) { } else if (e instanceof CharacterWalkingEvent) {
conn.write(new SM_MOVE_TYPE(((CharacterWalkingEvent) e) conn.write(new SM_MOVE_TYPE(((CharacterWalkingEvent) e)

View File

@@ -169,6 +169,14 @@ public class ComplexCalculator<T extends CalculatorContext, V extends Enum<V>>
getList(function.type()).remove(function); getList(function.type()).remove(function);
} }
/**
* Removes all functions from <code>type</code>
* @param type the type
*/
public void remove(V type) {
getList(type).clear();
}
/** /**
* Imports all functions from the given <tt>calculator</tt>. This is useful * Imports all functions from the given <tt>calculator</tt>. This is useful
* to preserve right calculation ordering but changes to original * to preserve right calculation ordering but changes to original