Instructions Jenkins Doxygen

[Added] PetControlDevice, PetControlObserver, and CallPetTask 68/968/2
authorIvojedi <ivojedi@swgemu.com>
Sun, 20 Oct 2013 12:17:09 +0000 (05:17 -0700)
committerIvojedi <ivojedi@swgemu.com>
Sun, 20 Oct 2013 12:46:45 +0000 (05:46 -0700)
[Added] stormtrooper and rebel trooper faction pets for purchase at
recruiters (temporary, for testing of the control devices. They don't do
anything but follow right now)

Change-Id: If486e408c1eae93d281395c12ae32308cc73a79a

15 files changed:
MMOCoreORB/bin/scripts/mobile/conversations/recruiter/imperial_recruiter_conv.lua
MMOCoreORB/bin/scripts/mobile/conversations/recruiter/rebel_recruiter_conv.lua
MMOCoreORB/bin/scripts/screenplays/recruiters/factionperkdata.lua
MMOCoreORB/bin/scripts/screenplays/recruiters/recruiters.lua
MMOCoreORB/src/Makefile.am
MMOCoreORB/src/server/zone/managers/director/DirectorManager.cpp
MMOCoreORB/src/server/zone/managers/object/ObjectManager.cpp
MMOCoreORB/src/server/zone/managers/object/objects.h
MMOCoreORB/src/server/zone/objects/intangible/PetControlDevice.idl [new file with mode: 0644]
MMOCoreORB/src/server/zone/objects/intangible/PetControlDeviceImplementation.cpp [new file with mode: 0644]
MMOCoreORB/src/server/zone/objects/intangible/PetControlObserver.idl [new file with mode: 0644]
MMOCoreORB/src/server/zone/objects/intangible/VehicleControlDevice.idl
MMOCoreORB/src/server/zone/objects/intangible/VehicleControlDeviceImplementation.cpp
MMOCoreORB/src/server/zone/objects/intangible/tasks/CallPetTask.h [new file with mode: 0644]
MMOCoreORB/src/server/zone/objects/scene/SceneObject.idl

index d98dcfd..85cedfa 100644 (file)
@@ -373,7 +373,7 @@ imp_recruiter_faction_purchase = ConvoScreen:new {
                        { "@faction_recruiter:option_purchase_uniforms", "fp_uniforms" }, -- I'm interested in uniforms
                        { "@faction_recruiter:option_purchase_furniture", "fp_furniture"}, -- I'm interested in furniture.
                        { "@faction_recruiter:option_purchase_installation", "fp_installations" }, -- I'm interested in installations.
-                       --{ "@faction_recruiter:option_hirelings", "fp_hirelings" }, -- I would like some personnel support.
+                       { "@faction_recruiter:option_hirelings", "fp_hirelings" }, -- I would like some personnel support.
        },
 }
 
index a3cf4a9..e89ada7 100644 (file)
@@ -369,7 +369,7 @@ imp_recruiter_faction_purchase = ConvoScreen:new {
                        { "@faction_recruiter:option_purchase_weapons_armor", "fp_weapons_armor" }, --I'm interested in weapons and armor
                        { "@faction_recruiter:option_purchase_furniture", "fp_furniture"}, -- I'm interested in furniture.
                        { "@faction_recruiter:option_purchase_installation", "fp_installations" }, -- I'm interested in installations.
-                       --{ "@faction_recruiter:option_hirelings", "fp_hirelings" }, -- I would like some personnel support.
+                       { "@faction_recruiter:option_hirelings", "fp_hirelings" }, -- I would like some personnel support.
        },
 }
 
