services.pet.MountService.java Source code

Java tutorial

Introduction

Here is the source code for services.pet.MountService.java

Source

/*******************************************************************************
 * Copyright (c) 2013 <Project SWG>
 * 
 * This File is part of NGECore2.
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program 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 Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. 
 * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination.
 ******************************************************************************/
package services.pet;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.LongAdder;

import org.apache.commons.collections.CollectionUtils;

import protocol.swg.UpdateContainmentMessage;
import main.NGECore;
import resources.common.OutOfBand;
import resources.datatables.DisplayType;
import resources.datatables.Options;
import resources.datatables.Posture;
import resources.datatables.State;
import resources.objects.building.BuildingObject;
import resources.objects.creature.CreatureObject;
import resources.objects.player.PlayerObject;
import tools.DevLog;
import engine.clientdata.ClientFileManager;
import engine.clientdata.visitors.DatatableVisitor;
import engine.resources.container.Traverser;
import engine.resources.objects.SWGObject;
import engine.resources.service.INetworkDispatch;
import engine.resources.service.INetworkRemoteEvent;

public class MountService implements INetworkDispatch {

    private NGECore core;

    public MountService(NGECore core) {
        this.core = core;
    }

    // Creature mounts are considered pets as well
    // Pet abilities and petId is in PLAY9

    // The functions for vehicles, mounts and pets are similar, but not the same
    // Hence the multiple services.

    public void generateVehicle(CreatureObject actor, SWGObject deed, String vehicleTemplate, String pcdTemplate) {
        if (actor == null || vehicleTemplate == null || pcdTemplate == null) {
            return;
        }

        if (actor.getSlottedObject("ghost") == null) {
            actor.sendSystemMessage(OutOfBand.ProsePackage("@pet/pet_menu:failed_to_call_vehicle"),
                    DisplayType.Broadcast);
            return;
        }

        SWGObject datapad = actor.getSlottedObject("datapad");

        if (datapad == null) {
            return;
        }

        // Unsure if these are the right attributes.  It doesn't generate the vehicle if the datapad has max # of vehicles.
        //if (datapad.getIntAttribute("data_size") >= datapad.getIntAttribute("datapad_slots")) {
        //actor.sendSystemMessage(OutOfBand.ProsePackage("@pet/pet_menu:has_max_vehicle"), DisplayType.Broadcast);
        //return;
        //}

        if (actor.getTefTime() > 0) {
            actor.sendSystemMessage(
                    OutOfBand.ProsePackage("@pet/pet_menu:prose_cant_generate_yet", actor.getTefTime()),
                    DisplayType.Broadcast);
            return;
        }

        SWGObject pcd = core.objectService.createObject(pcdTemplate, actor.getPlanet());

        if (pcd == null) {
            return;
        }

        if (pcd.getSlottedObject("inventory") == null) {
            pcd.add(core.objectService.createObject("object/tangible/inventory/shared_character_inventory.iff",
                    pcd.getPlanet()));
        }

        CreatureObject vehicle = (CreatureObject) core.objectService.createObject(vehicleTemplate,
                actor.getPlanet());

        if (vehicle == null) {
            return;
        }

        vehicle.setOptions(Options.MOUNT | Options.ATTACKABLE, true);

        vehicle.setOwnerId(actor.getObjectID());

        pcd.setAttachment("companionId", vehicle.getObjectID());

        pcd.getSlottedObject("inventory").add(vehicle);

        datapad.add(pcd);

        if (deed != null) {
            core.objectService.destroyObject(deed);
        }

        actor.sendSystemMessage(OutOfBand.ProsePackage("@pet/pet_menu:device_added"), DisplayType.Broadcast);

        call(actor, pcd);
    }

    public void generateMount(CreatureObject actor, SWGObject deed, String vehicleTemplate, String pcdTemplate) {
        return; // NOT IMPLEMENTED
    }

