// MissionObject.cpp // Copyright 2000-01, Sony Online Entertainment Inc., all rights reserved. // Author: Justin Randall //----------------------------------------------------------------------- #include "serverGame/FirstServerGame.h" #include "serverGame/MissionObject.h" #include "UnicodeUtils.h" #include "boost/smart_ptr.hpp" #include "serverGame/ContainerInterface.h" #include "serverGame/GameServer.h" #include "serverGame/MessageToQueue.h" #include "serverGame/ObjectIdManager.h" #include "serverGame/ObjectTracker.h" #include "serverGame/PlayerCreatureController.h" #include "serverGame/ServerMissionObjectTemplate.h" #include "serverGame/ServerObjectTemplate.h" #include "serverGame/ServerWorld.h" #include "serverScript/GameScriptObject.h" #include "serverScript/ScriptDictionary.h" #include "serverScript/ScriptParameters.h" #include "sharedFoundation/ConstCharCrcLowerString.h" #include "sharedFoundation/ConstCharCrcString.h" #include "sharedGame/WaypointData.h" #include "sharedMessageDispatch/Transceiver.h" #include "sharedNetworkMessages/MessageQueueMissionCreateRequestData.h" #include "sharedNetworkMessages/MessageQueueMissionDetailsResponseData.h" #include "sharedObject/NetworkIdManager.h" #include "sharedObject/ObjectTemplateList.h" //----------------------------------------------------------------------- const SharedObjectTemplate * MissionObject::m_defaultSharedTemplate = NULL; const char * const s_missionObjectTemplateName = "object/mission/base_mission_object.iff"; //----------------------------------------------------------------------- MissionObject::MissionObject(const ServerMissionObjectTemplate * t) : IntangibleObject(t), m_callback(new MessageDispatch::Callback), m_description(), m_difficulty(0), m_endLocation(), m_missionCreator(), m_missionType(), m_reward(0), m_rootScriptName(), m_startLocation(), m_targetAppearance(), m_title(), m_missionHolderId(), m_status(0), m_targetName() { addMembersToPackages(); ObjectTracker::addMissionObject(); Waypoint & w = const_cast(m_waypoint.get()); m_callback->connect(w.getChangeNotification(), *this, &MissionObject::setWaypoint); m_callback->connect(w.getLoadNotification(), *this, &MissionObject::onWaypointLoad); } //----------------------------------------------------------------------- MissionObject::~MissionObject() { ObjectTracker::removeMissionObject(); delete m_callback; } //----------------------------------------------------------------------- MissionObject * MissionObject::createMissionObjectInCreatureMissionBag(CreatureObject * creature) { MissionObject * result = 0; ServerObject * missionBag = creature->getMissionBag(); if(missionBag) result = safe_cast(ServerWorld::createNewObject(s_missionObjectTemplateName, *missionBag, false)); return result; } //----------------------------------------------------------------------- bool MissionObject::canTrade() const { return false; } //----------------------------------------------------------------------- bool MissionObject::onContainerAboutToLoseItem(ServerObject * destination, ServerObject& item, ServerObject* transferer) { if (transferer) return false; return ServerObject::onContainerAboutToLoseItem(destination, item, transferer); } //----------------------------------------------------------------------- bool MissionObject::onContainerAboutToTransfer(ServerObject * destination, ServerObject* transferer) { if (transferer) return false; return ServerObject::onContainerAboutToTransfer(destination, transferer); } //----------------------------------------------------------------------- int MissionObject::onContainerAboutToGainItem(ServerObject& item, ServerObject* transferer) { if (transferer) return Container::CEC_BlockedByDestinationContainer; return ServerObject::onContainerAboutToGainItem(item, transferer); } //----------------------------------------------------------------------- /** * Returns a shared template if none was given for this object. * * @return the shared template */ const SharedObjectTemplate * MissionObject::getDefaultSharedTemplate(void) const { static const ConstCharCrcLowerString templateName("object/mission/base/shared_mission_default.iff"); if (m_defaultSharedTemplate == NULL) { m_defaultSharedTemplate = safe_cast( ObjectTemplateList::fetch(templateName)); WARNING_STRICT_FATAL(m_defaultSharedTemplate == NULL, ("Cannot create " "default shared object template %s", templateName.getString())); if (m_defaultSharedTemplate != NULL) ExitChain::add (removeDefaultTemplate, "MissionObject::removeDefaultTemplate"); } return m_defaultSharedTemplate; } // MissionObject::getDefaultSharedTemplate //----------------------------------------------------------------------- /** * Cleans up the default shared template. */ void MissionObject::removeDefaultTemplate(void) { if (m_defaultSharedTemplate != NULL) { m_defaultSharedTemplate->releaseReference(); m_defaultSharedTemplate = NULL; } } // MissionObject::removeDefaultTemplate //----------------------------------------------------------------------- void MissionObject::abortMission() { ScriptParams params; ScriptDictionaryPtr dictionary; getScriptObject()->makeScriptDictionary(params, dictionary); if (dictionary.get() != NULL) { dictionary->serialize(); MessageToQueue::getInstance().sendMessageToJava(getNetworkId(), "abortMission", dictionary->getSerializedData(), 0, true); } /* CreatureObject *player = safe_cast(ServerWorld::findObjectByNetworkId(getMissionHolderId())); if (player) { player->abortMission(this); } */ } //----------------------------------------------------------------------- void MissionObject::endBaselines() { CreatureObject * c = dynamic_cast(NetworkIdManager::getObjectById(m_missionHolderId.get())); if(c) { setMissionHolderId(c->getNetworkId()); } ServerObject::endBaselines(); } //----------------------------------------------------------------------- void MissionObject::endMission(const bool) { } //----------------------------------------------------------------------- void MissionObject::setMissionHolderId(const NetworkId & h) { m_missionHolderId.set(h); } //----------------------------------------------------------------------- void MissionObject::getAttributes(stdvector >::fwd &data) const { IntangibleObject::getAttributes(data); std::string const & missionType = getMissionTypeString(); if (strncmp(missionType.c_str(),"space_",6)==0) { if (missionType=="space_battle") data.push_back(std::make_pair(std::string("type"),Unicode::narrowToWide("@space/quest:space_battle"))); // unfortunately, this one is inconsistent else if (missionType=="space_mining_destroy") data.push_back(std::make_pair(std::string("type"),Unicode::narrowToWide("@space/quest:space_mining_destroy"))); // unfortunately, this one is also inconsistent else data.push_back(std::make_pair(std::string("type"),Unicode::narrowToWide(std::string("@space/quest:") + std::string(missionType,6)))); } data.push_back(std::make_pair(std::string("description"),Unicode::narrowToWide(std::string("@") + getDescription().getCanonicalRepresentation()))); } //----------------------------------------------------------------------- MissionObject * MissionObject::asMissionObject() { return this; } //----------------------------------------------------------------------- MissionObject const * MissionObject::asMissionObject() const { return this; } //----------------------------------------------------------------------- const NetworkId & MissionObject::getMissionHolderId() const { return m_missionHolderId.get(); } //----------------------------------------------------------------------- const StringId & MissionObject::getDescription() const { return m_description.get(); } //----------------------------------------------------------------------- const int MissionObject::getDifficulty() const { return m_difficulty.get(); } //----------------------------------------------------------------------- const Location & MissionObject::getEndLocation() const { return m_endLocation.get(); } //----------------------------------------------------------------------- const Unicode::String & MissionObject::getMissionCreator() const { return m_missionCreator.get(); } //----------------------------------------------------------------------- const unsigned int MissionObject::getMissionType() const { return m_missionType.get(); } //----------------------------------------------------------------------- const std::string & MissionObject::getMissionTypeString() const { // @todo this should be a crc string table! static const unsigned int destroy = CrcLowerString::calculateCrc("destroy"); static const unsigned int recon = CrcLowerString::calculateCrc("recon"); static const unsigned int deliver = CrcLowerString::calculateCrc("deliver"); static const unsigned int escorttocreator = CrcLowerString::calculateCrc("escorttocreator"); static const unsigned int escort = CrcLowerString::calculateCrc("escort"); static const unsigned int bounty = CrcLowerString::calculateCrc("bounty"); static const unsigned int survey = CrcLowerString::calculateCrc("survey"); static const unsigned int crafting = CrcLowerString::calculateCrc("crafting"); static const unsigned int musician = CrcLowerString::calculateCrc("musician"); static const unsigned int dancer = CrcLowerString::calculateCrc("dancer"); static const unsigned int hunting = CrcLowerString::calculateCrc("hunting"); static const unsigned int space_assassination = CrcLowerString::calculateCrc("space_assassination"); static const unsigned int space_delivery = CrcLowerString::calculateCrc("space_delivery"); static const unsigned int space_delivery_duty = CrcLowerString::calculateCrc("space_delivery_duty"); static const unsigned int space_destroy = CrcLowerString::calculateCrc("space_destroy"); static const unsigned int space_destroy_duty = CrcLowerString::calculateCrc("space_destroy_duty"); static const unsigned int space_surprise_attack = CrcLowerString::calculateCrc("space_surprise_attack"); static const unsigned int space_escort = CrcLowerString::calculateCrc("space_escort"); static const unsigned int space_escort_duty = CrcLowerString::calculateCrc("space_escort duty"); static const unsigned int space_inspection = CrcLowerString::calculateCrc("space_inspection"); static const unsigned int space_patrol = CrcLowerString::calculateCrc("space_patrol"); static const unsigned int space_recovery = CrcLowerString::calculateCrc("space_recovery"); static const unsigned int space_recovery_duty = CrcLowerString::calculateCrc("space_recovery_duty"); static const unsigned int space_rescue = CrcLowerString::calculateCrc("space_rescue"); static const unsigned int space_rescue_duty = CrcLowerString::calculateCrc("space_rescue_duty"); static const unsigned int space_battle = CrcLowerString::calculateCrc("space_battle"); static const unsigned int space_survival = CrcLowerString::calculateCrc("space_survival"); static const unsigned int space_mining_destroy = CrcLowerString::calculateCrc("space_mining_destroy"); if(m_missionType.get() == destroy) { static const std::string r = "destroy"; return r; } else if(m_missionType.get() == recon) { static const std::string r = "recon"; return r; } else if(m_missionType.get() == deliver) { static const std::string r = "deliver"; return r; } else if(m_missionType.get() == escorttocreator) { static const std::string r = "escorttocreator"; return r; } else if(m_missionType.get() == escort) { static const std::string r = "escort"; return r; } else if(m_missionType.get() == bounty) { static const std::string r = "bounty"; return r; } else if(m_missionType.get() == survey) { static const std::string r = "survey"; return r; } else if(m_missionType.get() == crafting) { static const std::string r = "crafting"; return r; } else if(m_missionType.get() == musician) { static const std::string r = "musician"; return r; } else if(m_missionType.get() == dancer) { static const std::string r = "dancer"; return r; } else if(m_missionType.get() == hunting) { static const std::string r = "hunting"; return r; } else if(m_missionType.get() == space_assassination) { static const std::string r = "space_assassination"; return r; } else if(m_missionType.get() == space_delivery) { static const std::string r = "space_delivery"; return r; } else if(m_missionType.get() == space_delivery_duty) { static const std::string r = "space_delivery_duty"; return r; } else if(m_missionType.get() == space_destroy) { static const std::string r = "space_destroy"; return r; } else if(m_missionType.get() == space_destroy_duty) { static const std::string r = "space_destroy_duty"; return r; } else if(m_missionType.get() == space_surprise_attack) { static const std::string r = "space_surprise_attack"; return r; } else if(m_missionType.get() == space_escort) { static const std::string r = "space_escort"; return r; } else if(m_missionType.get() == space_escort_duty) { static const std::string r = "space_escort_duty"; return r; } else if(m_missionType.get() == space_inspection) { static const std::string r = "space_inspection"; return r; } else if(m_missionType.get() == space_patrol) { static const std::string r = "space_patrol"; return r; } else if(m_missionType.get() == space_recovery) { static const std::string r = "space_recovery"; return r; } else if(m_missionType.get() == space_recovery_duty) { static const std::string r = "space_recovery_duty"; return r; } else if(m_missionType.get() == space_rescue) { static const std::string r = "space_rescue"; return r; } else if(m_missionType.get() == space_rescue_duty) { static const std::string r = "space_rescue_duty"; return r; } else if(m_missionType.get() == space_battle) { static const std::string r = "space_battle"; return r; } else if(m_missionType.get() == space_survival) { static const std::string r = "space_survival"; return r; } else if(m_missionType.get() == space_mining_destroy) { static const std::string r = "space_mining_destroy"; return r; } static const std::string unknown("unknown"); return unknown; } //----------------------------------------------------------------------- const int MissionObject::getReward() const { return m_reward.get(); } //----------------------------------------------------------------------- const std::string & MissionObject::getRootScriptName() const { return m_rootScriptName.get(); } //----------------------------------------------------------------------- const Location & MissionObject::getStartLocation() const { return m_startLocation.get(); } //----------------------------------------------------------------------- const int MissionObject::getStatus() const { return m_status.get(); } //----------------------------------------------------------------------- const unsigned int MissionObject::getTargetAppearance() const { return m_targetAppearance.get(); } //----------------------------------------------------------------------- const std::string & MissionObject::getTargetName() const { return m_targetName.get(); } //----------------------------------------------------------------------- const StringId & MissionObject::getTitle() const { return m_title.get(); } //----------------------------------------------------------------------- const Waypoint & MissionObject::getWaypoint() const { return m_waypoint.get(); } //----------------------------------------------------------------------- void MissionObject::grantMissionTo(const NetworkId & target) { ScriptParams p; p.addParam(target); getScriptObject()->trigAllScripts(Scripting::TRIG_GRANT_MISSION, p); } //----------------------------------------------------------------------- void MissionObject::onAddedToWorld() { IntangibleObject::onAddedToWorld(); } //----------------------------------------------------------------------- void MissionObject::setDescription(const StringId & d) { m_description.set(d); } //----------------------------------------------------------------------- void MissionObject::setDifficulty(const int v) { m_difficulty.set(v); } //----------------------------------------------------------------------- void MissionObject::setEndLocation(const Location & v) { m_endLocation.set(v); } //----------------------------------------------------------------------- void MissionObject::setMissionCreator(const Unicode::String & c) { m_missionCreator.set(c); } //----------------------------------------------------------------------- void MissionObject::setMissionType(const unsigned char t) { m_missionType.set(t); } //----------------------------------------------------------------------- void MissionObject::setMissionType(const std::string & t) { m_missionType.set(CrcLowerString::calculateCrc(t.c_str())); } //----------------------------------------------------------------------- void MissionObject::setReward(const int v) { m_reward.set(v); } //----------------------------------------------------------------------- void MissionObject::setRootScriptName(const std::string & r) { if(! m_rootScriptName.get().empty()) { getScriptObject()->detachScript(getRootScriptName()); } m_rootScriptName.set(r); getScriptObject()->attachScript(m_rootScriptName.get(), true); } //----------------------------------------------------------------------- void MissionObject::setStartLocation(const Location & v) { m_startLocation.set(v); } //----------------------------------------------------------------------- void MissionObject::setStatus(int newStatus) { if(newStatus != 0) { m_status.set(m_status.get() + 1); } } //----------------------------------------------------------------------- void MissionObject::setTargetAppearance(const std::string & a) { const ServerObjectTemplate * t = dynamic_cast(ObjectTemplateList::fetch(a)); if(t) { std::string s = t->getSharedTemplate(); ConstCharCrcString c(s.c_str()); setTargetAppearance(c.getCrc()); } } //----------------------------------------------------------------------- void MissionObject::setTargetAppearance(unsigned int a) { m_targetAppearance.set(a); } //----------------------------------------------------------------------- void MissionObject::setTargetName(const std::string & n) { m_targetName.set(n); } //----------------------------------------------------------------------- void MissionObject::setTitle(const StringId & t) { m_title.set(t); } //----------------------------------------------------------------------- void MissionObject::setWaypoint(const Waypoint & w) { m_waypoint.set(w); } //----------------------------------------------------------------------- void MissionObject::onWaypointLoad(Waypoint::ChangeNotification & c) { Waypoint & w = const_cast(m_waypoint.get()); m_callback->disconnect(w.getChangeNotification(), *this, &MissionObject::setWaypoint); m_callback->connect(c, *this, &MissionObject::setWaypoint); } // ---------------------------------------------------------------------- void MissionObject::initializeFirstTimeObject() { m_waypoint.set(Waypoint(ObjectIdManager::getNewObjectId())); IntangibleObject::initializeFirstTimeObject(); } // ---------------------------------------------------------------------- void MissionObject::getByteStreamFromAutoVariable(const std::string & name, Archive::ByteStream & target) const { if (name == "moCtsPackUnpack") { // description m_description.pack(target); // difficulty m_difficulty.pack(target); // end location m_endLocation.pack(target); // mission creator m_missionCreator.pack(target); // mission type m_missionType.pack(target); // reward m_reward.pack(target); // root script name m_rootScriptName.pack(target); // start location m_startLocation.pack(target); // target appearance m_targetAppearance.pack(target); // title m_title.pack(target); // mission holder id // don't need to pack this, will be assigned the id of the destination character object // status m_status.pack(target); // target name m_targetName.pack(target); // waypoint Archive::put(target, m_waypoint.get().getWaypointDataBase()); // mission location target CreatureObject const * containingPlayer = NULL; ServerObject const * parent = safe_cast(ContainerInterface::getContainedByObject(*this)); while (parent) { containingPlayer = parent->asCreatureObject(); if (containingPlayer && PlayerCreatureController::getPlayerObject(containingPlayer)) break; containingPlayer = NULL; parent = safe_cast(ContainerInterface::getContainedByObject(*parent)); } bool hasMissionLocationTarget = false; if (containingPlayer) { std::vector const & locationData = containingPlayer->getLocationTargets(); for (std::vector::const_iterator iter = locationData.begin(); iter != locationData.end(); ++iter) { if (iter->name == Unicode::narrowToWide(getNetworkId().getValueString())) { Archive::put(target, true); Archive::put(target, *iter); hasMissionLocationTarget = true; break; } } } if (!hasMissionLocationTarget) Archive::put(target, false); } else { IntangibleObject::getByteStreamFromAutoVariable(name, target); } } // ---------------------------------------------------------------------- void MissionObject::setAutoVariableFromByteStream(const std::string & name, const Archive::ByteStream & source) { Archive::ReadIterator ri(source); if (name == "moCtsPackUnpack") { // description m_description.unpackDelta(ri); // difficulty m_difficulty.unpackDelta(ri); // end location m_endLocation.unpackDelta(ri); // mission creator m_missionCreator.unpackDelta(ri); // mission type m_missionType.unpackDelta(ri); // reward m_reward.unpackDelta(ri); // root script name m_rootScriptName.unpackDelta(ri); // start location m_startLocation.unpackDelta(ri); // target appearance m_targetAppearance.unpackDelta(ri); // title m_title.unpackDelta(ri); // mission holder id CreatureObject * containingPlayer = NULL; ServerObject * parent = safe_cast(ContainerInterface::getContainedByObject(*this)); while (parent) { containingPlayer = parent->asCreatureObject(); if (containingPlayer && PlayerCreatureController::getPlayerObject(containingPlayer)) break; containingPlayer = NULL; parent = safe_cast(ContainerInterface::getContainedByObject(*parent)); } if (containingPlayer) m_missionHolderId.set(containingPlayer->getNetworkId()); // status m_status.unpackDelta(ri); // target name m_targetName.unpackDelta(ri); // waypoint WaypointDataBase waypointDB; Archive::get(ri, waypointDB); Waypoint w = m_waypoint.get(); w.setAppearanceNameCrc(waypointDB.m_appearanceNameCrc); w.setLocation(waypointDB.m_location); w.setName(waypointDB.m_name); w.setColor(waypointDB.m_color); w.setActive(waypointDB.m_active); m_waypoint.set(w); DynamicVariableList const & objvar = getObjVars(); if (objvar.hasItem("objTargetWaypoint") && (objvar.getType("objTargetWaypoint") == DynamicVariable::NETWORK_ID)) IGNORE_RETURN(setObjVarItem("objTargetWaypoint", w.getNetworkId())); // mission location target bool hasMissionLocationTarget; Archive::get(ri, hasMissionLocationTarget); if (hasMissionLocationTarget) { LocationData locationData; Archive::get(ri, locationData); locationData.name = Unicode::narrowToWide(getNetworkId().getValueString()); if (containingPlayer) containingPlayer->addLocationTarget(locationData); } // questOwner objvar if (objvar.hasItem("questOwner") && (objvar.getType("questOwner") == DynamicVariable::NETWORK_ID) && containingPlayer) IGNORE_RETURN(setObjVarItem("questOwner", containingPlayer->getNetworkId())); // self objvar if (objvar.hasItem("self") && (objvar.getType("self") == DynamicVariable::NETWORK_ID)) IGNORE_RETURN(setObjVarItem("self", getNetworkId())); } else { IntangibleObject::setAutoVariableFromByteStream(name, source); } addObjectToConcludeList(); } // ======================================================================