index 16d4681..e0e587f 100644 (file)
@@ -354,21 +354,23 @@ imperial_racial_penalty = {
        imperial_hireling_list = {
                --"assaulttrooper",
                --"atst",
+               "stormtrooper",
        
        },
        
        imperial_hireling = {
-               
+               stormtrooper = { type=faction_reward_type.furniture, display="@mob/creature_names:stormtrooper", item="object/intangible/pet/pet_control.iff", controlledObjectTemplate="stormtrooper", cost=420},
        },
        
        rebel_hireling_list = {
                --"Comms Operator",
                --"Senior SpecForce Guerilla",
                --"marine",
+               "rebel_trooper",
        },
        
        rebel_hireling = {
-       
+               rebel_trooper = { type=faction_reward_type.furniture, display="@mob/creature_names:rebel_trooper", item="object/intangible/pet/pet_control.iff", controlledObjectTemplate="rebel_trooper", cost=500},
        }
 
 
index 0cc9611..ba94631 100644 (file)
@@ -864,7 +864,11 @@ function recruiter_convo_handler:transferData(player, pDatapad, itemstring)
                return self.TEMPLATEPATHERROR
        end
 
-       pItem = giveControlDevice(pDatapad, templatePath, genPath, -1)
+       if (self:isHireling(itemstring)) then
+               pItem = giveControlDevice(pDatapad, templatePath, genPath, -1, true)
+       else
+               pItem = giveControlDevice(pDatapad, templatePath, genPath, -1, false)
+       end
        
        if (pItem ~= nil) then
        
index 2431138..854b46a 100644 (file)
@@ -95,7 +95,9 @@ core3_TESTS =         server/zone/objects/area/areashapes/tests/CircularAreaShapeTest.c
                                server/zone/objects/terrain/tests/BasicTerrainTest.cpp \
                                server/zone/tests/ZoneTest.cpp
 
-core3_IDLS =   autogen/server/zone/managers/space/SpaceManager.cpp \
+core3_IDLS =   autogen/server/zone/objects/intangible/PetControlObserver.cpp \
+                               autogen/server/zone/objects/intangible/PetControlDevice.cpp \
+                               autogen/server/zone/managers/space/SpaceManager.cpp \
                                autogen/server/zone/objects/player/sessions/StructureStatusSession.cpp \
                                autogen/server/zone/objects/player/sessions/ImageDesignPositionObserver.cpp \
                                autogen/server/zone/objects/area/FsVillageArea.cpp \
@@ -539,6 +541,7 @@ core3_SOURCES =     $(core3_IDLS) \
                server/zone/objects/intangible/LuaIntangibleObject.cpp \
                server/zone/objects/staticobject/StaticObjectImplementation.cpp \
                server/zone/objects/intangible/VehicleControlDeviceImplementation.cpp \
+               server/zone/objects/intangible/PetControlDeviceImplementation.cpp \
                server/zone/objects/tangible/TangibleObjectImplementation.cpp \
                server/zone/objects/tangible/InstrumentImplementation.cpp \
                server/zone/objects/tangible/InstrumentObserverImplementation.cpp \
index e4a2796..8feeba3 100644 (file)
@@ -1264,29 +1264,67 @@ int DirectorManager::giveItem(lua_State* L) {
 }
 
 int DirectorManager::giveControlDevice(lua_State* L) {
-       if (checkArgumentCount(L, 4) == 1) {
+       if (checkArgumentCount(L, 5) == 1) {
                instance()->error("incorrect number of arguments passed to DirectorManager::giveControlDevice");
                ERROR_CODE = INCORRECT_ARGUMENTS;
                return 0;
        }
 
-       SceneObject* obj = (SceneObject*) lua_touserdata(L, -4);
-       String objectString = lua_tostring(L, -3);
-       String controlledObjectPath = lua_tostring(L, -2);
-       int slot = lua_tointeger(L, -1);
+       SceneObject* datapad = (SceneObject*) lua_touserdata(L, -5);
+       String objectString = lua_tostring(L, -4);
+       String controlledObjectPath = lua_tostring(L, -3);
+       int slot = lua_tointeger(L, -2);
+       bool mobile = lua_toboolean(L, -1);
 
-       if (obj == NULL)
-               return 0;
+       if (datapad == NULL) {
+               lua_pushnil(L);
+               return 1;
+       }
 
-       ZoneServer* zoneServer = obj->getZoneServer();
+       ZoneServer* zoneServer = datapad->getZoneServer();
+       Zone* zone = datapad->getZone();
+
+       if (zone == NULL) {
+               lua_pushnil(L);
+               return 1;
+       }
 
        ManagedReference<ControlDevice*> controlDevice = zoneServer->createObject(objectString.hashCode(), 1).castTo<ControlDevice*>();
 
-       ManagedReference<TangibleObject*> controlledObject = zoneServer->createObject(controlledObjectPath.hashCode(), 1).castTo<TangibleObject*>();
+       if (controlDevice == NULL) {
+               lua_pushnil(L);
+               return 1;
+       }
+
+       ManagedReference<TangibleObject*> controlledObject = NULL;
+       ManagedReference<CreatureObject*> player = (datapad->getParent().get()).castTo<CreatureObject*>();
+
+       if (mobile) {
+               CreatureManager* creatureManager = zone->getCreatureManager();
+               controlledObject = creatureManager->spawnCreature(controlledObjectPath.hashCode(), 0, player->getPositionX(), player->getPositionZ(), player->getPositionY(), player->getParentID(), true);
 
-       if (controlDevice != NULL && obj != NULL) {
+       } else {
+               controlledObject = zoneServer->createObject(controlledObjectPath.hashCode(), 1).castTo<TangibleObject*>();
+
+               SharedObjectTemplate* temp = controlledObject->getObjectTemplate();
+               controlledObject->loadTemplateData(temp);
+       }
+
+       if (controlledObject != NULL) {
                controlDevice->setControlledObject(controlledObject);
-               obj->transferObject(controlDevice, slot, true);
+               StringId s;
+               s.setStringId(controlledObject->getDisplayedName());
+               controlDevice->setObjectName(s);
+
+               if (controlledObject->isAiAgent()) {
+                       AiAgent* pet = controlledObject.castTo<AiAgent*>();
+                       pet->setFollowObject(player);
+                       pet->setCreatureLink(player);
+                       pet->setControlDevice(controlDevice);
+                       controlDevice->updateStatus(1);
+               }
+
+               datapad->transferObject(controlDevice, slot, true);
 
                controlDevice->_setUpdated(true); //mark updated so the GC doesnt delete it while in LUA
                lua_pushlightuserdata(L, controlDevice.get());
index f823f46..fca5d2b 100644 (file)
@@ -277,6 +277,7 @@ void ObjectManager::registerObjectTypes() {
 
 
        objectFactory.registerObject<VehicleControlDevice>(SceneObjectType::VEHICLECONTROLDEVICE);
+       objectFactory.registerObject<PetControlDevice>(SceneObjectType::PETCONTROLDEVICE);
        objectFactory.registerObject<ShipControlDevice>(SceneObjectType::SHIPCONTROLDEVICE);
 
        objectFactory.registerObject<VehicleObject>(SceneObjectType::VEHICLE);
index 635df73..27286b9 100644 (file)
@@ -14,6 +14,7 @@
 #include "server/zone/objects/creature/VehicleObject.h"
 #include "server/zone/objects/intangible/IntangibleObject.h"
 #include "server/zone/objects/intangible/VehicleControlDevice.h"
+#include "server/zone/objects/intangible/PetControlDevice.h"
 #include "server/zone/objects/intangible/ShipControlDevice.h"
 #include "server/zone/objects/ship/FighterShipObject.h"
 #include "server/zone/objects/ship/SpaceStationObject.h"
diff --git a/MMOCoreORB/src/server/zone/objects/intangible/PetControlDevice.idl b/MMOCoreORB/src/server/zone/objects/intangible/PetControlDevice.idl
new file mode 100644 (file)
index 0000000..4f9919c
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+Copyright (C) 2007 <SWGEmu>
+This File is part of Core3.
+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 2 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, write to
+the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+Linking Engine3 statically or dynamically with other modules 
+is making a combined work based on Engine3. 
+Thus, the terms and conditions of the GNU Lesser General Public License 
+cover the whole combination.
+In addition, as a special exception, the copyright holders of Engine3 
+give you permission to combine Engine3 program with free software 
+programs or libraries that are released under the GNU LGPL and with 
+code included in the standard release of Core3 under the GNU LGPL 
+license (or modified versions of such code, with unchanged license). 
+You may copy and distribute such a system following the terms of the 
+GNU LGPL for Engine3 and the licenses of the other code concerned, 
+provided that you include the source code of that other code when 
+and as the GNU LGPL requires distribution of source code.
+Note that people who make modified versions of Engine3 are not obligated 
+to grant this special exception for their modified versions; 
+it is their choice whether to do so. The GNU Lesser General Public License 
+gives permission to release a modified version without this exception; 
+this exception also makes it possible to release a modified version 
+which carries forward this exception.
+*/
+
+package server.zone.objects.intangible;
+
+import engine.lua.LuaObject;
+import server.zone.objects.intangible.IntangibleObject;
+import server.zone.objects.intangible.ControlDevice;
+import server.zone.objects.creature.CreatureObject;
+import server.zone.objects.tangible.TangibleObject;
+import server.zone.objects.scene.SceneObject;
+import server.zone.packets.scene.AttributeListMessage;
+import server.zone.Zone;
+import system.lang.System;
+include server.zone.managers.radial.RadialOptions;
+import server.zone.objects.creature.CreatureObject;
+import server.zone.objects.intangible.PetControlObserver;
+
+class PetControlDevice extends ControlDevice {
+
+       PetControlObserver petControlObserver;
+
+       int vitality;
+
+       public PetControlDevice() {
+               Logger.setLoggingName("PetControlDevice");
+               Logger.setLogging(false);
+               Logger.setGlobalLogging(true);
+               vitality = 100;
+       }
+
+       public native void storeObject(CreatureObject player);
+       
+       public native void callObject(CreatureObject player);
+
+       public native void spawnObject(CreatureObject player);
+       
+       public native void cancelSpawnObject(CreatureObject player);
+
+       public int handleObjectMenuSelect(CreatureObject player, byte selectedID) {
+               Logger.info("selected call");
+               
+               TangibleObject controlledObject = super.controlledObject;
+               
+               if (selectedID == 44) {
+                       
+                       if (controlledObject == null) {
+                               Logger.error("null controlled object in pet control device");
+                               return 1;
+                       } else {
+                               this.callObject(player);
+                       }
+               } else if (selectedID == 59) {
+                       if (controlledObject == null) {
+                               Logger.error("null controlled object in pet control device");
+                               return 1;
+                       } else {
+                               if (super.status == 1 && !controlledObject.isInQuadTree()) {
+                                       this.callObject(player);
+                               } else {
+                                       this.storeObject(player);
+                               }
+                       }
+               }
+               
+               return 0;
+       }
+       
+       /**
+        * Destroys this object from database
+        * @pre { this is locked }
+        * @post { this is locked }
+        * @param destroyContainedObjects if true, will destroy from database all its contained objects
+        */
+       public native void destroyObjectFromDatabase(boolean destroyContainedObjects = false);
+       
+       /**
+        * Checks if the object can be destroyed
+        * @pre { this is locked }
+        * @post { this is locked }
+        * @returns 0 on succes, != 0 on error
+        */
+       public native int canBeDestroyed(CreatureObject player);
+
+       /**
+        * Fills the attribute list message options that are sent to player creature
+        * @pre { }
+        * @post { }
+        * @param msg attribute list message with the attributes
+        * @param object player creature to which the message is sent
+        */
+       @local
+       public native void fillAttributeList(AttributeListMessage msg, CreatureObject object);  
+
+       public boolean isPetControlDevice() {
+               return true;
+       }
+}
diff --git a/MMOCoreORB/src/server/zone/objects/intangible/PetControlDeviceImplementation.cpp b/MMOCoreORB/src/server/zone/objects/intangible/PetControlDeviceImplementation.cpp
new file mode 100644 (file)
index 0000000..1b2b0c0
--- /dev/null
@@ -0,0 +1,282 @@
+#include "server/zone/objects/intangible/PetControlDevice.h"
+#include "server/zone/objects/intangible/PetControlObserver.h"
+#include "server/zone/managers/objectcontroller/ObjectController.h"
+#include "server/zone/objects/creature/CreatureObject.h"
+#include "server/zone/objects/creature/AiAgent.h"
+#include "server/zone/objects/player/PlayerObject.h"
+#include "server/zone/ZoneServer.h"
+#include "server/zone/Zone.h"
+#include "tasks/CallPetTask.h"
+#include "server/zone/objects/region/CityRegion.h"
+#include "server/zone/objects/player/sessions/TradeSession.h"
+#include "server/zone/managers/player/PlayerManager.h"
+
+
+void PetControlDeviceImplementation::callObject(CreatureObject* player) {
+       if (player->getParent() != NULL)
+               return;
+
+       if (!isASubChildOf(player))
+               return;
+
+       ManagedReference<TangibleObject*> controlledObject = this->controlledObject.get();
+
+       if (controlledObject == NULL)
+               return;
+
+       if (controlledObject->isInQuadTree())
+               return;
+
+       if (player->isInCombat() || player->isDead() || player->isIncapacitated()) {
+               player->sendSystemMessage("@pet/pet_menu:cant_call"); // You cannot call this pet right now.
+               return;
+       }
+
+       if (player->isRidingMount()) {
+               player->sendSystemMessage("@pet/pet_menu:mounted_call_warning"); // You cannot call a pet while mounted or riding a vehicle.
+               return;
+       }
+
+       ManagedReference<TradeSession*> tradeContainer = player->getActiveSession(SessionFacadeType::TRADE).castTo<TradeSession*>();
+
+       if (tradeContainer != NULL) {
+               server->getZoneServer()->getPlayerManager()->handleAbortTradeMessage(player);
+       }
+
+       if (vitality <= 0) {
+               player->sendSystemMessage("@pet/pet_menu:dead_pet"); // This pet is dead. Select DESTROY from the radial menu to delete this pet control device.
+               return;
+       }
+
+       if (!controlledObject->isAiAgent())
+               return;
+
+       ManagedReference<AiAgent*> pet = cast<AiAgent*>(controlledObject.get());
+
+       unsigned int petFaction = pet->getFaction();
+
+       if (petFaction != 0) {
+               if (player->getFaction() == 0) {
+                       StringIdChatParameter message("@faction_perk:prose_be_declared"); // You must be declared to a faction to use %TT.
+                       message.setTT(pet->getDisplayedName());
+                       player->sendSystemMessage(message);
+                       return;
+               }
+
+               PlayerObject* ghost = player->getPlayerObject();
+               if (player->getFaction() != petFaction || ghost->getFactionStatus() == FactionStatus::ONLEAVE) {
+                       StringIdChatParameter message("@faction_perk:prose_be_declared_faction"); // You must be a declared %TO to use %TT.
+                       message.setTO(pet->getFactionString());
+                       message.setTT(pet->getDisplayedName());
+                       player->sendSystemMessage(message);
+                       return;
+               }
+       }
+
+       if(player->getPendingTask("call_pet") != NULL) {
+               StringIdChatParameter waitTime("pet/pet_menu", "call_delay_finish_pet"); // Already calling a Pet: Call will be finished in %DI seconds.
+               Time nextExecution;
+               Core::getTaskManager()->getNextExecutionTime(player->getPendingTask("call_pet"), nextExecution);
+               int timeLeft = (nextExecution.getMiliTime() / 1000) - System::getTime();
+               waitTime.setDI(timeLeft);
+
+               player->sendSystemMessage(waitTime);
+               return;
+       }
+
+       ManagedReference<SceneObject*> datapad = player->getSlottedObject("datapad");
+
+       if (datapad == NULL)
+               return;
+
+       int currentlySpawned = 0;
+
+       int maxPets = 1;
+
+       String petType;
+
+       if (pet->isCreature()) {
+               if (player->hasSkill("outdoors_creaturehandler_novice")) {
+                       maxPets = player->getSkillMod("keep_creature");
+               }
+
+               petType = "creature";
+       } else if (pet->isNonPlayerCreatureObject()){
+               petType = "npc";
+       }
+
+       for (int i = 0; i < datapad->getContainerObjectsSize(); ++i) {
+               ManagedReference<SceneObject*> object = datapad->getContainerObject(i);
+
+               if (object->isPetControlDevice()) {
+                       PetControlDevice* device = cast<PetControlDevice*>( object.get());
+
+                       ManagedReference<AiAgent*> object = cast<AiAgent*>(device->getControlledObject());
+
+                       if (object != NULL && object->isInQuadTree()) {
+                               if ((object->isCreature() && petType == "creature") || (object->isNonPlayerCreatureObject() && petType == "npc")) {
+                                       if (++currentlySpawned >= maxPets) {
+                                               player->sendSystemMessage("@pet/pet_menu:at_max"); // You already have the maximum number of pets of this type that you can call.
+                                               return;
+                                       }
+                               }
+
+                       }
+               }
+       }
+
+       if(player->getCurrentCamp() == NULL && player->getCityRegion() == NULL) {
+
+               Reference<CallPetTask*> callPet = new CallPetTask(_this.get(), player, "call_pet");
+
+               StringIdChatParameter message("pet/pet_menu", "call_pet_delay"); // Calling pet in %DI seconds. Combat will terminate pet call.
+               message.setDI(15);
+               player->sendSystemMessage(message);
+
+               player->addPendingTask("call_pet", callPet, 15 * 1000);
+
+               if (petControlObserver == NULL) {
+                       petControlObserver = new PetControlObserver(_this.get());
+                       petControlObserver->deploy();
+               }
+
+               player->registerObserver(ObserverEventType::STARTCOMBAT, petControlObserver);
+
+       } else {
+
+               Locker clocker(controlledObject, player);
+               spawnObject(player);
+       }
+
+}
+
+void PetControlDeviceImplementation::spawnObject(CreatureObject* player) {
+       ZoneServer* zoneServer = getZoneServer();
+
+       ManagedReference<TangibleObject*> controlledObject = this->controlledObject.get();
+
+       if (controlledObject == NULL)
+               return;
+
+       if (!isASubChildOf(player))
+               return;
+
+       ManagedReference<TradeSession*> tradeContainer = player->getActiveSession(SessionFacadeType::TRADE).castTo<TradeSession*>();
+
+       if (tradeContainer != NULL) {
+               server->getZoneServer()->getPlayerManager()->handleAbortTradeMessage(player);
+       }
+
+       controlledObject->initializePosition(player->getPositionX(), player->getPositionZ(), player->getPositionY());
+       ManagedReference<CreatureObject*> creature = NULL;
+
+       if (controlledObject->isCreatureObject()) {
+               creature = cast<CreatureObject*>(controlledObject.get());
+               creature->setCreatureLink(player);
+               creature->setControlDevice(_this.get());
+               creature->setFaction(player->getFaction());
+               // TODO: need to have the pet take on the faction status of the owner (Special Forces, Combatant, or On Leave)
+       }
+
+       Zone* zone = player->getZone();
+
+       if (zone == NULL)
+               return;
+
+       zone->transferObject(controlledObject, -1, true);
+
+       updateStatus(1);
+
+       if (petControlObserver != NULL)
+               player->dropObserver(ObserverEventType::STARTCOMBAT, petControlObserver);
+
+       AiAgent* pet = cast<AiAgent*>(creature.get());
+
+       pet->setFollowObject(player);
+}
+
+void PetControlDeviceImplementation::cancelSpawnObject(CreatureObject* player) {
+
+       Reference<Task*> petTask = player->getPendingTask("call_pet");
+       if(petTask) {
+               petTask->cancel();
+               player->removePendingTask("call_pet");
+       }
+
+       if (petControlObserver != NULL)
+               player->dropObserver(ObserverEventType::STARTCOMBAT, petControlObserver);
+}
+
+void PetControlDeviceImplementation::storeObject(CreatureObject* player) {
+       ManagedReference<TangibleObject*> controlledObject = this->controlledObject.get();
+
+       if (controlledObject == NULL)
+               return;
+
+       if (player->isRidingMount() && player->getParent() == controlledObject) {
+
+               if (!player->checkCooldownRecovery("mount_dismount"))
+                       return;
+
+               player->executeObjectControllerAction(String("dismount").hashCode());
+
+               if (player->isRidingMount())
+                       return;
+       }
+
+       controlledObject->destroyObjectFromWorld(true);
+
+       if (controlledObject->isCreatureObject())
+               (cast<CreatureObject*>(controlledObject.get()))->setCreatureLink(NULL);
+
+       updateStatus(0);
+}
+
+
+void PetControlDeviceImplementation::destroyObjectFromDatabase(bool destroyContainedObjects) {
+       ManagedReference<TangibleObject*> controlledObject = this->controlledObject.get();
+
+       if (controlledObject != NULL) {
+               Locker locker(controlledObject);
+
+               ManagedReference<CreatureObject*> object = controlledObject->getSlottedObject("rider").castTo<CreatureObject*>();
+
+               if (object != NULL) {
+                       Locker clocker(object, controlledObject);
+
+                       object->executeObjectControllerAction(String("dismount").hashCode());
+
+                       object = controlledObject->getSlottedObject("rider").castTo<CreatureObject*>();
+
+                       if (object != NULL) {
+                               controlledObject->removeObject(object, NULL, true);
+
+                               Zone* zone = getZone();
+
+                               if (zone != NULL)
+                                       zone->transferObject(object, -1, false);
+                       }
+               }
+
+               controlledObject->destroyObjectFromDatabase(true);
+       }
+
+       IntangibleObjectImplementation::destroyObjectFromDatabase(destroyContainedObjects);
+}
+
+int PetControlDeviceImplementation::canBeDestroyed(CreatureObject* player) {
+       ManagedReference<TangibleObject*> controlledObject = this->controlledObject.get();
+
+       if (controlledObject != NULL) {
+               if (controlledObject->isInQuadTree())
+                       return 1;
+       }
+
+       return IntangibleObjectImplementation::canBeDestroyed(player);
+}
+
+void PetControlDeviceImplementation::fillAttributeList(AttributeListMessage* alm, CreatureObject* object) {
+       SceneObjectImplementation::fillAttributeList(alm, object);
+
+       alm->insertAttribute("creature_vitality", vitality);
+}
diff --git a/MMOCoreORB/src/server/zone/objects/intangible/PetControlObserver.idl b/MMOCoreORB/src/server/zone/objects/intangible/PetControlObserver.idl
new file mode 100644 (file)
index 0000000..ff671dd
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+Copyright (C) 2007 <SWGEmu>
+
+This File is part of Core3.
+
+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 2 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, write to
+the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Linking Engine3 statically or dynamically with other modules
+is making a combined work based on Engine3.
+Thus, the terms and conditions of the GNU Lesser General Public License
+cover the whole combination.
+
+In addition, as a special exception, the copyright holders of Engine3
+give you permission to combine Engine3 program with free software
+programs or libraries that are released under the GNU LGPL and with
+code included in the standard release of Core3 under the GNU LGPL
+license (or modified versions of such code, with unchanged license).
+You may copy and distribute such a system following the terms of the
+GNU LGPL for Engine3 and the licenses of the other code concerned,
+provided that you include the source code of that other code when
+and as the GNU LGPL requires distribution of source code.
+
+Note that people who make modified versions of Engine3 are not obligated
+to grant this special exception for their modified versions;
+it is their choice whether to do so. The GNU Lesser General Public License
+gives permission to release a modified version without this exception;
+this exception also makes it possible to release a modified version
+which carries forward this exception.
+ */
+
+package server.zone.objects.intangible;
+
+include engine.core.ManagedObject;
+
+import engine.log.Logger;
+import engine.core.ManagedReference;
+import system.lang.ref.Reference;
+import engine.core.Task;
+import engine.util.Observer;
+import engine.util.Observable;
+import server.zone.objects.creature.CreatureObject;
+import server.zone.objects.intangible.PetControlDevice;
+include server.zone.objects.scene.ObserverEventType;
+
+
+class PetControlObserver extends Observer {
+       
+       @weakReference
+       PetControlDevice petControlDevice;
+       
+       public PetControlObserver(PetControlDevice device) {
+               petControlDevice = device;
+       }
+
+       public int notifyObserverEvent(unsigned int eventType, Observable observable, ManagedObject arg1, long arg2) {
+               if (eventType != ObserverEventType.STARTCOMBAT) {
+                       return 1;
+               }
+
+               if (petControlDevice != null) {
+                       CreatureObject creature = (CreatureObject) observable;
+                       petControlDevice.cancelSpawnObject(creature);
+               }
+               
+               return 1;
+       }
+
+}
index 02f33e5..9144ba8 100644 (file)
@@ -131,6 +131,9 @@ class VehicleControlDevice extends ControlDevice {
         */
        @local
        public native void fillAttributeList(AttributeListMessage msg, CreatureObject object);  
-       
+
+       public boolean isVehicleControlDevice() {
+               return true;
+       }
 }
 
index 0ef0a09..85f7fc6 100644 (file)
@@ -63,8 +63,8 @@ void VehicleControlDeviceImplementation::generateObject(CreatureObject* player)
        for (int i = 0; i < datapad->getContainerObjectsSize(); ++i) {
                ManagedReference<SceneObject*> object = datapad->getContainerObject(i);
 
-               if (object->isControlDevice()) {
-                       ControlDevice* device = cast<ControlDevice*>( object.get());
+               if (object->isVehicleControlDevice()) {
+                       VehicleControlDevice* device = cast<VehicleControlDevice*>( object.get());
 
                        ManagedReference<SceneObject*> vehicle = device->getControlledObject();
 
diff --git a/MMOCoreORB/src/server/zone/objects/intangible/tasks/CallPetTask.h b/MMOCoreORB/src/server/zone/objects/intangible/tasks/CallPetTask.h
new file mode 100644 (file)
index 0000000..dfb38d2
--- /dev/null
@@ -0,0 +1,34 @@
+
+#ifndef CALLPETTASK_H_
+#define CALLPETTASK_H_
+
+#include "server/zone/objects/creature/CreatureObject.h"
+#include "server/zone/objects/intangible/ControlDevice.h"
+
+class CallPetTask : public Task {
+       ManagedReference<CreatureObject*> player;
+       ManagedReference<PetControlDevice*> device;
+       String taskName;
+
+public:
+       CallPetTask(PetControlDevice* controlDevice, CreatureObject* creo, const String& task) {
+               player = creo;
+               device = controlDevice;
+               taskName = task;
+       }
+
+       void run() {
+
+               Locker locker(player);
+
+               player->removePendingTask("call_pet");
+
+               if(player->isInCombat())
+                       return;
+
+               Locker clocker(device->getControlledObject(), player);
+               device->spawnObject(player);
+       }
+};
+
+#endif /* CALLPETTASK_H_ */
index 0334ee6..a06641b 100644 (file)
@@ -1833,7 +1833,17 @@ class SceneObject extends QuadTreeEntry implements Logger {
        public abstract boolean isControlDevice() {
                return false;
        }
-       
+
+       @dirty
+       public abstract boolean isPetControlDevice() {
+               return false;
+       }
+
+       @dirty
+       public abstract boolean isVehicleControlDevice() {
+               return false;
+       }
+
        @dirty
        public abstract boolean isMissionTerminal() {
                return false;