    public void call(CreatureObject actor, SWGObject pcd) {
        if (actor == null) {
            return;
        }

        if (pcd == null) {
            actor.sendSystemMessage(OutOfBand.ProsePackage("@pet/pet_menu:cant_call"), DisplayType.Broadcast);
            return;
        }

        if (isMounted(actor)) {
            actor.sendSystemMessage(OutOfBand.ProsePackage("@pet/pet_menu:cannot_call_another_rideable"),
                    DisplayType.Broadcast);
            return;
        }

        if (actor.isInCombat()) {
            actor.sendSystemMessage(OutOfBand.ProsePackage("@pet/pet_menu:cannot_call_in_combat"),
                    DisplayType.Broadcast);
            return;
        }

        if (actor.getContainer() != null) {
            actor.sendSystemMessage(OutOfBand.ProsePackage("@pet/pet_menu:cannot_call_indoors"),
                    DisplayType.Broadcast);
            return;
        }

        if (actor.getPosture() == Posture.Dead) {
            actor.sendSystemMessage(OutOfBand.ProsePackage("@pet/pet_menu:cannot_call_while_dead"),
                    DisplayType.Broadcast);
            return;
        }

        if (pcd.getSlottedObject("inventory") == null) {
            actor.sendSystemMessage(OutOfBand.ProsePackage("@pet/pet_menu:cant_call"), DisplayType.Broadcast);
            return;
        }

        if (pcd.getStringAttribute("required_faction") != null
                && pcd.getStringAttribute("required_faction").length() > 0) {
            if (!actor.getFaction().equals(pcd.getStringAttribute("required_faction"))) {
                actor.sendSystemMessage(OutOfBand.ProsePackage("@pet/pet_menu:officer_faction"),
                        DisplayType.Broadcast);
                return;
            }
        }

        PlayerObject player = (PlayerObject) actor.getSlottedObject("ghost");

        if (player == null) {
            return;
        }

        CreatureObject mount = (CreatureObject) core.objectService
                .getObject((Long) pcd.getAttachment("companionId"));

        if (mount == null) {
            // Somehow the vehicle object has got lost
            actor.sendSystemMessage(OutOfBand.ProsePackage("@pet/pet_menu:cant_call"), DisplayType.Broadcast);
            return;
        }

        mount.setAttachment("pcdAppearanceFilename", pcd.getTemplateData().getAttribute("appearanceFilename"));

        mount.setFaction(actor.getFaction());
        mount.setFactionStatus(actor.getFactionStatus());
        mount.setOwnerId(actor.getObjectID());

        if (pcd.getTemplate().contains("vehicle")) {
            callVehicle(actor, pcd, player, mount);
        } else {
            callMount(actor, pcd, player, mount);
        }
    }

