diff --git a/src/resources/containers/ContainerResult.java b/src/resources/containers/ContainerResult.java
new file mode 100644
index 000000000..48ec3ec0c
--- /dev/null
+++ b/src/resources/containers/ContainerResult.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2015 /// Project SWG /// www.projectswg.com
+ *
+ * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on
+ * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies.
+ * Our goal is to create an emulator which will provide a server for players to
+ * continue playing a game similar to the one they used to play. We are basing
+ * it on the final publish of the game prior to end-game events.
+ *
+ * This file is part of Holocore.
+ *
+ * --------------------------------------------------------------------------------
+ *
+ * Holocore is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * Holocore 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Holocore. If not, see
+ ******************************************************************************/
+
+package resources.containers;
+
+public enum ContainerResult {
+ SLOT_OCCUPIED,
+ SLOT_NO_EXIST,
+ CONTAINER_FULL,
+ NO_PERMISSION,
+ SUCCESS
+}
diff --git a/src/resources/objects/SWGObject.java b/src/resources/objects/SWGObject.java
index e1bd9823a..e810365a8 100644
--- a/src/resources/objects/SWGObject.java
+++ b/src/resources/objects/SWGObject.java
@@ -43,12 +43,12 @@ import network.packets.swg.zone.baselines.Baseline.BaselineType;
import network.packets.swg.zone.object_controller.DataTransform;
import resources.Location;
import resources.common.CRC;
+import resources.containers.ContainerResult;
import resources.encodables.Stf;
import resources.network.BaselineBuilder;
import resources.network.DeltaBuilder;
import resources.player.Player;
import resources.player.PlayerState;
-import resources.server_info.Log;
import utilities.Encoder.StringType;
public class SWGObject implements Serializable, Comparable {
@@ -103,13 +103,13 @@ public class SWGObject implements Serializable, Comparable {
* Adds the specified object to this object and places it in the appropriate slot if needed
* @param object
*/
- public void addObject(SWGObject object) {
+ public boolean addObject(SWGObject object) {
// If the arrangement is -1, then this object will be a contained object
int arrangementId = getArrangementId(object);
if (arrangementId == -1) {
containedObjects.put(object.getObjectId(), object);
object.parent = this;
- return;
+ return true;
}
// Not a child object, so time to check the slots!
@@ -117,7 +117,7 @@ public class SWGObject implements Serializable, Comparable {
List requiredSlots = object.getArrangement().get(arrangementId - 4);
// Note that some objects don't have a descriptor, meaning it has no slots
if (descriptor != null && !descriptor.containsAll(requiredSlots))
- return;
+ return false;
// Add object to the slot
for (String requiredSlot : requiredSlots) {
@@ -126,6 +126,7 @@ public class SWGObject implements Serializable, Comparable {
object.parent = this;
object.slotArrangement = arrangementId;
+ return true;
}
/**
@@ -153,9 +154,38 @@ public class SWGObject implements Serializable, Comparable {
* Moves the current object to the target object
* @param requester Object that is requesting to move the object, used for permission checking
* @param container Where this object should be moved to
+ * @return {@link ContainerResult}
*/
- public void moveToContainer(SWGObject requester, SWGObject container) {
- // Before doing anything, get a list of the observers so we can send create/destroy/update messages
+ public ContainerResult moveToContainer(SWGObject requester, SWGObject container) {
+ // TODO ContainerPermission check
+
+ // Check if object can fit into container or slots
+ int arrangementId = container.getArrangementId(this);
+ if (arrangementId == -1) {
+ // Item is going to go into the container, so check to see if it'll fit
+ if (container.getMaxContainerSize() >= container.getContainedObjects().size())
+ return ContainerResult.CONTAINER_FULL;
+ } else {
+ List requiredSlots = getArrangement().get(arrangementId - 4);
+ if (!container.getAvailableSlots().containsAll(requiredSlots))
+ return ContainerResult.SLOT_NO_EXIST;
+ else {
+ // Check to see if any of the required slots are occupied
+ int emptySlots = 0;
+ for (Map.Entry entry : container.getSlots().entrySet()) {
+ if (emptySlots == requiredSlots.size())
+ break;
+
+ if (requiredSlots.contains(entry.getKey()) && entry.getValue() == null)
+ emptySlots++;
+ }
+
+ if (emptySlots != requiredSlots.size())
+ return ContainerResult.SLOT_OCCUPIED;
+ }
+ }
+
+ // Get a pre-parent-removal list of the observers so we can send create/destroy/update messages
List oldObservers = getObjectsAware();
// Remove this object from the old parent if one exists
@@ -165,33 +195,10 @@ public class SWGObject implements Serializable, Comparable {
container.addObject(this);
- List newObservers = new ArrayList<>(container.getObjectsAware());
-
- List same = new ArrayList<>(oldObservers);
- same.retainAll(newObservers);
-
- List added = new ArrayList<>(newObservers);
- added.removeAll(oldObservers);
-
- List removed = new ArrayList<>(oldObservers);
- removed.removeAll(newObservers);
-
- for (SWGObject swgObject : same) {
- swgObject.sendSelf(new UpdateContainmentMessage(objectId, parent.getObjectId(), slotArrangement));
- }
-
- for (SWGObject swgObject : added) {
- if (swgObject.getOwner() != null) {
- createObject(swgObject.getOwner());
- }
- }
-
- for (SWGObject swgObject : removed) {
- if (swgObject.getOwner() != null) {
- sendSceneDestroyObject(swgObject.getOwner());
- }
- }
+ // Observer notification
+ sendUpdatedContainment(oldObservers, new ArrayList<>(container.getObjectsAware()));
+ return ContainerResult.SUCCESS;
}
public void addAttribute(String attribute, String value) {
@@ -298,7 +305,6 @@ public class SWGObject implements Serializable, Comparable {
if (owner != null)
return owner;
- // TODO getOwner() should also search for the "master" container that has a PlayerObject
if (getParent() != null)
return getParent().getOwner(); // Ziggy: Player owner is found recursively
@@ -429,7 +435,6 @@ public class SWGObject implements Serializable, Comparable {
create.setLocation(location);
create.setObjectCrc(crc);
target.sendPacket(create);
- // TODO: Move this to createChildrenObjects?
if (parent != null)
target.sendPacket(new UpdateContainmentMessage(objectId, parent.getObjectId(), slotArrangement));
@@ -516,7 +521,34 @@ public class SWGObject implements Serializable, Comparable {
if (owner != null)
owner.sendPacket(packets);
}
-
+
+ private void sendUpdatedContainment(List oldObservers, List newObservers) {
+ List same = new ArrayList<>(oldObservers);
+ same.retainAll(newObservers);
+
+ List added = new ArrayList<>(newObservers);
+ added.removeAll(oldObservers);
+
+ List removed = new ArrayList<>(oldObservers);
+ removed.removeAll(newObservers);
+
+ for (SWGObject swgObject : same) {
+ swgObject.sendSelf(new UpdateContainmentMessage(objectId, parent.getObjectId(), slotArrangement));
+ }
+
+ for (SWGObject swgObject : added) {
+ if (swgObject.getOwner() != null) {
+ createObject(swgObject.getOwner());
+ }
+ }
+
+ for (SWGObject swgObject : removed) {
+ if (swgObject.getOwner() != null) {
+ sendSceneDestroyObject(swgObject.getOwner());
+ }
+ }
+ }
+
public void updateObjectAwareness(List withinRange) {
synchronized (objectsAware) {
List outOfRange = new ArrayList(objectsAware);
diff --git a/src/services/objects/ObjectManager.java b/src/services/objects/ObjectManager.java
index 6f9c35a2e..1f1398ee0 100644
--- a/src/services/objects/ObjectManager.java
+++ b/src/services/objects/ObjectManager.java
@@ -222,18 +222,6 @@ public class ObjectManager extends Manager {
if (obj == null)
return null;
objectAwareness.remove(obj);
-
-/* for (Slot slot : obj.getSlots()) {
- if (slot != null) {
- if (slot instanceof Container) {
- for (SWGObject child : ((Container) slot).getContainedObjects()) {
- deleteObject(child.getObjectId());
- }
- }
- if (slot.getObject() != null)
- deleteObject(slot.getObject().getObjectId());
- }
- }*/
Log.i("ObjectManager", "Deleted object %d [%s]", obj.getObjectId(), obj.getTemplate());
return obj;
}
@@ -249,20 +237,15 @@ public class ObjectManager extends Manager {
long objId = object.getObjectId();
-/* Collection slots = object.getSlots();
- synchronized (slots) {
- for (Slot slot : slots) {
- if (slot != null) {
- if (slot instanceof Container) {
- for (SWGObject child : ((Container) slot).getContainedObjects()) {
- deleteObject(child.getObjectId());
- }
- }
- if (slot.getObject() != null)
- deleteObject(slot.getObject().getObjectId());
- }
- }
- }*/
+ for (SWGObject slottedObj : object.getSlots().values()) {
+ if (slottedObj != null)
+ destroyObject(slottedObj);
+ }
+
+ for (SWGObject containedObj : object.getContainedObjects()) {
+ if (containedObj != null)
+ destroyObject(containedObj);
+ }
// Remove object from the parent
SWGObject parent = object.getParent();
@@ -270,7 +253,7 @@ public class ObjectManager extends Manager {
if (parent instanceof CreatureObject) {
((CreatureObject) parent).removeEquipment(object);
}
- //parent.removeChild(object);
+ parent.removeObject(object);
}
object.sendObservers(new SceneDestroyObject(objId));