    private void callVehicle(CreatureObject actor, SWGObject pcd, PlayerObject player, CreatureObject mount) {
        if ((mount.getLevel() - actor.getLevel()) > 5) {
            actor.sendSystemMessage(OutOfBand.ProsePackage("@pet/pet_menu:cant_call_level"), DisplayType.Broadcast);
            return;
        }

        // FIXME Movement skillmod should always be used instead of CREO4 speed vars directly.  Movement skillmod should NEVER be 0 unless rooted.  Currently it is, which is wrong.
        //if (actor.getSkillModBase("movement") == 0) {
        //actor.sendSystemMessage(OutOfBand.ProsePackage("@pet/pet_menu:cant_call_vehicle_rooted"), DisplayType.Broadcast);
        //return;
        //}

        if (actor.getPlanet().getName().contains("kashyyyk") && !actor.getPlanet().getName().contains("_main")) {
            actor.sendSystemMessage(OutOfBand.ProsePackage("@pet/pet_menu:vehicle_restricted_scene"),
                    DisplayType.Broadcast);
            //mount_restricted_scene for creature mounts
            return;
        }

        if (player.isCallingCompanion()) {
            actor.sendSystemMessage(OutOfBand.ProsePackage("@pet/pet_menu:cant_call_1sec"), DisplayType.Broadcast);
            return;
        }

        core.petService.storeAll(actor);
        storeAll(actor);

        player.setCallingCompanion(true);

        if (actor.getTefTime() > 0) {
            actor.sendSystemMessage(OutOfBand.ProsePackage("@pet/pet_menu:call_vehicle_delay", actor.getTefTime()),
                    DisplayType.Broadcast);
        }

        try {
            while (actor.getTefTime() > 0) {
                Thread.sleep(3000);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        SWGObject datapad = actor.getSlottedObject("datapad");

        if (datapad == null) {
            return;
        }

        datapad.viewChildren(actor, false, false, new Traverser() {

            public void process(SWGObject pcd) {
                if (pcd.getAttachment("companionId") != null
                        && mount.getObjectID() == ((Long) pcd.getAttachment("companionId"))) {
                    if (pcd.getSlottedObject("inventory") != null) {
                        LongAdder adder = new LongAdder();
                        pcd.getSlottedObject("inventory").viewChildren(actor, false, false,
                                (obj) -> adder.increment());

                        if (adder.intValue() == 1) {
                            pcd.getSlottedObject("inventory").remove(mount);
                            mount.setPosition(actor.getPosition().clone());
                            mount.setOrientation(actor.getOrientation().clone());
                            mount.setPlanet(actor.getPlanet());
                            DevLog.debugout("Charon", "Mount Service", "PROCESS MOUNT " + mount.getTemplate());
                            core.simulationService.add(mount, actor.getWorldPosition().x,
                                    actor.getWorldPosition().z, false);
                        }
                    }
                }
            }

        });

        player.setCallingCompanion(false);

        // Make the vehicle visible

        List<SWGObject> newAwareObjects = core.simulationService.get(actor.getPlanet(), actor.getWorldPosition().x,
                actor.getWorldPosition().z, 512);
        ArrayList<SWGObject> oldAwareObjects = new ArrayList<SWGObject>(actor.getAwareObjects());
        @SuppressWarnings("unchecked")
        Collection<SWGObject> updateAwareObjects = CollectionUtils.intersection(oldAwareObjects, newAwareObjects);

        for (int i = 0; i < newAwareObjects.size(); i++) {
            SWGObject obj = newAwareObjects.get(i);
            //System.out.println(obj.getTemplate());
            if (!updateAwareObjects.contains(obj) && obj != actor && !actor.getAwareObjects().contains(obj)
                    && obj.getContainer() != actor && obj.isInQuadtree()) {
                if (obj.getAttachment("bigSpawnRange") == null
                        && obj.getWorldPosition().getDistance2D(actor.getWorldPosition()) > 200)
                    continue;
                actor.makeAware(obj);
                if (obj.getClient() != null)
                    obj.makeAware(actor);
            }
        }

    }

    private void callMount(CreatureObject actor, SWGObject pcd, PlayerObject player, CreatureObject mount) {
        return; // NOT IMPLEMENTED
    }

    public void damage(CreatureObject mount) {
        // alter components to progressively reduce the painting.
        //stfs
        //customization_fading_veh
        //customization_gone_veh

        if (mount == null) {
            return;
        }

        CreatureObject owner = (CreatureObject) core.objectService.getObject(mount.getOwnerId());

        if (!mount.getTemplate().contains("vehicle")) {
            dismount(owner, mount);
            store(owner, mount);
            mount.setConditionDamage(0);
            return;
        }

        if (mount.getConditionDamage() >= mount.getMaximumCondition()) {
            disable(mount);
        }
    }

    public void disable(CreatureObject mount) {
        mount.setOptions(Options.DISABLED, true);

        mount.viewChildren(mount, false, false, new Traverser() {

            public void process(SWGObject object) {
                if (object == null || !(object instanceof CreatureObject)) {
                    return;
                }

                CreatureObject rider = (CreatureObject) object;

                dismount(rider, mount);

                rider.sendSystemMessage(OutOfBand.ProsePackage("@pet/pet_menu:veh_disabled"),
                        DisplayType.Broadcast);
            }

        });
    }

    public boolean canRepair(CreatureObject actor, CreatureObject mount) {
        if (actor == null || mount == null) {
            return false;
        }

        if (!mount.getOption(Options.MOUNT)) {
            return false;
        }

        if (!mount.getTemplate().contains("vehicle")) {
            return false;
        }

        if (mount.getOwnerId() != actor.getObjectID()) {
            return false;
        }

        if (mount.getOption(Options.DISABLED)) {
            return false;
        }

        if (mount.getConditionDamage() == 0) {
            return false;
        }

        List<SWGObject> surroundings = core.simulationService.get(mount.getPlanet(), mount.getPosition().x,
                mount.getPosition().z, 32);

        for (SWGObject object : surroundings) {
            if (object instanceof BuildingObject) {
                if (object.getTemplate().contains("garage")) {
                    return true;
                }
            }
        }

        return false;
    }

    public void repair(CreatureObject repairer, CreatureObject mount) {
        if (repairer == null || mount == null) {
            return;
        }

        if (!mount.getOption(Options.MOUNT)) {
            return;
        }

        if (core.objectService.getObject(mount.getOwnerId()) != repairer) {
            return;
        }

        if (mount.getOption(Options.DISABLED)) {
            repairer.sendSystemMessage(OutOfBand.ProsePackage("@pet/pet_menu:cannot_repair_disabled"),
                    DisplayType.Broadcast);
            return;
        }

        if (mount.getConditionDamage() == 0) {
            repairer.sendSystemMessage(OutOfBand.ProsePackage("@pet/pet_menu:undamaged_vehicle"),
                    DisplayType.Broadcast);
            return;
        }

        // This should produce an SUI window regarding cost and cost might be determined differently.
        // But at the moment it's not important.

        if (!canRepair(repairer, mount)) {
            repairer.sendSystemMessage(OutOfBand.ProsePackage("@pet/pet_menu:repair_unrecognized_garages"),
                    DisplayType.Broadcast);
            return;
        }

        int cost = mount.getConditionDamage();

        if (repairer.getCashCredits() < cost) {
            repairer.sendSystemMessage(OutOfBand.ProsePackage("@pet/pet_menu:repair_failed_due_to_funds"),
                    DisplayType.Broadcast);
            return;
        }

        mount.setConditionDamage(0);

        mount.setOptions(Options.DISABLED, false);

        repairer.sendSystemMessage(OutOfBand.ProsePackage("@pet/pet_menu:repaired_to_max"), DisplayType.Broadcast);
    }

    public void mount(CreatureObject rider, CreatureObject mount) {
        // Check if mount may be mounted // This is already checked in canMount

        if (rider == null) {
            return;
        }

        if (mount == null) {
            return;
        }

        if (!mount.getOption(Options.MOUNT)) {
            return;
        }

        if (mount.getOption(Options.DISABLED)) {
            rider.sendSystemMessage(OutOfBand.ProsePackage("@pet/pet_menu:cant_mount_veh_disabled"),
                    DisplayType.Broadcast);
            return;
        }

        if (rider.isCloaked()) {
            rider.sendSystemMessage(OutOfBand.ProsePackage("@pet/pet_menu:no_mount_stealth"),
                    DisplayType.Broadcast);
            return;
        }

        if (!canMount(rider, mount)) {
            rider.sendSystemMessage(OutOfBand.ProsePackage("@pet/pet_menu:cant_mount"), DisplayType.Broadcast);
            return;
        }

        mount._add(rider);
        mount.notifyObservers(new UpdateContainmentMessage(rider.getObjectID(), mount.getObjectID(), 4), true);
        core.simulationService.remove(rider, rider.getWorldPosition().x, rider.getWorldPosition().z, false);

        rider.setState(State.RidingMount, true);
        mount.setState(State.MountedCreature, true);

        // For some reason SOE decided the mount would need the following posture to be set for the character to have the driving or riding animation.
        mount.setPosture(
                (mount.getTemplate().contains("vehicle")) ? Posture.DrivingVehicle : Posture.RidingCreature);

        if (!mount.getSlotNameForObject(rider).equals("rider1")) {
            core.buffService.addBuffToCreature(rider, "vehicle_passenger", mount);
        }
    }

    public CreatureObject getMount(SWGObject pcd) {
        if (pcd == null) {
            return null;
        }

        if (pcd.getAttachment("companionId") == null) {
            return null;
        }

        CreatureObject mount = (CreatureObject) core.objectService
                .getObject((Long) pcd.getAttachment("companionId"));

        if (mount == null) {
            return null;
        }

        if (mount.getContainer() != null) {
            return null;
        }

        return mount;
    }

    public CreatureObject getCompanion(CreatureObject actor) {
        if (actor == null) {
            return null;
        }

        if (isMounted(actor)) {
            return (CreatureObject) actor.getContainer();
        }

        SWGObject datapad = actor.getSlottedObject("datapad");

        if (datapad == null) {
            return null;
        }

        final List<CreatureObject> companions = new ArrayList<CreatureObject>();

        datapad.viewChildren(actor, false, false, new Traverser() {

            public void process(SWGObject pcd) {
                if (pcd.getAttachment("companionId") != null) {
                    if (pcd.getSlottedObject("inventory") != null) {
                        LongAdder adder = new LongAdder();
                        pcd.getSlottedObject("inventory").viewChildren(actor, false, false,
                                (obj) -> adder.increment());

                        if (adder.intValue() == 0) {
                            CreatureObject companion = (CreatureObject) core.objectService
                                    .getObject((Long) pcd.getAttachment("companionId"));
                            companions.add(companion);
                        }
                    }
                }
            }

        });

        if (companions.size() > 0) {
            return companions.get(0);
        } else {
            return null;
        }
    }

    public boolean isMounted(CreatureObject rider) {
        if (rider.getContainer() == null) {
            return false;
        }

        if (!(rider.getContainer() instanceof CreatureObject)) {
            return false;
        }

        CreatureObject mount = (CreatureObject) rider.getContainer();

        if (!mount.getOption(Options.MOUNT)) {
            return false;
        }

        return true;
    }

    public boolean isMounted(SWGObject actor, CreatureObject mount) {
        return actor.getContainer() == mount;
    }

    public boolean canMount(CreatureObject rider, CreatureObject mount) {
        if (mount == null) {
            return false;
        }

        if (!mount.getOption(Options.MOUNT)) {
            return false;
        }

        if (isMounted(rider)) {
            return false;
        }

        if (rider.getObjectID() == mount.getOwnerId()) {
            return true;
        }

        // It's a potential passenger

        // See if there's driver first
        if (mount.getSlottedObject("rider") == null) {
            return false;
        }

        // Check if there are any passenger slots left

        LongAdder adder = new LongAdder();

        try {
            mount.viewChildren(mount, false, false, (object) -> adder.increment());
        } catch (Exception ex) {

        }

        int passengers = adder.intValue();

        try {
            DatatableVisitor visitor = ClientFileManager.loadFile("datatables/mount/saddle_appearance_map.iff",
                    DatatableVisitor.class);

            for (int i = 0; i < visitor.getRowCount(); i++) {
                if (visitor.getObject(i, 2).equals(mount.getAttachment("pcdAppearanceFilename"))) { // saddle_appearance_filename
                    if (passengers >= (int) visitor.getObject(i, 1)) { // saddle_capacity
                        return false;
                    }

                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        CreatureObject owner = (CreatureObject) NGECore.getInstance().objectService.getObject(mount.getOwnerId());

        if (owner == null) {
            return false;
        }

        if (owner.isAttackableBy(rider)) {
            return false;
        }

        if (rider.getGroupId() == 0 || rider.getGroupId() != owner.getGroupId()) {
            return false;
        }

        return true;
    }

    public void dismount(CreatureObject rider, CreatureObject mount) {

        if (rider == null || mount == null) {
            return;
        }

        if (!isMounted(rider)) {
            return;
        }

        if (!mount.getOption(Options.MOUNT)) {
            return;
        }

        // Dismount all passengers
        if (rider.getObjectID() == mount.getOwnerId()) {

            mount.viewChildren(mount, false, false, new Traverser() {
                public void process(SWGObject passenger) {
                    if (passenger.getObjectId() != mount.getOwnerId())
                        dismount((CreatureObject) passenger, mount);
                }

            });
        }

        // Remove rider from mount
        mount._remove(rider);

        // Set mount states and stuff
        if (rider.getObjectID() == mount.getOwnerId()) {
            mount.setStateBitmask(mount.getOptionsBitmask() & ~State.MountedCreature);
            mount.setState(State.MountedCreature, false);
        }

        // Set rider states and stuff
        rider.setStateBitmask(rider.getOptionsBitmask() & ~State.RidingMount);
        rider.setState(State.RidingMount, false);
        rider.setPosture(Posture.Upright);

        // Update observers and quadtree
        mount.notifyObservers(new UpdateContainmentMessage(rider.getObjectID(), 0, -1), true);
        core.simulationService.teleport(rider, mount.getWorldPosition(), mount.getOrientation(), 0);
        core.simulationService.add(rider, mount.getWorldPosition().x, mount.getWorldPosition().z, false);

        core.buffService.clearBuffs(mount);
        core.buffService.removeBuffFromCreature(rider, rider.getBuffByName("vehicle_passenger"));

        // Store mount if it's a creature
        if (!mount.getTemplate().contains("vehicle") && rider.getObjectID() == mount.getOwnerId()) {
            store(rider, mount);
        }
    }

    /*
     * They seem to have been stored in the inventory of the pcd object.
     * Judging by the fact pcds have inventories and many other things don't.
     */
    public void store(CreatureObject storer, CreatureObject mount) {
        if (mount == null) {
            System.err.println("MountService:store(): mount is null; this should never be the case.");
            return;
        }

        if (mount.getContainer() != null) {
            return;
        }

        if (mount.getOwnerId() == 0) {
            return;
        }

        CreatureObject owner = (CreatureObject) core.objectService.getObject(mount.getOwnerId());

        if (owner == null || storer == null || owner != storer) {
            return;
        }

        PlayerObject player = (PlayerObject) owner.getSlottedObject("ghost");

        if (player.isCallingCompanion()) {
            storer.sendSystemMessage(OutOfBand.ProsePackage("@pet/pet_menu:cant_store_1sec"),
                    DisplayType.Broadcast);
            return;
        }

        if (isMounted(owner, mount)) {
            //storer.sendSystemMessage(OutOfBand.ProsePackage("@pet/pet_menu:must_dismount"), DisplayType.Broadcast);
            //return;
            dismount(storer, mount);
        }

        if (owner.getTefTime() > 0) {
            owner.sendSystemMessage(
                    OutOfBand.ProsePackage("@pet/pet_menu:prose_cant_store_yet", owner.getTefTime()),
                    DisplayType.Broadcast);
            return;
        }

        SWGObject datapad = owner.getSlottedObject("datapad");

        if (datapad == null) {
            return;
        }

        datapad.viewChildren(owner, false, false, new Traverser() {

            public void process(SWGObject pcd) {
                if (pcd.getAttachment("companionId") != null
                        && mount.getObjectID() == ((Long) pcd.getAttachment("companionId"))) {
                    if (pcd.getSlottedObject("inventory") != null) {
                        LongAdder adder = new LongAdder();
                        pcd.getSlottedObject("inventory").viewChildren(owner, false, false,
                                (obj) -> adder.increment());

                        if (adder.intValue() == 0) {
                            core.simulationService.remove(mount, mount.getWorldPosition().x,
                                    mount.getWorldPosition().z, true);
                            pcd.getSlottedObject("inventory").add(mount);
                        }
                    }
                }
            }

        });
    }

    public void storeAll(CreatureObject actor) {
        if (actor == null) {
            return;
        }

        while (getCompanion(actor) != null) {
            SWGObject mount = getCompanion(actor);

            SWGObject datapad = actor.getSlottedObject("datapad");

            if (datapad == null) {
                return;
            }

            datapad.viewChildren(actor, false, false, new Traverser() {

                public void process(SWGObject pcd) {
                    if (pcd.getAttachment("companionId") != null
                            && mount.getObjectID() == ((Long) pcd.getAttachment("companionId"))) {
                        if (pcd.getSlottedObject("inventory") != null) {
                            LongAdder adder = new LongAdder();
                            pcd.getSlottedObject("inventory").viewChildren(actor, false, false,
                                    (obj) -> adder.increment());

                            if (adder.intValue() == 0) {
                                core.simulationService.remove(mount, mount.getWorldPosition().x,
                                        mount.getWorldPosition().z, true);
                                pcd.getSlottedObject("inventory").add(mount);
                            }
                        }
                    }
                }

            });
        }
    }

    public void destroy(CreatureObject destroyer, SWGObject pcd) {
        if (destroyer == null || pcd == null || pcd.getGrandparent() == null) {
            return;
        }

        if (destroyer.getObjectID() != pcd.getGrandparent().getObjectID()) {
            return;
        }

        if (pcd.getAttachment("companionId") == null) {
            return;
        }

        CreatureObject mount = (CreatureObject) core.objectService
                .getObject((Long) pcd.getAttachment("companionId"));

        dismount(destroyer, mount);

        store(destroyer, mount);

        String type = mount.getTemplate();

        core.objectService.destroyObject(mount);
        core.objectService.destroyObject(pcd);

        if (type.contains("vehicle")) {
            destroyer.sendSystemMessage(OutOfBand.ProsePackage("@pet/pet_menu:vehicle_released"),
                    DisplayType.Broadcast);
        } else {
            destroyer.sendSystemMessage(OutOfBand.ProsePackage("@pet/pet_menu:pet_released"),
                    DisplayType.Broadcast);
        }
    }

    public void insertOpcodes(Map<Integer, INetworkRemoteEvent> arg0, Map<Integer, INetworkRemoteEvent> arg1) {

    }

    public void shutdown() {

    }

}