diff --git a/CMakeLists.txt b/CMakeLists.txt index 26c37eba..830b23e0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,13 +12,14 @@ set(SWG_GAME_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/game) find_package(Boost REQUIRED) find_package(Iconv REQUIRED) +find_package(JNI REQUIRED) find_package(LibXml2 REQUIRED) find_package(Oracle REQUIRED) find_package(Perl REQUIRED) find_package(STLPort REQUIRED) find_package(ZLib REQUIRED) -include_directories(${STLPORT_INCLUDE_DIR}) +#include_directories(${STLPORT_INCLUDE_DIR}) add_subdirectory(external) add_subdirectory(engine) diff --git a/engine/server/library/CMakeLists.txt b/engine/server/library/CMakeLists.txt index 98d7949b..843c0131 100644 --- a/engine/server/library/CMakeLists.txt +++ b/engine/server/library/CMakeLists.txt @@ -3,4 +3,5 @@ add_subdirectory(serverGame) add_subdirectory(serverKeyShare) add_subdirectory(serverMetrics) add_subdirectory(serverNetworkMessages) +add_subdirectory(serverScript) add_subdirectory(serverUtility) diff --git a/engine/server/library/serverScript/CMakeLists.txt b/engine/server/library/serverScript/CMakeLists.txt new file mode 100644 index 00000000..99648114 --- /dev/null +++ b/engine/server/library/serverScript/CMakeLists.txt @@ -0,0 +1,11 @@ +cmake_minimum_required(VERSION 2.8) + +project(serverScript) + +if(WIN32) + add_definitions(/D_CRT_SECURE_NO_WARNINGS) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/public) + +add_subdirectory(src) diff --git a/engine/server/library/serverScript/include/public/serverScript/ConfigServerScript.h b/engine/server/library/serverScript/include/public/serverScript/ConfigServerScript.h new file mode 100644 index 00000000..a653c943 --- /dev/null +++ b/engine/server/library/serverScript/include/public/serverScript/ConfigServerScript.h @@ -0,0 +1 @@ +#include "../../src/shared/ConfigServerScript.h" diff --git a/engine/server/library/serverScript/include/public/serverScript/FirstServerScript.h b/engine/server/library/serverScript/include/public/serverScript/FirstServerScript.h new file mode 100644 index 00000000..2d7d9970 --- /dev/null +++ b/engine/server/library/serverScript/include/public/serverScript/FirstServerScript.h @@ -0,0 +1 @@ +#include "../../src/shared/FirstServerScript.h" diff --git a/engine/server/library/serverScript/include/public/serverScript/GameScriptObject.h b/engine/server/library/serverScript/include/public/serverScript/GameScriptObject.h new file mode 100644 index 00000000..c9ce6b84 --- /dev/null +++ b/engine/server/library/serverScript/include/public/serverScript/GameScriptObject.h @@ -0,0 +1 @@ +#include "../../src/shared/GameScriptObject.h" diff --git a/engine/server/library/serverScript/include/public/serverScript/JNIWrappers.h b/engine/server/library/serverScript/include/public/serverScript/JNIWrappers.h new file mode 100644 index 00000000..0a09ff4d --- /dev/null +++ b/engine/server/library/serverScript/include/public/serverScript/JNIWrappers.h @@ -0,0 +1 @@ +#include "../../src/shared/JNIWrappers.h" diff --git a/engine/server/library/serverScript/include/public/serverScript/JavaLibrary.h b/engine/server/library/serverScript/include/public/serverScript/JavaLibrary.h new file mode 100644 index 00000000..d97f27fa --- /dev/null +++ b/engine/server/library/serverScript/include/public/serverScript/JavaLibrary.h @@ -0,0 +1 @@ +#include "../../src/shared/JavaLibrary.h" diff --git a/engine/server/library/serverScript/include/public/serverScript/ScriptDictionary.h b/engine/server/library/serverScript/include/public/serverScript/ScriptDictionary.h new file mode 100644 index 00000000..ed7847f6 --- /dev/null +++ b/engine/server/library/serverScript/include/public/serverScript/ScriptDictionary.h @@ -0,0 +1 @@ +#include "../../src/shared/ScriptDictionary.h" diff --git a/engine/server/library/serverScript/include/public/serverScript/ScriptFunctionTable.h b/engine/server/library/serverScript/include/public/serverScript/ScriptFunctionTable.h new file mode 100644 index 00000000..86b9ffed --- /dev/null +++ b/engine/server/library/serverScript/include/public/serverScript/ScriptFunctionTable.h @@ -0,0 +1 @@ +#include "../../src/shared/ScriptFunctionTable.h" diff --git a/engine/server/library/serverScript/include/public/serverScript/ScriptListEntry.h b/engine/server/library/serverScript/include/public/serverScript/ScriptListEntry.h new file mode 100644 index 00000000..0d0c6eab --- /dev/null +++ b/engine/server/library/serverScript/include/public/serverScript/ScriptListEntry.h @@ -0,0 +1,2 @@ +#include "../../src/shared/ScriptListEntry.h" + diff --git a/engine/server/library/serverScript/include/public/serverScript/ScriptMessage.h b/engine/server/library/serverScript/include/public/serverScript/ScriptMessage.h new file mode 100644 index 00000000..27d3b7ae --- /dev/null +++ b/engine/server/library/serverScript/include/public/serverScript/ScriptMessage.h @@ -0,0 +1 @@ +#include "../../src/shared/ScriptMessage.h" diff --git a/engine/server/library/serverScript/include/public/serverScript/ScriptParamArchive.h b/engine/server/library/serverScript/include/public/serverScript/ScriptParamArchive.h new file mode 100644 index 00000000..c131574f --- /dev/null +++ b/engine/server/library/serverScript/include/public/serverScript/ScriptParamArchive.h @@ -0,0 +1 @@ +#include "../../src/shared/ScriptParamArchive.h" diff --git a/engine/server/library/serverScript/include/public/serverScript/ScriptParameters.h b/engine/server/library/serverScript/include/public/serverScript/ScriptParameters.h new file mode 100644 index 00000000..860efa8c --- /dev/null +++ b/engine/server/library/serverScript/include/public/serverScript/ScriptParameters.h @@ -0,0 +1 @@ +#include "../../src/shared/ScriptParameters.h" diff --git a/engine/server/library/serverScript/include/public/serverScript/SetupScript.h b/engine/server/library/serverScript/include/public/serverScript/SetupScript.h new file mode 100644 index 00000000..abd65bb7 --- /dev/null +++ b/engine/server/library/serverScript/include/public/serverScript/SetupScript.h @@ -0,0 +1 @@ +#include "../../src/shared/SetupScript.h" diff --git a/engine/server/library/serverScript/src/CMakeLists.txt b/engine/server/library/serverScript/src/CMakeLists.txt new file mode 100644 index 00000000..583b92a6 --- /dev/null +++ b/engine/server/library/serverScript/src/CMakeLists.txt @@ -0,0 +1,145 @@ + +set(SHARED_SOURCES + shared/ConfigServerScript.cpp + shared/ConfigServerScript.h + shared/FirstServerScript.h + shared/GameScriptObject.cpp + shared/GameScriptObject.h + shared/JavaLibrary.cpp + shared/JavaLibrary.h + shared/JNIWrappers.cpp + shared/JNIWrappers.h + shared/ScriptDictionary.h + shared/ScriptFunctionTable.cpp + shared/ScriptFunctionTable.h + shared/ScriptListEntry.cpp + shared/ScriptMessage.cpp + shared/ScriptMessage.h + shared/ScriptMethodsActionStates.cpp + shared/ScriptMethodsAi.cpp + shared/ScriptMethodsAnimation.cpp + shared/ScriptMethodsAttributes.cpp + shared/ScriptMethodsAuction.cpp + shared/ScriptMethodsBank.cpp + shared/ScriptMethodsBeastMaster.cpp + shared/ScriptMethodsBroadcasting.cpp + shared/ScriptMethodsBuff.cpp + shared/ScriptMethodsBuffBuilder.cpp + shared/ScriptMethodsChat.cpp + shared/ScriptMethodsCity.cpp + shared/ScriptMethodsClientEffect.cpp + shared/ScriptMethodsClusterWideData.cpp + shared/ScriptMethodsCollection.cpp + shared/ScriptMethodsCombat.cpp + shared/ScriptMethodsCommandQueue.cpp + shared/ScriptMethodsConsole.cpp + shared/ScriptMethodsContainers.cpp + shared/ScriptMethodsCrafting.cpp + shared/ScriptMethodsDataTable.cpp + shared/ScriptMethodsDebug.cpp + shared/ScriptMethodsDynamicVariable.cpp + shared/ScriptMethodsForm.cpp + shared/ScriptMethodsGlobalQuery.cpp + shared/ScriptMethodsGuild.cpp + shared/ScriptMethodsHateList.cpp + shared/ScriptMethodsHolocube.cpp + shared/ScriptMethodsHyperspace.cpp + shared/ScriptMethodsImageDesign.cpp + shared/ScriptMethodsInstallation.cpp + shared/ScriptMethodsInterest.cpp + shared/ScriptMethodsInteriors.cpp + shared/ScriptMethodsJedi.cpp + shared/ScriptMethodsMap.cpp + shared/ScriptMethodsMentalStates.cpp + shared/ScriptMethodsMenu.cpp + shared/ScriptMethodsMission.cpp + shared/ScriptMethodsMoney.cpp + shared/ScriptMethodsMount.cpp + shared/ScriptMethodsNewbieTutorial.cpp + shared/ScriptMethodsNotification.cpp + shared/ScriptMethodsNpc.cpp + shared/ScriptMethodsObjectCreate.cpp + shared/ScriptMethodsObjectInfo.cpp + shared/ScriptMethodsObjectMove.cpp + shared/ScriptMethodsPermissions.cpp + shared/ScriptMethodsPilot.cpp + shared/ScriptMethodsPlanet.cpp + shared/ScriptMethodsPlayerAccount.cpp + shared/ScriptMethodsPlayerQuest.cpp + shared/ScriptMethodsPvp.cpp + shared/ScriptMethodsQuest.cpp + shared/ScriptMethodsRegion.cpp + shared/ScriptMethodsRegion3d.cpp + shared/ScriptMethodsRemoteDebug.cpp + shared/ScriptMethodsResource.cpp + shared/ScriptMethodsScript.cpp + shared/ScriptMethodsServerUI.cpp + shared/ScriptMethodsShip.cpp + shared/ScriptMethodsSkill.cpp + shared/ScriptMethodsSpawner.cpp + shared/ScriptMethodsString.cpp + shared/ScriptMethodsSystem.cpp + shared/ScriptMethodsTerrain.cpp + shared/ScriptMethodsTriggerVolume.cpp + shared/ScriptMethodsVeteran.cpp + shared/ScriptMethodsWaypoint.cpp + shared/ScriptMethodsWorldInfo.cpp + shared/ScriptParamArchive.cpp + shared/ScriptParamArchive.h + shared/ScriptParameters.cpp + shared/ScriptParameters.h + shared/SetupScript.cpp + shared/SetupScript.h +) + +if(WIN32) + set(PLATFORM_SOURCES + win32/FirstServerScript.cpp + ) +else() + set(PLATFORM_SOURCES "") +endif() + +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR}/shared + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedCollision/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedCommandParser/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedDebug/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFile/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFoundation/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFoundationTypes/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedGame/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedLog/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMath/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMathArchive/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMemoryManager/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMessageDispatch/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedNetwork/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedNetworkMessages/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedObject/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedPathfinding/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedRandom/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedSkillSystem/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedSynchronization/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedTerrain/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedThread/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedUtility/include/public + ${SWG_ENGINE_SOURCE_DIR}/server/library/serverGame/include/public + ${SWG_ENGINE_SOURCE_DIR}/server/library/serverNetworkMessages/include/public + ${SWG_ENGINE_SOURCE_DIR}/server/library/serverUtility/include/public + ${SWG_GAME_SOURCE_DIR}/shared/library/swgSharedUtility/include/public + ${SWG_EXTERNALS_SOURCE_DIR}/ours/library/archive/include + ${SWG_EXTERNALS_SOURCE_DIR}/ours/library/fileInterface/include/public + ${SWG_EXTERNALS_SOURCE_DIR}/ours/library/localization/include + ${SWG_EXTERNALS_SOURCE_DIR}/ours/library/localizationArchive/include/public + ${SWG_EXTERNALS_SOURCE_DIR}/ours/library/singleton/include + ${SWG_EXTERNALS_SOURCE_DIR}/ours/library/unicode/include + ${SWG_EXTERNALS_SOURCE_DIR}/ours/library/unicodeArchive/include/public + ${Boost_INCLUDE_DIR} + ${JNI_INCLUDE_DIRS} +) + +add_library(serverScript STATIC + ${SHARED_SOURCES} + ${PLATFORM_SOURCES} +) diff --git a/engine/server/library/serverScript/src/shared/ConfigServerScript.cpp b/engine/server/library/serverScript/src/shared/ConfigServerScript.cpp new file mode 100644 index 00000000..ab721d56 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ConfigServerScript.cpp @@ -0,0 +1,101 @@ +// +// ConfigServerScript.cpp +// +// copyright 2000, verant interactive +// +#include "serverScript/FirstServerScript.h" +#include "serverScript/ConfigServerScript.h" +#include "sharedMath/Vector.h" + +#include "sharedFoundation/ConfigFile.h" + +#include + +//------------------------------------------------------------------- + +ConfigServerScript::Data* ConfigServerScript::data; + +//------------------------------------------------------------------- + +static ConfigServerScript::Data staticData; + +//------------------------------------------------------------------- +//lint -e750 Disabling un used macros warning +#define KEY_INT(a,b) (data->a = ConfigFile::getKeyInt("ServerScript", #a, b)) +#define KEY_BOOL(a,b) (data->a = ConfigFile::getKeyBool("ServerScript", #a, b)) +#define KEY_REAL(a,b) (data->a = ConfigFile::getKeyReal("ServerScript", #a, b)) +#define KEY_STRING(a,b) (data->a = ConfigFile::getKeyString("ServerScript", #a, b)) + +//------------------------------------------------------------------- + +namespace ConfigServerScriptNamespace +{ + typedef std::vector StringPtrArray; + StringPtrArray ms_javaOptions; // ConfigFile owns the pointer +} + +using namespace ConfigServerScriptNamespace; + +// ====================================================================== + +bool ConfigServerScript::hasJavaOptions() +{ + return !ms_javaOptions.empty(); +} + +// ---------------------------------------------------------------------- + +int ConfigServerScript::getNumberOfJavaOptions() +{ + return static_cast(ms_javaOptions.size()); +} + +// ---------------------------------------------------------------------- + +char const * ConfigServerScript::getJavaOptions(int index) +{ + VALIDATE_RANGE_INCLUSIVE_EXCLUSIVE(0, index, getNumberOfJavaOptions()); + return ms_javaOptions[static_cast(index)]; +} + +// ---------------------------------------------------------------------- + +void ConfigServerScript::install(void) +{ + data = &staticData; + + KEY_STRING (scriptPath, "../../data/sku.0/sys.server/plt.shared/loc.shared" + "/compiled/game/script"); + KEY_STRING (javaLibPath, "./jvm"); + KEY_STRING (javaDebugPort, "8000"); + KEY_BOOL (useRemoteDebugJava, false); + KEY_BOOL (allowBuildClusterScriptAttach, false); + KEY_BOOL (allowDebugConsoleMessages, true); + KEY_BOOL (allowDebugSpeakMessages, true); + KEY_BOOL (disableScriptLogs, false); + KEY_BOOL (logBalance, false); + + int index = 0; + char const * result = 0; + do + { + // "javaOptions" are in the "GameServer" block and not the "ServerScript" block + result = ConfigFile::getKeyString("GameServer", "javaOptions", index++, 0); + if (result != 0) + { + ms_javaOptions.push_back(result); + } + } + while (result); +} + +//------------------------------------------------------------------- + +void ConfigServerScript::remove(void) +{ +} + +//------------------------------------------------------------------- + + + diff --git a/engine/server/library/serverScript/src/shared/ConfigServerScript.h b/engine/server/library/serverScript/src/shared/ConfigServerScript.h new file mode 100644 index 00000000..b9e98114 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ConfigServerScript.h @@ -0,0 +1,119 @@ +// +// ConfigServerscript.h +// asommers 9-11-2000 +// +// copyright 2000, verant interactive +// + +#ifndef _INCLUDED_ConfigServerScript_H +#define _INCLUDED_ConfigServerScript_H + + +//------------------------------------------------------------------- + +class ConfigServerScript +{ + public: + + struct Data + { + // script data + const char * scriptPath; // location of scripts + const char * javaLibPath; // location of jvm files + const char * javaDebugPort; // ip port we connect to for remote debugging + bool useRemoteDebugJava; // flag to use the jvm for remote debugging + bool allowBuildClusterScriptAttach; //used only on the build cluster for attaching scripts without a VM. + bool allowDebugConsoleMessages; //used only on the build cluster for attaching scripts without a VM. + bool allowDebugSpeakMessages; //used to enable/disable the debugSpeakMessage script function + bool disableScriptLogs; + bool logBalance; + }; + + private: + + static Data *data; + + public: + + static void install (void); + static void remove (void); + + static const char * getScriptPath (void); + static const char * getJavaLibPath (void); + static const char * getJavaDebugPort (void); + static bool getUseRemoteDebugJava (void); + static bool getAllowBuildClusterScriptAttach(); + static bool allowDebugConsoleMessages(); + static bool allowDebugSpeakMessages(); + static bool getDisableScriptLogs(); + static bool getLogBalance(); + + static bool hasJavaOptions(); + static int getNumberOfJavaOptions(); + static char const * getJavaOptions(int index); +}; + +inline const char *ConfigServerScript::getScriptPath(void) +{ + return data->scriptPath; +} + +//----------------------------------------------------------------------- + +inline const char *ConfigServerScript::getJavaLibPath(void) +{ + return data->javaLibPath; +} + +//----------------------------------------------------------------------- + +inline const char *ConfigServerScript::getJavaDebugPort(void) +{ + return data->javaDebugPort; +} + +//----------------------------------------------------------------------- + +inline bool ConfigServerScript::getUseRemoteDebugJava(void) +{ + return data->useRemoteDebugJava; +} + +//----------------------------------------------------------------------- + +inline bool ConfigServerScript::getAllowBuildClusterScriptAttach() +{ + return data->allowBuildClusterScriptAttach; +} + +//----------------------------------------------------------------------- + +inline bool ConfigServerScript::allowDebugConsoleMessages() +{ + return data->allowDebugConsoleMessages; +} + +inline bool ConfigServerScript::allowDebugSpeakMessages() +{ + return data->allowDebugSpeakMessages; +} + +//----------------------------------------------------------------------- + +inline bool ConfigServerScript::getDisableScriptLogs() +{ + return data->disableScriptLogs; +} + +//----------------------------------------------------------------------- + +inline bool ConfigServerScript::getLogBalance() +{ + return data->logBalance; +} + +//----------------------------------------------------------------------- + + +#endif // _INCLUDED_ConfigServerScript_H + diff --git a/engine/server/library/serverScript/src/shared/FirstServerScript.h b/engine/server/library/serverScript/src/shared/FirstServerScript.h new file mode 100644 index 00000000..0e096798 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/FirstServerScript.h @@ -0,0 +1,10 @@ +#ifndef INCLUDED_FirstServerScript_H +#define INCLUDED_FirstServerScript_H + +#include "boost/smart_ptr.hpp" +#include "sharedFoundation/FirstSharedFoundation.h" +#include "sharedMemoryManager/FirstSharedMemoryManager.h" + +#include "StringId.h" + +#endif diff --git a/engine/server/library/serverScript/src/shared/GameScriptObject.cpp b/engine/server/library/serverScript/src/shared/GameScriptObject.cpp new file mode 100644 index 00000000..c2d5c40f --- /dev/null +++ b/engine/server/library/serverScript/src/shared/GameScriptObject.cpp @@ -0,0 +1,1254 @@ +//======================================================================== +// +// GameScriptObject.cpp - responsible for managing/executing scripts. +// +// copyright 2001 Sony Online Entertainment +// +//======================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/GameScriptObject.h" + +#include "boost/smart_ptr.hpp" +#include "ScriptMessage.h" +#include "serverGame/ConfigServerGame.h" +#include "serverGame/ServerController.h" +#include "serverNetworkMessages/MessageQueueScriptTrigger.h" +#include "serverScript/ConfigServerScript.h" +#include "serverScript/ScriptFunctionTable.h" +#include "serverScript/JavaLibrary.h" +#include "serverScript/ScriptParameters.h" +#include "sharedDebug/Profiler.h" +#include "sharedFoundation/Scheduler.h" +#include "sharedNetworkMessages/MessageQueueString.h" +#include "sharedFoundation/GameControllerMessage.h" +#include "sharedLog/Log.h" +#include "sharedObject/NetworkIdManager.h" +#include "sharedObject/Object.h" +#include "serverGame/ServerObject.h" + +#include + + +#ifdef _WIN32 +#pragma warning (disable: 4514 4786) +#endif + + +//======================================================================== +// class GameScriptObject static members +//======================================================================== + +GameScriptObject::ScriptDataMap * GameScriptObject::ms_scriptDataMap = NULL; +bool GameScriptObject::m_pauseScripting = false; + + +//======================================================================== +// class GameScriptObject methods +//======================================================================== + +/** + * Class constructor. + */ +GameScriptObject::GameScriptObject(void) : + m_owner(NULL), + m_scriptList(), + m_scriptListInitialized(false), + m_scriptListValid(false), + m_lockScriptList(false), + m_attachingScript(0) +{ + m_synchronizedScriptList.setSourceObject (this); +} + +/** + * Class destructor. + */ +GameScriptObject::~GameScriptObject() +{ + { + PROFILER_AUTO_BLOCK_DEFINE("GameScriptObject::~GameScriptObject removeJavaId\n"); + if (JavaLibrary::instance() != NULL /*&& m_javaId != NULL*/) + { + NOT_NULL(m_owner); + JavaLibrary::removeJavaId(m_owner->getNetworkId()); +// m_javaId = NULL; + } + } + + { + PROFILER_AUTO_BLOCK_DEFINE("GameScriptObject::removeAll\n"); + removeAll(); + } + m_scriptList.clear(); + m_owner = NULL; +} // GameScriptObject::~GameScriptObject + +/** + * Creates the script engine. + * + * @return true on success, false on fail + */ +bool GameScriptObject::installScriptEngine(void) +{ + if (JavaLibrary::instance() != NULL) + { + DEBUG_WARNING(true, ("Trying to install script engine more than once")); + return true; + } + + ms_scriptDataMap = new GameScriptObject::ScriptDataMap; + Scripting::InitScriptFuncHashMap(); + JavaLibrary::install(); + if (JavaLibrary::instance() == NULL) + return false; + enableNewJediTracking(ConfigServerGame::getEnableNewJedi()); + return true; +} // GameScriptObject::installScriptEngine + +/** + * Destroys the script engine. + */ +void GameScriptObject::removeScriptEngine(void) +{ + JavaLibrary::remove(); + delete ms_scriptDataMap; + ms_scriptDataMap = NULL; + Scripting::RemoveScriptFuncHashMap(); +} // GameScriptObject::removeScriptEngine + +// ------------------------------------------------------------------------ + +void GameScriptObject::addToPackage(Archive::AutoDeltaByteStream & bs) + +{ + bs.addVariable(m_synchronizedScriptList); +} + +// ------------------------------------------------------------------------ + +/** + * Called during game alter phase. + * + * @param time time since last frame + */ +void GameScriptObject::alter(real time) +{ + UNREF(time); +} //lint !e1762 Do not make const + +/** + * Tells the scripting engine that my owner is authoritative on this server. + * + * @param authoritative flag if my owner is authoritative or not + */ +void GameScriptObject::setOwnerIsAuthoritative(bool authoritative, uint32 pid) +{ + if (JavaLibrary::instance() == NULL) + return; + + if (m_owner != NULL && m_owner->getNetworkId() != NetworkId::cms_invalid) + { + JavaLibrary::instance()->setObjIdAuthoritative(m_owner->getNetworkId(), authoritative, pid); + + // clear out old data + m_scriptListValid = false; + if (authoritative && m_scriptListInitialized) + { + initScriptInstances(); + } + } + else + { + DEBUG_WARNING(true, ("Error setting Java obj_id authority, no owner!")); + } +} // GameScriptObject::setOwnerIsAuthoritative + +/** + * Tells the scripting engine that my owner is loaded on this server. You cannot + * unload an object, it is marked unloaded when it is deleted. + */ +void GameScriptObject::setOwnerIsLoaded(void) +{ + if (JavaLibrary::instance() == NULL) + return; + if (m_owner != NULL && m_owner->getNetworkId() != NetworkId::cms_invalid) + { + JavaLibrary::instance()->setObjIdLoaded(m_owner->getNetworkId()); + } + else + { + DEBUG_WARNING(true, ("Error setting Java obj_id loaded, no owner!")); + } +} //lint !e1762 Do not make const + +/** + * Tells the scripting engine that my owner is initialized on this server. You cannot + * uninitialize an object, it is marked uninitialized when it is deleted. + */ +void GameScriptObject::setOwnerIsInitialized(void) +{ + if (JavaLibrary::instance() == NULL) + return; + if (m_owner != NULL && m_owner->getNetworkId() != NetworkId::cms_invalid) + { + JavaLibrary::instance()->setObjIdInitialized(m_owner->getNetworkId()); + if (m_owner->isAuthoritative()) + { + ScriptParams params; + IGNORE_RETURN(trigAllScripts(Scripting::TRIG_INITIALIZE, params)); + } + } + else + { + DEBUG_WARNING(true, ("Error setting Java obj_id loaded, no owner!")); + } +} //lint !e1762 Do not make const + +/** + * Flag the object in script as going to be destroyed, but hasn't actually been removed from the game yet. + */ +void GameScriptObject::setOwnerDestroyed(void) +{ + if (JavaLibrary::instance() == NULL) + return; + + if (m_owner != NULL && m_owner->getNetworkId() != NetworkId::cms_invalid && m_owner->isAuthoritative()) + JavaLibrary::flagDestroyed(m_owner->getNetworkId()); + +} //lint !e1762 Do not make const + +/** + * Adds a script to the start of the script list. + * + * @param scriptName script to add + * @param runTrigger flag to run the TRIG_ATTACH trigger + * + * @return SCRIPT_CONTINUE on success, SCRIPT_OVERRIDE on fail + */ +int GameScriptObject::attachScript(const std::string& scriptName, bool runTrigger) +{ + if (!m_owner) + { + WARNING_STRICT_FATAL(true, ("Attach script %s called with no owner", scriptName.c_str())); + return SCRIPT_OVERRIDE; + } + + if (scriptName.empty()) + { + DEBUG_WARNING(true, ("ERROR in GameScriptObject::AttachScript: no script name")); + return SCRIPT_OVERRIDE; + } + if (scriptName.size() >= MAX_SCRIPT_NAME_LEN) + { + DEBUG_WARNING(true, ("ERROR in GameScriptObject::AttachScript: name too long " + "(%s)", scriptName.c_str())); + return SCRIPT_OVERRIDE; + } + + if(!m_owner->isAuthoritative()) + { + + MessageQueueString * data = new MessageQueueString(scriptName); + m_owner->getController()->appendMessage( + static_cast(CM_attachScript), + 0.0f, + data, + GameControllerMessageFlags::SEND | + GameControllerMessageFlags::RELIABLE | + GameControllerMessageFlags::DEST_AUTH_SERVER); + return SCRIPT_CONTINUE; + } + if (m_lockScriptList) + { + DEBUG_WARNING(true, ("Trying to attach script %s to object %s while the " + "script list is locked.", scriptName.c_str(), + m_owner->getNetworkId().getValueString().c_str())); + return SCRIPT_OVERRIDE; + } + + if (hasScript(scriptName)) + { + DEBUG_WARNING(true, ("WARNING in GameScriptObject::AttachScript: dup script " + "(%s)", scriptName.c_str())); + return SCRIPT_OVERRIDE; + } + + if (ConfigServerScript::getAllowBuildClusterScriptAttach()) + { + //@todo check for file existance. + std::pair result = ms_scriptDataMap->insert(std::make_pair(scriptName, ScriptData())); + m_scriptList.push_back(ScriptListEntry(&(*result.first))); + } + else + { + if (ms_scriptDataMap == NULL || JavaLibrary::instance() == NULL) + return SCRIPT_CONTINUE; + + if (ms_scriptDataMap->find(scriptName) == ms_scriptDataMap->end()) + { + // if this is the first time the script has been attached, query it to get a + // list of triggers, messageHandlers, and pathFindHandlers it has + if (!JavaLibrary::instance()->queryScriptFunctions(scriptName)) + { + WARNING(true, ("Error while attaching script %s. Does it exist?", scriptName.c_str())); + return SCRIPT_OVERRIDE; + } + } + + ScriptListEntry entry = GameScriptObject::getScriptListEntry(scriptName); + + // put a pointer to the pair of scriptName and ScriptData in the script list + m_scriptList.push_back(entry); + + if (runTrigger) + { + // flag that we are attaching a script to ourselves so we can warn if + // we get a messageTo during this time + ++m_attachingScript; + + // Make sure to call the attach trigger on this one script if one exists. + ScriptParams params; + IGNORE_RETURN(trigOneScript(scriptName, Scripting::TRIG_ATTACH, params)); + + --m_attachingScript; + } + + // if the script list hasn't been initialized, wait until it has, + // else go ahead and initialize the script + if (m_scriptListValid && entry.isValid()) + { + JavaLibrary::instance()->attachScriptToObjId(m_owner->getNetworkId(), scriptName); + entry.getScriptData().owners.insert(m_owner->getNetworkId()); + } + } + packScriptList(); + return SCRIPT_CONTINUE; +} // GameScriptObject::attachScript + +/** + * Removes a script from the script list. + * + * @param scriptName script to remove + * + * @return SCRIPT_CONTINUE on success, SCRIPT_OVERRIDE on fail + */ +int GameScriptObject::detachScript(const std::string& scriptName) +{ + if (!m_owner) + { + WARNING_STRICT_FATAL(true, ("Detach script %s called with no owner", scriptName.c_str())); + return SCRIPT_OVERRIDE; + } + if (!m_owner->isAuthoritative()) + { + + MessageQueueString * data = new MessageQueueString(scriptName); + m_owner->getController()->appendMessage( + CM_detachScript, + 0.0f, + data, + GameControllerMessageFlags::SEND | + GameControllerMessageFlags::RELIABLE | + GameControllerMessageFlags::DEST_AUTH_SERVER); + return SCRIPT_CONTINUE; + } + + if (m_lockScriptList) + { + DEBUG_WARNING(true, ("Trying to detach script %s to object %s while the script list is locked.", + scriptName.c_str(), m_owner->getNetworkId().getValueString().c_str())); + return SCRIPT_OVERRIDE; + } + + ScriptList::iterator i; + for (i = m_scriptList.begin(); i != m_scriptList.end(); ++i) + if ((*i).isValid() && (*i).getScriptName() == scriptName) + break; + if (i==m_scriptList.end()) + { + return SCRIPT_OVERRIDE; + } + + int retval = SCRIPT_CONTINUE; + if (ConfigServerScript::getAllowBuildClusterScriptAttach()) + { + m_scriptList.erase(i); + } + else + { + + if (JavaLibrary::instance() == NULL) + return SCRIPT_CONTINUE; + + // Make sure to call the detach trigger on this one script if one exists. + ScriptParams params; + retval = trigOneScript(scriptName, Scripting::TRIG_DETACH, params); + + // Do not remove the script on a return of "override" + if (retval == SCRIPT_CONTINUE) + { + ScriptDataMap::iterator scriptIter = ms_scriptDataMap->find(scriptName); + if (scriptIter != ms_scriptDataMap->end()) + { + // remove ourself from the script's owners + (*scriptIter).second.owners.erase(m_owner->getNetworkId()); + } + + // the OnDetach triggers may have removed other scripts, added new scripts, etc., so we can't + // depend on our iterator still being valid. Find the script again: + for (i = m_scriptList.begin(); i != m_scriptList.end(); ++i) + if ((*i).isValid() && (*i).getScriptName() == scriptName) + { + m_scriptList.erase(i); + break; + } + + JavaLibrary::instance()->detachScriptFromObjId(m_owner->getNetworkId(), scriptName); + } + } + packScriptList(); + return retval; +} // GameScriptObject::detachScript + +/** + * Initialize script instance map with all de-persisted + * scripts + */ +void GameScriptObject::initScriptInstances() +{ + m_scriptListInitialized = true; + + if (JavaLibrary::instance() == NULL) + return; + + if (!m_owner) + { + WARNING_STRICT_FATAL(true, ("Use of null m_owner in ::initScriptInstances()")); + return; + } + + if (m_scriptListValid || !m_owner->isAuthoritative()) + return; + + // while we are in this function, scripts may not be attached or detached on the object + m_lockScriptList = true; + + // reset the script list on the Java side + JavaLibrary::instance()->detachAllScriptsFromObjId(m_owner->getNetworkId()); + JavaLibrary::instance()->attachScriptsToObjId(m_owner->getNetworkId(), m_scriptList); + + for (ScriptList::const_iterator i = m_scriptList.begin(); i != m_scriptList.end(); ++i) + { + if ((*i).isValid()) + (*i).getScriptData().owners.insert(m_owner->getNetworkId()); + } + + m_lockScriptList = false; + m_scriptListValid = true; +} // GameScriptObject::initScriptInstances + +/** + * Clears the script list. + */ +void GameScriptObject::removeAll(void) +{ + if (JavaLibrary::instance() == NULL) + return; + + // removeAll() cannot be overriden by scripts + + // remove ourself from all scripts + for (ScriptList::const_iterator i = m_scriptList.begin(); i != m_scriptList.end(); ++i) + { + if ((*i).isValid()) + (*i).getScriptData().owners.erase(m_owner->getNetworkId()); + } + + // clear our lists + m_scriptList.clear(); + packScriptList(); +} // GameScriptObject::removeAll + +/** + * Runs all the scripts in the script list. + * + * @param trigId script function id to call + * @param params params to pass to the script functions + * + * @return SCRIPT_CONTINUE on success, SCRIPT_OVERRIDE on fail + */ +int GameScriptObject::trigAllScripts(Scripting::TrigId trigId, ScriptParams ¶ms) +{ + NOT_NULL(m_owner); + + if (JavaLibrary::instance() == NULL) + return SCRIPT_CONTINUE; + +// if (m_javaId == NULL && m_owner != NULL && m_owner->getNetworkId().getValue() != 0) +// { +// if (JavaLibrary::instance() != NULL) +// m_javaId = JavaLibrary::getObjId(m_owner->getNetworkId()); +// } + + if (m_pauseScripting) + return SCRIPT_CONTINUE; + + //Authoritative check temporarily removed because some triggers aren't being called + //because the setAuth message hasn't come in yet from Central on load. + if (m_owner == NULL) //@todo FIX THIS HACK || !m_owner->isAuthoritative()) + return SCRIPT_CONTINUE; + + if(!m_owner->isAuthoritative()) + { + Archive::ByteStream paramArchive; + Archive::put(paramArchive, params); + MessageQueueScriptTrigger * data = new MessageQueueScriptTrigger(static_cast(trigId), paramArchive); + ServerController * controller = dynamic_cast(m_owner->getController()); + if(controller != NULL) + { + controller->appendMessage( + CM_scriptTrigger, + 0.0f, + data, + GameControllerMessageFlags::SEND | + GameControllerMessageFlags::RELIABLE | + GameControllerMessageFlags::DEST_AUTH_SERVER + ); + } + return SCRIPT_CONTINUE; + } + + // handle special login/logout needs + if (trigId == Scripting::TRIG_LOGIN) + JavaLibrary::instance()->setObjIdLoggedIn(m_owner->getNetworkId(), true); + else if (trigId == Scripting::TRIG_LOGOUT || trigId == Scripting::TRIG_IMMEDIATE_LOGOUT) + JavaLibrary::instance()->setObjIdLoggedIn(m_owner->getNetworkId(), false); + + if (m_scriptList.size() == 0) + return SCRIPT_CONTINUE; + + Scripting::_ScriptFuncHashMap::const_iterator funcIter = Scripting::ScriptFuncHashMap->find(static_cast(trigId)); + if (funcIter == Scripting::ScriptFuncHashMap->end()) + { + WARNING_STRICT_FATAL(true, ("Got bad trigger id\n")); + return SCRIPT_CONTINUE; + } + const Scripting::ScriptFuncTable *func = (*funcIter).second; + + // If any script has a handler for the trigger, invoke the script library's + // run all scripts function. + if (hasFunction(func->name)) + return JavaLibrary::instance()->runScripts(m_owner->getNetworkId(), func->name, func->argList, params); + + return SCRIPT_CONTINUE; +} // GameScriptObject::trigAllScripts + +/** + * Runs one script. + * + * @param scriptName script to run + * @param trigId script function id to call + * @param params params to pass to the script function + * + * @return SCRIPT_CONTINUE on success, SCRIPT_OVERRIDE on fail or the script + * does not exist + */ +int GameScriptObject::trigOneScript(const std::string& scriptName, Scripting::TrigId trigId, ScriptParams ¶ms) const +{ + if (JavaLibrary::instance() == NULL) + return SCRIPT_CONTINUE; + + if (m_pauseScripting) + return SCRIPT_CONTINUE; + + if (m_owner == NULL /*|| !m_owner->isAuthoritative()*/) + return SCRIPT_OVERRIDE; + + if (!m_owner->isAuthoritative() && (trigId != Scripting::TRIG_ATTACH && + trigId != Scripting::TRIG_DETACH && trigId != Scripting::TRIG_INITIALIZE)) + { + DEBUG_WARNING(true, ("Called trigOneScript on invalid trigger id %d", trigId)); + return SCRIPT_OVERRIDE; + } + + if (!hasScript(scriptName) && trigId != Scripting::TRIG_ATTACH) + return SCRIPT_OVERRIDE; + + Scripting::_ScriptFuncHashMap::const_iterator funcIter = Scripting::ScriptFuncHashMap->find(static_cast(trigId)); + if (funcIter == Scripting::ScriptFuncHashMap->end()) + return SCRIPT_OVERRIDE; + const Scripting::ScriptFuncTable *func = (*funcIter).second; + + NOT_NULL(m_owner); + + // check to see if the script supports the trigger + ScriptDataMap::iterator scriptFuncs = ms_scriptDataMap->find(scriptName); + if (scriptFuncs != ms_scriptDataMap->end()) + { + std::set::const_iterator result = (*scriptFuncs).second.functions.find(func->name); + if (result == (*scriptFuncs).second.functions.end()) + { + return SCRIPT_CONTINUE; + } + } + + return JavaLibrary::instance()->runScript(m_owner->getNetworkId(), scriptName, func->name, func->argList, params); +} // GameScriptObject::trigOneScript + +/** + * Runs one or all script(s), as invoked from the console. + * + * @param trigId script function id to call + * @param scriptName script to run; if 0 length, runs all scripts + * @param args params to send to the script (as a string vector) + */ +int GameScriptObject::trigScriptFromConsole(const Scripting::TrigId trigId, + const std::string &scriptName, const StringVector_t &args) const +{ + if (JavaLibrary::instance() == NULL) + { + LOG("ScriptInvestigation", ("Returning script continue from console trigger request because there is no JavaLibrary instance\n")); + return SCRIPT_CONTINUE; + } + + if (m_pauseScripting) + { + LOG("ScriptInvestigation", ("Returning script continue from console trigger request because scripting is paused\n")); + return SCRIPT_CONTINUE; + } + + if (m_owner == NULL ) + { + LOG("ScriptInvestigation", ("Returning script override from console trigger request becuase m_owner is null\n")); + return SCRIPT_OVERRIDE; + } + + if (!m_owner->isAuthoritative()) + { + LOG("ScriptInvestigation", ("Returning script override from console trigger request becuase owner is not authoritative\n")); + return SCRIPT_OVERRIDE; + } + + Scripting::_ScriptFuncHashMap::const_iterator funcIter = Scripting::ScriptFuncHashMap->find(static_cast(trigId)); + if (funcIter == Scripting::ScriptFuncHashMap->end()) + { + LOG("ScriptInvestigation", ("Returning script override from console trigger request becuase trigger id %i was not found\n", trigId)); + return SCRIPT_OVERRIDE; + } + const Scripting::ScriptFuncTable *func = (*funcIter).second; + + NOT_NULL(m_owner); + + int retval = SCRIPT_CONTINUE; + if (scriptName.size() == 0) + { + // trigger all scripts + if (hasFunction(func->name)) + retval = JavaLibrary::instance()->runScripts(m_owner->getNetworkId(), func->name, func->argList, args); + } + else + { + if (!hasScript(scriptName)) + return SCRIPT_OVERRIDE; + retval = JavaLibrary::instance()->runScript(m_owner->getNetworkId(), scriptName, func->name, func->argList, args); + } + return retval; +} // GameScriptObject::trigScriptFromConsole + +bool GameScriptObject::handleMessage(const std::string &messageName, + const ScriptDictionaryPtr & data) +{ + if (JavaLibrary::instance() == NULL) + { + WARNING_STRICT_FATAL(true, ("(messageToFailure) GameScriptObject::handleMessage got message " + "when Java not running")); + return true; + } + + if (getOwner() == NULL) + { + WARNING_STRICT_FATAL(true, ("(messageToFailure) GameScriptObject::handleMessage got message " + "with no owner")); + return true; + } + + if (m_pauseScripting) + { + LOG("messageToFailure", ("GameScriptObject::handleMessage received " + "message %s for object %s while scripting is paused", + messageName.c_str(), getOwner()->getNetworkId().getValueString().c_str())); + return false; + } + + if (!m_scriptListValid) + { + LOG("messageToFailure", ("GameScriptObject::handleMessage received " + "message %s for object %s while the script list is invalid", + messageName.c_str(), getOwner()->getNetworkId().getValueString().c_str())); + return false; + } + + WARNING (m_attachingScript > 0, ("(messageToFailure) Object %s received messageTo while attaching " + "a script, the message will not get to the script's handler", + getOwner()->getNetworkId().getValueString().c_str())); + + if (hasFunction(messageName)) + IGNORE_RETURN(JavaLibrary::instance()->callMessages(m_owner->getNetworkId(), messageName, data)); + return true; +} // GameScriptObject::handleMessage + +bool GameScriptObject::handleMessage(const std::string &messageName, const std::vector &packedData) +{ + ScriptDictionaryPtr dictionary; + + if (JavaLibrary::instance() == NULL) + return true; + + if (m_pauseScripting) + return false; + + bool result = false; + if (JavaLibrary::instance()->unpackDictionary(packedData, dictionary)) + { + result = handleMessage(messageName, dictionary); + } + else + { + WARNING(true, ("Failed to unpack dictionary for message %s. This message will not be handled.", messageName.c_str())); + // prevent the message from being resent + result = true; + } + return result; +} // GameScriptObject::handleMessage + +/** + * Execute any applicable command handlers in the script list. + * + * @param funcName name of the command handler to call + * @param params parameters to pass to the command handler + * + * @return SCRIPT_CONTINUE or SCRIPT_OVERRIDE + */ +int GameScriptObject::callScriptCommandHandler(std::string const &funcName, ScriptParams ¶ms) const +{ + if (JavaLibrary::instance() == NULL) + return SCRIPT_CONTINUE; + + if (m_pauseScripting) + return SCRIPT_CONTINUE; + + NOT_NULL(m_owner); + + if (hasFunction(funcName)) + return JavaLibrary::instance()->runScripts(m_owner->getNetworkId(), funcName, "Ouf", params); + + return SCRIPT_CONTINUE; +} + +/** + * Execute any applicable buff handlers in the script list. + * + * @param funcName name of the buff handler to call + * @param params parameters to pass to the buff handler + * + * @return SCRIPT_CONTINUE or SCRIPT_OVERRIDE + */ +int GameScriptObject::callScriptBuffHandler(std::string const &funcName, ScriptParams ¶ms) const +{ + if (JavaLibrary::instance() == NULL) + return SCRIPT_CONTINUE; + + if (m_pauseScripting) + return SCRIPT_CONTINUE; + + NOT_NULL(m_owner); + + if (hasFunction(funcName)) + return JavaLibrary::instance()->runScripts(m_owner->getNetworkId(), funcName, "ssffsO", params); + + return SCRIPT_CONTINUE; +} + +/** + * Determines if a script is in the script list. + * + * @param scriptName script to look for + * + * @return true if found, false if not + */ +bool GameScriptObject::hasScript(const std::string& scriptName) const +{ + for (ScriptList::const_iterator i = m_scriptList.begin(); i != m_scriptList.end(); ++i) + if ((*i).isValid() && (*i).getScriptName() == scriptName) + return true; + return false; +} // GameScriptObject::hasScript + +/** + * Determines if any script implements a given trigger. + * + * @param trigId the trigger to check for + * + * @return true if found, false if not + */ +bool GameScriptObject::hasTrigger(const Scripting::TrigId trigId) const +{ + // get the trigger fuction description + Scripting::_ScriptFuncHashMap::const_iterator funcIter = Scripting::ScriptFuncHashMap->find(static_cast(trigId)); + if (funcIter == Scripting::ScriptFuncHashMap->end()) + return false; + const Scripting::ScriptFuncTable *func = (*funcIter).second; + return hasFunction(func->name); +} // GameScriptObject::hasTrigger + +/** + * Fills in a vector with a copy of the current script list. + */ +void GameScriptObject::enumerateScripts(std::vector &scriptNames) const +{ + scriptNames.clear(); + for (ScriptList::const_iterator i = m_scriptList.begin(); i != m_scriptList.end(); ++i) + { + if ((*i).isValid()) + scriptNames.push_back((*i).getScriptName()); + } +} // GameScriptObject::EnumerateScripts + +/** + * Converts ScriptParams into a ScriptDictionary. + * + * @param params the ScriptParams to convert + * @param dictionary pointer that will be set to the dictionary. The caller + * is responsible for deleting the pointer. + */ +void GameScriptObject::makeScriptDictionary(const ScriptParams & params, ScriptDictionaryPtr & dictionary) +{ + if (JavaLibrary::instance() != NULL) + { + JavaDictionaryPtr jdp; + JavaLibrary::instance()->convert(params, jdp); + dictionary = jdp; + } +} + +/** + * Tests if the scripting engine is running. + * + * @return true if the engine is running, false if not + */ +bool GameScriptObject::isScriptingEnabled(void) +{ + if (JavaLibrary::instance() != NULL) + return true; + return false; +} // GameScriptObject::isScriptingEnabled + +/** + * Tells the script to reload a script file. + * + * @param scriptName the script name + * + * @return true on success, false if the script wasn't found + */ +bool GameScriptObject::reloadScript(const std::string& scriptName) +{ + if (JavaLibrary::instance() == NULL) + return false; + + + bool result = false; + ScriptDataMap::iterator scriptIter; + + scriptIter = ms_scriptDataMap->find(scriptName); + if (scriptIter != ms_scriptDataMap->end()) + (*scriptIter).second.functions.clear(); + + result = JavaLibrary::instance()->reloadScript(scriptName); + + // query the script to get a list of triggers, messageHandlers, and + // pathFindHandlers it has + if (result) + { + if (!JavaLibrary::instance()->queryScriptFunctions(scriptName)) + { + WARNING_STRICT_FATAL(true, ("Script query during reload of %s failed\n", scriptName.c_str())); + } + for(scriptIter = ms_scriptDataMap->begin(); scriptIter != ms_scriptDataMap->end(); ++scriptIter) + { + result = JavaLibrary::instance()->reloadScript(scriptIter->first); + if(result) + { + if (!JavaLibrary::instance()->queryScriptFunctions(scriptIter->first)) + { + WARNING_STRICT_FATAL(true, ("Script query during reload of %s failed\n", scriptIter->first.c_str())); + } + } + else + { + return false; + } + } + } + + return result; +} // GameScriptObject::reloadScript + +//----------------------------------------------------------------------- + +/** + * Turns script logging on or off. + * + * @param enable flag to turn logging on or off + */ +void GameScriptObject::enableLogging(bool enable) +{ + if (JavaLibrary::instance() != NULL) + JavaLibrary::instance()->enableLogging(enable); +} // GameScriptObject::enableLogging + +//----------------------------------------------------------------------- + +/** + * Turns tracking of players to see if they can become Jedi on or off. + * + * @param enableTracking flag to turn tracking on or off + */ +void GameScriptObject::enableNewJediTracking(bool enableTracking) +{ + if (JavaLibrary::instance() != NULL) + JavaLibrary::instance()->enableNewJediTracking(enableTracking); +} // GameScriptObject::enableNewJediTracking + +//----------------------------------------------------------------------- + +/** + * Returns the amount of free memory left to the script system. + */ +int GameScriptObject::getScriptFreeMem() +{ + int64 freemem = JavaLibrary::getFreeJavaMemory(); + if (freemem > INT_MAX) + return INT_MAX; + return static_cast(freemem); +} + +//----------------------------------------------------------------------- + +Scheduler & GameScriptObject::getScriptScheduler() +{ + static Scheduler scriptScheduler; + return scriptScheduler; +} + +//----------------------------------------------------------------------- + +void GameScriptObject::onStopWatching(ServerObject & subject) +{ + if (JavaLibrary::instance() == NULL) + return; + + if (m_owner) + { + JavaLibrary::onStopWatching(*m_owner, subject); + } +} + +//----------------------------------------------------------------------- + +void GameScriptObject::onWatching(ServerObject & subject) +{ + if (JavaLibrary::instance() == NULL) + return; + + if (m_owner) + { + JavaLibrary::onWatching(*m_owner, subject); + } +} + +//----------------------------------------------------------------------- + +void GameScriptObject::runOneScript(const std::string & scriptName, const std::string & methodName, const std::string & argTypes, ScriptParams & args) +{ + if (JavaLibrary::instance() != NULL) + IGNORE_RETURN( JavaLibrary::instance()->runScript(NetworkId(), scriptName, methodName, argTypes, args) ); +} + +//----------------------------------------------------------------------- + +/** + * Calls a special function on a script that returns a string instead of an + * integer. The script function has no "self" associated with it. + * + * @param scriptName the name of the script to call + * @param methodName the function name in the script + * @param argTypes the argument types that are being passed to the script + * @param args the arguments that are being passed to the script + * + * @return the string returned from the script function + */ +std::string GameScriptObject::callScriptConsoleHandler(const std::string & scriptName, + const std::string & methodName, const std::string & argTypes, ScriptParams & args) +{ +static const std::string errorReturnString; + + if (JavaLibrary::instance() != NULL) + { + return JavaLibrary::instance()->callScriptConsoleHandler(scriptName, methodName, argTypes, args); + } + return errorReturnString; +} // GameScriptObject::callScriptConsoleHandler + +//----------------------------------------------------------------------- + +void GameScriptObject::callSpaceMakeOvert(const NetworkId &player) +{ + JavaLibrary::spaceMakeOvert(player); +} + +//----------------------------------------------------------------------- + +void GameScriptObject::callSpaceClearOvert(const NetworkId &ship) +{ + JavaLibrary::spaceClearOvert(ship); +} + +//----------------------------------------------------------------------- + +std::string GameScriptObject::callDumpTargetInfo( NetworkId &id ) +{ + if( JavaLibrary::instance() != NULL ) + { + return JavaLibrary::instance()->getObjectDumpInfo( id ); + } + return ""; +} + +//----------------------------------------------------------------------- + +void GameScriptObject::setScriptVar(const std::string & name, int value) +{ + if (JavaLibrary::instance() == NULL || m_owner == NULL) + return; + + JavaLibrary::setScriptVar(*m_owner, name, value); +} + +//----------------------------------------------------------------------- + +void GameScriptObject::setScriptVar(const std::string & name, float value) +{ + if (JavaLibrary::instance() == NULL || m_owner == NULL) + return; + + JavaLibrary::setScriptVar(*m_owner, name, value); +} + +//----------------------------------------------------------------------- + +void GameScriptObject::setScriptVar(const std::string & name, const std::string & value) +{ + if (JavaLibrary::instance() == NULL || m_owner == NULL) + return; + + JavaLibrary::setScriptVar(*m_owner, name, value); +} + +//----------------------------------------------------------------------- + +void GameScriptObject::packAllScriptVarDeltas() +{ + if (JavaLibrary::instance() == NULL) + return; + + JavaLibrary::packAllDeltaScriptVars(); +} + +//----------------------------------------------------------------------- + +void GameScriptObject::clearScriptVars() +{ + if (JavaLibrary::instance() == NULL || m_owner == NULL) + return; + + JavaLibrary::clearScriptVars(*m_owner); +} + +//----------------------------------------------------------------------- + +void GameScriptObject::packScriptVars(std::vector & target) const +{ + if (JavaLibrary::instance() == NULL || m_owner == NULL) + return; + + JavaLibrary::packScriptVars(*m_owner, target); +} + +//----------------------------------------------------------------------- + +void GameScriptObject::unpackScriptVars(const std::vector & source) const +{ + if (JavaLibrary::instance() == NULL || m_owner == NULL) + return; + + JavaLibrary::unpackScriptVars(*m_owner, source); +} + +//----------------------------------------------------------------------- + +void GameScriptObject::unpackDeltaScriptVars(const std::vector & data) const +{ + if (JavaLibrary::instance() == NULL || m_owner == NULL) + return; + + DEBUG_REPORT_LOG(! m_owner, ("A game script object received a request to unpack script var synchronization data, but it has no owner object!!! All GameScriptObjects MUST have owners!\n")); + JavaLibrary::unpackDeltaScriptVars(*m_owner, data); +} + +//----------------------------------------------------------------------- + +bool GameScriptObject::hasFunction(std::string const &funcName) const +{ + for (ScriptList::const_iterator i = m_scriptList.begin(); i != m_scriptList.end(); ++i) + { + if ((*i).isValid()) + { + std::set const &functions = (*i).getScriptData().functions; + if (functions.find(funcName) != functions.end()) + return true; + } + } + return false; +} + +// ---------------------------------------------------------------------- + +ScriptListEntry GameScriptObject::getScriptListEntry(std::string const &scriptName) // static +{ + // This function gets a valid script list entry for the script name + // specified, regardless of whether the script has been previously + // loaded, or exists at all, and if the script was not previously + // loaded, looks up the accessible functions from the script. + std::pair result = ms_scriptDataMap->insert(std::make_pair(scriptName, ScriptData())); + ScriptListEntry entry(&(*result.first)); + if (result.second) + { + // if the script was not already in the map, then we need to look up the functions in it + if (!JavaLibrary::instance()->queryScriptFunctions(scriptName)) + WARNING(true, ("Error while attaching script %s. Does it exist?", scriptName.c_str())); + } + return entry; +} + +// ---------------------------------------------------------------------- + +/** + * Pack the script list vector into the synchronized variable + */ +void GameScriptObject::packScriptList() +{ + std::string newPackedList; + + for (ScriptList::const_iterator i=m_scriptList.begin(); i!=m_scriptList.end(); ++i) + { + newPackedList+=i->getScriptName()+':'; + } + + if (newPackedList.size() > 2000) + { + if (m_owner) + FATAL(true, ("Object %s has a script list that exceeds 2000 characters. The list: %s",m_owner->getNetworkId().getValueString().c_str(), newPackedList.c_str())); + else + FATAL(true, ("Object has a script list that exceeds 2000 characters, but the object id could not be determined. The list: %s", newPackedList.c_str())); + } + + m_synchronizedScriptList=newPackedList; +} + +// ---------------------------------------------------------------------- + +/** + * Unpack the script list from the synchronized variable + */ +void GameScriptObject::unpackScriptList() +{ + const std::string &packedList = m_synchronizedScriptList.get(); + + m_scriptList.clear(); + std::string scriptName; + for (std::string::const_iterator i=packedList.begin(); i!=packedList.end(); ++i) + { + if (*i==':') + { + m_scriptList.push_back(getScriptListEntry(scriptName)); + scriptName.clear(); + } + else + scriptName+=*i; + } +} + +// ---------------------------------------------------------------------- + +/** + * Called when the script list synchronized variable is modified. Updates + * the script list on non-authoritative objects. Updates the data in + * the Java obj_id object for both authoritative and non-authoritative objects. + */ +void GameScriptObject::SyncScriptListCallback::modified(GameScriptObject & target, const std::string & oldValue, const std::string & newValue, bool isLocal) const +{ + if (!isLocal) + { + target.unpackScriptList(); + if (!ConfigServerScript::getAllowBuildClusterScriptAttach()) + { + JavaLibrary::instance()->detachAllScriptsFromObjId(target.m_owner->getNetworkId()); + JavaLibrary::instance()->attachScriptsToObjId(target.m_owner->getNetworkId(),target.m_scriptList); + } + } +} + +// ====================================================================== + +namespace Archive +{ + + void get(ReadIterator &source, ScriptListEntry &target) + { + std::string scriptName; + get(source, scriptName); + target = GameScriptObject::getScriptListEntry(scriptName); + } + +// ---------------------------------------------------------------------- + + void put(ByteStream &target, ScriptListEntry const &source) + { + if (source.isValid()) + put(target, source.getScriptName()); + } + +// ---------------------------------------------------------------------- + +} + +// ---------------------------------------------------------------------- + +GameScriptObject * GameScriptObject::asGameScriptObject(Object * const object) +{ + ServerObject * const serverObject = (object != NULL) ? object->asServerObject() : NULL; + + return (serverObject != NULL) ? serverObject->getScriptObject() : NULL; +} + +// ---------------------------------------------------------------------- + +GameScriptObject const * GameScriptObject::asGameScriptObject(Object const * const object) +{ + ServerObject const * const serverObject = (object != NULL) ? object->asServerObject() : NULL; + + return (serverObject != NULL) ? serverObject->getScriptObject() : NULL; +} + +// ====================================================================== diff --git a/engine/server/library/serverScript/src/shared/GameScriptObject.h b/engine/server/library/serverScript/src/shared/GameScriptObject.h new file mode 100644 index 00000000..311ff9a5 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/GameScriptObject.h @@ -0,0 +1,272 @@ +//======================================================================== +// +// GameScriptObject.h - responsible for managing/executing scripts. +// +// copyright 2001 Sony Online Entertainment +// +//======================================================================== + +#ifndef _INCLUDED_GameScriptObject_H +#define _INCLUDED_GameScriptObject_H + +#ifdef WIN32 +#pragma warning(disable:4503) +#endif + +#include "Archive/AutoDeltaByteStream.h" +#include "Archive/AutoDeltaVariableCallback.h" +#include "Archive/AutoDeltaVector.h" +#include "StringId.h" +#include "serverScript/ScriptFunctionTable.h" +#include "serverScript/ScriptListEntry.h" +#include "sharedFoundation/Crc.h" +#include "sharedFoundation/NetworkId.h" +#include "sharedFoundation/Watcher.h" + +#include +#include + + +/*************************************************************************/ +// constants and typedefs +/*************************************************************************/ + +namespace boost +{ + template class shared_ptr; +} + +class CachedNetworkId; +class GameScriptObject; +class Object; +class Scheduler; +class ScriptDictionary; +class ScriptMessage; +class ScriptParams; +class ServerObject; +typedef boost::shared_ptr ScriptDictionaryPtr; + +struct ScriptData +{ + std::set owners; // who has this script attached + std::set functions; // functions available from this script +}; + +typedef std::vector ScriptList; + +typedef Unicode::String String_t; +typedef stdvector ::fwd StringVector_t; + +// values returned from script functions +enum +{ + SCRIPT_OVERRIDE = 0, + SCRIPT_CONTINUE = 1, + SCRIPT_DEFAULT = 2, + SCRIPT_INTERNAL_ERROR = 99 // internal scripting engine error +}; + +const size_t MAX_SCRIPT_NAME_LEN = 128; // including final '\0' + + +/*************************************************************************/ +// class GameScriptObject +/*************************************************************************/ + +class GameScriptObject +{ +public: + GameScriptObject(void); + ~GameScriptObject(); + + static GameScriptObject * asGameScriptObject(Object * object); + static GameScriptObject const * asGameScriptObject(Object const * object); + + void setOwner(ServerObject *owner); + const ServerObject * getOwner(void) const; + void setOwnerIsAuthoritative(bool authoritative, uint32 pid); + void setOwnerIsLoaded(void); + void setOwnerIsInitialized(void); + void setOwnerDestroyed(void); + + void alter(real time); + + // add this script object to an object's synchronization package. + void addToPackage(Archive::AutoDeltaByteStream &); + + // attachScript() adds a mutator script to the GameScriptObject with the given name, Return 1 if successful. 0 otherwise. + int attachScript(const std::string& scriptName, bool runTrigger); + + // detachScript() removes a mutator script to the GameScriptObject with the given name. Return 1 if successful, 0 otherwise. + int detachScript(const std::string& scriptName); + + void initScriptInstances (); + // removeAll() removes all mutator scripts from the obejct. + void removeAll(); + + // triggerAllScripts sends a trigger to the topmost mutator script. It will + // continue to send that trigger to each subsequent mutator script until one + // such trigger function returns 0. This function returns the value returned + // by the last trigger. This will tell the GameObject that invoked the trigger + // whether to run default behavior. + int trigAllScripts(const Scripting::TrigId trigId, ScriptParams ¶ms); + + int trigScriptFromConsole(const Scripting::TrigId trigId, const std::string &scriptName, const StringVector_t ¶ms) const; + + int callScriptCommandHandler(std::string const &funcName, ScriptParams ¶ms) const; + + int callScriptBuffHandler(std::string const &funcName, ScriptParams ¶ms) const; + + // hasScript() queries the object for the existance of a particular mutator script. + bool hasScript(const std::string& scriptName) const; + bool hasTrigger(const Scripting::TrigId trigId) const; + bool hasFunction(const std::string & funcName) const; + + size_t getScriptCount(void) const; + const ScriptList & getScripts(void) const; + bool isScriptListInitialized(void) const; + + // pack and unpack for the synchronized script list + void packScriptList(); + void unpackScriptList(); + + // call this function to create a copy of the scriptList used for debugging. + void enumerateScripts(std::vector &scriptNames) const; + + static void makeScriptDictionary(const ScriptParams & params, ScriptDictionaryPtr & dictionary); + bool handleMessage(const std::string &messageName, const ScriptDictionaryPtr & data); + bool handleMessage(const std::string &messageName, const stdvector::fwd & packedData); + + void onWatching(ServerObject & subject); + void onStopWatching(ServerObject & subject); + + static bool installScriptEngine(void); + static void removeScriptEngine(void); + static bool isScriptingEnabled(void); + static bool reloadScript(const std::string& scriptName); + static void pauseScripting(bool pause); + static bool isScriptingPaused(void); + static void enableLogging(bool enable); + static void enableNewJediTracking(bool enableTracking); + static int getScriptFreeMem(); + + static stdset::fwd & getScriptFunctions(const std::string & script); + static Scheduler & getScriptScheduler(); + static void runOneScript( + const std::string & scriptName, + const std::string & methodName, + const std::string & argTypes, + ScriptParams & args); + static std::string callScriptConsoleHandler( + const std::string & scriptName, + const std::string & methodName, + const std::string & argTypes, + ScriptParams & args); + + void setScriptVar(const std::string & name, int value); + void setScriptVar(const std::string & name, float value); + void setScriptVar(const std::string & name, const std::string & value); + + static void callSpaceMakeOvert(const NetworkId &player); + static void callSpaceClearOvert(const NetworkId &ship); + + static std::string callDumpTargetInfo( NetworkId &id ); + + static void packAllScriptVarDeltas(); + void clearScriptVars(); + void packScriptVars(stdvector::fwd & target) const; + void unpackScriptVars(const stdvector::fwd & data) const; + void unpackDeltaScriptVars(const stdvector::fwd & source) const; + + static ScriptListEntry getScriptListEntry(std::string const &scriptName); + + // trigOneScript() sends a trigger to a specific mutator script, thus not invoking the chain. + // TODO RAD: see if we can make this work off a ScriptListEntry or if we need to change our logic a bit + int trigOneScript(const std::string& scriptName, Scripting::TrigId trigId, ScriptParams ¶ms) const; + +private: + void addAvailableFunction(const std::string & funcName); + void removeAvailableFunction(const std::string & funcName); + +private: + struct SyncScriptListCallback + { + void modified (GameScriptObject & target, const std::string & oldValue, const std::string & newValue, bool isLocal) const; + }; + friend struct SyncScriptListCallback; + +private: + + ServerObject * m_owner; // the network object that controlls me + ScriptList m_scriptList; // list of scripts to execute + Archive::AutoDeltaVariableCallback m_synchronizedScriptList; // Packed script list to send on the network + bool m_scriptListInitialized; // flag that initScriptInstances() has been called + bool m_scriptListValid; // flag that the current script data is good; this is set true in initScriptInstances(), but will be cleared if the owner becomes non-authoritative + bool m_lockScriptList; // flag to disable manipulation of the script list + int m_attachingScript; // flag that we are attaching a script + + static bool m_pauseScripting; // flag to temporarily disable scriping calls + +private: + + typedef std::map ScriptDataMap; + static ScriptDataMap * ms_scriptDataMap; + +private: + GameScriptObject(const GameScriptObject &); +}; + +// ---------------------------------------------------------------------- + +inline void GameScriptObject::setOwner(ServerObject *owner) +{ + m_owner = owner; +} + +inline const ServerObject *GameScriptObject::getOwner(void) const +{ + return m_owner; +} + +inline size_t GameScriptObject::getScriptCount(void) const +{ + return m_scriptList.size(); +} + +inline const ScriptList & GameScriptObject::getScripts(void) const +{ + return m_scriptList; +} + +inline stdset::fwd & GameScriptObject::getScriptFunctions(const std::string & script) +{ + return (*ms_scriptDataMap)[script].functions; +} + +inline void GameScriptObject::pauseScripting(bool pause) +{ + m_pauseScripting = pause; +} + +inline bool GameScriptObject::isScriptingPaused(void) +{ + return m_pauseScripting; +} + +inline bool GameScriptObject::isScriptListInitialized(void) const +{ + return m_scriptListValid; +} + +// ====================================================================== + +namespace Archive +{ + void get(ReadIterator &source, ScriptListEntry &target); + void put(ByteStream &target, ScriptListEntry const &source); +} + +// ====================================================================== + +#endif // _INCLUDED_GameScriptObject_H + diff --git a/engine/server/library/serverScript/src/shared/JNIWrappers.cpp b/engine/server/library/serverScript/src/shared/JNIWrappers.cpp new file mode 100644 index 00000000..a6b55772 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/JNIWrappers.cpp @@ -0,0 +1,1076 @@ +//======================================================================== +// +// JNIWrappers.cpp - Classes and functions to wrap the JNI interface +// +// copyright 2004 Sony Online Entertainment +// +//======================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JNIWrappers.h" +#include "serverScript/JavaLibrary.h" +#include "sharedFoundation/Crc.h" + + +const LocalRefParamPtr LocalRefParam::cms_nullPtr(new LocalRefParam(static_cast(0))); +const LocalArrayRefParamPtr LocalArrayRefParam::cms_nullPtr(new LocalArrayRefParam(static_cast(0))); +const LocalObjectArrayRefParamPtr LocalObjectArrayRefParam::cms_nullPtr(new LocalObjectArrayRefParam(static_cast(0))); +const LocalRefPtr LocalRef::cms_nullPtr(new LocalRef(static_cast(0))); +const LocalArrayRefPtr LocalArrayRef::cms_nullPtr(new LocalArrayRef(static_cast(0))); +const LocalObjectArrayRefPtr LocalObjectArrayRef::cms_nullPtr(new LocalObjectArrayRef(static_cast(0))); +const LocalByteArrayRefPtr LocalByteArrayRef::cms_nullPtr(new LocalByteArrayRef(static_cast(0))); +const LocalIntArrayRefPtr LocalIntArrayRef::cms_nullPtr(new LocalIntArrayRef(static_cast(0))); +const LocalFloatArrayRefPtr LocalFloatArrayRef::cms_nullPtr(new LocalFloatArrayRef(static_cast(0))); +const LocalBooleanArrayRefPtr LocalBooleanArrayRef::cms_nullPtr(new LocalBooleanArrayRef(static_cast(0))); +const LocalLongArrayRefPtr LocalLongArrayRef::cms_nullPtr(new LocalLongArrayRef(static_cast(0))); +const GlobalRefPtr GlobalRef::cms_nullPtr(new GlobalRef(*LocalRefParam::cms_nullPtr)); +const GlobalArrayRefPtr GlobalArrayRef::cms_nullPtr(new GlobalArrayRef(*LocalObjectArrayRefParam::cms_nullPtr)); +const JavaStringParamPtr JavaStringParam::cms_nullPtr(new JavaStringParam(static_cast(0))); +const JavaStringPtr JavaString::cms_nullPtr(new JavaString(static_cast(0))); +const JavaDictionaryPtr JavaDictionary::cms_nullPtr(new JavaDictionary(static_cast(0))); + + +//======================================================================== + +namespace JNIWrappersNamespace +{ + +jboolean isInstanceOf(const LocalRefParam & object, jclass clazz) +{ + if (object.getValue() != 0) + return JavaLibrary::getEnv()->IsInstanceOf(object.getValue(), clazz); + return JNI_FALSE; +} + +//----------------------------------------------------------------------- + +jsize getArrayLength(const LocalArrayRefParam & array) +{ + if (array.getValue() != 0) + return JavaLibrary::getEnv()->GetArrayLength(array.getValue()); + return 0; +} + +//----------------------------------------------------------------------- + +jsize getStringLength(const JavaStringParam & string) +{ + if (string.getValue() != 0) + return JavaLibrary::getEnv()->GetStringLength(string.getValue()); + return 0; +} + +//----------------------------------------------------------------------- + +LocalRefPtr allocObject(jclass clazz) +{ + LocalRefPtr result(new LocalRef(JavaLibrary::getEnv()->AllocObject(clazz))); + if (result->getValue() == 0) + return LocalRef::cms_nullPtr; + return result; +} + +//----------------------------------------------------------------------- + +LocalRefPtr createNewObject(jclass clazz, jmethodID constructorID, ...) +{ + va_list marker; + va_start(marker, constructorID); + + LocalRefPtr result(new LocalRef(JavaLibrary::getEnv()->NewObjectV(clazz, constructorID, marker))); + if (result->getValue() == 0) + return LocalRef::cms_nullPtr; + return result; +} + +//----------------------------------------------------------------------- + +JavaStringPtr createNewString(const char * bytes) +{ + if (bytes != NULL) + { + JavaStringPtr result(new JavaString(JavaLibrary::getEnv()->NewStringUTF(bytes))); + if (result->getValue() != 0) + return result; + } + return JavaString::cms_nullPtr; +} + +//----------------------------------------------------------------------- + +JavaStringPtr createNewString(const jchar * unicodeChars, jsize len) +{ + if (unicodeChars != NULL && len >= 0) + { + JavaStringPtr result(new JavaString(JavaLibrary::getEnv()->NewString(unicodeChars, len))); + if (result->getValue() != 0) + return result; + } + return JavaString::cms_nullPtr; +} + +//----------------------------------------------------------------------- + +JavaDictionaryPtr createNewDictionary() +{ + JavaDictionaryPtr result(new JavaDictionary(JavaLibrary::getEnv()->NewObject(JavaLibrary::ms_clsDictionary, JavaLibrary::ms_midDictionary))); + if (result->getValue() != 0) + return result; + return JavaDictionary::cms_nullPtr; +} + +//----------------------------------------------------------------------- + +LocalObjectArrayRefPtr createNewObjectArray(jsize length, jclass clazz) +{ + LocalObjectArrayRefPtr result(new LocalObjectArrayRef(JavaLibrary::getEnv()->NewObjectArray(length, clazz, 0))); + if (result->getValue() == 0) + return LocalObjectArrayRef::cms_nullPtr; + return result; +} + +//----------------------------------------------------------------------- + +LocalByteArrayRefPtr createNewByteArray(jsize length) +{ + LocalByteArrayRefPtr result(new LocalByteArrayRef(JavaLibrary::getEnv()->NewByteArray(length))); + if (result->getValue() == 0) + return LocalByteArrayRef::cms_nullPtr; + return result; +} + +//----------------------------------------------------------------------- + +LocalIntArrayRefPtr createNewIntArray(jsize length) +{ + LocalIntArrayRefPtr result(new LocalIntArrayRef(JavaLibrary::getEnv()->NewIntArray(length))); + if (result->getValue() == 0) + return LocalIntArrayRef::cms_nullPtr; + return result; +} + +//----------------------------------------------------------------------- + +LocalFloatArrayRefPtr createNewFloatArray(jsize length) +{ + LocalFloatArrayRefPtr result(new LocalFloatArrayRef(JavaLibrary::getEnv()->NewFloatArray(length))); + if (result->getValue() == 0) + return LocalFloatArrayRef::cms_nullPtr; + return result; +} + +//----------------------------------------------------------------------- + +LocalBooleanArrayRefPtr createNewBooleanArray(jsize length) +{ + LocalBooleanArrayRefPtr result(new LocalBooleanArrayRef(JavaLibrary::getEnv()->NewBooleanArray(length))); + if (result->getValue() == 0) + return LocalBooleanArrayRef::cms_nullPtr; + return result; +} + +//----------------------------------------------------------------------- + +LocalLongArrayRefPtr createNewLongArray(jsize length) +{ + LocalLongArrayRefPtr result(new LocalLongArrayRef(JavaLibrary::getEnv()->NewLongArray(length))); + if (result->getValue() == 0) + return LocalLongArrayRef::cms_nullPtr; + return result; +} + +//----------------------------------------------------------------------- + +LocalRefPtr callObjectMethod(const LocalRefParam & object, jmethodID methodID, ...) +{ + if (object.getValue() != 0) + { + va_list marker; + va_start(marker, methodID); + + LocalRefPtr result(new LocalRef(JavaLibrary::getEnv()->CallObjectMethodV(object.getValue(), methodID, marker))); + if (result->getValue() != 0) + return result; + } + return LocalRef::cms_nullPtr; +} + +//----------------------------------------------------------------------- + +LocalObjectArrayRefPtr callObjectArrayMethod(const LocalRefParam & object, jmethodID methodID, ...) +{ + if (object.getValue() != 0) + { + va_list marker; + va_start(marker, methodID); + + LocalObjectArrayRefPtr result(new LocalObjectArrayRef(static_cast(JavaLibrary::getEnv()->CallObjectMethodV(object.getValue(), methodID, marker)))); + if (result->getValue() != 0) + return result; + } + return LocalObjectArrayRef::cms_nullPtr; +} + +//----------------------------------------------------------------------- + +LocalByteArrayRefPtr callByteArrayMethod(const LocalRefParam & object, jmethodID methodID, ...) +{ + if (object.getValue() != 0) + { + va_list marker; + va_start(marker, methodID); + + LocalByteArrayRefPtr result(new LocalByteArrayRef(static_cast(JavaLibrary::getEnv()->CallObjectMethodV(object.getValue(), methodID, marker)))); + if (result->getValue() != 0) + return result; + } + return LocalByteArrayRef::cms_nullPtr; +} + +//----------------------------------------------------------------------- + +jint callIntMethod(const LocalRefParam & object, jmethodID methodID, ...) +{ + if (object.getValue() != 0) + { + va_list marker; + va_start(marker, methodID); + + return JavaLibrary::getEnv()->CallIntMethodV(object.getValue(), methodID, marker); + } + return 0; +} + +//----------------------------------------------------------------------- + +jlong callLongMethod(const LocalRefParam & object, jmethodID methodID, ...) +{ + if (object.getValue() != 0) + { + va_list marker; + va_start(marker, methodID); + + return JavaLibrary::getEnv()->CallLongMethodV(object.getValue(), methodID, marker); + } + return 0; +} + +//----------------------------------------------------------------------- + +jfloat callFloatMethod(const LocalRefParam & object, jmethodID methodID, ...) +{ + if (object.getValue() != 0) + { + va_list marker; + va_start(marker, methodID); + + return JavaLibrary::getEnv()->CallFloatMethodV(object.getValue(), methodID, marker); + } + return 0; +} + +//----------------------------------------------------------------------- + +jboolean callBooleanMethod(const LocalRefParam & object, jmethodID methodID, ...) +{ + if (object.getValue() != 0) + { + va_list marker; + va_start(marker, methodID); + + return JavaLibrary::getEnv()->CallBooleanMethodV(object.getValue(), methodID, marker); + } + return JNI_FALSE; +} + +//----------------------------------------------------------------------- + +void callVoidMethod(const LocalRefParam & object, jmethodID methodID, ...) +{ + if (object.getValue() != 0) + { + va_list marker; + va_start(marker, methodID); + + JavaLibrary::getEnv()->CallVoidMethodV(object.getValue(), methodID, marker); + } +} + +//----------------------------------------------------------------------- + +jboolean callNonvirtualBooleanMethod(const LocalRefParam & object, jclass clazz, jmethodID methodID, ...) +{ + if (object.getValue() != 0) + { + va_list marker; + va_start(marker, methodID); + + return JavaLibrary::getEnv()->CallNonvirtualBooleanMethodV(object.getValue(), clazz, methodID, marker); + } + return JNI_FALSE; +} + +//----------------------------------------------------------------------- + +void callStaticVoidMethod(jclass clazz, jmethodID methodID, ...) +{ + va_list marker; + va_start(marker, methodID); + + JavaLibrary::getEnv()->CallStaticVoidMethodV(clazz, methodID, marker); +} + +//----------------------------------------------------------------------- + +LocalRefPtr callStaticObjectMethod(jclass clazz, jmethodID methodID, ...) +{ + va_list marker; + va_start(marker, methodID); + + LocalRefPtr result(new LocalRef(JavaLibrary::getEnv()->CallStaticObjectMethodV(clazz, methodID, marker))); + if (result->getValue() == 0) + return LocalRef::cms_nullPtr; + return result; +} + +//----------------------------------------------------------------------- + +LocalObjectArrayRefPtr callStaticObjectArrayMethod(jclass clazz, jmethodID methodID, ...) +{ + va_list marker; + va_start(marker, methodID); + + LocalObjectArrayRefPtr result(new LocalObjectArrayRef(static_cast(JavaLibrary::getEnv()->CallStaticObjectMethodV(clazz, methodID, marker)))); + if (result->getValue() == 0) + return LocalObjectArrayRef::cms_nullPtr; + return result; +} + +//----------------------------------------------------------------------- + +LocalByteArrayRefPtr callStaticByteArrayMethod(jclass clazz, jmethodID methodID, ...) +{ + va_list marker; + va_start(marker, methodID); + + LocalByteArrayRefPtr result(new LocalByteArrayRef(static_cast(JavaLibrary::getEnv()->CallStaticObjectMethodV(clazz, methodID, marker)))); + if (result->getValue() == 0) + return LocalByteArrayRef::cms_nullPtr; + return result; +} + +//----------------------------------------------------------------------- + +LocalRefPtr getObjectArrayElement(const LocalObjectArrayRefParam & array, int index) +{ + if (array.getValue() != 0 && index >= 0) + { + LocalRefPtr result(new LocalRef(JavaLibrary::getEnv()->GetObjectArrayElement(array.getValue(), static_cast(index)))); + if (result->getValue() != 0) + return result; + } + return LocalRef::cms_nullPtr; +} + +//----------------------------------------------------------------------- + +LocalRefPtr getObjectField(const LocalRefParam & object, jfieldID fieldID) +{ + if (object.getValue() != 0) + { + LocalRefPtr result(new LocalRef(JavaLibrary::getEnv()->GetObjectField(object.getValue(), fieldID))); + if (result->getValue() != 0) + return result; + } + return LocalRef::cms_nullPtr; +} +//----------------------------------------------------------------------- + +LocalObjectArrayRefPtr getArrayObjectField(const LocalRefParam & object, jfieldID fieldID) +{ + if (object.getValue() != 0) + { + LocalObjectArrayRefPtr result(new LocalObjectArrayRef(static_cast(JavaLibrary::getEnv()->GetObjectField(object.getValue(), fieldID)))); + if (result->getValue() != 0) + return result; + } + return LocalObjectArrayRef::cms_nullPtr; +} + +//----------------------------------------------------------------------- + +JavaStringPtr callStringMethod(const LocalRefParam & object, jmethodID methodID, ...) +{ + if (object.getValue() != 0) + { + va_list marker; + va_start(marker, methodID); + + jobject result = JavaLibrary::getEnv()->CallObjectMethodV(object.getValue(), methodID, marker); + if (result != 0) + { +#ifdef _DEBUG + if (!JavaLibrary::getEnv()->IsInstanceOf(result, JavaLibrary::ms_clsString)) + { + WARNING_STRICT_FATAL(true, ("JavaLibrary::callStringMethod called with non-string result")); + JavaLibrary::getEnv()->DeleteLocalRef(result); + return JavaString::cms_nullPtr; + } +#endif + return JavaStringPtr(new JavaString(static_cast(result))); + } + } + return JavaString::cms_nullPtr; +} + +//----------------------------------------------------------------------- + +JavaStringPtr callStaticStringMethod(jclass clazz, jmethodID methodID, ...) +{ + va_list marker; + va_start(marker, methodID); + + JavaStringPtr result(new JavaString(static_cast(JavaLibrary::getEnv()->CallStaticObjectMethodV(clazz, + methodID, marker)))); + if (result->getValue() != 0) + return result; + return JavaString::cms_nullPtr; +} + +//----------------------------------------------------------------------- + +JavaStringPtr getStringArrayElement(const LocalObjectArrayRefParam & array, int index) +{ + if (array.getValue() != 0 && index >= 0) + { + JavaStringPtr result(new JavaString(static_cast(JavaLibrary::getEnv()->GetObjectArrayElement(array.getValue(), + static_cast(index))))); + if (result->getValue() != 0) + return result; + } + return JavaString::cms_nullPtr; +} + +//----------------------------------------------------------------------- + +LocalArrayRefPtr getArrayArrayElement(const LocalObjectArrayRefParam & array, int index) +{ + if (array.getValue() != 0 && index >= 0) + { + LocalArrayRefPtr result(new LocalArrayRef(static_cast(JavaLibrary::getEnv()->GetObjectArrayElement(array.getValue(), + static_cast(index))))); + if (result->getValue() != 0) + return result; + } + return LocalArrayRef::cms_nullPtr; +} + +//----------------------------------------------------------------------- + +LocalObjectArrayRefPtr getObjectArrayArrayElement(const LocalObjectArrayRefParam & array, int index) +{ + if (array.getValue() != 0 && index >= 0) + { + LocalObjectArrayRefPtr result(new LocalObjectArrayRef(static_cast(JavaLibrary::getEnv()->GetObjectArrayElement(array.getValue(), + static_cast(index))))); + if (result->getValue() != 0) + return result; + } + return LocalObjectArrayRef::cms_nullPtr; +} + +//----------------------------------------------------------------------- + +LocalIntArrayRefPtr getIntArrayArrayElement(const LocalObjectArrayRefParam & array, int index) +{ + if (array.getValue() != 0 && index >= 0) + { + LocalIntArrayRefPtr result(new LocalIntArrayRef(static_cast(JavaLibrary::getEnv()->GetObjectArrayElement(array.getValue(), + static_cast(index))))); + if (result->getValue() != 0) + return result; + } + return LocalIntArrayRef::cms_nullPtr; +} + +//----------------------------------------------------------------------- + +LocalFloatArrayRefPtr getFloatArrayArrayElement(const LocalObjectArrayRefParam & array, int index) +{ + if (array.getValue() != 0 && index >= 0) + { + LocalFloatArrayRefPtr result(new LocalFloatArrayRef(static_cast(JavaLibrary::getEnv()->GetObjectArrayElement(array.getValue(), + static_cast(index))))); + if (result->getValue() != 0) + return result; + } + return LocalFloatArrayRef::cms_nullPtr; +} + +//----------------------------------------------------------------------- + +JavaStringPtr getStringField(const LocalRefParam & object, jfieldID fieldID) +{ + if (object.getValue() != 0) + { + JavaStringPtr result(new JavaString(static_cast(JavaLibrary::getEnv()->GetObjectField(object.getValue(), fieldID)))); + if (result->getValue() != 0) + return result; + } + return JavaString::cms_nullPtr; +} + +//----------------------------------------------------------------------- + +void setObjectArrayElement(const LocalObjectArrayRefParam & array, jsize index, const LocalRefParam & value) +{ + if (array.getValue() != 0 && index >= 0) + { +#ifdef _DEBUG + if (index >= JavaLibrary::getEnv()->GetArrayLength(array.getValue())) + { + WARNING(true, ("JavaLibrary::setObjectArrayElement array index %d " + "out of bounds", static_cast(index))); + return; + } +#endif + JavaLibrary::getEnv()->SetObjectArrayElement(array.getValue(), index, value.getValue()); + } +} + +//----------------------------------------------------------------------- + +void setObjectField(const LocalRefParam & object, jfieldID fieldID, const LocalRefParam & value) +{ + if (object.getValue() != 0) + { + JavaLibrary::getEnv()->SetObjectField(object.getValue(), fieldID, value.getValue()); + } +} + +//----------------------------------------------------------------------- + +jint getIntField(const LocalRefParam & object, jfieldID fieldID) +{ + if (object.getValue() != 0) + { + return JavaLibrary::getEnv()->GetIntField(object.getValue(), fieldID); + } + return 0; +} + +//----------------------------------------------------------------------- + +jfloat getFloatField(const LocalRefParam & object, jfieldID fieldID) +{ + if (object.getValue() != 0) + { + return JavaLibrary::getEnv()->GetFloatField(object.getValue(), fieldID); + } + return 0; +} + +//----------------------------------------------------------------------- + +jboolean getBooleanField(const LocalRefParam & object, jfieldID fieldID) +{ + if (object.getValue() != 0) + { + return JavaLibrary::getEnv()->GetBooleanField(object.getValue(), fieldID); + } + return false; +} + +//----------------------------------------------------------------------- + +void setIntField(const LocalRefParam & object, jfieldID fieldID, jint value) +{ + if (object.getValue() != 0) + { + JavaLibrary::getEnv()->SetIntField(object.getValue(), fieldID, value); + } +} + +//----------------------------------------------------------------------- + +void setFloatField(const LocalRefParam & object, jfieldID fieldID, jfloat value) +{ + if (object.getValue() != 0) + { + JavaLibrary::getEnv()->SetFloatField(object.getValue(), fieldID, value); + } +} + +//----------------------------------------------------------------------- + +void setBooleanField(const LocalRefParam & object, jfieldID fieldID, jboolean value) +{ + if (object.getValue() != 0) + { + JavaLibrary::getEnv()->SetBooleanField(object.getValue(), fieldID, value); + } +} + +//----------------------------------------------------------------------- + +void getByteArrayRegion(const LocalByteArrayRef & array, jsize start, jsize length, jbyte * buf) +{ + if (array.getValue() != 0) + { + JavaLibrary::getEnv()->GetByteArrayRegion(array.getValue(), start, length, buf); + } +} + +//----------------------------------------------------------------------- + +void getIntArrayRegion(const LocalIntArrayRef & array, jsize start, jsize length, jint * buf) +{ + if (array.getValue() != 0) + { + JavaLibrary::getEnv()->GetIntArrayRegion(array.getValue(), start, length, buf); + } +} + +//----------------------------------------------------------------------- + +void getFloatArrayRegion(const LocalFloatArrayRef & array, jsize start, jsize length, jfloat * buf) +{ + if (array.getValue() != 0) + { + JavaLibrary::getEnv()->GetFloatArrayRegion(array.getValue(), start, length, buf); + } +} + +//----------------------------------------------------------------------- + +void getBooleanArrayRegion(const LocalBooleanArrayRef & array, jsize start, jsize length, jboolean * buf) +{ + if (array.getValue() != 0) + { + JavaLibrary::getEnv()->GetBooleanArrayRegion(array.getValue(), start, length, buf); + } +} + +//----------------------------------------------------------------------- + +void getLongArrayRegion(const LocalLongArrayRef & array, jsize start, jsize length, jlong * buf) +{ + if (array.getValue() != 0) + { + JavaLibrary::getEnv()->GetLongArrayRegion(array.getValue(), start, length, buf); + } +} + +//----------------------------------------------------------------------- + +void setByteArrayRegion(const LocalByteArrayRef & array, jsize start, jsize length, jbyte * buf) +{ + if (array.getValue() != 0) + { + JavaLibrary::getEnv()->SetByteArrayRegion(array.getValue(), start, length, buf); + } +} + +//----------------------------------------------------------------------- + +void setIntArrayRegion(const LocalIntArrayRef & array, jsize start, jsize length, jint * buf) +{ + if (array.getValue() != 0) + { + JavaLibrary::getEnv()->SetIntArrayRegion(array.getValue(), start, length, buf); + } +} + +//----------------------------------------------------------------------- + +void setFloatArrayRegion(const LocalFloatArrayRef & array, jsize start, jsize length, jfloat * buf) +{ + if (array.getValue() != 0) + { + JavaLibrary::getEnv()->SetFloatArrayRegion(array.getValue(), start, length, buf); + } +} + +//----------------------------------------------------------------------- + +void setBooleanArrayRegion(const LocalBooleanArrayRef & array, jsize start, jsize length, jboolean * buf) +{ + if (array.getValue() != 0) + { + JavaLibrary::getEnv()->SetBooleanArrayRegion(array.getValue(), start, length, buf); + } +} + +//----------------------------------------------------------------------- + +void setLongArrayRegion(const LocalLongArrayRef & array, jsize start, jsize length, jlong * buf) +{ + if (array.getValue() != 0) + { + JavaLibrary::getEnv()->SetLongArrayRegion(array.getValue(), start, length, buf); + } +} + +//----------------------------------------------------------------------- + +/** + * Converts a Java array of strings to a vector of const char *. NOTE: The caller is + * responsible for freeing the returned strings. + */ +void getStringArray(const LocalObjectArrayRefParam & array, std::vector & strings) +{ + jsize count = getArrayLength(array); + strings.resize(count, 0); + + jstring stringElement; + jsize stringLength; + jsize bufferLength; + char * newString; + + JNIEnv * env = JavaLibrary::getEnv(); + jobjectArray arrayRef = array.getValue(); + std::vector::iterator stringsIter = strings.begin(); + for (jsize i = 0; i < count; ++i, ++stringsIter) + { + if (*stringsIter != 0) + delete[] const_cast(*stringsIter); + + newString = 0; + stringElement = static_cast(env->GetObjectArrayElement(arrayRef, i)); + if (stringElement != 0) + { + stringLength = env->GetStringLength(stringElement); + bufferLength = env->GetStringUTFLength(stringElement); + newString = new char[bufferLength+1]; + newString[bufferLength] = 0; + env->GetStringUTFRegion(stringElement, 0, stringLength, newString); + env->DeleteLocalRef(stringElement); + } + *stringsIter = newString; + } +} + +//----------------------------------------------------------------------- + +/** + * Converts a Java array of strings to a vector of const Unicode::String *. NOTE: + * The caller is responsible for freeing the returned strings. + */ +void getStringArray(const LocalObjectArrayRefParam & array, std::vector & strings) +{ + jsize count = getArrayLength(array); + strings.resize(count, 0); + + jsize stringLength; + jstring stringElement; + const jchar * newString; + + JNIEnv * env = JavaLibrary::getEnv(); + jobjectArray arrayRef = array.getValue(); + std::vector::iterator stringsIter = strings.begin(); + for (jsize i = 0; i < count; ++i, ++stringsIter) + { + if (*stringsIter != 0) + delete *stringsIter; + + stringElement = static_cast(env->GetObjectArrayElement(arrayRef, i)); + if (stringElement != 0) + { + stringLength = env->GetStringLength(stringElement); + newString = env->GetStringCritical(stringElement, 0); + *stringsIter = new Unicode::String(newString, stringLength); + env->ReleaseStringCritical(stringElement, newString); + env->DeleteLocalRef(stringElement); + } + else + *stringsIter = 0; + } +} + + +//----------------------------------------------------------------------- + +} // namespace JNIWrappersNamespace + + +//======================================================================== + +LocalRefParam::LocalRefParam(jobject src) : + m_ref(src) +{ +} + +LocalRefParam::~LocalRefParam() +{ +} + +jobject LocalRefParam::getReturnValue(void) +{ + jobject return_val = m_ref; + m_ref = 0; + return return_val; +} + +/** + * Only call this function if you really know what you're doing! Memory leaks + * may result! + */ +void LocalRefParam::emergencyClear() +{ + m_ref = 0; +} + + +//======================================================================== + +LocalArrayRefParam::LocalArrayRefParam(jarray src) : + LocalRefParam(src) +{ +} + +LocalArrayRefParam::~LocalArrayRefParam() +{ +} + + +//======================================================================== + +LocalObjectArrayRefParam::LocalObjectArrayRefParam(jobjectArray src) : + LocalArrayRefParam(src) +{ +} + +LocalObjectArrayRefParam::~LocalObjectArrayRefParam() +{ +} + + +//======================================================================== + +LocalRef::LocalRef(jobject src) : + LocalRefParam(src) +{ +} + +LocalRef::~LocalRef() +{ + if (m_ref != 0 && JavaLibrary::getEnv() != NULL) + JavaLibrary::getEnv()->DeleteLocalRef(m_ref); + m_ref = 0; +} + + +//======================================================================== + +LocalArrayRef::LocalArrayRef(jarray src) : + LocalArrayRefParam(src) +{ +} + +LocalArrayRef::~LocalArrayRef() +{ + if (m_ref != 0 && JavaLibrary::getEnv() != NULL) + JavaLibrary::getEnv()->DeleteLocalRef(m_ref); + m_ref = 0; +} + + +//======================================================================== + +LocalObjectArrayRef::LocalObjectArrayRef(jobjectArray src) : + LocalObjectArrayRefParam(src) +{ +} + +LocalObjectArrayRef::~LocalObjectArrayRef() +{ + if (m_ref != 0 && JavaLibrary::getEnv() != NULL) + JavaLibrary::getEnv()->DeleteLocalRef(m_ref); + m_ref = 0; +} + + +//======================================================================== + +LocalByteArrayRef::LocalByteArrayRef(jbyteArray src) : + LocalArrayRef(src) +{ +} + +LocalByteArrayRef::~LocalByteArrayRef() +{ +} + + +//======================================================================== + +LocalIntArrayRef::LocalIntArrayRef(jintArray src) : + LocalArrayRef(src) +{ +} + +LocalIntArrayRef::~LocalIntArrayRef() +{ +} + +//======================================================================== + +LocalFloatArrayRef::LocalFloatArrayRef(jfloatArray src) : + LocalArrayRef(src) +{ +} + +LocalFloatArrayRef::~LocalFloatArrayRef() +{ +} + + +//======================================================================== + +LocalBooleanArrayRef::LocalBooleanArrayRef(jbooleanArray src) : + LocalArrayRef(src) +{ +} + +LocalBooleanArrayRef::~LocalBooleanArrayRef() +{ +} + + +//======================================================================== + +LocalLongArrayRef::LocalLongArrayRef(jlongArray src) : + LocalArrayRef(src) +{ +} + +LocalLongArrayRef::~LocalLongArrayRef() +{ +} + + +//======================================================================== + +GlobalRef::GlobalRef(const LocalRefParam & src) : + LocalRefParam(static_cast(0)) +{ + if (src.getValue() != 0 && JavaLibrary::getEnv() != NULL) + m_ref = JavaLibrary::getEnv()->NewGlobalRef(src.getValue()); +} + +GlobalRef::~GlobalRef() +{ + if (m_ref != 0 && JavaLibrary::getEnv() != NULL) + JavaLibrary::getEnv()->DeleteGlobalRef(m_ref); + m_ref = 0; +} + + +//======================================================================== + +GlobalArrayRef::GlobalArrayRef(const LocalObjectArrayRefParam & src) : + LocalObjectArrayRefParam(static_cast(0)) +{ + if (src.getValue() != 0 && JavaLibrary::getEnv() != NULL) + m_ref = JavaLibrary::getEnv()->NewGlobalRef(src.getValue()); +} + +GlobalArrayRef::~GlobalArrayRef() +{ + if (m_ref != 0 && JavaLibrary::getEnv() != NULL) + JavaLibrary::getEnv()->DeleteGlobalRef(m_ref); + m_ref = 0; +} + +//======================================================================== + +JavaStringParam::JavaStringParam(jstring src) : + LocalRefParam(src) +{ +} + +JavaStringParam::JavaStringParam(const LocalRefParam & src) : + LocalRefParam(src.getValue()) +{ +} + +JavaStringParam::~JavaStringParam() +{ +} + +int JavaStringParam::fillBuffer(char * buffer, int size) const +{ + if (m_ref != 0 && buffer != NULL && JavaLibrary::getEnv() != NULL) + { + // Get the number of storage bytes required to convert this Java string into a UTF-8 string. + // Include the terminating null byte in the required buffer size. + int requiredBufferSize = JavaLibrary::getEnv()->GetStringUTFLength(static_cast(m_ref)) + 1; + if (requiredBufferSize <= size) + { + int stringLength = JavaLibrary::getEnv()->GetStringLength(static_cast(m_ref)); + + JavaLibrary::getEnv()->GetStringUTFRegion(static_cast(m_ref), 0, stringLength, buffer); + + // Null terminate the string. requiredBufferSize already includes the byte count for the null terminator. + buffer[requiredBufferSize - 1] = '\0'; + + return requiredBufferSize; + } + } + return 0; +} + + +//======================================================================== + +JavaString::JavaString(jstring src) : + JavaStringParam(src) +{ +} + +JavaString::JavaString(const char * src) : + JavaStringParam(JavaLibrary::getEnv()->NewStringUTF(src != NULL ? src : "")) +{ +} + +JavaString::JavaString(const std::string & src) : + JavaStringParam(JavaLibrary::getEnv()->NewStringUTF(src.c_str())) +{ +} + +JavaString::JavaString(const Unicode::String & src) : + JavaStringParam(JavaLibrary::getEnv()->NewString(src.data(), src.size())) +{ +} + +JavaString::~JavaString() +{ + if (m_ref != 0 && JavaLibrary::getEnv() != NULL) + JavaLibrary::getEnv()->DeleteLocalRef(m_ref); + m_ref = 0; +} + + +//======================================================================== + +JavaDictionary::JavaDictionary(jobject src) : + LocalRef(src) +{ +} + +JavaDictionary::~JavaDictionary() +{ +} + +/** + * Converts the data in a JavaDictionary to a string. + */ +void JavaDictionary::serialize(void) +{ + JavaLibrary::convert(*this, m_serializedData); + if (!m_serializedData.empty()) + m_crc = Crc::calculate(&m_serializedData[0], m_serializedData.size()); + else + m_crc = 0; +} + diff --git a/engine/server/library/serverScript/src/shared/JNIWrappers.h b/engine/server/library/serverScript/src/shared/JNIWrappers.h new file mode 100644 index 00000000..b664ccd2 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/JNIWrappers.h @@ -0,0 +1,615 @@ +//======================================================================== +// +// JNIWrappers.h - Classes and functions to wrap the JNI interface +// +// copyright 2004 Sony Online Entertainment +// +//======================================================================== + +#ifndef _INCLUDED_JNIWrappers_H +#define _INCLUDED_JNIWrappers_H + +#include +#include "serverScript/ScriptDictionary.h" + +namespace boost +{ + template class shared_ptr; +} + +class LocalRefParam; +class LocalArrayRefParam; +class LocalObjectArrayRefParam; +class LocalRef; +class LocalArrayRef; +class LocalObjectArrayRef; +class LocalByteArrayRef; +class LocalIntArrayRef; +class LocalFloatArrayRef; +class LocalBooleanArrayRef; +class LocalLongArrayRef; +class GlobalRef; +class GlobalArrayRef; +class JavaStringParam; +class JavaString; +class JavaDictionary; +typedef boost::shared_ptr LocalRefParamPtr; +typedef boost::shared_ptr LocalArrayRefParamPtr; +typedef boost::shared_ptr LocalObjectArrayRefParamPtr; +typedef boost::shared_ptr LocalRefPtr; +typedef boost::shared_ptr LocalArrayRefPtr; +typedef boost::shared_ptr LocalObjectArrayRefPtr; +typedef boost::shared_ptr LocalByteArrayRefPtr; +typedef boost::shared_ptr LocalIntArrayRefPtr; +typedef boost::shared_ptr LocalFloatArrayRefPtr; +typedef boost::shared_ptr LocalBooleanArrayRefPtr; +typedef boost::shared_ptr LocalLongArrayRefPtr; +typedef boost::shared_ptr GlobalRefPtr; +typedef boost::shared_ptr GlobalArrayRefPtr; +typedef boost::shared_ptr JavaStringParamPtr; +typedef boost::shared_ptr JavaStringPtr; +typedef boost::shared_ptr JavaDictionaryPtr; + + +//======================================================================== + +namespace JNIWrappersNamespace +{ +jboolean isInstanceOf(const LocalRefParam & object, jclass clazz); +jsize getArrayLength(const LocalArrayRefParam & array); +jsize getStringLength(const JavaStringParam & string); +LocalRefPtr allocObject(jclass clazz); +LocalRefPtr createNewObject(jclass clazz, jmethodID constructorID, ...); +JavaStringPtr createNewString(const char * bytes); +JavaStringPtr createNewString(const jchar * unicodeChars, jsize len); +JavaDictionaryPtr createNewDictionary(); +LocalObjectArrayRefPtr createNewObjectArray(jsize length, jclass clazz); +LocalByteArrayRefPtr createNewByteArray(jsize length); +LocalIntArrayRefPtr createNewIntArray(jsize length); +LocalFloatArrayRefPtr createNewFloatArray(jsize length); +LocalBooleanArrayRefPtr createNewBooleanArray(jsize length); +LocalLongArrayRefPtr createNewLongArray(jsize length); +LocalRefPtr callObjectMethod(const LocalRefParam & object, jmethodID methodID, ...); +LocalObjectArrayRefPtr callObjectArrayMethod(const LocalRefParam & object, jmethodID methodID, ...); +LocalByteArrayRefPtr callByteArrayMethod(const LocalRefParam & object, jmethodID methodID, ...); +jint callIntMethod(const LocalRefParam & object, jmethodID methodID, ...); +jlong callLongMethod(const LocalRefParam & object, jmethodID methodID, ...); +jfloat callFloatMethod(const LocalRefParam & object, jmethodID methodID, ...); +jboolean callBooleanMethod(const LocalRefParam & object, jmethodID methodID, ...); +void callVoidMethod(const LocalRefParam & object, jmethodID methodID, ...); +jboolean callNonvirtualBooleanMethod(const LocalRefParam & object, jclass clazz, jmethodID methodID, ...); +void callStaticVoidMethod(jclass clazz, jmethodID methodID, ...); +LocalRefPtr callStaticObjectMethod(jclass clazz, jmethodID methodID, ...); +LocalObjectArrayRefPtr callStaticObjectArrayMethod(jclass clazz, jmethodID methodID, ...); +LocalByteArrayRefPtr callStaticByteArrayMethod(jclass clazz, jmethodID methodID, ...); +JavaStringPtr callStringMethod(const LocalRefParam & object, jmethodID methodID, ...); +JavaStringPtr callStaticStringMethod(jclass clazz, jmethodID methodID, ...); +LocalRefPtr getObjectArrayElement(const LocalObjectArrayRefParam & array, int index); +JavaStringPtr getStringArrayElement(const LocalObjectArrayRefParam & array, int index); +LocalArrayRefPtr getArrayArrayElement(const LocalObjectArrayRefParam & array, int index); +LocalObjectArrayRefPtr getObjectArrayArrayElement(const LocalObjectArrayRefParam & array, int index); +LocalIntArrayRefPtr getIntArrayArrayElement(const LocalObjectArrayRefParam & array, int index); +LocalFloatArrayRefPtr getFloatArrayArrayElement(const LocalObjectArrayRefParam & array, int index); +LocalRefPtr getObjectField(const LocalRefParam & object, jfieldID fieldID); +LocalObjectArrayRefPtr getArrayObjectField(const LocalRefParam & object, jfieldID fieldID); +JavaStringPtr getStringField(const LocalRefParam & object, jfieldID fieldID); +void setObjectArrayElement(const LocalObjectArrayRefParam & array, jsize index, const LocalRefParam & value); +void setObjectField(const LocalRefParam & object, jfieldID fieldID, const LocalRefParam & value); +jint getIntField(const LocalRefParam & object, jfieldID fieldID); +jfloat getFloatField(const LocalRefParam & object, jfieldID fieldID); +jboolean getBooleanField(const LocalRefParam & object, jfieldID fieldID); +void setIntField(const LocalRefParam & object, jfieldID fieldID, jint value); +void setFloatField(const LocalRefParam & object, jfieldID fieldID, jfloat value); +void setBooleanField(const LocalRefParam & object, jfieldID fieldID, jboolean value); +void getByteArrayRegion(const LocalByteArrayRef & array, jsize start, jsize length, jbyte * buf); +void getIntArrayRegion(const LocalIntArrayRef & array, jsize start, jsize length, jint * buf); +void getFloatArrayRegion(const LocalFloatArrayRef & array, jsize start, jsize length, jfloat * buf); +void getBooleanArrayRegion(const LocalBooleanArrayRef & array, jsize start, jsize length, jboolean * buf); +void getLongArrayRegion(const LocalLongArrayRef & array, jsize start, jsize length, jlong * buf); +void setByteArrayRegion(const LocalByteArrayRef & array, jsize start, jsize length, jbyte * buf); +void setIntArrayRegion(const LocalIntArrayRef & array, jsize start, jsize length, jint * buf); +void setFloatArrayRegion(const LocalFloatArrayRef & array, jsize start, jsize length, jfloat * buf); +void setBooleanArrayRegion(const LocalBooleanArrayRef & array, jsize start, jsize length, jboolean * buf); +void setLongArrayRegion(const LocalLongArrayRef & array, jsize start, jsize length, jlong * buf); + +// these functions don't match a JNI function, but are useful for optimization reasons +void getStringArray(const LocalObjectArrayRefParam & array, std::vector & strings); +void getStringArray(const LocalObjectArrayRefParam & array, std::vector & strings); +} + + +//======================================================================== + +/** + * Wraps a jobject passed into a JNI callback function from Java. + */ +class LocalRefParam +{ +public: + static const LocalRefParamPtr cms_nullPtr; + +public: + explicit LocalRefParam(jobject src); + virtual ~LocalRefParam(); + + // getValue should be used when passing the wrapped object to a JNI function + jobject getValue(void) const; + // getReturnValue should be used when returning the wrapped object from a + // JNICALL function back to Java + jobject getReturnValue(void); + + void emergencyClear(); + +protected: + jobject m_ref; + +private: + LocalRefParam(); + LocalRefParam(const LocalRefParam &); +}; + +// ---------------------------------------------------------------------- + +inline jobject LocalRefParam::getValue(void) const +{ + return m_ref; +} + + +//======================================================================== + +/** + * Wraps a jarray passed into a JNI callback function from Java. + */ +class LocalArrayRefParam : public LocalRefParam +{ +public: + static const LocalArrayRefParamPtr cms_nullPtr; + +public: + explicit LocalArrayRefParam(jarray src); + virtual ~LocalArrayRefParam(); + + // getValue should be used when passing the wrapped object to a JNI function + jarray getValue(void) const; + // getReturnValue should be used when returning the wrapped object from a + // JNICALL function back to Java + jarray getReturnValue(void); + +private: + LocalArrayRefParam(); + LocalArrayRefParam(const LocalArrayRefParam &); +}; + +// ---------------------------------------------------------------------- + +inline jarray LocalArrayRefParam::getValue(void) const +{ + return static_cast(LocalRefParam::getValue()); +} + +inline jarray LocalArrayRefParam::getReturnValue(void) +{ + return static_cast(LocalRefParam::getReturnValue()); +} + + +//======================================================================== + +/** + * Wraps a jobjectArray passed into a JNI callback function from Java. + */ +class LocalObjectArrayRefParam : public LocalArrayRefParam +{ +public: + static const LocalObjectArrayRefParamPtr cms_nullPtr; + +public: + explicit LocalObjectArrayRefParam(jobjectArray src); + virtual ~LocalObjectArrayRefParam(); + + // getValue should be used when passing the wrapped object to a JNI function + jobjectArray getValue(void) const; + // getReturnValue should be used when returning the wrapped object from a + // JNICALL function back to Java + jobjectArray getReturnValue(void); + +private: + LocalObjectArrayRefParam(); + LocalObjectArrayRefParam(const LocalObjectArrayRefParam &); +}; + +// ---------------------------------------------------------------------- + +inline jobjectArray LocalObjectArrayRefParam::getValue(void) const +{ + return static_cast(LocalArrayRefParam::getValue()); +} + +inline jobjectArray LocalObjectArrayRefParam::getReturnValue(void) +{ + return static_cast(LocalArrayRefParam::getReturnValue()); +} + +//======================================================================== + +/** + * Wraps a jobject created/returned by a JNI function. + */ +class LocalRef : public LocalRefParam +{ +public: + static const LocalRefPtr cms_nullPtr; + +public: + explicit LocalRef(jobject src); + virtual ~LocalRef(); + +private: + LocalRef(); + LocalRef(const LocalRef &); +}; + + +//======================================================================== + +/** + * Wraps a jarray created/returned by a JNI function. + */ +class LocalArrayRef : public LocalArrayRefParam +{ +public: + static const LocalArrayRefPtr cms_nullPtr; + +public: + explicit LocalArrayRef(jarray src); + virtual ~LocalArrayRef(); + +private: + LocalArrayRef(); + LocalArrayRef(const LocalArrayRef &); +}; + + +//======================================================================== + +/** + * Wraps a jobjectArray created/returned by a JNI function. + */ +class LocalObjectArrayRef : public LocalObjectArrayRefParam +{ +public: + static const LocalObjectArrayRefPtr cms_nullPtr; + +public: + explicit LocalObjectArrayRef(jobjectArray src); + virtual ~LocalObjectArrayRef(); + +private: + LocalObjectArrayRef(); + LocalObjectArrayRef(const LocalObjectArrayRef &); +}; + + +//======================================================================== + +/** + * Wraps a jbyteArray created/returned by a JNI function. + */ +class LocalByteArrayRef : public LocalArrayRef +{ +public: + static const LocalByteArrayRefPtr cms_nullPtr; + +public: + explicit LocalByteArrayRef(jbyteArray src); + virtual ~LocalByteArrayRef(); + + // getValue should be used when passing the wrapped object to a JNI function + jbyteArray getValue(void) const; + // getReturnValue should be used when returning the wrapped object from a + // JNICALL function back to Java + jbyteArray getReturnValue(void); + +private: + LocalByteArrayRef(); + LocalByteArrayRef(const LocalByteArrayRef &); +}; + +// ---------------------------------------------------------------------- + +inline jbyteArray LocalByteArrayRef::getValue(void) const +{ + return static_cast(LocalArrayRef::getValue()); +} + +inline jbyteArray LocalByteArrayRef::getReturnValue(void) +{ + return static_cast(LocalArrayRef::getReturnValue()); +} + + +//======================================================================== + +/** + * Wraps a jintArray created/returned by a JNI function. + */ +class LocalIntArrayRef : public LocalArrayRef +{ +public: + static const LocalIntArrayRefPtr cms_nullPtr; + +public: + explicit LocalIntArrayRef(jintArray src); + virtual ~LocalIntArrayRef(); + + // getValue should be used when passing the wrapped object to a JNI function + jintArray getValue(void) const; + // getReturnValue should be used when returning the wrapped object from a + // JNICALL function back to Java + jintArray getReturnValue(void); + +private: + LocalIntArrayRef(); + LocalIntArrayRef(const LocalIntArrayRef &); +}; + +// ---------------------------------------------------------------------- + +inline jintArray LocalIntArrayRef::getValue(void) const +{ + return static_cast(LocalArrayRef::getValue()); +} + +inline jintArray LocalIntArrayRef::getReturnValue(void) +{ + return static_cast(LocalArrayRef::getReturnValue()); +} + + +//======================================================================== + +/** + * Wraps a jfloatArray created/returned by a JNI function. + */ +class LocalFloatArrayRef : public LocalArrayRef +{ +public: + static const LocalFloatArrayRefPtr cms_nullPtr; + +public: + explicit LocalFloatArrayRef(jfloatArray src); + virtual ~LocalFloatArrayRef(); + + // getValue should be used when passing the wrapped object to a JNI function + jfloatArray getValue(void) const; + // getReturnValue should be used when returning the wrapped object from a + // JNICALL function back to Java + jfloatArray getReturnValue(void); + +private: + LocalFloatArrayRef(); + LocalFloatArrayRef(const LocalFloatArrayRef &); +}; + +// ---------------------------------------------------------------------- + +inline jfloatArray LocalFloatArrayRef::getValue(void) const +{ + return static_cast(LocalArrayRef::getValue()); +} + +inline jfloatArray LocalFloatArrayRef::getReturnValue(void) +{ + return static_cast(LocalArrayRef::getReturnValue()); +} + + +//======================================================================== + +/** + * Wraps a jbooleanArray created/returned by a JNI function. + */ +class LocalBooleanArrayRef : public LocalArrayRef +{ +public: + static const LocalBooleanArrayRefPtr cms_nullPtr; + +public: + explicit LocalBooleanArrayRef(jbooleanArray src); + virtual ~LocalBooleanArrayRef(); + + // getValue should be used when passing the wrapped object to a JNI function + jbooleanArray getValue(void) const; + // getReturnValue should be used when returning the wrapped object from a + // JNICALL function back to Java + jbooleanArray getReturnValue(void); + +private: + LocalBooleanArrayRef(); + LocalBooleanArrayRef(const LocalBooleanArrayRef &); +}; + +// ---------------------------------------------------------------------- + +inline jbooleanArray LocalBooleanArrayRef::getValue(void) const +{ + return static_cast(LocalArrayRef::getValue()); +} + +inline jbooleanArray LocalBooleanArrayRef::getReturnValue(void) +{ + return static_cast(LocalArrayRef::getReturnValue()); +} + + +//======================================================================== + +/** + * Wraps a jlongArray created/returned by a JNI function. + */ +class LocalLongArrayRef : public LocalArrayRef +{ +public: + static const LocalLongArrayRefPtr cms_nullPtr; + +public: + explicit LocalLongArrayRef(jlongArray src); + virtual ~LocalLongArrayRef(); + + // getValue should be used when passing the wrapped object to a JNI function + jlongArray getValue(void) const; + // getReturnValue should be used when returning the wrapped object from a + // JNICALL function back to Java + jlongArray getReturnValue(void); + +private: + LocalLongArrayRef(); + LocalLongArrayRef(const LocalLongArrayRef &); +}; + +// ---------------------------------------------------------------------- + +inline jlongArray LocalLongArrayRef::getValue(void) const +{ + return static_cast(LocalArrayRef::getValue()); +} + +inline jlongArray LocalLongArrayRef::getReturnValue(void) +{ + return static_cast(LocalArrayRef::getReturnValue()); +} + + +//======================================================================== + +/** + * Creates a global reference from a local reference. + */ +class GlobalRef : public LocalRefParam +{ +public: + static const GlobalRefPtr cms_nullPtr; + +public: + explicit GlobalRef(const LocalRefParam & src); + virtual ~GlobalRef(); + +private: + GlobalRef(); + GlobalRef(const GlobalRef & src); +}; + + +//======================================================================== + +/** + * Creates a global array reference from a local array reference. + */ +class GlobalArrayRef : public LocalObjectArrayRefParam +{ +public: + static const GlobalArrayRefPtr cms_nullPtr; + +public: + explicit GlobalArrayRef(const LocalObjectArrayRefParam & src); + virtual ~GlobalArrayRef(); + +private: + GlobalArrayRef(); + GlobalArrayRef(const GlobalArrayRef &); +}; + + +//======================================================================== + +/** + * Wraps a jstring passed into a JNI callback function from Java. + */ +class JavaStringParam : public LocalRefParam +{ +public: + static const JavaStringParamPtr cms_nullPtr; + +public: + explicit JavaStringParam(jstring src); + explicit JavaStringParam(const LocalRefParam & src); + virtual ~JavaStringParam(); + + // getValue should be used when passing the wrapped object to a JNI function + jstring getValue(void) const; + // getReturnValue should be used when returning the wrapped object from a + // JNICALL function back to Java + jstring getReturnValue(void); + + int fillBuffer(char * buffer, int size) const; + +private: + JavaStringParam(); + JavaStringParam(const JavaStringParam & src); +}; + +// ---------------------------------------------------------------------- + +inline jstring JavaStringParam::getValue(void) const +{ + return static_cast(LocalRefParam::getValue()); +} + +inline jstring JavaStringParam::getReturnValue(void) +{ + return static_cast(LocalRefParam::getReturnValue()); +} + + +//======================================================================== + +/** + * Wraps a jstring created/returned by a JNI function. + */ +class JavaString : public JavaStringParam +{ +public: + static const JavaStringPtr cms_nullPtr; + +public: + explicit JavaString(jstring src); + explicit JavaString(const char * src); + explicit JavaString(const std::string & src); + explicit JavaString(const Unicode::String & src); + virtual ~JavaString(); + +private: + JavaString(); + JavaString(const JavaString & src); +}; + + +//======================================================================== + +/** + * Wraps a jobject that represents a Java script.dictionary object. + */ +class JavaDictionary : public LocalRef, public ScriptDictionary +{ +public: + static const JavaDictionaryPtr cms_nullPtr; + +public: + explicit JavaDictionary(jobject src); + virtual ~JavaDictionary(); + + virtual void serialize(void); + +private: + JavaDictionary(const JavaDictionary &); + JavaDictionary & operator = (const JavaDictionary &); +}; + + +//======================================================================== + +#endif // _INCLUDED_JNIWrappers_H + + + diff --git a/engine/server/library/serverScript/src/shared/JavaLibrary.cpp b/engine/server/library/serverScript/src/shared/JavaLibrary.cpp new file mode 100644 index 00000000..d6cb2448 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/JavaLibrary.cpp @@ -0,0 +1,6748 @@ +//======================================================================== +// +// JavaLibrary.cpp - interface to the JVM via JNI. +// +// copyright 2001 Sony Online Entertainment +// +//======================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "serverGame/AttribModNameManager.h" +#include "serverGame/CellPermissions.h" +#include "serverGame/ConfigServerGame.h" +#include "serverGame/ConsoleManager.h" +#include "serverGame/ContainerInterface.h" +#include "serverGame/CreatureObject.h" +#include "serverGame/GameServer.h" +#include "serverGame/ManufactureSchematicObject.h" +#include "serverGame/NameManager.h" +#include "serverGame/PlanetObject.h" +#include "serverGame/PlayerObject.h" +#include "serverGame/Region.h" +#include "serverGame/RegionMaster.h" +#include "serverGame/ServerObjectTemplate.h" +#include "serverGame/ServerWorld.h" +#include "serverScript/ConfigServerScript.h" +#include "serverScript/GameScriptObject.h" +#include "serverScript/ScriptListEntry.h" +#include "serverScript/ScriptParameters.h" +#include "sharedDebug/DebugHelp.h" +#include "sharedDebug/Profiler.h" +#include "sharedFoundation/ConfigFile.h" +#include "sharedFoundation/Crc.h" +#include "sharedFoundation/DynamicVariable.h" +#include "sharedFoundation/DynamicVariableList.h" +#include "sharedFoundation/Os.h" +#include "sharedGame/TextManager.h" +#include "sharedLog/Log.h" +#include "sharedNetworkMessages/ObjectMenuRequestData.h" //@todo move this header into a different library (sharedUserInterface) +#include "sharedObject/NetworkIdManager.h" +#include "sharedObject/Object.h" +#include "sharedSynchronization/Semaphore.h" +#include "sharedThread/RunThread.h" +#include "sharedUtility/ValueDictionary.h" + +using namespace JNIWrappersNamespace; + +#if !defined(linux) && !defined(WIN32) +#error Unsupported platform +#endif + +#if !defined(JNI_IBM_JAVA) && defined(WIN32) +//-- Justin Randall [1/21/2003 4:43:15 PM] -- +// The scripting system simply will not work properly with +// our linux servers running the ibm java vm if the win32 +// server is not also using that vm. There are serialization +// issues that render the game useless. Please do not +// change this until the broken interaction between various +// VM's has been rectified! +//#error Unsupported Java VM +#endif//JNI_IBM_JAVA + +//#undef JNI_IBM_JAVA + +#ifdef linux +// shared library includes +#include +#include +#endif + +#ifndef JNI_VERSION_1_2 +#error JNI version 1.2 or better only! +#endif + +//======================================================================== +// macros +//======================================================================== + + +#define GET_CLASS(var, name) tempClass = ms_env->FindClass(name); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); WARNING(true, ("Unable to find Java class "#name)); return false; } var = static_cast(ms_env->NewGlobalRef(tempClass)); ms_env->DeleteLocalRef(tempClass); if (var == 0) { DEBUG_WARNING(true, ("Unable to create global reference for JavaLibrary " #var )); return false; } +#define GET_FIELD(var, clazz, name, sig) var = ms_env->GetFieldID(clazz, name, sig); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); WARNING(true, ("Unable to find Java field "#name" for class "#clazz)); return false; } +#define GET_METHOD(var, clazz, name, sig) var = ms_env->GetMethodID(clazz, name, sig); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); WARNING(true, ("Unable to find Java method "#name" for class "#clazz)); return false; } +#define GET_STATIC_METHOD(var, clazz, name, sig) var = ms_env->GetStaticMethodID(clazz, name, sig); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); WARNING(true, ("Unable to find Java static method "#name" for class "#clazz)); return false; } + +#define FREE_CLASS(var) if (ms_env != NULL && var != NULL) { ms_env->DeleteGlobalRef(var); var = NULL; } + +//======================================================================== +// local constants +//======================================================================== + + +// set path to jvm +#if defined(WIN32) +#define PATH_SEPARATOR ";" +const char *JNI_DLL_PATH = "jvm.dll"; +#else +#define PATH_SEPARATOR ":" +const char *JNI_DBG_DLL_PATH = "libjvm.so";//"libjvm_g.so"; +const char *JNI_DLL_PATH = "libjvm.so"; +#endif + +extern "C" { +typedef jint (JNICALL *JNI_CREATEJAVAVMPROC)(JavaVM**, void**, void*); +} + +//======================================================================== +// JNI native function namespaces +//======================================================================== + + +namespace ScriptMethodsActionStatesNamespace +{ + bool install(); +} +namespace ScriptMethodsAiNamespace +{ + bool install(); +} +namespace ScriptMethodsAnimationNamespace +{ + bool install(); +} +namespace ScriptMethodsAttributesNamespace +{ + bool install(); +} +namespace ScriptMethodsAuctionNamespace +{ + bool install(); +} +namespace ScriptMethodsBankNamespace +{ + bool install(); +} +namespace ScriptMethodsBeastMasterNamespace +{ + bool install(); +} +namespace ScriptMethodsBroadcastingNamespace +{ + bool install(); +} +namespace ScriptMethodsBuffBuilderNamespace +{ + bool install(); +} +namespace ScriptMethodsBuffNamespace +{ + bool install(); +} +namespace ScriptMethodsChatNamespace +{ + bool install(); +} +namespace ScriptMethodsCityNamespace +{ + bool install(); +} +namespace ScriptMethodsClientEffectNamespace +{ + bool install(); +} +namespace ScriptMethodsClusterWideDataNamespace +{ + bool install(); +} +namespace ScriptMethodsCollectionNamespace +{ + bool install(); +} +namespace ScriptMethodsCombatNamespace +{ + bool install(); +} +namespace ScriptMethodsCommandQueueNamespace +{ + bool install(); +} +namespace ScriptMethodsConsoleNamespace +{ + bool install(); +} +namespace ScriptMethodsContainersNamespace +{ + bool install(); +} +namespace ScriptMethodsCraftingNamespace +{ + bool install(); +} +namespace ScriptMethodsDataTableNamespace +{ + bool install(); +} +namespace ScriptMethodsDebugNamespace +{ + bool install(); +} +namespace ScriptMethodsDynamicVariableNamespace +{ + bool install(); +} +namespace ScriptMethodsFormNamespace +{ + bool install(); +} +namespace ScriptMethodsGlobalQueryNamespace +{ + bool install(); +} +namespace ScriptMethodsGuildNamespace +{ + bool install(); +} +namespace ScriptMethodsHateListNamespace +{ + bool install(); +} +namespace ScriptMethodsHolocubeNamespace +{ + bool install(); +} +namespace ScriptMethodsHyperspaceNamespace +{ + bool install(); +} +namespace ScriptMethodsImageDesignNamespace +{ + bool install(); +} +namespace ScriptMethodsInstallationNamespace +{ + bool install(); +} +namespace ScriptMethodsInterestNamespace +{ + bool install(); +} +namespace ScriptMethodsInteriorsNamespace +{ + bool install(); +} +namespace ScriptMethodsJediNamespace +{ + bool install(); +} +namespace ScriptMethodsMapNamespace +{ + bool install(); +} +namespace ScriptMethodsMentalStatesNamespace +{ + bool install(); +} +namespace ScriptMethodsMenuNamespace +{ + bool install(); +} +namespace ScriptMethodsMissionNamespace +{ + bool install(); +} +namespace ScriptMethodsMoneyNamespace +{ + bool install(); +} +namespace ScriptMethodsMountNamespace +{ + bool install(); +} +namespace ScriptMethodsNewbieTutorialNamespace +{ + bool install(); +} +namespace ScriptMethodsNotificationNamespace +{ + bool install(); +} +namespace ScriptMethodsNpcNamespace +{ + bool install(); +} +namespace ScriptMethodsObjectCreateNamespace +{ + bool install(); +} +namespace ScriptMethodsObjectInfoNamespace +{ + bool install(); +} +namespace ScriptMethodsObjectMoveNamespace +{ + bool install(); +} +namespace ScriptMethodsPermissionsNamespace +{ + bool install(); +} +namespace ScriptMethodsPilotNamespace +{ + bool install(); +} +namespace ScriptMethodsPlanetNamespace +{ + bool install(); +} +namespace ScriptMethodsPlayerAccountNamespace +{ + bool install(); +} +namespace ScriptMethodsPlayerQuestNamespace +{ + bool install(); +} +namespace ScriptMethodsPvpNamespace +{ + bool install(); +} +namespace ScriptMethodsQuestNamespace +{ + bool install(); +} +namespace ScriptMethodsRegionNamespace +{ + bool install(); +} +namespace ScriptMethodsRegion3dNamespace +{ + bool install(); +} +namespace ScriptMethodsRemoteDebugNamespace +{ + bool install(); +} +namespace ScriptMethodsResourceNamespace +{ + bool install(); +} +namespace ScriptMethodsScriptNamespace +{ + bool install(); +} +namespace ScriptMethodsServerUINamespace +{ + bool install(); +} +namespace ScriptMethodsShipNamespace +{ + bool install(); +} +namespace ScriptMethodsSkillNamespace +{ + bool install(); +} +namespace ScriptMethodsSpawnerNamespace +{ + bool install(); +} +namespace ScriptMethodsStringNamespace +{ + bool install(); +} +namespace ScriptMethodsSystemNamespace +{ + bool install(); +} +namespace ScriptMethodsTerrainNamespace +{ + bool install(); +} +namespace ScriptMethodsTriggerVolumeNamespace +{ + bool install(); +} +namespace ScriptMethodsVeteranNamespace +{ + bool install(); +} +namespace ScriptMethodsWaypointNamespace +{ + bool install(); +} +namespace ScriptMethodsWorldInfoNamespace +{ + bool install(); +} + +//======================================================================== +// class JavaLibrary static members +//======================================================================== + +JavaLibrary* JavaLibrary::ms_instance = NULL; +int JavaLibrary::ms_javaVmType = JV_none; +//void* JavaLibrary::ms_libHandle = NULL; +JavaVM* JavaLibrary::ms_jvm = NULL; +JNIEnv* JavaLibrary::ms_env = NULL; +Thread * JavaLibrary::m_initializerThread = NULL; +int JavaLibrary::ms_envCount = 0; +int JavaLibrary::ms_currentRecursionCount = 0; +bool JavaLibrary::ms_resetJava = false; +jclass JavaLibrary::ms_clsScriptEntry = NULL; +jobject JavaLibrary::ms_scriptEntry = NULL; +jmethodID JavaLibrary::ms_midScriptEntryGetOwnerContext = NULL; +jmethodID JavaLibrary::ms_midScriptEntryEnableLogging = NULL; +jmethodID JavaLibrary::ms_midScriptEntryEnableNewJediTracking = NULL; +jmethodID JavaLibrary::ms_midScriptEntryGetFreeMem = NULL; +jclass JavaLibrary::ms_clsObject = NULL; +jclass JavaLibrary::ms_clsClass = NULL; +jmethodID JavaLibrary::ms_midClassGetName = NULL; +jmethodID JavaLibrary::ms_midClassGetMethods = NULL; +jclass JavaLibrary::ms_clsMethod = NULL; +jmethodID JavaLibrary::ms_midMethodGetName = NULL; +jclass JavaLibrary::ms_clsBoolean = NULL; +jclass JavaLibrary::ms_clsBooleanArray = NULL; +jmethodID JavaLibrary::ms_midBoolean = NULL; +jmethodID JavaLibrary::ms_midBooleanBooleanValue = NULL; +jclass JavaLibrary::ms_clsInteger = NULL; +jclass JavaLibrary::ms_clsIntegerArray = NULL; +jmethodID JavaLibrary::ms_midInteger = NULL; +jmethodID JavaLibrary::ms_midIntegerIntValue = NULL; +jclass JavaLibrary::ms_clsModifiableInt = NULL; +jmethodID JavaLibrary::ms_midModifiableInt = NULL; +jfieldID JavaLibrary::ms_fidModifiableIntData = NULL; +jclass JavaLibrary::ms_clsFloat = NULL; +jclass JavaLibrary::ms_clsFloatArray = NULL; +jmethodID JavaLibrary::ms_midFloat = NULL; +jmethodID JavaLibrary::ms_midFloatFloatValue = NULL; +jclass JavaLibrary::ms_clsModifiableFloat = NULL; +jmethodID JavaLibrary::ms_midModifiableFloat = NULL; +jfieldID JavaLibrary::ms_fidModifiableFloatData = NULL; +jclass JavaLibrary::ms_clsString = NULL; +jclass JavaLibrary::ms_clsStringArray = NULL; +jclass JavaLibrary::ms_clsMap = NULL; +jmethodID JavaLibrary::ms_midMapPut = NULL; +jmethodID JavaLibrary::ms_midMapGet = NULL; +jclass JavaLibrary::ms_clsHashtable = NULL; +jmethodID JavaLibrary::ms_midHashtable = NULL; +jclass JavaLibrary::ms_clsThrowable = NULL; +jclass JavaLibrary::ms_clsError = NULL; +jclass JavaLibrary::ms_clsStackOverflowError = NULL; +jmethodID JavaLibrary::ms_midThrowableGetMessage = NULL; +jclass JavaLibrary::ms_clsThread = NULL; +jmethodID JavaLibrary::ms_midThreadDumpStack = NULL; +jclass JavaLibrary::ms_clsInternalScriptError = NULL; +jclass JavaLibrary::ms_clsInternalScriptSeriousError = NULL; +jfieldID JavaLibrary::ms_fidInternalScriptSeriousErrorError = NULL; +jclass JavaLibrary::ms_clsDictionary = NULL; +jmethodID JavaLibrary::ms_midDictionary = NULL; +jmethodID JavaLibrary::ms_midDictionaryPack = NULL; +jmethodID JavaLibrary::ms_midDictionaryUnpack = NULL; +jmethodID JavaLibrary::ms_midDictionaryKeys = NULL; +jmethodID JavaLibrary::ms_midDictionaryValues = NULL; +jmethodID JavaLibrary::ms_midDictionaryPut = NULL; +jmethodID JavaLibrary::ms_midDictionaryPutInt = NULL; +jmethodID JavaLibrary::ms_midDictionaryPutFloat = NULL; +jmethodID JavaLibrary::ms_midDictionaryPutBool = NULL; +jmethodID JavaLibrary::ms_midDictionaryGet = NULL; +jclass JavaLibrary::ms_clsCollection = NULL; +jmethodID JavaLibrary::ms_midCollectionToArray = NULL; +jclass JavaLibrary::ms_clsEnumeration = NULL; +jmethodID JavaLibrary::ms_midEnumerationHasMoreElements = NULL; +jmethodID JavaLibrary::ms_midEnumerationNextElement = NULL; +jclass JavaLibrary::ms_clsBaseClassRangeInfo = NULL; +jfieldID JavaLibrary::ms_fidBaseClassRangeInfoMinRange = NULL; +jfieldID JavaLibrary::ms_fidBaseClassRangeInfoMaxRange = NULL; +jclass JavaLibrary::ms_clsBaseClassAttackerResults = NULL; +jfieldID JavaLibrary::ms_fidBaseClassAttackerResultsId = NULL; +jfieldID JavaLibrary::ms_fidBaseClassAttackerResultsWeapon = NULL; +jfieldID JavaLibrary::ms_fidBaseClassAttackerResultsPosture = NULL; +jfieldID JavaLibrary::ms_fidBaseClassAttackerResultsTrailBits = NULL; +jfieldID JavaLibrary::ms_fidBaseClassAttackerResultsClientEffectId = NULL; +jfieldID JavaLibrary::ms_fidBaseClassAttackerResultsActionName = NULL; +jfieldID JavaLibrary::ms_fidBaseClassAttackerResultsUseLocation = NULL; +jfieldID JavaLibrary::ms_fidBaseClassAttackerResultsTargetLocation = NULL; +jfieldID JavaLibrary::ms_fidBaseClassAttackerResultsTargetCell = NULL; +jclass JavaLibrary::ms_clsBaseClassDefenderResults = NULL; +jfieldID JavaLibrary::ms_fidBaseClassDefenderResultsId = NULL; +jfieldID JavaLibrary::ms_fidBaseClassDefenderResultsPosture = NULL; +jfieldID JavaLibrary::ms_fidBaseClassDefenderResultsResult = NULL; +jfieldID JavaLibrary::ms_fidBaseClassDefenderResultsClientEffectId = NULL; +jfieldID JavaLibrary::ms_fidBaseClassDefenderResultsHitLocation = NULL; +jfieldID JavaLibrary::ms_fidBaseClassDefenderDamageAmount = NULL; +jclass JavaLibrary::ms_clsDynamicVariable = NULL; +jfieldID JavaLibrary::ms_fidDynamicVariableName = NULL; +jfieldID JavaLibrary::ms_fidDynamicVariableData = NULL; +jmethodID JavaLibrary::ms_midDynamicVariableInt = NULL; +jmethodID JavaLibrary::ms_midDynamicVariableIntArray = NULL; +jmethodID JavaLibrary::ms_midDynamicVariableFloat = NULL; +jmethodID JavaLibrary::ms_midDynamicVariableFloatArray = NULL; +jmethodID JavaLibrary::ms_midDynamicVariableString = NULL; +jmethodID JavaLibrary::ms_midDynamicVariableStringArray = NULL; +jmethodID JavaLibrary::ms_midDynamicVariableObjId = NULL; +jmethodID JavaLibrary::ms_midDynamicVariableObjIdArray = NULL; +jmethodID JavaLibrary::ms_midDynamicVariableLocation = NULL; +jmethodID JavaLibrary::ms_midDynamicVariableLocationArray = NULL; +jclass JavaLibrary::ms_clsDynamicVariableList = NULL; +jmethodID JavaLibrary::ms_midDynamicVariableList = NULL; +jmethodID JavaLibrary::ms_midDynamicVariableListSet = NULL; +jmethodID JavaLibrary::ms_midDynamicVariableListSetInt = NULL; +jmethodID JavaLibrary::ms_midDynamicVariableListSetIntArray = NULL; +jmethodID JavaLibrary::ms_midDynamicVariableListSetFloat = NULL; +jmethodID JavaLibrary::ms_midDynamicVariableListSetFloatArray = NULL; +jmethodID JavaLibrary::ms_midDynamicVariableListSetString = NULL; +jmethodID JavaLibrary::ms_midDynamicVariableListSetStringArray = NULL; +jmethodID JavaLibrary::ms_midDynamicVariableListSetObjId = NULL; +jmethodID JavaLibrary::ms_midDynamicVariableListSetObjIdArray = NULL; +jmethodID JavaLibrary::ms_midDynamicVariableListSetLocation = NULL; +jmethodID JavaLibrary::ms_midDynamicVariableListSetLocationArray = NULL; +jmethodID JavaLibrary::ms_midDynamicVariableListSetStringId = NULL; +jmethodID JavaLibrary::ms_midDynamicVariableListSetStringIdArray = NULL; +jmethodID JavaLibrary::ms_midDynamicVariableListSetTransform = NULL; +jmethodID JavaLibrary::ms_midDynamicVariableListSetTransformArray = NULL; +jmethodID JavaLibrary::ms_midDynamicVariableListSetVector = NULL; +jmethodID JavaLibrary::ms_midDynamicVariableListSetVectorArray = NULL; +jclass JavaLibrary::ms_clsObjId = NULL; +jclass JavaLibrary::ms_clsObjIdArray = NULL; +jmethodID JavaLibrary::ms_midObjIdGetValue = NULL; +jmethodID JavaLibrary::ms_midObjIdGetObjId = NULL; +jmethodID JavaLibrary::ms_midObjIdClearObjId = NULL; +jmethodID JavaLibrary::ms_midObjIdFlagDestroyed = NULL; +jmethodID JavaLibrary::ms_midObjIdSetAuthoritative = NULL; +jmethodID JavaLibrary::ms_midObjIdSetLoaded = NULL; +jmethodID JavaLibrary::ms_midObjIdSetInitialized = NULL; +jmethodID JavaLibrary::ms_midObjIdSetLoggedIn = NULL; +jmethodID JavaLibrary::ms_midObjIdPackAllDeltaScriptVars = NULL; +jmethodID JavaLibrary::ms_midObjIdSetScriptVarInt = NULL; +jmethodID JavaLibrary::ms_midObjIdSetScriptVarFloat = NULL; +jmethodID JavaLibrary::ms_midObjIdSetScriptVarString = NULL; +jmethodID JavaLibrary::ms_midObjIdClearScriptVars = NULL; +jmethodID JavaLibrary::ms_midObjIdPackScriptVars = NULL; +jmethodID JavaLibrary::ms_midObjIdUnpackDeltaScriptVars = NULL; +jmethodID JavaLibrary::ms_midObjIdUnpackScriptVars = NULL; +jmethodID JavaLibrary::ms_midObjIdAttachScript = NULL; +jmethodID JavaLibrary::ms_midObjIdAttachScripts = NULL; +jmethodID JavaLibrary::ms_midObjIdDetachScript = NULL; +jmethodID JavaLibrary::ms_midObjIdDetachAllScripts = NULL; +jclass JavaLibrary::ms_clsStringId = NULL; +jmethodID JavaLibrary::ms_midStringId = NULL; +jclass JavaLibrary::ms_clsStringIdArray = NULL; +jfieldID JavaLibrary::ms_fidStringIdTable = NULL; +jfieldID JavaLibrary::ms_fidStringIdAsciiId = NULL; +jfieldID JavaLibrary::ms_fidStringIdIndexId = NULL; +jclass JavaLibrary::ms_clsModifiableStringId = NULL; +jclass JavaLibrary::ms_clsAttribute = NULL; +jmethodID JavaLibrary::ms_midAttribute = NULL; +jfieldID JavaLibrary::ms_fidAttributeType = NULL; +jfieldID JavaLibrary::ms_fidAttributeValue = NULL; +jclass JavaLibrary::ms_clsAttribMod = NULL; +jmethodID JavaLibrary::ms_midAttribMod = NULL; +jfieldID JavaLibrary::ms_fidAttribModName = NULL; +jfieldID JavaLibrary::ms_fidAttribModSkill = NULL; +jfieldID JavaLibrary::ms_fidAttribModType = NULL; +jfieldID JavaLibrary::ms_fidAttribModValue = NULL; +jfieldID JavaLibrary::ms_fidAttribModTime = NULL; +jfieldID JavaLibrary::ms_fidAttribModAttack = NULL; +jfieldID JavaLibrary::ms_fidAttribModDecay = NULL; +jfieldID JavaLibrary::ms_fidAttribModFlags = NULL; +jclass JavaLibrary::ms_clsMentalState = NULL; +jmethodID JavaLibrary::ms_midMentalState = NULL; +jfieldID JavaLibrary::ms_fidMentalStateType = NULL; +jfieldID JavaLibrary::ms_fidMentalStateValue = NULL; +jclass JavaLibrary::ms_clsMentalStateMod = NULL; +jmethodID JavaLibrary::ms_midMentalStateMod = NULL; +jfieldID JavaLibrary::ms_fidMentalStateModType = NULL; +jfieldID JavaLibrary::ms_fidMentalStateModValue = NULL; +jfieldID JavaLibrary::ms_fidMentalStateModTime = NULL; +jfieldID JavaLibrary::ms_fidMentalStateModAttack = NULL; +jfieldID JavaLibrary::ms_fidMentalStateModDecay = NULL; +jclass JavaLibrary::ms_clsLocation = NULL; +jclass JavaLibrary::ms_clsLocationArray = NULL; +jfieldID JavaLibrary::ms_fidLocationX = NULL; +jfieldID JavaLibrary::ms_fidLocationY = NULL; +jfieldID JavaLibrary::ms_fidLocationZ = NULL; +jfieldID JavaLibrary::ms_fidLocationArea = NULL; +jfieldID JavaLibrary::ms_fidLocationCell = NULL; +jmethodID JavaLibrary::ms_midRunOne = NULL; +jmethodID JavaLibrary::ms_midRunAll = NULL; +jmethodID JavaLibrary::ms_midCallMessages = NULL; +jmethodID JavaLibrary::ms_midRunConsoleHandler = NULL; +jmethodID JavaLibrary::ms_midUnload = NULL; +jmethodID JavaLibrary::ms_midGetClass = NULL; +jmethodID JavaLibrary::ms_midGetScriptFunctions = NULL; +jclass JavaLibrary::ms_clsMenuInfo = NULL; +jmethodID JavaLibrary::ms_midMenuInfo = NULL; +jmethodID JavaLibrary::ms_midMenuInfoSetMenuItemsInternal = NULL; +jmethodID JavaLibrary::ms_midMenuInfoGetMenuItemsInternal = NULL; +jclass JavaLibrary::ms_clsMenuInfoData = NULL; +jmethodID JavaLibrary::ms_midMenuInfoData = NULL; +jfieldID JavaLibrary::ms_fidMenuInfoDataId; +jfieldID JavaLibrary::ms_fidMenuInfoDataParent; +jfieldID JavaLibrary::ms_fidMenuInfoDataType; +jfieldID JavaLibrary::ms_fidMenuInfoDataLabel; +jfieldID JavaLibrary::ms_fidMenuInfoDataEnabled; +jfieldID JavaLibrary::ms_fidMenuInfoDataServerNotify; +jclass JavaLibrary::ms_clsCustomVar; +jmethodID JavaLibrary::ms_midCustomVarObjIdStringInt; +jclass JavaLibrary::ms_clsRangedIntCustomVar; +jmethodID JavaLibrary::ms_midRangedIntCustomVar; +jclass JavaLibrary::ms_clsPalcolorCustomVar; +jmethodID JavaLibrary::ms_midPalcolorCustomVar; +jclass JavaLibrary::ms_clsColor; +jmethodID JavaLibrary::ms_midColor; +jclass JavaLibrary::ms_clsDraftSchematic = NULL; +jfieldID JavaLibrary::ms_fidDraftSchematicCategory = NULL; +jfieldID JavaLibrary::ms_fidDraftSchematicComplexity = NULL; +jfieldID JavaLibrary::ms_fidDraftSchematicSlots = NULL; +jfieldID JavaLibrary::ms_fidDraftSchematicAttribs = NULL; +jfieldID JavaLibrary::ms_fidDraftSchematicExperimentalAttribs = NULL; +jfieldID JavaLibrary::ms_fidDraftSchematicCustomizations = NULL; +jfieldID JavaLibrary::ms_fidDraftSchematicAttribMap = NULL; +jfieldID JavaLibrary::ms_fidDraftSchematicObjectTemplateCreated = NULL; +jfieldID JavaLibrary::ms_fidDraftSchematicScripts = NULL; +jclass JavaLibrary::ms_clsDraftSchematicSlot = NULL; +jfieldID JavaLibrary::ms_fidDraftSchematicSlotName = NULL; +jfieldID JavaLibrary::ms_fidDraftSchematicSlotOption = NULL; +jfieldID JavaLibrary::ms_fidDraftSchematicSlotIngredientType = NULL; +jfieldID JavaLibrary::ms_fidDraftSchematicSlotIngredientName = NULL; +jfieldID JavaLibrary::ms_fidDraftSchematicSlotIngredients = NULL; +jfieldID JavaLibrary::ms_fidDraftSchematicSlotComplexity = NULL; +jfieldID JavaLibrary::ms_fidDraftSchematicSlotAmountRequired = NULL; +jfieldID JavaLibrary::ms_fidDraftSchematicSlotAppearance = NULL; +jclass JavaLibrary::ms_clsDraftSchematicAttrib = NULL; +jfieldID JavaLibrary::ms_fidDraftSchematicAttribName = NULL; +jfieldID JavaLibrary::ms_fidDraftSchematicAttribMinValue = NULL; +jfieldID JavaLibrary::ms_fidDraftSchematicAttribMaxValue = NULL; +jfieldID JavaLibrary::ms_fidDraftSchematicAttribResourceMaxValue = NULL; +jfieldID JavaLibrary::ms_fidDraftSchematicAttribCurrentValue = NULL; +jclass JavaLibrary::ms_clsDraftSchematicSimpleIngredient = NULL; +jfieldID JavaLibrary::ms_fidDraftSchematicSimpleIngredientIngredient = NULL; +jfieldID JavaLibrary::ms_fidDraftSchematicSimpleIngredientCount = NULL; +jfieldID JavaLibrary::ms_fidDraftSchematicSimpleIngredientSource = NULL; +jfieldID JavaLibrary::ms_fidDraftSchematicSimpleIngredientXpType = NULL; +jfieldID JavaLibrary::ms_fidDraftSchematicSimpleIngredientXpAmount = NULL; +jclass JavaLibrary::ms_clsDraftSchematicCustom = NULL; +jfieldID JavaLibrary::ms_fidDraftSchematicCustomName = NULL; +jfieldID JavaLibrary::ms_fidDraftSchematicCustomValue = NULL; +jfieldID JavaLibrary::ms_fidDraftSchematicCustomMinValue = NULL; +jfieldID JavaLibrary::ms_fidDraftSchematicCustomMaxValue = NULL; +//jfieldID JavaLibrary::ms_fidDraftSchematicCustomLocked = NULL; +jclass JavaLibrary::ms_clsMapLocation = NULL; +jmethodID JavaLibrary::ms_midMapLocation = NULL; +jclass JavaLibrary::ms_clsRegion = NULL; +jmethodID JavaLibrary::ms_midRegion = NULL; +jfieldID JavaLibrary::ms_fidRegionName = NULL; +jfieldID JavaLibrary::ms_fidRegionPlanet = NULL; +jclass JavaLibrary::ms_clsCombatEngine = NULL; +jclass JavaLibrary::ms_clsCombatEngineCombatantData = NULL; +jfieldID JavaLibrary::ms_fidCombatEngineCombatantDataPos = NULL; +jfieldID JavaLibrary::ms_fidCombatEngineCombatantDataWorldPos = NULL; +jfieldID JavaLibrary::ms_fidCombatEngineCombatantDataRadius = NULL; +jfieldID JavaLibrary::ms_fidCombatEngineCombatantDataIsCreature = NULL; +jfieldID JavaLibrary::ms_fidCombatEngineCombatantDataPosture = NULL; +jfieldID JavaLibrary::ms_fidCombatEngineCombatantDataLocomotion = NULL; +jfieldID JavaLibrary::ms_fidCombatEngineCombatantDataScriptMod = NULL; +jclass JavaLibrary::ms_clsCombatEngineAttackerData = NULL; +jfieldID JavaLibrary::ms_fidCombatEngineAttackerDataWeaponSkill = NULL; +jfieldID JavaLibrary::ms_fidCombatEngineAttackerDataAims = NULL; +jclass JavaLibrary::ms_clsCombatEngineDefenderData = NULL; +jfieldID JavaLibrary::ms_fidCombatEngineDefenderDataCombatSkeleton = NULL; +jfieldID JavaLibrary::ms_fidCombatEngineDefenderDataCover = NULL; +jfieldID JavaLibrary::ms_fidCombatEngineDefenderDataHitLocationChances = NULL; +jclass JavaLibrary::ms_clsCombatEngineWeaponData = NULL; +jfieldID JavaLibrary::ms_fidCombatEngineWeaponDataId = NULL; +jfieldID JavaLibrary::ms_fidCombatEngineWeaponDataMinDamage = NULL; +jfieldID JavaLibrary::ms_fidCombatEngineWeaponDataMaxDamage = NULL; +jfieldID JavaLibrary::ms_fidCombatEngineWeaponDataWeaponType = NULL; +jfieldID JavaLibrary::ms_fidCombatEngineWeaponDataAttackType = NULL; +jfieldID JavaLibrary::ms_fidCombatEngineWeaponDataDamageType = NULL; +jfieldID JavaLibrary::ms_fidCombatEngineWeaponDataElementalType = NULL; +jfieldID JavaLibrary::ms_fidCombatEngineWeaponDataElementalValue = NULL; +jfieldID JavaLibrary::ms_fidCombatEngineWeaponDataAttackSpeed = NULL; +jfieldID JavaLibrary::ms_fidCombatEngineWeaponDataWoundChance = NULL; +jfieldID JavaLibrary::ms_fidCombatEngineWeaponDataAccuracy = NULL; +jfieldID JavaLibrary::ms_fidCombatEngineWeaponDataMinRange = NULL; +jfieldID JavaLibrary::ms_fidCombatEngineWeaponDataMaxRange = NULL; +jfieldID JavaLibrary::ms_fidCombatEngineWeaponDataDamageRadius = NULL; +jfieldID JavaLibrary::ms_fidCombatEngineWeaponDataAttackCost = NULL; +jfieldID JavaLibrary::ms_fidCombatEngineWeaponDataIsDisabled = NULL; +jclass JavaLibrary::ms_clsCombatEngineHitResult; +jfieldID JavaLibrary::ms_fidCombatEngineHitResultSuccess; +jfieldID JavaLibrary::ms_fidCombatEngineHitResultCritical; +jfieldID JavaLibrary::ms_fidCombatEngineHitResultGlancing; +jfieldID JavaLibrary::ms_fidCombatEngineHitResultCrushing; +jfieldID JavaLibrary::ms_fidCombatEngineHitResultStrikethrough; +jfieldID JavaLibrary::ms_fidCombatEngineHitResultStrikethroughAmount; +jfieldID JavaLibrary::ms_fidCombatEngineHitResultEvadeResult; +jfieldID JavaLibrary::ms_fidCombatEngineHitResultEvadeAmount; +jfieldID JavaLibrary::ms_fidCombatEngineHitResultBlockResult; +jfieldID JavaLibrary::ms_fidCombatEngineHitResultBlock; +jfieldID JavaLibrary::ms_fidCombatEngineHitResultDodge; +jfieldID JavaLibrary::ms_fidCombatEngineHitResultParry; +jfieldID JavaLibrary::ms_fidCombatEngineHitResultProc; +jfieldID JavaLibrary::ms_fidCombatEngineHitResultBaseRoll; +jfieldID JavaLibrary::ms_fidCombatEngineHitResultFinalRoll; +jfieldID JavaLibrary::ms_fidCombatEngineHitResultAttackVal; +jfieldID JavaLibrary::ms_fidCombatEngineHitResultCanSee; +jfieldID JavaLibrary::ms_fidCombatEngineHitResultHitLocation; +jfieldID JavaLibrary::ms_fidCombatEngineHitResultDamage; +jfieldID JavaLibrary::ms_fidCombatEngineHitResultDamageType; +jfieldID JavaLibrary::ms_fidCombatEngineHitResultRawDamage; +jfieldID JavaLibrary::ms_fidCombatEngineHitResultElementalDamage; +jfieldID JavaLibrary::ms_fidCombatEngineHitResultElementalDamageType; +jfieldID JavaLibrary::ms_fidCombatEngineHitResultBleedDamage; +jfieldID JavaLibrary::ms_fidCombatEngineHitResultCritDamage; +jfieldID JavaLibrary::ms_fidCombatEngineHitResultBlockedDamage; +jfieldID JavaLibrary::ms_fidCombatEngineHitResultBlockingArmor; +jfieldID JavaLibrary::ms_fidCombatEngineHitResultBleedingChance; +jclass JavaLibrary::ms_clsTransform = NULL; +jclass JavaLibrary::ms_clsTransformArray = NULL; +jmethodID JavaLibrary::ms_midTransform = NULL; +jfieldID JavaLibrary::ms_fidTransformMatrix = NULL; +jclass JavaLibrary::ms_clsVector = NULL; +jclass JavaLibrary::ms_clsVectorArray = NULL; +jfieldID JavaLibrary::ms_fidVectorX = NULL; +jfieldID JavaLibrary::ms_fidVectorY = NULL; +jfieldID JavaLibrary::ms_fidVectorZ = NULL; +jclass JavaLibrary::ms_clsResourceDensity = NULL; +jfieldID JavaLibrary::ms_fidResourceDensityResourceType = NULL; +jfieldID JavaLibrary::ms_fidResourceDensityDensity = NULL; +jclass JavaLibrary::ms_clsResourceAttribute = NULL; +jfieldID JavaLibrary::ms_fidResourceAttributeName = NULL; +jfieldID JavaLibrary::ms_fidResourceAttributeValue = NULL; +jclass JavaLibrary::ms_clsLibrarySpaceTransition = NULL; +jmethodID JavaLibrary::ms_midLibrarySpaceTransitionSetPlayerOvert = NULL; +jmethodID JavaLibrary::ms_midLibrarySpaceTransitionClearOvertStatus = NULL; + +////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////// +// CS handlers +jclass JavaLibrary::ms_clsLibraryDump = NULL; +jmethodID JavaLibrary::ms_midLibraryDumpDumpTargetInfo = NULL; + +jclass JavaLibrary::ms_clsLibraryGMLib = NULL; +jmethodID JavaLibrary::ms_midLibraryGMLibFreeze = NULL; +jmethodID JavaLibrary::ms_midLibraryGMLibUnfreeze = NULL; + +////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////// + +int JavaLibrary::ms_loaded = 0; +Semaphore * JavaLibrary::ms_shutdownJava = NULL; + +int JavaLibrary::GlobalInstances::ms_stringIdIndex = 0; +int JavaLibrary::GlobalInstances::ms_attribModIndex = 0; +int JavaLibrary::GlobalInstances::ms_mentalStateModIndex = 0; +int JavaLibrary::GlobalInstances::ms_modifiableIntIndex = 0; +int JavaLibrary::GlobalInstances::ms_modifiableFloatIndex = 0; +int JavaLibrary::GlobalInstances::ms_modifiableStringIdIndex = 0; +GlobalRefPtr JavaLibrary::GlobalInstances::ms_stringIds[MAX_STRING_ID_PARAMS]; +GlobalRefPtr JavaLibrary::GlobalInstances::ms_attribMods[MAX_ATTRIB_MOD_PARAMS]; +GlobalRefPtr JavaLibrary::GlobalInstances::ms_mentalStateMods[MAX_MENTAL_STATE_MOD_PARAMS]; +GlobalRefPtr JavaLibrary::GlobalInstances::ms_modifiableInts[MAX_MODIFIABLE_INT_PARAMS]; +GlobalRefPtr JavaLibrary::GlobalInstances::ms_modifiableFloats[MAX_MODIFIABLE_FLOAT_PARAMS]; +GlobalRefPtr JavaLibrary::GlobalInstances::ms_modifiableStringIds[MAX_MODIFIABLE_STRING_ID_PARAMS]; +GlobalRefPtr JavaLibrary::GlobalInstances::ms_menuInfo; +GlobalArrayRefPtr JavaLibrary::ms_attribModList[MAX_RECURSION_COUNT]; +GlobalArrayRefPtr JavaLibrary::ms_mentalStateModList[MAX_RECURSION_COUNT]; + + +// ====================================================================== + +std::set s_profileSections; + +//======================================================================== +// class JavaLibrary methods +//======================================================================== + +void JavaLibrary::throwScriptException(char const * const format, ...) +{ + va_list va; + va_start(va, format); + + throwScriptException(format, va); + + va_end(va); +} + +void JavaLibrary::throwScriptException(char const * const format, va_list va) +{ + DEBUG_FATAL(!ms_env, ("JavaLibrary::throwScriptException: ms_env is NULL")); + if (ms_env) + { + char buffer[1024]; + vsnprintf(buffer, sizeof(buffer), format, va); + buffer[sizeof(buffer) - 1] = 0; + throwInternalScriptError(buffer); + } +} + +#ifdef linux +static struct sigaction OrgSa; // original signal handler, used to generate core files +static struct sigaction JavaSa; // Java signal handler, used to generate Java exceptions +static struct sigaction OurSa; // our signal handler +#endif + +void JavaLibrary::fatalHandler(int signum) +{ +#ifdef linux + fprintf(stderr, "In JavaLibrary::fatalHandler, signal %d: ", signum); + if (signum == SIGSEGV && ms_jvm) + { + + // try to see if our call stack came from C or Java + void *frameAddress = __builtin_frame_address(0); + // the address that generated the segfault is stored at an offset of 0x44 from + // the frame address + // @todo: find documentation on the offset to verify it is stable + void *crashAddress1 = *((void**)((static_cast(frameAddress)) + 0x44)); + // pass the crash address to addr2line to get the file name where the crash occurred + static const int BUFLEN = 2048; + char lib1[BUFLEN], lib2[BUFLEN]; + char file1[BUFLEN], file2[BUFLEN]; + int line1, line2; + bool result1 = DebugHelp::lookupAddress(reinterpret_cast(crashAddress1), lib1, file1, BUFLEN, line1); + + // do a second test based on the return address + // it turns out that in some java crashes we don't even have 2 return + // addresses, so check 0 and 1 just to make sure + bool result2 = false; + void *crashAddress2a = NULL; + void *crashAddress2b = NULL; + void *crashAddress2c = NULL; + void *frameAddressA = NULL; + void *frameAddressB = NULL; + uint32 frameAddressHigh = (reinterpret_cast(frameAddress) >> 16); + crashAddress2a = __builtin_return_address(0); + if (crashAddress2a != NULL) + { + frameAddressA = __builtin_frame_address(1); + if (frameAddressA != NULL && + (reinterpret_cast(frameAddressA) >> 16 == frameAddressHigh)) + { + crashAddress2b = __builtin_return_address(1); + if (crashAddress2b != NULL) + { + frameAddressB = __builtin_frame_address(2); + if (frameAddressB != NULL && + (reinterpret_cast(frameAddressB) >> 16 == frameAddressHigh)) + { + crashAddress2c = __builtin_return_address(2); + if (crashAddress2c != NULL) + { + result2 = DebugHelp::lookupAddress(reinterpret_cast( + crashAddress2c), lib2, file2, BUFLEN, line2); + } + } + } + } + } + + bool javaCrash = true; + if ((result1 || result2) && strstr(lib1, "libjvm.so") == NULL && strstr(lib2, "libjvm.so") == NULL) + { + if (result1 && result2) + { + fprintf(stderr, "I crashed in a file: <%s>, line %d, or in file " + "<%s>, line %d, going to core.\n", file1, line1, file2, line2); + } + else if (result1) + { + fprintf(stderr, "I crashed in a file: <%s>, line %d, going to core.\n", + file1, line1); + } + else + { + fprintf(stderr, "I crashed in a file: <%s>, line %d, going to core.\n", + file2, line2); + } + javaCrash = false; + } + + if (javaCrash) + { + fprintf(stderr, "I think I crashed in Java, calling the Java segfault hanlder.\n"); + IGNORE_RETURN(sigaction(SIGSEGV, &JavaSa, NULL)); + IGNORE_RETURN(pthread_kill(pthread_self(), SIGSEGV)); + } + else + { + // destroy Java threads + pthread_kill_other_threads_np(); + ms_instance = NULL; + ms_env = NULL; + ms_jvm = NULL; + // restore original signal handler and rethrow signal + IGNORE_RETURN(sigaction(SIGSEGV, &OrgSa, NULL)); + IGNORE_RETURN(pthread_kill(pthread_self(), SIGSEGV)); + } + } + else + ::abort(); +#endif +} // JavaLibrary::fatalHandler + +/** + * Class constructor. + */ +JavaLibrary::JavaLibrary(void) +{ +int i; + + if (ms_instance != NULL || ms_loaded != 0) + return; + + ms_shutdownJava = new Semaphore(); + + for (i = 0; i < MAX_RECURSION_COUNT; ++i) + { + ms_attribModList[i] = GlobalArrayRef::cms_nullPtr; + ms_mentalStateModList[i] = GlobalArrayRef::cms_nullPtr; + } + // initialize the GlobalInstances class static members + for (i = 0; i < MAX_STRING_ID_PARAMS; ++i) + GlobalInstances::ms_stringIds[i] = GlobalRef::cms_nullPtr; + for (i = 0; i < MAX_ATTRIB_MOD_PARAMS; ++i) + GlobalInstances::ms_attribMods[i] = GlobalRef::cms_nullPtr; + for (i = 0; i < MAX_MENTAL_STATE_MOD_PARAMS; ++i) + GlobalInstances::ms_mentalStateMods[i] = GlobalRef::cms_nullPtr; + for (i = 0; i < MAX_MODIFIABLE_INT_PARAMS; ++i) + GlobalInstances::ms_modifiableInts[i] = GlobalRef::cms_nullPtr; + for (i = 0; i < MAX_MODIFIABLE_FLOAT_PARAMS; ++i) + GlobalInstances::ms_modifiableFloats[i] = GlobalRef::cms_nullPtr; + for (i = 0; i < MAX_MODIFIABLE_STRING_ID_PARAMS; ++i) + GlobalInstances::ms_modifiableStringIds[i] = GlobalRef::cms_nullPtr; + + + m_initializerThread = new MemberFunctionThreadZero("JavaLibrary", *this, &JavaLibrary::initializeJavaThread); + ThreadHandle tempThreadHandle(m_initializerThread); // for some obscure reason, the thread doesn't run unless you create a handle, but we don't need the handle for anything + UNREF(tempThreadHandle); + + // wait until ms_loaded != 0; if it is 1, we have successfully initialized Java, + // if it is not 1, there was an error + while (ms_loaded == 0) + Os::sleep(100); + if (ms_loaded != 1) + return; + + if (!connectToJava()) + return; + + ms_instance = this; + DEBUG_REPORT_LOG(true, ("Java initialized\n")); +} // JavaLibrary::JavaLibrary + +/** + * Class destructor. + */ +JavaLibrary::~JavaLibrary() +{ + disconnectFromJava(); + + if (ms_shutdownJava != NULL) + { + // tell the initialize thread to shut down + if (ms_loaded > 0) + { + ms_shutdownJava->signal(); + while (ms_loaded > 0) + Os::sleep(100); + } + delete ms_shutdownJava; + ms_shutdownJava = NULL; + } + + ms_instance = NULL; +} // JavaLibrary::~JavaLibrary + +//---------------------------------------------------------------------- + +/** + * Creates the singleton JavaLibrary instance. + */ +void JavaLibrary::install(void) +{ + if (ms_instance == NULL) + { + JavaLibrary *lib = new JavaLibrary; + if (lib != ms_instance) + { + if (ms_instance == NULL) + { + delete lib; + if (ms_javaVmType != JV_none) + FATAL (true, ("Unable to initialize Java")); + } + } + } + else + DEBUG_REPORT_LOG(true, ("JavaLibrary::JavaLibrary error: dup instance\n")); +} // JavaLibrary::install + +//---------------------------------------------------------------------- + +/** + * Destroys the singleton JavaLibrary instance. + */ +void JavaLibrary::remove(void) +{ + if (ms_instance != NULL) + { + JavaLibrary * temp = ms_instance; + ms_instance = NULL; + delete temp; + s_profileSections.clear(); + } +} // JavaLibrary::remove + +//---------------------------------------------------------------------- + +/** + * Entry point for the Java initialization thread. We create the Java VM from here, + * and then wait until we get a signal to shut down Java. The main game thread will + * connect to our VM via the connectToJava function. + */ +void JavaLibrary::initializeJavaThread() +{ + if (ms_loaded != 0) + { + WARNING(true, ("JavaLibrary::initializeJavaThread called when already loaded!")); + return; + } + + const char *javaVMName = ConfigServerGame::getJavaVMName(); + if (javaVMName == NULL || ( + strcmp(javaVMName, "none") != 0 && + strcmp(javaVMName, "ibm") != 0 && + strcmp(javaVMName, "sun") != 0)) + { + FATAL(true, ("[ServerGame] javaVMName not defined. Valid values are: " + "none, ibm, or sun")); + } + else if (strcmp(javaVMName, "ibm") == 0) + { + ms_javaVmType = JV_ibm; + } + else if (strcmp(javaVMName, "sun") == 0) + { + ms_javaVmType = JV_sun; + } + + if (ms_javaVmType == JV_none) + { + DEBUG_REPORT_LOG(true, ("Scripting is disabled.\n")); + ms_loaded = -1; + return; + } + +#ifdef linux + + // get the default signal handler + IGNORE_RETURN(sigaction(SIGSEGV, NULL, &OrgSa)); + + if (ms_javaVmType == JV_ibm) + { + // check PATH to make sure that it has /usr/bin/java + const char * env = getenv("PATH"); + const char * bin = NULL; + int envlen = 0; + if (env != NULL) + { + bin = strstr(env, "/usr/java/bin"); + envlen = strlen(env); + } + + if (bin == NULL) + { + WARNING(true, ("/usr/java/bin not found in PATH which is needed for IBM Java VM. Adding it now")); + char * tmpbuffer = new char[envlen + 128]; + if (env) + strcpy(tmpbuffer, env); + strcat(tmpbuffer, ":/usr/java/bin"); + setenv("PATH", tmpbuffer, 1); + delete [] tmpbuffer; + } + + // check LD_LIBRARY_PATH for /usr/java/jre/bin and /usr/java/jre/bin/classic + env = getenv("LD_LIBRARY_PATH"); + bin = NULL; + envlen = 0; + const char * classic = NULL; + if (env != NULL) + { + bin = strstr(env, "/usr/java/jre/bin"); + classic = strstr(env, "/usr/java/jre/bin/classic"); + if (bin == classic && bin != NULL) + bin = strstr(classic + 1, "/usr/java/jre/bin"); + envlen = strlen(env); + } + if (bin == NULL || classic == NULL) + { + WARNING(true, ("/usr/java/jre/bin or /usr/java/jre/bin/classic not found " + "in LD_LIBRARY_PATH, needed for IBM Java VM. Adding them both now.")); + char * tmpbuffer = new char[envlen + 256]; + memset(tmpbuffer, 0, envlen + 256); + if (env) + strcpy(tmpbuffer, env); + strcat(tmpbuffer, ":/usr/java/jre/bin"); + strcat(tmpbuffer, ":/usr/java/jre/bin/classic"); + setenv("LD_LIBRARY_PATH", tmpbuffer, 1); + delete [] tmpbuffer; + } + + // check if LD_ASSUME_KERNEL is defined + env = getenv("LD_ASSUME_KERNEL"); + if (env == NULL || strcmp(env, "2.4.1") != 0) + { +// WARNING(true, ("LD_ASSUME_KERNEL=2.4.1 not set, Java may not run correctly")); + } + } +#endif // linux + + // dynamically load the jni dll and JNI_CreateJavaVM + void * libHandle = NULL; + JNI_CREATEJAVAVMPROC JNI_CreateJavaVMProc; +#if defined(WIN32) + std::string dllPath = ConfigServerGame::getJavaLibPath(); + HINSTANCE hVm = LoadLibrary(dllPath.c_str()); + if (hVm == NULL) + { + FATAL(true, ("jvm open fail error: could not open %s", dllPath.c_str())); + ms_loaded = -1; + return; + } + libHandle = hVm; + JNI_CreateJavaVMProc = + (JNI_CREATEJAVAVMPROC)GetProcAddress(hVm, "JNI_CreateJavaVM"); //lint !e1924 C-style cast +#else + void *libVM = NULL; + std::string dllPath = ConfigServerGame::getJavaLibPath(); + libVM = dlopen(dllPath.c_str(), RTLD_LAZY); + if (libVM == NULL) + { + FATAL(true, ("jvm open fail! error: %s", dlerror())); + ms_loaded = -1; + return; + } + libHandle = libVM; + JNI_CreateJavaVMProc = + (JNI_CREATEJAVAVMPROC)dlsym(libVM, "JNI_CreateJavaVM"); +#endif + if (JNI_CreateJavaVMProc == NULL) + { + FATAL(true, ("Error getting JNI_CreateJavaVM from jvm shared library")); + ms_loaded = -1; + return; + } + +#if defined(_DEBUG) //&& defined(linux) +#define REMOTE_DEBUG_ON +#endif + + // set up the args to initialize the jvm + std::string classPath = "-Djava.class.path="; +// classPath += PATH_SEPARATOR; + classPath += ConfigServerGame::getScriptPath(); + +// DEBUG_REPORT_LOG(true, ("Java class path = %s\n", classPath.c_str())); + + JavaVMInitArgs vm_args; + JavaVMOption tempOption = {NULL, NULL}; + std::vector options; + char *jdwpBuffer = NULL; + + UNREF(jdwpBuffer); + +// classPath += PATH_SEPARATOR; +// classPath += "/home/sjakab/temp/OptimizeitSuiteDemo/lib/optit.jar"; +// tempOption.optionString = "-Xnoclassgc"; +// options.push_back(tempOption); + + if (ConfigServerScript::hasJavaOptions()) + { + int const numberOfJavaOptions = ConfigServerScript::getNumberOfJavaOptions(); + for (int i = 0; i < numberOfJavaOptions; ++i) + { + char const * p = ConfigServerScript::getJavaOptions(i); + tempOption.optionString = const_cast(p); + options.push_back(tempOption); + } + } + else + { + // use options derived from config file settings + + // set up memory requirements + tempOption.optionString = "-Xms128m"; + options.push_back(tempOption); + tempOption.optionString = "-Xmx512m"; + options.push_back(tempOption); + tempOption.optionString = "-Xss768k"; + options.push_back(tempOption); + if (ms_javaVmType == JV_ibm) + { + tempOption.optionString = "-Xoss768k"; + options.push_back(tempOption); + } + + if (ms_javaVmType == JV_ibm) + { + tempOption.optionString = "-Xcheck:jni"; + options.push_back(tempOption); + tempOption.optionString = "-Xcheck:nabounds"; + options.push_back(tempOption); + tempOption.optionString = "-Xrs"; + options.push_back(tempOption); +#ifndef WIN32 + tempOption.optionString = "-Xgcpolicy:optavgpause"; + options.push_back(tempOption); +#endif + } + else + { + if (ConfigServerGame::getCompileScripts()) + { + tempOption.optionString = "-Xint"; + options.push_back(tempOption); + } + tempOption.optionString = "-Xincgc"; + options.push_back(tempOption); + } + + if (ConfigServerGame::getUseVerboseJava()) + { + tempOption.optionString = "-verbose:jni"; + options.push_back(tempOption); + tempOption.optionString = "-verbose:gc"; + options.push_back(tempOption); + tempOption.optionString = "-verbose:class"; + options.push_back(tempOption); + } + +#ifdef JNI_VERSION_1_4 + if (!ms_javaVmType == JV_ibm) + { + tempOption.optionString = "-Xrs"; + options.push_back(tempOption); + tempOption.optionString = "-Xcheck:jni"; + options.push_back(tempOption); + } + if (ConfigServerGame::getLogJavaGc()) + { + tempOption.optionString = "-Xloggc:javagc.log"; + options.push_back(tempOption); +// tempOption.optionString = "-Xrunpri"; +// options.push_back(tempOption); +// tempOption.optionString = "-Xbootclasspath/a:/home/sjakab/temp/OptimizeitSuiteDemo/lib/oibcp.jar"; +// options.push_back(tempOption); +// tempOption.optionString = "-Xboundthreads"; +// options.push_back(tempOption); +// tempOption.optionString = "-Xrunhprof:heap=format=b"; +// options.push_back(tempOption); + } + +#endif + +#ifdef REMOTE_DEBUG_ON + char *jdwpBuffer = NULL; + if (ConfigServerGame::getUseRemoteDebugJava()) + { + if (ms_javaVmType == JV_ibm) + { + tempOption.optionString = "-Xnoagent"; + options.push_back(tempOption); + tempOption.optionString = "-Djava.compiler=NONE"; + options.push_back(tempOption); + } + tempOption.optionString = "-Xdebug"; + options.push_back(tempOption); + // we need to copy the -Xrunjdwp parameter into a char buffer due to a bug + // in the Java VM + const char * jdwpString = "-Xrunjdwp:transport=dt_socket,server=y,suspend=n"; + jdwpBuffer = new char[strlen(jdwpString) + 32]; + strcpy(jdwpBuffer, jdwpString); + if (strlen(ConfigServerGame::getJavaDebugPort()) > 0) + { + strcat(jdwpBuffer, ",address="); + strcat(jdwpBuffer, ConfigServerGame::getJavaDebugPort()); + } + tempOption.optionString = jdwpBuffer; + options.push_back(tempOption); + } +#endif // REMOTE_DEBUG_ON + + if (ConfigServerGame::getProfileScripts()) + { + if (ms_javaVmType == JV_ibm) + { + char profileBuffer[128]; + strcpy(profileBuffer,"-Xrunhprof:cpu=times"); + tempOption.optionString = profileBuffer; + options.push_back(tempOption); + } + else + { + WARNING(true, ("profileScripts option enabled using Sun JVM. This option " + "is only supported using the IBM JVM.")); + } + } + } + + tempOption.optionString = const_cast(classPath.c_str()); + options.push_back(tempOption); + +#ifdef JNI_VERSION_1_4 + vm_args.version = JNI_VERSION_1_4; +#else + vm_args.version = JNI_VERSION_1_2; +#endif + vm_args.options = &options[0]; + vm_args.nOptions = options.size(); + vm_args.ignoreUnrecognized = JNI_FALSE; + + // create the JVM + JNIEnv * env = NULL; + jint result = (*JNI_CreateJavaVMProc)(&ms_jvm, reinterpret_cast(&env), &vm_args); + +#ifdef REMOTE_DEBUG_ON + if (jdwpBuffer != NULL) + { + delete[] jdwpBuffer; + jdwpBuffer = NULL; + } +#endif + + if (result != 0) + { + FATAL (true, ("Failed to CreateJavaVMProc: %d", result)); + ms_loaded = -1; + return; + } + ms_loaded = 1; + +#ifdef linux + if (ConfigServerGame::getTrapScriptCrashes()) + { + //set up signal handler for fatals in linux + OurSa.sa_handler = fatalHandler; + sigemptyset(&OurSa.sa_mask); + OurSa.sa_flags = 0; + IGNORE_RETURN(sigaction(SIGSEGV, &OurSa, &JavaSa)); + } +#endif + + // wait until the main thread tells us to shutdown + ms_shutdownJava->wait(); + + // clean up + IGNORE_RETURN(ms_jvm->DestroyJavaVM()); + ms_jvm = NULL; + +#ifdef linux + if (ConfigServerGame::getTrapScriptCrashes()) + { + // restore the default signal handler + IGNORE_RETURN(sigaction(SIGSEGV, &OrgSa, NULL)); + } +#endif + +#if defined(_WIN32) + IGNORE_RETURN(FreeLibrary(static_cast(libHandle))); +#elif defined(linux) + dlclose(libHandle); +#endif + + ms_loaded = 0; +} // JavaLibrary::initializeJavaThread + +//---------------------------------------------------------------------- + +/** + * Connects this thread to the Java VM and initializes our member vars that + * reference Java objects. + * + * @return true on success, false if we were unable to connect to Java or + * initialize our members + */ +bool JavaLibrary::connectToJava() +{ + if (ms_jvm == 0) + return false; + + // attach our thread to the VM + jint result = ms_jvm->AttachCurrentThread(reinterpret_cast(&ms_env), NULL); + if (result != 0) + { + FATAL(true, ("Failed to attach to the Java VM! Error code returned = %d", result)); + return false; + } + + int i; + jmethodID constructor; + LocalRefPtr localInstance; + LocalObjectArrayRefPtr localArrayInstance; + jclass tempClass; + + // set the local reference count limit + int localRefLimit = ConfigServerGame::getJavaLocalRefLimit(); + if (localRefLimit < 16) + localRefLimit = 16; + ms_env->EnsureLocalCapacity(localRefLimit); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + return false; + } + + // get the script_entry class + GET_CLASS(ms_clsScriptEntry, "script/script_entry"); + GET_METHOD(constructor, ms_clsScriptEntry, "", "(Ljava/lang/String;ZZIIIZ)V"); + GET_STATIC_METHOD(ms_midScriptEntryGetOwnerContext, ms_clsScriptEntry, "getOwnerContext", "()Lscript/obj_id;"); + GET_STATIC_METHOD(ms_midScriptEntryEnableLogging, ms_clsScriptEntry, "enableScriptLogging", "(Z)V"); + GET_STATIC_METHOD(ms_midScriptEntryEnableNewJediTracking, ms_clsScriptEntry, "enableNewJediTracking", "(Z)V"); + GET_STATIC_METHOD(ms_midScriptEntryGetFreeMem, ms_clsScriptEntry, "getFreeMemory", "()J"); + + // create an instance of script_entry class to initialze the system on the Java side + JavaString scriptPath(ConfigServerGame::getScriptPath()); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + return false; + } + jobject localEntry = ms_env->NewObject(ms_clsScriptEntry, constructor, + scriptPath.getValue(), + ConfigServerGame::getJavaConsoleDebugMessages(), + ConfigServerGame::getCrashOnScriptError(), + ConfigServerGame::getScriptWatcherWarnTime(), + ConfigServerGame::getScriptWatcherInterruptTime(), + ConfigServerGame::getScriptStackErrorLimit(), + ConfigServerGame::getScriptStackErrorLevel() == 1); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + return false; + } + ms_scriptEntry = ms_env->NewGlobalRef(localEntry); + ms_env->DeleteLocalRef(localEntry); + + // get the methodIDs for the runScript() and the unloadClass() methods + GET_STATIC_METHOD(ms_midRunOne,ms_clsScriptEntry, "runScript", "(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)I"); + GET_STATIC_METHOD(ms_midRunAll, ms_clsScriptEntry, "runScripts", "(Ljava/lang/String;[Ljava/lang/Object;)I"); + GET_STATIC_METHOD(ms_midCallMessages, ms_clsScriptEntry, "callMessageHandlers", "(Ljava/lang/String;JLscript/dictionary;)I"); + GET_STATIC_METHOD(ms_midRunConsoleHandler, ms_clsScriptEntry, "runConsoleHandler", "(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;"); + GET_STATIC_METHOD(ms_midUnload, ms_clsScriptEntry, "unloadClass", "(Ljava/lang/String;)Z"); + GET_STATIC_METHOD(ms_midGetClass, ms_clsScriptEntry, "getClass", "(Ljava/lang/String;)Ljava/lang/Class;"); + GET_STATIC_METHOD(ms_midGetScriptFunctions, ms_clsScriptEntry, "getScriptFunctions", "(Ljava/lang/String;)[Ljava/lang/String;"); + + // get the class and method ids for java.lang.Object + GET_CLASS(ms_clsObject, "java/lang/Object"); + + // get the class and method ids for java.lang.Class + GET_CLASS(ms_clsClass, "java/lang/Class"); + GET_METHOD(ms_midClassGetName, ms_clsClass, "getName", "()Ljava/lang/String;"); + GET_METHOD(ms_midClassGetMethods, ms_clsClass, "getMethods", "()[Ljava/lang/reflect/Method;"); + + // get the class and method ids for java.reflect.Method + GET_CLASS(ms_clsMethod, "java/lang/reflect/Method"); + GET_METHOD(ms_midMethodGetName, ms_clsMethod, "getName", "()Ljava/lang/String;"); + + // get the class and constructor methodID for java.lang.Boolean + GET_CLASS(ms_clsBoolean, "java/lang/Boolean"); + GET_CLASS(ms_clsBooleanArray, "[Ljava/lang/Boolean;"); + GET_METHOD(ms_midBoolean, ms_clsBoolean, "", "(Z)V"); + GET_METHOD(ms_midBooleanBooleanValue, ms_clsBoolean, "booleanValue", "()Z"); + + // get the class and constructor methodID for java.lang.Integer + GET_CLASS(ms_clsInteger, "java/lang/Integer"); + GET_CLASS(ms_clsIntegerArray, "[Ljava/lang/Integer;"); + GET_METHOD(ms_midInteger, ms_clsInteger, "", "(I)V"); + GET_METHOD(ms_midIntegerIntValue, ms_clsInteger, "intValue", "()I"); + + // get the class and constructor methodID for modifiable_int + GET_CLASS(ms_clsModifiableInt, "script/modifiable_int"); + GET_FIELD(ms_fidModifiableIntData, ms_clsModifiableInt, "m_data", "I"); + GET_METHOD(ms_midModifiableInt, ms_clsModifiableInt, "", "()V"); + + // create some global modifiable_int class instances to be used parameters for + // events + for (i = 0; i < MAX_MODIFIABLE_INT_PARAMS; ++i) + { + localInstance = createNewObject(ms_clsModifiableInt, ms_midModifiableInt); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + return false; + } + GlobalInstances::ms_modifiableInts[i] = GlobalRefPtr(new GlobalRef(*localInstance)); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + return false; + } + } + + // get the class and constructor methodID for java.lang.Float + GET_CLASS(ms_clsFloat, "java/lang/Float"); + GET_CLASS(ms_clsFloatArray, "[Ljava/lang/Float;"); + GET_METHOD(ms_midFloat, ms_clsFloat, "", "(F)V"); + GET_METHOD(ms_midFloatFloatValue, ms_clsFloat, "floatValue", "()F"); + + // get the class and constructor methodID for modifiable_float + GET_CLASS(ms_clsModifiableFloat, "script/modifiable_float"); + GET_FIELD(ms_fidModifiableFloatData, ms_clsModifiableFloat, "m_data", "F"); + GET_METHOD(ms_midModifiableFloat, ms_clsModifiableFloat, "", "()V"); + + // create some global modifiable_float class instances to be used parameters for + // events + for (i = 0; i < MAX_MODIFIABLE_FLOAT_PARAMS; ++i) + { + localInstance = createNewObject(ms_clsModifiableFloat, ms_midModifiableFloat); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + return false; + } + GlobalInstances::ms_modifiableFloats[i] = GlobalRefPtr(new GlobalRef(*localInstance)); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + return false; + } + } + + // get the class for java.lang.String + GET_CLASS(ms_clsString, "java/lang/String"); + GET_CLASS(ms_clsStringArray, "[Ljava/lang/String;"); + + // get the class and methods for java.util.Map and java.util.Hashtable + GET_CLASS(ms_clsMap, "java/util/Map"); + GET_METHOD(ms_midMapPut, ms_clsMap, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); + GET_METHOD(ms_midMapGet, ms_clsMap, "get", "(Ljava/lang/Object;)Ljava/lang/Object;"); + + GET_CLASS(ms_clsHashtable, "java/util/Hashtable"); + GET_METHOD(ms_midHashtable, ms_clsHashtable, "", "()V"); + + GET_CLASS(ms_clsThrowable, "java/lang/Throwable"); + GET_CLASS(ms_clsError, "java/lang/Error"); + GET_CLASS(ms_clsStackOverflowError, "java/lang/StackOverflowError"); + GET_METHOD(ms_midThrowableGetMessage, ms_clsThrowable, "getMessage", "()Ljava/lang/String;"); + + GET_CLASS(ms_clsThread, "java/lang/Thread"); + GET_STATIC_METHOD(ms_midThreadDumpStack, ms_clsThread, "dumpStack", "()V"); + + GET_CLASS(ms_clsInternalScriptError, "script/internal_script_exception"); + GET_CLASS(ms_clsInternalScriptSeriousError, "script/internal_script_error"); + GET_FIELD(ms_fidInternalScriptSeriousErrorError, ms_clsInternalScriptSeriousError, "wrappedError", "Ljava/lang/Error;"); + + // get the class and methods for dictionary + GET_CLASS(ms_clsDictionary, "script/dictionary"); + GET_METHOD(ms_midDictionary, ms_clsDictionary, "", "()V"); + GET_METHOD(ms_midDictionaryPack, ms_clsDictionary, "pack", "()[B"); + GET_METHOD(ms_midDictionaryKeys, ms_clsDictionary, "keys", "()Ljava/util/Enumeration;"); + GET_METHOD(ms_midDictionaryValues, ms_clsDictionary, "values", "()Ljava/util/Collection;"); + GET_METHOD(ms_midDictionaryPut, ms_clsDictionary, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); + GET_METHOD(ms_midDictionaryPutInt, ms_clsDictionary, "put", "(Ljava/lang/Object;I)Ljava/lang/Object;"); + GET_METHOD(ms_midDictionaryPutBool, ms_clsDictionary, "put", "(Ljava/lang/Object;Z)Ljava/lang/Object;"); + GET_METHOD(ms_midDictionaryPutFloat, ms_clsDictionary, "put", "(Ljava/lang/Object;F)Ljava/lang/Object;"); + GET_METHOD(ms_midDictionaryGet, ms_clsDictionary, "get", "(Ljava/lang/Object;)Ljava/lang/Object;"); + GET_STATIC_METHOD(ms_midDictionaryUnpack, ms_clsDictionary, "unpack", "([B)Lscript/dictionary;"); + + // get the class and methods for java.util.Collection + GET_CLASS(ms_clsCollection, "java/util/Collection"); + GET_METHOD(ms_midCollectionToArray, ms_clsCollection, "toArray", "()[Ljava/lang/Object;"); + + // get the class and methods for java.util.Enumeration + GET_CLASS(ms_clsEnumeration, "java/util/Enumeration"); + GET_METHOD(ms_midEnumerationHasMoreElements, ms_clsEnumeration, "hasMoreElements", "()Z"); + GET_METHOD(ms_midEnumerationNextElement, ms_clsEnumeration, "nextElement", "()Ljava/lang/Object;"); + + // get the class, field ids and constructor methodIDs for obj_var + GET_CLASS(ms_clsDynamicVariable, "script/obj_var"); + GET_FIELD(ms_fidDynamicVariableName, ms_clsDynamicVariable, "m_name", "Ljava/lang/String;"); + GET_FIELD(ms_fidDynamicVariableData, ms_clsDynamicVariable, "m_data", "Ljava/lang/Object;"); + GET_METHOD(ms_midDynamicVariableInt, ms_clsDynamicVariable, "", "(Ljava/lang/String;I)V"); + GET_METHOD(ms_midDynamicVariableIntArray, ms_clsDynamicVariable, "", "(Ljava/lang/String;[I)V"); + GET_METHOD(ms_midDynamicVariableFloat, ms_clsDynamicVariable, "", "(Ljava/lang/String;F)V"); + GET_METHOD(ms_midDynamicVariableFloatArray, ms_clsDynamicVariable, "", "(Ljava/lang/String;[F)V"); + GET_METHOD(ms_midDynamicVariableString, ms_clsDynamicVariable, "", "(Ljava/lang/String;Ljava/lang/String;)V"); + GET_METHOD(ms_midDynamicVariableStringArray, ms_clsDynamicVariable, "", "(Ljava/lang/String;[Ljava/lang/String;)V"); + GET_METHOD(ms_midDynamicVariableObjId, ms_clsDynamicVariable, "", "(Ljava/lang/String;J)V"); + GET_METHOD(ms_midDynamicVariableObjIdArray, ms_clsDynamicVariable, "", "(Ljava/lang/String;[J)V"); + GET_METHOD(ms_midDynamicVariableLocation, ms_clsDynamicVariable, "", "(Ljava/lang/String;Lscript/location;)V"); + GET_METHOD(ms_midDynamicVariableLocationArray, ms_clsDynamicVariable, "", "(Ljava/lang/String;[Lscript/location;)V"); + + // get the class, field ids and constructor methodIDs for obj_var_list + GET_CLASS(ms_clsDynamicVariableList, "script/obj_var_list"); + GET_METHOD(ms_midDynamicVariableList, ms_clsDynamicVariableList, "", "(Ljava/lang/String;I)V"); + GET_METHOD(ms_midDynamicVariableListSet, ms_clsDynamicVariableList, "setObjVar", "(Lscript/obj_var;)Z"); + GET_METHOD(ms_midDynamicVariableListSetInt, ms_clsDynamicVariableList, "setObjVar", "(Ljava/lang/String;I)Z"); + GET_METHOD(ms_midDynamicVariableListSetIntArray, ms_clsDynamicVariableList, "setObjVar", "(Ljava/lang/String;[I)Z"); + GET_METHOD(ms_midDynamicVariableListSetFloat, ms_clsDynamicVariableList, "setObjVar", "(Ljava/lang/String;F)Z"); + GET_METHOD(ms_midDynamicVariableListSetFloatArray, ms_clsDynamicVariableList, "setObjVar", "(Ljava/lang/String;[F)Z"); + GET_METHOD(ms_midDynamicVariableListSetString, ms_clsDynamicVariableList, "setObjVar", "(Ljava/lang/String;Ljava/lang/String;)Z"); + GET_METHOD(ms_midDynamicVariableListSetStringArray, ms_clsDynamicVariableList, "setObjVar", "(Ljava/lang/String;[Ljava/lang/String;)Z"); + GET_METHOD(ms_midDynamicVariableListSetObjId, ms_clsDynamicVariableList, "setObjVar", "(Ljava/lang/String;J)Z"); + GET_METHOD(ms_midDynamicVariableListSetObjIdArray, ms_clsDynamicVariableList, "setObjVar", "(Ljava/lang/String;[J)Z"); + GET_METHOD(ms_midDynamicVariableListSetLocation, ms_clsDynamicVariableList, "setObjVar", "(Ljava/lang/String;Lscript/location;)Z"); + GET_METHOD(ms_midDynamicVariableListSetLocationArray, ms_clsDynamicVariableList, "setObjVar", "(Ljava/lang/String;[Lscript/location;)Z"); + GET_METHOD(ms_midDynamicVariableListSetStringId, ms_clsDynamicVariableList, "setObjVar", "(Ljava/lang/String;Lscript/string_id;)Z"); + GET_METHOD(ms_midDynamicVariableListSetStringIdArray, ms_clsDynamicVariableList, "setObjVar", "(Ljava/lang/String;[Lscript/string_id;)Z"); + GET_METHOD(ms_midDynamicVariableListSetTransform, ms_clsDynamicVariableList, "setObjVar", "(Ljava/lang/String;Lscript/transform;)Z"); + GET_METHOD(ms_midDynamicVariableListSetTransformArray, ms_clsDynamicVariableList, "setObjVar", "(Ljava/lang/String;[Lscript/transform;)Z"); + GET_METHOD(ms_midDynamicVariableListSetVector, ms_clsDynamicVariableList, "setObjVar", "(Ljava/lang/String;Lscript/vector;)Z"); + GET_METHOD(ms_midDynamicVariableListSetVectorArray, ms_clsDynamicVariableList, "setObjVar", "(Ljava/lang/String;[Lscript/vector;)Z"); + + // get the class, field ids and constructor methodID for attribute + GET_CLASS(ms_clsAttribute, "script/attribute"); + GET_FIELD(ms_fidAttributeType, ms_clsAttribute, "m_type", "I"); + GET_FIELD(ms_fidAttributeValue, ms_clsAttribute, "m_value", "I"); + GET_METHOD(ms_midAttribute, ms_clsAttribute, "", "(II)V"); + + // get the class, field ids and constructor methodID for attribMod + GET_CLASS(ms_clsAttribMod, "script/attrib_mod"); + GET_FIELD(ms_fidAttribModName, ms_clsAttribMod, "m_name", "Ljava/lang/String;"); + GET_FIELD(ms_fidAttribModSkill, ms_clsAttribMod, "m_skill", "Ljava/lang/String;"); + GET_FIELD(ms_fidAttribModType, ms_clsAttribMod, "m_attrib", "I"); + GET_FIELD(ms_fidAttribModValue, ms_clsAttribMod, "m_value", "I"); + GET_FIELD(ms_fidAttribModTime, ms_clsAttribMod, "m_duration", "F"); + GET_FIELD(ms_fidAttribModAttack, ms_clsAttribMod, "m_attack", "F"); + GET_FIELD(ms_fidAttribModDecay, ms_clsAttribMod, "m_decay", "F"); + GET_FIELD(ms_fidAttribModFlags, ms_clsAttribMod, "m_flags", "I"); + GET_METHOD(ms_midAttribMod, ms_clsAttribMod, "", "()V"); + + // create some attribMod instances for use as script paramters + for (i = 0; i < MAX_ATTRIB_MOD_PARAMS; ++i) + { + localInstance = createNewObject(ms_clsAttribMod, ms_midAttribMod); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + return false; + } + GlobalInstances::ms_attribMods[i] = GlobalRefPtr(new GlobalRef(*localInstance)); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + return false; + } + } + // create the attribModList + for (i = 0; i < MAX_RECURSION_COUNT; ++i) + { + localArrayInstance = createNewObjectArray(MAX_ATTRIB_MOD_PARAMS, ms_clsAttribMod); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + return false; + } + ms_attribModList[i] = GlobalArrayRefPtr(new GlobalArrayRef(*localArrayInstance)); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + return false; + } + } + + //------- + // get the class, field ids and constructor methodID for mental state + GET_CLASS(ms_clsMentalState, "script/mental_state"); + GET_FIELD(ms_fidMentalStateType, ms_clsMentalState, "m_type", "I"); + GET_FIELD(ms_fidMentalStateValue, ms_clsMentalState, "m_value", "F"); + GET_METHOD(ms_midMentalState, ms_clsMentalState, "", "(IF)V"); + + // get the class, field ids and constructor methodID for mental_state_mod + GET_CLASS(ms_clsMentalStateMod, "script/mental_state_mod"); + GET_FIELD(ms_fidMentalStateModType, ms_clsMentalStateMod, "m_mental_state", "I"); + GET_FIELD(ms_fidMentalStateModValue, ms_clsMentalStateMod, "m_value", "F"); + GET_FIELD(ms_fidMentalStateModTime, ms_clsMentalStateMod, "m_duration", "F"); + GET_FIELD(ms_fidMentalStateModAttack, ms_clsMentalStateMod, "m_attack", "F"); + GET_FIELD(ms_fidMentalStateModDecay, ms_clsMentalStateMod, "m_decay", "F"); + GET_METHOD(ms_midMentalStateMod, ms_clsMentalStateMod, "", "(IFFFF)V"); + + // create some mentalStateMod instances for use as script paramters + for (i = 0; i < MAX_MENTAL_STATE_MOD_PARAMS; ++i) + { + localInstance = createNewObject(ms_clsMentalStateMod, ms_midMentalStateMod, + 0, 0, 0, 0, 0); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + return false; + } + GlobalInstances::ms_mentalStateMods[i] = GlobalRefPtr(new GlobalRef(*localInstance)); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + return false; + } + } + // create the mentalStateModList + for (i = 0; i < MAX_RECURSION_COUNT; ++i) + { + localArrayInstance = createNewObjectArray(MAX_MENTAL_STATE_MOD_PARAMS, ms_clsMentalStateMod); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + return false; + } + ms_mentalStateModList[i] = GlobalArrayRefPtr(new GlobalArrayRef(*localArrayInstance)); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + return false; + } + } + + //---------------------------------------------------------------------- + // MenuInfo + + GET_CLASS(ms_clsMenuInfo, "script/menu_info"); + GET_METHOD(ms_midMenuInfo, ms_clsMenuInfo, "", "()V"); + GET_METHOD(ms_midMenuInfoSetMenuItemsInternal, ms_clsMenuInfo, "setMenuItemsInternal", "([Lscript/menu_info_data;)Z"); + GET_METHOD(ms_midMenuInfoGetMenuItemsInternal, ms_clsMenuInfo, "getMenuItemsInternal", "()[Ljava/lang/Object;"); + + //-- create the global instance for the menu_info + { + localInstance = createNewObject(ms_clsMenuInfo, ms_midMenuInfo); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + return false; + } + GlobalInstances::ms_menuInfo = GlobalRefPtr(new GlobalRef(*localInstance)); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + return false; + } + } + + //-- menu_info_data + // + GET_CLASS(ms_clsMenuInfoData, "script/menu_info_data"); + GET_FIELD(ms_fidMenuInfoDataId, ms_clsMenuInfoData, "m_id", "I"); + GET_FIELD(ms_fidMenuInfoDataParent, ms_clsMenuInfoData, "m_parent", "I"); + GET_FIELD(ms_fidMenuInfoDataLabel, ms_clsMenuInfoData, "m_label", "Lscript/string_id;"); + GET_FIELD(ms_fidMenuInfoDataType, ms_clsMenuInfoData, "m_type", "I"); + GET_FIELD(ms_fidMenuInfoDataEnabled, ms_clsMenuInfoData, "m_enabled", "Z"); + GET_FIELD(ms_fidMenuInfoDataServerNotify, ms_clsMenuInfoData, "m_serverNotify", "Z"); + GET_METHOD(ms_midMenuInfoData, ms_clsMenuInfoData, "", "()V"); + + // + // get class and fields for class draft_schematic + // + GET_CLASS(ms_clsDraftSchematic, "script/draft_schematic"); + GET_FIELD(ms_fidDraftSchematicCategory, ms_clsDraftSchematic, "m_category", "I"); + GET_FIELD(ms_fidDraftSchematicComplexity, ms_clsDraftSchematic, "m_complexity", "F"); + GET_FIELD(ms_fidDraftSchematicSlots, ms_clsDraftSchematic, "m_slots", "[Lscript/draft_schematic$slot;"); + GET_FIELD(ms_fidDraftSchematicAttribs, ms_clsDraftSchematic, "m_attribs", "[Lscript/draft_schematic$attribute;"); + GET_FIELD(ms_fidDraftSchematicExperimentalAttribs, ms_clsDraftSchematic, "m_experimentalAttribs", "[Lscript/draft_schematic$attribute;"); + GET_FIELD(ms_fidDraftSchematicCustomizations, ms_clsDraftSchematic, "m_customizations", "[Lscript/draft_schematic$custom;"); + GET_FIELD(ms_fidDraftSchematicAttribMap, ms_clsDraftSchematic, "m_attribMap", "Ljava/util/Hashtable;"); + GET_FIELD(ms_fidDraftSchematicObjectTemplateCreated, ms_clsDraftSchematic, "m_objectTemplateCreated", "I"); + GET_FIELD(ms_fidDraftSchematicScripts, ms_clsDraftSchematic, "m_scripts", "[Ljava/lang/String;"); + + // get the draft_schematic.slot data + GET_CLASS(ms_clsDraftSchematicSlot, "script/draft_schematic$slot"); + GET_FIELD(ms_fidDraftSchematicSlotName, ms_clsDraftSchematicSlot, "name", "Lscript/string_id;"); + GET_FIELD(ms_fidDraftSchematicSlotOption, ms_clsDraftSchematicSlot, "slotOption", "I"); + GET_FIELD(ms_fidDraftSchematicSlotIngredientType, ms_clsDraftSchematicSlot, "ingredientType", "I"); + GET_FIELD(ms_fidDraftSchematicSlotIngredientName, ms_clsDraftSchematicSlot, "ingredientName", "Ljava/lang/String;"); + GET_FIELD(ms_fidDraftSchematicSlotIngredients, ms_clsDraftSchematicSlot, "ingredients", "[Lscript/draft_schematic$simple_ingredient;"); + GET_FIELD(ms_fidDraftSchematicSlotComplexity, ms_clsDraftSchematicSlot, "complexity", "F"); + GET_FIELD(ms_fidDraftSchematicSlotAmountRequired, ms_clsDraftSchematicSlot, "amountRequired", "I"); + GET_FIELD(ms_fidDraftSchematicSlotAppearance, ms_clsDraftSchematicSlot, "appearance", "Ljava/lang/String;"); + + // get the draft_schematic.attribute data + GET_CLASS(ms_clsDraftSchematicAttrib, "script/draft_schematic$attribute"); + GET_FIELD(ms_fidDraftSchematicAttribName, ms_clsDraftSchematicAttrib, "name", "Lscript/string_id;"); + GET_FIELD(ms_fidDraftSchematicAttribMinValue, ms_clsDraftSchematicAttrib, "minValue", "F"); + GET_FIELD(ms_fidDraftSchematicAttribMaxValue, ms_clsDraftSchematicAttrib, "maxValue", "F"); + GET_FIELD(ms_fidDraftSchematicAttribResourceMaxValue, ms_clsDraftSchematicAttrib, "resourceMaxValue", "F"); + GET_FIELD(ms_fidDraftSchematicAttribCurrentValue, ms_clsDraftSchematicAttrib, "currentValue", "F"); + + // get the draft_schematic.simple_ingredient data + GET_CLASS(ms_clsDraftSchematicSimpleIngredient, "script/draft_schematic$simple_ingredient"); + GET_FIELD(ms_fidDraftSchematicSimpleIngredientIngredient, ms_clsDraftSchematicSimpleIngredient, "ingredient", "Lscript/obj_id;"); + GET_FIELD(ms_fidDraftSchematicSimpleIngredientCount, ms_clsDraftSchematicSimpleIngredient, "count", "I"); + GET_FIELD(ms_fidDraftSchematicSimpleIngredientSource, ms_clsDraftSchematicSimpleIngredient, "source", "Lscript/obj_id;"); + GET_FIELD(ms_fidDraftSchematicSimpleIngredientXpType, ms_clsDraftSchematicSimpleIngredient, "xpType", "I"); + GET_FIELD(ms_fidDraftSchematicSimpleIngredientXpAmount, ms_clsDraftSchematicSimpleIngredient, "xpAmount", "I"); + + // get the draft_schematic.custom data + GET_CLASS(ms_clsDraftSchematicCustom, "script/draft_schematic$custom"); + GET_FIELD(ms_fidDraftSchematicCustomName, ms_clsDraftSchematicCustom, "name", "Ljava/lang/String;"); + GET_FIELD(ms_fidDraftSchematicCustomValue, ms_clsDraftSchematicCustom, "value", "I"); + GET_FIELD(ms_fidDraftSchematicCustomMinValue, ms_clsDraftSchematicCustom, "minValue", "I"); + GET_FIELD(ms_fidDraftSchematicCustomMaxValue, ms_clsDraftSchematicCustom, "maxValue", "I"); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // customization data + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + GET_CLASS(ms_clsCustomVar, "script/custom_var"); + GET_METHOD(ms_midCustomVarObjIdStringInt, ms_clsCustomVar, "", "(JLjava/lang/String;I)V"); + + GET_CLASS(ms_clsRangedIntCustomVar, "script/ranged_int_custom_var"); + GET_METHOD(ms_midRangedIntCustomVar, ms_clsRangedIntCustomVar, "", "(JLjava/lang/String;III)V"); + + GET_CLASS(ms_clsPalcolorCustomVar, "script/palcolor_custom_var"); + GET_METHOD(ms_midPalcolorCustomVar, ms_clsPalcolorCustomVar, "", "(JLjava/lang/String;III)V"); + + GET_CLASS(ms_clsColor, "script/color"); + GET_METHOD(ms_midColor, ms_clsColor, "", "(IIII)V"); + + //---------------------------------------------------------------------- + + // get the class, field ids and constructor methodID for location + GET_CLASS(ms_clsLocation, "script/location"); + GET_CLASS(ms_clsLocationArray, "[Lscript/location;"); + GET_FIELD(ms_fidLocationX, ms_clsLocation, "x", "F"); + GET_FIELD(ms_fidLocationY, ms_clsLocation, "y", "F"); + GET_FIELD(ms_fidLocationZ, ms_clsLocation, "z", "F"); + GET_FIELD(ms_fidLocationArea, ms_clsLocation, "area", "Ljava/lang/String;"); + GET_FIELD(ms_fidLocationCell, ms_clsLocation, "cell", "Lscript/obj_id;"); + + // get class and fields for map location + GET_CLASS(ms_clsMapLocation, "script/map_location"); + GET_METHOD(ms_midMapLocation, ms_clsMapLocation, "", "(JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;JJB)V"); + + // get class and fields for class region + GET_CLASS(ms_clsRegion, "script/region"); + GET_FIELD(ms_fidRegionName, ms_clsRegion, "m_name", "Ljava/lang/String;"); + GET_FIELD(ms_fidRegionPlanet, ms_clsRegion, "m_planetName", "Ljava/lang/String;"); + GET_METHOD(ms_midRegion, ms_clsRegion, "", "(Ljava/lang/String;IIIIIIIILjava/lang/String;)V"); + + // get class and fields for base_class.range_info + GET_CLASS(ms_clsBaseClassRangeInfo, "script/base_class$range_info"); + GET_FIELD(ms_fidBaseClassRangeInfoMinRange, ms_clsBaseClassRangeInfo, "minRange", "F"); + GET_FIELD(ms_fidBaseClassRangeInfoMaxRange, ms_clsBaseClassRangeInfo, "maxRange", "F"); + + // get class and fields for base_class.attacker_results + GET_CLASS(ms_clsBaseClassAttackerResults, "script/base_class$attacker_results"); + GET_FIELD(ms_fidBaseClassAttackerResultsId, ms_clsBaseClassAttackerResults, "id", "Lscript/obj_id;"); + GET_FIELD(ms_fidBaseClassAttackerResultsWeapon, ms_clsBaseClassAttackerResults, "weapon", "Lscript/obj_id;"); + GET_FIELD(ms_fidBaseClassAttackerResultsPosture, ms_clsBaseClassAttackerResults, "endPosture", "I"); + GET_FIELD(ms_fidBaseClassAttackerResultsTrailBits, ms_clsBaseClassAttackerResults, "m_trailBits", "I"); + GET_FIELD(ms_fidBaseClassAttackerResultsClientEffectId, ms_clsBaseClassAttackerResults, "clientEffectId", "I"); + GET_FIELD(ms_fidBaseClassAttackerResultsActionName, ms_clsBaseClassAttackerResults, "actionName", "I"); + GET_FIELD(ms_fidBaseClassAttackerResultsUseLocation, ms_clsBaseClassAttackerResults, "useLocation", "Z"); + GET_FIELD(ms_fidBaseClassAttackerResultsTargetLocation, ms_clsBaseClassAttackerResults, "targetLocation", "Lscript/vector;"); + GET_FIELD(ms_fidBaseClassAttackerResultsTargetCell, ms_clsBaseClassAttackerResults, "targetCell", "Lscript/obj_id;"); + + // get class and fields for base_class.defender_results + GET_CLASS(ms_clsBaseClassDefenderResults, "script/base_class$defender_results"); + GET_FIELD(ms_fidBaseClassDefenderResultsId, ms_clsBaseClassDefenderResults, "id", "Lscript/obj_id;"); + GET_FIELD(ms_fidBaseClassDefenderResultsPosture, ms_clsBaseClassDefenderResults, "endPosture", "I"); + GET_FIELD(ms_fidBaseClassDefenderResultsResult, ms_clsBaseClassDefenderResults, "result", "I"); + GET_FIELD(ms_fidBaseClassDefenderResultsClientEffectId, ms_clsBaseClassDefenderResults, "clientEffectId", "I"); + GET_FIELD(ms_fidBaseClassDefenderResultsHitLocation, ms_clsBaseClassDefenderResults, "hitLocation", "I"); + GET_FIELD(ms_fidBaseClassDefenderDamageAmount, ms_clsBaseClassDefenderResults, "damageAmount", "I"); + + // get class obj_id info + GET_CLASS(ms_clsObjId, "script/obj_id"); + GET_CLASS(ms_clsObjIdArray, "[Lscript/obj_id;"); + GET_METHOD(ms_midObjIdGetValue, ms_clsObjId, "getValue", "()J"); + GET_METHOD(ms_midObjIdSetAuthoritative, ms_clsObjId, "setAuthoritative", "(ZI)V"); + GET_METHOD(ms_midObjIdSetLoaded, ms_clsObjId, "setLoaded", "()V"); + GET_METHOD(ms_midObjIdSetInitialized, ms_clsObjId, "setInitialized", "()V"); + GET_METHOD(ms_midObjIdSetLoggedIn, ms_clsObjId, "setLoggedIn", "(Z)V"); + GET_METHOD(ms_midObjIdAttachScript, ms_clsObjId, "attachScript", "(Ljava/lang/String;)V"); + GET_METHOD(ms_midObjIdAttachScripts, ms_clsObjId, "attachScript", "([Ljava/lang/String;)V"); + GET_METHOD(ms_midObjIdDetachScript, ms_clsObjId, "detachScript", "(Ljava/lang/String;)V"); + GET_METHOD(ms_midObjIdDetachAllScripts, ms_clsObjId, "detachAllScripts", "()V"); + GET_METHOD(ms_midObjIdSetScriptVarInt, ms_clsObjId, "setScriptVar", "(Ljava/lang/String;I)V"); + GET_METHOD(ms_midObjIdSetScriptVarFloat, ms_clsObjId, "setScriptVar", "(Ljava/lang/String;F)V"); + GET_METHOD(ms_midObjIdSetScriptVarString, ms_clsObjId, "setScriptVar", "(Ljava/lang/String;Ljava/lang/String;)V"); + GET_METHOD(ms_midObjIdClearScriptVars, ms_clsObjId, "clearScriptVars", "()V"); + GET_STATIC_METHOD(ms_midObjIdGetObjId, ms_clsObjId, "getObjId", "(J)Lscript/obj_id;"); + GET_STATIC_METHOD(ms_midObjIdClearObjId, ms_clsObjId, "clearObjId", "(J)V"); + GET_STATIC_METHOD(ms_midObjIdFlagDestroyed, ms_clsObjId, "flagDestroyed", "(J)V"); + GET_STATIC_METHOD(ms_midObjIdPackAllDeltaScriptVars, ms_clsObjId, "packAllScriptVars", "()V"); + GET_STATIC_METHOD(ms_midObjIdPackScriptVars, ms_clsObjId, "packScriptVars", "(J)[B"); + GET_STATIC_METHOD(ms_midObjIdUnpackDeltaScriptVars, ms_clsObjId, "unpackDeltaScriptVars", "(J[B)V"); + GET_STATIC_METHOD(ms_midObjIdUnpackScriptVars, ms_clsObjId, "unpackScriptVars", "(J[B)V"); + + // get class combat_engine info + GET_CLASS(ms_clsCombatEngine, "script/combat_engine"); + GET_CLASS(ms_clsCombatEngineCombatantData, "script/combat_engine$combatant_data"); + GET_FIELD(ms_fidCombatEngineCombatantDataPos, ms_clsCombatEngineCombatantData, "pos", "Lscript/location;"); + GET_FIELD(ms_fidCombatEngineCombatantDataWorldPos, ms_clsCombatEngineCombatantData, "worldPos", "Lscript/location;"); + GET_FIELD(ms_fidCombatEngineCombatantDataRadius, ms_clsCombatEngineCombatantData, "radius", "F"); + GET_FIELD(ms_fidCombatEngineCombatantDataIsCreature, ms_clsCombatEngineCombatantData, "isCreature", "Z"); + GET_FIELD(ms_fidCombatEngineCombatantDataPosture, ms_clsCombatEngineCombatantData, "posture", "I"); + GET_FIELD(ms_fidCombatEngineCombatantDataLocomotion, ms_clsCombatEngineCombatantData, "locomotion", "I"); + GET_FIELD(ms_fidCombatEngineCombatantDataScriptMod, ms_clsCombatEngineCombatantData, "scriptMod", "I"); + + GET_CLASS(ms_clsCombatEngineAttackerData, "script/combat_engine$attacker_data"); + GET_FIELD(ms_fidCombatEngineAttackerDataWeaponSkill, ms_clsCombatEngineAttackerData, "weaponSkillMod", "I"); + GET_FIELD(ms_fidCombatEngineAttackerDataAims, ms_clsCombatEngineAttackerData, "aims", "I"); + + GET_CLASS(ms_clsCombatEngineDefenderData, "script/combat_engine$defender_data"); + GET_FIELD(ms_fidCombatEngineDefenderDataCombatSkeleton, ms_clsCombatEngineDefenderData, "combatSkeleton", "I"); + GET_FIELD(ms_fidCombatEngineDefenderDataCover, ms_clsCombatEngineDefenderData, "cover", "I"); + GET_FIELD(ms_fidCombatEngineDefenderDataHitLocationChances, ms_clsCombatEngineDefenderData, "hitLocationChances", "[I"); + + GET_CLASS(ms_clsCombatEngineWeaponData, "script/combat_engine$weapon_data"); + GET_FIELD(ms_fidCombatEngineWeaponDataId, ms_clsCombatEngineWeaponData, "id", "Lscript/obj_id;"); + GET_FIELD(ms_fidCombatEngineWeaponDataMinDamage, ms_clsCombatEngineWeaponData, "minDamage", "I"); + GET_FIELD(ms_fidCombatEngineWeaponDataMaxDamage, ms_clsCombatEngineWeaponData, "maxDamage", "I"); + GET_FIELD(ms_fidCombatEngineWeaponDataWeaponType, ms_clsCombatEngineWeaponData, "weaponType", "I"); + GET_FIELD(ms_fidCombatEngineWeaponDataAttackType, ms_clsCombatEngineWeaponData, "attackType", "I"); + GET_FIELD(ms_fidCombatEngineWeaponDataDamageType, ms_clsCombatEngineWeaponData, "damageType", "I"); + GET_FIELD(ms_fidCombatEngineWeaponDataElementalType, ms_clsCombatEngineWeaponData, "elementalType", "I"); + GET_FIELD(ms_fidCombatEngineWeaponDataElementalValue, ms_clsCombatEngineWeaponData, "elementalValue", "I"); + GET_FIELD(ms_fidCombatEngineWeaponDataAttackSpeed, ms_clsCombatEngineWeaponData, "attackSpeed", "F"); + GET_FIELD(ms_fidCombatEngineWeaponDataWoundChance, ms_clsCombatEngineWeaponData, "woundChance", "F"); + GET_FIELD(ms_fidCombatEngineWeaponDataAccuracy, ms_clsCombatEngineWeaponData, "accuracy", "I"); + GET_FIELD(ms_fidCombatEngineWeaponDataMinRange, ms_clsCombatEngineWeaponData, "minRange", "F"); + GET_FIELD(ms_fidCombatEngineWeaponDataMaxRange, ms_clsCombatEngineWeaponData, "maxRange", "F"); + GET_FIELD(ms_fidCombatEngineWeaponDataDamageRadius, ms_clsCombatEngineWeaponData, "damageRadius", "F"); + GET_FIELD(ms_fidCombatEngineWeaponDataAttackCost, ms_clsCombatEngineWeaponData, "attackCost", "I"); + GET_FIELD(ms_fidCombatEngineWeaponDataIsDisabled, ms_clsCombatEngineWeaponData, "isDisabled", "Z"); + + GET_CLASS(ms_clsCombatEngineHitResult, "script/combat_engine$hit_result"); + GET_FIELD(ms_fidCombatEngineHitResultSuccess, ms_clsCombatEngineHitResult, "success", "Z"); + GET_FIELD(ms_fidCombatEngineHitResultCritical, ms_clsCombatEngineHitResult, "critical", "Z"); + GET_FIELD(ms_fidCombatEngineHitResultGlancing, ms_clsCombatEngineHitResult, "glancing", "Z"); + GET_FIELD(ms_fidCombatEngineHitResultCrushing, ms_clsCombatEngineHitResult, "crushing", "Z"); + GET_FIELD(ms_fidCombatEngineHitResultStrikethrough, ms_clsCombatEngineHitResult, "strikethrough", "Z"); + GET_FIELD(ms_fidCombatEngineHitResultStrikethroughAmount, ms_clsCombatEngineHitResult, "strikethroughAmmount", "F"); + GET_FIELD(ms_fidCombatEngineHitResultEvadeResult, ms_clsCombatEngineHitResult, "evadeResult", "Z"); + GET_FIELD(ms_fidCombatEngineHitResultEvadeAmount, ms_clsCombatEngineHitResult, "evadeAmmount", "F"); + GET_FIELD(ms_fidCombatEngineHitResultBlockResult, ms_clsCombatEngineHitResult, "blockResult", "Z"); + GET_FIELD(ms_fidCombatEngineHitResultBlock, ms_clsCombatEngineHitResult, "block", "I"); + GET_FIELD(ms_fidCombatEngineHitResultDodge, ms_clsCombatEngineHitResult, "dodge", "Z"); + GET_FIELD(ms_fidCombatEngineHitResultParry, ms_clsCombatEngineHitResult, "parry", "Z"); + GET_FIELD(ms_fidCombatEngineHitResultProc, ms_clsCombatEngineHitResult, "proc", "Z"); + GET_FIELD(ms_fidCombatEngineHitResultBaseRoll, ms_clsCombatEngineHitResult, "baseRoll", "I"); + GET_FIELD(ms_fidCombatEngineHitResultFinalRoll, ms_clsCombatEngineHitResult, "finalRoll", "I"); + GET_FIELD(ms_fidCombatEngineHitResultAttackVal, ms_clsCombatEngineHitResult, "attackVal", "F"); + GET_FIELD(ms_fidCombatEngineHitResultCanSee, ms_clsCombatEngineHitResult, "canSee", "Z"); + GET_FIELD(ms_fidCombatEngineHitResultHitLocation, ms_clsCombatEngineHitResult, "hitLocation", "I"); + GET_FIELD(ms_fidCombatEngineHitResultDamage, ms_clsCombatEngineHitResult, "damage", "I"); + GET_FIELD(ms_fidCombatEngineHitResultDamageType, ms_clsCombatEngineHitResult, "damageType", "I"); + GET_FIELD(ms_fidCombatEngineHitResultRawDamage, ms_clsCombatEngineHitResult, "rawDamage", "I"); + GET_FIELD(ms_fidCombatEngineHitResultElementalDamage, ms_clsCombatEngineHitResult, "elementalDamage", "I"); + GET_FIELD(ms_fidCombatEngineHitResultElementalDamageType, ms_clsCombatEngineHitResult, "elementalDamageType", "I"); + GET_FIELD(ms_fidCombatEngineHitResultBleedDamage, ms_clsCombatEngineHitResult, "bleedDamage", "I"); + GET_FIELD(ms_fidCombatEngineHitResultCritDamage, ms_clsCombatEngineHitResult, "critDamage", "I"); + GET_FIELD(ms_fidCombatEngineHitResultBlockedDamage, ms_clsCombatEngineHitResult, "blockedDamage", "I"); + GET_FIELD(ms_fidCombatEngineHitResultBlockingArmor, ms_clsCombatEngineHitResult, "blockingArmor", "Lscript/obj_id;"); + GET_FIELD(ms_fidCombatEngineHitResultBleedingChance, ms_clsCombatEngineHitResult, "bleedingChance", "I"); + + // be used parameters for events + GET_CLASS(ms_clsStringId, "script/string_id"); + GET_CLASS(ms_clsStringIdArray, "[Lscript/string_id;"); + GET_CLASS(ms_clsModifiableStringId, "script/modifiable_string_id"); + GET_FIELD(ms_fidStringIdTable, ms_clsStringId, "m_table", "Ljava/lang/String;"); + GET_FIELD(ms_fidStringIdAsciiId, ms_clsStringId, "m_asciiId", "Ljava/lang/String;"); + GET_FIELD(ms_fidStringIdIndexId, ms_clsStringId, "m_indexId", "I"); + GET_METHOD(ms_midStringId, ms_clsStringId, "", "(Ljava/lang/String;I)V"); + + for (i = 0; i < MAX_STRING_ID_PARAMS; ++i) + { + localInstance = createNewObject(ms_clsStringId, ms_midStringId, NULL, -1); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + return false; + } + GlobalInstances::ms_stringIds[i] = GlobalRefPtr(new GlobalRef(*localInstance)); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + return false; + } + } + + GET_METHOD(constructor, ms_clsModifiableStringId, "", "(Ljava/lang/String;I)V"); + for (i = 0; i < MAX_MODIFIABLE_STRING_ID_PARAMS; ++i) + { + localInstance = createNewObject(ms_clsModifiableStringId, constructor, + NULL, -1); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + return false; + } + GlobalInstances::ms_modifiableStringIds[i] = GlobalRefPtr(new GlobalRef(*localInstance)); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + return false; + } + } + + // get class and fields for class transform + GET_CLASS(ms_clsTransform, "script/transform"); + GET_CLASS(ms_clsTransformArray, "[Lscript/transform;"); + GET_METHOD(ms_midTransform, ms_clsTransform, "", "(FFFFFFFFFFFF)V"); + GET_FIELD(ms_fidTransformMatrix, ms_clsTransform, "matrix", "[[F"); + + // get class and fields for class vector + GET_CLASS(ms_clsVector, "script/vector"); + GET_CLASS(ms_clsVectorArray, "[Lscript/vector;"); + GET_FIELD(ms_fidVectorX, ms_clsVector, "x", "F"); + GET_FIELD(ms_fidVectorY, ms_clsVector, "y", "F"); + GET_FIELD(ms_fidVectorZ, ms_clsVector, "z", "F"); + + GET_CLASS(ms_clsResourceDensity, "script/resource_density"); + GET_FIELD(ms_fidResourceDensityResourceType, ms_clsResourceDensity, "m_resourceType", "Lscript/obj_id;"); + GET_FIELD(ms_fidResourceDensityDensity, ms_clsResourceDensity, "m_density", "F"); + + GET_CLASS(ms_clsResourceAttribute, "script/resource_attribute"); + GET_FIELD(ms_fidResourceAttributeName, ms_clsResourceAttribute, "m_name", "Ljava/lang/String;"); + GET_FIELD(ms_fidResourceAttributeValue, ms_clsResourceAttribute, "m_value", "I"); + + GET_CLASS(ms_clsLibrarySpaceTransition, "script/library/space_transition"); + GET_STATIC_METHOD(ms_midLibrarySpaceTransitionSetPlayerOvert, ms_clsLibrarySpaceTransition, "setPlayerOvert", "(J)V"); + GET_STATIC_METHOD(ms_midLibrarySpaceTransitionClearOvertStatus, ms_clsLibrarySpaceTransition, "clearOvertStatus", "(J)V"); + + /////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////// + + // get class and field info needed by the CS Handler stuff. These may not have been + // written specifically for the CS Handler. + + + + GET_CLASS( ms_clsLibraryDump, "script/library/dump" ); + GET_STATIC_METHOD( ms_midLibraryDumpDumpTargetInfo, ms_clsLibraryDump, "getTargetInfoStringByLong", "(J)Ljava/lang/String;" ); + + GET_CLASS( ms_clsLibraryGMLib, "script/library/gmlib" ); + GET_STATIC_METHOD( ms_midLibraryGMLibFreeze, ms_clsLibraryGMLib, "freezePlayer", "(J)Ljava/lang/String;" ); + GET_STATIC_METHOD( ms_midLibraryGMLibUnfreeze, ms_clsLibraryGMLib, "unFreezePlayer", "(J)V" ); + + + ///////////////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////////////// + // register our native methods + bool registerSuccess = true; + registerSuccess &= ScriptMethodsActionStatesNamespace::install(); + registerSuccess &= ScriptMethodsAiNamespace::install(); + registerSuccess &= ScriptMethodsAnimationNamespace::install(); + registerSuccess &= ScriptMethodsAttributesNamespace::install(); + registerSuccess &= ScriptMethodsAuctionNamespace::install(); + registerSuccess &= ScriptMethodsBankNamespace::install(); + registerSuccess &= ScriptMethodsBeastMasterNamespace::install(); + registerSuccess &= ScriptMethodsBroadcastingNamespace::install(); + registerSuccess &= ScriptMethodsBuffBuilderNamespace::install(); + registerSuccess &= ScriptMethodsBuffNamespace::install(); + registerSuccess &= ScriptMethodsChatNamespace::install(); + registerSuccess &= ScriptMethodsCityNamespace::install(); + registerSuccess &= ScriptMethodsClientEffectNamespace::install(); + registerSuccess &= ScriptMethodsClusterWideDataNamespace::install(); + registerSuccess &= ScriptMethodsCollectionNamespace::install(); + registerSuccess &= ScriptMethodsCombatNamespace::install(); + registerSuccess &= ScriptMethodsCommandQueueNamespace::install(); + registerSuccess &= ScriptMethodsConsoleNamespace::install(); + registerSuccess &= ScriptMethodsContainersNamespace::install(); + registerSuccess &= ScriptMethodsCraftingNamespace::install(); + registerSuccess &= ScriptMethodsDataTableNamespace::install(); + registerSuccess &= ScriptMethodsDebugNamespace::install(); + registerSuccess &= ScriptMethodsDynamicVariableNamespace::install(); + registerSuccess &= ScriptMethodsFormNamespace::install(); + registerSuccess &= ScriptMethodsGlobalQueryNamespace::install(); + registerSuccess &= ScriptMethodsGuildNamespace::install(); + registerSuccess &= ScriptMethodsHateListNamespace::install(); + registerSuccess &= ScriptMethodsHolocubeNamespace::install(); + registerSuccess &= ScriptMethodsHyperspaceNamespace::install(); + registerSuccess &= ScriptMethodsImageDesignNamespace::install(); + registerSuccess &= ScriptMethodsInstallationNamespace::install(); + registerSuccess &= ScriptMethodsInterestNamespace::install(); + registerSuccess &= ScriptMethodsInteriorsNamespace::install(); + registerSuccess &= ScriptMethodsJediNamespace::install(); + registerSuccess &= ScriptMethodsMapNamespace::install(); + registerSuccess &= ScriptMethodsMentalStatesNamespace::install(); + registerSuccess &= ScriptMethodsMenuNamespace::install(); + registerSuccess &= ScriptMethodsMissionNamespace::install(); + registerSuccess &= ScriptMethodsMoneyNamespace::install(); + registerSuccess &= ScriptMethodsMountNamespace::install(); + registerSuccess &= ScriptMethodsNewbieTutorialNamespace::install(); + registerSuccess &= ScriptMethodsNotificationNamespace::install(); + registerSuccess &= ScriptMethodsNpcNamespace::install(); + registerSuccess &= ScriptMethodsObjectCreateNamespace::install(); + registerSuccess &= ScriptMethodsObjectInfoNamespace::install(); + registerSuccess &= ScriptMethodsObjectMoveNamespace::install(); + registerSuccess &= ScriptMethodsPermissionsNamespace::install(); + registerSuccess &= ScriptMethodsPilotNamespace::install(); + registerSuccess &= ScriptMethodsPlanetNamespace::install(); + registerSuccess &= ScriptMethodsPlayerAccountNamespace::install(); + registerSuccess &= ScriptMethodsPlayerQuestNamespace::install(); + registerSuccess &= ScriptMethodsPvpNamespace::install(); + registerSuccess &= ScriptMethodsQuestNamespace::install(); + registerSuccess &= ScriptMethodsRegionNamespace::install(); + registerSuccess &= ScriptMethodsRegion3dNamespace::install(); + registerSuccess &= ScriptMethodsRemoteDebugNamespace::install(); + registerSuccess &= ScriptMethodsResourceNamespace::install(); + registerSuccess &= ScriptMethodsScriptNamespace::install(); + registerSuccess &= ScriptMethodsServerUINamespace::install(); + registerSuccess &= ScriptMethodsShipNamespace::install(); + registerSuccess &= ScriptMethodsSkillNamespace::install(); + registerSuccess &= ScriptMethodsSpawnerNamespace::install(); + registerSuccess &= ScriptMethodsStringNamespace::install(); + registerSuccess &= ScriptMethodsSystemNamespace::install(); + registerSuccess &= ScriptMethodsTerrainNamespace::install(); + registerSuccess &= ScriptMethodsTriggerVolumeNamespace::install(); + registerSuccess &= ScriptMethodsVeteranNamespace::install(); + registerSuccess &= ScriptMethodsWaypointNamespace::install(); + registerSuccess &= ScriptMethodsWorldInfoNamespace::install(); + + if (!registerSuccess) + { + FATAL(true, ("JavaLibrary RegisterNatives fail!\n")); + return false; + } + + ++ms_envCount; + return true; +} // JavaLibrary::connectToJava + +//---------------------------------------------------------------------- + +bool JavaLibrary::registerNatives(const JNINativeMethod natives[], int count) +{ + jclass baseClass = ms_env->FindClass("script/base_class"); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + return false; + } + + int result = 0; + for (int i = 0; i < count; ++i) + { + if (!natives[i].signature) + { + DEBUG_REPORT_LOG(true, ("RegisterNatives failed: %s - NULL signature\n", natives[i].name)); + result = 1; + continue; + } + int lresult = ms_env->RegisterNatives(baseClass, &natives[i], 1); + if (lresult != 0) + { + ms_env->ExceptionClear(); + DEBUG_REPORT_LOG(true, ("RegisterNatives failed: %s: %s\n", natives[i].name, natives[i].signature)); + result = lresult; + } + } + + ms_env->DeleteLocalRef(baseClass); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + return false; + } + if (result != 0) + { + FATAL(true, ("JavaLibrary RegisterNatives fail!\n")); + return false; + } + return true; +} + +//---------------------------------------------------------------------- + +/** + * Disconnects this thread from the Java VM. Any vars that reference Java objects + * will be invalid after this call. + */ +void JavaLibrary::disconnectFromJava() +{ +int i; + + if (ms_jvm == 0 || ms_env == 0) + return; + + FREE_CLASS(ms_clsScriptEntry); + FREE_CLASS(ms_clsObject); + FREE_CLASS(ms_clsClass); + FREE_CLASS(ms_clsMethod); + FREE_CLASS(ms_clsBoolean); + FREE_CLASS(ms_clsBooleanArray); + FREE_CLASS(ms_clsInteger); + FREE_CLASS(ms_clsIntegerArray); + FREE_CLASS(ms_clsModifiableInt); + FREE_CLASS(ms_clsFloat); + FREE_CLASS(ms_clsFloatArray); + FREE_CLASS(ms_clsModifiableFloat); + FREE_CLASS(ms_clsString); + FREE_CLASS(ms_clsStringArray); + FREE_CLASS(ms_clsMap); + FREE_CLASS(ms_clsHashtable); + FREE_CLASS(ms_clsThrowable); + FREE_CLASS(ms_clsError); + FREE_CLASS(ms_clsStackOverflowError); + FREE_CLASS(ms_clsThread); + FREE_CLASS(ms_clsInternalScriptError); + FREE_CLASS(ms_clsInternalScriptSeriousError); + FREE_CLASS(ms_clsDictionary); + FREE_CLASS(ms_clsCollection); + FREE_CLASS(ms_clsDynamicVariable); + FREE_CLASS(ms_clsDynamicVariableList); + FREE_CLASS(ms_clsAttribute); + FREE_CLASS(ms_clsAttribMod); + FREE_CLASS(ms_clsMentalState); + FREE_CLASS(ms_clsMentalStateMod); + FREE_CLASS(ms_clsMenuInfo); + FREE_CLASS(ms_clsMenuInfoData); + FREE_CLASS(ms_clsDraftSchematic); + FREE_CLASS(ms_clsDraftSchematicSlot); + FREE_CLASS(ms_clsDraftSchematicAttrib); + FREE_CLASS(ms_clsDraftSchematicSimpleIngredient); + FREE_CLASS(ms_clsDraftSchematicCustom); + FREE_CLASS(ms_clsCustomVar); + FREE_CLASS(ms_clsRangedIntCustomVar); + FREE_CLASS(ms_clsPalcolorCustomVar); + FREE_CLASS(ms_clsColor); + FREE_CLASS(ms_clsLocation); + FREE_CLASS(ms_clsLocationArray); + FREE_CLASS(ms_clsRegion); + FREE_CLASS(ms_clsObjId); + FREE_CLASS(ms_clsObjIdArray); + FREE_CLASS(ms_clsStringId); + FREE_CLASS(ms_clsStringIdArray); + FREE_CLASS(ms_clsModifiableStringId); + FREE_CLASS(ms_clsBaseClassRangeInfo); + FREE_CLASS(ms_clsBaseClassAttackerResults); + FREE_CLASS(ms_clsBaseClassDefenderResults); + FREE_CLASS(ms_clsCombatEngine); + FREE_CLASS(ms_clsCombatEngineCombatantData); + FREE_CLASS(ms_clsCombatEngineAttackerData); + FREE_CLASS(ms_clsCombatEngineDefenderData); + FREE_CLASS(ms_clsCombatEngineWeaponData); + FREE_CLASS(ms_clsCombatEngineHitResult); + FREE_CLASS(ms_clsTransform); + FREE_CLASS(ms_clsTransformArray); + FREE_CLASS(ms_clsVector); + FREE_CLASS(ms_clsVectorArray); + FREE_CLASS(ms_clsResourceDensity); + FREE_CLASS(ms_clsResourceAttribute); + FREE_CLASS(ms_clsLibrarySpaceTransition); + FREE_CLASS(ms_clsLibraryDump); + FREE_CLASS(ms_clsLibraryGMLib); + + if (ms_scriptEntry != NULL) + { + if (ms_env) + ms_env->DeleteGlobalRef(ms_scriptEntry); + ms_scriptEntry = NULL; + } + + for (i = 0; i < MAX_RECURSION_COUNT; ++i) + { + ms_attribModList[i] = GlobalArrayRef::cms_nullPtr; + ms_mentalStateModList[i] = GlobalArrayRef::cms_nullPtr; + } + for (i = 0; i < MAX_STRING_ID_PARAMS; ++i) + GlobalInstances::ms_stringIds[i] = GlobalRef::cms_nullPtr; + for (i = 0; i < MAX_ATTRIB_MOD_PARAMS; ++i) + GlobalInstances::ms_attribMods[i] = GlobalRef::cms_nullPtr; + for (i = 0; i < MAX_MENTAL_STATE_MOD_PARAMS; ++i) + GlobalInstances::ms_mentalStateMods[i] = GlobalRef::cms_nullPtr; + for (i = 0; i < MAX_MODIFIABLE_INT_PARAMS; ++i) + GlobalInstances::ms_modifiableInts[i] = GlobalRef::cms_nullPtr; + for (i = 0; i < MAX_MODIFIABLE_FLOAT_PARAMS; ++i) + GlobalInstances::ms_modifiableFloats[i] = GlobalRef::cms_nullPtr; + for (i = 0; i < MAX_MODIFIABLE_STRING_ID_PARAMS; ++i) + GlobalInstances::ms_modifiableStringIds[i] = GlobalRef::cms_nullPtr; + GlobalInstances::ms_menuInfo = GlobalRef::cms_nullPtr; + + IGNORE_RETURN(ms_jvm->DetachCurrentThread()); + ms_env = NULL; +} // JavaLibrary::disconnectFromJava + +//---------------------------------------------------------------------- + +/** + * Resets our connection to the Java VM. + */ +void JavaLibrary::resetJavaConnection() +{ + if (ms_currentRecursionCount == 0) + { + LOG("ScriptInvestigation", ("Reconnecting to Java after VM error")); + ms_instance->disconnectFromJava(); + if (!ms_instance->connectToJava()) + { + FATAL(true, ("Unable to reconnect to Java after error, fataling")); + } + ms_resetJava = false; + LOG("ScriptInvestigation", ("Reconnection succeeded")); + } + else + ms_resetJava = true; +} // JavaLibrary::resetJavaConnection() + +//---------------------------------------------------------------------- + +/** + * Gets a list of public methods of a given script, and adds the info to the + * GameScriptObject class so we don't have to go into the JVM to see if a + * script handles a given trigger, etc. + * + * @param scriptName the name of the script to query + * @return false on failure. True on success. + */ +bool JavaLibrary::queryScriptFunctions(const std::string & scriptName) +{ + if (ms_instance == NULL) + return false; + + JavaString scriptClassName(("script." + scriptName).c_str()); + LocalObjectArrayRefPtr scriptMethods = callStaticObjectArrayMethod( + ms_clsScriptEntry, ms_midGetScriptFunctions, scriptClassName.getValue()); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + return false; + } + if (scriptMethods == LocalObjectArrayRef::cms_nullPtr) + return false; + + std::set & functionList = GameScriptObject::getScriptFunctions( + scriptName); + functionList.clear(); + +// DEBUG_REPORT_LOG(true, ("Querying script %s methods:\n", scriptName.c_str())); + + // get the name of each method + bool result = true; + int count = getArrayLength(*scriptMethods); + for (int i = 0; i < count; ++i) + { + JavaStringPtr methodName = getStringArrayElement(*scriptMethods, i); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + result = false; + break; + } + if (methodName == JavaString::cms_nullPtr) + { + result = false; + break; + } + + // convert the method name to a C string and store it + std::string localName; + convert(*methodName, localName); +// DEBUG_REPORT_LOG(true, ("\t%s\n", localName)); + functionList.insert(localName); + } + return result; +} // JavaLibrary::queryScriptFunctions + +/** + * Returns the amount of free Java heap space left. + * + * @return the amount of Java memory free + */ +jlong JavaLibrary::getFreeJavaMemory() +{ + if (ms_instance == NULL || ms_env == NULL) + return 0; + + return ms_env->CallStaticLongMethod(ms_clsScriptEntry, ms_midScriptEntryGetFreeMem); +} // JavaLibrary::getFreeJavaMemory + +/** + * Prints the current java stack to stdout. + */ +void JavaLibrary::printJavaStack() +{ + ms_env->CallStaticVoidMethod(ms_clsThread, ms_midThreadDumpStack); +} + +/** + * Turns script logging on or off. + * + * @param enable flag to turn logging on or off + */ +void JavaLibrary::enableLogging(bool enable) const +{ + if (ms_instance == NULL || ms_env == NULL) + return; + + ms_env->CallStaticVoidMethod(ms_clsScriptEntry, + ms_midScriptEntryEnableLogging, enable); +} // JavaLibrary::enableLogging + +/** + * Turns tracking of players to see if they can become Jedi on or off. + * + * @param enableTracking flag to turn tracking on or off + */ +void JavaLibrary::enableNewJediTracking(bool enableTracking) +{ + if (ms_instance == NULL || ms_env == NULL) + return; + + ms_env->CallStaticVoidMethod(ms_clsScriptEntry, + ms_midScriptEntryEnableNewJediTracking, enableTracking); +} // JavaLibrary::enableNewJediTracking + +/** + * Asks the Java script library for a obj_id mapped to a ServerObject. + * + * @param object the NetworkId::NetworkIdType we want to map + * + * @return the jobject obj_id + */ +LocalRefPtr JavaLibrary::getObjId(const ServerObject & object) +{ + return getObjId(object.getNetworkId()); +} // JavaLibrary::getObjId(const ServerObject &) + +/** + * Asks the Java script library for a obj_id mapped to a NetworkId::NetworkIdType. + * + * @param id the NetworkId::NetworkIdType we want to map + * + * @return the jobject obj_id + */ +LocalRefPtr JavaLibrary::getObjId(const NetworkId::NetworkIdType & id) +{ + return getObjId(NetworkId(id)); +} // JavaLibrary::getObjId(const NetworkId::NetworkIdType &) + +/** + * Asks the Java script library for a obj_id mapped to a NetworkId. + * + * @param id the NetworkId we want to map + * + * @return the jobject obj_id + */ +LocalRefPtr JavaLibrary::getObjId(const NetworkId & id) +{ + if (ms_env != NULL && ms_instance != NULL) + return callStaticObjectMethod(ms_clsObjId, ms_midObjIdGetObjId, id.getValue()); + return LocalRef::cms_nullPtr; +} // JavaLibrary::getObjId(const CachedNetworkId &) + +void JavaLibrary::spaceMakeOvert(const NetworkId & player) +{ + callStaticVoidMethod(ms_clsLibrarySpaceTransition, ms_midLibrarySpaceTransitionSetPlayerOvert, player.getValue()); +} + +void JavaLibrary::spaceClearOvert(const NetworkId & ship) +{ + callStaticVoidMethod(ms_clsLibrarySpaceTransition, ms_midLibrarySpaceTransitionClearOvertStatus, ship.getValue()); +} + +std::string JavaLibrary::getObjectDumpInfo( NetworkId id ) +{ + + JavaStringPtr s = callStaticStringMethod(ms_clsLibraryDump, ms_midLibraryDumpDumpTargetInfo, id.getValue() ); + + std::string retval; + convert( *s, retval ); + + return retval; +} + +void JavaLibrary::freezePlayer( const NetworkId & id ) +{ + DEBUG_REPORT_LOG( true, ( "calling freeze code in script" ) ); + JavaStringPtr s = callStaticStringMethod( ms_clsLibraryGMLib, ms_midLibraryGMLibFreeze, id.getValue() ); + DEBUG_REPORT_LOG( true, ( "done with script" ) ); + std::string retval; + convert( *s, retval ); + DEBUG_REPORT_LOG( true, ("Got back %s", retval.c_str() ) ); +} + +void JavaLibrary::unFreezePlayer( const NetworkId & id ) +{ + callStaticVoidMethod( ms_clsLibraryGMLib, ms_midLibraryGMLibUnfreeze, id.getValue() ); +} + +/** + * Returns the NetworkId associated with a Java obj_id. + * + * @param source the obj_id + * + * @return the NetworkId + */ +const NetworkId JavaLibrary::getNetworkId(const jobject & source) +{ + NetworkId result(NetworkId::cms_invalid); + if (ms_env && source != 0 && ms_env->IsInstanceOf(source, ms_clsObjId)) + { + result = NetworkId(static_cast(ms_env->CallLongMethod(source, ms_midObjIdGetValue))); + } + return result; +} // getNetworkId(const jobject &) + +/** + * Returns the NetworkId associated with a Java obj_id. + * + * @param source the obj_id + * + * @return the NetworkId + */ +const NetworkId JavaLibrary::getNetworkId(const LocalRefParam & source) +{ + NetworkId result(NetworkId::cms_invalid); + if (ms_env && source.getValue() != 0 && isInstanceOf(source, ms_clsObjId)) + { + result = NetworkId(static_cast(callLongMethod(source, ms_midObjIdGetValue))); + } + return result; +} // getNetworkId(const LocalRef &) + +LocalRefPtr JavaLibrary::getVector(Vector const & vector) +{ + LocalRefPtr temp; + ScriptConversion::convert(vector, temp); + return temp; +} + +/** + * Frees a Java obj_id matching a NetwrokId. + * + * @param id the NetworkId we want to remove + */ +void JavaLibrary::removeJavaId(const NetworkId & id) +{ + if (ms_env == NULL || ms_clsObjId == NULL || ms_midObjIdClearObjId == NULL) + { + return; + } + + if (id.getValue()) + { + ms_env->CallStaticVoidMethod(ms_clsObjId, ms_midObjIdClearObjId, id.getValue()); + } +} // JavaLibrary::removeJavaId + +/** + * Flag the object in script as going to be destroyed, but hasn't actually been removed from the game yet. + * + * @param id the NetworkId of the object + */ +void JavaLibrary::flagDestroyed(const NetworkId & id) +{ + if (ms_env == NULL || ms_clsObjId == NULL || ms_midObjIdFlagDestroyed == NULL) + { + return; + } + + if (id.getValue()) + { + ms_env->CallStaticVoidMethod(ms_clsObjId, ms_midObjIdFlagDestroyed, id.getValue()); + } +} // JavaLibrary::flagDestroyed + +/** + * Sets the authoritative flag of an obj_id. + * + * @param object the object we want to flag + * @param authoritative authoritative flag + */ +void JavaLibrary::setObjIdAuthoritative(const NetworkId & object, bool authoritative, uint32 pid) +{ + if (ms_env == NULL || ms_midObjIdSetAuthoritative == NULL) + { + return; + } + LocalRefPtr id = getObjId(object); + if (id == LocalRef::cms_nullPtr) + { + DEBUG_WARNING(true, ("JavaLibrary::setObjIdAuthoritative: could not get id for object %s", + object.getValueString().c_str())); + return; + } + callVoidMethod(*id, ms_midObjIdSetAuthoritative, + static_cast(authoritative ? JNI_TRUE : JNI_FALSE), pid); +} // JavaLibrary::setObjIdAuthoritative + +/** + * Sets the loaded flag of an obj_id. You cannot unload an object, it is marked + * unloaded when it is deleted. + * + * @param object the object we want to flag as loaded + */ +void JavaLibrary::setObjIdLoaded(const NetworkId &object) +{ + if (ms_env == NULL || ms_midObjIdSetLoaded == NULL) + { + return; + } + LocalRefPtr id = getObjId(object); + if (id == LocalRef::cms_nullPtr) + { + DEBUG_WARNING(true, ("JavaLibrary::setObjIdLoaded: could not get id for object %s", + object.getValueString().c_str())); + return; + } + callVoidMethod(*id, ms_midObjIdSetLoaded); +} // JavaLibrary::setObjIdLoaded + +/** + * Sets the initialized flag of an obj_id. You cannot uninitialize an object, + * it is marked uninitialized when it is deleted. + * + * @param object the object we want to flag as initialized + */ +void JavaLibrary::setObjIdInitialized(const NetworkId &object) +{ + if (ms_env == NULL || ms_midObjIdSetInitialized == NULL) + { + return; + } + LocalRefPtr id = getObjId(object); + if (id == LocalRef::cms_nullPtr) + { + DEBUG_WARNING(true, ("JavaLibrary::setObjIdInitialized: could not get " + "id for object %s", object.getValueString().c_str())); + return; + } + callVoidMethod(*id, ms_midObjIdSetInitialized); +} // JavaLibrary::setObjIdInitialized + +/** + * Sets the logged in flag of an obj_id. + * + * @param object the object we want to flag + * @param loggedIn true if logged in, false if logged out + */ +void JavaLibrary::setObjIdLoggedIn(const NetworkId & object, bool loggedIn) +{ + if (ms_env == NULL || ms_midObjIdSetLoggedIn == NULL) + { + return; + } + LocalRefPtr id = getObjId(object); + if (id == LocalRef::cms_nullPtr) + { + DEBUG_WARNING(true, ("JavaLibrary::setObjIdLoggedIn: could not get " + "id for object %s", object.getValueString().c_str())); + return; + } + callVoidMethod(*id, ms_midObjIdSetLoggedIn, loggedIn); +} // JavaLibrary::setObjIdLoggedIn + +/** + * Adds a script name to an obj_id. + * + * @param object object we want to attach the script to + * @param script name of the script to attach + */ +void JavaLibrary::attachScriptToObjId(const NetworkId &object, + const std::string & script) +{ + if (ms_env != NULL) + { + LocalRefPtr obj_id = getObjId(object); + if (obj_id == LocalRef::cms_nullPtr) + return; + + JavaString jscript(script.c_str()); + + callVoidMethod(*obj_id, ms_midObjIdAttachScript, jscript.getValue()); + } +} // JavaLibrary::attachScriptToObjId + +/** + * Adds script names to an obj_id. + * + * @param object object we want to attach the scripts to + * @param scripts names of the scripts to attach + */ +void JavaLibrary::attachScriptsToObjId(const NetworkId &object, + const ScriptList & scripts) +{ + if (scripts.size() == 0 || ms_env == NULL) + return; + + LocalRefPtr obj_id = getObjId(object); + if (obj_id == LocalRef::cms_nullPtr) + return; + + LocalObjectArrayRefPtr jscripts = createNewObjectArray(scripts.size(), ms_clsString); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + return; + } + int index = 0; + for (ScriptList::const_iterator i = scripts.begin(); i != scripts.end(); ++i) + { + if ((*i).isValid()) + { + JavaString js((*i).getScriptName()); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + return; + } + setObjectArrayElement(*jscripts, index, js); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + return; + } + ++index; + } + } + + callVoidMethod(*obj_id, ms_midObjIdAttachScripts, jscripts->getValue()); +} // JavaLibrary::attachScriptsToObjId + +/** + * Removes a script name from an obj_id. + * + * @param object object we want to detach the script from + * @param script name of the script to detach + */ +void JavaLibrary::detachScriptFromObjId(const NetworkId &object, + const std::string & script) +{ + if (ms_env != NULL) + { + LocalRefPtr obj_id = getObjId(object); + if (obj_id == LocalRef::cms_nullPtr) + return; + + JavaString jscript(script.c_str()); + + callVoidMethod(*obj_id, ms_midObjIdDetachScript, jscript.getValue()); + } +} // JavaLibrary::detachScriptFromObjId + +/** + * Removes all the scripts from an obj_id. + * + * @param object object we want to detach the script from + */ +void JavaLibrary::detachAllScriptsFromObjId(const NetworkId &object) +{ + if (ms_env != NULL) + { + LocalRefPtr obj_id = getObjId(object); + if (obj_id == LocalRef::cms_nullPtr) + return; + + callVoidMethod(*obj_id, ms_midObjIdDetachAllScripts); + } +} // JavaLibrary::detachAllScriptsFromObjId + +/** + * Handles errors after calling into script_entry.java. + * + * @param result the result we got back from script_entry + * + * @return the result to be returned to the calling trigger + */ +jint JavaLibrary::handleScriptEntryCleanup(jint result) +{ + if (ms_resetJava) + { + ms_instance->resetJavaConnection(); + result = SCRIPT_CONTINUE; + } + else if (result == SCRIPT_INTERNAL_ERROR || ms_env->ExceptionCheck()) + { + if (ms_env->ExceptionCheck()) + { + // if this is an internal error, clear it so we don't print the error + // message later + jthrowable err = ms_env->ExceptionOccurred(); + ms_env->ExceptionClear(); + if (ms_env->IsInstanceOf(err, ms_clsError)) + { + if (ms_env->IsInstanceOf(err, ms_clsInternalScriptError)) + { + LOG("ScriptInvestigation", ("call to script_entry.java failed because of a script internal error")); + if (ConfigServerGame::getScriptStackErrorLevel() == 2) + { + // if the internal error was caused by a stack overflow, fatal + LocalRefPtr wrappedErr = getObjectField(LocalRefParam(err), ms_fidInternalScriptSeriousErrorError); + if (wrappedErr != LocalRef::cms_nullPtr && isInstanceOf(*wrappedErr, ms_clsStackOverflowError)) + { + FATAL(true, ("Java stack overflow error, fataling")); + } + } + } + // we are going to reset our connection to the Java VM + ms_instance->resetJavaConnection(); + result = SCRIPT_CONTINUE; + } + else + ms_env->DeleteLocalRef(err); + } + else if (result == SCRIPT_INTERNAL_ERROR) + { + LOG("ScriptInvestigation", ("call to script_entry.java failed because of a script internal exception")); + result = SCRIPT_CONTINUE; + } +#ifdef linux + if (ConfigServerGame::getTrapScriptCrashes()) + { + // the script threw an error or exception, restore our segfault handler + IGNORE_RETURN(sigaction(SIGSEGV, &OurSa, NULL)); + } +#endif + } + return result; +} // JavaLibrary::handleScriptEntryCleanup + +/** + * Entry point into the Java VM for scripts. All functions should use this to call + * into the VM. This version of the function executes on a single script. + * + * @param script the script name to use + * @param method the script method to call + * @param params parameters to be sent to the script method + * + * @return return value from the script method, usually SCRIPT_CONTINUE or SCRIPT_OVERRIDE + */ +jint JavaLibrary::callScriptEntry(const JavaStringParam & script, + const JavaStringParam & method, jobjectArray params) +{ + if (ms_env == NULL || ms_clsScriptEntry == NULL || ms_midRunOne == NULL) + { + LOG("ScriptInvestigation", ("callScriptEntry failed because something was null")); + if (!ms_env) + { + LOG("ScriptInvestigation", ("callScriptEntry failed because ms_env was null")); + } + if (!ms_clsScriptEntry) + { + LOG("ScriptInvestigation", ("callScriptEntry failed because scriptEntry was null")); + } + if (!ms_midRunOne) + { + LOG("ScriptInvestigation", ("callScriptEntry failed because runOne was null")); + } + + return SCRIPT_OVERRIDE; + } + + PROFILER_BLOCK_DEFINE(p, "JavaLibrary::callScriptEntry1"); + PROFILER_BLOCK_ENTER(p); + + ++ms_currentRecursionCount; + if (ms_currentRecursionCount > 3) + { + LOG("ScriptRecursion", ("callScriptEntry1 recursion %d", ms_currentRecursionCount)); + } + jint result = ms_env->CallStaticIntMethod(ms_clsScriptEntry, ms_midRunOne, + script.getValue(), method.getValue(), params); + --ms_currentRecursionCount; + + result = handleScriptEntryCleanup(result); + + PROFILER_BLOCK_LOST_CHECK(p); + PROFILER_BLOCK_LEAVE(p); + + return result; +} // JavaLibrary::callScriptEntry(JavaStringParam, JavaStringParam, jobjectArray) + +/** + * Entry point into the Java VM for scripts. All functions should use this to call + * into the VM. This version of the function executes on all scripts attached to + * an object. + * + * @param method the script method to call + * @param params parameters to be sent to the script method + * + * @return return value from the script method, usually SCRIPT_CONTINUE or SCRIPT_OVERRIDE + */ +jint JavaLibrary::callScriptEntry(const JavaStringParam & method, jobjectArray params) +{ + if (ms_env == NULL || ms_clsScriptEntry == NULL || ms_midRunAll == NULL) + { + LOG("ScriptInvestigation", ("callScriptEntry2 failed because something was null")); + if (!ms_env) + { + LOG("ScriptInvestigation", ("callScriptEntry2 failed because ms_env was null")); + } + if (!ms_clsScriptEntry) + { + LOG("ScriptInvestigation", ("callScriptEntry2 failed because scriptEntry was null")); + } + if (!ms_midRunOne) + { + LOG("ScriptInvestigation", ("callScriptEntry2 failed because runOne was null")); + } + return SCRIPT_OVERRIDE; + } + + PROFILER_BLOCK_DEFINE(p, "JavaLibrary::callScriptEntry2"); + PROFILER_BLOCK_ENTER(p); + + ++ms_currentRecursionCount; + if (ms_currentRecursionCount > 3) + { + LOG("ScriptRecursion", ("callScriptEntry2 recursion %d", ms_currentRecursionCount)); + } + jint result = ms_env->CallStaticIntMethod(ms_clsScriptEntry, ms_midRunAll, + method.getValue(), params); + --ms_currentRecursionCount; + + result = handleScriptEntryCleanup(result); + + PROFILER_BLOCK_LOST_CHECK(p); + PROFILER_BLOCK_LEAVE(p); + + return result; +} // JavaLibrary::callScriptEntry(JavaStringParam, jobjectArray) + +/** + * Entry point into the Java VM for calling console handler script functions. + * + * @param script the script name to use + * @param method the script method to call + * @param params parameters to be sent to the script method + * + * @return string returned by the console handler + */ +jstring JavaLibrary::callScriptConsoleHandlerEntry(const JavaStringParam & script, const JavaStringParam & method, jobjectArray params) +{ + if (ms_env == NULL || ms_clsScriptEntry == NULL || ms_midRunConsoleHandler == NULL) + { + LOG("ScriptInvestigation", ("callScriptConsoleHandlerEntry failed because something was null")); + if (!ms_env) + { + LOG("ScriptInvestigation", ("callScriptConsoleHandlerEntry failed because ms_env was null")); + } + if (!ms_clsScriptEntry) + { + LOG("ScriptInvestigation", ("callScriptConsoleHandlerEntry failed because scriptEntry was null")); + } + if (!ms_midRunConsoleHandler) + { + LOG("ScriptInvestigation", ("callScriptConsoleHandlerEntry failed because runConsoleHandler was null")); + } + + return 0; + } + + PROFILER_BLOCK_DEFINE(p, "JavaLibrary::callScriptConsoleHandlerEntry"); + PROFILER_BLOCK_ENTER(p); + + ++ms_currentRecursionCount; + if (ms_currentRecursionCount > 3) + { + LOG("ScriptRecursion", ("callScriptConsoleHandlerEntry recursion %d", ms_currentRecursionCount)); + } + jstring result = static_cast(ms_env->CallStaticObjectMethod( + ms_clsScriptEntry, ms_midRunConsoleHandler, script.getValue(), method.getValue(), params)); + --ms_currentRecursionCount; + + IGNORE_RETURN(handleScriptEntryCleanup(SCRIPT_CONTINUE)); + + PROFILER_BLOCK_LOST_CHECK(p); + PROFILER_BLOCK_LEAVE(p); + + return result; +} // JavaLibrary::callScriptConsoleHandlerEntry + +// ---------------------------------------------------------------------- + +/** + * Converts ScriptParams into a Java script.dictionary class. + * + * @param params the ScriptParams to convert + * @param dictionary pointer that will be set to the dictionary. The caller + * is responsible for deleting the pointer. + */ +void JavaLibrary::convert(const ScriptParams & params, JavaDictionaryPtr & dictionary) +{ + dictionary.reset(); + + if (ms_env == NULL) + return; + + // create the dictionary + JavaDictionaryPtr localDictionary(createNewDictionary()); + if (localDictionary == JavaDictionary::cms_nullPtr) + return; + + for (int i = 0; i < params.getParamCount(); ++i) + { + JavaString paramName(params.getParamName(i).c_str()); + switch (params.getParamType(i)) + { + case Param::BOOL: + { + callObjectMethod(*localDictionary, + ms_midDictionaryPutBool, paramName.getValue(), + params.getBoolParam(i)); + } + break; + case Param::BOOL_ARRAY: + { + const std::deque & boolArray = params.getBoolArrayParam(i); + LocalBooleanArrayRefPtr array = createNewBooleanArray(boolArray.size()); + if (array != LocalBooleanArrayRef::cms_nullPtr) + { + if (boolArray.size() > 0) + { + // we need the array of bool to be contiguous in order to + // "memcopy" it into the Java return buffer; a deque + // does not store the array of bool contiguously; neither + // does a vector; in fact, if you find an stl container + // of bool that stores the array of bool contiguously, you + // should change this code to use it; for now, we allocate + // a temporary bool array and copy the deque's bool array + // into it, and pass that to the JNI call to do the "memcopy" + bool * tempBoolArray = new bool[boolArray.size()]; + int indexBoolArray = 0; + for (std::deque::const_iterator iter = boolArray.begin(); iter != boolArray.end(); ++iter, ++indexBoolArray) + tempBoolArray[indexBoolArray] = *iter; + + setBooleanArrayRegion(*array, 0, boolArray.size(), + const_cast(reinterpret_cast(&tempBoolArray[0]))); + + delete [] tempBoolArray; + } + + callObjectMethod(*localDictionary, + ms_midDictionaryPut, paramName.getValue(), array->getValue() + ); + } + } + break; + case Param::INT: + { + callObjectMethod(*localDictionary, + ms_midDictionaryPutInt, paramName.getValue(), + params.getIntParam(i)); + } + break; + case Param::INT_ARRAY: + { + const std::vector & intArray = params.getIntArrayParam(i); + LocalIntArrayRefPtr array = createNewIntArray(intArray.size()); + if (array != LocalIntArrayRef::cms_nullPtr) + { + if (intArray.size() > 0) + { +#if INT_MAX == LONG_MAX + setIntArrayRegion(*array, 0, intArray.size(), const_cast( + reinterpret_cast(&intArray[0]))); +#else + std::vector intArray2(intArray.begin(), intArray.end()); + setIntArrayRegion(*array, 0, intArray.size(), const_cast(&intArray2[0])); +#endif + } + + callObjectMethod(*localDictionary, + ms_midDictionaryPut, paramName.getValue(), array->getValue() + ); + } + } + break; + case Param::FLOAT: + { + callObjectMethod(*localDictionary, + ms_midDictionaryPutFloat, paramName.getValue(), + params.getFloatParam(i)); + } + break; + case Param::STRING: + { + JavaString value(params.getStringParam(i)); + callObjectMethod(*localDictionary, + ms_midDictionaryPut, paramName.getValue(), value.getValue()); + } + break; + case Param::STRING_ARRAY: + { + LocalObjectArrayRefPtr value; + ScriptConversion::convert(params.getStringArrayParam(i), value); + callObjectMethod(*localDictionary, + ms_midDictionaryPut, paramName.getValue(), value->getValue()); + } + break; + case Param::UNICODE: + { + JavaString value(params.getUnicodeParam(i)); + callObjectMethod(*localDictionary, + ms_midDictionaryPut, paramName.getValue(), value.getValue()); + } + break; + case Param::UNICODE_ARRAY: + { + LocalObjectArrayRefPtr value; + ScriptConversion::convert(params.getUnicodeArrayParam(i), value); + callObjectMethod(*localDictionary, + ms_midDictionaryPut, paramName.getValue(), value->getValue()); + } + break; + case Param::OBJECT_ID: + { + LocalRefPtr arg = getObjId(params.getObjIdParam(i)); + if (arg == LocalRef::cms_nullPtr) + return; + callObjectMethod(*localDictionary, + ms_midDictionaryPut, paramName.getValue(), arg->getValue()); + } + break; + case Param::OBJECT_ID_ARRAY: + { + const std::vector & objIds = + params.getObjIdArrayParam(i); + LocalObjectArrayRefPtr array = createNewObjectArray(objIds.size(), ms_clsObjId); + if (array != LocalObjectArrayRef::cms_nullPtr) + { + int count = objIds.size(); + for (int j = 0; j < count; ++j) + { + LocalRefPtr id = getObjId(objIds[j]); + if (id != LocalRef::cms_nullPtr) + { + setObjectArrayElement(*array, j, *id); + } + } + callObjectMethod(*localDictionary, + ms_midDictionaryPut, paramName.getValue(), array->getValue()); + } + else + { + if (ms_env->ExceptionCheck()) + ms_env->ExceptionDescribe(); + return; + } + } + break; + case Param::CACHED_OBJECT_ID_ARRAY: + { + const std::vector & objIds = + params.getCachedObjIdArrayParam(i); + LocalObjectArrayRefPtr array = createNewObjectArray(objIds.size(), ms_clsObjId); + if (array != LocalObjectArrayRef::cms_nullPtr) + { + int count = objIds.size(); + for (int j = 0; j < count; ++j) + { + LocalRefPtr id = getObjId(objIds[j]); + if (id != LocalRef::cms_nullPtr) + { + setObjectArrayElement(*array, j, *id); + } + } + callObjectMethod(*localDictionary, + ms_midDictionaryPut, paramName.getValue(), array->getValue()); + } + else + { + if (ms_env->ExceptionCheck()) + ms_env->ExceptionDescribe(); + return; + } + } + break; + case Param::OBJECT_ID_ARRAY_ARRAY: + { + const std::vector *> & objIds = + params.getObjIdArrayArrayParam(i); + LocalObjectArrayRefPtr array = createNewObjectArray(objIds.size(), ms_clsObjIdArray); + if (array != LocalObjectArrayRef::cms_nullPtr) + { + int count = objIds.size(); + for (int j = 0; j < count; ++j) + { + const std::vector * inner = objIds[j]; + if (inner != NULL) + { + LocalObjectArrayRefPtr innerArray = createNewObjectArray(inner->size(), ms_clsObjId); + if (innerArray != LocalObjectArrayRef::cms_nullPtr) + { + int innerCount = inner->size(); + for (int k = 0; k < innerCount; ++k) + { + LocalRefPtr id = getObjId(inner->at(k)); + if (id != LocalRef::cms_nullPtr) + { + setObjectArrayElement(*innerArray, k, *id); + } + } + setObjectArrayElement(*array, j, *innerArray); + } + else + { + if (ms_env->ExceptionCheck()) + ms_env->ExceptionDescribe(); + return; + } + } + else + { + setObjectArrayElement(*array, j, *LocalRef::cms_nullPtr); + } + } + callObjectMethod(*localDictionary, + ms_midDictionaryPut, paramName.getValue(), array->getValue()); + } + else + { + if (ms_env->ExceptionCheck()) + ms_env->ExceptionDescribe(); + return; + } + } + break; + case Param::LOCATION: + { + LocalRefPtr location; + if (ScriptConversion::convert(params.getLocationParam(i), "", NetworkId::cms_invalid, location)) + { + callObjectMethod(*localDictionary, + ms_midDictionaryPut, paramName.getValue(), location->getValue()); + } + } + break; + case Param::LOCATION_ARRAY: + { + LocalObjectArrayRefPtr locations; + if (ScriptConversion::convert(params.getLocationArrayParam(i), locations)) + { + callObjectMethod(*localDictionary, + ms_midDictionaryPut, paramName.getValue(), locations->getValue()); + } + } + break; + case Param::DICTIONARY: + { + LocalRefPtr dictionaryArg = convert(params.getValueDictionaryParam(i)); + if (dictionaryArg != LocalRef::cms_nullPtr) + { + callObjectMethod(*localDictionary, + ms_midDictionaryPut, paramName.getValue(), dictionaryArg->getValue()); + } + else + { + if (ms_env->ExceptionCheck()) + ms_env->ExceptionDescribe(); + return; + } + } + break; + default: + { + DEBUG_REPORT_LOG(true, ("Unknown/unhandled parameter type " + "%d while parsing ScriptParameters\n", static_cast( + params.getParamType(i)))); + return; + } + break; + } + } + + dictionary = localDictionary; +} // JavaLibrary::convert(const ScriptParams &, ScriptDictionaryPtr &) + +// ---------------------------------------------------------------------- + +/** + * Converts ScriptParams to an array of Java objects. The first parameter of the + * objects will be the NetworkId of the object we are running scripts on ("self"). + * + * @param self the network id that scripts are attached to + * @param argList argument list description + * @param args the parameters we want to convert + * + * @return self and args converted to Java data, or 0 on error + */ +LocalObjectArrayRefPtr JavaLibrary::convert(const NetworkId & self, const std::string& argList, const ScriptParams &args) +{ + if (ms_env == NULL) + return LocalObjectArrayRef::cms_nullPtr; + + // convert the params to jobjects + LocalObjectArrayRefPtr jparams = createNewObjectArray(static_cast(args.getParamCount() + 1), ms_clsObject); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + return LocalObjectArrayRef::cms_nullPtr; + } + // add the "self" parameter + { + LocalRefPtr jself = getObjId(self); + setObjectArrayElement(*jparams, 0, *jself); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + return LocalObjectArrayRef::cms_nullPtr; + } + } + + if (convert(jparams, 1, argList, args)) + return jparams; + + return LocalObjectArrayRef::cms_nullPtr; +} // JavaLibrary::convert + +/** + * Converts ScriptParams to an array of Java objects. + * + * @param argList argument list description + * @param args the parameters we want to convert + * + * @return args converted to Java data, or 0 on error + */ +LocalObjectArrayRefPtr JavaLibrary::convert(const std::string& argList, const ScriptParams &args) +{ + if (ms_env == NULL) + return LocalObjectArrayRef::cms_nullPtr; + + // convert the params to jobjects + LocalObjectArrayRefPtr jparams = createNewObjectArray(static_cast( + args.getParamCount()), ms_clsObject); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + return LocalObjectArrayRef::cms_nullPtr; + } + + if (convert(jparams, 0, argList, args)) + return jparams; + return LocalObjectArrayRef::cms_nullPtr; +} // JavaLibrary::convert + +/** + * Converts ScriptParams to an array of Java objects. + * + * @param javaParams Java object array to be filled in with the params + * @param startIndex index to start inserting params into the javaParams + * @param argList argument list description + * @param args the parameters we want to convert + * + * @return true on success, false if there was an error + */ +bool JavaLibrary::convert(LocalObjectArrayRefPtr & javaParams, int startIndex, const std::string& argList, const ScriptParams &args) +{ + if (ms_env == NULL) + return 0; + + GlobalInstances globals; + + PROFILER_AUTO_BLOCK_CHECK_DEFINE("JavaLibrary::convert(ScriptParams)"); + + // add the rest of the parameters + jsize paramIndex = 0; + for (unsigned i = 0; i < argList.size(); ++paramIndex) + { + const char argType = argList[i]; + int dimensions = 0; + int modifiable = false; + while (argList[i]) + { + ++i; + if (argList[i] == '*') + modifiable = true; + else if (argList[i] != '[') + break; + else + ++dimensions; + } + + if (paramIndex >= args.getParamCount()) + { + REPORT_LOG(true, ("JavaLibrary::convert(argList, ScriptParams) called with too few parameters: expected %s, got %d\n", argList.c_str(), args.getParamCount())); + return 0; + } + LocalRefParamPtr arg = LocalRefParam::cms_nullPtr; + switch (argType) + { + case 'b': + if (dimensions == 0) + { + if (args.getParamType(paramIndex) != Param::BOOL) + break; + jboolean param = args.getBoolParam(paramIndex); + arg = createNewObject(ms_clsBoolean, ms_midBoolean, param); + } + else + { + if (args.getParamType(paramIndex) != Param::BOOL_ARRAY) + break; + const std::deque & param = args.getBoolArrayParam(paramIndex); + int count = param.size(); + LocalBooleanArrayRefPtr localInstance = createNewBooleanArray(count); + + if (count > 0) + { + // we need the array of bool to be contiguous in order to + // "memcopy" it into the Java return buffer; a deque + // does not store the array of bool contiguously; neither + // does a vector; in fact, if you find an stl container + // of bool that stores the array of bool contiguously, you + // should change this code to use it; for now, we allocate + // a temporary bool array and copy the deque's bool array + // into it, and pass that to the JNI call to do the "memcopy" + bool * tempBoolArray = new bool[count]; + int indexBoolArray = 0; + for (std::deque::const_iterator iter = param.begin(); iter != param.end(); ++iter, ++indexBoolArray) + tempBoolArray[indexBoolArray] = *iter; + + setBooleanArrayRegion(*localInstance, 0, count, + const_cast(reinterpret_cast(&tempBoolArray[0]))); + + delete [] tempBoolArray; + } + + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + return 0; + } + arg = localInstance; + } + break; + case 'i': + if (dimensions == 0) + { + if (args.getParamType(paramIndex) != Param::INT) + break; + if (modifiable) + { + arg = globals.getNextModifiableInt(); + if (arg == GlobalRef::cms_nullPtr) + break; + jint param = args.getIntParam(paramIndex); + setIntField(*arg, ms_fidModifiableIntData, param); + } + else + { + jint param = args.getIntParam(paramIndex); + arg = createNewObject(ms_clsInteger, ms_midInteger, param); + } + } + else + { + if (args.getParamType(paramIndex) != Param::INT_ARRAY) + break; + const std::vector & param = args.getIntArrayParam(paramIndex); + int count = param.size(); + LocalIntArrayRefPtr localInstance = createNewIntArray(count); + jint * destination = ms_env->GetIntArrayElements(localInstance->getValue(), 0); + if (destination) + { + int i; + for (i=0; iReleaseIntArrayElements(localInstance->getValue(), destination, 0); + } + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + return 0; + } + arg = localInstance; + } + break; + case 'U': + { + if (dimensions != 0) + { + if (args.getParamType(paramIndex) != Param::BYTE_ARRAY) + break; + const std::vector & param = args.getByteArrayParam(paramIndex); + int count = param.size(); + LocalByteArrayRefPtr localInstance = createNewByteArray(count); + jbyte * destination = ms_env->GetByteArrayElements(localInstance->getValue(), 0); + if (destination) + { + int i; + for (i=0; iReleaseByteArrayElements(localInstance->getValue(), destination, 0); + } + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + return 0; + } + arg = localInstance; + } + } + break; + case 'f': + if (dimensions == 0) + { + if (args.getParamType(paramIndex) != Param::FLOAT) + break; + if (modifiable) + { + arg = globals.getNextModifiableFloat(); + if (arg == GlobalRef::cms_nullPtr) + break; + jfloat param = args.getFloatParam(paramIndex); + setFloatField(*arg, ms_fidModifiableFloatData, param); + } + else + { + jfloat param = args.getFloatParam(paramIndex); + arg = createNewObject(ms_clsFloat, ms_midFloat, param); + } + } + else + { + if (args.getParamType(paramIndex) != Param::FLOAT_ARRAY) + break; + const std::vector & floats = args.getFloatArrayParam(paramIndex); + LocalFloatArrayRefPtr farray = createNewFloatArray(floats.size()); + if (farray != LocalFloatArrayRef::cms_nullPtr) + { + if (floats.size() > 0) + setFloatArrayRegion(*farray, 0, floats.size(), const_cast(&floats[0])); + arg = farray; + } + } + break; + case 's': + if (dimensions == 0) + { + if (args.getParamType(paramIndex) != Param::STRING) + break; + arg = createNewString(args.getStringParam(paramIndex)); + } + else + { + if (args.getParamType(paramIndex) != Param::STRING_ARRAY) + break; + + const std::vector & strings = + args.getStringArrayParam(paramIndex); + LocalObjectArrayRefPtr localInstance = createNewObjectArray(strings.size(), ms_clsString); + int i; + std::vector::const_iterator iter; + for (i = 0, iter = strings.begin(); iter != strings.end(); + ++i, ++iter) + { + if (*iter) + { + JavaString newString(*iter); + setObjectArrayElement(*localInstance, i, newString); + } + } + arg = localInstance; + } + break; + case 'u': + if (dimensions == 0) + { + if (args.getParamType(paramIndex) != Param::UNICODE) + break; + if (modifiable) + break; + const String_t ¶m = args.getUnicodeParam(paramIndex); + arg = createNewString(param.c_str(), static_cast(param.size())); + } + else + { + if (args.getParamType(paramIndex) != Param::UNICODE_ARRAY) + break; + + const std::vector & strings = + args.getUnicodeArrayParam(paramIndex); + LocalObjectArrayRefPtr localInstance = createNewObjectArray(strings.size(), ms_clsString); + int i; + std::vector::const_iterator iter; + for (i = 0, iter = strings.begin(); iter != strings.end(); + ++i, ++iter) + { + if (*iter != NULL) + { + JavaString newString(**iter); + setObjectArrayElement(*localInstance, i, newString); + } + } + arg = localInstance; + } + break; + case 'L': + if (dimensions == 0) + { + if (args.getParamType(paramIndex) != Param::LOCATION) + break; + NetworkId cell; + LocalRefPtr target; + if (!ScriptConversion::convert(args.getLocationParam(paramIndex), cell, target)) + break; + arg = target; + } + else + { + if (args.getParamType(paramIndex) != Param::LOCATION_ARRAY) + break; + const std::vector & locations = args.getLocationArrayParam(paramIndex); + LocalObjectArrayRefPtr target; + if (!ScriptConversion::convert(locations, target)) + break; + arg = target; + } + break; + case 'O': + { + if (modifiable || dimensions > 1) + break; + if (dimensions == 1) + { + // obj_id array + if (args.getParamType(paramIndex) == Param::OBJECT_ID_ARRAY) + { + const std::vector & param = args.getObjIdArrayParam(paramIndex); + int count = param.size(); + int paramCount = 0; + LocalObjectArrayRefPtr localInstance = createNewObjectArray(count, ms_clsObjId); + for (int j = 0; j < count; ++j) + { + LocalRefPtr id = getObjId(param[j]); + if (id == LocalRef::cms_nullPtr) + break; + setObjectArrayElement(*localInstance, static_cast(paramCount), *id); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + return 0; + } + ++paramCount; + } + arg = localInstance; + } + else if (args.getParamType(paramIndex) == Param::CACHED_OBJECT_ID_ARRAY) + { + const std::vector & param = args.getCachedObjIdArrayParam(paramIndex); + int count = param.size(); + int paramCount = 0; + LocalObjectArrayRefPtr localInstance = createNewObjectArray(count, ms_clsObjId); + for (int j = 0; j < count; ++j) + { + LocalRefPtr id = getObjId(param[j]); + if (id == LocalRef::cms_nullPtr) + break; + setObjectArrayElement(*localInstance, static_cast(paramCount), *id); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + return 0; + } + ++paramCount; + } + arg = localInstance; + } + } + else + { + if (args.getParamType(paramIndex) != Param::OBJECT_ID) + break; + arg = getObjId(args.getObjIdParam(paramIndex)); + } + } + break; + + //---------------------------------------------------------------------- + //-- menu info + + case 'm': + { + if (dimensions != 0) + break; + + if (args.getParamType(paramIndex) != Param::OBJECT_MENU_INFO) + break; + + const MenuDataVector & menuVector = args.getObjectMenuRequestDataArrayParam (paramIndex); + + arg = globals.getMenuInfo (); + + if (!convert (menuVector, arg)) + { + return 0; + } + } + break; + + //---------------------------------------------------------------------- + + case 'S': + if (dimensions == 0) + { + if (args.getParamType(paramIndex) != Param::STRING_ID) + break; + if (modifiable) + arg = globals.getNextModifiableStringId(); + else + arg = globals.getNextStringId(); + if (arg == GlobalArrayRef::cms_nullPtr) + break; + const StringId & param = args.getStringIdParam(paramIndex); + JavaString text(param.getTable().c_str()); + setObjectField(*arg, ms_fidStringIdTable, text); + if (param.getText().empty()) + { + setIntField(*arg, ms_fidStringIdIndexId, + static_cast(param.getTextIndex())); + JavaString text(""); + setObjectField(*arg, ms_fidStringIdAsciiId, text); + } + else + { + JavaString text(param.getText().c_str()); + setObjectField(*arg, ms_fidStringIdAsciiId, text); + } + } + else + { + if (args.getParamType(paramIndex) != Param::STRING_ID_ARRAY) + break; + if (modifiable) + break; + + const std::vector & strings = args.getStringIdArrayParam(paramIndex); + LocalObjectArrayRefPtr localInstance = createNewObjectArray(strings.size(), ms_clsStringId); + + int i; + std::vector::const_iterator iter; + for (i = 0, iter = strings.begin(); iter != strings.end(); ++i, ++iter) + { + const StringId * param = *iter; + // get the next available stringId from the pool + GlobalRefPtr stringIdObject = globals.getNextStringId(); + if (stringIdObject == GlobalRef::cms_nullPtr) + break; + // set the stringId elements + JavaString text(param->getTable().c_str()); + setObjectField(*stringIdObject, ms_fidStringIdTable, text); + if (param->getText().empty()) + { + setIntField(*stringIdObject, ms_fidStringIdIndexId, + static_cast(param->getTextIndex())); + JavaString text(""); + setObjectField(*stringIdObject, ms_fidStringIdAsciiId, text); + } + else + { + JavaString text(param->getText().c_str()); + setObjectField(*stringIdObject, ms_fidStringIdAsciiId, text); + } + // add the string id to the array + setObjectArrayElement(*localInstance, i, *stringIdObject); + } + arg = localInstance; + } + break; + case 'E': + //@todo: implement this + break; + case 'A': + if (modifiable || dimensions > 1) + break; + if (dimensions == 1) + { + // attribMod array + if (args.getParamType(paramIndex) != Param::ATTRIB_MOD_ARRAY) + break; + const std::vector & param = args.getAttribModArrayParam(paramIndex); + int count = param.size(); + int paramCount = 0; + for (int j = 0; j < count; ++j) + { + // only send attribMods that actually do something + if (param[j].value != 0) + { + arg = globals.getNextAttribMod(); + if (arg == GlobalRef::cms_nullPtr) + return 0; + + JavaString name(AttribModNameManager::getInstance( + ).getAttribModName(param[j].tag)); + setObjectField(*arg, ms_fidAttribModName, name); + if (!AttribMod::isSkillMod(param[j])) + { + setIntField(*arg, ms_fidAttribModType, static_cast(param[j].attrib)); + } + else + { + JavaString skill(AttribModNameManager::getInstance( + ).getAttribModName(param[j].skill)); + setObjectField(*arg, ms_fidAttribModSkill, skill); + } + setIntField(*arg, ms_fidAttribModValue, param[j].value); + setFloatField(*arg, ms_fidAttribModTime, param[j].sustain); + setFloatField(*arg, ms_fidAttribModAttack, param[j].attack); + setFloatField(*arg, ms_fidAttribModDecay, param[j].decay); + setIntField(*arg, ms_fidAttribModFlags, param[j].flags); + setObjectArrayElement(*ms_attribModList[ms_currentRecursionCount], static_cast(paramCount), *arg); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + return 0; + } + ++paramCount; + } + } + // fill in the rest of ms_attribModList with null + for (; paramCount < MAX_ATTRIB_MOD_PARAMS; ++paramCount) + { + setObjectArrayElement(*ms_attribModList[ms_currentRecursionCount], static_cast(paramCount), *LocalRefParam::cms_nullPtr); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + return 0; + } + } + arg = ms_attribModList[ms_currentRecursionCount]; + } + else + { + // single attribMod + if (args.getParamType(paramIndex) != Param::ATTRIB_MOD) + break; + const AttribMod::AttribMod ¶m = args.getAttribModParam(paramIndex); + arg = globals.getNextAttribMod(); + if (arg == GlobalRef::cms_nullPtr) + return 0; + + JavaString name(AttribModNameManager::getInstance( + ).getAttribModName(param.tag)); + setObjectField(*arg, ms_fidAttribModName, name); + if (!AttribMod::isSkillMod(param)) + { + setIntField(*arg, ms_fidAttribModType, param.attrib); + } + else + { + JavaString skill(AttribModNameManager::getInstance( + ).getAttribModName(param.skill)); + setObjectField(*arg, ms_fidAttribModSkill, skill); + } + setIntField(*arg, ms_fidAttribModValue, param.value); + setFloatField(*arg, ms_fidAttribModTime, param.sustain); + setFloatField(*arg, ms_fidAttribModAttack, param.attack); + setFloatField(*arg, ms_fidAttribModDecay, param.decay); + setIntField(*arg, ms_fidAttribModFlags, param.flags); + } + break; + + case 'M': + if (modifiable || dimensions > 1) + break; + if (dimensions == 1) + { + // mental_state_mod array + if (args.getParamType(paramIndex) != Param::MENTAL_STATE_MOD_ARRAY) + break; + const std::vector & param = args.getMentalStateModArrayParam(paramIndex); + int count = param.size(); + int paramCount = 0; + for (int j = 0; j < count; ++j) + { + // only send mental_state_mods that actually do something + if (param[j].value != 0) + { + arg = globals.getNextMentalStateMod(); + if (arg == GlobalRef::cms_nullPtr) + return 0; + + setIntField(*arg, ms_fidMentalStateModType, param[j].target); + setFloatField(*arg, ms_fidMentalStateModValue, param[j].value); + setFloatField(*arg, ms_fidMentalStateModTime, param[j].timeAtValue); + setFloatField(*arg, ms_fidMentalStateModAttack, param[j].time); + setFloatField(*arg, ms_fidMentalStateModDecay, param[j].decay); + setObjectArrayElement( + *ms_mentalStateModList[ms_currentRecursionCount], + static_cast(paramCount), *arg); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + return 0; + } + ++paramCount; + } + } + // fill in the rest of ms_mentalStateModList with null + for (; paramCount < MAX_MENTAL_STATE_MOD_PARAMS; ++paramCount) + { + setObjectArrayElement( + *ms_mentalStateModList[ms_currentRecursionCount], + static_cast(paramCount), *LocalRefParam::cms_nullPtr); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + return 0; + } + } + arg = ms_mentalStateModList[ms_currentRecursionCount]; + } + else + { + // single mental_state_mod + if (args.getParamType(paramIndex) != Param::MENTAL_STATE_MOD) + break; + const ServerObjectTemplate::MentalStateMod ¶m = args.getMentalStateModParam(paramIndex); + arg = globals.getNextMentalStateMod(); + if (arg == GlobalRef::cms_nullPtr) + return 0; + + setIntField(*arg, ms_fidMentalStateModType, param.target); + setFloatField(*arg, ms_fidMentalStateModValue, param.value); + setFloatField(*arg, ms_fidMentalStateModTime, param.timeAtValue); + setFloatField(*arg, ms_fidMentalStateModAttack, param.time); + setFloatField(*arg, ms_fidMentalStateModDecay, param.decay); + } + break; + + case 'D': + if (!modifiable && dimensions == 0) + { + const ManufactureObjectInterface & schematic = args.getManufactureSchematicParam(paramIndex); + arg = convert(schematic); + } + break; + + case 'I': + if (!modifiable && dimensions == 0) + { + const Crafting::IngredientSlot & slot = args.getIngredientSlotParam(paramIndex); + const ManufactureObjectInterface & schematic = args.getIngredientSlotParamSchematic(paramIndex); + int amountRequired = args.getIngredientSlotParamAmountRequired(paramIndex); + const std::string & appearance = args.getIngredientSlotParamAppearance(paramIndex); + arg = convert(schematic, slot, amountRequired, appearance, ""); + } + break; + + case 'V': + if (!modifiable) + { + if (dimensions == 0) + { + const ValueDictionary & dictionary = args.getValueDictionaryParam(paramIndex); + arg = convert(dictionary); + } + else if (dimensions == 1) + { + const std::vector & param = args.getValueDictionaryArrayParam(paramIndex); + LocalObjectArrayRefPtr localInstance = createNewObjectArray(param.size(), ms_clsDictionary); + + int paramCount = 0; + std::vector::const_iterator iter; + for (iter = param.begin(); iter != param.end(); ++iter) + { + setObjectArrayElement(*localInstance, static_cast(paramCount++), *convert(*iter)); + + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + return 0; + } + } + arg = localInstance; + } + } + break; + + default: + DEBUG_REPORT_LOG(true, ("unknown parameter type %c(%#x)\n", argType, + static_cast(argType))); //lint !e571 suspicious cast + return 0; + } + if (arg.get() == NULL || arg == LocalRef::cms_nullPtr) + { + DEBUG_REPORT_LOG(true, ("bad parameter, %c%s%d%s\n", argType, + modifiable ? "*" : "", + dimensions, + dimensions > 0 ? " dimensions" : "" + )); + return 0; + } + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + return 0; + } + setObjectArrayElement(*javaParams, static_cast(paramIndex + startIndex), *arg); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + return 0; + } + } + return true; +} // JavaLibrary::convert + +/** + * Copies any modifiable params from Java to C. This is called after a script + * has run. + * + * @param jparams Java parameters + * @param argList argument list description + * @param args arguments that were passed to the script + */ +void JavaLibrary::alterScriptParams(jobjectArray jparams, const std::string& argList, + ScriptParams &args) +{ + if (ms_env == NULL) + return; + + PROFILER_AUTO_BLOCK_CHECK_DEFINE("JavaLibrary::alterScriptParams"); + + int paramIndex = 0; + for (unsigned i = 0; i < argList.size(); ++i, ++paramIndex) + { + switch (argList[i]) + { + case 'i': + if (i < argList.size() - 1 && argList[i+1] == '*') + { + ++i; + if (i == argList.size() || argList[i+1] != '[') + { + LocalRefPtr arg = getObjectArrayElement(LocalObjectArrayRefParam(jparams), paramIndex + 1); + if (arg != LocalRef::cms_nullPtr) + { + int value = getIntField(*arg, ms_fidModifiableIntData); + args.changeParam(paramIndex, value); + } + else + { + WARNING_STRICT_FATAL(true, ("Error getting back integer param on script return paramIndex=%d, i=%d", paramIndex, i)); + } + } + else if (i < argList.size() - 1 && argList[i+1] == '[') + { + ++i; + + LocalArrayRefPtr arg = getArrayArrayElement(LocalObjectArrayRefParam(jparams), paramIndex + 1); + if (arg != LocalArrayRef::cms_nullPtr) + { + int count = getArrayLength(*arg); + std::vector * values = new std::vector(count, 0); + jint * jvalues = static_cast(ms_env->GetPrimitiveArrayCritical(static_cast(arg->getValue()), NULL)); + for (int j = 0; j < count; ++j) + { + values->at(j) = static_cast(jvalues[j]); + } + ms_env->ReleasePrimitiveArrayCritical(static_cast(arg->getValue()), jvalues, JNI_ABORT); + args.changeParam(paramIndex, *values, true); + } + else + { + WARNING_STRICT_FATAL(true, ("Error getting back integer array param on script return")); + } + } + } + break; + case 'U': + if (i < argList.size() - 1 && argList[i+1] == '*') + { + ++i; + if (i == argList.size() || argList[i+1] != '[') + { + WARNING_STRICT_FATAL(true, ("Error getting back vector param on script return paramIndex=%d, i=%d", paramIndex, i)); + } + else if (i < argList.size() - 1 && argList[i+1] == '[') + { + ++i; + + LocalArrayRefPtr arg = getArrayArrayElement(LocalObjectArrayRefParam(jparams), paramIndex + 1); + if (arg != LocalArrayRef::cms_nullPtr) + { + int count = getArrayLength(*arg); + std::vector * values = new std::vector(count, 0); + jbyte * jvalues = static_cast(ms_env->GetPrimitiveArrayCritical(static_cast(arg->getValue()), NULL)); + for (int j = 0; j < count; ++j) + { + values->at(j) = static_cast(jvalues[j]); + } + ms_env->ReleasePrimitiveArrayCritical(static_cast(arg->getValue()), jvalues, JNI_ABORT); + args.changeParam(paramIndex, *values, true); + } + else + { + WARNING_STRICT_FATAL(true, ("Error getting back integer array param on script return")); + } + } + } + break; + + case 'f': + if (i < argList.size() - 1 && argList[i+1] == '*') + { + ++i; + LocalRefPtr arg = getObjectArrayElement(LocalObjectArrayRefParam(jparams), paramIndex + 1); + if (arg != LocalRef::cms_nullPtr) + { + args.changeParam(paramIndex, getFloatField(*arg, ms_fidModifiableFloatData)); + } + else + { + WARNING_STRICT_FATAL(true, ("Error getting back float param on script return")); + } + } + break; + case 's': + if (i < argList.size() - 1 && argList[i+1] == '*') + { + ++i; + if (i < argList.size() - 1 && argList[i+1] == '[') + { + ++i; + LocalObjectArrayRefPtr arg = getObjectArrayArrayElement(LocalObjectArrayRefParam(jparams), paramIndex + 1); + if (arg != LocalObjectArrayRef::cms_nullPtr) + { + std::vector * strings = new std::vector(); + getStringArray(*arg, *strings); + args.changeParam(paramIndex, *strings, true); + } + else + { + WARNING_STRICT_FATAL(true, ("Error getting back string array param on script return")); + } + } + } + break; + case 'u': + if (i < argList.size() - 1 && argList[i+1] == '*') + { + ++i; + if (i < argList.size() - 1 && argList[i+1] == '[') + { + ++i; + LocalObjectArrayRefPtr arg = getObjectArrayArrayElement(LocalObjectArrayRefParam(jparams), paramIndex + 1); + if (arg != LocalObjectArrayRef::cms_nullPtr) + { + std::vector * strings = new std::vector(); + getStringArray(*arg, *strings); + args.changeParam(paramIndex, *strings, true); + } + else + { + WARNING_STRICT_FATAL(true, ("Error getting back string array param on script return")); + } + } + } + break; + case 'S': + if (i < argList.size() - 1 && argList[i+1] == '*') + { + ++i; + StringId * value = new StringId(); + LocalRefPtr arg = getObjectArrayElement(LocalObjectArrayRefParam(jparams), paramIndex + 1); + if (arg != LocalRef::cms_nullPtr) + { + // get the string id table + JavaStringPtr table = getStringField(*arg, ms_fidStringIdTable); + std::string localString; + convert(*table, localString); + value->setTable(localString); + // get the string id text, if it is not NULL/empty, use it + localString.clear(); + JavaStringPtr text = getStringField(*arg, ms_fidStringIdAsciiId); + if (text != JavaString::cms_nullPtr) + convert(*text, localString); + if (localString[0] != '\0') + value->setText(localString); + else + { + // use the textIndex field instead + jint textIndex = getIntField(*arg, ms_fidStringIdIndexId); + value->setTextIndex(textIndex); + } + args.changeParam(paramIndex, *value, true); + } + else + { + WARNING_STRICT_FATAL(true, ("Error getting back string id param on script return")); + } + } + break; + + + //---------------------------------------------------------------------- + //-- menu info + + case 'm': + if (i < argList.size() - 1 && argList[i+1] == '*') + { + ++i; + + LocalRefPtr arg = getObjectArrayElement(LocalObjectArrayRefParam(jparams), paramIndex + 1); + MenuDataVector * menuVector = new MenuDataVector; + convert(arg, *menuVector); + args.changeParam (paramIndex, *menuVector, true); + } + break; + + //---------------------------------------------------------------------- + + default: + break; + } + // skip extra characters in the arglist + if (i < argList.size() - 1) + { + if (argList[i+1] == '[' || argList[i+1] == '*') + ++i; + } + } +} // JavaLibrary::alterScriptParams + +/** + * Executes all the scripts attached to an object; invoked from C code. + * + * @param caller object id of the network object invoking this script + * @param method script method name + * @param argList argument list description + * @param args arguments to be passed to the script + * + * @return SCRIPT_CONTINUE or SCRIPT_OVERRIDE + */ +int JavaLibrary::runScripts(const NetworkId & caller, + const std::string& method, const std::string& argList, ScriptParams & args) +{ + // get the current env count, in case we reset our Java connection + int currentEnvCount = ms_envCount; + + PROFILER_AUTO_BLOCK_CHECK_DEFINE("JavaLibrary::runScripts"); + + GlobalInstances globals; + + DEBUG_REPORT_LOG(ConfigServerGame::getJavaConsoleDebugMessages(), ( + "JavaLibrary::runScripts enter, self = %s, method = %s\n", + caller.getValueString().c_str(), method.c_str())); + + if (ms_env == NULL || ms_clsObject == NULL) + { + DEBUG_REPORT_LOG(ConfigServerGame::getJavaConsoleDebugMessages(), ( + "JavaLibrary::runScripts exit, self = %s, method = %s\n", + caller.getValueString().c_str(), method.c_str())); + if (!ms_env) + { + LOG("ScriptInvestigation", ("runSCripts failed because env was null")); + } + else + { + LOG("ScriptInvestigation", ("runSCripts failed because clsObject was null")); + } + return SCRIPT_OVERRIDE; + } + + if (ms_currentRecursionCount >= MAX_RECURSION_COUNT) + { + DEBUG_REPORT_LOG(true, ("JavaLibrary::runScripts (C version) max recursion " + "count reached, method = %s, object id = %s, dumping script!\n", + method.c_str(), caller.getValueString().c_str())); + LOG("ScriptInvestigation", ("runSCripts failed because max recursion count reached")); + return SCRIPT_OVERRIDE; + } + + // convert the script and method strings to jstrings + JavaString jmethod(method.c_str()); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + REPORT_LOG(ConfigServerGame::getJavaConsoleDebugMessages(), ( + "JavaLibrary::runScripts exit, self = %s, method = %s\n", + caller.getValueString().c_str(), method.c_str())); + LOG("ScriptInvestigation", ("runScripts failed trying to convert method " + "name to jstring")); + return SCRIPT_OVERRIDE; + } + + // convert the params to jobjects + LocalObjectArrayRefPtr jparams = convert(caller, argList, args); + if (jparams == LocalObjectArrayRef::cms_nullPtr) + { + DEBUG_REPORT_LOG(ConfigServerGame::getJavaConsoleDebugMessages(), ( + "JavaLibrary::runScripts exit, self = %s, method = %s\n", + caller.getValueString().c_str(), method.c_str())); + LOG("ScriptInvestigation", ("runSCripts failed because could not convert params")); + return SCRIPT_OVERRIDE; + } + + // invoke the script method + jint result = callScriptEntry(jmethod, jparams->getValue()); + + //========================================================================== + // !!IMPORTANT after this point our env pointer may have changed, we can't + // call any JNI functions on objects created with the old pointer!! + //========================================================================== + + if (result == SCRIPT_CONTINUE && argList.find('*') != std::string::npos) + { + if (currentEnvCount == ms_envCount) + { + // copy any modifiable params from Java to C + alterScriptParams(jparams->getValue(), argList, args); + } + else + { + LOG("ScriptInvestigation", ("JavaLibrary::runScripts env has changed, " + "we can't get return params for trigger %s", method.c_str())); + } + } + + if (currentEnvCount == ms_envCount) + { + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + DEBUG_REPORT_LOG(ConfigServerGame::getJavaConsoleDebugMessages(), ( + "JavaLibrary::runScripts exit, self = %s, method = %s\n", + caller.getValueString().c_str(), method.c_str())); + LOG("ScriptInvestigation", ("runSCripts failed because exception after delete")); + return SCRIPT_OVERRIDE; + } + } + else + { + DEBUG_LOG("ScriptInvestigation", ("JavaLibrary::runScripts env changed after trigger %s", method.c_str())); + jmethod.emergencyClear(); + } + + DEBUG_REPORT_LOG(ConfigServerGame::getJavaConsoleDebugMessages(), ( + "JavaLibrary::runScripts exit, self = %s, method = %s\n", + caller.getValueString().c_str(), method.c_str())); + return result; +} // JavaLibrary::runScripts(const ScriptParams & args) + +/** + * Executes all the scripts attached to an object; invoked from the console. + * + * @param caller object id of the network object invoking this script + * @param method script method name + * @param argList argument list description + * @param args arguments to be passed to the script + * + * @return SCRIPT_CONTINUE or SCRIPT_OVERRIDE + */ +int JavaLibrary::runScripts(const NetworkId & caller, + const std::string& method, const std::string& argList, const StringVector_t &args) +{ + DEBUG_WARNING(true, ("Running scripts from the console not currently supported")); + LOG("ScriptInvestigation", ("runScripts from console is not supported")); + return SCRIPT_OVERRIDE; +} // JavaLibrary::runScripts(StringVector_t args) + +/** + * Executes a script invoked from C code. + * + * @param caller object id of the network object invoking this script + * @param script script name + * @param method script method name + * @param argList argument list description + * @param args arguments to be passed to the script + * + * @return SCRIPT_CONTINUE or SCRIPT_OVERRIDE + */ +int JavaLibrary::runScript(const NetworkId & caller, const std::string& script, + const std::string& method, const std::string& argList, ScriptParams & args) +{ + // get the current env count, in case we reset our Java connection + int currentEnvCount = ms_envCount; + + PROFILER_AUTO_BLOCK_CHECK_DEFINE("JavaLibrary::runScript"); + + GlobalInstances globals; + + DEBUG_REPORT_LOG(ConfigServerGame::getJavaConsoleDebugMessages(), ( + "JavaLibrary::runScript %s enter, self = %s, method = %s\n", + script.c_str(), caller.getValueString().c_str(), method.c_str())); + + if (ms_env == NULL || ms_midRunOne == NULL || ms_clsObject == NULL) + { + if (!ms_env) + { + LOG("ScriptInvestigation", ("runSCripts2 failed because env was null")); + } + else if (!ms_midRunOne) + { + LOG("ScriptInvestigation", ("runSCripts2 failed because midRunOne was null")); + } + else + { + LOG("ScriptInvestigation", ("runSCripts2 failed because clsObject was null")); + } + + return SCRIPT_OVERRIDE; + } + + if (ms_currentRecursionCount >= MAX_RECURSION_COUNT) + { + DEBUG_REPORT_LOG(true, ("JavaLibrary::runScript (C version) max recursion " + "count reached, script = %s, method = %s, object id = %s, dumping " + "script!\n", script.c_str(), method.c_str(), caller.getValueString().c_str())); + LOG("ScriptInvestigation", ("runSCripts2 failed because max recursion count reached")); + return SCRIPT_OVERRIDE; + } + + // convert the script and method strings to jstrings + JavaString jscript(("script." + script).c_str()); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + LOG("ScriptInvestigation", ("runSCripts2 failed because of exception")); + return SCRIPT_OVERRIDE; + } + JavaString jmethod(method.c_str()); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + LOG("ScriptInvestigation", ("runSCripts2 failed because of exception2")); + return SCRIPT_OVERRIDE; + } + + // convert the params to jobjects + LocalObjectArrayRefPtr jparams = convert(caller, argList, args); + if (jparams == LocalObjectArrayRef::cms_nullPtr) + { + ms_env->ExceptionDescribe(); + LOG("ScriptInvestigation", ("runSCripts2 failed because of exception3")); + return SCRIPT_OVERRIDE; + } + + // invoke the script method + jint result = callScriptEntry(jscript, jmethod, jparams->getValue()); + + //========================================================================== + // !!IMPORTANT after this point our env pointer may have changed, we can't + // call any JNI functions on objects created with the old pointer!! + //========================================================================== + + if (result == SCRIPT_DEFAULT) + result = SCRIPT_CONTINUE; + if (result == SCRIPT_CONTINUE && argList.find('*') != std::string::npos) + { + if (currentEnvCount == ms_envCount) + { + // copy any modifiable params from Java to C + alterScriptParams(jparams->getValue(), argList, args); + } + else + { + LOG("ScriptInvestigation", ("JavaLibrary::runScript env has changed, " + "we can't get return params for trigger %s", method.c_str())); + } + } + + if (currentEnvCount == ms_envCount) + { + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + LOG("ScriptInvestigation", ("runScript failed because of exception4")); + return SCRIPT_OVERRIDE; + } + } + else + { + DEBUG_LOG("ScriptInvestigation", ("JavaLibrary::runScript env changed after trigger %s", method.c_str())); + jscript.emergencyClear(); + jmethod.emergencyClear(); + } + + DEBUG_REPORT_LOG(ConfigServerGame::getJavaConsoleDebugMessages(), ( + "JavaLibrary::runScript %s exit, self = %s, method = %s\n", + script.c_str(), caller.getValueString().c_str(), method.c_str())); + + return result; +} // JavaLibrary::runScript(const ScriptParams & args) + +/** + * Executes a script invoked from Java code. + * + * @param caller object id of the network object invoking this script + * @param script script name + * @param method script method name + * @param args arguments to be passed to the script + * + * @return SCRIPT_CONTINUE or SCRIPT_OVERRIDE + */ +int JavaLibrary::runScript(const NetworkId & caller, const std::string& script, + const std::string& method, jobjectArray args) +{ + // get the current env count, in case we reset our Java connection + int currentEnvCount = ms_envCount; + + PROFILER_AUTO_BLOCK_CHECK_DEFINE("JavaLibrary::runScript"); + + DEBUG_REPORT_LOG(true, ("JavaLibrary::runScript %s enter, method = %s\n", + script.c_str(), method.c_str())); + + if (ms_env == NULL || ms_midRunOne == NULL || ms_clsObject == NULL) + { + if (!ms_env) + { + LOG("ScriptInvestigation", ("runSCripts3 failed because env was null")); + } + else if (!ms_midRunOne) + { + LOG("ScriptInvestigation", ("runSCripts3 failed because midRunOne was null")); + } + else + { + LOG("ScriptInvestigation", ("runSCripts3 failed because clsObject was null")); + } + return SCRIPT_OVERRIDE; + } + + if (ms_currentRecursionCount >= MAX_RECURSION_COUNT) + { + DEBUG_REPORT_LOG(true, ("JavaLibrary::runScript (Java version) max " + "recursion count reached, script = %s, method = %s, object id = %s, " + "dumping script!\n", script.c_str(), method.c_str(), + caller.getValueString().c_str())); + LOG("ScriptInvestigation", ("runSCripts3 failed because of max recursion count")); + return SCRIPT_OVERRIDE; + } + + // convert the script and method strings to jstrings + JavaString jscript(("script." + script).c_str()); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + LOG("ScriptInvestigation", ("runSCripts3 failed because of exception")); + return SCRIPT_OVERRIDE; + } + JavaString jmethod(method.c_str()); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + LOG("ScriptInvestigation", ("runSCripts3 failed because of exception2")); + return SCRIPT_OVERRIDE; + } + + // copy the args to a new array that has the object id tacked on + int argsCount = 1; + if (args != 0) + argsCount += ms_env->GetArrayLength(args); + + LocalObjectArrayRefPtr jparams = createNewObjectArray(argsCount, ms_clsObject); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + LOG("ScriptInvestigation", ("runSCripts3 failed because of exception3")); + return SCRIPT_OVERRIDE; + } + for (int i = 1; i < argsCount; ++i) + { + LocalRefPtr element = getObjectArrayElement(LocalObjectArrayRefParam(args), i - 1); + setObjectArrayElement(*jparams, i, *element); + } + + // add the "self" parameter as the 1st argument + LocalRefPtr self = getObjId(caller); + setObjectArrayElement(*jparams, 0, *self); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + LOG("ScriptInvestigation", ("runSCripts3 failed because of exception4")); + return SCRIPT_OVERRIDE; + } + + // invoke the script method + jint result = callScriptEntry(jscript, jmethod, jparams->getValue()); + + //========================================================================== + // !!IMPORTANT after this point our env pointer may have changed, we can't + // call any JNI functions on objects created with the old pointer!! + //========================================================================== + + if (currentEnvCount == ms_envCount) + { + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + LOG("ScriptInvestigation", ("runSCripts3 failed because of exception5")); + return SCRIPT_OVERRIDE; + } + } + else + { + DEBUG_LOG("ScriptInvestigation", ("JavaLibrary::runScript(from java) env changed after trigger %s", method.c_str())); + self->emergencyClear(); + jparams->emergencyClear(); + jscript.emergencyClear(); + jmethod.emergencyClear(); + } + + DEBUG_REPORT_LOG(true, ("JavaLibrary::runScript %s exit, method = %s\n", + script.c_str(), method.c_str())); + + return result; +} // JavaLibrary::runScript(jobjectArray args) + +/** + * Executes a script invoked from the console. + * + * @param caller object id of the network object invoking this script + * @param script script name + * @param method script method name + * @param argList argument list description + * @param args arguments to be passed to the script + * + * @return SCRIPT_CONTINUE or SCRIPT_OVERRIDE + */ +int JavaLibrary::runScript(const NetworkId & caller, const std::string& script, + const std::string& method, const std::string& argList, const StringVector_t &args) +{ + // get the current env count, in case we reset our Java connection + int currentEnvCount = ms_envCount; + + PROFILER_AUTO_BLOCK_CHECK_DEFINE("JavaLibrary::runScript"); + + GlobalInstances globals; + + DEBUG_REPORT_LOG(true, ("JavaLibrary::runScript %s enter, method = %s\n", script.c_str(), + method.c_str())); + + if (ms_env == NULL || ms_midRunOne == NULL || ms_clsObject == NULL) + { + if (!ms_env) + { + LOG("ScriptInvestigation", ("runSCripts4 failed because env was null")); + } + else if (!ms_midRunOne) + { + LOG("ScriptInvestigation", ("runSCripts4 failed because midRunOne was null")); + } + else + { + LOG("ScriptInvestigation", ("runSCripts4 failed because clsObject was null")); + } + + return SCRIPT_OVERRIDE; + } + + if (ms_currentRecursionCount >= MAX_RECURSION_COUNT) + { + DEBUG_REPORT_LOG(true, ("JavaLibrary::runScript (console version) max " + "recursion count reached, script = %s, method = %s, object id = %s, " + "dumping script!\n", script.c_str(), method.c_str(), + caller.getValueString().c_str())); + LOG("ScriptInvestigation", ("runSCripts4 failed because of max recursion count")); + return SCRIPT_OVERRIDE; + } + + // convert the script and method strings to jstrings + JavaString jscript(("script." + script).c_str()); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + LOG("ScriptInvestigation", ("runSCripts4 failed because of exception")); + return SCRIPT_OVERRIDE; + } + JavaString jmethod(method.c_str()); + if (ms_env->ExceptionCheck()) + { + LOG("ScriptInvestigation", ("runSCripts4 failed because of exception2")); + ms_env->ExceptionDescribe(); + return SCRIPT_OVERRIDE; + } + + // convert the params to jobjects + LocalObjectArrayRefPtr jparams = createNewObjectArray(static_cast(argList.size() + 1), + ms_clsObject); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + LOG("ScriptInvestigation", ("runSCripts4 failed because of exception3")); + return SCRIPT_OVERRIDE; + } + // add the "self" parameter + LocalRefPtr self = getObjId(caller); + setObjectArrayElement(*jparams, 0, *self); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + LOG("ScriptInvestigation", ("runSCripts4 failed because of exception4")); + return SCRIPT_OVERRIDE; + } + + // add the rest of the parameters + for (unsigned i = 0; i < argList.size(); ++i) + { + LocalRefParamPtr arg = LocalRefParam::cms_nullPtr; + const char *stringArg = Unicode::wideToNarrow(args[i]).c_str(); + switch (argList[i]) + { + case 'i': + { + jint param = atoi(stringArg); + arg = createNewObject(ms_clsInteger, ms_midInteger, param); + } + break; + case 'f': + { + jfloat param = static_cast(atof(stringArg)); + arg = createNewObject(ms_clsFloat, ms_midFloat, param); + } + break; + case 's': + { + arg = createNewString(stringArg); + } + break; + case 'u': + { + arg = createNewString(args[i].c_str(), static_cast(args[i].size())); + } + break; + case 'O': + { + arg = getObjId(NetworkId(stringArg)); + if (arg == LocalRef::cms_nullPtr) + { + LOG("ScriptInvestigation", ("runSCripts4 failed because of bad objid")); + return SCRIPT_OVERRIDE; + } + } + break; +#if 0 + case 'S': + { + arg = globals.getNextStringId(); + if (arg == 0) + { + return SCRIPT_OVERRIDE; + } + // @todo: fix this when we get real string ids +// int param = atoi(stringArg); +// ms_env->SetIntField(arg, ms_fidStringIdData, static_cast(param)); + } + break; +#endif + default: + DEBUG_REPORT_LOG(true, ("unknown parameter type %c(%#x)\n", argList[i], + static_cast(argList[i]))); //lint !e571 suspicious cast + LOG("ScriptInvestigation", ("runSCripts4 failed because of param")); + return SCRIPT_OVERRIDE; + } + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + LOG("ScriptInvestigation", ("runSCripts4 failed because of exception5")); + return SCRIPT_OVERRIDE; + } + setObjectArrayElement(*jparams, static_cast(i + 1), *arg); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + LOG("ScriptInvestigation", ("runSCripts4 failed because of exception6")); + return SCRIPT_OVERRIDE; + } + } + + // invoke the script method + jint result = callScriptEntry(jscript, jmethod, jparams->getValue()); + + //========================================================================== + // !!IMPORTANT after this point our env pointer may have changed, we can't + // call any JNI functions on objects created with the old pointer!! + //========================================================================== + + if (currentEnvCount == ms_envCount) + { + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + LOG("ScriptInvestigation", ("runSCripts4 failed because of exception7")); + return SCRIPT_OVERRIDE; + } + } + else + { + DEBUG_LOG("ScriptInvestigation", ("JavaLibrary::runScript(from console) env changed after trigger %s", method.c_str())); + self->emergencyClear(); + jparams->emergencyClear(); + jscript.emergencyClear(); + jmethod.emergencyClear(); + } + + return result; +} // JavaLibrary::runScript(StringVector_t args) + +/** + * Calls a special function on a script that returns a string instead of an + * integer. The script function has no "self" associated with it. + * + * @param script the name of the script to call + * @param method the function name in the script + * @param argList the argument types that are being passed to the script + * @param args the arguments that are being passed to the script + * + * @return the string returned from the script function + */ +std::string JavaLibrary::callScriptConsoleHandler(const std::string & script, + const std::string & method, const std::string & argList, ScriptParams & args) +{ +static const std::string errorReturnString; + + // get the current env count, in case we reset our Java connection + int currentEnvCount = ms_envCount; + + PROFILER_AUTO_BLOCK_CHECK_DEFINE("JavaLibrary::callScriptConsoleHandler"); + + GlobalInstances globals; + + DEBUG_REPORT_LOG(ConfigServerGame::getJavaConsoleDebugMessages(), ( + "JavaLibrary::runScript %s enter, method = %s\n", script.c_str(), + method.c_str())); + + if (ms_env == NULL || ms_midRunConsoleHandler == NULL || ms_clsObject == NULL) + { + if (!ms_env) + { + LOG("ScriptInvestigation", ("runSCripts2 failed because env was null")); + } + else if (!ms_midRunConsoleHandler) + { + LOG("ScriptInvestigation", ("runSCripts2 failed because midRunConsoleHandler was null")); + } + else + { + LOG("ScriptInvestigation", ("runSCripts2 failed because clsObject was null")); + } + + return errorReturnString; + } + + if (ms_currentRecursionCount >= MAX_RECURSION_COUNT) + { + DEBUG_REPORT_LOG(true, ("JavaLibrary::callScriptConsoleHandler max recursion " + "count reached, script = %s, method = %s, dumping " + "script!\n", script.c_str(), method.c_str())); + LOG("ScriptInvestigation", ("callScriptConsoleHandler failed because max recursion count reached")); + return errorReturnString; + } + + // convert the script and method strings to jstrings + JavaString jscript(("script." + script).c_str()); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + LOG("ScriptInvestigation", ("callScriptConsoleHandler failed because of exception")); + return errorReturnString; + } + JavaString jmethod(method.c_str()); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + LOG("ScriptInvestigation", ("callScriptConsoleHandler failed because of exception2")); + return errorReturnString; + } + + // convert the params to jobjects + LocalObjectArrayRefPtr jparams = convert(argList, args); + if (jparams == LocalObjectArrayRef::cms_nullPtr) + { + ms_env->ExceptionDescribe(); + LOG("ScriptInvestigation", ("callScriptConsoleHandler failed because of exception3")); + return errorReturnString; + } + + // invoke the script method + jstring result = callScriptConsoleHandlerEntry(jscript, jmethod, jparams->getValue()); + + //========================================================================== + // !!IMPORTANT after this point our env pointer may have changed, we can't + // call any JNI functions on objects created with the old pointer!! + //========================================================================== + + std::string returnResult; + if (currentEnvCount == ms_envCount) + { + JavaString resultString(result); + + if (argList.find('*') != std::string::npos) + { + // copy any modifiable params from Java to C + alterScriptParams(jparams->getValue(), argList, args); + } + + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + LOG("ScriptInvestigation", ("callScriptConsoleHandler failed because of exception4")); + return errorReturnString; + } + convert(resultString, returnResult); + } + else + { + DEBUG_LOG("ScriptInvestigation", ("JavaLibrary::callScriptConsoleHandler env changed after trigger %s", method.c_str())); + jscript.emergencyClear(); + jmethod.emergencyClear(); + } + + DEBUG_REPORT_LOG(ConfigServerGame::getJavaConsoleDebugMessages(), ( + "JavaLibrary::callScriptConsoleHandler %s exit, method = %s\n", + script.c_str(), method.c_str())); + + return returnResult; +} // JavaLibrary::callScriptConsoleHandler + +/** + * Tells the script engine to reload a script file. + * + * @param scriptName the script name + * + * @return true on success, false if the script wasn't found + */ +bool JavaLibrary::reloadScript(const std::string& scriptName) +{ + if (ms_env == NULL || ms_clsScriptEntry == NULL || ms_midUnload == NULL) + return false; + + // convert the script name to jstring + JavaString jscript(("script." + scriptName).c_str()); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + return false; + } + + // call the unload method + jboolean result = ms_env->CallStaticBooleanMethod(ms_clsScriptEntry, ms_midUnload, + jscript.getValue()); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + return false; + } + return result; +} // JavaLibrary::reloadScript + +/** + * Calls a user-defined message method on all scripts attached to an object. + * + * @param caller object id of the network object invoking this script + * @param method script message method name + * @param data data to be passed to the message + * + * @return SCRIPT_CONTINUE or SCRIPT_OVERRIDE + */ +int JavaLibrary::callMessages(const NetworkId & caller, const std::string & method, const ScriptDictionaryPtr & data) +{ + // get the current env count, in case we reset our Java connection + int currentEnvCount = ms_envCount; + + DEBUG_REPORT_LOG(ConfigServerGame::getJavaConsoleDebugMessages(), ( + "JavaLibrary::callMessages enter, self = %s, method = %s\n", + caller.getValueString().c_str(), method.c_str())); + + int result = SCRIPT_CONTINUE; + + if (ms_env == NULL || ms_midRunOne == NULL || ms_clsObject == NULL) + { + DEBUG_REPORT_LOG(ConfigServerGame::getJavaConsoleDebugMessages(), ( + "JavaLibrary::callMessages exit, self = %s, method = %s\n", + caller.getValueString().c_str(), method.c_str())); + if (!ms_env) + { + LOG("ScriptInvestigation", ("callMessages failed because env was null")); + } + else if (!ms_midRunOne) + { + LOG("ScriptInvestigation", ("callMessages failed because midRunOne was null")); + } + else + { + LOG("ScriptInvestigation", ("callMessages failed because clsObject was null")); + } + + return SCRIPT_OVERRIDE; + } + + if (ms_currentRecursionCount >= MAX_RECURSION_COUNT) + { + DEBUG_REPORT_LOG(true, ("JavaLibrary::callMessages max recursion count reached, " + "method = %s, object id = %s, dumping script!\n", + method.c_str(), caller.getValueString().c_str())); + LOG("ScriptInvestigation", ("callMessages failed because max recurion count")); + return SCRIPT_OVERRIDE; + } + + const JavaDictionary * dictionary = safe_cast(data.get()); + jobject jdictionary = 0; + if (dictionary != NULL) + jdictionary = dictionary->getValue(); + + // convert the method string to jstrings + JavaString jmethod(method.c_str()); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + DEBUG_REPORT_LOG(ConfigServerGame::getJavaConsoleDebugMessages(), ( + "JavaLibrary::callMessages exit, self = %s, method = %s\n", + caller.getValueString().c_str(), method.c_str())); + LOG("ScriptInvestigation", ("callMessages failed because of exception")); + return SCRIPT_OVERRIDE; + } + + ++ms_currentRecursionCount; + if (ms_currentRecursionCount > 3) + { + LOG("ScriptRecursion", ("callMessages recursion %d", ms_currentRecursionCount)); + } + result = ms_env->CallStaticIntMethod(ms_clsScriptEntry, ms_midCallMessages, jmethod.getValue(), caller.getValue(), jdictionary); + --ms_currentRecursionCount; + + result = handleScriptEntryCleanup(result); + + //========================================================================== + // !!IMPORTANT after this point our env pointer may have changed, we can't + // call any JNI functions on objects created with the old pointer!! + //========================================================================== + + if (currentEnvCount != ms_envCount) + { + jmethod.emergencyClear(); + } + + DEBUG_REPORT_LOG(ConfigServerGame::getJavaConsoleDebugMessages(), ( + "JavaLibrary::callMessages exit, self = %s, method = %s\n", + caller.getValueString().c_str(), method.c_str())); + + return result; +} // JavaLibrary::callMessages + +/** + * Calls a user-defined message method on a script attached to an object. + * + * @param caller object id of the network object invoking this script + * @param script script name + * @param method script message method name + * @param data data to be passed to the message + * + * @return SCRIPT_CONTINUE or SCRIPT_OVERRIDE + */ +int JavaLibrary::callMessage(const NetworkId & caller, const std::string & script, + const std::string & method, const ScriptDictionary & data) +{ + // get the current env count, in case we reset our Java connection + int currentEnvCount = ms_envCount; + + DEBUG_REPORT_LOG(ConfigServerGame::getJavaConsoleDebugMessages(), ( + "JavaLibrary::callMessage %s enter, self = %s, method = %s\n", + script.c_str(), caller.getValueString().c_str(), method.c_str())); + + if (ms_env == NULL || ms_midRunOne == NULL || ms_clsObject == NULL) + { + DEBUG_REPORT_LOG(ConfigServerGame::getJavaConsoleDebugMessages(), ( + "JavaLibrary::callMessage %s exit, self = %s, method = %s\n", + script.c_str(), caller.getValueString().c_str(), method.c_str())); + if (!ms_env) + { + LOG("ScriptInvestigation", ("callMessage failed because env was null")); + } + else if (!ms_midRunOne) + { + LOG("ScriptInvestigation", ("callMessage failed because midRunOne was null")); + } + else + { + LOG("ScriptInvestigation", ("callMessage failed because clsObject was null")); + } + + return SCRIPT_OVERRIDE; + } + + if (ms_currentRecursionCount >= MAX_RECURSION_COUNT) + { + DEBUG_REPORT_LOG(true, ("JavaLibrary::callMessage max recursion count reached, " + "script = %s, method = %s, object id = %s, dumping script!\n", + script.c_str(), method.c_str(), caller.getValueString().c_str())); + LOG("ScriptInvestigation", ("callMessage failed because max recursion count")); + return SCRIPT_OVERRIDE; + } + + const JavaDictionary * dictionary = dynamic_cast(&data); + if (dictionary == NULL) + { + DEBUG_REPORT_LOG(ConfigServerGame::getJavaConsoleDebugMessages(), ( + "JavaLibrary::callMessage %s exit, self = %s, method = %s\n", + script.c_str(), caller.getValueString().c_str(), method.c_str())); + LOG("ScriptInvestigation", ("callMessage failed because bad dictionary")); + return SCRIPT_OVERRIDE; + } + + // convert the script and method strings to jstrings + JavaString jscript(script.c_str()); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + DEBUG_REPORT_LOG(ConfigServerGame::getJavaConsoleDebugMessages(), ( + "JavaLibrary::callMessage %s exit, self = %s, method = %s\n", + script.c_str(), caller.getValueString().c_str(), method.c_str())); + LOG("ScriptInvestigation", ("callMessage failed because exception")); + return SCRIPT_OVERRIDE; + } + JavaString jmethod(method.c_str()); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + DEBUG_REPORT_LOG(ConfigServerGame::getJavaConsoleDebugMessages(), ( + "JavaLibrary::callMessage %s exit, self = %s, method = %s\n", + script.c_str(), caller.getValueString().c_str(), method.c_str())); + LOG("ScriptInvestigation", ("callMessage failed because exception2")); + return SCRIPT_OVERRIDE; + } + + // set up the parameters + LocalObjectArrayRefPtr jparams = createNewObjectArray(2, ms_clsObject); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + DEBUG_REPORT_LOG(ConfigServerGame::getJavaConsoleDebugMessages(), ( + "JavaLibrary::callMessage %s exit, self = %s, method = %s\n", + script.c_str(), caller.getValueString().c_str(), method.c_str())); + LOG("ScriptInvestigation", ("callMessage failed because exception3")); + return SCRIPT_OVERRIDE; + } + // add the data parameter + setObjectArrayElement(*jparams, 1, *dictionary); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + DEBUG_REPORT_LOG(ConfigServerGame::getJavaConsoleDebugMessages(), ( + "JavaLibrary::callMessage %s exit, self = %s, method = %s\n", + script.c_str(), caller.getValueString().c_str(), method.c_str())); + LOG("ScriptInvestigation", ("callMessage failed because exception4")); + return SCRIPT_OVERRIDE; + } + + // add the "self" parameter + LocalRefPtr self = getObjId(caller); + setObjectArrayElement(*jparams, 0, *self); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + DEBUG_REPORT_LOG(ConfigServerGame::getJavaConsoleDebugMessages(), ( + "JavaLibrary::callMessage %s exit, self = %s, method = %s\n", + script.c_str(), caller.getValueString().c_str(), method.c_str())); + LOG("ScriptInvestigation", ("callMessage failed because exception5")); + return SCRIPT_OVERRIDE; + } + + int result = callScriptEntry(jscript, jmethod, jparams->getValue()); + + //========================================================================== + // !!IMPORTANT after this point our env pointer may have changed, we can't + // call any JNI functions on objects created with the old pointer!! + //========================================================================== + + if (currentEnvCount == ms_envCount) + { + if (ms_env->ExceptionCheck()) + ms_env->ExceptionDescribe(); + } + else + { + DEBUG_LOG("ScriptInvestigation", ("JavaLibrary::callMessage env changed after message %s", method.c_str())); + self->emergencyClear(); + jparams->emergencyClear(); + jscript.emergencyClear(); + jmethod.emergencyClear(); + } + + return result; +} // JavaLibrary::callMessage + +//======================================================================== +// class JavaLibrary string/stringId methods +//======================================================================== + +/** + * Gets the name of a java class/script. + * + * @param sourceClass the class we want the name of + * @param target string that will be filled in with the name + * + * @reurn true on success, false on error + */ +const bool JavaLibrary::getClassName(const jclass & sourceClass, std::string & target) +{ + bool result = false; + if(ms_env) + { + const LocalRefParamPtr classPtr(new LocalRefParam(sourceClass)); + JavaStringPtr s = callStringMethod(*classPtr, JavaLibrary::ms_midClassGetName); + if (s != JavaString::cms_nullPtr) + { + if (convert(*s, target)) + { + //@todo Make sure this is the correct way to do things + //we need to strip script. from the beginning of the class string + const std::string scriptString("script."); + size_t position = target.find(scriptString); + if (position == 0) + { + target.erase(position, scriptString.length()); + } + result = true; + } + } + } + return result; +} // JavaLibrary::getClassName(const jclass &) + +/** + * Gets the name of a java class/script. + * + * @param source the object we want the class name of + * @param target string that will be filled in with the name + * + * @reurn true on success, false on error + */ +const bool JavaLibrary::getClassName(const jobject & source, std::string & target) +{ + bool result = false; + if (ms_env) + { + jclass tempClass = ms_env->GetObjectClass(source); + result = getClassName(tempClass, target); + } + return result; +} // JavaLibrary::getClassName(const jobject &) + +//----------------------------------------------------------------------- + +/** + * Packs a Java dictionary class into a string for network transmission. + * + * @param dictionary the dictionary to pack + * @param packedData the string to be filled with the packed dictionary + */ +void JavaLibrary::packDictionary(const ScriptDictionary & dictionary, + std::vector & packedData) +{ + const_cast(dictionary).serialize(); + packedData = dictionary.getSerializedData(); +} // JavaLibrary::packDictionary + +/** + * Unpacks a Java dictionary class from a string. + * + * @param packedData the string to unpack + * @param dictionary pointer to be set to the unpacked dictionary + * + * @return true on success, false on error + */ +bool JavaLibrary::unpackDictionary(const std::vector & packedData, + ScriptDictionaryPtr & dictionary) +{ + if (ms_env == NULL) + return false; + + dictionary = JavaDictionary::cms_nullPtr; + + if (!packedData.empty()) + { + // get the crc from the data +// uint32 crc = 0; + int dataLen = packedData.size(); + const int8 * data = &packedData[0]; + /* + std::vector::const_iterator result = std::find(packedData.begin(), + packedData.end(), '*'); + if (result != packedData.end()) + { + // double-check: verify all the characters before the marker are + // digits + int i; + int markerPos = packedData.end() - result; + for (i = 0; i < markerPos; ++i) + { + if (!isdigit(data[i])) + break; + crc = crc * 10 + (data[i] - '0'); + } + if (i == markerPos) + { + data = &data[markerPos+1]; + // verify the crc + dataLen -= markerPos + 1; + uint32 dataCrc = Crc::calculate(data, dataLen); + if (crc != dataCrc) + { + WARNING(true, ("JavaLibrary::unpackDictionary got packed data with " + "bad crc! Expected: %lu, got %lu.", crc, dataCrc)); + return false; + } + } + } + */ + if (data != NULL && *data != '\0') + { + LocalByteArrayRefPtr jdata = createNewByteArray(dataLen); + if (jdata != LocalByteArrayRef::cms_nullPtr) + { + setByteArrayRegion(*jdata, 0, dataLen, const_cast(data)); + JavaDictionaryPtr lref(new JavaDictionary(ms_env->CallStaticObjectMethod(ms_clsDictionary, ms_midDictionaryUnpack, jdata->getValue()))); + if (lref == JavaDictionary::cms_nullPtr) + { + WARNING(true, ("JavaLibrary::unpackDictionary error unpacking dictionary")); + return false; + } + dictionary = lref; + } + } + } + return true; +} // JavaLibrary::unpackDictionary + +//----------------------------------------------------------------------- + +/** + * Convert a JavaString to a std::string. + */ +const bool JavaLibrary::convert(const JavaStringParam & source, std::string & target) +{ + bool result = false; + if (ms_env) + { + if (source.getValue() != 0) + { + jboolean isCopy(false); + const char * temp = ms_env->GetStringUTFChars(source.getValue(), &isCopy); + if(temp) + { + target = temp; + ms_env->ReleaseStringUTFChars(source.getValue(), temp); + result = true; + } + } + } + return result; +} // JavaLibrary::convert(const JavaStringParam &, std::string &) + +/** + * Convert a JavaString to a Unicode::String. + */ +const bool JavaLibrary::convert(const JavaStringParam & source, Unicode::String & target) +{ + bool result = false; + if (ms_env) + { + if (source.getValue() != 0) + { + jboolean isCopy = JNI_FALSE; + jsize len = getStringLength(source); + const jchar * temp = ms_env->GetStringCritical(source.getValue(), &isCopy); + if (temp) + { + target.assign(temp, len); + ms_env->ReleaseStringCritical(source.getValue(), temp); + result = true; + } + } + } + return result; +} // JavaLibrary::convert(const JavaStringParam &, Unicode::String &) + +//----------------------------------------------------------------------- + +/** + * Serializes a JavaDictionary into a string. + */ +const bool JavaLibrary::convert(const JavaDictionary & source, std::vector & target) +{ + bool result = false; + if (ms_env != NULL) + { + if (source.getValue() != 0) + { + // convert the dictionary to a jstring + LocalByteArrayRefPtr packedData = callByteArrayMethod(source, ms_midDictionaryPack); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + } + else if (packedData != LocalByteArrayRef::cms_nullPtr) + { + // convert the Java array to a vector + int count = getArrayLength(*packedData); + target.reserve(count); + target.resize(count); + getByteArrayRegion(*packedData, 0, count, &target[0]); + result = true; + } + } + } + return result; +} // JavaLibrary::convert(const JavaDictionary &, std::string &) + + +//======================================================================= + +const bool JavaLibrary::convert(const std::map & source, JavaDictionaryPtr & target) +{ + std::vector > sourceData; + std::map:: const_iterator i; + for(i = source.begin(); i != source.end(); ++i) + { + sourceData.push_back(*i); + } + return convert(sourceData, target); +} + +//----------------------------------------------------------------------- + +const bool JavaLibrary::convert(const std::vector > & source, JavaDictionaryPtr & target) +{ + if (!JavaLibrary::getEnv()) + return false; + + target = createNewDictionary(); + if (target == JavaDictionary::cms_nullPtr) + return false; + + std::vector >::const_iterator i; + for(i = source.begin(); i != source.end(); ++i) + { + int value = (*i).second; + JavaString name((*i).first.c_str()); + callObjectMethod(*target, ms_midDictionaryPutInt, name.getValue(), value); + } + return true; +} + +//----------------------------------------------------------------------- + +const bool JavaLibrary::convert(const std::vector > > & source, JavaDictionaryPtr & target) +{ + if (!JavaLibrary::getEnv()) + return false; + + target = createNewDictionary(); + if (target == JavaDictionary::cms_nullPtr) + return false; + + std::vector > >::const_iterator i; + for(i = source.begin(); i != source.end(); ++i) + { + int value = (*i).second.first; + JavaString name((*i).first.c_str()); + callObjectMethod(*target, ms_midDictionaryPutInt, name.getValue(), value); + } + return true; +} + +//----------------------------------------------------------------------- + +const bool JavaLibrary::convert(const std::vector > & source, JavaDictionaryPtr & target) +{ + if (!JavaLibrary::getEnv()) + return false; + + target = createNewDictionary(); + if (target == JavaDictionary::cms_nullPtr) + return false; + + std::vector >::const_iterator i; + for(i = source.begin(); i != source.end(); ++i) +{ + JavaString name((*i).first.c_str()); + bool value = (*i).second; + callObjectMethod(*target, ms_midDictionaryPutBool, name.getValue(), value); + } + return true; +} + +//======================================================================= + +namespace ScriptConversion { + +const bool convert(const jobject & source, Vector & target, NetworkId & targetCell, const Vector & i_default) +{ + if (!convert(source, target, targetCell)) + { + target = i_default; + targetCell = NetworkId::cms_invalid; + } + return true; +} + +const bool convert(const std::vector & source, LocalObjectArrayRefPtr & target) +{ + if (!JavaLibrary::getEnv()) + return false; + + bool result = false; + int count = source.size(); + target = createNewObjectArray(count, JavaLibrary::ms_clsString); + if (target != LocalObjectArrayRef::cms_nullPtr) + { + result = true; + for (int i = 0; i < count; ++i) + { + if (source[i] != NULL) + { + JavaString targetElement(*source[i]); + setObjectArrayElement(*target, i, targetElement); + } + } + } + return result; +} + +const bool convert(const jobject source, StringId & target) +{ + if (source == 0) + return false; + + JNIEnv * env = JavaLibrary::getEnv(); + if (!env) + return false; + + if (env->IsInstanceOf(source, JavaLibrary::ms_clsStringId) == JNI_FALSE) + return false; + + // @todo: it would be nice if we had a known max length for the table + // name and text in order to use buffers to get the strings + + // get the table + { + JavaStringPtr tempString = getStringField(LocalRefParam(source), JavaLibrary::ms_fidStringIdTable); + std::string localString; + JavaLibrary::convert(*tempString, localString); + target.setTable(localString); + } + + // get the text + { + JavaStringPtr tempString = getStringField(LocalRefParam(source), JavaLibrary::ms_fidStringIdAsciiId); + if (tempString != JavaString::cms_nullPtr && getStringLength(*tempString) > 0) + { + std::string localString; + JavaLibrary::convert(*tempString, localString); + target.setText(localString); + } + else + { + // get the text index + jint textIndex = env->GetIntField(source, JavaLibrary::ms_fidStringIdIndexId); + target.setTextIndex(textIndex); + } + } + + return true; +} + +const bool convert(const LocalRefParam & source, StringId & target) +{ + return convert(source.getValue(), target); +} + +const bool convert(const StringId & source, LocalRefPtr & target) +{ + if (!JavaLibrary::getEnv()) + return false; + + target = allocObject(JavaLibrary::ms_clsStringId); + if (target == LocalRef::cms_nullPtr) + return false; + + // convert the table + { + JavaString tempString(source.getTable().c_str()); + setObjectField(*target, JavaLibrary::ms_fidStringIdTable, tempString); + } + + // convert the text + { + JavaString tempString(source.getText().c_str()); + setObjectField(*target, JavaLibrary::ms_fidStringIdAsciiId, tempString); + } + + // convert the index + setIntField(*target, JavaLibrary::ms_fidStringIdIndexId, source.getTextIndex()); + return true; +} + +const bool convert(const std::vector & source, LocalObjectArrayRefPtr & strArray) +{ + JNIEnv * env = JavaLibrary::getEnv(); + if (!env) + return false; + + if (env->ExceptionCheck()) + { + env->ExceptionDescribe(); + return false; + } + + strArray = createNewObjectArray(static_cast(source.size()), JavaLibrary::ms_clsString); + std::vector::const_iterator i; + int index = 0; + for(i = source.begin(); i != source.end(); ++i) + { + const char * s = (*i).c_str(); + JavaString js(s); + if (env->ExceptionCheck()) + { + env->ExceptionDescribe(); + return false; + } + setObjectArrayElement(*strArray, index, js); + if (env->ExceptionCheck()) + { + env->ExceptionDescribe(); + return false; + } + ++index; + } + return true; +} + +const bool convert(const std::vector & source, LocalObjectArrayRefPtr & strArray) +{ + JNIEnv * env = JavaLibrary::getEnv(); + if (!env) + return false; + + if (env->ExceptionCheck()) + { + env->ExceptionDescribe(); + return false; + } + + strArray = createNewObjectArray(static_cast(source.size()), JavaLibrary::ms_clsString); + std::vector::const_iterator i; + int index = 0; + for(i = source.begin(); i != source.end(); ++i) + { + JavaString js(*i); + if (env->ExceptionCheck()) + { + env->ExceptionDescribe(); + return false; + } + setObjectArrayElement(*strArray, index, js); + if (env->ExceptionCheck()) + { + env->ExceptionDescribe(); + return false; + } + ++index; + } + return true; +} + +const bool convert(const std::set & source, LocalObjectArrayRefPtr & strArray) +{ + JNIEnv * env = JavaLibrary::getEnv(); + if (!env) + return false; + + if (env->ExceptionCheck()) + { + env->ExceptionDescribe(); + return false; + } + + strArray = createNewObjectArray(static_cast(source.size()), JavaLibrary::ms_clsString); + std::set::const_iterator i; + int index = 0; + for(i = source.begin(); i != source.end(); ++i) + { + const std::string name = (*i).getName(); + const char * const s = name.c_str(); + + JavaString js(s); + if (env->ExceptionCheck()) + { + env->ExceptionDescribe(); + return false; + } + setObjectArrayElement(*strArray, index, js); + if (env->ExceptionCheck()) + { + env->ExceptionDescribe(); + return false; + } + ++index; + } + + return true; +} + +const bool convert(const jobjectArray & source, stdvector::fwd & target) +{ + JNIEnv * env = JavaLibrary::getEnv(); + if (!env || !source) + return false; + + int count = env->GetArrayLength(source); + target.resize(count, ""); + + std::string tempString; + for (int i = 0; i < count; ++i) + { + JavaStringPtr s = getStringArrayElement(LocalObjectArrayRefParam(source), i); + if (s != JavaString::cms_nullPtr) +{ + if (JavaLibrary::convert(*s, tempString)) + target[i] = tempString; + } + } + return true; +} + +const bool convert(const jlongArray & source, std::vector &results) +{ + bool result = false; + JNIEnv * env = JavaLibrary::getEnv(); + if (!env || !source) + return false; + + jsize count = env->GetArrayLength(source); + jsize i; + result = true; + jlong jlongTmp; + for (i=0; iGetLongArrayRegion(source, i, 1, &jlongTmp); + NetworkId nid(jlongTmp); + if (!nid) + { + result = false; + } + else + { + results.push_back(nid); + } + } + + return result; +} + +const bool convert(const jlongArray & source, std::vector &results) +{ + JNIEnv * env = JavaLibrary::getEnv(); + if (!env || !source) + return false; + + bool result = false; + + jsize count = env->GetArrayLength(source); + jsize i; + result = true; + for (i=0; iGetLongArrayRegion(source, i, 1, &id); + ServerObject * object = 0; + if (!JavaLibrary::getObject(id, object)) + { + result = false; + } + else + { + results.push_back(object); + } + } + + return result; +} + +const bool convert(const std::vector &source, LocalLongArrayRefPtr & result) +{ + JNIEnv * env = JavaLibrary::getEnv(); + if (!env) + return false; + + int count = source.size(); + bool rv = true; + int resultCount = 0; + for (int i = 0; i < count; ++i) + { + if (source[i]) + { + resultCount++; + } + } + result = createNewLongArray(resultCount); + for (int j = 0; j < count; ++j) + { + if (source[j]) + { + jlong arg = (source[j]->getNetworkId()).getValue(); + if (arg == 0) + { + rv = false; + break; + } + setLongArrayRegion(*result, static_cast(--resultCount), 1, &arg); + } + } + if (env->ExceptionCheck()) + { + env->ExceptionDescribe(); + rv = false; + } + return rv; +} + +const bool convert(const std::vector &source, LocalLongArrayRefPtr & result) +{ + JNIEnv * env = JavaLibrary::getEnv(); + if (!env) + return false; + + int count = source.size(); + bool rv = true; + int i; + int resultCount = 0; + for (i = 0; i < count; ++i) + { + if (source[i].isValid()) + { + resultCount++; + } + } + result = createNewLongArray(resultCount); + jlong jlongTmp; + for (int j = 0; j < count; ++j) + { + if (source[j].isValid()) + { + jlongTmp = source[j].getValue(); + + setLongArrayRegion(*result, static_cast(--resultCount), 1, &jlongTmp); + } + else + { + rv = false; + } + } + if (env->ExceptionCheck()) + { + env->ExceptionDescribe(); + rv = false; + } + return rv; +} + +const bool ScriptConversion::convert(const jobject & source, Vector &target, NetworkId & targetCell) +{ + JNIEnv * env = JavaLibrary::getEnv(); + if (!env) + return false; + + if (!source) + return false; + + ServerObject * object = 0; + + if (env->IsInstanceOf(source, JavaLibrary::ms_clsLocation)) + { + target.x = env->GetFloatField(source, JavaLibrary::ms_fidLocationX); + target.y = env->GetFloatField(source, JavaLibrary::ms_fidLocationY); + target.z = env->GetFloatField(source, JavaLibrary::ms_fidLocationZ); + + LocalRefPtr cell = getObjectField(LocalRefParam(source), JavaLibrary::ms_fidLocationCell); + targetCell = JavaLibrary::getNetworkId(*cell); + return true; + } + else if (JavaLibrary::getObject(source, object)) + { + target = object->getPosition_p(); + const Object * cell = ContainerInterface::getContainedByObject(*object); + targetCell = (cell) ? cell->getNetworkId() : NetworkId::cms_invalid; + return true; + } + return false; +} + +const bool ScriptConversion::convertWorld(const jobject & source, Vector &target) +{ + JNIEnv * env = JavaLibrary::getEnv(); + if (!env) + return false; + + if (!source) + return false; + + ServerObject * object = 0; + + if (env->IsInstanceOf(source, JavaLibrary::ms_clsLocation)) + { + target.x = env->GetFloatField(source, JavaLibrary::ms_fidLocationX); + target.y = env->GetFloatField(source, JavaLibrary::ms_fidLocationY); + target.z = env->GetFloatField(source, JavaLibrary::ms_fidLocationZ); + + LocalRefPtr cell = getObjectField(LocalRefParam(source), JavaLibrary::ms_fidLocationCell); + Object * cellObject = 0; + if (JavaLibrary::getObject(*cell, cellObject)) + { + target = cellObject->rotateTranslate_o2w(target); + } + return true; + } + else if (JavaLibrary::getObject(source, object)) + { + target = object->getPosition_w(); + return true; + } + return false; +} + +const bool ScriptConversion::convertWorld(const jlong & source, Vector &target) +{ + JNIEnv * env = JavaLibrary::getEnv(); + if (!env) + return false; + + if (source == 0) + return false; + + ServerObject * object = 0; + + if (JavaLibrary::getObject(source, object)) + { + target = object->getPosition_w(); + return true; + } + return false; +} + +const bool ScriptConversion::convertWorld(const LocalRefParam & source, Vector &target) +{ + return convertWorld(source.getValue(), target); +} + +const bool ScriptConversion::convert(const Vector & source, const NetworkId & sourceCell, LocalRefPtr & target) +{ + return convert(source, ServerWorld::getSceneId(), sourceCell, target); +} + +const bool ScriptConversion::convert(const jobject & source, Vector & targetLoc, std::string & targetSceneId, NetworkId & targetCell) +{ + JNIEnv * env = JavaLibrary::getEnv(); + if (!env) + return false; + + if (!source) + return false; + + Object * object = 0; + + if (env->IsInstanceOf(source, JavaLibrary::ms_clsLocation)) + { + // get the xyz coords + targetLoc.x = env->GetFloatField(source, JavaLibrary::ms_fidLocationX); + targetLoc.y = env->GetFloatField(source, JavaLibrary::ms_fidLocationY); + targetLoc.z = env->GetFloatField(source, JavaLibrary::ms_fidLocationZ); + + // get the scene + //@todo EAS what's the right answer here? + JavaStringPtr sceneId = getStringField(LocalRefParam(source), JavaLibrary::ms_fidLocationArea); + if (sceneId == JavaString::cms_nullPtr) + { + targetSceneId = ""; + return false; + } + JavaLibrary::convert(*sceneId, targetSceneId); + + // get the cell + LocalRefPtr cell = getObjectField(LocalRefParam(source), JavaLibrary::ms_fidLocationCell); + targetCell = JavaLibrary::getNetworkId(*cell); + return true; + } + else if (JavaLibrary::getObject(source, object)) + { + targetLoc = object->getPosition_p(); + targetSceneId = ServerWorld::getSceneId(); + const Object * cell = ContainerInterface::getContainedByObject(*object); + targetCell = (cell) ? cell->getNetworkId() : NetworkId::cms_invalid; + return true; + } + return false; +} + +const bool ScriptConversion::convertWorld(const jobject & source, Vector & targetLoc, std::string & targetSceneId) +{ + JNIEnv * env = JavaLibrary::getEnv(); + if (!env) + return false; + + if (!source) + return false; + + Object * object = 0; + + if (env->IsInstanceOf(source, JavaLibrary::ms_clsLocation)) + { + // get the xyz coords + targetLoc.x = env->GetFloatField(source, JavaLibrary::ms_fidLocationX); + targetLoc.y = env->GetFloatField(source, JavaLibrary::ms_fidLocationY); + targetLoc.z = env->GetFloatField(source, JavaLibrary::ms_fidLocationZ); + + // get the scene + //@todo EAS what's the right answer here? + JavaStringPtr sceneId = getStringField(LocalRefParam(source), JavaLibrary::ms_fidLocationArea); + if (sceneId == JavaString::cms_nullPtr) + { + targetSceneId = ""; + return false; + } + JavaLibrary::convert(*sceneId, targetSceneId); + + // get the cell + LocalRefPtr cell = getObjectField(LocalRefParam(source), JavaLibrary::ms_fidLocationCell); + Object * cellObject = 0; + if (JavaLibrary::getObject(*cell, cellObject)) + { + targetLoc = cellObject->rotateTranslate_o2w(targetLoc); + } + return true; + } + else if (JavaLibrary::getObject(source, object)) + { + targetLoc = object->getPosition_w(); + targetSceneId = ServerWorld::getSceneId(); + return true; + } + return false; +} + +const bool ScriptConversion::convert(const Location & sourceLoc, LocalRefPtr & target) +{ + JNIEnv * env = JavaLibrary::getEnv(); + if (!env) + return false; + + target = allocObject(JavaLibrary::ms_clsLocation); + if (target == LocalRef::cms_nullPtr) + return false; + + // set xyz + setFloatField(*target, JavaLibrary::ms_fidLocationX, sourceLoc.getCoordinates().x); + setFloatField(*target, JavaLibrary::ms_fidLocationY, sourceLoc.getCoordinates().y); + setFloatField(*target, JavaLibrary::ms_fidLocationZ, sourceLoc.getCoordinates().z); + // set scene id + JavaString area(sourceLoc.getSceneId()); //ServerWorld::getSceneId().c_str()); + setObjectField(*target, JavaLibrary::ms_fidLocationArea, area); + // set cell + LocalRefPtr cell = JavaLibrary::getObjId(sourceLoc.getCell()); + setObjectField(*target, JavaLibrary::ms_fidLocationCell, *cell); + return true; +} + +const bool ScriptConversion::convert(const LocalRefParam & sourceLoc, Location & target) +{ + JNIEnv * env = JavaLibrary::getEnv(); + if (!env) + return false; + + if (sourceLoc.getValue() == 0) + return false; + + float x = getFloatField(sourceLoc, JavaLibrary::ms_fidLocationX); + float y = getFloatField(sourceLoc, JavaLibrary::ms_fidLocationY); + float z = getFloatField(sourceLoc, JavaLibrary::ms_fidLocationZ); + + std::string planetName; + JavaStringPtr jplanetName = getStringField(sourceLoc, JavaLibrary::ms_fidLocationArea); + if (!JavaLibrary::convert(*jplanetName, planetName)) + return false; + + LocalRefPtr cell = getObjectField(sourceLoc, JavaLibrary::ms_fidLocationCell); + NetworkId targetCell = JavaLibrary::getNetworkId(*cell); + + target.setCoordinates(Vector(x, y, z)); + target.setSceneId(planetName.c_str()); + target.setCell(targetCell); + return true; +} + +const bool ScriptConversion::convert(const LocalObjectArrayRefParam & sourceLoc, std::vector & target) +{ + JNIEnv * env = JavaLibrary::getEnv(); + if (!env) + return false; + + if (sourceLoc.getValue() == 0) + return false; + + jsize count = getArrayLength(sourceLoc); + target.resize(count); + for (int i = 0; i < count; ++i) + { + LocalRefPtr location(getObjectArrayElement(sourceLoc, i)); + if (location == LocalRef::cms_nullPtr || !convert(*location, target.at(i))) + return false; + } + return true; +} + +const bool ScriptConversion::convert(const Vector & sourceLoc, const std::string & sourceSceneId, const NetworkId & sourceCell, LocalRefPtr & target) +{ + JNIEnv * env = JavaLibrary::getEnv(); + if (!env) + return false; + + target = allocObject(JavaLibrary::ms_clsLocation); + if (target == LocalRef::cms_nullPtr) + return false; + + // set xyz + setFloatField(*target, JavaLibrary::ms_fidLocationX, sourceLoc.x); + setFloatField(*target, JavaLibrary::ms_fidLocationY, sourceLoc.y); + setFloatField(*target, JavaLibrary::ms_fidLocationZ, sourceLoc.z); + // set scene id + JavaString area(sourceSceneId.c_str()); //ServerWorld::getSceneId().c_str()); + setObjectField(*target, JavaLibrary::ms_fidLocationArea, area); + // set cell + LocalRefPtr cell = JavaLibrary::getObjId(sourceCell); + setObjectField(*target, JavaLibrary::ms_fidLocationCell, *cell); + return true; +} + +const bool ScriptConversion::convertWorld(const jobjectArray & source, std::vector &target) +{ + JNIEnv * env = JavaLibrary::getEnv(); + if (!env) + return false; + + if (!source || !env->IsInstanceOf(source, JavaLibrary::ms_clsLocationArray)) return false; + + jsize count = env->GetArrayLength(source); + jsize i; + Vector v; + NetworkId cell; + bool result = true; + for (i=0; i & source, LocalObjectArrayRefPtr & target) +{ + JNIEnv * env = JavaLibrary::getEnv(); + if (!env) + return false; + + if (source.empty()) + return false; + + int count = source.size(); + int i; + + target = createNewObjectArray(source.size(), JavaLibrary::ms_clsLocation); + if (target == LocalObjectArrayRef::cms_nullPtr) + return false; + + NetworkId cell(NetworkId::cms_invalid); + bool result = true; + for (i=0; i < count; ++i) + { + LocalRefPtr element; + if (convert(*source[i], cell, element)) + { + setObjectArrayElement(*target, i, *element); + } + else + { + result = false; + } + } + + return result; +} + +const bool ScriptConversion::convert(const LocalRefParam & source, const Region * & target) +{ + return convert(source.getValue(), target); +} + +/** This method converts a java script.region class into a C++ Region class + */ +const bool ScriptConversion::convert(const jobject & source, const Region * &target) +{ + JNIEnv * env = JavaLibrary::getEnv(); + if (env == NULL || source == NULL) + return false; + if (!env->IsInstanceOf(source, JavaLibrary::ms_clsRegion)) + return false; + + std::string planetName; + JavaStringPtr jplanetName = getStringField(LocalRefParam(source), JavaLibrary::ms_fidRegionPlanet); + if (!JavaLibrary::convert(*jplanetName, planetName)) + return false; + + Unicode::String regionName; + JavaStringPtr jregionName = getStringField(LocalRefParam(source), JavaLibrary::ms_fidRegionName); + if (!JavaLibrary::convert(*jregionName, regionName)) + return false; + + target = RegionMaster::getRegionByName(planetName, regionName); + return target != 0; +} + +/** This method converts a C++ RegionObject class into a Java script.region class + */ +const bool ScriptConversion::convert(const Region & source, LocalRefPtr & target) +{ + JNIEnv * env = JavaLibrary::getEnv(); + if (!env) + return false; + + int pvp = source.getPvp(); + int mun = source.getMunicipal(); + int build = source.getBuildable(); + int geo = source.getGeography(); + int minDiff = source.getMinDifficulty(); + int maxDiff = source.getMaxDifficulty(); + int spawn = source.getSpawn(); + int mission = source.getMission(); + + const Unicode::String name(source.getName()); + JavaString jname(name); + + const std::string planetName(source.getPlanet()); + JavaString jplanetName(planetName); + + target = createNewObject(JavaLibrary::ms_clsRegion, JavaLibrary::ms_midRegion, + jname.getValue(), pvp, build, mun, geo, minDiff, maxDiff, spawn, mission, jplanetName.getValue()); + return (target != LocalRef::cms_nullPtr); +} + +// ---------------------------------------------------------------------- + +const bool ScriptConversion::convert(Transform const &sourceTransform, LocalRefPtr &target) +{ + JNIEnv * const env = JavaLibrary::getEnv(); + if (!env) + return false; + + Vector const i(sourceTransform.getLocalFrameI_p()); + Vector const j(sourceTransform.getLocalFrameJ_p()); + Vector const k(sourceTransform.getLocalFrameK_p()); + Vector const p(sourceTransform.getPosition_p()); + target = createNewObject(JavaLibrary::ms_clsTransform, JavaLibrary::ms_midTransform, + i.x, j.x, k.x, p.x, + i.y, j.y, k.y, p.y, + i.z, j.z, k.z, p.z); + return (target != LocalRef::cms_nullPtr); +} + +// ---------------------------------------------------------------------- + +const bool ScriptConversion::convert(const jobject &sourceTransform, Transform &target) +{ + JNIEnv * const env = JavaLibrary::getEnv(); + if (!env || !sourceTransform) + return false; + if (!env->IsInstanceOf(sourceTransform, JavaLibrary::ms_clsTransform)) + return false; + + LocalObjectArrayRefPtr matrix = getArrayObjectField(LocalRefParam(sourceTransform), JavaLibrary::ms_fidTransformMatrix); + LocalFloatArrayRefPtr row0 = getFloatArrayArrayElement(*matrix, 0); + LocalFloatArrayRefPtr row1 = getFloatArrayArrayElement(*matrix, 1); + LocalFloatArrayRefPtr row2 = getFloatArrayArrayElement(*matrix, 2); + + float * const row0Elements = env->GetFloatArrayElements(row0->getValue(), 0); + float * const row1Elements = env->GetFloatArrayElements(row1->getValue(), 0); + float * const row2Elements = env->GetFloatArrayElements(row2->getValue(), 0); + + target.setLocalFrameIJK_p( + Vector(row0Elements[0], row1Elements[0], row2Elements[0]), + Vector(row0Elements[1], row1Elements[1], row2Elements[1]), + Vector(row0Elements[2], row1Elements[2], row2Elements[2])); + target.setPosition_p(row0Elements[3], row1Elements[3], row2Elements[3]); + + env->ReleaseFloatArrayElements(row2->getValue(), row2Elements, JNI_ABORT); + env->ReleaseFloatArrayElements(row1->getValue(), row1Elements, JNI_ABORT); + env->ReleaseFloatArrayElements(row0->getValue(), row0Elements, JNI_ABORT); + + return true; +} + +// ---------------------------------------------------------------------- + +const bool ScriptConversion::convert(const LocalRefParam &sourceTransform, Transform &target) +{ + return convert(sourceTransform.getValue(), target); +} + +// ---------------------------------------------------------------------- + +const bool ScriptConversion::convert(const jobjectArray & source, std::vector &target) +{ + JNIEnv * const env = JavaLibrary::getEnv(); + if (!env) + return false; + + if (!source || !env->IsInstanceOf(source, JavaLibrary::ms_clsTransformArray)) return false; + + jsize const count = env->GetArrayLength(source); + bool result = true; + for (jsize i = 0; i < count; ++i) + { + LocalRefPtr element = getObjectArrayElement(LocalObjectArrayRefParam(source), i); + + Transform t; + if (convert(*element, t)) + { + target.push_back(t); + } + else + { + result = false; + } + } + + return result && !target.empty(); + } + +// ---------------------------------------------------------------------- + +const bool ScriptConversion::convert(const std::vector &source, LocalObjectArrayRefPtr & target) +{ + JNIEnv * const env = JavaLibrary::getEnv(); + if (!env) + return false; + + int const count = source.size(); + + bool result = true; + + target = createNewObjectArray(count, JavaLibrary::ms_clsObjId); + + for (int i = 0; i < count; ++i) + { + LocalRefPtr temp; + if (convert(source[i],temp)) + { + setObjectArrayElement(*target, i, *temp); + } + else + { + result = false; + target = LocalObjectArrayRef::cms_nullPtr; + break; + } + } + + if (env->ExceptionCheck()) + { + env->ExceptionDescribe(); + result = false; + } + + return result; +} + + + +// ---------------------------------------------------------------------- + +const bool ScriptConversion::convert(const Vector &sourceVector, LocalRefPtr &target) +{ + JNIEnv *env = JavaLibrary::getEnv(); + if (!env) + return false; + + target = allocObject(JavaLibrary::ms_clsVector); + if (target == LocalRef::cms_nullPtr) + return false; + + setFloatField(*target, JavaLibrary::ms_fidVectorX, sourceVector.x); + setFloatField(*target, JavaLibrary::ms_fidVectorY, sourceVector.y); + setFloatField(*target, JavaLibrary::ms_fidVectorZ, sourceVector.z); + return true; +} + +// ---------------------------------------------------------------------- + +const bool ScriptConversion::convert(const jobject & sourceVector, Vector & target) +{ + JNIEnv *env = JavaLibrary::getEnv(); + if (!env || !sourceVector) + return false; + if (!env->IsInstanceOf(sourceVector, JavaLibrary::ms_clsVector)) + return false; + + target.x = env->GetFloatField(sourceVector, JavaLibrary::ms_fidVectorX); + target.y = env->GetFloatField(sourceVector, JavaLibrary::ms_fidVectorY); + target.z = env->GetFloatField(sourceVector, JavaLibrary::ms_fidVectorZ); + return true; +} + +// ---------------------------------------------------------------------- + +const bool ScriptConversion::convert(const LocalRefParam & sourceVector, Vector & target) +{ + return convert(sourceVector.getValue(), target); +} + +// ---------------------------------------------------------------------- + +/** + * Convert a C++ AttribMod to a Java attrib_mod. + */ +const bool convert(const AttribMod::AttribMod & source, LocalRefPtr & target) +{ + JNIEnv * env = JavaLibrary::getEnv(); + if (env == NULL) + return false; + + target = allocObject(JavaLibrary::ms_clsAttribMod); + if (target == LocalRef::cms_nullPtr) + return false; + + JavaString name(AttribModNameManager::getInstance( + ).getAttribModName(source.tag)); + setObjectField(*target, JavaLibrary::ms_fidAttribModName, name); + if (!AttribMod::isSkillMod(source)) + { + setIntField(*target, JavaLibrary::ms_fidAttribModType, source.attrib); + } + else + { + JavaString skill(AttribModNameManager::getInstance( + ).getAttribModName(source.skill)); + setObjectField(*target, JavaLibrary::ms_fidAttribModSkill, skill); + } + setIntField(*target, JavaLibrary::ms_fidAttribModValue, source.value); + setFloatField(*target, JavaLibrary::ms_fidAttribModTime, source.sustain); + setFloatField(*target, JavaLibrary::ms_fidAttribModAttack, source.attack); + setFloatField(*target, JavaLibrary::ms_fidAttribModDecay, source.decay); + setIntField(*target, JavaLibrary::ms_fidAttribModFlags, source.flags); + return true; +} + +/** + * Convert a Java attrib_mod to a C++ AttribMod. + */ +const bool convert(const jobject & source, AttribMod::AttribMod & target) +{ + JNIEnv * env = JavaLibrary::getEnv(); + if (env == NULL) + return false; + + if (source == 0 || env->IsInstanceOf(source, JavaLibrary::ms_clsAttribMod) == JNI_FALSE) + return false; + + std::string modName; + JavaStringPtr name = getStringField(LocalRefParam(source), JavaLibrary::ms_fidAttribModName); + if (name != JavaString::cms_nullPtr) + { + if (!JavaLibrary::convert(*name, modName)) + return false; + + target.tag = Crc::calculate(modName.c_str()); + AttribModNameManager::getInstance().addAttribModName(modName.c_str()); + } + else + target.tag = 0; + + target.flags = env->GetIntField(source, JavaLibrary::ms_fidAttribModFlags); + if (!AttribMod::isSkillMod(target)) + { + target.attrib = env->GetIntField(source, JavaLibrary::ms_fidAttribModType); + } + else + { + std::string skillModName; + JavaStringPtr skillName = getStringField(LocalRefParam(source), JavaLibrary::ms_fidAttribModSkill); + + // a skillmod mod must have a skillmod name + if (skillName == JavaString::cms_nullPtr) + return false; + if (!JavaLibrary::convert(*skillName, skillModName)) + return false; + + target.skill = Crc::calculate(skillModName.c_str()); + AttribModNameManager::getInstance().addAttribModName(skillModName.c_str()); + } + target.value = env->GetIntField(source, JavaLibrary::ms_fidAttribModValue); + target.sustain = env->GetFloatField(source, JavaLibrary::ms_fidAttribModTime); + target.attack = env->GetFloatField(source, JavaLibrary::ms_fidAttribModAttack); + target.decay = env->GetFloatField(source, JavaLibrary::ms_fidAttribModDecay); + return true; +} + +/** + * Convert a Java attrib_mod to a C++ AttribMod. + */ +const bool convert(const LocalRefParam & source, AttribMod::AttribMod & target) +{ + return convert(source.getValue(), target); +} + +/** + * Convert a C++ AttribMod vector to a Java attrib_mod[]. + */ +const bool convert(const std::vector & source, LocalObjectArrayRefPtr & target) +{ + JNIEnv * env = JavaLibrary::getEnv(); + if (env == NULL) + return false; + + int count = source.size(); + target = createNewObjectArray(count, JavaLibrary::ms_clsAttribMod); + if (target == LocalObjectArrayRef::cms_nullPtr) + return false; + + LocalRefPtr mod; + for (int i = 0; i < count; ++i) + { + if (!convert(source[i], mod)) + { + target = LocalObjectArrayRef::cms_nullPtr; + return false; + } + setObjectArrayElement(*target, i, *mod); + } + return true; +} + +/** + * Convert a Java attrib_mod[] to a C++ AttribMod vector. + */ +const bool convert(const jobjectArray & source, std::vector & target) +{ + JNIEnv * env = JavaLibrary::getEnv(); + if (env == NULL) + return false; + + if (source == 0) + return false; + + AttribMod::AttribMod mod; + int count = env->GetArrayLength(source); + for (int i = 0; i < count; ++i) + { + LocalRefPtr element = getObjectArrayElement(LocalObjectArrayRefParam(source), i); + bool result = convert(*element, mod); + if (!result) + { + target.clear(); + return false; + } + target.push_back(mod); + } + return true; +} + +const bool convert(const jbyteArray & source, std::vector & target) +{ + JNIEnv * env = JavaLibrary::getEnv(); + if (env == NULL) + return false; + + if (source == 0) + return false; + + int size = env->GetArrayLength(source); + target.reserve(size); + target.resize(size); + env->GetByteArrayRegion(source, 0, size, &target[0]); + return true; +} + +const bool convert(const LocalByteArrayRef & source, std::vector & target) +{ + JNIEnv * env = JavaLibrary::getEnv(); + if (env == NULL) + return false; + + if (source.getValue() == 0) + return false; + + int size = getArrayLength(source); + target.reserve(size); + target.resize(size); + getByteArrayRegion(source, 0, size, &target[0]); + return true; +} + +const bool convert(const std::vector & source, LocalByteArrayRefPtr & target) +{ + JNIEnv * env = JavaLibrary::getEnv(); + if (env == NULL) + return false; + + int count = source.size(); + target = createNewByteArray(count); + if (target == LocalByteArrayRef::cms_nullPtr) + return false; + + if (count > 0) + setByteArrayRegion(*target, 0, count, const_cast(&source[0])); + return true; +} + +}//namespace ScriptConversion + +//---------------------------------------------------------------------- + +ServerObject * JavaLibrary::findObjectByNetworkId (const NetworkId & id) +{ + return ServerWorld::findObjectByNetworkId(id); +} + +//---------------------------------------------------------------------- + +CreatureObject *JavaLibrary::getCreatureThrow(JNIEnv *env, jlong objId, char const *errorDescription, bool throwIfNotOnServer) +{ + NOT_NULL(env); + + char buffer[512]; + + if (!objId) + { + IGNORE_RETURN(snprintf(buffer, sizeof(buffer) - 1, "%s: null object id from script.", errorDescription)); + buffer[sizeof(buffer) - 1] = '\0'; + throwInternalScriptError(buffer); + return NULL; + } + else + { + NetworkId networkId(objId); + if (!networkId.isValid()) + { + IGNORE_RETURN(snprintf(buffer, sizeof(buffer) - 1, "%s: invalid or non-convertable network id [%s].", errorDescription, networkId.getValueString().c_str())); + buffer[sizeof(buffer) - 1] = '\0'; + throwInternalScriptError(buffer); + return NULL; + } + else + { + Object *const object = NetworkIdManager::getObjectById(networkId); + if (!object) + { + if (!throwIfNotOnServer) + { + // The specified object is not on this server. It might not even be a real object. + // Since the caller does not want this to throw, simply return NULL. + return NULL; + } + + IGNORE_RETURN(snprintf(buffer, sizeof(buffer) - 1, "%s: object for network id [%s] not on this server.", errorDescription, networkId.getValueString().c_str())); + buffer[sizeof(buffer) - 1] = '\0'; + throwInternalScriptError(buffer); + return NULL; + } + else + { + ServerObject *const serverObject = object->asServerObject(); + CreatureObject *const creatureObject = serverObject ? serverObject->asCreatureObject() : NULL; + + if (creatureObject) + return creatureObject; + else + { + IGNORE_RETURN(snprintf(buffer, sizeof(buffer) - 1, "%s: object id=[%s], template=[%s] is not a CreatureObject.", errorDescription, networkId.getValueString().c_str(), object->getObjectTemplateName())); + buffer[sizeof(buffer) - 1] = '\0'; + throwInternalScriptError(buffer); + return NULL; + } + } + } + } +} + +//---------------------------------------------------------------------- + +ShipObject *JavaLibrary::getShipThrow(JNIEnv *env, jlong objId, char const *errorDescription, bool throwIfNotOnServer) +{ + NOT_NULL(env); + + char buffer[512]; + + if (objId == 0) + { + IGNORE_RETURN(snprintf(buffer, sizeof(buffer) - 1, "%s: null object id from script.", errorDescription)); + buffer[sizeof(buffer) - 1] = '\0'; + throwInternalScriptError(buffer); + return NULL; + } + else + { + NetworkId networkId(objId); + if (!networkId.isValid()) + { + IGNORE_RETURN(snprintf(buffer, sizeof(buffer) - 1, "%s: invalid or non-convertable network id [%s].", errorDescription, networkId.getValueString().c_str())); + buffer[sizeof(buffer) - 1] = '\0'; + throwInternalScriptError(buffer); + return NULL; + } + else + { + Object *const object = NetworkIdManager::getObjectById(networkId); + if (!object) + { + if (!throwIfNotOnServer) + { + // The specified object is not on this server. It might not even be a real object. + // Since the caller does not want this to throw, simply return NULL. + return NULL; + } + + IGNORE_RETURN(snprintf(buffer, sizeof(buffer) - 1, "%s: object for network id [%s] not on this server.", errorDescription, networkId.getValueString().c_str())); + buffer[sizeof(buffer) - 1] = '\0'; + throwInternalScriptError(buffer); + return NULL; + } + else + { + ServerObject *const serverObject = object->asServerObject(); + ShipObject *const shipObject = serverObject ? serverObject->asShipObject() : NULL; + + if (shipObject) + return shipObject; + else + { + IGNORE_RETURN(snprintf(buffer, sizeof(buffer) - 1, "%s: object id=[%s], template=[%s] is not a ShipObject.", errorDescription, networkId.getValueString().c_str(), object->getObjectTemplateName())); + buffer[sizeof(buffer) - 1] = '\0'; + throwInternalScriptError(buffer); + return NULL; + } + } + } + } +} + +//----------------------------------------------------------------------- + +/** + * Causes an internal_script_error to be thrown in the Java engine. + * + * @param message the message to be returned by internal_script_error.getMessage() + */ +void JavaLibrary::throwInternalScriptError(const char * message) +{ + if (ms_env != NULL && message != NULL) + { + ms_env->ThrowNew(ms_clsInternalScriptError, message); + } +} + +//----------------------------------------------------------------------- diff --git a/engine/server/library/serverScript/src/shared/JavaLibrary.h b/engine/server/library/serverScript/src/shared/JavaLibrary.h new file mode 100644 index 00000000..6a4a5471 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/JavaLibrary.h @@ -0,0 +1,1974 @@ +//======================================================================== +// +// JavaLibrary.h - interface to the JVM via JNI. +// +// copyright 2001 Sony Online Entertainment +// +//======================================================================== + +#ifndef _INCLUDED_JavaLibrary_H +#define _INCLUDED_JavaLibrary_H + +#ifdef WIN32 +#pragma warning (disable: 4100) +#pragma warning (disable: 4786) +#endif + +#include +#include "serverScript/JNIWrappers.h" +#include "serverScript/ScriptDictionary.h" +#include "sharedUtility/Location.h" + +class Container; +class CreatureObject; +class CustomizationData; +class CustomizationVariable; +class DraftSchematicObject; +class DynamicVariableList; +class DynamicVariableListNestedList; +class GameScriptObject; +class ManufactureObjectInterface; +class NetworkId; +class PaletteColorCustomizationVariable; +class RangedIntCustomizationVariable; +class Region; +class ScriptListEntry; +class ScriptParams; +class Semaphore; +class ServerObject; +class ShipObject; +class TangibleObject; +class Thread; +class Transform; +class ValueDictionary; +class Vector; +class WeaponObject; +struct ObjectMenuRequestData; + +namespace AttribMod +{ + struct AttribMod; +}; + +namespace CellPermissions +{ + class PermissionObject; +}; + +namespace Crafting +{ + struct IngredientSlot; +}; + +namespace Archive +{ +// struct DefaultObjectType; + template class AutoDeltaVector; +} + +typedef std::vector ScriptList; +typedef Unicode::String String_t; +typedef stdvector ::fwd StringVector_t; +typedef stdvector::fwd MenuDataVector; + + +//======================================================================== +// C<->Java conversion functions +//======================================================================== + + +namespace ScriptConversion +{ + const bool convert(const Location & sourceLoc, LocalRefPtr & target); + const bool convert(const LocalRefParam & sourceLoc, Location & target); + const bool convert(const LocalObjectArrayRefParam & sourceLoc, stdvector::fwd & target); + const bool convert(const stdvector::fwd & source, LocalObjectArrayRefPtr & target); + const bool convert(const jobject source, StringId & target); + const bool convert(const LocalRefParam & source, StringId & target); + const bool convert(const StringId & source, LocalRefPtr & target); + const bool getClassName(const jobject & source, std::string & target); + const bool convert(const stdvector::fwd & source, LocalObjectArrayRefPtr & strArray); + const bool convert(const stdvector::fwd & source, LocalObjectArrayRefPtr & strArray); + const bool convert(const jobjectArray & source, stdvector::fwd & strArray); + const bool convert(const stdset::fwd & source, LocalObjectArrayRefPtr & strArray); + const bool convert(const stdvector::fwd & source, LocalLongArrayRefPtr & target); + const bool convert(const stdvector::fwd & source, LocalLongArrayRefPtr & target); + const bool convert(const jlongArray & source, stdvector::fwd & target); + const bool convert(const jlongArray & source, stdvector::fwd & target); + const bool convert(const jobject & source, Vector & target, NetworkId & targetCell); + const bool convertWorld(const jobject & source, Vector & target); + const bool convertWorld(const jlong & source, Vector & target); + const bool convertWorld(const LocalRefParam & source, Vector & target); + const bool convert(const Vector & source, const NetworkId & sourceCell, LocalRefPtr & target); + const bool convert(const jobject & source, Vector & targetLoc, std::string & targetSceneId, NetworkId & targetCell); + const bool convertWorld(const jobject & source, Vector & targetLoc, std::string & targetSceneId); + const bool convert(const Vector & sourceLoc, const std::string & sourceSceneId, const NetworkId & sourceCell, LocalRefPtr & target); + const bool convertWorld(const jobjectArray & source, stdvector::fwd & target); + const bool convert(const stdvector::fwd & source, LocalObjectArrayRefPtr & target); + const bool convert(const LocalRefParam & source, const Region * & target); + const bool convert(const jobject & source, const Region * & target); + const bool convert(const Region & source, LocalRefPtr & target); + const bool convert(const AttribMod::AttribMod & source, LocalRefPtr & target); + const bool convert(const jobject & source, AttribMod::AttribMod & target); + const bool convert(const LocalRefParam & source, AttribMod::AttribMod & target); + const bool convert(const stdvector::fwd & source, LocalObjectArrayRefPtr & target); + const bool convert(const jobjectArray & source, stdvector::fwd & target); + const bool convert(const jobject & source, Vector & target, NetworkId & targetCell, const Vector & i_default); + const bool convert(const jbyteArray & source, std::vector & target); + const bool convert(const LocalByteArrayRef & source, std::vector & target); + const bool convert(const std::vector & source, LocalByteArrayRefPtr & target); + const bool convert(const Transform & sourceTransform, LocalRefPtr & target); + const bool convert(const jobject & sourceTransform, Transform & target); + const bool convert(const LocalRefParam & sourceTransform, Transform & target); + const bool convert(const std::vector & source, LocalObjectArrayRefPtr & target); + const bool convert(const jobjectArray & source, std::vector & target); + const bool convert(const Vector & sourceVector, LocalRefPtr & target); + const bool convert(const jobject & sourceVector, Vector & target); + const bool convert(const LocalRefParam & sourceVector, Vector & target); +} + + +//======================================================================== +// class JavaLibrary +//======================================================================== + +class JavaLibrary +{ +// friend jobject convertDynamicVariableListToObject(JNIEnv *env, const DynamicVariableList& list); + friend const bool ScriptConversion::convert(const Location & sourceLoc, LocalRefPtr & target); + friend const bool ScriptConversion::convert(const LocalRefParam & sourceLoc, Location & target); + friend const bool ScriptConversion::convert(const LocalObjectArrayRefParam & sourceLoc, stdvector::fwd & target); + friend const bool ScriptConversion::convert(const stdvector::fwd & source, LocalObjectArrayRefPtr & target); + friend const bool ScriptConversion::convert(const jobject source, StringId & target); + friend const bool ScriptConversion::convert(const LocalRefParam & source, StringId & target); + friend const bool ScriptConversion::convert(const StringId & source, LocalRefPtr & target); + friend const bool ScriptConversion::convert(const stdvector::fwd & source, LocalLongArrayRefPtr & target); + friend const bool ScriptConversion::convert(const stdvector::fwd & source, LocalLongArrayRefPtr & target); + friend const bool ScriptConversion::convert(const stdvector::fwd & source, LocalObjectArrayRefPtr & strArray); + friend const bool ScriptConversion::convert(const jlongArray & source, stdvector::fwd & target); + friend const bool ScriptConversion::convert(const jlongArray & source, stdvector::fwd & target); + friend const bool ScriptConversion::convert(const jobject & source, Vector & target, NetworkId & targetCell); + friend const bool ScriptConversion::convertWorld(const jobject & source, Vector & target); + friend const bool ScriptConversion::convertWorld(const jlong & source, Vector & target); + friend const bool ScriptConversion::convertWorld(const LocalRefParam & source, Vector & target); + friend const bool ScriptConversion::convert(const Vector & source, const NetworkId & sourceCell, LocalRefPtr & target); + friend const bool ScriptConversion::convert(const jobject & source, Vector & targetLoc, std::string & targetSceneId, NetworkId & targetCell); + friend const bool ScriptConversion::convertWorld(const jobject & source, Vector & targetLoc, std::string & targetSceneId); + friend const bool ScriptConversion::convert(const Vector & sourceLoc, const std::string & sourceSceneId, const NetworkId & sourceCell, LocalRefPtr & target); + friend const bool ScriptConversion::convertWorld(const jobjectArray & source, stdvector::fwd & target); + friend const bool ScriptConversion::convert(const stdvector::fwd & source, LocalObjectArrayRefPtr & target); + friend const bool ScriptConversion::convert(const jobject & source, const Region* &target); + friend const bool ScriptConversion::convert(const Region & source, LocalRefPtr & target); + friend const bool ScriptConversion::convert(const stdvector::fwd & source, LocalObjectArrayRefPtr & strArray); + friend const bool ScriptConversion::convert(const jobjectArray & source, stdvector::fwd & strArray); + friend const bool ScriptConversion::convert(const stdset::fwd & source, LocalObjectArrayRefPtr & strArray); + friend const bool ScriptConversion::convert(const AttribMod::AttribMod & source, LocalRefPtr & target); + friend const bool ScriptConversion::convert(const jobject & source, AttribMod::AttribMod & target); + friend const bool ScriptConversion::convert(const LocalRefParam & source, AttribMod::AttribMod & target); + friend const bool ScriptConversion::convert(const stdvector::fwd & source, LocalObjectArrayRefPtr & target); + friend const bool ScriptConversion::convert(const jobjectArray & source, stdvector::fwd & target); + friend const bool ScriptConversion::convert(const jbyteArray & source, std::vector & target); + friend const bool ScriptConversion::convert(const LocalByteArrayRef & source, std::vector & target); + friend const bool ScriptConversion::convert(const std::vector & source, LocalByteArrayRefPtr & target); + friend const bool ScriptConversion::convert(const Transform & sourceTransform, LocalRefPtr & target); + friend const bool ScriptConversion::convert(const jobject & sourceTransform, Transform & target); + friend const bool ScriptConversion::convert(const LocalRefParam & sourceTransform, Transform & target); + friend const bool ScriptConversion::convert(const std::vector & source, LocalObjectArrayRefPtr & target); + friend const bool ScriptConversion::convert(const jobjectArray & source, std::vector & target); + friend const bool ScriptConversion::convert(const Vector & sourceVector, LocalRefPtr & target); + friend const bool ScriptConversion::convert(const jobject & sourceVector, Vector & target); + friend const bool ScriptConversion::convert(const LocalRefParam & sourceVector, Vector & target); + + friend JavaDictionaryPtr JNIWrappersNamespace::createNewDictionary(); + friend JavaStringPtr JNIWrappersNamespace::callStringMethod(const LocalRefParam & object, jmethodID methodID, ...); + +public: + enum JavaVMs + { + JV_none, + JV_ibm, + JV_sun + }; + +public: + + static void throwScriptException(char const * format, ...); + + static void throwScriptException(char const * format, va_list va); + +public: + // singleton methods + static void install(void); + static void remove(void); + static JavaLibrary* instance(void); + + static bool registerNatives(const JNINativeMethod natives[], int count); + +public: + static void onWatching(ServerObject & observer, ServerObject & subject); + static void onStopWatching(ServerObject & observer, ServerObject & subject); + + // obj_id functions +// static void removeJavaId(void * id); + static void removeJavaId(const NetworkId & id); + static void flagDestroyed(const NetworkId & id); + void setObjIdAuthoritative(const NetworkId & id, bool authoritative, uint32 pid); + void setObjIdLoaded(const NetworkId & id); + void setObjIdInitialized(const NetworkId & id); + void setObjIdLoggedIn(const NetworkId & id, bool loggedIn); + void attachScriptToObjId(const NetworkId &object, const std::string & script); + void attachScriptsToObjId(const NetworkId &object, const ScriptList & scripts); + void detachScriptFromObjId(const NetworkId &object, const std::string & script); + void detachAllScriptsFromObjId(const NetworkId &object); + static void setScriptVar(const ServerObject &object, const std::string & name, int value); + static void setScriptVar(const ServerObject &object, const std::string & name, float value); + static void setScriptVar(const ServerObject &object, const std::string & name, const std::string & value); + static void clearScriptVars(const ServerObject & source); + static void unpackScriptVars(const ServerObject & target, const stdvector::fwd & data); + static void unpackDeltaScriptVars(const ServerObject & target, const stdvector::fwd & data); + static void packScriptVars(const ServerObject & source, stdvector::fwd & data); + static void packAllDeltaScriptVars(); + + // accessor functions + static JNIEnv * getEnv(void); + static int getJavaVmType(); + static const bool getClassName(const jobject & source, std::string & target); + static const bool getClassName(const jclass & sourceClass, std::string & target); + + // debug functions + static jlong getFreeJavaMemory(); + static void printJavaStack(); + + static ServerObject * findObjectByNetworkId (const NetworkId & id); + + static CreatureObject *getCreatureThrow(JNIEnv *env, jlong objId, char const *errorDescription, bool throwIfNotOnServer = true); + static ShipObject * getShipThrow(JNIEnv *env, jlong objId, char const *errorDescription, bool throwIfNotOnServer = true); + + template + static bool getObject(const jobject obj, OBJPTR &result) + { + if (obj != 0) + { + NetworkId id(getNetworkId(obj)); + result = dynamic_cast(findObjectByNetworkId (id)); + return result != 0; + } + return 0; + } + + template + static bool getObject(const jlong obj, OBJPTR &result) + { + if (obj != 0) + { + NetworkId id(static_cast(obj)); + result = dynamic_cast(findObjectByNetworkId (id)); + return result != 0; + } + return 0; + } + + template + static bool getObject(const LocalRefParam & obj, OBJPTR &result) + { + if (obj.getValue() != 0) + { + NetworkId id(getNetworkId(obj)); + result = dynamic_cast(findObjectByNetworkId (id)); + return result != 0; + } + return 0; + } + + template + static bool getObjectController(const jobject obj, OBJPTR &object, CTLPTR &controller) + { + if (getObject (obj, object) && object) + { + controller = dynamic_cast(object->getController()); + return controller != 0; + } + return 0; + } + + template + static bool getObjectController(const jlong obj, OBJPTR &object, CTLPTR &controller) + { + if (getObject (obj, object) && object) + { + controller = dynamic_cast(object->getController()); + return controller != 0; + } + return 0; + } + + // efficiency functions + bool queryScriptFunctions(const std::string & scriptName); + void enableLogging(bool enable) const; + void enableNewJediTracking(bool enableTracking); + + // conversion functions + static const bool convert(const std::string & source, JavaString & target); + static const bool convert(const JavaStringParam & source, std::string & target); + static const bool convert(const Unicode::String & source, JavaString & target); + static const bool convert(const JavaStringParam & source, Unicode::String & target); + static const bool convert(const JavaDictionary & source, stdvector::fwd & target); + static const bool convert(const LocalRefParamPtr & source, MenuDataVector & target); + static const bool convert(const MenuDataVector & source, LocalRefParamPtr & target); + static const bool convert(const stdmap::fwd & source, JavaDictionaryPtr & target); + static const bool convert(const stdvector >::fwd & source, JavaDictionaryPtr & target); + static const bool convert(const stdvector > >::fwd & source, JavaDictionaryPtr & target); + static const bool convert(const stdvector >::fwd & source, JavaDictionaryPtr & target); + static LocalRefPtr convert(const ValueDictionary & source); + static void convert(const jobject & source, ValueDictionary & target); + + // trigger functions + int runScripts(const NetworkId & caller, const std::string& method, const std::string& argList, ScriptParams &args); + int runScripts(const NetworkId & caller, const std::string& method, const std::string& argList, const StringVector_t &args); + int runScript(const NetworkId & caller, const std::string& script, const std::string& method, const std::string& argList, ScriptParams &args); + int runScript(const NetworkId & caller, const std::string& script, const std::string& method, const std::string& argList, const StringVector_t &args); + int runScript(const NetworkId & caller, const std::string& script, const std::string& method, jobjectArray args); + std::string callScriptConsoleHandler(const std::string & script, + const std::string & method, const std::string & argList, ScriptParams & args); + bool reloadScript(const std::string& scriptName); + + // message functions + int callMessages(const NetworkId & caller, const std::string & method, const ScriptDictionaryPtr & data); + int callMessage(const NetworkId & caller, const std::string & script, const std::string & method, const ScriptDictionary & data); + void packDictionary(const ScriptDictionary & dictionary, stdvector::fwd & packedData); + bool unpackDictionary(const stdvector::fwd & packedData, ScriptDictionaryPtr & dictionary); + void convert(const ScriptParams & params, JavaDictionaryPtr & dictionary); + + static void setupWeaponCombatData(JNIEnv *env, const WeaponObject * weapon, jobject weaponData); + static LocalRefPtr createObjectAttribute(const ManufactureObjectInterface & manfSchematic, const DraftSchematicObject & draftSchematic, int attribIndex); + static LocalRefPtr createExperimentAttribute(const ManufactureObjectInterface & manfSchematic, const StringId & attribName); + static LocalRefPtr convert(const ManufactureObjectInterface & source); + static LocalRefPtr convert(const ManufactureObjectInterface & schematic, const Crafting::IngredientSlot & source, int amountRequired, const std::string & appearance, const std::string & requiredIngredient); + static jobject convert(const DraftSchematicObject & source); + static jboolean updateDynamicVariableList(JNIEnv *env, DynamicVariableList &list, jobject data); + + static void throwInternalScriptError(const char * message); + +public: + // JNI class and id accessors + static jclass getClsAttribute(); + static jmethodID getMidAttribute(); + static jfieldID getFidAttributeType(); + static jfieldID getFidAttributeValue(); + + static jclass getClsBaseClassRangeInfo(); + static jfieldID getFidBaseClassRangeInfoMinRange(); + static jfieldID getFidBaseClassRangeInfoMaxRange(); + static jfieldID getFidBaseClassAttackerResultsId(); + static jfieldID getFidBaseClassAttackerResultsWeapon(); + static jfieldID getFidBaseClassAttackerResultsPosture(); + static jfieldID getFidBaseClassAttackerResultsTrailBits(); + static jfieldID getFidBaseClassAttackerResultsClientEffectId(); + static jfieldID getFidBaseClassAttackerResultsActionName(); + static jfieldID getFidBaseClassAttackerResultsUseLocation(); + static jfieldID getFidBaseClassAttackerResultsTargetLocation(); + static jfieldID getFidBaseClassAttackerResultsTargetCell(); + static jfieldID getFidBaseClassDefenderDamageAmount(); + static jfieldID getFidBaseClassDefenderResultsHitLocation(); + static jfieldID getFidBaseClassDefenderResultsId(); + static jfieldID getFidBaseClassDefenderResultsPosture(); + static jfieldID getFidBaseClassDefenderResultsResult(); + static jfieldID getFidBaseClassDefenderResultsClientEffectId(); + + static jclass getClsColor(); + static jmethodID getMidColor(); + + static jfieldID getFidCombatEngineAttackerDataWeaponSkill(); + static jfieldID getFidCombatEngineAttackerDataAims(); + static jfieldID getFidCombatEngineCombatantDataPos(); + static jfieldID getFidCombatEngineCombatantDataWorldPos(); + static jfieldID getFidCombatEngineCombatantDataRadius(); + static jfieldID getFidCombatEngineCombatantDataIsCreature(); + static jfieldID getFidCombatEngineCombatantDataPosture(); + static jfieldID getFidCombatEngineCombatantDataLocomotion(); + static jfieldID getFidCombatEngineCombatantDataScriptMod(); + static jfieldID getFidCombatEngineDefenderDataCombatSkeleton(); + static jfieldID getFidCombatEngineDefenderDataCover(); + static jfieldID getFidCombatEngineDefenderDataHitLocationChances(); + static jfieldID getFidCombatEngineHitResultRawDamage(); + static jfieldID getFidCombatEngineHitResultDamageType(); + static jfieldID getFidCombatEngineHitResultElementalDamage(); + static jfieldID getFidCombatEngineHitResultElementalDamageType(); + static jfieldID getFidCombatEngineHitResultBleedDamage(); + static jfieldID getFidCombatEngineHitResultCritDamage(); + static jfieldID getFidCombatEngineHitResultBlockedDamage(); + static jfieldID getFidCombatEngineHitResultDamage(); + static jfieldID getFidCombatEngineHitResultHitLocation(); + static jfieldID getFidCombatEngineHitResultSuccess(); + static jfieldID getFidCombatEngineHitResultCritical(); + static jfieldID getFidCombatEngineHitResultGlancing(); + static jfieldID getFidCombatEngineHitResultCrushing(); + static jfieldID getFidCombatEngineHitResultStrikethrough(); + static jfieldID getFidCombatEngineHitResultStrikethroughAmount(); + static jfieldID getFidCombatEngineHitResultEvadeResult(); + static jfieldID getFidCombatEngineHitResultEvadeAmount(); + static jfieldID getFidCombatEngineHitResultBlockResult(); + static jfieldID getFidCombatEngineHitResultBlock(); + static jfieldID getFidCombatEngineHitResultDodge(); + static jfieldID getFidCombatEngineHitResultParry(); + static jfieldID getFidCombatEngineHitResultProc(); + static jfieldID getFidCombatEngineHitResultBlockingArmor(); + + static jclass getClsCustomVar(); + static jmethodID getMidCustomVarObjIdStringInt(); + + static jclass getClsDraftSchematic(); + static jclass getClsDraftSchematicAttrib(); + static jfieldID getFidDraftSchematicAttribs(); + static jfieldID getFidDraftSchematicAttribMap(); + static jfieldID getFidDraftSchematicAttribName(); + static jfieldID getFidDraftSchematicAttribCurrentValue(); + static jfieldID getFidDraftSchematicAttribResourceMaxValue(); + static jfieldID getFidDraftSchematicAttribMinValue(); + static jfieldID getFidDraftSchematicAttribMaxValue(); + static jfieldID getFidDraftSchematicCustomName(); + static jfieldID getFidDraftSchematicCustomValue(); + static jfieldID getFidDraftSchematicCustomMinValue(); + static jfieldID getFidDraftSchematicCustomMaxValue(); + static jfieldID getFidDraftSchematicExperimentalAttribs(); + + static jclass getClsDynamicVariable(); + static jmethodID getMidDynamicVariableFloat(); + static jmethodID getMidDynamicVariableFloatArray(); + static jmethodID getMidDynamicVariableInt(); + static jmethodID getMidDynamicVariableIntArray(); + static jmethodID getMidDynamicVariableLocation(); + static jmethodID getMidDynamicVariableLocationArray(); + static jmethodID getMidDynamicVariableObjId(); + static jmethodID getMidDynamicVariableObjIdArray(); + static jmethodID getMidDynamicVariableString(); + static jmethodID getMidDynamicVariableStringArray(); + + static jclass getClsDynamicVariableList(); + static jmethodID getMidDynamicVariableList(); + static jmethodID getMidDynamicVariableListSet(); + static jmethodID getMidDynamicVariableListSetFloat(); + static jmethodID getMidDynamicVariableListSetFloatArray(); + static jmethodID getMidDynamicVariableListSetInt(); + static jmethodID getMidDynamicVariableListSetIntArray(); + static jmethodID getMidDynamicVariableListSetLocation(); + static jmethodID getMidDynamicVariableListSetLocationArray(); + static jmethodID getMidDynamicVariableListSetObjId(); + static jmethodID getMidDynamicVariableListSetObjIdArray(); + static jmethodID getMidDynamicVariableListSetString(); + static jmethodID getMidDynamicVariableListSetStringArray(); + static jmethodID getMidDynamicVariableListSetStringId(); + static jmethodID getMidDynamicVariableListSetStringIdArray(); + static jmethodID getMidDynamicVariableListSetTransform(); + static jmethodID getMidDynamicVariableListSetTransformArray(); + static jmethodID getMidDynamicVariableListSetVector(); + static jmethodID getMidDynamicVariableListSetVectorArray(); + + static jclass getClsBoolean(); + static jmethodID getMidBooleanBooleanValue(); + + static jclass getClsDictionary(); + static jmethodID getMidDictionary(); + static jmethodID getMidDictionaryGet(); + static jmethodID getMidDictionaryKeys(); + static jmethodID getMidDictionaryPut(); + static jmethodID getMidDictionaryPutFloat(); + static jmethodID getMidDictionaryPutInt(); + + static jmethodID getMidEnumerationHasMoreElements(); + static jmethodID getMidEnumerationNextElement(); + + static jclass getClsFloat(); + static jmethodID getMidFloatFloatValue(); + + static jclass getClsHashtable(); + static jmethodID getMidHashtable(); + + static jclass getClsInteger(); + static jmethodID getMidIntegerIntValue(); + + static jclass getClsLocation(); + static jclass getClsLocationArray(); + static jfieldID getFidLocationArea(); + static jfieldID getFidLocationCell(); + static jfieldID getFidLocationX(); + static jfieldID getFidLocationY(); + static jfieldID getFidLocationZ(); + + static jmethodID getMidMapPut(); + + static jclass getClsMapLocation(); + static jmethodID getMidMapLocation(); + + static jclass getClsMentalState(); + static jmethodID getMidMentalState(); + static jfieldID getFidMentalStateType(); + static jfieldID getFidMentalStateValue(); + + static jmethodID getMidObjIdGetValue(); + static jmethodID getMidObjIdSetAuthoritative(); + + static jclass getClsPalcolorCustomVar(); + static jmethodID getMidPalcolorCustomVar(); + + static jclass getClsRangedIntCustomVar(); + static jmethodID getMidRangedIntCustomVar(); + + static jclass getClsRegion(); + + static jclass getClsResourceAttribute(); + static jfieldID getFidResourceAttributeName(); + static jfieldID getFidResourceAttributeValue(); + + static jclass getClsResourceDensity(); + static jfieldID getFidResourceDensityDensity(); + static jfieldID getFidResourceDensityResourceType(); + + static jclass getClsScriptEntry(); + static jmethodID getMidScriptEntryGetOwnerContext(); + + static jclass getClsString(); + static jclass getClsStringArray(); + static jclass getClsStringId(); + static jclass getClsStringIdArray(); + static jfieldID getFidStringIdAsciiId(); + static jfieldID getFidStringIdTable(); + + static jclass getClsTransform(); + static jclass getClsTransformArray(); + + static jclass getClsVector(); + static jclass getClsVectorArray(); + +protected: + JavaLibrary(void); + virtual ~JavaLibrary(); + +private: + enum + { + MAX_STRING_ID_PARAMS = 10, + MAX_ATTRIB_MOD_PARAMS = 12, + MAX_MENTAL_STATE_MOD_PARAMS = 8, + MAX_MODIFIABLE_INT_PARAMS = 2, + MAX_MODIFIABLE_FLOAT_PARAMS = 1, + MAX_MODIFIABLE_STRING_ID_PARAMS = 2, + MAX_RECURSION_COUNT = 10 + }; + + // Function to make the java output quiet + static void fatalHandler(int); + + // class global instances stores a pool of commonly used java classes so we + // don't have to keep allocating/deallocating them + class GlobalInstances; + friend class GlobalInstances; + class GlobalInstances + { + friend class JavaLibrary; + public: + GlobalInstances(void); + ~GlobalInstances(); + + GlobalRefPtr getNextStringId(void); + GlobalRefPtr getNextAttribMod(void); + GlobalRefPtr getNextMentalStateMod(void); + GlobalRefPtr getNextModifiableInt(void); + GlobalRefPtr getNextModifiableFloat(void); + GlobalRefPtr getNextModifiableStringId(void); + GlobalRefPtr getMenuInfo(); + + private: + static int ms_stringIdIndex; // next string_id instance to use + static int ms_attribModIndex; // next attrib_mod instance to use + static int ms_mentalStateModIndex; // next mental_state instance to use + static int ms_modifiableIntIndex; // next modifiable_int instance to use + static int ms_modifiableFloatIndex; // next modifiable_float instance to use + static int ms_modifiableStringIdIndex; // next modifiable_string_id instance to use + static GlobalRefPtr ms_stringIds[MAX_STRING_ID_PARAMS]; // global string_id instances for paramaters + static GlobalRefPtr ms_attribMods[MAX_ATTRIB_MOD_PARAMS]; // global attrib_mod instances for paramaters + static GlobalRefPtr ms_mentalStateMods[MAX_MENTAL_STATE_MOD_PARAMS]; // global mental_state instances for parameters + static GlobalRefPtr ms_modifiableInts[MAX_MODIFIABLE_INT_PARAMS]; // global modifiable_int instances for other paramaters + static GlobalRefPtr ms_modifiableFloats[MAX_MODIFIABLE_FLOAT_PARAMS]; // global modifiable_float instances for paramaters + static GlobalRefPtr ms_modifiableStringIds[MAX_MODIFIABLE_STRING_ID_PARAMS]; // global modifiable_string_id instances for paramaters + static GlobalRefPtr ms_menuInfo; + int m_stringIdCount; // next string_id instance to use + int m_attribModCount; // next attrib_mod instance to use + int m_mentalStateModCount; // next mental_state instance to use + int m_modifiableIntCount; // next modifiable_int instance to use + int m_modifiableFloatCount; // next modifiable_float instance to use + int m_modifiableStringIdCount; // next modifiable_string_id instance to use + }; + +private: + + static JavaLibrary* ms_instance; // singleton instance + static int ms_javaVmType; // what kind of vm we are running +// static void* ms_libHandle; // handle to the Java shared library + static JavaVM* ms_jvm; // Java Virtual Machine + static JNIEnv* ms_env; // Java environment + static Thread * m_initializerThread; // thread that initializes the jvm + static int ms_envCount; // number of times we've reset the ms_env pointer + static int ms_currentRecursionCount; // number of times we've called into runScript + static bool ms_resetJava; // flag that we need to reset the Java connection as soon as we're all the way out of Java + static jclass ms_clsScriptEntry; // entry point for all scripts + static jobject ms_scriptEntry; // instance of class script_entry, used to initialize the class + static jmethodID ms_midScriptEntryGetOwnerContext; // the current game object ID of the running script + static jmethodID ms_midScriptEntryEnableLogging; // turn script logging on/off + static jmethodID ms_midScriptEntryEnableNewJediTracking; // turns tracking of players to see if they can become Jedi on or off + static jmethodID ms_midScriptEntryGetFreeMem; // gets the amount of free memory left in Java + static jclass ms_clsObject; // reference to java.lang.Object + static jclass ms_clsClass; // reference to java.lang.Class + static jmethodID ms_midClassGetName; // reference to java.lang.Class function getName + static jmethodID ms_midClassGetMethods; // reference to java.lang.Class function getMethods + static jclass ms_clsMethod; // reference to java.reflect.Method + static jmethodID ms_midMethodGetName; // reference to java.reflect.Method function getName + static jclass ms_clsBoolean; // reference to java.lang.Boolean + static jclass ms_clsBooleanArray; // reference to java.lang.Boolean[] + static jmethodID ms_midBoolean; // methodID for java.lang.Boolean constructor + static jmethodID ms_midBooleanBooleanValue; // methodID for java.lang.Boolean booleanValue() + static jclass ms_clsInteger; // reference to java.lang.Integer + static jclass ms_clsIntegerArray; // reference to java.lang.Integer[] + static jmethodID ms_midInteger; // methodID for java.lang.Integer constructor + static jmethodID ms_midIntegerIntValue; // methodID for java.lang.Integer intValue() + static jclass ms_clsModifiableInt; // reference to modifiable_int + static jmethodID ms_midModifiableInt; // methodID for modifiable_int constructor + static jfieldID ms_fidModifiableIntData; // reference to m_data field of modifiable_int + static jclass ms_clsFloat; // reference to java.lang.Float + static jclass ms_clsFloatArray; // reference to java.lang.Float[] + static jmethodID ms_midFloat; // methodID for java.lang.Float constructor + static jmethodID ms_midFloatFloatValue; // methodID for java.lang.Float floatValue() + static jclass ms_clsModifiableFloat; // reference to modifiable_float + static jmethodID ms_midModifiableFloat; // methodID for modifiable_float constructor + static jfieldID ms_fidModifiableFloatData; // reference to m_data field of modifiable_float + static jclass ms_clsString; // reference to java.lang.String + static jclass ms_clsStringArray; // reference to java.lang.String[] + static jclass ms_clsMap; // reference to java.util.Map + static jmethodID ms_midMapPut; // methodID for java.util.Map.put() + static jmethodID ms_midMapGet; // methodID for java.util.Map.get() + static jclass ms_clsHashtable; // reference to java.util.Hashtable + static jmethodID ms_midHashtable; // reference to java.util.Hashtable constructor + static jclass ms_clsThrowable; // reference to java.lang.Throwable + static jclass ms_clsError; // reference to java.lang.Error + static jclass ms_clsStackOverflowError;// reference to java.lang.StackOverflowError + static jmethodID ms_midThrowableGetMessage;// reference to java.lang.Throwable.getMessage() + static jclass ms_clsThread; // reference to java.lang.Thread + static jmethodID ms_midThreadDumpStack; // reference to java.lang.Thread.dumpStack() + + + static jclass ms_clsInternalScriptError; // reference to internal_script_exception + static jclass ms_clsInternalScriptSeriousError; // reference to internal_script_error + static jfieldID ms_fidInternalScriptSeriousErrorError; // fieldID for internal_script_error.wrappedError + + static jclass ms_clsDictionary; // reference to dictionary + static jmethodID ms_midDictionary; // method for the dictionary constructor + static jmethodID ms_midDictionaryPack; // method for dictionary::pack() + static jmethodID ms_midDictionaryUnpack; // method for dictionary::unpack() + + static jmethodID ms_midDictionaryKeys; // methodID for keys() + static jmethodID ms_midDictionaryValues; // methodID for values() + static jmethodID ms_midDictionaryGet; // methodID for dictionary::get() + static jmethodID ms_midDictionaryPut; // methodID for dictionary::put() + static jmethodID ms_midDictionaryPutInt; + static jmethodID ms_midDictionaryPutFloat; + static jmethodID ms_midDictionaryPutBool; + static jclass ms_clsCollection; // reference to Collection + static jmethodID ms_midCollectionToArray; // methodID for toArray() + static jclass ms_clsEnumeration; // reference to Enumeration + static jmethodID ms_midEnumerationHasMoreElements; // methodID for hasMoreElements() + static jmethodID ms_midEnumerationNextElement; // methodID for nextElement() + + static jclass ms_clsBaseClassRangeInfo; // reference to base_class.range_info + static jfieldID ms_fidBaseClassRangeInfoMinRange; // reference to minRange field of base_class.range_info + static jfieldID ms_fidBaseClassRangeInfoMaxRange; // reference to maxRange field of base_class.range_info + static jclass ms_clsBaseClassAttackerResults; // reference to base_class.attacker_results + static jfieldID ms_fidBaseClassAttackerResultsId; // reference to id field of base_class.attacker_results + static jfieldID ms_fidBaseClassAttackerResultsWeapon; // reference to weapon field of base_class.attacker_results + static jfieldID ms_fidBaseClassAttackerResultsPosture; // reference to endPosture field of base_class.attacker_results + static jfieldID ms_fidBaseClassAttackerResultsTrailBits;// reference to m_trailBits field of base_class.attacker_results + static jfieldID ms_fidBaseClassAttackerResultsClientEffectId; // reference to clientEffectId field of base_class.attacker_results + static jfieldID ms_fidBaseClassAttackerResultsActionName; // reference to actionName field of base_class.attacker_results + static jfieldID ms_fidBaseClassAttackerResultsUseLocation; // reference to useLocation field of base_class.attacker_results + static jfieldID ms_fidBaseClassAttackerResultsTargetLocation; // reference to targetLocation field of base_class.attacker_results + static jfieldID ms_fidBaseClassAttackerResultsTargetCell; // reference to targetCell field of base_class.attacker_results + static jclass ms_clsBaseClassDefenderResults; // reference to base_class.defender_results + static jfieldID ms_fidBaseClassDefenderResultsId; // reference to id field of base_class.defender_results + static jfieldID ms_fidBaseClassDefenderResultsPosture; // reference to endPosture field of base_class.defender_results + static jfieldID ms_fidBaseClassDefenderResultsResult; // reference to result field of base_class.defender_results + static jfieldID ms_fidBaseClassDefenderResultsClientEffectId; // reference to clientEffectId field of base_class.defender_results + static jfieldID ms_fidBaseClassDefenderResultsHitLocation; // reference to hitLocation field of base_class.defender_results + static jfieldID ms_fidBaseClassDefenderDamageAmount; // reference to damage amount field of base_class.defender_results + + static jclass ms_clsDynamicVariable; // reference to objVar + static jfieldID ms_fidDynamicVariableName; // reference to m_name field of objVar + static jfieldID ms_fidDynamicVariableData; // reference to m_data field of objVar + static jmethodID ms_midDynamicVariableInt; // methodID for integer objVar constructor + static jmethodID ms_midDynamicVariableIntArray; // methodID for integer array objVar constructor + static jmethodID ms_midDynamicVariableFloat; // methodID for float objVar constructor + static jmethodID ms_midDynamicVariableFloatArray; // methodID for float array objVar constructor + static jmethodID ms_midDynamicVariableString; // methodID for string objVar constructor + static jmethodID ms_midDynamicVariableStringArray; // methodID for string array objVar constructor + static jmethodID ms_midDynamicVariableObjId; // methodID for obj_id objVar constructor + static jmethodID ms_midDynamicVariableObjIdArray; // methodID for obj_id array objVar constructor + static jmethodID ms_midDynamicVariableLocation; // methodID for location objVar constructor + static jmethodID ms_midDynamicVariableLocationArray; // methodID for location array objVar constructor + + static jclass ms_clsDynamicVariableList; // reference to objVarList + static jmethodID ms_midDynamicVariableList; // methodID for integer objVarList constructor + static jmethodID ms_midDynamicVariableListSet; // methodID for setDynamicVariable(objVar data) + static jmethodID ms_midDynamicVariableListSetInt; // methodID for setDynamicVariable(String name, int data) + static jmethodID ms_midDynamicVariableListSetIntArray; // methodID for setDynamicVariable(String name, int[] data) + static jmethodID ms_midDynamicVariableListSetFloat; // methodID for setDynamicVariable(String name, float data) + static jmethodID ms_midDynamicVariableListSetFloatArray; // methodID for setDynamicVariable(String name, float[] data) + static jmethodID ms_midDynamicVariableListSetString; // methodID for setDynamicVariable(String name, string data) + static jmethodID ms_midDynamicVariableListSetStringArray; // methodID for setDynamicVariable(String name, string[] data) + static jmethodID ms_midDynamicVariableListSetObjId; // methodID for setDynamicVariable(String name, obj_id data) + static jmethodID ms_midDynamicVariableListSetObjIdArray; // methodID for setDynamicVariable(String name, obj_id[] data) + static jmethodID ms_midDynamicVariableListSetLocation; // methodID for setDynamicVariable(String name, location data) + static jmethodID ms_midDynamicVariableListSetLocationArray; // methodID for setDynamicVariable(String name, location[] data) + static jmethodID ms_midDynamicVariableListSetStringId; // methodID for setDynamicVariable(String name, string_id data) + static jmethodID ms_midDynamicVariableListSetStringIdArray; // methodID for setDynamicVariable(String name, string_id[] data) + static jmethodID ms_midDynamicVariableListSetTransform; // methodID for setDynamicVariable(String name, transform data) + static jmethodID ms_midDynamicVariableListSetTransformArray; // methodID for setDynamicVariable(String name, transform[] data) + static jmethodID ms_midDynamicVariableListSetVector; // methodID for setDynamicVariable(String name, vector data) + static jmethodID ms_midDynamicVariableListSetVectorArray; // methodID for setDynamicVariable(String name, vector[] data) + + static jclass ms_clsObjId; // reference to objId + static jclass ms_clsObjIdArray; // reference to objId[] + static jobjectArray ms_objIdList[MAX_RECURSION_COUNT]; // global objId array for sendings lists of objIds + static jmethodID ms_midObjIdGetValue; // methodID for objId.getValue + static jmethodID ms_midObjIdGetObjId; // methodID for objId.getObjId + static jmethodID ms_midObjIdClearObjId; // methodID for objId.clearObjId + static jmethodID ms_midObjIdFlagDestroyed;// methodID for objId.flagDestroyed + static jmethodID ms_midObjIdSetAuthoritative; // methodID for objId.setAuthoritative + static jmethodID ms_midObjIdSetLoaded; // methodID for objId.setLoaded + static jmethodID ms_midObjIdSetInitialized; // methodID for objId.setInitialized + static jmethodID ms_midObjIdSetLoggedIn; // methodID for objId.setLoggedIn + static jmethodID ms_midObjIdAttachScript; // methodID for objId.attachScript(String) + static jmethodID ms_midObjIdAttachScripts; // methodID for objId.attachScript(String[]) + static jmethodID ms_midObjIdDetachScript; // methodID for objId.detachScript + static jmethodID ms_midObjIdDetachAllScripts; // methodID for objId.detachAllScripts + static jmethodID ms_midObjIdPackAllDeltaScriptVars; // methodID for String obj_id.packAllScriptVars() + static jmethodID ms_midObjIdSetScriptVarInt; // methodID for objId.setScriptVar(int) + static jmethodID ms_midObjIdSetScriptVarFloat; // methodID for objId.setScriptVar(float) + static jmethodID ms_midObjIdSetScriptVarString; // methodID for objId.setScriptVar(String) + static jmethodID ms_midObjIdClearScriptVars; // methodID for objId.clearScriptVars() + static jmethodID ms_midObjIdPackScriptVars; // methoID for String obj_id.packScriptVars() + static jmethodID ms_midObjIdPackDeltaScriptVars; // methodID for String obj_id.packDeltaScriptVars() + static jmethodID ms_midObjIdUnpackScriptVars; // methodID for obj_id.unpackScriptVars(String) + static jmethodID ms_midObjIdUnpackDeltaScriptVars; // methodID for obj_id.unpackDeltaScriptVars(String) + static jclass ms_clsStringId; // reference to string_id + static jmethodID ms_midStringId; // methodID for string_id constructor + static jclass ms_clsStringIdArray; // reference to string_id[] + static jfieldID ms_fidStringIdTable; // reference to m_table field of string_id + static jfieldID ms_fidStringIdAsciiId; // reference to m_asciiId field of string_id + static jfieldID ms_fidStringIdIndexId; // reference to m_indexId field of string_id + static jclass ms_clsModifiableStringId;// reference to modifiable_string_id + +// static jobject ms_stringIdArray[MAX_STRINGID_PARAMS]; // global stringId instances for paramaters + static jclass ms_clsAttribute; // reference to attribute + static jmethodID ms_midAttribute; // methodID for attribute constructor + static jfieldID ms_fidAttributeType; // reference to m_type field of attribute + static jfieldID ms_fidAttributeValue; // reference to m_value field of attribute + static jclass ms_clsAttribMod; // reference to attribMod + static jmethodID ms_midAttribMod; // methodID for attribMod constructor + static jfieldID ms_fidAttribModName; // reference to m_name field of attribMod + static jfieldID ms_fidAttribModSkill; // reference to m_skill field of attribMod + static jfieldID ms_fidAttribModType; // reference to m_attrib field of attribMod + static jfieldID ms_fidAttribModValue; // reference to m_value field of attribMod + static jfieldID ms_fidAttribModTime; // reference to m_duration field of attribMod + static jfieldID ms_fidAttribModAttack; // reference to m_attack field of attribMod + static jfieldID ms_fidAttribModDecay; // reference to m_decay field of attribMod + static jfieldID ms_fidAttribModFlags; // reference to m_flags field of attribMod + static GlobalArrayRefPtr ms_attribModList[MAX_RECURSION_COUNT]; // global attribMod array for sending list of attribMods + + static jclass ms_clsMentalState; // reference to MentalState + static jmethodID ms_midMentalState; // methodID for MentalState constructor + static jfieldID ms_fidMentalStateType; // reference to m_type field of MentalState + static jfieldID ms_fidMentalStateValue;// reference to m_value field of MentalState + static jclass ms_clsMentalStateMod; // reference to MentalStateMod + static jmethodID ms_midMentalStateMod; // methodID for MentalStateMod constructor + static jfieldID ms_fidMentalStateModType; // reference to m_attrib field of MentalStateMod + static jfieldID ms_fidMentalStateModValue;// reference to m_value field of MentalStateMod + static jfieldID ms_fidMentalStateModTime; // reference to m_duration field of MentalStateMod + static jfieldID ms_fidMentalStateModAttack;// reference to m_attack field of MentalStateMod + static jfieldID ms_fidMentalStateModDecay;// reference to m_decay field of MentalStateMod + static GlobalArrayRefPtr ms_mentalStateModList[MAX_RECURSION_COUNT]; // global MentalStateMod array for sending list of MentalStateMods + + static jclass ms_clsLocation; // reference to location + static jclass ms_clsLocationArray; // reference to location[] + static jfieldID ms_fidLocationX; // reference to x field of location + static jfieldID ms_fidLocationY; // reference to y field of location + static jfieldID ms_fidLocationZ; // reference to z field of location + static jfieldID ms_fidLocationArea; // reference to planetName field of location + static jfieldID ms_fidLocationCell; // reference to cell field of location + + static jmethodID ms_midRunOne; // methodID for script_entry.runScript() + static jmethodID ms_midRunAll; // methodID for script_entry.runScripts() + static jmethodID ms_midCallMessages; // methodID for script_entry.callMessageHandlers() + static jmethodID ms_midRunConsoleHandler; // methodID for script_entry.runConsoleHandler() + static jmethodID ms_midUnload; // methodID for script_entry.unloadClass() + static jmethodID ms_midGetClass; // methodID for script_entry.getClass() + static jmethodID ms_midGetScriptFunctions;// methodID for script_entry.getScriptFunctions() + + static jclass ms_clsMenuInfo; + static jmethodID ms_midMenuInfo; + static jmethodID ms_midMenuInfoSetMenuItemsInternal; + static jmethodID ms_midMenuInfoGetMenuItemsInternal; + static jclass ms_clsMenuInfoData; + static jmethodID ms_midMenuInfoData; + static jfieldID ms_fidMenuInfoDataId; + static jfieldID ms_fidMenuInfoDataParent; + static jfieldID ms_fidMenuInfoDataType; + static jfieldID ms_fidMenuInfoDataLabel; + static jfieldID ms_fidMenuInfoDataEnabled; + static jfieldID ms_fidMenuInfoDataServerNotify; + + // customization-related class, method, field specification + static jclass ms_clsCustomVar; + static jmethodID ms_midCustomVarObjIdStringInt; + static jclass ms_clsRangedIntCustomVar; + static jmethodID ms_midRangedIntCustomVar; + + static jclass ms_clsPalcolorCustomVar; + static jmethodID ms_midPalcolorCustomVar; + + static jclass ms_clsColor; + static jmethodID ms_midColor; + + static jclass ms_clsDraftSchematic; // reference to draft_schematic + static jfieldID ms_fidDraftSchematicCategory; // reference to m_category field of draft_schematic + static jfieldID ms_fidDraftSchematicComplexity; // reference to m_complexity field of draft_schematic + static jfieldID ms_fidDraftSchematicSlots; // reference to m_slots field of draft_schematic + static jfieldID ms_fidDraftSchematicAttribs; // reference to m_attribs field of draft_schematic + static jfieldID ms_fidDraftSchematicExperimentalAttribs; // reference to m_attribs field of draft_schematic + static jfieldID ms_fidDraftSchematicCustomizations; // reference to m_customizations field of draft_schematic + static jfieldID ms_fidDraftSchematicAttribMap; // reference to m_attribMap field of draft_schematic + static jfieldID ms_fidDraftSchematicObjectTemplateCreated;// reference to m_objectTemplateCreated field of draft_schematic + static jfieldID ms_fidDraftSchematicScripts; // reference to m_scripts field of draft_schematic + static jclass ms_clsDraftSchematicSlot; // reference to draft_schematic.slot + static jfieldID ms_fidDraftSchematicSlotName; // reference to name field of draft_schematic.slot + static jfieldID ms_fidDraftSchematicSlotOption; // reference to slotOption field of draft_schematic.slot + static jfieldID ms_fidDraftSchematicSlotIngredientType; // reference to ingredientType field of draft_schematic.slot + static jfieldID ms_fidDraftSchematicSlotIngredientName; // reference to ingredientName field of draft_schematic.slot + static jfieldID ms_fidDraftSchematicSlotIngredients; // reference to ingredients field of draft_schematic.slot + static jfieldID ms_fidDraftSchematicSlotComplexity; // reference to complexity field of draft_schematic.slot + static jfieldID ms_fidDraftSchematicSlotAmountRequired; // reference to amountRequired field of draft_schematic.slot + static jfieldID ms_fidDraftSchematicSlotAppearance; // reference to appearance field of draft_schematic.slot + static jclass ms_clsDraftSchematicAttrib; // reference to draft_schematic.attribute + static jfieldID ms_fidDraftSchematicAttribName; // reference to name field of draft_schematic.attribute + static jfieldID ms_fidDraftSchematicAttribMinValue; // reference to minValue field of draft_schematic.attribute + static jfieldID ms_fidDraftSchematicAttribMaxValue; // reference to maxValue field of draft_schematic.attribute + static jfieldID ms_fidDraftSchematicAttribResourceMaxValue;// reference to resourceMaxValue field of draft_schematic.attribute + static jfieldID ms_fidDraftSchematicAttribCurrentValue; // reference to currentValue field of draft_schematic.attribute + static jclass ms_clsDraftSchematicSimpleIngredient; // reference to draft_schematic.simple_ingredient + static jfieldID ms_fidDraftSchematicSimpleIngredientIngredient; // reference to ingredient field of draft_schematic.simple_ingredient + static jfieldID ms_fidDraftSchematicSimpleIngredientCount; // reference to count field of draft_schematic.simple_ingredient + static jfieldID ms_fidDraftSchematicSimpleIngredientSource; // reference to source field of draft_schematic.simple_ingredient + static jfieldID ms_fidDraftSchematicSimpleIngredientXpType; // reference to xpType field of draft_schematic.simple_ingredient + static jfieldID ms_fidDraftSchematicSimpleIngredientXpAmount; // reference to xpAmount field of draft_schematic.simple_ingredient + static jclass ms_clsDraftSchematicCustom; // reference to draft_schematic.custom + static jfieldID ms_fidDraftSchematicCustomName; // reference to name field of draft_schematic.custom + static jfieldID ms_fidDraftSchematicCustomValue; // reference to value field of draft_schematic.custom + static jfieldID ms_fidDraftSchematicCustomMinValue; // reference to minValue field of draft_schematic.custom + static jfieldID ms_fidDraftSchematicCustomMaxValue; // reference to maxValue field of draft_schematic.custom +// static jfieldID ms_fidDraftSchematicCustomLocked; // reference to locked field of draft_schematic.custom + + static jclass ms_clsMapLocation; + static jmethodID ms_midMapLocation; + + static jclass ms_clsRegion; + static jmethodID ms_midRegion; + static jfieldID ms_fidRegionName; + static jfieldID ms_fidRegionPlanet; + + static jclass ms_clsCombatEngine; + static jclass ms_clsCombatEngineCombatantData; + static jfieldID ms_fidCombatEngineCombatantDataPos; + static jfieldID ms_fidCombatEngineCombatantDataWorldPos; + static jfieldID ms_fidCombatEngineCombatantDataRadius; + static jfieldID ms_fidCombatEngineCombatantDataIsCreature; + static jfieldID ms_fidCombatEngineCombatantDataPosture; + static jfieldID ms_fidCombatEngineCombatantDataLocomotion; + static jfieldID ms_fidCombatEngineCombatantDataScriptMod; + static jclass ms_clsCombatEngineAttackerData; + static jfieldID ms_fidCombatEngineAttackerDataWeaponSkill; + static jfieldID ms_fidCombatEngineAttackerDataAims; + static jclass ms_clsCombatEngineDefenderData; + static jfieldID ms_fidCombatEngineDefenderDataCombatSkeleton; + static jfieldID ms_fidCombatEngineDefenderDataCover; + static jfieldID ms_fidCombatEngineDefenderDataHitLocationChances; + static jclass ms_clsCombatEngineWeaponData; + static jfieldID ms_fidCombatEngineWeaponDataId; + static jfieldID ms_fidCombatEngineWeaponDataMinDamage; + static jfieldID ms_fidCombatEngineWeaponDataMaxDamage; + static jfieldID ms_fidCombatEngineWeaponDataWeaponType; + static jfieldID ms_fidCombatEngineWeaponDataAttackType; + static jfieldID ms_fidCombatEngineWeaponDataDamageType; + static jfieldID ms_fidCombatEngineWeaponDataElementalType; + static jfieldID ms_fidCombatEngineWeaponDataElementalValue; + static jfieldID ms_fidCombatEngineWeaponDataAttackSpeed; + static jfieldID ms_fidCombatEngineWeaponDataWoundChance; + static jfieldID ms_fidCombatEngineWeaponDataAccuracy; + static jfieldID ms_fidCombatEngineWeaponDataMinRange; + static jfieldID ms_fidCombatEngineWeaponDataMaxRange; + static jfieldID ms_fidCombatEngineWeaponDataDamageRadius; + static jfieldID ms_fidCombatEngineWeaponDataAttackCost; + static jfieldID ms_fidCombatEngineWeaponDataIsDisabled; + static jclass ms_clsCombatEngineHitResult; + static jfieldID ms_fidCombatEngineHitResultSuccess; + static jfieldID ms_fidCombatEngineHitResultCritical; + static jfieldID ms_fidCombatEngineHitResultGlancing; + static jfieldID ms_fidCombatEngineHitResultCrushing; + static jfieldID ms_fidCombatEngineHitResultStrikethrough; + static jfieldID ms_fidCombatEngineHitResultStrikethroughAmount; + static jfieldID ms_fidCombatEngineHitResultEvadeResult; + static jfieldID ms_fidCombatEngineHitResultEvadeAmount; + static jfieldID ms_fidCombatEngineHitResultBlockResult; + static jfieldID ms_fidCombatEngineHitResultBlock; + static jfieldID ms_fidCombatEngineHitResultDodge; + static jfieldID ms_fidCombatEngineHitResultParry; + static jfieldID ms_fidCombatEngineHitResultProc; + static jfieldID ms_fidCombatEngineHitResultBaseRoll; + static jfieldID ms_fidCombatEngineHitResultFinalRoll; + static jfieldID ms_fidCombatEngineHitResultAttackVal; + static jfieldID ms_fidCombatEngineHitResultCanSee; + static jfieldID ms_fidCombatEngineHitResultHitLocation; + static jfieldID ms_fidCombatEngineHitResultDamage; + static jfieldID ms_fidCombatEngineHitResultDamageType; + static jfieldID ms_fidCombatEngineHitResultRawDamage; + static jfieldID ms_fidCombatEngineHitResultElementalDamage; + static jfieldID ms_fidCombatEngineHitResultElementalDamageType; + static jfieldID ms_fidCombatEngineHitResultBleedDamage; + static jfieldID ms_fidCombatEngineHitResultCritDamage; + static jfieldID ms_fidCombatEngineHitResultBlockedDamage; + static jfieldID ms_fidCombatEngineHitResultBlockingArmor; + static jfieldID ms_fidCombatEngineHitResultBleedingChance; + + static jclass ms_clsTransform; + static jclass ms_clsTransformArray; + static jmethodID ms_midTransform; + static jfieldID ms_fidTransformMatrix; + + static jclass ms_clsVector; + static jclass ms_clsVectorArray; + static jfieldID ms_fidVectorX; + static jfieldID ms_fidVectorY; + static jfieldID ms_fidVectorZ; + + static jclass ms_clsResourceDensity; + static jfieldID ms_fidResourceDensityResourceType; + static jfieldID ms_fidResourceDensityDensity; + + static jclass ms_clsResourceAttribute; + static jfieldID ms_fidResourceAttributeName; + static jfieldID ms_fidResourceAttributeValue; + + static jclass ms_clsLibrarySpaceTransition; + static jmethodID ms_midLibrarySpaceTransitionSetPlayerOvert; + static jmethodID ms_midLibrarySpaceTransitionClearOvertStatus; + +//////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// + // java classes/methods needed by CS Handlers. These classes may not be CS specific + // if there is no previous call into them specifically. + + static jclass ms_clsLibraryDump; + static jmethodID ms_midLibraryDumpDumpTargetInfo; + + static jclass ms_clsLibraryGMLib; + static jmethodID ms_midLibraryGMLibFreeze; + static jmethodID ms_midLibraryGMLibUnfreeze; + +//////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// + + // flag that the JVM was loaded; once it is, it can never be loaded again + // without restarting the program + static int ms_loaded; + static Semaphore * ms_shutdownJava; + + // Java initialization functions + void initializeJavaThread(); + bool connectToJava(); + void disconnectFromJava(); + void resetJavaConnection(); + + // entry point to Java VM + static jint handleScriptEntryCleanup(jint result); + static jint callScriptEntry(const JavaStringParam & script, const JavaStringParam & method, jobjectArray params); + static jint callScriptEntry(const JavaStringParam & method, jobjectArray params); + static jstring callScriptConsoleHandlerEntry(const JavaStringParam & script, const JavaStringParam & method, jobjectArray params); + + // obj_id functions + public: + static LocalRefPtr getObjId(const ServerObject & object); + static LocalRefPtr getObjId(const NetworkId::NetworkIdType & id); + static LocalRefPtr getObjId(const NetworkId & id); + + static const NetworkId getNetworkId(const jobject & source); + static const NetworkId getNetworkId(const LocalRefParam & source); + + static LocalRefPtr getVector(Vector const & vector); + +///////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// + static void spaceMakeOvert(const NetworkId &player); + static void spaceClearOvert(const NetworkId &ship); + + static std::string getObjectDumpInfo( NetworkId id ); + + static void freezePlayer( const NetworkId &id ); + static void unFreezePlayer( const NetworkId &id ); + +///////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// + + private: + + // misc support functions + static LocalObjectArrayRefPtr convert(const NetworkId & caller, const std::string& argList, const ScriptParams &args); + static LocalObjectArrayRefPtr convert(const std::string& argList, const ScriptParams &args); + static bool convert(LocalObjectArrayRefPtr & javaParams, int startIndex, const std::string& argList, const ScriptParams &args); + static void alterScriptParams(jobjectArray jparams, const std::string& argList, ScriptParams &args); +}; + +// ---------------------------------------------------------------------- +inline JavaLibrary* JavaLibrary::instance(void) +{ + return ms_instance; +} // JavaLibrary::Instance + +inline JavaLibrary::GlobalInstances::GlobalInstances(void) : + m_stringIdCount(0), + m_attribModCount(0), + m_mentalStateModCount(0), + m_modifiableIntCount(0), + m_modifiableFloatCount(0), + m_modifiableStringIdCount(0) +{ +} // JavaLibrary::GlobalInstances::GlobalInstances + +inline JavaLibrary::GlobalInstances::~GlobalInstances() +{ + ms_stringIdIndex -= m_stringIdCount; + ms_attribModIndex -= m_attribModCount; + ms_mentalStateModIndex -= m_mentalStateModCount; + ms_modifiableIntIndex -= m_modifiableIntCount; + ms_modifiableFloatIndex -= m_modifiableFloatCount; + ms_modifiableStringIdIndex -= m_modifiableStringIdCount; +} // JavaLibrary::GlobalInstances::~GlobalInstances + +inline GlobalRefPtr JavaLibrary::GlobalInstances::getNextStringId(void) +{ + if (ms_stringIdIndex == MAX_STRING_ID_PARAMS) + { + DEBUG_REPORT_LOG(true, ("Too many stringId params, max = %d\n", + MAX_STRING_ID_PARAMS)); + return GlobalRef::cms_nullPtr; + } + ++m_stringIdCount; + return ms_stringIds[ms_stringIdIndex++]; +} // JavaLibrary::GlobalInstances::getNextStringId + +inline GlobalRefPtr JavaLibrary::GlobalInstances::getNextAttribMod(void) +{ + if (ms_attribModIndex == MAX_ATTRIB_MOD_PARAMS) + { + DEBUG_REPORT_LOG(true, ("Too many attribMod params, max = %d\n", + MAX_ATTRIB_MOD_PARAMS)); + return GlobalRef::cms_nullPtr; + } + ++m_attribModCount; + return ms_attribMods[ms_attribModIndex++]; +} // JavaLibrary::GlobalInstances::getNextAttribMod + +inline GlobalRefPtr JavaLibrary::GlobalInstances::getNextModifiableInt(void) +{ + if (ms_modifiableIntIndex == MAX_MODIFIABLE_INT_PARAMS) + { + DEBUG_REPORT_LOG(true, ("Too many modifiableInt params, max = %d\n", + MAX_MODIFIABLE_INT_PARAMS)); + return GlobalRef::cms_nullPtr; + } + ++m_modifiableIntCount; + return ms_modifiableInts[ms_modifiableIntIndex++]; +} // JavaLibrary::GlobalInstances::getNextModifiableInt + +inline GlobalRefPtr JavaLibrary::GlobalInstances::getNextModifiableFloat(void) +{ + if (ms_modifiableFloatIndex == MAX_MODIFIABLE_FLOAT_PARAMS) + { + DEBUG_REPORT_LOG(true, ("Too many modifiableFloat params, max = %d\n", + MAX_MODIFIABLE_FLOAT_PARAMS)); + return GlobalRef::cms_nullPtr; + } + ++m_modifiableFloatCount; + return ms_modifiableFloats[ms_modifiableFloatIndex++]; +} // JavaLibrary::GlobalInstances::getNextModifiableFloat + +inline GlobalRefPtr JavaLibrary::GlobalInstances::getNextModifiableStringId(void) +{ + if (ms_modifiableStringIdIndex == MAX_MODIFIABLE_STRING_ID_PARAMS) + { + DEBUG_REPORT_LOG(true, ("Too many modifiableStringId params, max = %d\n", + MAX_MODIFIABLE_STRING_ID_PARAMS)); + return GlobalRef::cms_nullPtr; + } + ++m_modifiableStringIdCount; + return ms_modifiableStringIds[ms_modifiableStringIdIndex++]; +} // JavaLibrary::GlobalInstances::getNextModifiableStringId + +inline GlobalRefPtr JavaLibrary::GlobalInstances::getNextMentalStateMod(void) +{ + if (ms_mentalStateModIndex == MAX_MENTAL_STATE_MOD_PARAMS) + { + DEBUG_REPORT_LOG(true, ("Too many mental_state_mod params, max = %d\n", + MAX_MENTAL_STATE_MOD_PARAMS)); + return GlobalRef::cms_nullPtr; + } + ++m_mentalStateModCount; + return ms_mentalStateMods[ms_mentalStateModIndex++]; +} // JavaLibrary::GlobalInstances::getNextMentalStateMod + +inline GlobalRefPtr JavaLibrary::GlobalInstances::getMenuInfo() +{ + return ms_menuInfo; +} + +// ---------------------------------------------------------------------- + +inline JNIEnv * JavaLibrary::getEnv(void) +{ + return ms_env; +} + +// ---------------------------------------------------------------------- + +inline int JavaLibrary::getJavaVmType() +{ + return ms_javaVmType; +} + +// ---------------------------------------------------------------------- + +namespace ScriptConversion +{ + inline const bool getClassName(const jobject & source, std::string & target) + { + return JavaLibrary::getClassName(source, target); + } +}; + +//---------------------------------------------------------------------- + +#define JAVA_THROW_SCRIPT_EXCEPTION(a, b) ((a) ? JavaLibrary::throwScriptException b : NOP) + +//---------------------------------------------------------------------- + +inline jclass JavaLibrary::getClsAttribute() +{ + return ms_clsAttribute; +} + +inline jmethodID JavaLibrary::getMidAttribute() +{ + return ms_midAttribute; +} + +inline jfieldID JavaLibrary::getFidAttributeType() +{ + return ms_fidAttributeType; +} + +inline jfieldID JavaLibrary::getFidAttributeValue() +{ + return ms_fidAttributeValue; +} + +inline jclass JavaLibrary::getClsBaseClassRangeInfo() +{ + return ms_clsBaseClassRangeInfo; +} + +inline jfieldID JavaLibrary::getFidBaseClassRangeInfoMinRange() +{ + return ms_fidBaseClassRangeInfoMinRange; +} + +inline jfieldID JavaLibrary::getFidBaseClassRangeInfoMaxRange() +{ + return ms_fidBaseClassRangeInfoMaxRange; +} + +inline jfieldID JavaLibrary::getFidBaseClassAttackerResultsId() +{ + return ms_fidBaseClassAttackerResultsId; +} + +inline jfieldID JavaLibrary::getFidBaseClassAttackerResultsWeapon() +{ + return ms_fidBaseClassAttackerResultsWeapon; +} + +inline jfieldID JavaLibrary::getFidBaseClassAttackerResultsPosture() +{ + return ms_fidBaseClassAttackerResultsPosture; +} + +inline jfieldID JavaLibrary::getFidBaseClassAttackerResultsTrailBits() +{ + return ms_fidBaseClassAttackerResultsTrailBits; +} + +inline jfieldID JavaLibrary::getFidBaseClassAttackerResultsClientEffectId() +{ + return ms_fidBaseClassAttackerResultsClientEffectId; +} + +inline jfieldID JavaLibrary::getFidBaseClassAttackerResultsActionName() +{ + return ms_fidBaseClassAttackerResultsActionName; +} + +inline jfieldID JavaLibrary::getFidBaseClassAttackerResultsUseLocation() +{ + return ms_fidBaseClassAttackerResultsUseLocation; +} + +inline jfieldID JavaLibrary::getFidBaseClassAttackerResultsTargetLocation() +{ + return ms_fidBaseClassAttackerResultsTargetLocation; +} + +inline jfieldID JavaLibrary::getFidBaseClassAttackerResultsTargetCell() +{ + return ms_fidBaseClassAttackerResultsTargetCell; +} + +inline jfieldID JavaLibrary::getFidBaseClassDefenderDamageAmount() +{ + return ms_fidBaseClassDefenderDamageAmount; +} + +inline jfieldID JavaLibrary::getFidBaseClassDefenderResultsHitLocation() +{ + return ms_fidBaseClassDefenderResultsHitLocation; +} + +inline jfieldID JavaLibrary::getFidBaseClassDefenderResultsId() +{ + return ms_fidBaseClassDefenderResultsId; +} + +inline jfieldID JavaLibrary::getFidBaseClassDefenderResultsPosture() +{ + return ms_fidBaseClassDefenderResultsPosture; +} + +inline jfieldID JavaLibrary::getFidBaseClassDefenderResultsResult() +{ + return ms_fidBaseClassDefenderResultsResult; +} + +inline jfieldID JavaLibrary::getFidBaseClassDefenderResultsClientEffectId() +{ + return ms_fidBaseClassDefenderResultsClientEffectId; +} + +inline jclass JavaLibrary::getClsColor() +{ + return ms_clsColor; +} + +inline jmethodID JavaLibrary::getMidColor() +{ + return ms_midColor; +} + +inline jfieldID JavaLibrary::getFidCombatEngineAttackerDataWeaponSkill() +{ + return ms_fidCombatEngineAttackerDataWeaponSkill; +} + +inline jfieldID JavaLibrary::getFidCombatEngineAttackerDataAims() +{ + return ms_fidCombatEngineAttackerDataAims; +} + +inline jfieldID JavaLibrary::getFidCombatEngineCombatantDataPos() +{ + return ms_fidCombatEngineCombatantDataPos; +} + +inline jfieldID JavaLibrary::getFidCombatEngineCombatantDataWorldPos() +{ + return ms_fidCombatEngineCombatantDataWorldPos; +} + +inline jfieldID JavaLibrary::getFidCombatEngineCombatantDataRadius() +{ + return ms_fidCombatEngineCombatantDataRadius; +} + +inline jfieldID JavaLibrary::getFidCombatEngineCombatantDataIsCreature() +{ + return ms_fidCombatEngineCombatantDataIsCreature; +} + +inline jfieldID JavaLibrary::getFidCombatEngineCombatantDataPosture() +{ + return ms_fidCombatEngineCombatantDataPosture; +} + +inline jfieldID JavaLibrary::getFidCombatEngineCombatantDataLocomotion() +{ + return ms_fidCombatEngineCombatantDataLocomotion; +} + +inline jfieldID JavaLibrary::getFidCombatEngineCombatantDataScriptMod() +{ + return ms_fidCombatEngineCombatantDataScriptMod; +} + +inline jfieldID JavaLibrary::getFidCombatEngineDefenderDataCombatSkeleton() +{ + return ms_fidCombatEngineDefenderDataCombatSkeleton; +} + +inline jfieldID JavaLibrary::getFidCombatEngineDefenderDataCover() +{ + return ms_fidCombatEngineDefenderDataCover; +} + +inline jfieldID JavaLibrary::getFidCombatEngineDefenderDataHitLocationChances() +{ + return ms_fidCombatEngineDefenderDataHitLocationChances; +} + +inline jfieldID JavaLibrary::getFidCombatEngineHitResultRawDamage() +{ + return ms_fidCombatEngineHitResultRawDamage; +} + +inline jfieldID JavaLibrary::getFidCombatEngineHitResultDamageType() +{ + return ms_fidCombatEngineHitResultDamageType; +} + +inline jfieldID JavaLibrary::getFidCombatEngineHitResultElementalDamage() +{ + return ms_fidCombatEngineHitResultElementalDamage; +} + +inline jfieldID JavaLibrary::getFidCombatEngineHitResultElementalDamageType() +{ + return ms_fidCombatEngineHitResultElementalDamageType; +} + +inline jfieldID JavaLibrary::getFidCombatEngineHitResultBleedDamage() +{ + return ms_fidCombatEngineHitResultBleedDamage; +} + +inline jfieldID JavaLibrary::getFidCombatEngineHitResultCritDamage() +{ + return ms_fidCombatEngineHitResultCritDamage; +} + +inline jfieldID JavaLibrary::getFidCombatEngineHitResultBlockedDamage() +{ + return ms_fidCombatEngineHitResultBlockedDamage; +} + +inline jfieldID JavaLibrary::getFidCombatEngineHitResultDamage() +{ + return ms_fidCombatEngineHitResultDamage; +} + +inline jfieldID JavaLibrary::getFidCombatEngineHitResultHitLocation() +{ + return ms_fidCombatEngineHitResultHitLocation; +} + +inline jfieldID JavaLibrary::getFidCombatEngineHitResultSuccess() +{ + return ms_fidCombatEngineHitResultSuccess; +} + +inline jfieldID JavaLibrary::getFidCombatEngineHitResultCritical() +{ + return ms_fidCombatEngineHitResultCritical; +} + +inline jfieldID JavaLibrary::getFidCombatEngineHitResultGlancing() +{ + return ms_fidCombatEngineHitResultGlancing; +} + +inline jfieldID JavaLibrary::getFidCombatEngineHitResultCrushing() +{ + return ms_fidCombatEngineHitResultCrushing; +} + +inline jfieldID JavaLibrary::getFidCombatEngineHitResultStrikethrough() +{ + return ms_fidCombatEngineHitResultStrikethrough; +} + +inline jfieldID JavaLibrary::getFidCombatEngineHitResultStrikethroughAmount() +{ + return ms_fidCombatEngineHitResultStrikethroughAmount; +} + +inline jfieldID JavaLibrary::getFidCombatEngineHitResultEvadeResult() +{ + return ms_fidCombatEngineHitResultEvadeResult; +} + +inline jfieldID JavaLibrary::getFidCombatEngineHitResultEvadeAmount() +{ + return ms_fidCombatEngineHitResultEvadeAmount; +} + +inline jfieldID JavaLibrary::getFidCombatEngineHitResultBlockResult() +{ + return ms_fidCombatEngineHitResultBlockResult; +} + +inline jfieldID JavaLibrary::getFidCombatEngineHitResultBlock() +{ + return ms_fidCombatEngineHitResultBlock; +} + +inline jfieldID JavaLibrary::getFidCombatEngineHitResultDodge() +{ + return ms_fidCombatEngineHitResultDodge; +} + +inline jfieldID JavaLibrary::getFidCombatEngineHitResultParry() +{ + return ms_fidCombatEngineHitResultParry; +} + +inline jfieldID JavaLibrary::getFidCombatEngineHitResultProc() +{ + return ms_fidCombatEngineHitResultProc; +} + +inline jfieldID JavaLibrary::getFidCombatEngineHitResultBlockingArmor() +{ + return ms_fidCombatEngineHitResultBlockingArmor; +} + +inline jclass JavaLibrary::getClsCustomVar() +{ + return ms_clsCustomVar; +} + +inline jmethodID JavaLibrary::getMidCustomVarObjIdStringInt() +{ + return ms_midCustomVarObjIdStringInt; +} + +inline jclass JavaLibrary::getClsDraftSchematic() +{ + return ms_clsDraftSchematic; +} + +inline jclass JavaLibrary::getClsDraftSchematicAttrib() +{ + return ms_clsDraftSchematicAttrib; +} + +inline jfieldID JavaLibrary::getFidDraftSchematicAttribs() +{ + return ms_fidDraftSchematicAttribs; +} + +inline jfieldID JavaLibrary::getFidDraftSchematicAttribMap() +{ + return ms_fidDraftSchematicAttribMap; +} + +inline jfieldID JavaLibrary::getFidDraftSchematicAttribName() +{ + return ms_fidDraftSchematicAttribName; +} + +inline jfieldID JavaLibrary::getFidDraftSchematicAttribCurrentValue() +{ + return ms_fidDraftSchematicAttribCurrentValue; +} + +inline jfieldID JavaLibrary::getFidDraftSchematicAttribResourceMaxValue() +{ + return ms_fidDraftSchematicAttribResourceMaxValue; +} + +inline jfieldID JavaLibrary::getFidDraftSchematicAttribMinValue() +{ + return ms_fidDraftSchematicAttribMinValue; +} + +inline jfieldID JavaLibrary::getFidDraftSchematicAttribMaxValue() +{ + return ms_fidDraftSchematicAttribMaxValue; +} + +inline jfieldID JavaLibrary::getFidDraftSchematicCustomName() +{ + return ms_fidDraftSchematicCustomName; +} + +inline jfieldID JavaLibrary::getFidDraftSchematicCustomValue() +{ + return ms_fidDraftSchematicCustomValue; +} + +inline jfieldID JavaLibrary::getFidDraftSchematicCustomMinValue() +{ + return ms_fidDraftSchematicCustomMinValue; +} + +inline jfieldID JavaLibrary::getFidDraftSchematicCustomMaxValue() +{ + return ms_fidDraftSchematicCustomMaxValue; +} + +inline jfieldID JavaLibrary::getFidDraftSchematicExperimentalAttribs() +{ + return ms_fidDraftSchematicExperimentalAttribs; +} + +inline jclass JavaLibrary::getClsDynamicVariable() +{ + return ms_clsDynamicVariable; +} + +inline jmethodID JavaLibrary::getMidDynamicVariableFloat() +{ + return ms_midDynamicVariableFloat; +} + +inline jmethodID JavaLibrary::getMidDynamicVariableFloatArray() +{ + return ms_midDynamicVariableFloatArray; +} + +inline jmethodID JavaLibrary::getMidDynamicVariableInt() +{ + return ms_midDynamicVariableInt; +} + +inline jmethodID JavaLibrary::getMidDynamicVariableIntArray() +{ + return ms_midDynamicVariableIntArray; +} + +inline jmethodID JavaLibrary::getMidDynamicVariableLocation() +{ + return ms_midDynamicVariableLocation; +} + +inline jmethodID JavaLibrary::getMidDynamicVariableLocationArray() +{ + return ms_midDynamicVariableLocationArray; +} + +inline jmethodID JavaLibrary::getMidDynamicVariableObjId() +{ + return ms_midDynamicVariableObjId; +} + +inline jmethodID JavaLibrary::getMidDynamicVariableObjIdArray() +{ + return ms_midDynamicVariableObjIdArray; +} + +inline jmethodID JavaLibrary::getMidDynamicVariableString() +{ + return ms_midDynamicVariableString; +} + +inline jmethodID JavaLibrary::getMidDynamicVariableStringArray() +{ + return ms_midDynamicVariableStringArray; +} + +inline jclass JavaLibrary::getClsDynamicVariableList() +{ + return ms_clsDynamicVariableList; +} + +inline jmethodID JavaLibrary::getMidDynamicVariableList() +{ + return ms_midDynamicVariableList; +} + +inline jmethodID JavaLibrary::getMidDynamicVariableListSet() +{ + return ms_midDynamicVariableListSet; +} + +inline jmethodID JavaLibrary::getMidDynamicVariableListSetFloat() +{ + return ms_midDynamicVariableListSetFloat; +} + +inline jmethodID JavaLibrary::getMidDynamicVariableListSetFloatArray() +{ + return ms_midDynamicVariableListSetFloatArray; +} + +inline jmethodID JavaLibrary::getMidDynamicVariableListSetInt() +{ + return ms_midDynamicVariableListSetInt; +} + +inline jmethodID JavaLibrary::getMidDynamicVariableListSetIntArray() +{ + return ms_midDynamicVariableListSetIntArray; +} + +inline jmethodID JavaLibrary::getMidDynamicVariableListSetLocation() +{ + return ms_midDynamicVariableListSetLocation; +} + +inline jmethodID JavaLibrary::getMidDynamicVariableListSetLocationArray() +{ + return ms_midDynamicVariableListSetLocationArray; +} + +inline jmethodID JavaLibrary::getMidDynamicVariableListSetObjId() +{ + return ms_midDynamicVariableListSetObjId; +} + +inline jmethodID JavaLibrary::getMidDynamicVariableListSetObjIdArray() +{ + return ms_midDynamicVariableListSetObjIdArray; +} + +inline jmethodID JavaLibrary::getMidDynamicVariableListSetString() +{ + return ms_midDynamicVariableListSetString; +} + +inline jmethodID JavaLibrary::getMidDynamicVariableListSetStringArray() +{ + return ms_midDynamicVariableListSetStringArray; +} + +inline jmethodID JavaLibrary::getMidDynamicVariableListSetStringId() +{ + return ms_midDynamicVariableListSetStringId; +} + +inline jmethodID JavaLibrary::getMidDynamicVariableListSetStringIdArray() +{ + return ms_midDynamicVariableListSetStringIdArray; +} + +inline jmethodID JavaLibrary::getMidDynamicVariableListSetTransform() +{ + return ms_midDynamicVariableListSetTransform; +} + +inline jmethodID JavaLibrary::getMidDynamicVariableListSetTransformArray() +{ + return ms_midDynamicVariableListSetTransformArray; +} + +inline jmethodID JavaLibrary::getMidDynamicVariableListSetVector() +{ + return ms_midDynamicVariableListSetVector; +} + +inline jmethodID JavaLibrary::getMidDynamicVariableListSetVectorArray() +{ + return ms_midDynamicVariableListSetVectorArray; +} + +inline jclass JavaLibrary::getClsBoolean() +{ + return ms_clsBoolean; +} + +inline jmethodID JavaLibrary::getMidBooleanBooleanValue() +{ + return ms_midBooleanBooleanValue; +} + +inline jclass JavaLibrary::getClsDictionary() +{ + return ms_clsDictionary; +} + +inline jmethodID JavaLibrary::getMidDictionary() +{ + return ms_midDictionary; +} + +inline jmethodID JavaLibrary::getMidDictionaryGet() +{ + return ms_midDictionaryGet; +} + +inline jmethodID JavaLibrary::getMidDictionaryKeys() +{ + return ms_midDictionaryKeys; +} + +inline jmethodID JavaLibrary::getMidDictionaryPut() +{ + return ms_midDictionaryPut; +} + +inline jmethodID JavaLibrary::getMidDictionaryPutFloat() +{ + return ms_midDictionaryPutFloat; +} + +inline jmethodID JavaLibrary::getMidDictionaryPutInt() +{ + return ms_midDictionaryPutInt; +} + +inline jmethodID JavaLibrary::getMidEnumerationHasMoreElements() +{ + return ms_midEnumerationHasMoreElements; +} + +inline jmethodID JavaLibrary::getMidEnumerationNextElement() +{ + return ms_midEnumerationNextElement; +} + +inline jclass JavaLibrary::getClsFloat() +{ + return ms_clsFloat; +} + +inline jmethodID JavaLibrary::getMidFloatFloatValue() +{ + return ms_midFloatFloatValue; +} + +inline jclass JavaLibrary::getClsHashtable() +{ + return ms_clsHashtable; +} + +inline jmethodID JavaLibrary::getMidHashtable() +{ + return ms_midHashtable; +} + +inline jclass JavaLibrary::getClsInteger() +{ + return ms_clsInteger; +} + +inline jmethodID JavaLibrary::getMidIntegerIntValue() +{ + return ms_midIntegerIntValue; +} + +inline jclass JavaLibrary::getClsLocation() +{ + return ms_clsLocation; +} + +inline jclass JavaLibrary::getClsLocationArray() +{ + return ms_clsLocationArray; +} + +inline jfieldID JavaLibrary::getFidLocationArea() +{ + return ms_fidLocationArea; +} + +inline jfieldID JavaLibrary::getFidLocationCell() +{ + return ms_fidLocationCell; +} + +inline jfieldID JavaLibrary::getFidLocationX() +{ + return ms_fidLocationX; +} + +inline jfieldID JavaLibrary::getFidLocationY() +{ + return ms_fidLocationY; +} + +inline jfieldID JavaLibrary::getFidLocationZ() +{ + return ms_fidLocationZ; +} + +inline jmethodID JavaLibrary::getMidMapPut() +{ + return ms_midMapPut; +} + +inline jclass JavaLibrary::getClsMapLocation() +{ + return ms_clsMapLocation; +} + +inline jmethodID JavaLibrary::getMidMapLocation() +{ + return ms_midMapLocation; +} + +inline jclass JavaLibrary::getClsMentalState() +{ + return ms_clsMentalState; +} + +inline jmethodID JavaLibrary::getMidMentalState() +{ + return ms_midMentalState; +} + +inline jfieldID JavaLibrary::getFidMentalStateType() +{ + return ms_fidMentalStateType; +} + +inline jfieldID JavaLibrary::getFidMentalStateValue() +{ + return ms_fidMentalStateValue; +} + +inline jmethodID JavaLibrary::getMidObjIdGetValue() +{ + return ms_midObjIdGetValue; +} + +inline jmethodID JavaLibrary::getMidObjIdSetAuthoritative() +{ + return ms_midObjIdSetAuthoritative; +} + +inline jclass JavaLibrary::getClsPalcolorCustomVar() +{ + return ms_clsPalcolorCustomVar; +} + +inline jmethodID JavaLibrary::getMidPalcolorCustomVar() +{ + return ms_midPalcolorCustomVar; +} + +inline jclass JavaLibrary::getClsRangedIntCustomVar() +{ + return ms_clsRangedIntCustomVar; +} + +inline jmethodID JavaLibrary::getMidRangedIntCustomVar() +{ + return ms_midRangedIntCustomVar; +} + +inline jclass JavaLibrary::getClsRegion() +{ + return ms_clsRegion; +} + +inline jclass JavaLibrary::getClsResourceAttribute() +{ + return ms_clsResourceAttribute; +} + +inline jfieldID JavaLibrary::getFidResourceAttributeName() +{ + return ms_fidResourceAttributeName; +} + +inline jfieldID JavaLibrary::getFidResourceAttributeValue() +{ + return ms_fidResourceAttributeValue; +} + +inline jclass JavaLibrary::getClsResourceDensity() +{ + return ms_clsResourceDensity; +} + +inline jfieldID JavaLibrary::getFidResourceDensityDensity() +{ + return ms_fidResourceDensityDensity; +} + +inline jfieldID JavaLibrary::getFidResourceDensityResourceType() +{ + return ms_fidResourceDensityResourceType; +} + +inline jclass JavaLibrary::getClsScriptEntry() +{ + return ms_clsScriptEntry; +} + +inline jmethodID JavaLibrary::getMidScriptEntryGetOwnerContext() +{ + return ms_midScriptEntryGetOwnerContext; +} + +inline jclass JavaLibrary::getClsString() +{ + return ms_clsString; +} + +inline jclass JavaLibrary::getClsStringArray() +{ + return ms_clsStringArray; +} + +inline jclass JavaLibrary::getClsStringId() +{ + return ms_clsStringId; +} + +inline jclass JavaLibrary::getClsStringIdArray() +{ + return ms_clsStringIdArray; +} + +inline jfieldID JavaLibrary::getFidStringIdAsciiId() +{ + return ms_fidStringIdAsciiId; +} + +inline jfieldID JavaLibrary::getFidStringIdTable() +{ + return ms_fidStringIdTable; +} + +inline jclass JavaLibrary::getClsTransform() +{ + return ms_clsTransform; +} + +inline jclass JavaLibrary::getClsTransformArray() +{ + return ms_clsTransformArray; +} + +inline jclass JavaLibrary::getClsVector() +{ + return ms_clsVector; +} + +inline jclass JavaLibrary::getClsVectorArray() +{ + return ms_clsVectorArray; +} + +#endif // _INCLUDED_JavaLibrary_H diff --git a/engine/server/library/serverScript/src/shared/ScriptDictionary.h b/engine/server/library/serverScript/src/shared/ScriptDictionary.h new file mode 100644 index 00000000..5b689226 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptDictionary.h @@ -0,0 +1,67 @@ +//======================================================================== +// +// ScriptDictionary.h - interface class to pass dictionaries around. Must be +// derived by a real class that hold the dictionary data. +// +// copyright 2001 Sony Online Entertainment +// +//======================================================================== + +#ifndef _INCLUDED_ScriptDictionary_H +#define _INCLUDED_ScriptDictionary_H + +#include + + +namespace boost +{ + template class shared_ptr; +} + + +class ScriptDictionary +{ +public: + + virtual ~ScriptDictionary(); + + virtual void serialize(void) = 0; + + const stdvector::fwd & getSerializedData(void) const; + uint32 getCrc(void) const; + +protected: + + ScriptDictionary(void); + + + stdvector::fwd m_serializedData; + uint32 m_crc; + +private: + ScriptDictionary(const ScriptDictionary &); + ScriptDictionary & operator = (const ScriptDictionary &); +}; +typedef boost::shared_ptr ScriptDictionaryPtr; + + +inline ScriptDictionary::ScriptDictionary(void) +{ +} + +inline ScriptDictionary::~ScriptDictionary() +{ +} + +inline const stdvector::fwd & ScriptDictionary::getSerializedData(void) const +{ + return m_serializedData; +} + +inline uint32 ScriptDictionary::getCrc(void) const +{ + return m_crc; +} + + +#endif // _INCLUDED_ScriptDictionary_H diff --git a/engine/server/library/serverScript/src/shared/ScriptFunctionTable.cpp b/engine/server/library/serverScript/src/shared/ScriptFunctionTable.cpp new file mode 100644 index 00000000..2a24c8dd --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptFunctionTable.cpp @@ -0,0 +1,474 @@ +//======================================================================== +// +// ScriptFuncTable.cpp - Default values for initializing the script function list. +// +// copyright 2001 Sony Online Entertainment +// +//======================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/ScriptFunctionTable.h" + + +//======================================================================== +// local constants +//======================================================================== + +// +// values for script parameters: +// b = boolean +// i = integer (4 byte) +// f = float (4 byte) +// s = string (const char *) +// u = unicode string (const uint16 *) +// V = class ValueDictionary +// O = class objId +// S = class stringId +// E = class slotData +// A = class attribMod +// M = class mentalStateMod +// L = class location +// m = class menu_info +// D = class draft_schematic +// I = struct Crafting::IngredientSlot +// U = unsigned char +// [ = previous identifier was an array +// * = previous identifier was the modifiable version of the data (currently int, float, and stringId) +// + +static const Scripting::ScriptFuncTable ScriptFuncList[] = +{ + {Scripting::TRIG_ATTACH, "OnAttach", ""}, + {Scripting::TRIG_DETACH, "OnDetach", ""}, + {Scripting::TRIG_INITIALIZE, "OnInitialize", ""}, + {Scripting::TRIG_SPEAKING, "OnSpeaking", "u"}, + {Scripting::TRIG_HEAR_SPEECH_STRING, "OnHearSpeech", "Ou"}, + {Scripting::TRIG_HEAR_SPEECH_STRINGID, "OnHearSpeech", "OS"}, + {Scripting::TRIG_PERFORM_EMOTE, "OnPerformEmote", "u"}, + {Scripting::TRIG_SAW_EMOTE, "OnSawEmote", "Ou"}, + {Scripting::TRIG_INSPECTED, "OnInspected", "OS"}, + {Scripting::TRIG_LOGOUT, "OnLogout", ""}, + {Scripting::TRIG_LOGIN, "OnLogin", ""}, + {Scripting::TRIG_ITEM_EQUIP, "OnItemEquip", "OE["}, + {Scripting::TRIG_ITEM_UNEQUIP, "OnItemUneqip", "OE["}, + {Scripting::TRIG_TARGET_EQUIPS_ITEM, "OnTargetEquipsItem", "OE["}, + {Scripting::TRIG_TARGET_UNEQUIPS_ITEM, "OnTargetUnequipsItem", "OE["}, + {Scripting::TRIG_ABOUT_TO_RECEIVE_ITEM, "OnAboutToReceiveItem", "OOO"}, + {Scripting::TRIG_RECEIVED_ITEM, "OnReceivedItem", "OOO"}, + {Scripting::TRIG_ABOUT_TO_BE_XFERRED, "OnAboutToBeTransferred","OO"}, + {Scripting::TRIG_XFERRED, "OnTransferred", "OOO"}, + {Scripting::TRIG_ABOUT_TO_LOSE_ITEM, "OnAboutToLoseItem", "OOO"}, + {Scripting::TRIG_LOST_ITEM, "OnLostItem", "OOO"}, + {Scripting::TRIG_LOADED_FROM_DB, "OnLoadedFromDb", ""}, + {Scripting::TRIG_UNLOADED_FROM_MEMORY, "OnUnloadedFromMemory", ""}, + {Scripting::TRIG_DECAY, "OnDecay", ""}, + {Scripting::TRIG_OBJECT_DISABLED, "OnObjectDisabled", "O"}, + {Scripting::TRIG_DESTROY, "OnDestroy", ""}, + {Scripting::TRIG_SERVER_TRANSFER, "OnServerTransfer", ""}, + {Scripting::TRIG_MADE_AUTHORITATIVE, "OnMadeAuthoritative", ""}, + {Scripting::TRIG_ABOUT_TO_BE_INCAPACITATED, "OnAboutToBeIncapacitated", "O"}, + {Scripting::TRIG_INCAPACITATED, "OnIncapacitated", "O"}, + {Scripting::TRIG_RECAPACITATED, "OnRecapacitated", ""}, + {Scripting::TRIG_ABOUT_TO_DIE, "OnAboutToDie", "O"}, + {Scripting::TRIG_DEATH, "OnDeath", "OO"}, + {Scripting::TRIG_ENVIRONMENTAL_DEATH, "OnEnvironmentalDeath", ""}, + {Scripting::TRIG_ENTERED_COMBAT, "OnEnteredCombat", ""}, + {Scripting::TRIG_EXITED_COMBAT, "OnExitedCombat", ""}, + {Scripting::TRIG_DEFENDER_COMBAT_ACTION, "OnDefenderCombatAction","OOi"}, + {Scripting::TRIG_ATTACKER_COMBAT_ACTION, "OnAttackerCombatAction","OO"}, + {Scripting::TRIG_WEAPON_COMBAT_ACTION, "OnWeaponCombatAction", "OO"}, + {Scripting::TRIG_CHANGED_POSTURE, "OnChangedPosture", "ii"}, + {Scripting::TRIG_COMBAT_DAMAGED, "OnCombatDamaged", "OOi"}, + {Scripting::TRIG_CREATURE_DAMAGED, "OnCreatureDamaged", "OOi["}, + {Scripting::TRIG_OBJECT_DAMAGED, "OnObjectDamaged", "OOi"}, + {Scripting::TRIG_INCAPACITATE_TARGET, "OnIncapacitateTarget", "O"}, + {Scripting::TRIG_ADDED_TO_WORLD, "OnAddedToWorld", ""}, + {Scripting::TRIG_REMOVING_FROM_WORLD, "OnRemovingFromWorld", ""}, + {Scripting::TRIG_PRELOAD_COMPLETE, "OnPreloadComplete", ""}, + {Scripting::TRIG_BEHAVIOR_CHANGE, "OnBehaviorChange", "iii["}, + {Scripting::TRIG_TARGET_CHANGE, "OnBehaviorTargetChange", "ii["}, + {Scripting::TRIG_START_NPC_CONVERSATION, "OnStartNpcConversation","O"}, + {Scripting::TRIG_END_NPC_CONVERSATION, "OnEndNpcConversation", "O"}, + {Scripting::TRIG_START_CONVERSATION , "OnStartConversation", "O"}, + {Scripting::TRIG_END_CONVERSATION, "OnEndConversation", "O"}, + {Scripting::TRIG_ARRIVE_AT_LOCATION, "OnArrivedAtLocation", "u"}, + {Scripting::TRIG_NPC_CONVERSATION_RESPONSE, "OnNpcConversationResponse", "sOS"}, + {Scripting::TRIG_COMBAT_TARGETED, "OnTargeted", "O"}, + {Scripting::TRIG_COMBAT_UNTARGETED, "OnUntargeted", "O"}, + {Scripting::TRIG_COMBAT_LOST_TARGET, "OnLostTarget", "O"}, + {Scripting::TRIG_PLAYER_REQUEST_MISSION_BOARD, "OnPlayerRequestMissionBoard", "OOO["}, + {Scripting::TRIG_OUT_OF_AMMO, "OnOutOfAmmo", "O"}, + {Scripting::TRIG_PVP_TYPE_CHANGED, "OnPvpTypeChanged", "ii"}, + {Scripting::TRIG_PVP_FACTION_CHANGED, "OnPvpFactionChanged", "ii"}, + {Scripting::TRIG_CITY_CHANGED, "OnCityChanged", "ii"}, + {Scripting::TRIG_ENTER_SWIMMING, "OnEnterSwimming", ""}, + {Scripting::TRIG_EXIT_SWIMMING, "OnExitSwimming", ""}, + {Scripting::TRIG_PLACE_STRUCTURE, "OnPlaceStructure", "OOLi"}, + {Scripting::TRIG_PURCHASE_TICKET, "OnPurchaseTicket", "Ouuuub"}, + {Scripting::TRIG_PURCHASE_TICKET_INSTANT_TRAVEL, "OnPurchaseTicketInstantTravel", "Ouuuub"}, + {Scripting::TRIG_LOCATION_RECEIVED, "OnLocationReceived", "sOLf"}, + {Scripting::TRIG_GET_ATTRIBS, "OnGetAttributes", "Os*[u*["}, + {Scripting::TRIG_GET_SCRIPTVARS, "OnGetScriptvars", "Os*[u*["}, + {Scripting::TRIG_SOCKET_USED, "OnSocketUsed", "s[i["}, + {Scripting::TRIG_GET_RESPAWN_LOC, "OnGetRespawnLocation", "i*"}, + {Scripting::TRIG_SKILL_ABOUT_TO_BE_GRANTED, "OnSkillAboutToBeGranted", "s"}, + {Scripting::TRIG_SKILL_ABOUT_TO_BE_REVOKED, "OnSkillAboutToBeRevoked", "s"}, + {Scripting::TRIG_SKILL_GRANTED, "OnSkillGranted", "s"}, + {Scripting::TRIG_SKILL_REVOKED, "OnSkillRevoked", "s"}, + {Scripting::TRIG_ATTRIB_MOD_DONE, "OnAttribModDone", "sb"}, + {Scripting::TRIG_SKILL_MOD_DONE, "OnSkillModDone", "sb"}, + {Scripting::TRIG_SKILLMODS_CHANGED, "OnSkillModsChanged", "s[i["}, + {Scripting::TRIG_THEATER_CREATED, "OnTheaterCreated", "O[OO"}, + {Scripting::TRIG_PLAYER_THEATER_FAIL, "OnPlayerTheaterFail", "ss"}, + {Scripting::TRIG_GRANT_SCHEMATIC, "OnGrantedSchematic", "ib"}, + {Scripting::TRIG_REVOKE_SCHEMATIC, "OnRevokedSchematic", "ib"}, + {Scripting::TRIG_DO_STRUCTURE_ROLLUP, "OnDoStructureRollup", "Ob"}, + + //- added when changing to scripting system that verifies triggers + + {Scripting::TRIG_UPLOAD_CHARACTER, "OnUploadCharacter", "V"}, + {Scripting::TRIG_REQUEST_RESOURCE_WEIGHTS, "OnRequestResourceWeights", "Os[s[i[i[i["}, + {Scripting::TRIG_FSQUEST_COMPLETED, "OnForceSensitiveQuestCompleted", "sb"}, + + {Scripting::TRIG_QUEST_COMPLETED, "OnQuestCompleted", "i"}, + {Scripting::TRIG_QUEST_CLEARED, "OnQuestCleared", "i"}, + + + //---------------------------------------------------------------------- + //-- resource harvesting + + {Scripting::TRIG_RESOURCE_HARVESTER_SET_ACTIVE, "OnResourceHarvesterSetActive", "Oi" }, + {Scripting::TRIG_RESOURCE_HARVESTER_REQUEST_STATUS, "OnResourceHarvesterRequestStatus", "O" }, + {Scripting::TRIG_RESOURCE_HARVESTER_REQUEST_RESOURCE_DATA, "OnResourceHarvesterRequestResourceData", "O" }, + + //---------------------------------------------------------------------- + + {Scripting::TRIG_OBJECT_MENU_SELECT, "OnObjectMenuSelect", "Oi" }, + {Scripting::TRIG_OBJECT_MENU_REQUEST, "OnObjectMenuRequest", "Om*" }, + + // combat state triggers + {Scripting::TRIG_GET_STATE_INFO, "GetStateDescription", "S*S*"}, + + //---------------------------------------------------------------------- + //-- Action state triggers + {Scripting::TRIG_WANDER_MOVING, "OnWanderMoving", ""}, + {Scripting::TRIG_WANDER_WAYPOINT, "OnWanderWaypoint", ""}, + {Scripting::TRIG_WANDER_WAITING, "OnWanderWaiting", "f*"}, + {Scripting::TRIG_WANDER_PATH_NOT_FOUND, "OnWanderPathNotFound", ""}, + + {Scripting::TRIG_LOITER_MOVING, "OnLoiterMoving", ""}, + {Scripting::TRIG_LOITER_WAYPOINT, "OnLoiterWaypoint", ""}, + {Scripting::TRIG_LOITER_WAITING, "OnLoiterWaiting", "f*"}, + + {Scripting::TRIG_FOLLOW_TARGET_LOST, "OnFollowTargetLost", "O"}, + {Scripting::TRIG_FOLLOW_WAITING, "OnFollowWaiting", "O"}, + {Scripting::TRIG_FOLLOW_MOVING, "OnFollowMoving", "O"}, + {Scripting::TRIG_FOLLOW_PATH_NOT_FOUND, "OnFollowPathNotFound", "O"}, + + {Scripting::TRIG_FLEE_TARGET_LOST, "OnFleeTargetLost", "O"}, + {Scripting::TRIG_FLEE_WAYPOINT, "OnFleeWaypoint", "O"}, + {Scripting::TRIG_FLEE_PATH_NOT_FOUND, "OnFleePathNotFound", "O"}, + + {Scripting::TRIG_MOVE_PATH_COMPLETE, "OnMovePathComplete", ""}, + {Scripting::TRIG_MOVE_MOVING, "OnMoveMoving", ""}, + {Scripting::TRIG_MOVE_PATH_NOT_FOUND, "OnMovePathNotFound", ""}, + {Scripting::TRIG_MOVE_PATH_BLOCKED, "OnMovePathBlocked", ""}, + + //---------------------------------------------------------------------- + //-- crafting triggers + {Scripting::TRIG_REQUEST_DRAFT_SCHEMATICS, "OnRequestDraftSchematics", "Oi[f["}, + {Scripting::TRIG_CRAFTING_ADD_RESOURCE, "OnCraftingAddResource", "OOIi*["}, + {Scripting::TRIG_MANUFACTURING_SCHEMATIC_CREATION, "OnManufacturingSchematicCreation", "OODi*i*"}, + {Scripting::TRIG_CRAFTING_EXPERIMENT, "OnCraftingExperiment", "OOS[i[ii*i"}, + {Scripting::TRIG_FINALIZE_SCHEMATIC, "OnFinalizeSchematic", "OOD"}, + {Scripting::TRIG_MANUFACTURE_OBJECT, "OnManufactureObject", "OODbb"}, + {Scripting::TRIG_CRAFTING_DONE, "OnCraftingDone", "Osib"}, + {Scripting::TRIG_MAKE_CRAFTED_ITEM, "OnMakeCraftedItem", "ODf"}, + + //----------------------------------------------------------------------- + //-- mission triggers + {Scripting::TRIG_GRANT_MISSION, "OnGrantMission", "O"}, + + //----------------------------------------------------------------------- + //-- monitored creature movement + {Scripting::TRIG_MONITORED_CREATURE_MOVEMENT, "OnMonitoredCreatureMoved", "OLLf"}, + + {Scripting::TRIG_VOLUME_ENTERED, "OnTriggerVolumeEntered", "sO"}, + {Scripting::TRIG_VOLUME_EXITED, "OnTriggerVolumeExited", "sO"}, + + {Scripting::TRIG_ABOUT_TO_OPEN_CONTAINER, "OnAboutToOpenContainer", "O"}, + {Scripting::TRIG_OPENED_CONTAINER, "OnOpenedContainer", "O"}, + {Scripting::TRIG_CLOSED_CONTAINER, "OnClosedContainer", "O"}, + {Scripting::TRIG_SPAWN_HEARTBEAT, "OnSpawnHeartbeat", ""}, + + {Scripting::TRIG_REQUEST_SURVEY, "OnRequestSurvey", "Ou"}, + {Scripting::TRIG_REQUEST_CORESAMPLE, "OnRequestCoreSample", "Ou"}, + + {Scripting::TRIG_PERMISSION_LIST_MODIFY, "OnPermissionListModify", "Ouuu"}, + + {Scripting::TRIG_LOCOMOTION_CHANGED, "OnLocomotionChanged", "ii"}, + + //---------------------------------------------------------------------- + //-- group triggers + {Scripting::TRIG_GROUP_LEADER_CHANGED, "OnGroupLeaderChanged", "OOO"}, + {Scripting::TRIG_REMOVED_FROM_GROUP, "OnRemovedFromGroup", "O"}, + {Scripting::TRIG_GROUP_DISBANDED, "OnGroupDisbanded", "O"}, + {Scripting::TRIG_ADDED_TO_GROUP, "OnAddedToGroup", "O"}, + {Scripting::TRIG_GROUP_FORMED, "OnGroupFormed", "O"}, + {Scripting::TRIG_GROUP_MEMBERS_CHANGED, "OnGroupMembersChanged", "OO[O[O["}, + + {Scripting::TRIG_LOOT_LOTTERY_SELECTED, "OnLootLotterySelected", "OO["}, + + //------------------------------------------------------------------------ + //-- Universe Object triggers + {Scripting::TRIG_UNIVERSE_COMPLETE, "OnUniverseComplete", ""}, + + //------------------------------------------------------------------------ + //-- Auction triggers + {Scripting::TRIG_AUCTION_ITEM, "OnAuctionItem", "Oi*"}, + {Scripting::TRIG_REQUEST_AUCTION_FEE, "OnRequestAuctionFee", "OOObi*"}, + {Scripting::TRIG_QUERY_AUCTIONS, "OnQueryAuctions", "OO"}, + {Scripting::TRIG_MISSION_ENTRIES_CREATED, "OnMissionEntriesCreated", "O"}, + + {Scripting::TRIG_NEWBIE_TUTORIAL_RESPONSE, "OnNewbieTutorialResponse", "s"}, + {Scripting::TRIG_IMMEDIATE_LOGOUT, "OnImmediateLogout", ""}, + {Scripting::TRIG_SAW_ATTACK, "OnSawAttack", "OO["}, + {Scripting::TRIG_GIVE_ITEM, "OnGiveItem", "OO"}, + + {Scripting::TRIG_SURVEY_DATA_RECEIVED, "OnSurveyDataReceived", "f[f[f["}, + + {Scripting::TRIG_APPLY_POWERUP, "OnApplyPowerup", "OO"}, + + {Scripting::TRIG_IMAGE_DESIGN_VALIDATE, "OnImageDesignValidate", "OOOiibssiibs[f[s[i[s"}, + {Scripting::TRIG_IMAGE_DESIGN_COMPLETED, "OnImageDesignCompleted", "OOOiibssiibs[f[s[i[s"}, + {Scripting::TRIG_IMAGE_DESIGN_CANCELED, "OnImageDesignCanceled", ""}, + + //------------------------------------------------------------------------ + //-- Hibernation triggers + + {Scripting::TRIG_HIBERNATE_BEGIN, "OnHibernateBegin", ""}, + {Scripting::TRIG_HIBERNATE_END, "OnHibernateEnd", ""}, + + //------------------------------------------------------------------------ + //-- Waypoint triggers + {Scripting::TRIG_WAYPOINT_CREATED, "OnWaypointCreated", "O"}, + {Scripting::TRIG_WAYPOINT_DESTROYED, "OnWaypointDestroyed", "O"}, + {Scripting::TRIG_WAYPOINT_ON_GET_ATTRIBUTES, "OnWaypointGetAttributes", "OOs*[u*["}, + + //------------------------------------------------------------------------ + //-- Character transfer triggers + {Scripting::TRIG_START_CHARACTER_UPLOAD, "OnStartCharacterUpload", "U*[i*bb"}, + {Scripting::TRIG_RECEIVE_CHARACTER_TRANSFER_STATUS_MESSAGE, "OnReceiveCharacterTransferStatusMessage", "s"}, + {Scripting::TRIG_DOWNLOAD_CHARACTER, "OnDownloadCharacter", "U*["}, + + //------------------------------------------------------------------------ + //-- Stomach update + {Scripting::TRIG_STOMACH_UPDATE, "OnStomachUpdate", ""}, + + //------------------------------------------------------------------------ + //-- Cluster wide data manager + {Scripting::TRIG_RECEIVE_CLUSTER_WIDE_DATA_RESPONSE, "OnClusterWideDataResponse", "ssis[V[i"}, + + //------------------------------------------------------------------------ + //-- Space triggers + {Scripting::TRIG_SHIP_HIT, "OnShipWasHit", "Oibiibfff"}, + {Scripting::TRIG_SHIP_HITTING, "OnShipIsHitting", "Oii"}, + {Scripting::TRIG_SHIP_BEHAVIOR_CHANGED, "OnShipBehaviorChanged", "ii"}, + {Scripting::TRIG_SHIP_COMPONENT_POWER_SUFFICIENT, "OnShipComponentPowerSufficient", "if"}, + {Scripting::TRIG_SHIP_COMPONENT_POWER_INSUFFICIENT, "OnShipComponentPowerInsufficient", "iff"}, + {Scripting::TRIG_FORM_CREATEOBJECT, "OnFormCreateObject", "sfffOs[s["}, + {Scripting::TRIG_FORM_EDITOBJECT, "OnFormEditObject", "Os[s["}, + {Scripting::TRIG_FORM_REQUESTDATA, "OnFormRequestEditObject", "Os["}, + + {Scripting::TRIG_SHIP_COMPONENT_INSTALLING, "OnShipComponentInstalling", "OOi"}, + {Scripting::TRIG_SHIP_COMPONENT_INSTALLED, "OnShipComponentInstalled", "Oi"}, + {Scripting::TRIG_SHIP_COMPONENT_UNINSTALLING, "OnShipComponentUninstalling", "OiO"}, + {Scripting::TRIG_SHIP_COMPONENT_UNINSTALLED, "OnShipComponentUninstalled", "OOiO"}, + + {Scripting::TRIG_SHIP_COMPONENT_ITEM_DROPPED_ON_SLOT, "OnDroppedItemOntoShipComponent", "iOO"}, + {Scripting::TRIG_SHIP_TRY_TO_EQUIP_DROID_CONTROL_DEVICE_IN_SHIP, "OnTryToEquipDroidControlDeviceInShip", "OO"}, + {Scripting::TRIG_SHIP_HIT_BY_LIGHTNING, "OnShipHitByLightning", "if"}, + {Scripting::TRIG_SHIP_HIT_BY_ENVIRONMENT, "OnShipHitByEnvironment", "if"}, + {Scripting::TRIG_SHIP_FIRED_MISSILE, "OnShipFiredMissile", "iiiOOi"}, + {Scripting::TRIG_SHIP_TARGETED_BY_MISSILE, "OnShipTargetedByMissile", "iiiOOi"}, + {Scripting::TRIG_SHIP_FIRED_COUNTERMEASURE, "OnShipFiredCountermeasure", "iO"}, + + {Scripting::TRIG_SPACE_UNIT_MOVE_TO_COMPLETE, "OnSpaceUnitMoveToComplete", ""}, + {Scripting::TRIG_SPACE_UNIT_BEHAVIOR_CHANGED, "OnSpaceUnitBehaviorChanged", "ii"}, + {Scripting::TRIG_SPACE_UNIT_FOLLOW_LOST, "OnSpaceUnitFollowLost", "O"}, + {Scripting::TRIG_SPACE_UNIT_DOCKED, "OnSpaceUnitDocked", "O"}, + {Scripting::TRIG_SPACE_UNIT_UNDOCKED, "OnSpaceUnitUnDocked", "Ob"}, + {Scripting::TRIG_SPACE_UNIT_ENTER_COMBAT, "OnSpaceUnitEnterCombat", "O"}, + {Scripting::TRIG_ABOUT_TO_LAUNCH_TO_SPACE, "OnAboutToLaunchIntoSpace", "OOO[ss"}, + {Scripting::TRIG_SPACE_UNIT_START_UNDOCK, "OnSpaceUnitStartUnDock", "O"}, + {Scripting::TRIG_SPACE_EJECT_PLAYER_FROM_SHIP, "OnSpaceEjectPlayerFromShip", ""}, + {Scripting::TRIG_AI_PRIMARY_WEAPON_EQUIPPED, "OnAiPrimaryWeaponEquipped", "O"}, + {Scripting::TRIG_AI_SECONDARY_WEAPON_EQUIPPED, "OnAiSecondaryWeaponEquipped", "O"}, + {Scripting::TRIG_AI_RETREAT_COMPLETE, "OnAiTetherComplete", ""}, + {Scripting::TRIG_HATE_TARGET_CHANGED, "OnHateTargetChanged", "O"}, + {Scripting::TRIG_HATE_TARGET_ADDED, "OnHateTargetAdded", "O"}, + {Scripting::TRIG_HATE_TARGET_REMOVED, "OnHateTargetRemoved", "O"}, + {Scripting::TRIG_AI_RETREAT_START, "OnAiTetherStart", ""}, + {Scripting::TRIG_INVULNERABLE_CHANGED, "OnInvulnerableChanged", "b"}, + {Scripting::TRIG_AI_COMBAT_FRAME, "OnAiCombatFrame", ""}, + + {Scripting::TRIG_PROGRAM_DROID_COMMANDS, "OnCommitDroidProgramCommands", "Os[O[O["}, + + {Scripting::TRIG_SHIP_INTERNAL_DAMAGE_OVER_TIME_REMOVED, "OnShipInternalDamageOverTimeRemoved", "iff"}, + {Scripting::TRIG_SHIP_DAMAGED_BY_INTERNAL_DAMAGE_OVER_TIME, "OnShipDamagedByInternalDamageOverTime", "ifff"}, + + //---------------------------------------------------------------------- + //-- Chat + {Scripting::TRIG_CHAT_ON_LOGIN, "OnChatLogin", ""}, + + {Scripting::TRIG_CONTAINER_CHILD_GAIN_ITEM, "OnContainerChildGainItem", "OOO"}, + {Scripting::TRIG_CONTAINER_CHILD_LOST_ITEM, "OnContainerChildLostItem", "OOOO"}, + + {Scripting::TRIG_QUEST_ACTIVATED, "OnQuestActivated", "i"}, + + {Scripting::TRIG_CRAFTED_PROTOTYPE, "OnCraftedPrototype", "OD"}, + + {Scripting::TRIG_ENTER_REGION, "OnEnterRegion", "ss"}, + {Scripting::TRIG_EXIT_REGION, "OnExitRegion", "ss"}, + + //---------------------------------------------------------------------- + {Scripting::TRIG_VENDOR_ITEM_COUNT_REPLY, "OnVendorItemCountReply", "ii"}, + {Scripting::TRIG_VENDOR_STATUS_CHANGE, "OnVendorStatusChange", "i"}, + {Scripting::TRIG_PLAYER_VENDOR_COUNT_REPLY, "OnPlayerVendorCountReply", "i"}, + + {Scripting::TRIG_TASK_ACTIVATED, "OnTaskActivated", "ii"}, + {Scripting::TRIG_TASK_COMPLETED, "OnTaskCompleted", "ii"}, + {Scripting::TRIG_TASK_FAILED, "OnTaskFailed", "ii"}, + {Scripting::TRIG_TASK_CLEARED, "OnTaskCleared", "ii"}, + {Scripting::TRIG_BEGIN_WARMUP, "OnBeginWarmup", "siif[sO" }, + + //---------------------------------------------------------------------- + + {Scripting::TRIG_BUILDOUT_OBJECT_REGISTER_WITH_CONTROLLER, "OnBuildoutObjectRegisterWithController", "O"}, + {Scripting::TRIG_CYBERNETIC_CHANGE_REQUEST, "OnCyberneticChangeRequest", "OiO" }, + + {Scripting::TRIG_SOME_TASK_ACTIVATED, "OnSomeTaskActivated", "ii"}, + {Scripting::TRIG_SOME_TASK_COMPLETED, "OnSomeTaskCompleted", "ii"}, + {Scripting::TRIG_SOME_TASK_FAILED, "OnSomeTaskFailed", "ii"}, + {Scripting::TRIG_SOME_TASK_CLEARED, "OnSomeTaskCleared", "ii"}, + + // params: player, ship, station, resource, amount + {Scripting::TRIG_SPACE_MINING_SELL_RESOURCE, "OnSpaceMiningSellResource", "OOOOi"}, + + {Scripting::TRIG_UNSTICKING, "OnUnsticking", ""}, + + {Scripting::TRIG_REQUEST_STATIC_ITEM_DATA, "OnRequestStaticItemData", "s"}, + + //---------------------------------------------------------------------- + //-- Skills + {Scripting::TRIG_SKILL_TEMPLATE_CHANGED, "OnSkillTemplateChanged", "sb"}, + {Scripting::TRIG_WORKING_SKILL_CHANGED, "OnWorkingSkillChanged", "sb"}, + {Scripting::TRIG_COMBAT_LEVEL_CHANGED, "OnCombatLevelChanged", "ii"}, + + {Scripting::TRIG_QUEST_GRANT_REWARD, "OnQuestReceivedReward", "is"}, + + {Scripting::TRIG_GET_STATIC_ITEM_ATTRIBS, "OnGetStaticItemsAttributes", "ss*[u*["}, + + {Scripting::TRIG_HYPERSPACE_TO_HOME_LOCATION, "OnHyperspaceToHomeLocation", ""}, + + //---------------------------------------------------------------------- + //-- CS stuff + {Scripting::TRIG_CS_CREATE_STATIC_ITEM, "OnCSCreateItem", "Os"}, + + {Scripting::TRIG_ON_CUSTOMIZE_FINISHED, "OnCustomizeFinished", "Os"}, + + {Scripting::TRIG_PVP_RANKING_CHANGED, "OnPvpRankingChanged", "ii"}, + + + //----------------------------------------------------------------------- + //-- buff builder + {Scripting::TRIG_BUFF_BUILDER_VALIDATE, "OnBuffBuilderValidate", "OOiiibs[i["}, + {Scripting::TRIG_BUFF_BUILDER_COMPLETED, "OnBuffBuilderCompleted", "OOiiibs[i["}, + {Scripting::TRIG_BUFF_BUILDER_CANCELED, "OnBuffBuilderCanceled", ""}, + + //---------------------------------------------------------------------- + //-- Building packing + {Scripting::TRIG_BUILDING_CONTENTS_LOADED, "OnContentsLoadedForBuildingToBePacked", "O"}, + + //----------------------------------------------------------------------- + //-- incubator + {Scripting::TRIG_INCUBATOR_COMMITTED, "OnIncubatorCommitted", "OOOOOOiiiiiiiiiiiiiii"}, + {Scripting::TRIG_INCUBATOR_CANCELED, "OnIncubatorCancelled","OO"}, + + //----------------------------------------------------------------------- + //-- collection + {Scripting::TRIG_COLLECTION_SLOT_MODIFIED, "OnCollectionSlotModified", "ssssbiiib"}, + {Scripting::TRIG_COLLECTION_SERVER_FIRST, "OnCollectionServerFirst", "sss"}, + + //----------------------------------------------------------------------- + //-- veteran reward + {Scripting::TRIG_CREATE_VETERAN_REWARD, "DoCreateVeteranReward", "s*["}, + + //----------------------------------------------------------------------- + //-- Storyteller location trigger + {Scripting::TRIG_GROUND_TARGET_LOC, "OnGroundTargetLoc", "Oifff"}, + + // Duel Trigger + {Scripting::TRIG_ON_DUEL_REQUEST, "OnDuelRequest","OO"}, + {Scripting::TRIG_ON_DUEL_START, "OnDuelStart", "OO"}, + + {Scripting::TRIG_ON_ABOUT_TO_CHANGE_APPEARANCE, "OnAboutToChangeAppearance","Os"}, + {Scripting::TRIG_ON_ABOUT_TO_REVERT_APPEARANCE, "OnAboutToRevertAppearance","O"}, + + // Group pickup point travel + {Scripting::TRIG_ABOUT_TO_TRAVEL_TO_GROUP_PICKUP_POINT, "OnAboutToTravelToGroupPickupPoint", ""}, + {Scripting::TRIG_TRAVEL_TO_GROUP_PICKUP_POINT, "OnTravelToGroupPickupPoint", "ss"}, + + {Scripting::TRIG_CHANGED_APPEARANCE, "OnChangedAppearance", "O"}, + {Scripting::TRIG_REVERTED_APPEARANCE, "OnRevertedAppearance", "O"}, + + {Scripting::TRIG_ON_DYNAMIC_SPAWN_REGION_CREATED, "OnDynamicSpawnRegionCreated", "Osfff"}, + + {Scripting::TRIG_DO_RESTORE_ITEM_DECORATION_LAYOUT, "DoRestoreItemDecorationLayout", "OOLbffff"}, + {Scripting::TRIG_DO_RESTORE_ITEM_DECORATION_LAYOUT_ROTATION_ONLY, "DoRestoreItemDecorationLayoutRotationOnly", "Offff"}, + + {Scripting::TRIG_ON_RATING_FINISHED, "OnRatingFinished", "i"}, + {Scripting::TRIG_ON_ABANDON_PLAYER_QUEST, "OnAbandonPlayerQuest", "O"}, + + {Scripting::TRIG_ON_GCW_SCORE_CATEGORY_PERCENTILE_CHANGE, "OnGcwScoreCategoryPercentileChange", "sii"}, + +//-- finish it up + + {Scripting::TRIG_LAST_TRIGGER, NULL, NULL} +}; + +const int NUM_SCRIPT_FUNCTIONS = sizeof(ScriptFuncList) / sizeof(ScriptFuncList[0]) - 1; + + +//======================================================================== +// globals +//======================================================================== + +Scripting::_ScriptFuncHashMap *Scripting::ScriptFuncHashMap = NULL; + + +//======================================================================== +// initialize the ScriptFuncHashMap +//======================================================================== + +/** + * Initialize the ScriptFuncHashMap + */ +void Scripting::InitScriptFuncHashMap(void) +{ + Scripting::ScriptFuncHashMap = new Scripting::_ScriptFuncHashMap(NUM_SCRIPT_FUNCTIONS); + + for (int i = 0; i < NUM_SCRIPT_FUNCTIONS; ++i) + IGNORE_RETURN(Scripting::ScriptFuncHashMap->insert(std::make_pair(static_cast(ScriptFuncList[i].id), &ScriptFuncList[i]))); +} // InitScriptFuncHashMap + +/** + * Cleans up memory. + */ +void Scripting::RemoveScriptFuncHashMap(void) +{ + if (Scripting::ScriptFuncHashMap) + delete Scripting::ScriptFuncHashMap; + Scripting::ScriptFuncHashMap = NULL; +} + diff --git a/engine/server/library/serverScript/src/shared/ScriptFunctionTable.h b/engine/server/library/serverScript/src/shared/ScriptFunctionTable.h new file mode 100644 index 00000000..3b47c932 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptFunctionTable.h @@ -0,0 +1,505 @@ +//======================================================================== +// +// ScriptFuncTable.h - Default values for initializing the script function list. +// +// copyright 2001 Sony Online Entertainment +// +//======================================================================== + +#ifndef _INCLUDED_ScriptFuncTable_H +#define _INCLUDED_ScriptFuncTable_H + +#include + +namespace Scripting +{ + + /* This is the id list for supported trigger types. + * ================================================================= + * When you add to this list, make sure you enter your trigger in + * ScriptFunctionTable.cpp + * base_class.java + * base_script.script + * ================================================================= + * When you add to this list, make sure you enter your trigger in + * ScriptFunctionTable.cpp + * base_class.java + * base_script.script + * ================================================================= + * When you add to this list, make sure you enter your trigger in + * ScriptFunctionTable.cpp + * base_class.java + * base_script.script + * ================================================================= + * When you add to this list, make sure you enter your trigger in + * ScriptFunctionTable.cpp + * base_class.java + * base_script.script + * ================================================================= + * When you add to this list, make sure you enter your trigger in + * ScriptFunctionTable.cpp + * base_class.java + * base_script.script + * ================================================================= + * When you add to this list, make sure you enter your trigger in + * ScriptFunctionTable.cpp + * base_class.java + * base_script.script + * ================================================================= + * When you add to this list, make sure you enter your trigger in + * ScriptFunctionTable.cpp + * base_class.java + * base_script.script + * ================================================================= + * When you add to this list, make sure you enter your trigger in + * ScriptFunctionTable.cpp + * base_class.java + * base_script.script + * ================================================================= + * When you add to this list, make sure you enter your trigger in + * ScriptFunctionTable.cpp + * base_class.java + * base_script.script + * ================================================================= + * When you add to this list, make sure you enter your trigger in + * ScriptFunctionTable.cpp + * base_class.java + * base_script.script + * ================================================================= + * When you add to this list, make sure you enter your trigger in + * ScriptFunctionTable.cpp + * base_class.java + * base_script.script + * ================================================================= + * When you add to this list, make sure you enter your trigger in + * ScriptFunctionTable.cpp + * base_class.java + * base_script.script + * ================================================================= + * When you add to this list, make sure you enter your trigger in + * ScriptFunctionTable.cpp + * base_class.java + * base_script.script + * ================================================================= + * When you add to this list, make sure you enter your trigger in + * ScriptFunctionTable.cpp + * base_class.java + * base_script.script + * ================================================================= + * When you add to this list, make sure you enter your trigger in + * ScriptFunctionTable.cpp + * base_class.java + * base_script.script + * ================================================================= + * When you add to this list, make sure you enter your trigger in + * ScriptFunctionTable.cpp + * base_class.java + * base_script.script + * ================================================================= + * When you add to this list, make sure you enter your trigger in + * ScriptFunctionTable.cpp + * base_class.java + * base_script.script + * ================================================================= + * When you add to this list, make sure you enter your trigger in + * ScriptFunctionTable.cpp + * base_class.java + * base_script.script + * ================================================================= + * When you add to this list, make sure you enter your trigger in + * ScriptFunctionTable.cpp + * base_class.java + * base_script.script + * ================================================================= + * When you add to this list, make sure you enter your trigger in + * ScriptFunctionTable.cpp + * base_class.java + * base_script.script + * ================================================================= + * When you add to this list, make sure you enter your trigger in + * ScriptFunctionTable.cpp + * base_class.java + * base_script.script + * ================================================================= + * When you add to this list, make sure you enter your trigger in + * ScriptFunctionTable.cpp + * base_class.java + * base_script.script + * ================================================================= + * When you add to this list, make sure you enter your trigger in + * ScriptFunctionTable.cpp + * base_class.java + * base_script.script + * ================================================================= + * When you add to this list, make sure you enter your trigger in + * ScriptFunctionTable.cpp + * base_class.java + * base_script.script + * ================================================================= + * When you add to this list, make sure you enter your trigger in + * ScriptFunctionTable.cpp + * base_class.java + * base_script.script + * ================================================================= + * When you add to this list, make sure you enter your trigger in + * ScriptFunctionTable.cpp + * base_class.java + * base_script.script + * ================================================================= + * When you add to this list, make sure you enter your trigger in + * ScriptFunctionTable.cpp + * base_class.java + * base_script.script + * ================================================================= + * When you add to this list, make sure you enter your trigger in + * ScriptFunctionTable.cpp + * base_class.java + * base_script.script + * ================================================================= + * When you add to this list, make sure you enter your trigger in + * ScriptFunctionTable.cpp + * base_class.java + * base_script.script + * ================================================================= + * When you add to this list, make sure you enter your trigger in + * ScriptFunctionTable.cpp + * base_class.java + * base_script.script + * ================================================================= + * When you add to this list, make sure you enter your trigger in + * ScriptFunctionTable.cpp + * base_class.java + * base_script.script + * ================================================================= + * When you add to this list, make sure you enter your trigger in + * ScriptFunctionTable.cpp + * base_class.java + * base_script.script + * ================================================================= + * When you add to this list, make sure you enter your trigger in + * ScriptFunctionTable.cpp + * base_class.java + * base_script.script + * ================================================================= + * When you add to this list, make sure you enter your trigger in + * ScriptFunctionTable.cpp + * base_class.java + * base_script.script + * ================================================================= + * When you add to this list, make sure you enter your trigger in + * ScriptFunctionTable.cpp + * base_class.java + * base_script.script + * ================================================================= + * When you add to this list, make sure you enter your trigger in + * ScriptFunctionTable.cpp + * base_class.java + * base_script.script + * ================================================================= + * I MEAN IT! + */ +enum TrigId +{ + TRIG_ATTACH = 0, + TRIG_DETACH = 1, + TRIG_SPEAKING = 2, + TRIG_HEAR_SPEECH_STRING = 3, + TRIG_HEAR_SPEECH_STRINGID = 4, + TRIG_INSPECTED = 5, + TRIG_LOGOUT = 6, + TRIG_LOGIN = 7, + TRIG_ITEM_EQUIP = 8, + TRIG_ITEM_UNEQUIP = 9, + TRIG_TARGET_EQUIPS_ITEM = 10, + TRIG_TARGET_UNEQUIPS_ITEM = 11, + TRIG_ABOUT_TO_RECEIVE_ITEM = 12, + TRIG_RECEIVED_ITEM = 13, + TRIG_ABOUT_TO_BE_XFERRED = 14, + TRIG_XFERRED = 15, + TRIG_ABOUT_TO_LOSE_ITEM = 16, + TRIG_LOST_ITEM = 17, + TRIG_LOADED_FROM_DB = 18, + TRIG_UNLOADED_FROM_MEMORY = 19, + TRIG_DECAY = 20, + TRIG_DESTROY = 21, + TRIG_SERVER_TRANSFER = 22, + TRIG_MADE_AUTHORITATIVE = 23, + TRIG_INCAPACITATED = 24, + TRIG_ABOUT_TO_DIE = 25, + TRIG_DEATH = 26, +// TRIG_COMBAT_LOOP = 27, + TRIG_DEFENDER_COMBAT_ACTION = 28, + TRIG_ATTACKER_COMBAT_ACTION = 29, + TRIG_WEAPON_COMBAT_ACTION = 30, +// TRIG_WAS_HIT = 31, + TRIG_INCAPACITATE_TARGET = 32, +// TRIG_SAW_INCAPACITATION = 33, +// TRIG_SAW_DEATH = 34, +// TRIG_SAW_ATTACK = 35, + //TRIG_FUMBLE = 36, + TRIG_ADDED_TO_WORLD = 37, + TRIG_REMOVING_FROM_WORLD = 38, + TRIG_PRELOAD_COMPLETE = 39, + //TRIG_REPATH_COMPLETE = 40, + TRIG_GET_STATE_INFO = 41, + TRIG_BEHAVIOR_CHANGE = 46, + //TRIG_PATH_COMPLETE = 47, + //TRIG_TARGET_LOST = 48, + TRIG_START_NPC_CONVERSATION = 49, + TRIG_END_NPC_CONVERSATION = 50, + TRIG_NPC_CONVERSATION_RESPONSE = 51, + TRIG_TARGET_CHANGE = 52, + TRIG_RESOURCE_HARVESTER_SET_ACTIVE = 53, + TRIG_RESOURCE_HARVESTER_REQUEST_STATUS = 54, + TRIG_RESOURCE_HARVESTER_REQUEST_RESOURCE_DATA = 55, + TRIG_OBJECT_MENU_SELECT = 56, + TRIG_OBJECT_MENU_REQUEST = 57, +// TRIG_MY_WEAPON_IS_MISSING = 58, +// TRIG_COMBAT_QUEUE_EMPTIED = 59, +// TRIG_WAS_MISSED = 60, +// TRIG_IS_MISSING = 61, + TRIG_RECAPACITATED = 62, + TRIG_WANDER_MOVING = 63, + TRIG_WANDER_WAYPOINT = 64, + TRIG_WANDER_WAITING = 65, + TRIG_WANDER_PATH_NOT_FOUND = 66, + TRIG_LOITER_MOVING = 67, + TRIG_LOITER_WAYPOINT = 68, + TRIG_LOITER_WAITING = 69, + TRIG_FOLLOW_TARGET_LOST = 75, + TRIG_FOLLOW_WAITING = 76, + TRIG_FOLLOW_MOVING = 77, + TRIG_FOLLOW_PATH_NOT_FOUND = 79, + TRIG_FLEE_TARGET_LOST = 80, + TRIG_FLEE_WAYPOINT = 81, + TRIG_FLEE_PATH_NOT_FOUND = 48, + TRIG_MOVE_PATH_COMPLETE = 47, + TRIG_MOVE_MOVING = 40, + TRIG_MOVE_PATH_NOT_FOUND = 36, + TRIG_INITIALIZE = 82, + TRIG_REQUEST_DRAFT_SCHEMATICS = 83, + TRIG_MANUFACTURING_SCHEMATIC_CREATION = 84, + TRIG_CRAFTING_EXPERIMENT = 85, + TRIG_MANUFACTURE_OBJECT = 86, + TRIG_CRAFTING_DONE = 87, + TRIG_ARRIVE_AT_LOCATION = 88, +// TRIG_EXITED_LOCATION = 89, + TRIG_GRANT_MISSION = 90, + TRIG_COMBAT_TARGETED = 91, + TRIG_COMBAT_UNTARGETED = 92, + TRIG_PLAYER_REQUEST_MISSION_BOARD = 93, + TRIG_CRAFTING_ADD_RESOURCE = 94, + TRIG_MONITORED_CREATURE_MOVEMENT = 96, + TRIG_OUT_OF_AMMO = 97, + TRIG_OBJECT_DISABLED = 98, + TRIG_VOLUME_ENTERED = 99, + TRIG_VOLUME_EXITED = 100, + TRIG_MODIFY_WEAPON_DAMAGE = 102, + TRIG_ENTERED_COMBAT = 103, + TRIG_EXITED_COMBAT = 104, + TRIG_CHANGED_POSTURE = 105, + TRIG_COMBAT_DAMAGED = 106, + TRIG_COMBAT_LOST_TARGET = 107, + TRIG_SAW_EMOTE = 108, + TRIG_OPENED_CONTAINER = 110, + TRIG_CLOSED_CONTAINER = 111, + TRIG_SPAWN_HEARTBEAT = 112, + TRIG_PVP_TYPE_CHANGED = 113, + TRIG_PVP_FACTION_CHANGED = 114, + TRIG_CITY_CHANGED = 115, + TRIG_ENTER_SWIMMING = 116, + TRIG_EXIT_SWIMMING = 117, + TRIG_PLACE_STRUCTURE = 118, + TRIG_ABOUT_TO_OPEN_CONTAINER = 119, + TRIG_REQUEST_SURVEY = 120, + TRIG_PERMISSION_LIST_MODIFY = 121, + TRIG_PURCHASE_TICKET = 122, + TRIG_GROUP_LEADER_CHANGED = 123, + TRIG_REMOVED_FROM_GROUP = 124, + TRIG_GROUP_DISBANDED = 125, + TRIG_ADDED_TO_GROUP = 126, + TRIG_GROUP_FORMED = 127, + TRIG_GET_ATTRIBS = 128, + TRIG_REQUEST_CORESAMPLE = 129, + TRIG_UNIVERSE_COMPLETE = 130, + TRIG_AUCTION_ITEM = 131, + TRIG_MISSION_ENTRIES_CREATED = 132, + TRIG_NEWBIE_TUTORIAL_RESPONSE = 133, + TRIG_IMMEDIATE_LOGOUT = 134, + TRIG_CREATURE_DAMAGED = 135, + TRIG_OBJECT_DAMAGED = 136, + TRIG_SAW_ATTACK = 137, + TRIG_GIVE_ITEM = 138, + TRIG_SURVEY_DATA_RECEIVED = 139, + TRIG_APPLY_POWERUP = 140, + TRIG_IMAGE_DESIGN_VALIDATE = 141, + TRIG_IMAGE_DESIGN_COMPLETED = 142, + TRIG_HIBERNATE_BEGIN = 143, + TRIG_HIBERNATE_END = 144, + TRIG_SOCKET_USED = 145, + TRIG_QUERY_AUCTIONS = 146, + TRIG_REQUEST_AUCTION_FEE = 147, +// TRIG_IMAGE_DESIGN_REQUESTCONSENT = 148, + TRIG_GET_RESPAWN_LOC = 149, + TRIG_WAYPOINT_CREATED = 150, + TRIG_WAYPOINT_DESTROYED = 151, + TRIG_WAYPOINT_ON_GET_ATTRIBUTES = 152, + TRIG_FINALIZE_SCHEMATIC = 153, + TRIG_SKILL_GRANTED = 154, + TRIG_SKILL_REVOKED = 155, + TRIG_MAKE_CRAFTED_ITEM = 156, + TRIG_START_CHARACTER_UPLOAD = 157, + TRIG_RECEIVE_CHARACTER_TRANSFER_STATUS_MESSAGE = 158, + TRIG_LOCATION_RECEIVED = 159, + TRIG_ATTRIB_MOD_DONE = 160, + TRIG_SKILL_MOD_DONE = 161, + TRIG_STOMACH_UPDATE = 162, + TRIG_RECEIVE_CLUSTER_WIDE_DATA_RESPONSE = 163, + TRIG_IMAGE_DESIGN_CANCELED = 164, + TRIG_DOWNLOAD_CHARACTER = 165, + TRIG_PERFORM_EMOTE = 166, + TRIG_CHAT_ON_LOGIN = 167, + TRIG_ABOUT_TO_BE_INCAPACITATED = 168, + TRIG_SKILL_ABOUT_TO_BE_GRANTED = 169, + TRIG_SKILL_ABOUT_TO_BE_REVOKED = 170, + TRIG_CONTAINER_CHILD_GAIN_ITEM = 171, + TRIG_CONTAINER_CHILD_LOST_ITEM = 172, + TRIG_QUEST_ACTIVATED = 173, + TRIG_CRAFTED_PROTOTYPE = 174, + TRIG_THEATER_CREATED = 175, + TRIG_ENTER_REGION = 176, + TRIG_EXIT_REGION = 177, + TRIG_VENDOR_ITEM_COUNT_REPLY = 178, + TRIG_VENDOR_STATUS_CHANGE = 179, + TRIG_PLAYER_THEATER_FAIL = 180, + TRIG_GRANT_SCHEMATIC = 181, + TRIG_REVOKE_SCHEMATIC = 182, + TRIG_PLAYER_VENDOR_COUNT_REPLY = 183, + TRIG_SHIP_HIT = 200, + TRIG_SHIP_HITTING = 201, + TRIG_SHIP_BEHAVIOR_CHANGED = 202, + TRIG_SHIP_COMPONENT_POWER_SUFFICIENT = 203, + TRIG_SHIP_COMPONENT_POWER_INSUFFICIENT = 204, + TRIG_FORM_CREATEOBJECT = 205, + TRIG_FORM_EDITOBJECT = 206, + TRIG_FORM_REQUESTDATA = 207, + TRIG_SHIP_COMPONENT_INSTALLING = 208, + TRIG_SHIP_COMPONENT_INSTALLED = 209, + TRIG_SHIP_COMPONENT_UNINSTALLING = 210, + TRIG_SHIP_COMPONENT_UNINSTALLED = 211, + TRIG_SHIP_COMPONENT_ITEM_DROPPED_ON_SLOT = 212, + TRIG_SHIP_TRY_TO_EQUIP_DROID_CONTROL_DEVICE_IN_SHIP = 213, + TRIG_SHIP_HIT_BY_LIGHTNING = 214, + TRIG_SHIP_HIT_BY_ENVIRONMENT = 215, + TRIG_SHIP_FIRED_MISSILE = 216, + TRIG_SHIP_TARGETED_BY_MISSILE = 217, + TRIG_SHIP_FIRED_COUNTERMEASURE = 218, + TRIG_SPACE_UNIT_MOVE_TO_COMPLETE = 219, + TRIG_SPACE_UNIT_BEHAVIOR_CHANGED = 220, + TRIG_SPACE_UNIT_FOLLOW_LOST = 221, + TRIG_SHIP_INTERNAL_DAMAGE_OVER_TIME_REMOVED = 222, + TRIG_SHIP_DAMAGED_BY_INTERNAL_DAMAGE_OVER_TIME = 223, + TRIG_SPACE_UNIT_DOCKED = 224, + TRIG_SPACE_UNIT_UNDOCKED = 225, + TRIG_SPACE_UNIT_ENTER_COMBAT = 226, + TRIG_ABOUT_TO_LAUNCH_TO_SPACE = 227, + TRIG_SPACE_UNIT_START_UNDOCK = 228, + TRIG_SPACE_EJECT_PLAYER_FROM_SHIP = 229, + TRIG_TASK_ACTIVATED = 230, + TRIG_TASK_COMPLETED = 231, + TRIG_TASK_FAILED = 232, + TRIG_TASK_CLEARED = 233, + TRIG_PROGRAM_DROID_COMMANDS = 234, + TRIG_START_CONVERSATION = 235, + TRIG_END_CONVERSATION = 236, + TRIG_BEGIN_WARMUP = 237, + TRIG_LOOT_LOTTERY_SELECTED = 238, + TRIG_AI_PRIMARY_WEAPON_EQUIPPED = 239, + TRIG_AI_SECONDARY_WEAPON_EQUIPPED = 240, + TRIG_BUILDOUT_OBJECT_REGISTER_WITH_CONTROLLER = 241, + TRIG_CYBERNETIC_CHANGE_REQUEST = 242, + TRIG_SOME_TASK_ACTIVATED = 243, + TRIG_SOME_TASK_COMPLETED = 244, + TRIG_SOME_TASK_FAILED = 245, + TRIG_SOME_TASK_CLEARED = 246, + TRIG_SPACE_MINING_SELL_RESOURCE = 247, + TRIG_AI_RETREAT_COMPLETE = 248, + TRIG_HATE_TARGET_CHANGED = 249, + TRIG_HATE_TARGET_ADDED = 250, + TRIG_HATE_TARGET_REMOVED = 251, + TRIG_AI_RETREAT_START = 252, + TRIG_DO_STRUCTURE_ROLLUP = 253, + TRIG_GET_SCRIPTVARS = 254, + //TRIG_DEFAULT_ATTACK = 255, + TRIG_INVULNERABLE_CHANGED = 256, + TRIG_UNSTICKING = 257, + TRIG_AI_COMBAT_FRAME = 258, + TRIG_UPLOAD_CHARACTER = 259, + TRIG_REQUEST_RESOURCE_WEIGHTS = 260, + TRIG_FSQUEST_COMPLETED = 261, + TRIG_MOVE_PATH_BLOCKED = 262, + TRIG_QUEST_COMPLETED = 263, + TRIG_QUEST_CLEARED = 264, + TRIG_GROUP_MEMBERS_CHANGED= 265, + TRIG_ENVIRONMENTAL_DEATH=266, + TRIG_LOCOMOTION_CHANGED= 267, + TRIG_REQUEST_STATIC_ITEM_DATA = 268, + TRIG_SKILL_TEMPLATE_CHANGED = 269, + TRIG_WORKING_SKILL_CHANGED = 270, + TRIG_COMBAT_LEVEL_CHANGED = 271, + TRIG_QUEST_GRANT_REWARD = 272, + TRIG_SKILLMODS_CHANGED = 273, + TRIG_GET_STATIC_ITEM_ATTRIBS = 274, + TRIG_PURCHASE_TICKET_INSTANT_TRAVEL = 275, + TRIG_HYPERSPACE_TO_HOME_LOCATION = 276, + TRIG_CS_CREATE_STATIC_ITEM = 277, + TRIG_ON_CUSTOMIZE_FINISHED = 278, + TRIG_PVP_RANKING_CHANGED = 279, + TRIG_BUFF_BUILDER_VALIDATE = 280, + TRIG_BUFF_BUILDER_COMPLETED = 281, + TRIG_BUFF_BUILDER_CANCELED = 282, + TRIG_BUILDING_CONTENTS_LOADED = 283, + TRIG_INCUBATOR_COMMITTED = 284, + TRIG_INCUBATOR_CANCELED = 285, + TRIG_COLLECTION_SLOT_MODIFIED = 286, + TRIG_COLLECTION_SERVER_FIRST = 287, + TRIG_CREATE_VETERAN_REWARD = 288, + TRIG_GROUND_TARGET_LOC = 289, + TRIG_ON_DUEL_REQUEST = 290, + TRIG_ON_DUEL_START = 291, + TRIG_ON_ABOUT_TO_CHANGE_APPEARANCE = 292, + TRIG_ON_ABOUT_TO_REVERT_APPEARANCE = 293, + TRIG_ABOUT_TO_TRAVEL_TO_GROUP_PICKUP_POINT = 294, + TRIG_TRAVEL_TO_GROUP_PICKUP_POINT = 295, + TRIG_CHANGED_APPEARANCE = 296, + TRIG_REVERTED_APPEARANCE = 297, + TRIG_ON_DYNAMIC_SPAWN_REGION_CREATED = 298, + TRIG_DO_RESTORE_ITEM_DECORATION_LAYOUT = 299, + TRIG_DO_RESTORE_ITEM_DECORATION_LAYOUT_ROTATION_ONLY = 300, + TRIG_ON_RATING_FINISHED = 301, + TRIG_ON_ABANDON_PLAYER_QUEST = 302, + TRIG_ON_GCW_SCORE_CATEGORY_PERCENTILE_CHANGE = 303, + TRIG_LAST_TRIGGER +}; + +// This is a sample object for describing the specifics of a supported trigger. +// It contains the Trigger id, the name of the function to be invoked for that +// trigger, and the argument type list. Argument types are described using the +// Python specification without the return type. All triggers are assumed to +// return an int indicating stop or continue. e.g. "is" would specify that the +// function took an integer for the first parameter, and a string for the second. +struct ScriptFuncTable +{ + TrigId id; + const char *name; + const char *argList; +}; + +typedef std::hash_map< int, const ScriptFuncTable * > _ScriptFuncHashMap; +extern _ScriptFuncHashMap *ScriptFuncHashMap; +extern void InitScriptFuncHashMap(void); +extern void RemoveScriptFuncHashMap(void); + +} + +#endif // _INCLUDED_ScriptFuncTable_H diff --git a/engine/server/library/serverScript/src/shared/ScriptListEntry.cpp b/engine/server/library/serverScript/src/shared/ScriptListEntry.cpp new file mode 100644 index 00000000..1f55096a --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptListEntry.cpp @@ -0,0 +1,38 @@ +// ====================================================================== +// +// ScriptListEntry.cpp +// +// Copyright 2003 Sony Online Entertainment +// +// ====================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/ScriptListEntry.h" +#include "serverScript/GameScriptObject.h" + +// ====================================================================== + +std::string const &ScriptListEntry::getScriptName() const +{ +static const std::string emptyString; + + if (m_data != NULL) + return m_data->first; + WARNING_STRICT_FATAL(true, ("ScriptListEntry::getScriptName called with m_data = NULL")); + return emptyString; +} + +// ---------------------------------------------------------------------- + +ScriptData &ScriptListEntry::getScriptData() const +{ +static ScriptData emptyData; + + if (m_data != NULL) + return m_data->second; + WARNING_STRICT_FATAL(true, ("ScriptListEntry::getScriptData called with m_data = NULL")); + return emptyData; +} + +// ====================================================================== + diff --git a/engine/server/library/serverScript/src/shared/ScriptListEntry.h b/engine/server/library/serverScript/src/shared/ScriptListEntry.h new file mode 100644 index 00000000..1d5e8f66 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptListEntry.h @@ -0,0 +1,62 @@ +// ====================================================================== +// +// ScriptListEntry.h +// +// Copyright 2003 Sony Online Entertainment +// +// ====================================================================== + +#ifndef _ScriptListEntry_H_ +#define _ScriptListEntry_H_ + +// ====================================================================== + +struct ScriptData; + +// ====================================================================== + +class ScriptListEntry +{ +public: + ScriptListEntry(); + ScriptListEntry(std::pair * data); + bool operator==(ScriptListEntry const &rhs) const; + bool isValid() const; + std::string const &getScriptName() const; + ScriptData &getScriptData() const; +private: + std::pair *m_data; +}; + +// ---------------------------------------------------------------------- + +inline ScriptListEntry::ScriptListEntry() : + m_data(0) +{ +} + +// ---------------------------------------------------------------------- + +inline ScriptListEntry::ScriptListEntry(std::pair * data) : + m_data(data) +{ +} + +// ---------------------------------------------------------------------- + +inline bool ScriptListEntry::operator==(ScriptListEntry const &rhs) const +{ + return m_data == rhs.m_data; +} + +// ---------------------------------------------------------------------- + +inline bool ScriptListEntry::isValid() const +{ + return m_data != NULL; +} + +// ====================================================================== + +#endif // _ScriptListEntry_H_ + diff --git a/engine/server/library/serverScript/src/shared/ScriptMessage.cpp b/engine/server/library/serverScript/src/shared/ScriptMessage.cpp new file mode 100644 index 00000000..9a6bec59 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMessage.cpp @@ -0,0 +1,48 @@ +// ScriptMessage.cpp +// copyright 2001 Sony Online Entertainment +// Author: Justin Randall + +//----------------------------------------------------------------------- +#include "serverScript/FirstServerScript.h" +#include "serverScript/ScriptMessage.h" +#include "serverScript/ScriptDictionary.h" + + +//----------------------------------------------------------------------- + +ScriptMessage::ScriptMessage(const std::string & sourceScriptName, const std::string & scriptFunctionName, const ScriptDictionary & parameters) : +MessageBase(scriptFunctionName.c_str()), +m_parameters(parameters), +m_scriptFunctionName(scriptFunctionName), +m_sourceScriptName(sourceScriptName) +{ +} + +//----------------------------------------------------------------------- + +ScriptMessage::ScriptMessage(const ScriptMessage & source) : +MessageBase(source.getType()), +m_parameters(source.getParameters()), + m_scriptFunctionName(source.getScriptFunctionName()) +{ +} + +//----------------------------------------------------------------------- + +ScriptMessage::~ScriptMessage() +{ +} + +//----------------------------------------------------------------------- + +ScriptMessage & ScriptMessage::operator = (const ScriptMessage & rhs) +{ + if(this != &rhs) + { + // make assignments if right hand side is not this instance + } + return *this; +} + +//----------------------------------------------------------------------- + diff --git a/engine/server/library/serverScript/src/shared/ScriptMessage.h b/engine/server/library/serverScript/src/shared/ScriptMessage.h new file mode 100644 index 00000000..6f9782c1 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMessage.h @@ -0,0 +1,63 @@ +// ScriptMessage.h +// copyright 2001 Sony Online Entertainment +// Author: Justin Randall + +#ifndef _INCLUDED_ScriptMessage_H +#define _INCLUDED_ScriptMessage_H + +//----------------------------------------------------------------------- + +#include "sharedMessageDispatch/Message.h" +#include + +class ScriptParams; +class ScriptDictionary; + + +//----------------------------------------------------------------------- + +class ScriptMessage : public MessageDispatch::MessageBase +{ +public: + ScriptMessage (const std::string & sourceScript, const std::string & scriptFunctionName, const ScriptDictionary & parameters); + ~ScriptMessage (); + + const ScriptDictionary & getParameters () const; + const std::string & getScriptFunctionName () const; + const std::string & getSourceScriptName () const; + +private: + ScriptMessage & operator = (const ScriptMessage & rhs); + ScriptMessage (const ScriptMessage & source); + ScriptMessage(); + +private: + const ScriptDictionary & m_parameters; + const std::string m_scriptFunctionName; + const std::string m_sourceScriptName; +}; + +//----------------------------------------------------------------------- + +inline const ScriptDictionary & ScriptMessage::getParameters() const +{ + return m_parameters; +} + +//----------------------------------------------------------------------- + +inline const std::string & ScriptMessage::getScriptFunctionName() const +{ + return m_scriptFunctionName; +} + +//----------------------------------------------------------------------- + +inline const std::string & ScriptMessage::getSourceScriptName() const +{ + return m_sourceScriptName; +} + +//----------------------------------------------------------------------- + +#endif // _INCLUDED_ScriptMessage_H diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsActionStates.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsActionStates.cpp new file mode 100644 index 00000000..cc17ad42 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsActionStates.cpp @@ -0,0 +1,491 @@ +//======================================================================== +// +// ScriptMethodsActionStatesNamespace.cpp - implements script methods dealing with action states +// +// copyright 2001 Sony Online Entertainment +// +//======================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "serverGame/AiCreatureController.h" +#include "serverGame/CellObject.h" +#include "serverGame/ConfigServerGame.h" +#include "serverGame/ContainerInterface.h" +#include "serverGame/CreatureObject.h" +#include "serverGame/ServerWorld.h" +#include "sharedFoundation/DynamicVariableList.h" +#include "sharedObject/CellProperty.h" +#include "sharedObject/NetworkIdManager.h" + +using namespace JNIWrappersNamespace; + + +//======================================================================== +// ScriptMethodsActionStatesNamespace +//======================================================================== + +namespace ScriptMethodsActionStatesNamespace +{ + bool install(); + + jboolean JNICALL wanderAngleDelay(JNIEnv *env, jobject self, jlong mob, jfloat minDist, jfloat maxDist, jfloat minAngle, jfloat maxAngle, jfloat minDelay, jfloat maxDelay); + void JNICALL setCreatureStatic(JNIEnv *env, jobject self, jlong creature, jboolean value); + void JNICALL stop(JNIEnv *env, jobject self, jlong mob); + jboolean JNICALL follow(JNIEnv *env, jobject self, jlong mob, jlong target, jfloat minDistance, jfloat maxDistance); + jboolean JNICALL followOffset(JNIEnv *env, jobject self, jlong mob, jlong target, jobject offset); + jboolean JNICALL swarm(JNIEnv *env, jobject self, jlong mob, jlong target); + jboolean JNICALL swarm2(JNIEnv *env, jobject self, jlong mob, jlong target, jfloat offset); + jboolean JNICALL flee(JNIEnv *env, jobject self, jlong mob, jlong target, jfloat minDistance, jfloat maxDistance); + jboolean JNICALL suspendMovement(JNIEnv *env, jobject self, jlong mob); + jboolean JNICALL resumeMovement(JNIEnv *env, jobject self, jlong mob); + jboolean JNICALL hasSuspendedMovement(JNIEnv *env, jobject self, jlong mob); + jfloat JNICALL getAcceleration(JNIEnv *env, jobject self, jlong mob, jint movementType); + jfloat JNICALL getTurnRate(JNIEnv *env, jobject self, jlong mob, jint movementType); + jfloat JNICALL getStepHeight(JNIEnv *env, jobject self, jlong mob); + jfloat JNICALL getApproachTriggerRange(JNIEnv *env, jobject self, jlong mob); + jboolean JNICALL isCreatureStatic(JNIEnv *env, jobject self, jlong creature); +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsActionStatesNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsActionStatesNamespace::c)} + JF("_wanderAngleDelay", "(JFFFFFF)Z", wanderAngleDelay), + JF("_setCreatureStatic", "(JZ)V", setCreatureStatic), + JF("_stop", "(J)V", stop), + JF("_follow", "(JJFF)Z", follow), + JF("_follow", "(JJLscript/location;)Z", followOffset), + JF("_swarm", "(JJ)Z", swarm), + JF("_swarm", "(JJF)Z", swarm2), + JF("_flee", "(JJFF)Z", flee), + JF("_suspendMovement", "(J)Z", suspendMovement), + JF("_resumeMovement", "(J)Z", resumeMovement), + JF("_hasSuspendedMovement", "(J)Z", hasSuspendedMovement), + JF("_getAcceleration", "(JI)F",getAcceleration), + JF("_getTurnRate", "(JI)F",getTurnRate), + JF("_getStepHeight", "(J)F",getStepHeight), + JF("_getApproachTriggerRange", "(J)F",getApproachTriggerRange), + JF("_isCreatureStatic", "(J)Z", isCreatureStatic), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +//======================================================================== +// class JavaLibrary JNI action state callback methods +//======================================================================== + +/** + * Sets a creature into the "Stop" state where he doesn't do anything. + * + * @param env Java environment + * @param self class calling this function + * @param target id of creature to access + * + * @return JNI_TRUE if the creature stopped, or false if there was an error + */ +void JNICALL ScriptMethodsActionStatesNamespace::stop(JNIEnv *env, jobject , jlong ai) +{ + CreatureObject * aiCreatureObject = 0; + AICreatureController * aiCreatureController = 0; + + if (!JavaLibrary::getObjectController(ai, aiCreatureObject, aiCreatureController)) + { + return; + } + + if (aiCreatureController->isRetreating()) + { + JAVA_THROW_SCRIPT_EXCEPTION(ConfigServerGame::getMovementWhileRetreatingThrowsException(), + ("ScriptMethodsActionStatesNamespace::stop() ai(%s) Calling a movement command on a retreating AI is not allowed.", aiCreatureObject->getDebugInformation().c_str())); + return; + } + + aiCreatureController->stop(); +} + +/** + * Sets a creature into the "Follow" state where he follows someone else around. + * + * @param env Java environment + * @param self class calling this function + * @param mob id of creature to access + * @param target target id of creature to follow + * @param minDist closest to get to creature + * @param maxDist farthest to get from target + * + * @return JNI_TRUE if the creature stopped, or false if there was an error + */ +jboolean JNICALL ScriptMethodsActionStatesNamespace::follow(JNIEnv *env, jobject self, jlong mob, jlong target, jfloat minDist, jfloat maxDist) +{ + UNREF(self); + + if (mob == 0 || target == 0) + return JNI_FALSE; + + CreatureObject * object = 0; + AICreatureController * controller = 0; + jboolean result=JNI_FALSE; + + if (!JavaLibrary::getObjectController(mob, object, controller)) + return result; + + NetworkId mobId = object->getNetworkId(); + NetworkId targetId(target); + + if(mobId == targetId) + { + JavaLibrary::throwInternalScriptError("ScriptMethodsActionStatesNamespace::follow - Creature is trying to follow itself\n"); + return JNI_FALSE; + } + + if (controller->follow(NetworkId(target), minDist, maxDist)) + result = JNI_TRUE; + + return result; +} + +/** + * Sets a creature into the "Follow" state where he follows someone else around. + * + * @param env Java environment + * @param self class calling this function + * @param mob id of creature to access + * @param target target id of creature to follow + * @param minDist closest to get to creature + * @param maxDist farthest to get from target + * + * @return JNI_TRUE if the creature stopped, or false if there was an error + */ +jboolean JNICALL ScriptMethodsActionStatesNamespace::followOffset(JNIEnv *env, jobject self, jlong mob, jlong target, jobject offset) +{ + UNREF(self); + + if (mob == 0 || target == 0) + return JNI_FALSE; + + CreatureObject * object = 0; + AICreatureController * controller = 0; + jboolean result=JNI_FALSE; + + if (!JavaLibrary::getObjectController(mob, object, controller)) + return result; + + Vector location; + NetworkId cell; + ScriptConversion::convert(offset, location, cell, object->getPosition_w()); + + NetworkId mobId = object->getNetworkId(); + NetworkId targetId(target); + + if(mobId == targetId) + { + JavaLibrary::throwInternalScriptError("ScriptMethodsActionStatesNamespace::followOffset - Creature is trying to follow itself\n"); + return JNI_FALSE; + } + + if (controller->follow(NetworkId(target), location)) + result = JNI_TRUE; + + return result; +} + +/** + * Sets a creature into the "Swarm" state where he and his comrades try to follow and surround the target. + * + * @param env Java environment + * @param self class calling this function + * @param mob id of creature to access + * @param target target id of creature to follow + * @param minDist closest to get to creature + * @param maxDist farthest to get from target + * + * @return JNI_TRUE if the creature stopped, or false if there was an error + */ +jboolean JNICALL ScriptMethodsActionStatesNamespace::swarm(JNIEnv *env, jobject self, jlong mob, jlong target) +{ + UNREF(self); + + if (mob == 0 || target == 0) + return JNI_FALSE; + + CreatureObject * object = 0; + AICreatureController * controller = 0; + jboolean result=JNI_FALSE; + + if (!JavaLibrary::getObjectController(mob, object, controller)) + return result; + + NetworkId mobId = object->getNetworkId(); + NetworkId targetId(target); + + if(mobId == targetId) + { + JavaLibrary::throwInternalScriptError("ScriptMethodsActionStatesNamespace::swarm - Creature is trying to swarm itself\n"); + return JNI_FALSE; + } + + if (controller->swarm(NetworkId(target))) + result = JNI_TRUE; + + return result; +} + +/** + * Sets a creature into the "Swarm" state where he and his comrades try to follow and surround the target. + * + * @param env Java environment + * @param self class calling this function + * @param mob id of creature to access + * @param target target id of creature to follow + * @param offset how far away to stay from the target + * + * @return JNI_TRUE if the creature stopped, or false if there was an error + */ +jboolean JNICALL ScriptMethodsActionStatesNamespace::swarm2(JNIEnv *env, jobject self, jlong mob, jlong target, jfloat offset) +{ + UNREF(self); + + if (mob == 0 || target == 0) + return JNI_FALSE; + + CreatureObject * object = 0; + AICreatureController * controller = 0; + jboolean result=JNI_FALSE; + + if (!JavaLibrary::getObjectController(mob, object, controller)) + return result; + + NetworkId mobId = object->getNetworkId(); + NetworkId targetId(target); + + if(mobId == targetId) + { + JavaLibrary::throwInternalScriptError("ScriptMethodsActionStatesNamespace::swarm - Creature is trying to swarm itself\n"); + return JNI_FALSE; + } + + if (controller->swarm(NetworkId(target), offset)) + result = JNI_TRUE; + + return result; +} + +/** + * Sets a creature into the "Flee" state where he runs away from another object. + * + * @param env Java environment + * @param self class calling this function + * @param mob id of creature to access + * @param target target id of creature to flee + * + * @return JNI_TRUE if the creature stopped, or false if there was an error + */ +jboolean JNICALL ScriptMethodsActionStatesNamespace::flee(JNIEnv *env, jobject self, jlong mob, jlong target, jfloat minDistance, jfloat maxDistance) +{ + UNREF(self); + + if (mob == 0 || target == 0) + return JNI_FALSE; + + CreatureObject * object = 0; + AICreatureController * controller = 0; + jboolean result=JNI_FALSE; + + if (!JavaLibrary::getObjectController(mob, object, controller)) + return result; + + NetworkId mobId = object->getNetworkId(); + NetworkId targetId(target); + + if(mobId == targetId) + { + JavaLibrary::throwInternalScriptError("ScriptMethodsActionStatesNamespace::flee - Creature is trying to flee from itself\n"); + return JNI_FALSE; + } + + if (controller->flee(NetworkId(target), minDistance, maxDistance)) + result = JNI_TRUE; + + return result; +} + +/** + * Sets a creature into the "Wander" state where he wanders around somewhat aimlessly. The wandering is broken into legs, + * each of which is between minDist and maxDist distance. After each leg he will turn either left or right at an angle between + * minAngle and maxAngle degrees. + * + * @param env Java environment + * @param self class calling this function + * @param mob id of creature to access + * @param minDist minimum length of a leg + * @param maxDist maximum length of a leg + * @param minAngle minimum angle to turn after a leg + * @param maxAngle maximum angle to turn after a leg + * @param minDelay minimum time to wait between movements + * @param maxDelay maximum time to wait between movements + * + * @return JNI_TRUE if the creature stopped, or false if there was an error + */ +jboolean JNICALL ScriptMethodsActionStatesNamespace::wanderAngleDelay(JNIEnv *env, jobject self, jlong mob, jfloat minDist, jfloat maxDist, jfloat minAngle, jfloat maxAngle, jfloat minDelay, jfloat maxDelay) +{ + UNREF(self); + CreatureObject * object = 0; + AICreatureController * controller = 0; + + if (!JavaLibrary::getObjectController(mob, object, controller)) + return JNI_FALSE; + + minAngle *= PI_OVER_180; + maxAngle *= PI_OVER_180; + + controller->wander(minDist, maxDist, minAngle, maxAngle, minDelay, maxDelay); + + return JNI_TRUE; +} // ScriptMethodsActionStatesNamespace::stop() + +//------------------------------------------------------------------------------------------------ + +/** + * Stops the current movement type of the creature, allowing it to be resumed at a + * later time. + * + * NOTE: Only one movement can be suspended at a time. If this function + * is called while a previous movement is suspended, it will fail. + * + * @return true if the movement has been suspended, false if not. + */ +jboolean JNICALL ScriptMethodsActionStatesNamespace::suspendMovement(JNIEnv *env, jobject self, jlong mob) +{ + UNREF(self); + CreatureObject * object = 0; + AICreatureController * controller = 0; + if (!JavaLibrary::getObjectController(mob, object, controller)) + return JNI_FALSE; + + return static_cast(controller->suspendMovement() ? JNI_TRUE : JNI_FALSE); +} + +//------------------------------------------------------------------------------------------------ + +/** + * Resumes a previously suspended movement. + * + * @return true if the movement was resumed, false if there was no previous movement. + */ +jboolean JNICALL ScriptMethodsActionStatesNamespace::resumeMovement(JNIEnv *env, jobject self, jlong mob) +{ + UNREF(self); + CreatureObject * object = 0; + AICreatureController * controller = 0; + if (!JavaLibrary::getObjectController(mob, object, controller)) + return JNI_FALSE; + + return static_cast(controller->resumeMovement() ? JNI_TRUE : JNI_FALSE); +} + +//------------------------------------------------------------------------------------------------ + +/** + * Returns if a creature has movement suspended or not. + * + * @return true there is suspended movement, false if not + */ +jboolean JNICALL ScriptMethodsActionStatesNamespace::hasSuspendedMovement(JNIEnv *env, jobject self, jlong mob) +{ + UNREF(self); + CreatureObject * object = 0; + AICreatureController * controller = 0; + if (!JavaLibrary::getObjectController(mob, object, controller)) + return JNI_FALSE; + + return static_cast(controller->hasSuspendedMovement() ? JNI_TRUE : JNI_FALSE); +} + +//------------------------------------------------------------------------------------------------ + +jfloat JNICALL ScriptMethodsActionStatesNamespace::getAcceleration(JNIEnv *env, jobject self, jlong mob, jint movementType) +{ + CreatureObject * object = 0; + float result = -1.0f; + if (!JavaLibrary::getObject(mob, object)) + return result; + + return object->getAcceleration(static_cast(movementType)); + +} +//------------------------------------------------------------------------------------------------ + +jfloat JNICALL ScriptMethodsActionStatesNamespace::getTurnRate(JNIEnv *env, jobject self, jlong mob, jint movementType) +{ + CreatureObject * object = 0; + float result = -1.0f; + if (!JavaLibrary::getObject(mob, object)) + return result; + + return object->getTurnRate(static_cast(movementType)); + +} + +//------------------------------------------------------------------------------------------------ + +jfloat JNICALL ScriptMethodsActionStatesNamespace::getStepHeight(JNIEnv *env, jobject self, jlong mob) +{ + CreatureObject * object = 0; + float result = -1.0f; + if (!JavaLibrary::getObject(mob, object)) + return result; + + return object->getStepHeight(); + +} + +//------------------------------------------------------------------------------------------------ + +jfloat JNICALL ScriptMethodsActionStatesNamespace::getApproachTriggerRange(JNIEnv *env, jobject self, jlong mob) +{ + CreatureObject * object = 0; + float result = -1.0f; + if (!JavaLibrary::getObject(mob, object)) + return result; + + return object->getApproachTriggerRange(); + +} + +//------------------------------------------------------------------------------------------------ + +void JNICALL ScriptMethodsActionStatesNamespace::setCreatureStatic(JNIEnv *env, jobject self, jlong creature, jboolean value) +{ + CreatureObject * object = 0; + if (!JavaLibrary::getObject(creature, object)) + return; + + DEBUG_REPORT_LOG(!value, ("Script is setting a creature to not be static. This is ok, but questionable.\n")); + object->setIsStatic(value); + +} + +//------------------------------------------------------------------------------------------------ + +jboolean JNICALL ScriptMethodsActionStatesNamespace::isCreatureStatic(JNIEnv *env, jobject self, jlong creature) +{ + CreatureObject * object = 0; + if (!JavaLibrary::getObject(creature, object)) + return JNI_FALSE; + + if(!object) + return JNI_FALSE; + + return object->getIsStatic() ? JNI_TRUE : JNI_FALSE; +} + +//------------------------------------------------------------------------------------------------ diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsAi.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsAi.cpp new file mode 100644 index 00000000..eab60dd9 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsAi.cpp @@ -0,0 +1,829 @@ +// ====================================================================== +// +// ScriptMethodsAi.cpp +// Copyright 2005 Sony Online Eentertainment, Inc. +// All rights reserved. +// +// ====================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "serverGame/AiCreatureCombatProfile.h" +#include "serverGame/AiCreatureController.h" +#include "serverGame/AiLogManager.h" +#include "serverGame/CellObject.h" +#include "serverGame/ConfigServerGame.h" +#include "serverGame/CreatureObject.h" +#include "serverGame/HateList.h" +#include "serverGame/WeaponObject.h" +#include "sharedCollision/CollisionProperty.h" +#include "sharedLog/Log.h" +#include "sharedObject/CellProperty.h" +#include "sharedObject/NetworkIdManager.h" + +using namespace JNIWrappersNamespace; + + +// ====================================================================== +// ScriptMethodsAiNamespace +// ====================================================================== + +namespace ScriptMethodsAiNamespace +{ + bool install(); + AICreatureController * const getAiCreatureController(jlong ai); + + jint JNICALL aiGetMovementState(JNIEnv *env, jobject self, jlong ai); + jboolean JNICALL aiLoggingEnabled(JNIEnv * env, jobject self, jlong ai); + jboolean JNICALL aiIsFrozen(JNIEnv * env, jobject self, jlong ai); + jboolean JNICALL aiIsAggressive(JNIEnv * env, jobject self, jlong ai); + jboolean JNICALL aiIsAssist(JNIEnv * env, jobject self, jlong ai); + jboolean JNICALL aiIsStalker(JNIEnv * env, jobject self, jlong ai); + jboolean JNICALL aiIsKiller(JNIEnv * env, jobject self, jlong ai); + void JNICALL aiTether(JNIEnv * env, jobject self, jlong ai); + jboolean JNICALL aiIsTethered(JNIEnv * env, jobject self, jlong ai); + void JNICALL aiSetHomeLocation(JNIEnv * env, jobject self, jlong ai, jobject location); + jobject JNICALL aiGetHomeLocation(JNIEnv * env, jobject self, jlong ai); + jobject JNICALL aiGetLeashAnchorLocation(JNIEnv * env, jobject self, jlong ai); + jfloat JNICALL aiGetLeashRadius(JNIEnv * env, jobject self); + jfloat JNICALL aiGetRespectRadius(JNIEnv * env, jobject self, jlong ai, jlong target); + jfloat JNICALL aiGetAggroRadius(JNIEnv * env, jobject self, jlong ai); + void JNICALL aiEquipPrimaryWeapon(JNIEnv * env, jobject self, jlong ai); + void JNICALL aiEquipSecondaryWeapon(JNIEnv * env, jobject self, jlong ai); + void JNICALL aiUnEquipWeapons(JNIEnv * env, jobject self, jlong ai); + jboolean JNICALL aiHasPrimaryWeapon(JNIEnv * env, jobject self, jlong ai); + jboolean JNICALL aiHasSecondaryWeapon(JNIEnv * env, jobject self, jlong ai); + jboolean JNICALL aiUsingPrimaryWeapon(JNIEnv * env, jobject self, jlong ai); + jboolean JNICALL aiUsingSecondaryWeapon(JNIEnv * env, jobject self, jlong ai); + jlong JNICALL aiGetPrimaryWeapon(JNIEnv * env, jobject self, jlong ai); + jlong JNICALL aiGetSecondaryWeapon(JNIEnv * env, jobject self, jlong ai); + float JNICALL aiGetMovementSpeedPercent(JNIEnv * env, jobject self, jlong ai); + jstring JNICALL aiGetCombatAction(JNIEnv * env, jobject self, jlong ai); + jint JNICALL aiGetKnockDownRecoveryTime(JNIEnv * env, jobject self, jlong ai); + void JNICALL pathToLocation(JNIEnv *env, jobject self, jlong mob, jobject location); + void JNICALL pathToName(JNIEnv *env, jobject self, jlong objectId, jstring targetName); + void JNICALL patrolToLocation(JNIEnv *env, jobject self, jlong ai, jobjectArray targets, jboolean random, jboolean flip, jboolean repeat, jint startPoint); + void JNICALL patrolToName(JNIEnv *env, jobject self, jlong ai, jobjectArray targetNames, jboolean random, jboolean flip, jboolean repeat, jint startPoint); + void JNICALL loiterLocation(JNIEnv *env, jobject self, jlong ai, jobject anchorLocation, jfloat minDistance, jfloat maxDistance, jfloat minDelay, jfloat maxDelay); + void JNICALL loiterTarget(JNIEnv *env, jobject self, jlong ai, jlong target, jfloat minDistance, jfloat maxDistance, jfloat minDelay, jfloat maxDelay); + jboolean JNICALL setHibernationDelay(JNIEnv *env, jobject self, jlong creature, jfloat delay); +} + +using namespace ScriptMethodsAiNamespace; + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsAiNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsAiNamespace::c)} + JF("_aiGetMovementState", "(J)I", aiGetMovementState), + JF("_aiLoggingEnabled", "(J)Z", aiLoggingEnabled), + JF("_aiIsFrozen", "(J)Z", aiIsFrozen), + JF("_aiIsAggressive", "(J)Z", aiIsAggressive), + JF("_aiIsAssist", "(J)Z", aiIsAssist), + JF("_aiIsStalker", "(J)Z", aiIsStalker), + JF("_aiIsKiller", "(J)Z", aiIsKiller), + JF("_aiTether", "(J)V", aiTether), + JF("_aiIsTethered", "(J)Z", aiIsTethered), + JF("_aiSetHomeLocation", "(JLscript/location;)V", aiSetHomeLocation), + JF("_aiGetHomeLocation", "(J)Lscript/location;", aiGetHomeLocation), + JF("_aiGetLeashAnchorLocation", "(J)Lscript/location;", aiGetLeashAnchorLocation), + JF("aiGetLeashRadius", "()F", aiGetLeashRadius), + JF("_aiGetRespectRadius", "(JJ)F", aiGetRespectRadius), + JF("_aiGetAggroRadius", "(J)F", aiGetAggroRadius), + JF("_aiEquipPrimaryWeapon", "(J)V", aiEquipPrimaryWeapon), + JF("_aiEquipSecondaryWeapon", "(J)V", aiEquipSecondaryWeapon), + JF("_aiUnEquipWeapons", "(J)V", aiUnEquipWeapons), + JF("_aiUsingPrimaryWeapon", "(J)Z", aiUsingPrimaryWeapon), + JF("_aiHasPrimaryWeapon", "(J)Z", aiHasPrimaryWeapon), + JF("_aiHasSecondaryWeapon", "(J)Z", aiHasSecondaryWeapon), + JF("_aiUsingSecondaryWeapon", "(J)Z", aiUsingSecondaryWeapon), + JF("_aiGetPrimaryWeapon", "(J)J", aiGetPrimaryWeapon), + JF("_aiGetSecondaryWeapon", "(J)J", aiGetSecondaryWeapon), + JF("_aiGetMovementSpeedPercent", "(J)F", aiGetMovementSpeedPercent), + JF("_aiGetCombatAction", "(J)Ljava/lang/String;", aiGetCombatAction), + JF("_aiGetKnockDownRecoveryTime", "(J)I", aiGetKnockDownRecoveryTime), + JF("_pathTo", "(JLscript/location;)V", pathToLocation), + JF("_pathTo", "(JLjava/lang/String;)V", pathToName), + JF("_patrol", "(J[Lscript/location;ZZZI)V", patrolToLocation), + JF("_patrol", "(J[Ljava/lang/String;ZZZI)V", patrolToName), + JF("_loiterLocation", "(JLscript/location;FFFF)V", loiterLocation), + JF("_loiterTarget", "(JJFFFF)V", loiterTarget), + JF("_setHibernationDelay", "(JF)Z", setHibernationDelay), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + +// ---------------------------------------------------------------------- + +AICreatureController * const ScriptMethodsAiNamespace::getAiCreatureController(jlong ai) +{ + NetworkId const aiNetworkId(ai); + CreatureObject * const aiCreatureObject = CreatureObject::getCreatureObject(aiNetworkId); + + if (aiCreatureObject == NULL) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("Unable to resolve the ai(%s) to a CreatureObject.", aiNetworkId.getValueString().c_str())); + return NULL; + } + + AICreatureController * const aiCreatureController = AICreatureController::asAiCreatureController(aiCreatureObject->getController()); + + if (aiCreatureController == NULL) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("Unable to get the ai's(%s) AiCreatureController.", aiCreatureObject->getDebugInformation().c_str())); + return NULL; + } + + return aiCreatureController; +} + +// ====================================================================== +// +// ScriptMethodsAi +// +// ====================================================================== + +// ---------------------------------------------------------------------- +jint JNICALL ScriptMethodsAiNamespace::aiGetMovementState(JNIEnv * /*env*/, jobject /*self*/, jlong ai) +{ + NetworkId const aiNetworkId(ai); + CreatureObject * const aiCreatureObject = CreatureObject::getCreatureObject(aiNetworkId); + + if (aiCreatureObject == NULL) + { + return AMT_invalid; + } + + AICreatureController * const aiCreatureController = AICreatureController::asAiCreatureController(aiCreatureObject->getController()); + + if (aiCreatureController == NULL) + { + return AMT_invalid; + } + + jint const nextState = aiCreatureController->getPendingMovementType(); + + // If we will change states next frame, return the pending state + + if (nextState != AMT_invalid) + { + return nextState; + } + + jint const currentState = aiCreatureController->getMovementType(); + + return currentState; +} + +// ---------------------------------------------------------------------- +jboolean JNICALL ScriptMethodsAiNamespace::aiLoggingEnabled(JNIEnv * /*env*/, jobject /*self*/, jlong ai) +{ + NetworkId const aiNetworkId(ai); + CreatureObject * const aiCreatureObject = CreatureObject::getCreatureObject(aiNetworkId); + + if (aiCreatureObject == NULL) + { + return JNI_FALSE; + } + + AICreatureController * const aiCreatureController = AICreatureController::asAiCreatureController(aiCreatureObject->getController()); + + if (aiCreatureController == NULL) + { + return JNI_FALSE; + } + + if (ConfigServerGame::isAiLoggingEnabled()) + { + return JNI_TRUE; + } + + return aiCreatureController->isLogging(); +} + +// ---------------------------------------------------------------------- +jboolean JNICALL ScriptMethodsAiNamespace::aiIsFrozen(JNIEnv * /*env*/, jobject /*self*/, jlong ai) +{ + AICreatureController * const aiCreatureController = ScriptMethodsAiNamespace::getAiCreatureController(ai); + + if (aiCreatureController == NULL) + { + return JNI_FALSE; + } + + return aiCreatureController->isFrozen(); +} + +// ---------------------------------------------------------------------- +jboolean JNICALL ScriptMethodsAiNamespace::aiIsAggressive(JNIEnv * /*env*/, jobject /*self*/, jlong ai) +{ + NetworkId const aiNetworkId(ai); + CreatureObject * const aiCreatureObject = CreatureObject::getCreatureObject(aiNetworkId); + + if (aiCreatureObject == NULL) + { + return JNI_FALSE; + } + + AICreatureController * const aiCreatureController = AICreatureController::asAiCreatureController(aiCreatureObject->getController()); + + if (aiCreatureController == NULL) + { + return JNI_FALSE; + } + + return aiCreatureController->isAggressive(); +} + +// ---------------------------------------------------------------------- +jboolean JNICALL ScriptMethodsAiNamespace::aiIsAssist(JNIEnv * /*env*/, jobject /*self*/, jlong ai) +{ + NetworkId const aiNetworkId(ai); + CreatureObject * const aiCreatureObject = CreatureObject::getCreatureObject(aiNetworkId); + + if (aiCreatureObject == NULL) + { + return JNI_FALSE; + } + + AICreatureController * const aiCreatureController = AICreatureController::asAiCreatureController(aiCreatureObject->getController()); + + if (aiCreatureController == NULL) + { + return JNI_FALSE; + } + + return aiCreatureController->isAssist(); +} + +// ---------------------------------------------------------------------- +jboolean JNICALL ScriptMethodsAiNamespace::aiIsStalker(JNIEnv * /*env*/, jobject /*self*/, jlong ai) +{ + AICreatureController * const aiCreatureController = ScriptMethodsAiNamespace::getAiCreatureController(ai); + + if (aiCreatureController == NULL) + { + return JNI_FALSE; + } + + return aiCreatureController->isStalker(); +} + + +// ---------------------------------------------------------------------- +jboolean JNICALL ScriptMethodsAiNamespace::aiIsKiller(JNIEnv * /*env*/, jobject /*self*/, jlong ai) +{ + NetworkId const aiNetworkId(ai); + CreatureObject * const aiCreatureObject = CreatureObject::getCreatureObject(aiNetworkId); + + if (aiCreatureObject == NULL) + { + return JNI_FALSE; + } + + AICreatureController * const aiCreatureController = AICreatureController::asAiCreatureController(aiCreatureObject->getController()); + + if (aiCreatureController == NULL) + { + return JNI_FALSE; + } + + return aiCreatureController->isKiller(); +} + +// ---------------------------------------------------------------------- +void JNICALL ScriptMethodsAiNamespace::aiTether(JNIEnv * /*env*/, jobject /*self*/, jlong ai) +{ + AICreatureController * const aiCreatureController = ScriptMethodsAiNamespace::getAiCreatureController(ai); + + if (aiCreatureController == NULL) + { + return; + } + + aiCreatureController->setRetreating(true); +} + +// ---------------------------------------------------------------------- +jboolean JNICALL ScriptMethodsAiNamespace::aiIsTethered(JNIEnv * /*env*/, jobject /*self*/, jlong ai) +{ + NetworkId const aiNetworkId(ai); + CreatureObject * const aiCreatureObject = CreatureObject::getCreatureObject(aiNetworkId); + + if (aiCreatureObject == NULL) + { + return JNI_FALSE; + } + + AICreatureController * const aiCreatureController = AICreatureController::asAiCreatureController(aiCreatureObject->getController()); + + if (aiCreatureController == NULL) + { + return JNI_FALSE; + } + + return aiCreatureController->isRetreating(); +} + +// ---------------------------------------------------------------------- +void JNICALL ScriptMethodsAiNamespace::aiSetHomeLocation(JNIEnv * /*env*/, jobject /*self*/, jlong ai, jobject location) +{ + AICreatureController * const aiCreatureController = ScriptMethodsAiNamespace::getAiCreatureController(ai); + + if (aiCreatureController == NULL) + { + return; + } + + Location homeLocation; + if (!ScriptConversion::convert(LocalRefParam(location), homeLocation)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsAi::aiSetHomeLocation() Unable to resolve the ai's(%s) location to a Location.", aiCreatureController->getCreature()->getDebugInformation().c_str())); + return; + } + + aiCreatureController->setHomeLocation(homeLocation); +} + +// ---------------------------------------------------------------------- +jobject JNICALL ScriptMethodsAiNamespace::aiGetHomeLocation(JNIEnv * /*env*/, jobject /*self*/, jlong ai) +{ + AICreatureController * const aiCreatureController = ScriptMethodsAiNamespace::getAiCreatureController(ai); + + if (aiCreatureController == NULL) + { + return JavaLibrary::getVector(Vector::zero)->getReturnValue(); + } + + Location const & homeLocation = aiCreatureController->getHomeLocation(); + LocalRefPtr location; + ScriptConversion::convert(homeLocation, location); + + return location->getReturnValue(); +} + +// ---------------------------------------------------------------------- +jobject JNICALL ScriptMethodsAiNamespace::aiGetLeashAnchorLocation(JNIEnv * /*env*/, jobject /*self*/, jlong ai) +{ + AICreatureController * const aiCreatureController = ScriptMethodsAiNamespace::getAiCreatureController(ai); + + if (aiCreatureController == NULL) + { + return JavaLibrary::getVector(Vector::zero)->getReturnValue(); + } + + Location const & startCombatLocation = aiCreatureController->getCombatStartLocation(); + LocalRefPtr location; + ScriptConversion::convert(startCombatLocation, location); + + return location->getReturnValue(); +} + +// ---------------------------------------------------------------------- +jfloat JNICALL ScriptMethodsAiNamespace::aiGetLeashRadius(JNIEnv * /*env*/, jobject /*self*/) +{ + return AICreatureController::getLeashRadius(); +} + +// ---------------------------------------------------------------------- +jfloat JNICALL ScriptMethodsAiNamespace::aiGetRespectRadius(JNIEnv * /*env*/, jobject /*self*/, jlong ai, jlong target) +{ + AICreatureController * const aiCreatureController = ScriptMethodsAiNamespace::getAiCreatureController(ai); + + if (aiCreatureController == NULL) + { + return 0.0f; + } + + NetworkId const targetNetworkId(target); + + return aiCreatureController->getRespectRadius(targetNetworkId); +} + +// ---------------------------------------------------------------------- +jfloat JNICALL ScriptMethodsAiNamespace::aiGetAggroRadius(JNIEnv * /*env*/, jobject /*self*/, jlong ai) +{ + AICreatureController * const aiCreatureController = ScriptMethodsAiNamespace::getAiCreatureController(ai); + + if (aiCreatureController == NULL) + { + return 0.0f; + } + + return aiCreatureController->getAggroRadius(); +} + +// ---------------------------------------------------------------------- +void JNICALL ScriptMethodsAiNamespace::aiEquipPrimaryWeapon(JNIEnv * /*env*/, jobject /*self*/, jlong ai) +{ + AICreatureController * const aiCreatureController = ScriptMethodsAiNamespace::getAiCreatureController(ai); + + if (aiCreatureController == NULL) + { + return; + } + + aiCreatureController->equipPrimaryWeapon(); +} + +// ---------------------------------------------------------------------- +void JNICALL ScriptMethodsAiNamespace::aiEquipSecondaryWeapon(JNIEnv * /*env*/, jobject /*self*/, jlong ai) +{ + AICreatureController * const aiCreatureController = ScriptMethodsAiNamespace::getAiCreatureController(ai); + + if (aiCreatureController == NULL) + { + return; + } + + aiCreatureController->equipSecondaryWeapon(); +} + +// ---------------------------------------------------------------------- +void JNICALL ScriptMethodsAiNamespace::aiUnEquipWeapons(JNIEnv * /*env*/, jobject /*self*/, jlong ai) +{ + AICreatureController * const aiCreatureController = ScriptMethodsAiNamespace::getAiCreatureController(ai); + + if (aiCreatureController == NULL) + { + return; + } + + aiCreatureController->unEquipWeapons(); +} + +// ---------------------------------------------------------------------- +jboolean JNICALL ScriptMethodsAiNamespace::aiHasPrimaryWeapon(JNIEnv * /*env*/, jobject /*self*/, jlong ai) +{ + AICreatureController * const aiCreatureController = ScriptMethodsAiNamespace::getAiCreatureController(ai); + + if (aiCreatureController == NULL) + { + return JNI_FALSE; + } + + return aiCreatureController->hasPrimaryWeapon(); +} + +// ---------------------------------------------------------------------- +jboolean JNICALL ScriptMethodsAiNamespace::aiHasSecondaryWeapon(JNIEnv * /*env*/, jobject /*self*/, jlong ai) +{ + AICreatureController * const aiCreatureController = ScriptMethodsAiNamespace::getAiCreatureController(ai); + + if (aiCreatureController == NULL) + { + return JNI_FALSE; + } + + return aiCreatureController->hasSecondaryWeapon(); +} + +// ---------------------------------------------------------------------- +jboolean JNICALL ScriptMethodsAiNamespace::aiUsingPrimaryWeapon(JNIEnv * /*env*/, jobject /*self*/, jlong ai) +{ + AICreatureController * const aiCreatureController = ScriptMethodsAiNamespace::getAiCreatureController(ai); + + if (aiCreatureController == NULL) + { + return JNI_FALSE; + } + + return aiCreatureController->usingPrimaryWeapon(); +} + +// ---------------------------------------------------------------------- +jboolean JNICALL ScriptMethodsAiNamespace::aiUsingSecondaryWeapon(JNIEnv * /*env*/, jobject /*self*/, jlong ai) +{ + AICreatureController * const aiCreatureController = ScriptMethodsAiNamespace::getAiCreatureController(ai); + + if (aiCreatureController == NULL) + { + return JNI_FALSE; + } + + return aiCreatureController->usingSecondaryWeapon(); +} + +// ---------------------------------------------------------------------- +jlong JNICALL ScriptMethodsAiNamespace::aiGetPrimaryWeapon(JNIEnv * /*env*/, jobject /*self*/, jlong ai) +{ + AICreatureController * const aiCreatureController = ScriptMethodsAiNamespace::getAiCreatureController(ai); + + if (aiCreatureController == NULL) + { + return 0; + } + + return (aiCreatureController->getPrimaryWeapon()).getValue(); +} + +// ---------------------------------------------------------------------- +jlong JNICALL ScriptMethodsAiNamespace::aiGetSecondaryWeapon(JNIEnv * /*env*/, jobject /*self*/, jlong ai) +{ + AICreatureController * const aiCreatureController = ScriptMethodsAiNamespace::getAiCreatureController(ai); + + if (aiCreatureController == NULL) + { + return 0; + } + + return (aiCreatureController->getSecondaryWeapon()).getValue(); +} + +// ---------------------------------------------------------------------- +jfloat JNICALL ScriptMethodsAiNamespace::aiGetMovementSpeedPercent(JNIEnv * /*env*/, jobject /*self*/, jlong ai) +{ + AICreatureController * const aiCreatureController = ScriptMethodsAiNamespace::getAiCreatureController(ai); + + if (aiCreatureController == NULL) + { + return 0.0f; + } + + return aiCreatureController->getMovementSpeedPercent(); +} + +// ---------------------------------------------------------------------- +void JNICALL ScriptMethodsAiNamespace::loiterLocation(JNIEnv * /*env*/, jobject /*self*/, jlong ai, jobject anchorLocation, jfloat minDistance, jfloat maxDistance, jfloat minDelay, jfloat maxDelay) +{ + AICreatureController * const aiCreatureController = ScriptMethodsAiNamespace::getAiCreatureController(ai); + + if (aiCreatureController == NULL) + { + return; + } + + if (aiCreatureController->isRetreating()) + { + JAVA_THROW_SCRIPT_EXCEPTION(ConfigServerGame::getMovementWhileRetreatingThrowsException(), + ("ScriptMethodsAi::loiterLocation() ai(%s) Calling a movement command on a retreating AI is not allowed.", aiCreatureController->getCreature()->getDebugInformation().c_str())); + return; + } + + Vector position_c; + NetworkId cellId; + + if (ScriptConversion::convert(anchorLocation, position_c, cellId)) + { + if (cellId == NetworkId::cms_invalid) + { + LOGC(AiLogManager::isLogging(aiCreatureController->getOwner()->getNetworkId()), "debug_ai", ("ScriptMethodsAi::loiterLocation() ai(%s) WORLD CELL", aiCreatureController->getOwner()->getNetworkId().getValueString().c_str())); + + CellProperty const * const cellProperty = CellProperty::getWorldCellProperty(); + + aiCreatureController->loiter(cellProperty, position_c, minDistance, maxDistance, minDelay, maxDelay); + } + else + { + LOGC(AiLogManager::isLogging(aiCreatureController->getOwner()->getNetworkId()), "debug_ai", ("ScriptMethodsAi::loiterLocation() ai(%s) NON-WORLD CELL", aiCreatureController->getOwner()->getNetworkId().getValueString().c_str())); + + CellObject const * const cellObject = CellObject::getCellObject(cellId); + + if (cellObject != NULL) + { + CellProperty const * const cellProperty = cellObject->getCellProperty(); + + aiCreatureController->loiter(cellProperty, position_c, minDistance, maxDistance, minDelay, maxDelay); + } + else + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsAi::loiterLocation() ai(%s) Unable to resolve the cellId(%s) to a CellObject", aiCreatureController->getCreature()->getDebugInformation().c_str(), cellId.getValueString().c_str())); + } + } + } + else + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsAi::loiterLocation() ai(%s) Unable to resolve the loiter location", aiCreatureController->getCreature()->getDebugInformation().c_str())); + } +} + +// ---------------------------------------------------------------------- +void JNICALL ScriptMethodsAiNamespace::loiterTarget(JNIEnv * /*env*/, jobject /*self*/, jlong ai, jlong target, jfloat minDistance, jfloat maxDistance, jfloat minDelay, jfloat maxDelay) +{ + AICreatureController * const aiCreatureController = ScriptMethodsAiNamespace::getAiCreatureController(ai); + + if (aiCreatureController == NULL) + { + return; + } + + if (aiCreatureController->isRetreating()) + { + JAVA_THROW_SCRIPT_EXCEPTION(ConfigServerGame::getMovementWhileRetreatingThrowsException(), + ("ScriptMethodsAi::loiterTarget() ai(%s) Calling a movement command on a retreating AI is not allowed.", aiCreatureController->getCreature()->getDebugInformation().c_str())); + return; + } + + NetworkId const targetNetworkId(static_cast(target)); + Object * const targetObject = NetworkIdManager::getObjectById(targetNetworkId); + + if (targetObject == NULL) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsAi::loiterTarget() ai(%s) Unable to resolve the target(%s) to a Object", aiCreatureController->getCreature()->getDebugInformation().c_str(), targetNetworkId.getValueString().c_str())); + return; + } + + if (aiCreatureController->getCreature()->getNetworkId() == targetNetworkId) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsAi::loiterTarget() ai(%s) The AI was told to loiter itself", aiCreatureController->getCreature()->getDebugInformation().c_str())); + return; + } + + aiCreatureController->loiter(targetObject->getNetworkId(), minDistance, maxDistance, minDelay, maxDelay); +} + +// ---------------------------------------------------------------------- +void JNICALL ScriptMethodsAiNamespace::pathToLocation(JNIEnv * /*env*/, jobject /*self*/, jlong ai, jobject location) +{ + AICreatureController * const aiCreatureController = ScriptMethodsAiNamespace::getAiCreatureController(ai); + + if (aiCreatureController == NULL) + { + return; + } + + if (aiCreatureController->isRetreating()) + { + JAVA_THROW_SCRIPT_EXCEPTION(ConfigServerGame::getMovementWhileRetreatingThrowsException(), + ("ScriptMethodsAi::pathToLocation() ai(%s) Calling a movement command on a retreating AI is not allowed.", aiCreatureController->getCreature()->getDebugInformation().c_str())); + return; + } + + Vector position_c; + NetworkId cellId; + + if (ScriptConversion::convert(location, position_c, cellId)) + { + if (cellId != NetworkId::cms_invalid) + { + CellObject const * const cellObject = CellObject::getCellObject(cellId); + + if (cellObject != NULL) + { + CellProperty const * const cellProperty = cellObject->getCellProperty(); + + aiCreatureController->moveTo(cellProperty, position_c); + } + else + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsAi::pathToLocation() ai(%s) Unable to resolve the cellId(%s) to a CellObject", aiCreatureController->getCreature()->getDebugInformation().c_str(), cellId.getValueString().c_str())); + return; + } + } + else + { + aiCreatureController->moveTo(CellProperty::getWorldCellProperty(), position_c); + } + } + else + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsAi::pathToLocation() ai(%s) Unable to resolve the destination location", aiCreatureController->getCreature()->getDebugInformation().c_str())); + return; + } +} + +// ---------------------------------------------------------------------- +/** + * Plots a path from an object's current location in the world to a path node with the given name + * + */ +void JNICALL ScriptMethodsAiNamespace::pathToName(JNIEnv * /*env*/, jobject /*self*/, jlong ai, jstring targetName) +{ + AICreatureController * const aiCreatureController = ScriptMethodsAiNamespace::getAiCreatureController(ai); + + if (aiCreatureController == NULL) + { + return; + } + + if (aiCreatureController->isRetreating()) + { + JAVA_THROW_SCRIPT_EXCEPTION(ConfigServerGame::getMovementWhileRetreatingThrowsException(), + ("ScriptMethodsAi::pathToName() ai(%s) Calling a movement command on a retreating AI is not allowed.", aiCreatureController->getCreature()->getDebugInformation().c_str())); + return; + } + + JavaStringParam localName(targetName); + Unicode::String nameString; + JavaLibrary::convert(localName, nameString); + + aiCreatureController->moveTo(nameString); +} + +// ---------------------------------------------------------------------- + +/** + * Causes an AI to move along a series of points. + * + * @param ai the AI to move + * @param targets the points the AI will move along + * @param random flag to tell the AI to choose a random target to move to next, instead of the next one in the targets array + * @param flip if true, when the AI gets to the last point in the targets array, it will then go along them in reverse order + * @param repeat if true, the AI will go back to the first point after reaching the last one; if false, the ai will stop at the last point + * @param startPoint which point the ai will start its patrol at (base-0) + */ +void JNICALL ScriptMethodsAiNamespace::patrolToLocation(JNIEnv *, jobject, jlong ai, jobjectArray targets, jboolean random, jboolean flip, jboolean repeat, jint startPoint) +{ + AICreatureController * const aiCreatureController = ScriptMethodsAiNamespace::getAiCreatureController(ai); + if (aiCreatureController == NULL) + return; + + std::vector locations; + if (!ScriptConversion::convert(LocalObjectArrayRefParam(targets), locations)) + return; + + aiCreatureController->patrol(locations, random, flip, repeat, startPoint); +} // JavaLibrary::patrolToLocation + +// ---------------------------------------------------------------------- + +/** + * Causes an AI to move along a series of points. + * @param ai the AI to move + * @param targetNames the waypoint names the AI will move along + * @param random flag to tell the AI to choose a random target to move to next, instead of the next one in the targets array + * @param flip if true, when the AI gets to the last point in the targets array, it will then go along them in reverse order + * @param repeat if true, the AI will go back to the first point after reaching the last one; if false, the ai will stop at the last point + * @param startPoint which point the ai will start its patrol at (base-0) + */ +void JNICALL ScriptMethodsAiNamespace::patrolToName(JNIEnv *, jobject, jlong ai, jobjectArray targetNames, jboolean random, jboolean flip, jboolean repeat, jint startPoint) +{ + AICreatureController * const aiCreatureController = ScriptMethodsAiNamespace::getAiCreatureController(ai); + if (aiCreatureController == NULL) + return; + + std::vector locations; + getStringArray(LocalObjectArrayRefParam(targetNames), locations); + + // we have to copy the string pointers to strings, which sucks + int count = locations.size(); + std::vector realLocations; + realLocations.reserve(count); + for (int i = 0; i < count; ++i) + { + const Unicode::String * location = locations[i]; + if (location != NULL) + { + realLocations.push_back(*location); + delete location; + locations[i] = NULL; + } + } + aiCreatureController->patrol(realLocations, random, flip, repeat, startPoint); +} // JavaLibrary::patrolToName + +// ---------------------------------------------------------------------- +jstring JNICALL ScriptMethodsAiNamespace::aiGetCombatAction(JNIEnv * /*env*/, jobject /*self*/, jlong ai) +{ + AICreatureController * const aiCreatureController = ScriptMethodsAiNamespace::getAiCreatureController(ai); + + if (aiCreatureController == NULL) + { + return NULL; + } + + PersistentCrcString const & result = aiCreatureController->getCombatAction(); + + if (result.isEmpty()) + { + return NULL; + } + + JavaString javaString(result.getString()); + + return javaString.getReturnValue(); +} + +// ---------------------------------------------------------------------- +jint JNICALL ScriptMethodsAiNamespace::aiGetKnockDownRecoveryTime(JNIEnv * /*env*/, jobject /*self*/, jlong ai) +{ + AICreatureController * const aiCreatureController = ScriptMethodsAiNamespace::getAiCreatureController(ai); + + if (aiCreatureController == NULL) + { + return 0; + } + + return int(aiCreatureController->getKnockDownRecoveryTime()); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsAiNamespace::setHibernationDelay(JNIEnv *env, jobject self, jlong creature, jfloat delay) +{ + AICreatureController * const aiCreatureController = ScriptMethodsAiNamespace::getAiCreatureController(creature); + + if (aiCreatureController == NULL) + return JNI_FALSE; + + aiCreatureController->setHibernationDelay(delay); + return JNI_TRUE; +} + +// ====================================================================== diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsAnimation.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsAnimation.cpp new file mode 100644 index 00000000..d41f22ca --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsAnimation.cpp @@ -0,0 +1,237 @@ +//======================================================================== +//http://www.guidescope.com/home/bar.htm +// ScriptMethodsAnimation.cpp - implements script methods dealing with object +// movement. +// +// copyright 2001 Sony Online Entertainment +// +//======================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "serverGame/CreatureObject.h" +#include "serverGame/CreatureController.h" +#include "serverGame/ServerObject.h" +#include "serverGame/TangibleObject.h" +#include "sharedNetworkMessages/MessageQueueString.h" +#include "sharedObject/Controller.h" +#include "sharedFoundation/GameControllerMessage.h" +#include "sharedObject/CellProperty.h" +#include "sharedObject/NetworkIdManager.h" + +namespace ScriptMethodsAnimationNamespace +{ + bool install(); + + void JNICALL doAnimationAction (JNIEnv *env, jobject self, jlong target, jstring animationName); + void JNICALL setAnimationMood (JNIEnv *env, jobject self, jlong target, jstring moodName); + jstring JNICALL getAnimationMood (JNIEnv *env, jobject self, jlong target); + jboolean JNICALL sitOnObject (JNIEnv *env, jobject self, jlong sitterId, jlong chairId, jint positionIndex); + void JNICALL setObjectAppearance (JNIEnv *env, jobject self, jlong target, jstring sharedTemplateName); + void JNICALL revertObjectAppearance (JNIEnv *env, jobject self, jlong target); +} + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsAnimationNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsAnimationNamespace::c)} + JF("_doAnimationAction", "(JLjava/lang/String;)V", doAnimationAction), + JF("_setAnimationMood", "(JLjava/lang/String;)V", setAnimationMood), + JF("_getAnimationMood", "(J)Ljava/lang/String;", getAnimationMood), + JF("_sitOnObject", "(JJI)Z", sitOnObject), + JF("_setObjectAppearance", "(JLjava/lang/String;)V", setObjectAppearance), + JF("_revertObjectAppearance", "(J)V", revertObjectAppearance) +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + +//======================================================================== +// class JavaLibrary JNI object location callback methods +//======================================================================== + +//---------------------------------------------------------------------- + + +void JNICALL ScriptMethodsAnimationNamespace::doAnimationAction (JNIEnv *env, jobject self, jlong target, jstring animationName) +{ + UNREF(self); + UNREF (env); + + TangibleObject * tangibleObject = 0; + Controller * controller = 0; + if (!JavaLibrary::getObjectController(target, tangibleObject, controller)) + { + WARNING (true, ("doAnimationAction on bad TangibleObject/Controller id %d", NetworkId(target).getValue ())); + return; + } + + JavaStringParam localAnimationName(animationName); + std::string animationNameStr; + + if (!JavaLibrary::convert(localAnimationName, animationNameStr)) + { + WARNING (true, ("doAnimationAction unable to convert animationName to std::string")); + return; + } + + MessageQueueString * const msg = new MessageQueueString (animationNameStr); + + controller->appendMessage(CM_animationAction, 0, msg, + GameControllerMessageFlags::SEND | + GameControllerMessageFlags::RELIABLE | + GameControllerMessageFlags::DEST_ALL_CLIENT); +} + +//---------------------------------------------------------------------- +//@todo these are stubbed in right now. +void JNICALL ScriptMethodsAnimationNamespace::setAnimationMood (JNIEnv *env, jobject self, jlong target, jstring moodName) +{ + UNREF(env); + UNREF(self); + + JavaStringParam localMoodName(moodName); + + ServerObject * targetObject = NULL; + if (!JavaLibrary::getObject(target, targetObject)) + return; + + std::string moodString; + JavaLibrary::convert(localMoodName, moodString); + + CreatureObject * c = dynamic_cast(targetObject); + if (!c) + return; + c->setAnimationMood(moodString); +} + +//---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsAnimationNamespace::getAnimationMood (JNIEnv *env, jobject self, jlong target) +{ + ServerObject * targetObject = NULL; + if (!JavaLibrary::getObject(target, targetObject)) + return 0; + + JavaString javaString("neutral"); + return javaString.getReturnValue(); + + CreatureObject * c = dynamic_cast(targetObject); + if (!c) + return 0; + + std::string moodString(c->getAnimationMood()); + JavaString javaReturn(moodString.c_str()); + return javaReturn.getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsAnimationNamespace::sitOnObject (JNIEnv *env, jobject self, jlong sitterId, jlong chairId, jint positionIndex) +{ + UNREF(env); + UNREF(self); + UNREF(chairId); + UNREF(positionIndex); + + //-- Get the creature who will be doing the sitting. + CreatureObject *sitterObject = 0; + if (!JavaLibrary::getObject (sitterId, sitterObject) || !sitterObject) + { + DEBUG_WARNING (true, ("sitOnObject(): Sitter object is NULL.")); + return JNI_FALSE; + } + + if (!sitterObject->isInWorld()) + { + DEBUG_WARNING (true, ("sitOnObject(): Sitter object is not in the world.")); + return JNI_FALSE; + } + + //-- Tell creature to sit on the closest chair to its current position. This will be an issue on the + // client if no chair is within range (currently a 2 meter radius). + NetworkId creatureCellId; + + if (sitterObject->isInWorldCell()) + creatureCellId = NetworkId::cms_invalid; + else + creatureCellId = NON_NULL(sitterObject->getParentCell())->getOwner().getNetworkId(); + + sitterObject->sitOnObject(creatureCellId, sitterObject->getPosition_w()); + + //-- Return success. At this point, the creature should at least go sit on the ground if not in the chair. + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsAnimationNamespace::setObjectAppearance(JNIEnv *env, jobject self, jlong target, jstring sharedTemplateName) +{ + UNREF(env); + UNREF(self); + + CreatureObject* creature = NULL; + + if(!JavaLibrary::getObject(target, creature) || !creature) + { + DEBUG_WARNING(true, ("SetObjectAppearance() : Creature object was NULL.\n")); + return; + } + + if(!creature->isInWorld()) + { + DEBUG_WARNING(true, ("SetObjectAppearance(): Creature is not in the world.\n")); + return; + } + std::string templateString; + JavaStringParam sharedTemplateNameJString(sharedTemplateName); + JavaLibrary::convert(sharedTemplateNameJString, templateString); + + CreatureController* controller = creature->getCreatureController(); + if(!controller) + { + DEBUG_WARNING(true, ("SetObjectAppearance(): Could not get creature controller.\n")); + return; + } + + controller->setAppearanceFromObjectTemplate(templateString); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsAnimationNamespace::revertObjectAppearance(JNIEnv *env, jobject self, jlong target) +{ + UNREF(env); + UNREF(self); + + CreatureObject* creature = NULL; + + if(!JavaLibrary::getObject(target, creature) || !creature) + { + DEBUG_WARNING(true, ("RevertObjectAppearance() : Creature object was NULL.\n")); + return; + } + + if(!creature->isInWorld()) + { + DEBUG_WARNING(true, ("RevertObjectAppearance(): Creature is not in the world.\n")); + return; + } + + CreatureController* controller = creature->getCreatureController(); + if(!controller) + { + DEBUG_WARNING(true, ("RevertObjectAppearance(): Could not get creature controller.\n")); + return; + } + + std::string const revert("none"); + controller->setAppearanceFromObjectTemplate(revert); +} + +// ====================================================================== diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsAttributes.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsAttributes.cpp new file mode 100644 index 00000000..7c5cc5ca --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsAttributes.cpp @@ -0,0 +1,1502 @@ +//======================================================================== +// +// ScriptMethodsAttributes.cpp - implements script methods dealing with attributes. +// +// copyright 2001 Sony Online Entertainment +// +//======================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "serverGame/AttribModNameManager.h" +#include "serverGame/ConfigServerGame.h" +#include "serverGame/CreatureController.h" +#include "serverGame/CreatureObject.h" +#include "serverGame/ServerWeaponObjectTemplate.h" +#include "serverGame/ServerWorld.h" +#include "sharedFoundation/Crc.h" +#include "sharedGame/GameObjectTypes.h" +#include "swgSharedUtility/CombatEngineData.h" + +using namespace JNIWrappersNamespace; + + +//======================================================================== +// constants +//======================================================================== + +static const int ATTRIB_ERROR = INT_MIN; + +//======================================================================== +// namespace +//======================================================================== + +namespace ScriptMethodsAttributesNamespace +{ + bool install(); + jboolean addAttribModifierInternal(JNIEnv *env, CreatureObject * creature,jobject mod); + + jint JNICALL getAttrib(JNIEnv *env, jobject self, jlong target, jint attrib); + jint JNICALL getUnmodifiedAttrib(JNIEnv *env, jobject self, jlong target, jint attrib); + jint JNICALL getMaxAttrib(JNIEnv *env, jobject self, jlong target, jint attrib); + jint JNICALL getWoundedMaxAttrib(JNIEnv *env, jobject self, jlong target, jint attrib); + jint JNICALL getUnmodifiedMaxAttrib(JNIEnv *env, jobject self, jlong target, jint attrib); + jboolean JNICALL setAttrib(JNIEnv *env, jobject self, jlong target, jint attrib, jint value); + jboolean JNICALL setMaxAttrib(JNIEnv *env, jobject self, jlong target, jint attrib, jint value); + jboolean JNICALL addToAttrib(JNIEnv *env, jobject self, jlong target, jint attrib, jint value); + jboolean JNICALL addToMaxAttrib(JNIEnv *env, jobject self, jlong target, jint attrib, jint value); + jboolean JNICALL addAttribModifier(JNIEnv *env, jobject self, jlong target, jobject mod); + jboolean JNICALL addAttribModifiers(JNIEnv *env, jobject self, jlong target, jobjectArray mods); + jboolean JNICALL hasAttribModifier(JNIEnv *env, jobject self, jlong target, jstring modName); + jboolean JNICALL hasSkillModModifier(JNIEnv *env, jobject self, jlong target, jstring modName); + jobjectArray JNICALL getAttribModifiers(JNIEnv *env, jobject self, jlong target, jint attrib); + jobjectArray JNICALL getAllAttribModifiers(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL removeAttribModifier(JNIEnv *env, jobject self, jlong target, jstring modName); + jboolean JNICALL removeAllAttribModifiers(JNIEnv *env, jobject self, jlong target); + jobjectArray JNICALL getAttribs(JNIEnv *env, jobject self, jlong target); + jobjectArray JNICALL getUnmodifiedAttribs(JNIEnv *env, jobject self, jlong target); + jobjectArray JNICALL getMaxAttribs(JNIEnv *env, jobject self, jlong target); + jobjectArray JNICALL getWoundedMaxAttribs(JNIEnv *env, jobject self, jlong target); + jobjectArray JNICALL getUnmodifiedMaxAttribs(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL setAttribs(JNIEnv *env, jobject self, jlong target, jobjectArray values); + jboolean JNICALL setMaxAttribs(JNIEnv *env, jobject self, jlong target, jobjectArray values); + jboolean JNICALL addToAttribs(JNIEnv *env, jobject self, jlong target, jobjectArray values); + jboolean JNICALL addToMaxAttribs(JNIEnv *env, jobject self, jlong target, jobjectArray values); + jint JNICALL getHitpoints(JNIEnv *env, jobject self, jlong target); + jint JNICALL getMaxHitpoints(JNIEnv *env, jobject self, jlong target); + jint JNICALL getTotalHitpoints(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL setHitpoints(JNIEnv *env, jobject self, jlong target, jint hitPoints); + jboolean JNICALL setMaxHitpoints(JNIEnv *env, jobject self, jlong target, jint hitPoints); + jboolean JNICALL setInvulnerableHitpoints(JNIEnv *env, jobject self, jlong target, jint hitPoints); + jint JNICALL getShockWound(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL setShockWound(JNIEnv *env, jobject self, jlong target, jint wound); + jboolean JNICALL addShockWound(JNIEnv *env, jobject self, jlong target, jint wound); + jboolean JNICALL healShockWound(JNIEnv *env, jobject self, jlong target, jint value); + jboolean JNICALL drainAttributes(JNIEnv *env, jobject self, jlong target, jint action, jint mind); + jint JNICALL testDrainAttribute(JNIEnv *env, jobject self, jlong target, jint attribute, jint value); + jboolean JNICALL addBuffIcon(JNIEnv *env, jobject self, jlong target, jstring modName, jfloat time); + jboolean JNICALL clearBuffIcon(JNIEnv *env, jobject self, jlong target, jstring modName); + jfloat JNICALL getRegenRate(JNIEnv *env, jobject self, jlong target, jint attrib); + void JNICALL setRegenRate(JNIEnv *env, jobject self, jlong target, jint attrib, jfloat value); +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsAttributesNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsAttributesNamespace::c)} + JF("_getAttrib", "(JI)I", getAttrib), + JF("_getUnmodifiedAttrib", "(JI)I", getUnmodifiedAttrib), + JF("_getMaxAttrib", "(JI)I", getMaxAttrib), + JF("_getWoundedMaxAttrib", "(JI)I", getWoundedMaxAttrib), + JF("_getUnmodifiedMaxAttrib", "(JI)I", getUnmodifiedMaxAttrib), + JF("_setAttrib", "(JII)Z", setAttrib), + JF("_setMaxAttrib", "(JII)Z", setMaxAttrib), + JF("_addToAttrib", "(JII)Z", addToAttrib), + JF("_addToMaxAttrib", "(JII)Z", addToMaxAttrib), + JF("_addAttribModifier", "(JLscript/attrib_mod;)Z", addAttribModifier), + JF("_addAttribModifiers", "(J[Lscript/attrib_mod;)Z", addAttribModifiers), + JF("_hasAttribModifier", "(JLjava/lang/String;)Z", hasAttribModifier), + JF("_hasSkillModModifier", "(JLjava/lang/String;)Z", hasSkillModModifier), + JF("_getAttribModifiers", "(JI)[Lscript/attrib_mod;", getAttribModifiers), + JF("_getAllAttribModifiers", "(J)[Lscript/attrib_mod;", getAllAttribModifiers), + JF("_removeAttribOrSkillModModifier", "(JLjava/lang/String;)Z", removeAttribModifier), + JF("_removeAllAttribModifiers", "(J)Z", removeAllAttribModifiers), + JF("_getAttribs", "(J)[Lscript/attribute;", getAttribs), + JF("_getUnmodifiedAttribs", "(J)[Lscript/attribute;", getUnmodifiedAttribs), + JF("_getMaxAttribs", "(J)[Lscript/attribute;", getMaxAttribs), + JF("_getWoundedMaxAttribs", "(J)[Lscript/attribute;", getWoundedMaxAttribs), + JF("_getUnmodifiedMaxAttribs", "(J)[Lscript/attribute;", getUnmodifiedMaxAttribs), + JF("_setAttribs", "(J[Lscript/attribute;)Z", setAttribs), + JF("_setMaxAttribs", "(J[Lscript/attribute;)Z", setMaxAttribs), + JF("_addToAttribs", "(J[Lscript/attribute;)Z", addToAttribs), + JF("_addToMaxAttribs", "(J[Lscript/attribute;)Z", addToMaxAttribs), + JF("_getHitpoints", "(J)I", getHitpoints), + JF("_getMaxHitpoints", "(J)I", getMaxHitpoints), + JF("_getTotalHitpoints", "(J)I", getTotalHitpoints), + JF("_setHitpoints", "(JI)Z", setHitpoints), + JF("_setMaxHitpoints", "(JI)Z", setMaxHitpoints), + JF("_setInvulnerableHitpoints", "(JI)Z", setInvulnerableHitpoints), + JF("_getShockWound", "(J)I", getShockWound), + JF("_setShockWound", "(JI)Z", setShockWound), + JF("_addShockWound", "(JI)Z", addShockWound), + JF("_healShockWound", "(JI)Z", healShockWound), + JF("_drainAttributes", "(JII)Z", drainAttributes), + JF("_testDrainAttribute", "(JII)I", testDrainAttribute), + JF("_addBuffIcon", "(JLjava/lang/String;F)Z", addBuffIcon), + JF("_clearBuffIcon", "(JLjava/lang/String;)Z", clearBuffIcon), + JF("_getRegenRate", "(JI)F", getRegenRate), + JF("_setRegenRate", "(JIF)V", setRegenRate), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +//======================================================================== +// class JavaLibrary internal functions +//======================================================================== + +/** + * Adds an attribute modifier to a creature. + * + * @param env Java environment + * @param creature creature to add the mod to + * @param mod the attrib_mod to add + * + * @return true on success, false on fail + */ +jboolean ScriptMethodsAttributesNamespace::addAttribModifierInternal(JNIEnv *env, CreatureObject * creature, + jobject mod) +{ + if (creature == 0 || mod == 0) + return JNI_FALSE; + + // get the mod's data + AttribMod::AttribMod attribMod; + if (!ScriptConversion::convert(mod, attribMod)) + return JNI_FALSE; + + if (AttribMod::isAttribMod(attribMod) || AttribMod::isDirectDamage(attribMod)) + { + // verify data for mods that affect attribs + if (attribMod.attrib < 0 || attribMod.attrib >= Attributes::NumberOfAttributes) + return JNI_FALSE; + + if (!Attributes::isAttribPool(attribMod.attrib)) + { + if (AttribMod::isDirectDamage(attribMod)) + { + if (ConfigServerGame::getEnableAttribModWarnings()) + { + WARNING(true, ("[script bug] addAttribModifier trying to permanently " + "change non-pool attribute %d for creature %s. This is not allowed, " + "since non-pool attribs don't regen.", attribMod.attrib, + creature->getNetworkId().getValueString().c_str())); + } + JavaLibrary::throwInternalScriptError("JavaLibrary::addAttribModifier " + "trying to permantly modify a non-pool attribute."); + } + if (attribMod.decay == AttribMod::AMDS_pool) + { + WARNING(true, ("[script bug] addAttribModifier trying to change a " + "non-pool attribute %d for creature %s with decay = MOD_POOL", + attribMod.attrib, + creature->getNetworkId().getValueString().c_str())); + return JNI_FALSE; + } + // non-pool mods must change both max and current + attribMod.flags |= + AttribMod::AMF_changeMax | + AttribMod::AMF_attackCurrent | + AttribMod::AMF_decayCurrent; + } + } + else if (AttribMod::isSkillMod(attribMod)) + { + // verify data for mods that affect skillmods + if (attribMod.skill == 0) + { + WARNING(true, ("[script bug] addAttribModifier adding skillmod mod " + "with no skillmod name")); + return JNI_FALSE; + } + } + + if ((attribMod.flags & AttribMod::AMF_triggerOnDone) && attribMod.tag == 0) + { + DEBUG_WARNING(true, ("[script bug] addAttribModifier adding mod with " + "end-trigger but has no name! The trigger will not be called " + "when the mod ends.")); + } + + creature->addAttributeModifier(attribMod); + return JNI_TRUE; +} // JavaLibrary::addAttribModifier + + +//======================================================================== +// class JavaLibrary JNI attribute callback methods +//======================================================================== + +/** + * Returns a creature's attribute. + * + * @param env Java environment + * @param self class calling this function + * @param target id of creature to access + * @param attrib attribute we are interested in + * + * @return the attribute value, or ATTRIB_ERROR on error + */ +jint JNICALL ScriptMethodsAttributesNamespace::getAttrib(JNIEnv *env, jobject self, jlong target, jint attrib) +{ + UNREF(self); + + if (attrib < 0 || attrib >= Attributes::NumberOfAttributes) + return ATTRIB_ERROR; + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return ATTRIB_ERROR; + + return creature->getAttribute(static_cast(attrib)); +} // JavaLibrary::getAttrib + +/** + * Returns a creature's unmodified attribute. + * + * @param env Java environment + * @param self class calling this function + * @param target id of creature to access + * @param attrib attribute we are interested in + * + * @return the attribute value, or ATTRIB_ERROR on error + */ +jint JNICALL ScriptMethodsAttributesNamespace::getUnmodifiedAttrib(JNIEnv *env, jobject self, jlong target, jint attrib) +{ + UNREF(self); + + if (attrib < 0 || attrib >= Attributes::NumberOfAttributes) + return ATTRIB_ERROR; + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return ATTRIB_ERROR; + + return creature->getUnmodifiedAttribute(static_cast(attrib)); +} // JavaLibrary::getUnmodifiedAttrib + +/** + * Returns a creature's max attribute. + * + * @param env Java environment + * @param self class calling this function + * @param target id of creature to access + * @param attrib attribute we are interested in + * + * @return the max attribute value, or ATTRIB_ERROR on error + */ +jint JNICALL ScriptMethodsAttributesNamespace::getMaxAttrib(JNIEnv *env, jobject self, jlong target, jint attrib) +{ + UNREF(self); + + if (attrib < 0 || attrib >= Attributes::NumberOfAttributes) + return ATTRIB_ERROR; + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return ATTRIB_ERROR; + + return creature->getMaxAttribute(static_cast(attrib)); +} // JavaLibrary::getMaxAttrib + +/** + * Returns a creature's max attribute, modified by wounds. + * + * @param env Java environment + * @param self class calling this function + * @param target id of creature to access + * @param attrib attribute we are interested in + * + * @return the max attribute value, or ATTRIB_ERROR on error + */ +jint JNICALL ScriptMethodsAttributesNamespace::getWoundedMaxAttrib(JNIEnv *env, jobject self, jlong target, jint attrib) +{ + UNREF(self); + + if (attrib < 0 || attrib >= Attributes::NumberOfAttributes) + return ATTRIB_ERROR; + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return ATTRIB_ERROR; + + return creature->getMaxAttribute(static_cast(attrib)); +} // JavaLibrary::getWoundedMaxAttrib + +/** + * Returns a creature's unmodified max attribute. + * + * @param env Java environment + * @param self class calling this function + * @param target id of creature to access + * @param attrib attribute we are interested in + * + * @return the max attribute value, or ATTRIB_ERROR on error + */ +jint JNICALL ScriptMethodsAttributesNamespace::getUnmodifiedMaxAttrib(JNIEnv *env, jobject self, jlong target, jint attrib) +{ + UNREF(self); + + if (attrib < 0 || attrib >= Attributes::NumberOfAttributes) + return ATTRIB_ERROR; + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return ATTRIB_ERROR; + + return creature->getUnmodifiedMaxAttribute(static_cast(attrib)); +} // JavaLibrary::getUnmodifiedMaxAttrib + +/** + * Sets a creatue's attribute. + * + * @param env Java environment + * @param self class calling this function + * @param target id of creature to access + * @param attrib attribute we are interested in + * @param value value to set the attribute to + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsAttributesNamespace::setAttrib(JNIEnv *env, jobject self, jlong target, jint attrib, jint value) +{ + UNREF(self); + + if (attrib < 0 || attrib >= Attributes::NumberOfAttributes) + return JNI_FALSE; + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + if (!Attributes::isAttribPool(attrib) && creature->isPlayerControlled()) + { + WARNING(true, ("[designer bug] setAttrib called on player %s for " + "non-pool attribute %d", creature->getNetworkId().getValueString().c_str(), + attrib)); + return JNI_FALSE; + } + + creature->setAttribute(static_cast(attrib), + static_cast(value)); + return JNI_TRUE; +} // JavaLibrary::setAttrib + +/** + * Sets a creatue's max attribute. + * + * @param env Java environment + * @param self class calling this function + * @param target id of creature to access + * @param attrib attribute we are interested in + * @param value value to set the max attribute to + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsAttributesNamespace::setMaxAttrib(JNIEnv *env, jobject self, jlong target, jint attrib, jint value) +{ + UNREF(self); + + if (attrib < 0 || attrib >= Attributes::NumberOfAttributes) + return JNI_FALSE; + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + creature->setMaxAttribute(static_cast(attrib), + static_cast(value)); + return JNI_TRUE; +} // JavaLibrary::setMaxAttrib + +/** + * Adds a value to a creature's attribute. + * + * @param env Java environment + * @param self class calling this function + * @param target id of creature to access + * @param attrib attribute we are interested in + * @param value value to add to the attribute + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsAttributesNamespace::addToAttrib(JNIEnv *env, jobject self, jlong target, jint attrib, jint value) +{ + UNREF(self); + + if (attrib < 0 || attrib >= Attributes::NumberOfAttributes) + return JNI_FALSE; + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + if (!Attributes::isAttribPool(attrib) && creature->isPlayerControlled()) + { + WARNING(true, ("[designer bug] addToAttrib called on player %s for " + "non-pool attribute %d", creature->getNetworkId().getValueString().c_str(), + attrib)); + return JNI_FALSE; + } + + creature->setAttribute(static_cast(attrib), + static_cast((creature->getAttribute( + static_cast(attrib)) + value))); + return JNI_TRUE; +} // JavaLibrary::addToAttrib + +/** + * Adds a value to a creature's max attribute. + * + * @param env Java environment + * @param self class calling this function + * @param target id of creature to access + * @param attrib attribute we are interested in + * @param value value to add to the max attribute + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsAttributesNamespace::addToMaxAttrib(JNIEnv *env, jobject self, jlong target, jint attrib, jint value) +{ + UNREF(self); + + if (attrib < 0 || attrib >= Attributes::NumberOfAttributes) + return JNI_FALSE; + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + creature->setMaxAttribute(static_cast(attrib), + static_cast((creature->getUnmodifiedMaxAttribute( + static_cast(attrib)) + value))); + return JNI_TRUE; +} // JavaLibrary::addToMaxAttrib + +/** + * Adds an attribute modifier to a creature. + * + * @param env Java environment + * @param self class calling this function + * @param target id of creature to access + * @param mod the attrib_mod to add + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsAttributesNamespace::addAttribModifier(JNIEnv *env, jobject self, jlong target, jobject mod) +{ + UNREF(self); + + if (target == 0 || mod == 0) + return JNI_FALSE; + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + return addAttribModifierInternal(env, creature, mod); +} // JavaLibrary::addAttribModifier + +/** + * Adds a series of attribute modifiers to a creature. + * + * @param env Java environment + * @param self class calling this function + * @param target id of creature to access + * @param mods the attrib_mods we want to apply + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsAttributesNamespace::addAttribModifiers(JNIEnv *env, jobject self, jlong target, jobjectArray mods) +{ + UNREF(self); + + if (target == 0 || mods == 0) + return JNI_FALSE; + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + jint count = env->GetArrayLength(mods); + for (int i = 0; i < count; ++i) + { + LocalRef mod(env->GetObjectArrayElement(mods, i)); + if (addAttribModifierInternal(env, creature, mod.getValue()) == JNI_FALSE) + return JNI_FALSE; + } + return JNI_TRUE; +} // JavaLibrary::addAttribModifiers + +/** + * Tests to see if a creature has a given attrib mod or mod group. + * + * @param env Java environment + * @param self class calling this function + * @param target id of creature to test + * @param modName name of the mod we want + * + * @return true if the creature has the mod, false if not + */ +jboolean JNICALL ScriptMethodsAttributesNamespace::hasAttribModifier(JNIEnv *env, jobject self, jlong target, jstring modName) +{ + UNREF(self); + + if (target == 0 || modName == 0) + return JNI_FALSE; + + JavaStringParam jmodName(modName); + std::string name; + if (!JavaLibrary::convert(jmodName, name)) + return JNI_FALSE; + + const CreatureObject * creature = NULL; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + const AttribMod::AttribMod * mod = creature->getAttributeModifier(name); + if (mod != NULL && AttribMod::isAttribMod(*mod)) + return JNI_TRUE; + + return JNI_FALSE; +} // JavaLibrary::hasAttribModifier + +/** + * Tests to see if a creature has a given skill mod or mod group. + * + * @param env Java environment + * @param self class calling this function + * @param target id of creature to test + * @param modName name of the mod we want + * + * @return true if the creature has the mod, false if not + */ +jboolean JNICALL ScriptMethodsAttributesNamespace::hasSkillModModifier(JNIEnv *env, jobject self, jlong target, jstring modName) +{ + UNREF(self); + + if (target == 0 || modName == 0) + return JNI_FALSE; + + JavaStringParam jmodName(modName); + std::string name; + if (!JavaLibrary::convert(jmodName, name)) + return JNI_FALSE; + + const CreatureObject * creature = NULL; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + const AttribMod::AttribMod * mod = creature->getAttributeModifier(name); + if (mod != NULL && AttribMod::isSkillMod(*mod)) + return JNI_TRUE; + + return JNI_FALSE; +} // JavaLibrary::hasSkillModModifier + +/** + * Returns the attribute modifiers on a creature for a given attribute. + * + * @param env Java environment + * @param self class calling this function + * @param target id of creature to access + * @param attrib attribute we are interested in + * + * @return the attribute modifiers for the creature, or null if it has none + */ +jobjectArray JNICALL ScriptMethodsAttributesNamespace::getAttribModifiers(JNIEnv *env, jobject self, jlong target, jint attrib) +{ + typedef std::map ModList; + + UNREF(self); + + if (attrib < 0 || attrib >= Attributes::NumberOfAttributes) + return 0; + + const CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return 0; + + std::vector destMods; + const ModList & sourceMods = creature->getAttributeModifiers(); + for (ModList::const_iterator iter = sourceMods.begin(); iter != sourceMods.end(); + ++iter) + { + if (AttribMod::isAttribMod((*iter).second.mod) && + (*iter).second.mod.attrib == attrib) + { + destMods.push_back((*iter).second.mod); + } + } + + LocalObjectArrayRefPtr result; + if (!ScriptConversion::convert(destMods, result)) + return 0; + + return result->getReturnValue(); +} // JavaLibrary::getAttribModifiers + +/** + * Returns the attribute modifiers on a creature. + * + * @param env Java environment + * @param self class calling this function + * @param target id of creature to access + * + * @return the attribute modifiers for the creature, or null if it has none + */ +jobjectArray JNICALL ScriptMethodsAttributesNamespace::getAllAttribModifiers(JNIEnv *env, jobject self, jlong target) +{ + typedef std::map ModList; + + UNREF(self); + + const CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return 0; + + std::vector destMods; + const ModList & sourceMods = creature->getAttributeModifiers(); + for (ModList::const_iterator iter = sourceMods.begin(); iter != sourceMods.end(); + ++iter) + { + if (AttribMod::isAttribMod((*iter).second.mod)) + destMods.push_back((*iter).second.mod); + } + + LocalObjectArrayRefPtr result; + if (!ScriptConversion::convert(destMods, result)) + return 0; + + return result->getReturnValue(); +} // JavaLibrary::getAllAttribModifiers + +/** + * Removes the attrib/skill mod(s) with a given name. + * + * @param env Java environment + * @param self class calling this function + * @param target id of creature + * @param modName name of the mod we want to remove + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsAttributesNamespace::removeAttribModifier(JNIEnv *env, jobject self, jlong target, jstring modName) +{ + UNREF(self); + + if (target == 0 || modName == 0) + return JNI_FALSE; + + JavaStringParam jmodName(modName); + std::string name; + if (!JavaLibrary::convert(jmodName, name)) + return JNI_FALSE; + + CreatureObject * creature = NULL; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + creature->removeAttributeModifier(name); + return JNI_TRUE; +} // JavaLibrary::removeAttribModifier + +/** + * Removes all the attribute modifiers from a creature. + * + * @param env Java environment + * @param self class calling this function + * @param target id of creature to access + * + * @return JNI_TRUE on success, JNI_FALSE on fail + */ +jboolean JNICALL ScriptMethodsAttributesNamespace::removeAllAttribModifiers(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + creature->removeAllAttributeModifiers(); + + return JNI_TRUE; +} // JavaLibrary::removeAllAttribModifiers + +/** + * Returns all the attributes for a creature. + * + * @param env Java environment + * @param self class calling this function + * @param target id of creature to access + * + * @return the attributes for the creature + */ +jobjectArray JNICALL ScriptMethodsAttributesNamespace::getAttribs(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return 0; + + // create the array of attributes + LocalObjectArrayRefPtr attribs = createNewObjectArray(Attributes::NumberOfAttributes, JavaLibrary::getClsAttribute()); + if (env->ExceptionCheck()) + { + env->ExceptionDescribe(); + return 0; + } + + // set the array elements + for (int i = 0; i < Attributes::NumberOfAttributes; ++i) + { + LocalRefPtr attrib = createNewObject(JavaLibrary::getClsAttribute(), JavaLibrary::getMidAttribute(), + i, creature->getAttribute(static_cast(i))); + if (env->ExceptionCheck()) + { + env->ExceptionDescribe(); + return 0; + } + setObjectArrayElement(*attribs, i, *attrib); + } + return attribs->getReturnValue(); +} // JavaLibrary::getAttribs + +/** + * Returns all the unmodified attributes for a creature. + * + * @param env Java environment + * @param self class calling this function + * @param target id of creature to access + * + * @return the attributes for the creature + */ +jobjectArray JNICALL ScriptMethodsAttributesNamespace::getUnmodifiedAttribs(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return 0; + + // create the array of attributes + LocalObjectArrayRefPtr attribs = createNewObjectArray( + Attributes::NumberOfAttributes, JavaLibrary::getClsAttribute()); + if (env->ExceptionCheck()) + { + env->ExceptionDescribe(); + return 0; + } + + // set the array elements + for (int i = 0; i < Attributes::NumberOfAttributes; ++i) + { + LocalRefPtr attrib = createNewObject(JavaLibrary::getClsAttribute(), JavaLibrary::getMidAttribute(), + i, creature->getUnmodifiedAttribute(static_cast(i))); + if (env->ExceptionCheck()) + { + env->ExceptionDescribe(); + return 0; + } + setObjectArrayElement(*attribs, i, *attrib); + } + return attribs->getReturnValue(); +} // JavaLibrary::getUnmodifiedAttribs + +/** + * Returns all the max attributes for a creature. + * + * @param env Java environment + * @param self class calling this function + * @param target id of creature to access + * + * @return the max attributes for the creature + */ +jobjectArray JNICALL ScriptMethodsAttributesNamespace::getMaxAttribs(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return 0; + + // create the array of attributes + LocalObjectArrayRefPtr attribs = createNewObjectArray( + Attributes::NumberOfAttributes, JavaLibrary::getClsAttribute()); + if (env->ExceptionCheck()) + { + env->ExceptionDescribe(); + return 0; + } + + // set the array elements + for (int i = 0; i < Attributes::NumberOfAttributes; ++i) + { + LocalRefPtr attrib = createNewObject(JavaLibrary::getClsAttribute(), JavaLibrary::getMidAttribute(), + i, creature->getMaxAttribute(static_cast(i))); + if (env->ExceptionCheck()) + { + env->ExceptionDescribe(); + return 0; + } + setObjectArrayElement(*attribs, i, *attrib); + } + return attribs->getReturnValue(); +} // JavaLibrary::getMaxAttribs + +/** + * Returns all the max attributes for a creature, modified by wounds. + * + * @param env Java environment + * @param self class calling this function + * @param target id of creature to access + * + * @return the max attributes for the creature + */ +jobjectArray JNICALL ScriptMethodsAttributesNamespace::getWoundedMaxAttribs(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return 0; + + // create the array of attributes + LocalObjectArrayRefPtr attribs = createNewObjectArray( + Attributes::NumberOfAttributes, JavaLibrary::getClsAttribute()); + if (env->ExceptionCheck()) + { + env->ExceptionDescribe(); + return 0; + } + + // set the array elements + for (int i = 0; i < Attributes::NumberOfAttributes; ++i) + { + LocalRefPtr attrib = createNewObject(JavaLibrary::getClsAttribute(), JavaLibrary::getMidAttribute(), + i, creature->getMaxAttribute(static_cast(i))); + if (env->ExceptionCheck()) + { + env->ExceptionDescribe(); + return 0; + } + setObjectArrayElement(*attribs, i, *attrib); + } + return attribs->getReturnValue(); +} // JavaLibrary::getWoundedMaxAttribs + +/** + * Returns all the unmodified max attributes for a creature. + * + * @param env Java environment + * @param self class calling this function + * @param target id of creature to access + * + * @return the max attributes for the creature + */ +jobjectArray JNICALL ScriptMethodsAttributesNamespace::getUnmodifiedMaxAttribs(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return 0; + + // create the array of attributes + LocalObjectArrayRefPtr attribs = createNewObjectArray( + Attributes::NumberOfAttributes, JavaLibrary::getClsAttribute()); + if (env->ExceptionCheck()) + { + env->ExceptionDescribe(); + return 0; + } + + // set the array elements + for (int i = 0; i < Attributes::NumberOfAttributes; ++i) + { + LocalRefPtr attrib = createNewObject(JavaLibrary::getClsAttribute(), JavaLibrary::getMidAttribute(), + i, creature->getUnmodifiedMaxAttribute(static_cast( + i))); + if (env->ExceptionCheck()) + { + env->ExceptionDescribe(); + return 0; + } + setObjectArrayElement(*attribs, i, *attrib); + } + return attribs->getReturnValue(); +} // JavaLibrary::getUnmodifiedMaxAttribs + +/** + * Sets the attributes for a creature. + * + * @param env Java environment + * @param self class calling this function + * @param target id of creature to access + * @param values attribute/value pairs to set + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsAttributesNamespace::setAttribs(JNIEnv *env, jobject self, jlong target, jobjectArray values) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + int count = env->GetArrayLength(values); + for (int i = 0; i < count; ++i) + { + LocalRefPtr attrib = getObjectArrayElement(LocalObjectArrayRefParam(values), i); + if (attrib == LocalRef::cms_nullPtr) + return JNI_FALSE; + int type = getIntField(*attrib, JavaLibrary::getFidAttributeType()); + if (type < 0 || type >= Attributes::NumberOfAttributes) + return JNI_FALSE; + + creature->setAttribute(static_cast(type), + static_cast(getIntField(*attrib, JavaLibrary::getFidAttributeValue()))); + } + return JNI_TRUE; +} // JavaLibrary::setAttribs + +/** + * Sets the max attributes for a creature. + * + * @param env Java environment + * @param self class calling this function + * @param target id of creature to access + * @param values attribute/value pairs to set + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsAttributesNamespace::setMaxAttribs(JNIEnv *env, jobject self, jlong target, jobjectArray values) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + int count = env->GetArrayLength(values); + for (int i = 0; i < count; ++i) + { + LocalRefPtr attrib = getObjectArrayElement(LocalObjectArrayRefParam(values), i); + if (attrib == LocalRef::cms_nullPtr) + return JNI_FALSE; + int type = getIntField(*attrib, JavaLibrary::getFidAttributeType()); + if (type < 0 || type >= Attributes::NumberOfAttributes) + return JNI_FALSE; + creature->setMaxAttribute(static_cast(type), + static_cast(getIntField(*attrib, + JavaLibrary::getFidAttributeValue())), false); + } + return JNI_TRUE; +} // JavaLibrary::setMaxAttribs + +/** + * Adds values to the attributes for a creature. + * + * @param env Java environment + * @param self class calling this function + * @param target id of creature to access + * @param values attribute/value pairs to add + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsAttributesNamespace::addToAttribs(JNIEnv *env, jobject self, jlong target, jobjectArray values) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + int count = env->GetArrayLength(values); + for (int i = 0; i < count; ++i) + { + LocalRefPtr attrib = getObjectArrayElement(LocalObjectArrayRefParam(values), i); + if (attrib == LocalRef::cms_nullPtr) + return JNI_FALSE; + int type = getIntField(*attrib, JavaLibrary::getFidAttributeType()); + if (type < 0 || type >= Attributes::NumberOfAttributes) + return JNI_FALSE; + + int value = creature->getAttribute(static_cast(type)); + value += getIntField(*attrib, JavaLibrary::getFidAttributeValue()); + creature->setAttribute(static_cast(type), + static_cast(value)); + } + return JNI_TRUE; +} // JavaLibrary::addToAttribs + +/** + * Adds values to the max attributes for a creature. + * + * @param env Java environment + * @param self class calling this function + * @param target id of creature to access + * @param values attribute/value pairs to add + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsAttributesNamespace::addToMaxAttribs(JNIEnv *env, jobject self, jlong target, jobjectArray values) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + int count = env->GetArrayLength(values); + for (int i = 0; i < count; ++i) + { + LocalRefPtr attrib = getObjectArrayElement(LocalObjectArrayRefParam(values), i); + if (attrib == LocalRef::cms_nullPtr) + return JNI_FALSE; + int type = getIntField(*attrib, JavaLibrary::getFidAttributeType()); + if (type < 0 || type >= Attributes::NumberOfAttributes) + return JNI_FALSE; + int value = creature->getUnmodifiedMaxAttribute(static_cast< + Attributes::Enumerator>(type)); + value += getIntField(*attrib, JavaLibrary::getFidAttributeValue()); + creature->setMaxAttribute(static_cast(type), + static_cast(value)); + } + return JNI_TRUE; +} // JavaLibrary::addToMaxAttribs + +//======================================================================== +// class JavaLibrary JNI hitpoint callback methods +//======================================================================== + +/** + * Gets the hitpoints of an object. + * + * @param env Java environment + * @param self class calling this function + * @param target id of object + * + * @return the object's hitpoints, or ATTRIB_ERROR on error + */ +jint JNICALL ScriptMethodsAttributesNamespace::getHitpoints(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + const TangibleObject * object = NULL; + if (!JavaLibrary::getObject(target, object)) + return ATTRIB_ERROR; + + // make sure the object isn't a creature or is a vehicle + if (object->asCreatureObject () != NULL && + !GameObjectTypes::isTypeOf (object->getGameObjectType (), SharedObjectTemplate::GOT_vehicle)) + return ATTRIB_ERROR; + + jint hp = 0; + hp = object->getMaxHitPoints() - object->getDamageTaken(); + return hp; +} // JavaLibrary::getHitpoints + +/** + * Gets the max hitpoints of an object. + * + * @param env Java environment + * @param self class calling this function + * @param target id of object + * + * @return the object's max hitpoints, or ATTRIB_ERROR on error + */ +jint JNICALL ScriptMethodsAttributesNamespace::getMaxHitpoints(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + const TangibleObject * object = NULL; + if (!JavaLibrary::getObject(target, object)) + return ATTRIB_ERROR; + + // make sure the object isn't a creature or is a vehicle + if (object->asCreatureObject () != NULL && + !GameObjectTypes::isTypeOf (object->getGameObjectType (), SharedObjectTemplate::GOT_vehicle)) + return ATTRIB_ERROR; + + return object->getMaxHitPoints(); +} // JavaLibrary::getMaxHitpoints + +/** + * Gets the total hitpoints of an object, including component hitpoints. + * + * @param env Java environment + * @param self class calling this function + * @param target id of object + * + * @return the object's total hitpoints, or ATTRIB_ERROR on error + */ +jint JNICALL ScriptMethodsAttributesNamespace::getTotalHitpoints(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + const TangibleObject * object = NULL; + if (!JavaLibrary::getObject(target, object)) + return ATTRIB_ERROR; + + // make sure the object isn't a creature + // make sure the object isn't a creature or is a vehicle + if (object->asCreatureObject () != NULL && + !GameObjectTypes::isTypeOf (object->getGameObjectType (), SharedObjectTemplate::GOT_vehicle)) + return ATTRIB_ERROR; + + return object->getMaxHitPoints(); +} // JavaLibrary::getTotalHitpoints + +/** + * Sets the hitpoints of an object. Note that if this is used to damage an + * object it will bypass the object's armor! + * + * @param env Java environment + * @param self class calling this function + * @param target id of object + * @param hitPoints the hitpoints to set + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsAttributesNamespace::setHitpoints(JNIEnv *env, jobject self, jlong target, jint hitPoints) +{ + UNREF(self); + + TangibleObject * object = NULL; + if (!JavaLibrary::getObject(target, object)) + return JNI_FALSE; + + // make sure the object isn't a creature or is a vehicle + if (object->asCreatureObject () != NULL && + !GameObjectTypes::isTypeOf (object->getGameObjectType (), SharedObjectTemplate::GOT_vehicle)) + return JNI_FALSE; + + // determine how much "damage" is needed to get the object's hitpoints to the + // right value + int maxHitPoints = object->getMaxHitPoints(); + int currentHitPoints = maxHitPoints - object->getDamageTaken(); + if (hitPoints > maxHitPoints) + hitPoints = maxHitPoints; + + CombatEngineData::DamageData damageData; + struct AttribMod::AttribMod damage; + damage.tag = 0; + damage.attrib = Attributes::Health; + damage.value = hitPoints - currentHitPoints; + damage.attack = 0; + damage.sustain = 0; + damage.decay = AttribMod::AMDS_pool; + damage.flags = AttribMod::AMF_directDamage; + damageData.damage.push_back(damage); + + object->applyDamage(damageData); + return JNI_TRUE; +} // JavaLibrary::setHitpoints + +/** + * Sets the max hitpoints of an object. + * + * @param env Java environment + * @param self class calling this function + * @param target id of object + * @param hitPoints the hitpoints to set + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsAttributesNamespace::setMaxHitpoints(JNIEnv *env, jobject self, jlong target, jint hitPoints) +{ + UNREF(self); + + TangibleObject * object = NULL; + if (!JavaLibrary::getObject(target, object)) + return JNI_FALSE; + + // make sure the object isn't a creature or is a vehicle + if (object->asCreatureObject () != NULL && + !GameObjectTypes::isTypeOf (object->getGameObjectType (), SharedObjectTemplate::GOT_vehicle)) + return JNI_FALSE; + + object->setMaxHitPoints(hitPoints); + return JNI_TRUE; +} // JavaLibrary::setMaxHitpoints + +/** + * Sets the hitpoints of an object, ignoring the invulnerable flag of the object. + * Note that if this is used to damage an object it will bypass the object's armor! + * + * @param env Java environment + * @param self class calling this function + * @param target id of object + * @param hitPoints the hitpoints to set + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsAttributesNamespace::setInvulnerableHitpoints(JNIEnv *env, jobject self, jlong target, jint hitPoints) +{ + UNREF(self); + + TangibleObject * object = NULL; + if (!JavaLibrary::getObject(target, object)) + return JNI_FALSE; + + // make sure the object isn't a creature or is a vehicle + if (object->asCreatureObject () != NULL && + !GameObjectTypes::isTypeOf (object->getGameObjectType (), SharedObjectTemplate::GOT_vehicle)) + return JNI_FALSE; + + // determine how much "damage" is needed to get the object's hitpoints to the + // right value + int maxHitPoints = object->getMaxHitPoints(); + int currentHitPoints = maxHitPoints - object->getDamageTaken(); + if (hitPoints > maxHitPoints) + hitPoints = maxHitPoints; + + CombatEngineData::DamageData damageData; + struct AttribMod::AttribMod damage; + damage.tag = 0; + damage.attrib = Attributes::Health; + damage.value = hitPoints - currentHitPoints; + damage.attack = 0; + damage.sustain = 0; + damage.decay = AttribMod::AMDS_pool; + damage.flags = AttribMod::AMF_directDamage; + damageData.damage.push_back(damage); + damageData.ignoreInvulnerable = true; + + object->applyDamage(damageData); + return JNI_TRUE; +} // JavaLibrary::setInvulnerableHitpoints + +/** + * Returns the shock wound value of a creature. + * + * @param env Java environment + * @param self class calling this function + * @param target id of creature + * + * @return the shock wound value, or ATTRIB_ERROR on error + */ +jint JNICALL ScriptMethodsAttributesNamespace::getShockWound(JNIEnv *env, jobject self, jlong target) +{ + const CreatureObject * creature = NULL; + if (!JavaLibrary::getObject(target, creature)) + return ATTRIB_ERROR; + + return creature->getShockWounds(); +} // JavaLibrary::getShockWound + +/** + * Sets the shock wound value of a creature. + * + * @param env Java environment + * @param self class calling this function + * @param target id of creature + * @param wound the shock wound value + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsAttributesNamespace::setShockWound(JNIEnv *env, jobject self, jlong target, jint wound) +{ + CreatureObject * creature = NULL; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + creature->setShockWounds(wound); + return JNI_TRUE; +} // JavaLibrary::setShockWound + +/** + * Adds to the shock wound value of a creature. + * + * @param env Java environment + * @param self class calling this function + * @param target id of creature + * @param wound the amount to add + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsAttributesNamespace::addShockWound(JNIEnv *env, jobject self, jlong target, jint wound) +{ + CreatureObject * creature = NULL; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + creature->setShockWounds(creature->getShockWounds() + wound); + return JNI_TRUE; +} // JavaLibrary::addShockWound + +/** + * Heals the shock wound value of a creature. + * + * @param env Java environment + * @param self class calling this function + * @param target id of creature + * @param value the amount to heal + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsAttributesNamespace::healShockWound(JNIEnv *env, jobject self, jlong target, jint value) +{ + CreatureObject * creature = NULL; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + creature->setShockWounds(creature->getShockWounds() - value); + return JNI_TRUE; +} // JavaLibrary::healShockWound + +/** + * Drains a creature's pool attributes, based on it's drain attributes. + * + * @param env Java environment + * @param self class calling this function + * @param target creature we want to drain + * @param action amount to drain the creature's action attribute + * @param mind amount to drain the creature's mind attribute + * + * @return JNI_TRUE on success, JNI_FALSE on error + */ +jboolean JNICALL ScriptMethodsAttributesNamespace::drainAttributes(JNIEnv *env, jobject self, jlong target, jint action, jint mind) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + bool result = creature->drainAttributes(static_cast(action), static_cast(mind)); + + if (result) + return JNI_TRUE; + return JNI_FALSE; +} // JavaLibrary::drainAttributes + +/** + * Tests draining an attribute, but does not actually modify the attrib. + * + * @param env Java environment + * @param self class calling this function + * @param target creature we want to drain + * @param attribute the attribute to test + * @param value the amount to drain the attribute by + * + * @return the amount the attribute would be drained by, or -1 on error + */ +jint JNICALL ScriptMethodsAttributesNamespace::testDrainAttribute(JNIEnv *env, jobject self, jlong target, jint attribute, jint value) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return -1; + + int result = creature->testDrainAttribute(static_cast( + attribute), static_cast(value)); + + return result; +} // JavaLibrary::testDrainAttribute + +/** + * Sends a message to a player telling the ui to add a mod icon for a given + * amount of time. The name passed to this function should be from the visible + * attrib mod datatable. + * + * @param env Java environment + * @param self class calling this function + * @param target player to send the info to + * @param modName the mod datatable entry name for the icon to show + * @param time how long to show the icon (<0 = indefinite) + * + * @return true on success, false on error + */ +jboolean JNICALL ScriptMethodsAttributesNamespace::addBuffIcon(JNIEnv *env, jobject self, jlong target, jstring modName, jfloat time) +{ + UNREF(self); + + JavaStringParam jmodName(modName); + + if (target == 0 || modName == 0) + return JNI_FALSE; + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + std::string name; + if (!JavaLibrary::convert(jmodName, name)) + return JNI_FALSE; + + creature->sendTimedModData(Crc::calculate(name.c_str()), time); + return JNI_TRUE; +} // JavaLibrary::addBuffIcon + +/** + * Sends a message to a player telling the ui to remove a mod icon. The name + * passed to this function should be from the visible attrib mod datatable. + * + * @param env Java environment + * @param self class calling this function + * @param target player to send the info to + * @param modName the mod datatable entry name for the icon to show + * + * @return true on success, false on error + */ +jboolean JNICALL ScriptMethodsAttributesNamespace::clearBuffIcon(JNIEnv *env, jobject self, jlong target, jstring modName) +{ + UNREF(self); + + JavaStringParam jmodName(modName); + + if (target == 0 || modName == 0) + return JNI_FALSE; + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + std::string name; + if (!JavaLibrary::convert(jmodName, name)) + return JNI_FALSE; + + creature->sendCancelTimedMod(Crc::calculate(name.c_str())); + return JNI_TRUE; +} // JavaLibrary::clearBuffIcon + +/** + * Returns the regeneration rate of the attribute of a creature. + * + * @param env Java environment + * @param self class calling this function + * @param target player to send the info to + * @param attrib index of the attrib to get (health, action, mind) + * + * @return the regeneration rate, in units/sec + */ +jfloat JNICALL ScriptMethodsAttributesNamespace::getRegenRate(JNIEnv *env, jobject self, jlong target, jint attrib) +{ + const CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return 0; + + return creature->getRegenRate(attrib); +} // ScriptMethodsAttributesNamespace::getRegenRate + +/** + * Sets the regeneration rate of the attribute of a creature. + * + * @param env Java environment + * @param self class calling this function + * @param target player to send the info to + * @param attrib index of the attrib to set (health, action, mind) + * @param value the regen rate, in units/sec + */ +void JNICALL ScriptMethodsAttributesNamespace::setRegenRate(JNIEnv *env, jobject self, jlong target, jint attrib, jfloat value) +{ + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return; + + creature->setRegenRate(attrib, value); +} // ScriptMethodsAttributesNamespace::setRegenRate + + diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsAuction.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsAuction.cpp new file mode 100644 index 00000000..0a76643b --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsAuction.cpp @@ -0,0 +1,304 @@ +//======================================================================== +// +// ScriptMethodsAuction.cpp - implements script methods dealing with bank +// +// copyright 2001 Sony Online Entertainment +// +//======================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "sharedFoundation/DynamicVariable.h" +#include "sharedFoundation/DynamicVariableList.h" +#include "serverGame/CommoditiesMarket.h" +#include "serverGame/ContainerInterface.h" +#include "serverGame/CreatureObject.h" +#include "serverGame/GameServer.h" +#include "serverGame/ServerObject.h" +#include "serverGame/TangibleObject.h" +#include "sharedNetworkMessages/GenericValueTypeMessage.h" +#include "sharedObject/NetworkIdManager.h" +#include "serverScript/GameScriptObject.h" +#include "serverScript/ScriptParameters.h" + +// ====================================================================== +// ScriptMethodsAuctionNamespace +// ====================================================================== + +namespace ScriptMethodsAuctionNamespace +{ + bool install(); + + jboolean JNICALL isCommoditiesServerAvailable(JNIEnv *env, jobject self); + void JNICALL createVendorMarket(JNIEnv *env, jobject script, jlong player, jlong container, jint entranceCharge); + void JNICALL updateVendorValue(JNIEnv *env, jobject script, jlong container); + void JNICALL setSalesTax(JNIEnv *env, jobject script, jint salesTax, jlong bank, jlong container); + void JNICALL requestVendorItemCount(JNIEnv *env, jobject script, jlong vendor); + void JNICALL requestPlayerVendorCount(JNIEnv *env, jobject script, jlong player); + void JNICALL updateVendorSearchOption(JNIEnv *env, jobject self, jlong vendor, jboolean enabled); + void JNICALL setEntranceCharge(JNIEnv *env, jobject self, jlong vendor, jint entranceCharge); + void JNICALL auctionCreatePermanent(JNIEnv *env, jobject script, jstring jownerName, jlong jitem, jlong jauctionContainer, jint cost, jstring userDescription); + void JNICALL removeAllAuctions(JNIEnv *env, jobject script, jlong vendor); + void JNICALL reinitializeVendor(JNIEnv *env, jobject script, jlong vendor, jlong player); + void JNICALL updateVendorStatus(JNIEnv *env, jobject script, jlong vendor, jint status); +} + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsAuctionNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsAuctionNamespace::c)} + JF("isCommoditiesServerAvailable", "()Z", isCommoditiesServerAvailable), + JF("_createVendorMarket", "(JJI)V",createVendorMarket), + JF("_updateVendorValue", "(J)V",updateVendorValue), + JF("_setSalesTax", "(IJJ)V",setSalesTax), + JF("_requestVendorItemCount", "(J)V", requestVendorItemCount), + JF("_requestPlayerVendorCount", "(J)V", requestPlayerVendorCount), + JF("_updateVendorSearchOption", "(JZ)V", updateVendorSearchOption), + JF("_setEntranceCharge", "(JI)V", setEntranceCharge), + JF("_auctionCreatePermanent", "(Ljava/lang/String;JJILjava/lang/String;)V",auctionCreatePermanent), + JF("_removeAllAuctions", "(J)V",removeAllAuctions), + JF("_reinitializeVendor", "(JJ)V",reinitializeVendor), + JF("_updateVendorStatus", "(JI)V", updateVendorStatus), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsAuctionNamespace::isCommoditiesServerAvailable(JNIEnv *env, jobject script) +{ + return CommoditiesMarket::isCommoditiesServerAvailable(); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsAuctionNamespace::createVendorMarket(JNIEnv *env, jobject script, jlong player, jlong container, jint entranceCharge) +{ + ServerObject * sourceObj = 0; + if (!JavaLibrary::getObject(player, sourceObj)) + { + DEBUG_WARNING(true, ("[designer bug] createVendorMarket() player parameter (1) is invalid")); + return; + } + + ServerObject *containerObj = 0; + if (!JavaLibrary::getObject(container, containerObj)) + { + DEBUG_WARNING(true, ("[designer bug] createVendorMarket() container parameter (2) is invalid")); + return; + } + containerObj->makeVendor(); + + CreatureObject *playerObj = dynamic_cast(sourceObj); + if (playerObj) + { + CommoditiesMarket::createVendorMarket(*playerObj, *containerObj, entranceCharge); + } + else + { + DEBUG_WARNING(true, ("[designer bug] createVendorMarket() player parameter (1) is not a creature")); + } +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsAuctionNamespace::auctionCreatePermanent(JNIEnv *env, jobject script, jstring jownerName, jlong jitem, jlong jauctionContainer, jint jprice, jstring juserDescription) +{ + TangibleObject *itemObject = NULL; + ServerObject *containerObj = NULL; + + if (!JavaLibrary::getObject(jitem, itemObject)) + { + DEBUG_WARNING(true, ("[designer bug] auctionCreatePermanent() item parameter (2) is invalid")); + return; + } + + if (!JavaLibrary::getObject(jauctionContainer, containerObj)) + { + DEBUG_WARNING(true, ("[designer bug] auctionCreatePermanent() container parameter (3) is invalid")); + return; + } + + JavaStringParam ownerNameParam(jownerName); + JavaStringParam descriptionParam(juserDescription); + + std::string ownerName; + Unicode::String description; + if(!JavaLibrary::convert(ownerNameParam, ownerName)) + { + DEBUG_WARNING(true, ("[script bug] invalid ownerName passed to auctionCreatePermanent")); + return; + } + if(!JavaLibrary::convert(descriptionParam, description)) + { + DEBUG_WARNING(true, ("[script bug] invalid description passed to auctionCreatePermanent")); + return; + } + + CommoditiesMarket::auctionCreatePermanent(ownerName, *itemObject, + *containerObj, jprice, description); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsAuctionNamespace::updateVendorValue(JNIEnv *env, jobject script, jlong container) +{ + ServerObject *containerObj = 0; + if (!JavaLibrary::getObject(container, containerObj)) + { + DEBUG_WARNING(true, ("[designer bug] updateVendorValue() container parameter (1) is invalid")); + return; + } + + CommoditiesMarket::getVendorValue(*containerObj); +} + +// salesTax is an integer that will be divided by 10000. So a 10% sales tax would be an integer=1000 +void JNICALL ScriptMethodsAuctionNamespace::setSalesTax(JNIEnv *env, jobject script, jint salesTax, jlong bank, jlong container) +{ + ServerObject *containerObj = 0; + ServerObject *bankObj = 0; + if( !JavaLibrary::getObject(container, containerObj) ) + { + DEBUG_WARNING(true, ("[designer bug] setSalesTax() auction container is invalid.")); + return; + } + + // are we setting a sales tax? + if( salesTax!=0 ) + { + // do we have a bank object? + if( !JavaLibrary::getObject(bank, bankObj) ) + { + DEBUG_WARNING(true, ("[designer bug] setSalesTax() bank object is invalid.")); + return; + } + } + + if( salesTax!=0 ) + { + CommoditiesMarket::setSalesTax(salesTax, bankObj->getNetworkId(), *containerObj); + } + else + { + // turn off sales tax for this vendor + CommoditiesMarket::setSalesTax(0, NetworkId(), *containerObj); + } +} + +void JNICALL ScriptMethodsAuctionNamespace::requestVendorItemCount(JNIEnv *env, jobject script, jlong vendor) +{ + ServerObject* vendorObject = NULL; + if( !JavaLibrary::getObject(vendor, vendorObject) ) + { + WARNING(true, ("[designer bug] requestVendorItemLimit() vendor is invalid.")); + return; + } + + CommoditiesMarket::requestVendorItemCount(vendorObject->getNetworkId()); +} + +void JNICALL ScriptMethodsAuctionNamespace::requestPlayerVendorCount(JNIEnv *env, jobject script, jlong player) +{ + ServerObject* playerObject = NULL; + if( !JavaLibrary::getObject(player, playerObject) ) + { + WARNING(true, ("[designer bug] requestPlayerVendorCount() player is invalid.")); + return; + } + + CommoditiesMarket::requestPlayerVendorCount(playerObject->getNetworkId()); +} + +void JNICALL ScriptMethodsAuctionNamespace::updateVendorSearchOption(JNIEnv *env, jobject script, jlong vendor, jboolean enable) +{ + ServerObject* vendorObject = NULL; + bool enabled; + if( !JavaLibrary::getObject(vendor, vendorObject) ) + { + WARNING(true, ("[designer bug] updateVendorSearchOption() vendor is invalid.")); + return; + } + + if (enable == JNI_TRUE) + enabled = true; + else + enabled = false; + CommoditiesMarket::updateVendorSearchOption(vendorObject->getNetworkId(), enabled); +} + +void JNICALL ScriptMethodsAuctionNamespace::setEntranceCharge(JNIEnv *env, jobject script, jlong vendor, jint entranceCharge) +{ + ServerObject* vendorObject = NULL; + if( !JavaLibrary::getObject(vendor, vendorObject) ) + { + WARNING(true, ("[designer bug] setEntranceCharge() vendor is invalid.")); + return; + } + + CommoditiesMarket::setEntranceCharge(vendorObject->getNetworkId(), entranceCharge); +} + +void JNICALL ScriptMethodsAuctionNamespace::removeAllAuctions(JNIEnv *env, jobject script, jlong jvendor) +{ + ServerObject* vendorObject = NULL; + if( !JavaLibrary::getObject(jvendor, vendorObject) ) + { + WARNING(true, ("[designer bug] removeAllAuctions() vendor is invalid.")); + return; + } + + vendorObject->removeAllAuctions(); +} + +void JNICALL ScriptMethodsAuctionNamespace::reinitializeVendor(JNIEnv *env, jobject script, jlong vendor, jlong player) +{ + ServerObject* vendorObject = NULL; + if( !JavaLibrary::getObject(vendor, vendorObject) ) + { + WARNING(true, ("[designer bug] reinitializeVendor() vendor is invalid.")); + return; + } + ServerObject* auctionContainer = vendorObject->getBazaarContainer(); + if ( auctionContainer == NULL ) + { + WARNING(true, ("[designer bug] reinitializeVendor() vendor doesn't have an auction container.")); + return; + } + + + ServerObject* playerObject = NULL; + if ( !JavaLibrary::getObject(player, playerObject) ) + { + WARNING(true, ("[designer bug] reinitializeVendor() player is invalid.")); + return; + } + + NetworkId playerId = playerObject->getNetworkId(); + if( playerId == NetworkId::cms_invalid ) + { + WARNING(true, ("[designer bug] reinitializeVendor() player has an invalid NetworkId.")); + return; + } + + CommoditiesMarket::reinitializeVendor( *auctionContainer, playerId ); +} + +void JNICALL ScriptMethodsAuctionNamespace::updateVendorStatus(JNIEnv *env, jobject script, jlong vendor, jint status) +{ + ServerObject const * vendorObject = NULL; + + if (!JavaLibrary::getObject(vendor, vendorObject)) + { + WARNING(true, ("[designer bug] updateVendorStatus() vendor is invalid.")); + return; + } + + CommoditiesMarket::updateVendorStatus(vendorObject->getNetworkId(), status); +} diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsBank.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsBank.cpp new file mode 100644 index 00000000..75517d1f --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsBank.cpp @@ -0,0 +1,117 @@ +//======================================================================== +// +// ScriptMethodsBank.cpp - implements script methods dealing with bank +// +// copyright 2001 Sony Online Entertainment +// +//======================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "sharedFoundation/DynamicVariable.h" +#include "sharedFoundation/DynamicVariableList.h" + +#include "serverGame/ContainerInterface.h" +#include "serverGame/CreatureObject.h" +#include "serverGame/GameServer.h" +#include "serverGame/ServerObject.h" +#include "sharedNetworkMessages/ClientOpenContainerMessage.h" +#include "sharedNetworkMessages/GenericValueTypeMessage.h" +#include "sharedObject/NetworkIdManager.h" + + +// ====================================================================== +// ScriptMethodsBankNamespace +// ====================================================================== + +namespace ScriptMethodsBankNamespace +{ + bool install(); + + void JNICALL openBankContainer(JNIEnv *env, jobject script, jlong self, jlong player); + void JNICALL quitBank(JNIEnv *env, jobject self, jlong player); + void JNICALL joinBank(JNIEnv *env, jobject self, jlong player, jstring bank); +} + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsBankNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsBankNamespace::c)} + JF("_openBankContainer", "(JJ)V",openBankContainer), + JF("_quitBank", "(J)V",quitBank), + JF("_joinBank", "(JLjava/lang/String;)V",joinBank), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsBankNamespace::openBankContainer(JNIEnv *env, jobject script, jlong self, jlong player) +{ + CreatureObject *playerObj = 0; + ServerObject *bankObj = 0; + if (!JavaLibrary::getObject(player, playerObj) || !JavaLibrary::getObject(self, bankObj)) + return; + + Client *client = playerObj->getClient(); + if (client) + { + ServerObject *bankContainer = playerObj->getBankContainer(); + if (bankContainer) + { + if (!bankContainer->areContentsLoaded()) + { + bankContainer->loadAllContentsFromDB(); + } + else + client->openContainer(*bankContainer, 0, std::string()); + + static const std::string bankLocation("open_bank_location"); + NetworkId bankId = bankObj->getNetworkId(); + playerObj->setObjVarItem(bankLocation, bankId); + } + } +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsBankNamespace::joinBank(JNIEnv *env, jobject self, jlong player, jstring bank) +{ + ServerObject * sourceObj = 0; + if (!JavaLibrary::getObject(player, sourceObj)) + return; + + CreatureObject *playerObj = dynamic_cast(sourceObj); + if (playerObj) + { + Unicode::String myBankName; + + JavaString temp(bank); + if (!JavaLibrary::convert(temp,myBankName)) + return; + playerObj->joinBank(myBankName); + } +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsBankNamespace::quitBank(JNIEnv *env, jobject self, jlong player) +{ + ServerObject * sourceObj = 0; + if (!JavaLibrary::getObject(player, sourceObj)) + return; + + CreatureObject *playerObj = dynamic_cast(sourceObj); + if (playerObj) + { + playerObj->quitBank(); + } +} + +//======================================================================== diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsBeastMaster.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsBeastMaster.cpp new file mode 100644 index 00000000..99e095fe --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsBeastMaster.cpp @@ -0,0 +1,304 @@ +//======================================================================== +// +// ScriptMethodsBeastMaster.cpp - script methods dealing with beastmaster stuff. +// +// copyright 2007 Sony Online Entertainment +// +//======================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" +#include "serverScript/JNIWrappers.h" + +#include "serverGame/CreatureObject.h" +#include "serverGame/PlayerCreatureController.h" +#include "serverGame/PlayerObject.h" +#include "serverGame/ResourceTypeObject.h" +#include "serverGame/ServerObject.h" +#include "serverGame/ServerUniverse.h" +#include "sharedNetworkMessages/IncubatorStartMessage.h" +#include "sharedObject/Controller.h" + +// ====================================================================== +// ScriptMethodsBeastMaster +// ====================================================================== + +using namespace JNIWrappersNamespace; + +namespace ScriptMethodsBeastMasterNamespace +{ + bool install(); + + void JNICALL incubatorStart_development(JNIEnv *env, jobject self, jlong jplayerId, jlong jterminalId ); + void JNICALL incubatorStart(JNIEnv *env, jobject self, + jint jsessionNumber, // I + jlong jplayerId, // J + jlong jterminalId, // J + jint jpowerGauge, // I + jint jinitialPointsSurvival, //I + jint jinitialPointsBeastialResilience, // I + jint jinitialPointsCunning, // I + jint jinitialPointsIntelligence, // I + jint jinitialPointsAggression, // I + jint jinitialPointsHuntersInstinct, // I + jint jtemperatureGauge, // I + jint jnutrientGauge, // I + jint jinitialCreatureColorIndex, // I + jstring jcreatureTemplateName // Ljava/lang/String + ); + jboolean JNICALL setBeastMasterPetCommands(JNIEnv *env, jobject self, jlong objId, jobjectArray value); + jboolean JNICALL setBeastMasterToggledPetCommands(JNIEnv *env, jobject self, jlong objId, jobjectArray value); + void JNICALL setIncubatorPowerResourceName(JNIEnv *env, jobject self, jlong incubatorId, jstring resourceName); +}; + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsBeastMasterNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsBeastMasterNamespace::c)} + JF("_incubatorStart_development", "(JJ)V", incubatorStart_development), + JF("_incubatorStart","(IJJIIIIIIIIIILjava/lang/String;)V",incubatorStart), + JF("_setBeastmasterPetCommands", "(J[Ljava/lang/String;)Z", setBeastMasterPetCommands), + JF("_setBeastmasterToggledPetCommands", "(J[Ljava/lang/String;)Z", setBeastMasterToggledPetCommands), + JF("_setIncubatorPowerResourceName","(JLjava/lang/String;)V",setIncubatorPowerResourceName), + }; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + +//======================================================================== +// class JavaLibrary JNI beastmaster callback methods +//======================================================================== + +void JNICALL ScriptMethodsBeastMasterNamespace::incubatorStart_development(JNIEnv *env, jobject self, jlong jplayerId, jlong jterminalId) +{ + UNREF(env); + UNREF(self); + + ServerObject * playerObj = 0; + if (!JavaLibrary::getObject(jplayerId, playerObj)) + { + WARNING(true, ("bad player passed to JavaLibrary::incubatorStart")); + return; + } + + ServerObject * terminalObj = 0; + if (!JavaLibrary::getObject(jterminalId, terminalObj)) + { + WARNING(true, ("bad terminal passed to JavaLibrary::incubatorStart")); + return; + } + + Controller * const playerController = playerObj->getController(); + if(playerController) + { + // JU_TODO: test data + + IncubatorStartMessage* const msg = new IncubatorStartMessage( + 1, // sessionNumber + playerObj->getNetworkId(), // playerId + NetworkId::cms_invalid, // terminalId + 75, // powerGauge + 2, // initialPointsSurvival + 3, // initialPointsBeastialReilience, + 4, // initialPointsCunning + 5, // initialPointsIntelligence + 6, // initialPointsAggression + 7, // initialPointsHuntersInstinct + 2, // temperatureGauge + 1, // nutrientGauge + -1, // initialCreatureColorIndex + "foobar_deadbeef" // creatureTemplateName + ); + + playerController->appendMessage(CM_incubatorStart, 0, msg, GameControllerMessageFlags::SEND | GameControllerMessageFlags::RELIABLE | GameControllerMessageFlags::DEST_AUTH_CLIENT); + } +} + +//------------------------------------------------------------------------ + +void JNICALL ScriptMethodsBeastMasterNamespace::incubatorStart(JNIEnv *env, jobject self, + jint jsessionNumber, // I + jlong jplayerId, // J + jlong jterminalId, // J + jint jpowerGauge, // I + jint jinitialPointsSurvival, //I + jint jinitialPointsBeastialResilience, // I + jint jinitialPointsCunning, // I + jint jinitialPointsIntelligence, // I + jint jinitialPointsAggression, // I + jint jinitialPointsHuntersInstinct, // I + jint jtemperatureGauge, // I + jint jnutrientGauge, // I + jint jinitialCreatureColorIndex, // I + jstring jcreatureTemplateName // Ljava/lang/String + ) +{ + UNREF(env); + UNREF(self); + + ServerObject * playerObj = 0; + if (!JavaLibrary::getObject(jplayerId, playerObj)) + { + WARNING(true, ("bad player passed to JavaLibrary::incubatorStart")); + return; + } + + ServerObject * terminalObj = 0; + if (!JavaLibrary::getObject(jterminalId, terminalObj)) + { + WARNING(true, ("bad terminal passed to JavaLibrary::incubatorStart")); + return; + + } + + JavaStringParam localCreatureTemplateName(jcreatureTemplateName); + std::string creatureTemplateName; + if (!JavaLibrary::convert(localCreatureTemplateName, creatureTemplateName)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JNICALL incubatorStart - could not resolve creature template name")); + return; + } + + Controller * const playerController = playerObj->getController(); + if(playerController) + { + IncubatorStartMessage* const msg = new IncubatorStartMessage( + jsessionNumber, // sessionNumber + playerObj->getNetworkId(), // playerId + terminalObj->getNetworkId(), // terminalId + jpowerGauge, // powerGauge + jinitialPointsSurvival, // initialPointsSurvival + jinitialPointsBeastialResilience, // initialPointsBeastialReilience, + jinitialPointsCunning, // initialPointsCunning + jinitialPointsIntelligence, // initialPointsIntelligence + jinitialPointsAggression, // initialPointsAggression + jinitialPointsHuntersInstinct, // initialPointsHuntersInstinct + jtemperatureGauge, // temperatureGauge + jnutrientGauge, // nutrientGauge + jinitialCreatureColorIndex, // initialCreatureColorIndex + creatureTemplateName // creatureTemplateName + ); + + playerController->appendMessage(CM_incubatorStart, 0, msg, GameControllerMessageFlags::SEND | GameControllerMessageFlags::RELIABLE | GameControllerMessageFlags::DEST_AUTH_CLIENT); + } +} + +jboolean JNICALL ScriptMethodsBeastMasterNamespace::setBeastMasterPetCommands(JNIEnv *env, jobject self, jlong objId, jobjectArray value) +{ + if (objId == 0 || value == 0) + return JNI_FALSE; + + if (env->IsInstanceOf(value, JavaLibrary::getClsStringArray()) == JNI_FALSE) + return JNI_FALSE; + + + CreatureObject *creatureObject = 0; + if (!JavaLibrary::getObject(objId, creatureObject)) + { + WARNING(true, ("ScriptMethodsBeastMasterNamespace::setBeastMasterPetCommands() Object could not be resolved to a CreatureObject")); + return JNI_FALSE; + } + + PlayerObject *po = PlayerCreatureController::getPlayerObject(creatureObject); + + if(!po) + { + WARNING(true, ("ScriptMethodsBeastMasterNamespace::setBeastMasterPetCommands() Object has no player object")); + return JNI_FALSE; + } + + std::vector commands; + size_t size = env->GetArrayLength(value); + commands.resize(size); + + for (size_t i = 0; i < size; ++i) + { + JavaStringPtr item = getStringArrayElement(LocalObjectArrayRefParam(value), i); + if (item != JavaString::cms_nullPtr) + JavaLibrary::convert(*item, commands[i]); + else + commands[i] = ""; + } + po->setPetCommandList(commands); + return JNI_TRUE; +} + +jboolean JNICALL ScriptMethodsBeastMasterNamespace::setBeastMasterToggledPetCommands(JNIEnv *env, jobject self, jlong objId, jobjectArray value) +{ + if (objId == 0 || value == 0) + return JNI_FALSE; + + if (env->IsInstanceOf(value, JavaLibrary::getClsStringArray()) == JNI_FALSE) + return JNI_FALSE; + + + CreatureObject *creatureObject = 0; + if (!JavaLibrary::getObject(objId, creatureObject)) + { + WARNING(true, ("ScriptMethodsBeastMasterNamespace::setBeastMasterToggledPetCommands() Object could not be resolved to a CreatureObject")); + return JNI_FALSE; + } + + PlayerObject *po = PlayerCreatureController::getPlayerObject(creatureObject); + + if(!po) + { + WARNING(true, ("ScriptMethodsBeastMasterNamespace::setBeastMasterToggledPetCommands() Object has no player object")); + return JNI_FALSE; + } + + std::vector commands; + size_t size = env->GetArrayLength(value); + commands.resize(size); + + for (size_t i = 0; i < size; ++i) + { + JavaStringPtr item = getStringArrayElement(LocalObjectArrayRefParam(value), i); + if (item != JavaString::cms_nullPtr) + JavaLibrary::convert(*item, commands[i]); + else + commands[i] = ""; + } + po->setPetToggledCommands(commands); + return JNI_TRUE; +} + +void JNICALL ScriptMethodsBeastMasterNamespace::setIncubatorPowerResourceName(JNIEnv *env, jobject self, jlong incubatorId, jstring resourceName) +{ + UNREF(env); + UNREF(self); + + ServerObject * incubatorObj = 0; + if (!JavaLibrary::getObject(incubatorId, incubatorObj)) + return; + + if (!incubatorObj->asTangibleObject()) + return; + + if (resourceName == 0) + return; + + JavaStringParam jspResourceName(resourceName); + std::string sResourceName; + if (!JavaLibrary::convert(jspResourceName, sResourceName)) + return; + + if (sResourceName.empty()) + return; + + IGNORE_RETURN(incubatorObj->setObjVarItem("power.name", sResourceName)); + + // store additional information if the resource is an imported resource from another galaxy + ResourceTypeObject const * const rto = ServerUniverse::getInstance().getResourceTypeByName(sResourceName); + if (rto && (rto->getNetworkId().getValue() > NetworkId::cms_maxNetworkIdWithoutClusterId)) + { + std::string const resourceData = rto->getResourceTypeDataForExport(); + + if (!resourceData.empty()) + IGNORE_RETURN(incubatorObj->setObjVarItem("power.resourceData", resourceData)); + } +} diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsBroadcasting.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsBroadcasting.cpp new file mode 100644 index 00000000..aaea9f3c --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsBroadcasting.cpp @@ -0,0 +1,147 @@ +//======================================================================== +// +// ScriptMethodsBroadcasting.cpp - implements script methods dealing +// with broadcasting +// +// copyright 2001 Sony Online Entertainment +// +//======================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "serverGame/ServerObject.h" +#include "sharedObject/CachedNetworkId.h" + +#include + +using namespace JNIWrappersNamespace; + + +// ====================================================================== +// ScriptMethodsBroadcastingNamespace +// ====================================================================== + +namespace ScriptMethodsBroadcastingNamespace +{ + bool install(); + + void JNICALL listenToMessage(JNIEnv *env, jobject self, jlong listener, jlong emitter, jstring messageHandlerName); + void JNICALL stopListeningToMessage(JNIEnv *env, jobject self, jlong listener, jlong emitter, jstring messageHandlerName); + jlongArray JNICALL getMessageListeners(JNIEnv *env, jobject self, jlong emitter, jstring messageHandlerName); +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsBroadcastingNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsBroadcastingNamespace::c)} + JF("_listenToMessage", "(JJLjava/lang/String;)V", listenToMessage), + JF("_stopListeningToMessage", "(JJLjava/lang/String;)V", stopListeningToMessage), + JF("_getMessageListeners", "(JLjava/lang/String;)[J", getMessageListeners), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + +//-------------------------------------------------------------------------------------- + +void JNICALL ScriptMethodsBroadcastingNamespace::listenToMessage(JNIEnv *env, jobject self, jlong listener, jlong emitter, jstring messageHandlerName) +{ + UNREF(self); + + if (listener == 0 || emitter == 0 || messageHandlerName == 0) + return; + + JavaStringParam localMessageHandlerName(messageHandlerName); + + CachedNetworkId listenerId(listener); + CachedNetworkId emitterId(emitter); + + ServerObject* listenerObject = dynamic_cast(listenerId.getObject()); + if (listenerObject == NULL) + return; + + std::string messageHandlerNameString; + JavaLibrary::convert(localMessageHandlerName, messageHandlerNameString); + listenerObject->listenToBroadcastMessage(messageHandlerNameString, emitterId); + + return; +} // JavaLibrary::listenToMessage + +//-------------------------------------------------------------------------------------- + +void JNICALL ScriptMethodsBroadcastingNamespace::stopListeningToMessage(JNIEnv *env, jobject self, jlong listener, jlong emitter, jstring messageHandlerName) +{ + UNREF(self); + + if (listener == 0 || emitter == 0 || messageHandlerName == 0) + return; + + JavaStringParam localMessageHandlerName(messageHandlerName); + + CachedNetworkId listenerId(listener); + CachedNetworkId emitterId(emitter); + + ServerObject* listenerObject = dynamic_cast(listenerId.getObject()); + if (listenerObject == NULL) + return; + + std::string messageHandlerNameString; + JavaLibrary::convert(localMessageHandlerName, messageHandlerNameString); + listenerObject->stopListeningToBroadcastMessage(messageHandlerNameString, emitterId); + + return; +} // JavaLibrary::stopListeningToMessage + +//-------------------------------------------------------------------------------------- + +jlongArray JNICALL ScriptMethodsBroadcastingNamespace::getMessageListeners(JNIEnv *env, jobject self, jlong emitter, jstring messageHandlerName) +{ + UNREF(self); + + if (emitter == 0 || messageHandlerName == 0) + return 0; + + JavaStringParam localMessageHandlerName(messageHandlerName); + + CachedNetworkId emitterId(emitter); + + ServerObject* emitterObject = dynamic_cast(emitterId.getObject()); + if (emitterObject == NULL) + return 0; + + std::string messageHandlerNameString; + JavaLibrary::convert(localMessageHandlerName, messageHandlerNameString); + + // the listener list is a set of , and we + // need to quickly locate the first entry in the set that contains the + // messageHandlerName we are looking for + static const NetworkId s_minNetworkId(std::numeric_limits::min()); + ServerObject::BroadcastMap const & listeners = emitterObject->getBroadcastListeners(); + std::vector listenerIds; + + for (ServerObject::BroadcastMap::const_iterator iter = listeners.lower_bound(std::make_pair(messageHandlerNameString, s_minNetworkId)); ((iter != listeners.end()) && (iter->first == messageHandlerNameString)); ++iter) + listenerIds.push_back(iter->second); + + if (listenerIds.empty()) + return 0; + + size_t count = listenerIds.size(); + LocalLongArrayRefPtr listenerIdsArray = createNewLongArray(count); + if (listenerIdsArray == LocalLongArrayRef::cms_nullPtr) + return 0; + + jlong jlongTmp; + for (size_t i = 0; i < count; ++i) + { + jlongTmp = listenerIds[i].getValue(); + setLongArrayRegion(*listenerIdsArray, i, 1, &jlongTmp); + } + + return listenerIdsArray->getReturnValue(); +} // JavaLibrary::getMessageListeners diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsBuff.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsBuff.cpp new file mode 100644 index 00000000..706ef92f --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsBuff.cpp @@ -0,0 +1,472 @@ +//======================================================================== +// +// ScriptMethodsBuff.cpp - implements script methods dealing armor. +// +// copyright 2001 Sony Online Entertainment +// +//======================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" +#include "serverGame/BuffManager.h" +#include "serverGame/ConfigServerGame.h" +#include "serverGame/CreatureObject.h" +#include "serverGame/PlayerCreatureController.h" +#include "serverGame/ServerArmorTemplate.h" +#include "serverGame/PlayerObject.h" +#include "serverGame/TangibleObject.h" +#include "sharedFile/TreeFile.h" +#include "sharedFoundation/DynamicVariableList.h" +#include "sharedObject/ObjectTemplateList.h" +#include "swgSharedUtility/Attributes.def" +#include "serverUtility/ServerClock.h" + +using namespace JNIWrappersNamespace; + + +// ====================================================================== +// ScriptMethodsBuffNamespace +// ====================================================================== + +namespace ScriptMethodsBuffNamespace +{ + bool install(); + + jboolean JNICALL addBuff(JNIEnv *env, jobject self, jlong target, jint nameCrc); + jboolean JNICALL addBuffCaster(JNIEnv *env, jobject self, jlong target, jlong caster, jint nameCrc); + jboolean JNICALL addBuffWithDuration(JNIEnv *env, jobject self, jlong target, jint nameCrc, jfloat duration, jfloat value); + jboolean JNICALL addBuffWithDurationCaster(JNIEnv *env, jobject self, jlong target, jlong caster, jint nameCrc, jfloat duration, jfloat value); + jboolean JNICALL addBuffDurationCasterStack(JNIEnv *env, jobject self, jlong target, jlong caster, jint nameCrc, jfloat duration, jfloat value, jint count); + jboolean JNICALL removeBuff(JNIEnv *env, jobject self, jlong target, jint nameCrc); + jboolean JNICALL hasBuff(JNIEnv *env, jobject self, jlong target, jint nameCrc); + jintArray JNICALL getAllBuffs(JNIEnv *env, jobject self, jlong target); + jfloat JNICALL getBuffTimeRemaining(JNIEnv *env, jobject self, jlong target, jint nameCrc); + jfloat JNICALL getBuffCustomValue(JNIEnv *env, jobject self, jlong target, jint nameCrc); + jlong JNICALL getBuffStackCount(JNIEnv *env, jobject self, jlong target, jint nameCrc); + jboolean JNICALL decrementBuffStack(JNIEnv *env, jobject self, jlong target, jint nameCrc, jint stacksToRemove); + jlong JNICALL getBuffCaster(JNIEnv *env, jobject self, jlong target, jint nameCrc); + jboolean JNICALL decayBuff(JNIEnv *env, jobject self, jlong target, jint nameCrc, jfloat decayPercent); +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsBuffNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsBuffNamespace::c)} + JF("__addBuff", "(JI)Z", addBuff), + JF("__addBuff", "(JJI)Z", addBuffCaster), + JF("__addBuff", "(JIFF)Z", addBuffWithDuration), + JF("__addBuff", "(JJIFF)Z", addBuffWithDurationCaster), + JF("__addBuff", "(JJIFFI)Z", addBuffDurationCasterStack), + JF("__removeBuff", "(JI)Z", removeBuff), + JF("__hasBuff", "(JI)Z", hasBuff), + JF("__getAllBuffs", "(J)[I", getAllBuffs), + JF("__getBuffTimeRemaining", "(JI)F", getBuffTimeRemaining), + JF("__getBuffCustomValue", "(JI)F", getBuffCustomValue), + JF("__getBuffStackCount", "(JI)J", getBuffStackCount), + JF("__decrementBuffStack", "(JII)Z", decrementBuffStack), + JF("__getBuffCaster", "(JI)J", getBuffCaster), + JF("__decayBuff", "(JIF)Z", decayBuff), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +//======================================================================== +// class JavaLibrary JNI buff callback methods +//======================================================================== + +/** + * Adds a buff to a creature. + * + * @param env Java environment + * @param self class calling this function + * @param target the creature to add the buff to + * @param nameCrc crc of the name of the buff to add + * + * @return false if an error occurred + */ +jboolean JNICALL ScriptMethodsBuffNamespace::addBuff(JNIEnv *env, jobject self, jlong target, jint nameCrc) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + creature->addBuff(nameCrc); + return JNI_TRUE; +} // JavaLibrary::addBuff + +//-------------------------------------------------------- + +/** +* Adds a buff to a creature. +* +* @param env Java environment +* @param self class calling this function +* @param target the creature to add the buff to +* @param nameCrc crc of the name of the buff to add +* +* @return false if an error occurred +*/ +jboolean JNICALL ScriptMethodsBuffNamespace::addBuffCaster(JNIEnv *env, jobject self, jlong target, jlong caster, jint nameCrc) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + + creature->addBuff(nameCrc, 0.0f, 0.0f, NetworkId(caster)); + return JNI_TRUE; +} // JavaLibrary::addBuff + +//-------------------------------------------------------- + +/** +* Adds a buff to a creature. +* +* @param env Java environment +* @param self class calling this function +* @param target the creature to add the buff to +* @param nameCrc crc of the name of the buff to add +* @param duration float in seconds of the buff duration, or 0 as default +* @param value a float value that replaces the first effect's strength +* +* @return false if an error occurred +*/ +jboolean JNICALL ScriptMethodsBuffNamespace::addBuffWithDurationCaster(JNIEnv *env, jobject self, jlong target, jlong caster, jint nameCrc, jfloat duration, jfloat value) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + creature->addBuff( nameCrc, duration, value, NetworkId(caster)); + return JNI_TRUE; +} + +//-------------------------------------------------------- + +/** +* Adds a buff to a creature. +* +* @param env Java environment +* @param self class calling this function +* @param target the creature to add the buff to +* @param nameCrc crc of the name of the buff to add +* @param duration float in seconds of the buff duration, or 0 as default +* @param value a float value that replaces the first effect's strength +* @param count the stack count to apply +* +* @return false if an error occurred +*/ +jboolean JNICALL ScriptMethodsBuffNamespace::addBuffDurationCasterStack(JNIEnv *env, jobject self, jlong target, jlong caster, jint nameCrc, jfloat duration, jfloat value, jint count) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + creature->addBuff( nameCrc, duration, value, NetworkId(caster), count); + return JNI_TRUE; +} + +//-------------------------------------------------------- + +/** + * Adds a buff to a creature. + * + * @param env Java environment + * @param self class calling this function + * @param target the creature to add the buff to + * @param nameCrc crc of the name of the buff to add + * @param duration float in seconds of the buff duration, or 0 as default + * @param value a float value that replaces the first effect's strength + * + * @return false if an error occurred + */ +jboolean JNICALL ScriptMethodsBuffNamespace::addBuffWithDuration(JNIEnv *env, jobject self, jlong target, jint nameCrc, jfloat duration, jfloat value) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + creature->addBuff(nameCrc, duration, value); + return JNI_TRUE; +} // JavaLibrary::addBuffWithDuration + +//-------------------------------------------------------- + +/** + * Removes a buff from a creature. Remember buffs expire naturally. + * + * @param env Java environment + * @param self class calling this function + * @param target the creature to remove the buff from + * @param nameCrc crc of the name of the buff to remove + * + * @return false if an error occurred + */ +jboolean JNICALL ScriptMethodsBuffNamespace::removeBuff(JNIEnv *env, jobject self, jlong target, jint nameCrc) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + creature->removeBuff(nameCrc); + return JNI_TRUE; +} // JavaLibrary::removeBuff + +//-------------------------------------------------------- + +/** + * Does this creature have this buff? + * + * @param env Java environment + * @param self class calling this function + * @param target the creature to check + * @param nameCrc crc of the name of the buff to check + * + * @return false if an error occurred + */ +jboolean JNICALL ScriptMethodsBuffNamespace::hasBuff(JNIEnv *env, jobject self, jlong target, jint nameCrc) +{ + UNREF(self); + + CreatureObject const * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + return static_cast(creature->hasBuff(nameCrc) ? JNI_TRUE : JNI_FALSE); +} // JavaLibrary::hasBuff + +//-------------------------------------------------------- + +/** + * Return the crcs of all the buffs the creature has + * + * @param env Java environment + * @param self class calling this function + * @param target the creature to get buffs for + * + * @return false if an error occurred + */ +jintArray JNICALL ScriptMethodsBuffNamespace::getAllBuffs(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + CreatureObject const * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + std::vector buffCrcs; + creature->getAllBuffs(buffCrcs); + + LocalIntArrayRefPtr valueArray = createNewIntArray(buffCrcs.size()); + if (valueArray == LocalIntArrayRef::cms_nullPtr) + return 0; + + setIntArrayRegion(*valueArray, 0, buffCrcs.size(), reinterpret_cast(&buffCrcs[0]) ); + return valueArray->getReturnValue(); + + +} // JavaLibrary::getAllBuffs + +//-------------------------------------------------------- + +/** + * Return the time remaining on this buff for this character + * + * @param env Java environment + * @param self class calling this function + * @param target the creature to get buff for + * @param nameCrc the buff crc to get info for + * + * @return -1 / 0 for the 2 different "timeless" buffs, otherwise return the time left in seconds. + */ +jfloat JNICALL ScriptMethodsBuffNamespace::getBuffTimeRemaining(JNIEnv *env, jobject self, jlong target, jint nameCrc) +{ + UNREF(self); + + CreatureObject const * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return 0.0f; + + Buff b; + if(!creature->getBuff(nameCrc, b)) + return 0.0f; + if (creature->isPlayerControlled()) + { + PlayerObject const * const playerObject = PlayerCreatureController::getPlayerObject(creature); + if (playerObject && playerObject->isInitialized()) + { + uint32 currentTime = playerObject->getPlayedTime(); + + if (BuffManager::getBuffIsCelestial(nameCrc)) + { + currentTime = ServerClock::getInstance().getGameTimeSeconds(); + } + + jfloat timeLeft = 0.0f; + + if (b.m_timestamp == 0xFFFFFFFF) + { + timeLeft = -1.0f; + } + else if (b.m_timestamp == 0) + { + timeLeft = 0.0f; + } + else + { + timeLeft = static_cast( static_cast(b.m_timestamp) - static_cast(currentTime)); + } + + return timeLeft; + } + } + return static_cast(b.m_timestamp - creature->getPseudoPlayedTime()); +} // JavaLibrary::getBuffTimeRemaining + +//-------------------------------------------------------- + +/** + * Return the time remaining on this buff for this character + * + * @param env Java environment + * @param self class calling this function + * @param target the creature to get buff for + * @param nameCrc the buff crc to get info for + * + * @return 0 if the buff doesn't exist - time is in seconds + */ +jfloat JNICALL ScriptMethodsBuffNamespace::getBuffCustomValue(JNIEnv *env, jobject self, jlong target, jint nameCrc) +{ + UNREF(self); + + CreatureObject const * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return 0.0f; + + Buff b; + if(!creature->getBuff(nameCrc, b)) + return 0.0f; + return static_cast(b.m_value); +} // JavaLibrary::getBuffCustomValue + +//-------------------------------------------------------- + +/** +* Return the current stack count of the buff +* +* @param env Java environment +* @param self class calling this function +* @param target the creature to get buff for +* @param nameCrc the buff crc to get info for +* +* @return 0 if the buff doesn't exist - otherwise return the stackcount +*/ +jlong JNICALL ScriptMethodsBuffNamespace::getBuffStackCount(JNIEnv *env, jobject self, jlong target, jint nameCrc) +{ + UNREF(self); + + CreatureObject const * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return 0; + + Buff b; + if(!creature->getBuff(nameCrc, b)) + return 0; + + return static_cast(b.m_stackCount); +} // JavaLibrary::getBuffStackCount + +//-------------------------------------------------------- + +/** +* Return true if the buff stack was decremented +* +* @param env Java environment +* @param self class calling this function +* @param target the creature to decrement +* @param nameCrc the buff crc to get info for +* +* @return false if the buff doesn't exist - true if it succeeded +*/ +jboolean JNICALL ScriptMethodsBuffNamespace::decrementBuffStack(JNIEnv *env, jobject self, jlong target, jint nameCrc, jint stacksToRemove) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + Buff b; + if(!creature->getBuff(nameCrc, b)) + return JNI_FALSE; + + creature->decrementBuff(nameCrc, stacksToRemove); + + return JNI_TRUE; +} // JavaLibrary::decrementBuffStack + +//-------------------------------------------------------- + +/** +* Return the OID of the buff caster +* +* @param env Java environment +* @param self class calling this function +* @param target the creature to get buff for +* @param nameCrc the buff crc to get info for +* +* @return -1 if the buff or creature cant be found, 0 will return if no OID was supplied originally +*/ +jlong JNICALL ScriptMethodsBuffNamespace::getBuffCaster(JNIEnv *env, jobject self, jlong target, jint nameCrc) +{ + UNREF(self); + + CreatureObject const * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return -1; + + Buff b; + if(!creature->getBuff(nameCrc, b)) + return -1; + + return static_cast(b.m_caster.getValue()); +} // JavaLibrary::getBuffCaster + +//-------------------------------------------------------- + +jboolean JNICALL ScriptMethodsBuffNamespace::decayBuff(JNIEnv *env, jobject self, jlong target, jint nameCrc, jfloat decayPercent) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + if(!creature->hasBuff(nameCrc)) + return JNI_FALSE; + + creature->decayBuff(nameCrc, decayPercent); + + return JNI_TRUE; +} + +//-------------------------------------------------------- diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsBuffBuilder.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsBuffBuilder.cpp new file mode 100644 index 00000000..3f9b5cea --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsBuffBuilder.cpp @@ -0,0 +1,218 @@ +//======================================================================== +// +// ScriptMethodsBuffBuilder.cpp - script methods dealing with the buff builder. +// +// copyright 2006 Sony Online Entertainment +// +//======================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "serverGame/Chat.h" +#include "serverGame/ServerBuffBuilderManager.h" +#include "serverGame/ServerObject.h" +#include "sharedFoundation/Os.h" +#include "sharedGame/SharedBuffBuilderManager.h" +#include "sharedGame/SharedStringIds.h" +#include "sharedNetworkMessages/BuffBuilderStartMessage.h" +#include "sharedObject/Controller.h" + + +// ====================================================================== +// ScriptMethodsBuffBuilderNamespace +// ====================================================================== + +namespace ScriptMethodsBuffBuilderNamespace +{ + bool install(); + + void JNICALL buffBuilderStart(JNIEnv *env, jobject self, jlong jbufferId, jlong jrecipientId ); + jboolean JNICALL buffBuilderValidated(JNIEnv *env, jobject self, + jlong jbufferId, + jlong jrecipientId, + + jint jstartingTime, + jint jbufferRequiredCredits, + jint jrecipientPaidCredits, + + jboolean jaccepted, + jobjectArray jbuffComponentKeys, + jintArray jbuffComponentValues); +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsBuffBuilderNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsBuffBuilderNamespace::c)} + JF("_buffBuilderStart", "(JJ)V", buffBuilderStart), + JF("_buffBuilderValidated", "(JJIIIZ[Ljava/lang/String;[I)Z", buffBuilderValidated) +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +//======================================================================== +// class JavaLibrary JNI buff builder callback methods +//======================================================================== + +void JNICALL ScriptMethodsBuffBuilderNamespace::buffBuilderStart(JNIEnv *env, jobject self, jlong jbufferId, jlong jrecipientId) +{ + UNREF(env); + UNREF(self); + ServerObject * bufferObj = 0; + if (!JavaLibrary::getObject(jbufferId, bufferObj)) + { + WARNING(true, ("bad buffer passed to JavaLibrary::buffBuilderStart")); + return; + } + + ServerObject * recipientObj = 0; + if (!JavaLibrary::getObject(jrecipientId, recipientObj)) + { + WARNING(true, ("bad recipient passed to JavaLibrary::buffBuilderStart")); + return; + } + + SharedBuffBuilderManager::Session newSession; + newSession.bufferId = bufferObj->getNetworkId(); + newSession.recipientId = recipientObj->getNetworkId(); + newSession.startingTime = Os::getRealSystemTime(); + + SharedBuffBuilderManager::startSession(newSession); + + Controller * const bufferController = bufferObj->getController(); + if(bufferController) + { + BuffBuilderStartMessage * const msg = new BuffBuilderStartMessage(bufferObj->getNetworkId(), recipientObj->getNetworkId()); + bufferController->appendMessage(CM_buffBuilderStart, 0, msg, GameControllerMessageFlags::SEND | GameControllerMessageFlags::RELIABLE | GameControllerMessageFlags::DEST_AUTH_CLIENT); + } + + Controller * const recipientController = recipientObj->getController(); + if(recipientController && recipientController != bufferController) + { + BuffBuilderStartMessage * const msg = new BuffBuilderStartMessage(bufferObj->getNetworkId(), recipientObj->getNetworkId()); + recipientController->appendMessage(CM_buffBuilderStart, 0, msg, GameControllerMessageFlags::SEND | GameControllerMessageFlags::RELIABLE | GameControllerMessageFlags::DEST_AUTH_CLIENT); + } +} + +//------------------------------------------------------------------------ + +jboolean JNICALL ScriptMethodsBuffBuilderNamespace::buffBuilderValidated(JNIEnv *env, jobject self, jlong jbufferId, jlong jrecipientId, jint jstartingTime, jint jbufferRequiredCredits, jint jrecipientPaidCredits, jboolean jaccepted, jobjectArray jbuffComponentKeys, jintArray jbuffComponentValues) +{ + UNREF(self); + UNREF(jrecipientPaidCredits); + + SharedBuffBuilderManager::Session session; + ServerObject * bufferObj = 0; + if (!JavaLibrary::getObject(jbufferId, bufferObj) || !bufferObj) + { + WARNING(true, ("bad buffer passed to JavaLibrary::buffBuilderValidated")); + return JNI_FALSE; + } + + ServerObject * recipientObj = 0; + if (!JavaLibrary::getObject(jrecipientId, recipientObj) || !recipientObj) + { + WARNING(true, ("bad recipient passed to JavaLibrary::buffBuilderValidated")); + return JNI_FALSE; + } + + session.bufferId = bufferObj->getNetworkId(); + session.recipientId = recipientObj->getNetworkId(); + session.startingTime = jstartingTime; + session.bufferRequiredCredits = jbufferRequiredCredits; + session.accepted = jaccepted; + + SharedBuffBuilderManager::Session currentSession; + bool const gotCurrentSession = SharedBuffBuilderManager::getSession(session.bufferId, currentSession); + if(!gotCurrentSession) + { + WARNING(true,("ScriptMethodsBuffBuilderNamespace::buffBuilderValidated - could not get current session\n")); + return JNI_FALSE; + } + + //if the session isn't valid, cancel it and don't apply changes + if(!session.accepted) + { + Chat::sendSystemMessage(*bufferObj, SharedStringIds::buffbuilder_session_not_valid, Unicode::emptyString); + + if(bufferObj != recipientObj) + { + Chat::sendSystemMessage(*recipientObj, SharedStringIds::buffbuilder_session_not_valid, Unicode::emptyString); + } + ServerBuffBuilderManager::cancelSession(session.bufferId, session.recipientId); + return JNI_TRUE; + } + + std::string tempString; + + //get buffComponent values + std::map > buffComponents; + int countKeys = env->GetArrayLength(jbuffComponentKeys); + int countValues = env->GetArrayLength(jbuffComponentValues); + if(countKeys != countValues) + { + WARNING(true, ("index keys and values arrays are of diffent sizes")); + return JNI_FALSE; + } + jint * const buffComponentsValuesArray = env->GetIntArrayElements(jbuffComponentValues, NULL); + if (buffComponentsValuesArray == NULL) + { + return JNI_FALSE; + } + std::vector buffComponentsValues(buffComponentsValuesArray, &buffComponentsValuesArray[countValues]); + env->ReleaseIntArrayElements(jbuffComponentValues, buffComponentsValuesArray, JNI_ABORT); + for (int j = 0; j < countKeys; ++j) + { + JavaString jTempString(static_cast(env->GetObjectArrayElement(jbuffComponentKeys, j))); + if (JavaLibrary::convert(jTempString, tempString)) + { + buffComponents[tempString].first = buffComponentsValues[static_cast(j)]; + buffComponents[tempString].second = currentSession.buffComponents[tempString].second; + } + } + session.buffComponents = buffComponents; + + bool const result = ServerBuffBuilderManager::makeChanges(session); + if(!result) + { + Chat::sendSystemMessage(*bufferObj, SharedStringIds::buffbuilder_session_not_valid, Unicode::emptyString); + if(bufferObj != recipientObj) + { + Chat::sendSystemMessage(*recipientObj, SharedStringIds::buffbuilder_session_not_valid, Unicode::emptyString); + } + ServerBuffBuilderManager::cancelSession(session.bufferId, session.recipientId); + } + else + { + //send the final change message to the buffer to indicate acceptance + + Controller * const bufferController = bufferObj ? bufferObj->getController() : NULL; + if(bufferController) + { + BuffBuilderChangeMessage * outMsg = new BuffBuilderChangeMessage(); + if(outMsg) + { + outMsg->setBufferId(session.bufferId); + outMsg->setRecipientId(session.recipientId); + outMsg->setOrigin(BuffBuilderChangeMessage::O_SERVER); + outMsg->setAccepted(true); + bufferController->appendMessage(static_cast(CM_buffBuilderChange), 0.0f, outMsg, GameControllerMessageFlags::SEND | GameControllerMessageFlags::RELIABLE | GameControllerMessageFlags::DEST_AUTH_CLIENT); + } + } + } + + if(result) + return JNI_TRUE; + else + return JNI_FALSE; +} + +//------------------------------------------------------------------------ diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsChat.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsChat.cpp new file mode 100644 index 00000000..8e36a847 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsChat.cpp @@ -0,0 +1,757 @@ +// ScriptMethodsChat.cpp +// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved. +// Author: Justin Randall + +//----------------------------------------------------------------------- + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "UnicodeUtils.h" +#include "serverGame/Chat.h" +#include "serverGame/GameServer.h" +#include "serverGame/ServerObject.h" +#include "serverGame/ServerWorld.h" +#include "serverNetworkMessages/FactionalSystemMessage.h" +#include "serverScript/ConfigServerScript.h" +#include "sharedGame/OutOfBandPackager.h" +#include "sharedGame/ProsePackage.h" +#include "sharedGame/ProsePackageArchive.h" +#include "sharedGame/SocialsManager.h" +#include "sharedGame/Waypoint.h" +#include "sharedGame/WaypointData.h" +#include "sharedMathArchive/VectorArchive.h" + +// ====================================================================== +// ScriptMethodsChatNamespace +// ====================================================================== + +namespace ScriptMethodsChatNamespace +{ + bool install(); + + void JNICALL chatCreateRoom(JNIEnv * env, jobject self, jstring me, jboolean isPublic, jstring roomName, jstring roomTitle); + void JNICALL chatDestroyRoom(JNIEnv * env, jobject self, jstring roomName); + void JNICALL chatEnterRoom(JNIEnv * env, jobject self, jstring who, jstring roomName); + void JNICALL chatExitRoom(JNIEnv * env, jobject self, jstring who, jstring roomName); + void JNICALL chatAddModeratorToRoom(JNIEnv * env, jobject self, jstring roomName, jstring moderatorName); + jstring JNICALL chatPackOutOfBandToken(JNIEnv * env, jobject self, jlong source, jstring target, jint position); + jstring JNICALL chatPackOutOfBandWaypoint(JNIEnv * env, jobject self, jlong source, jstring target, jint position); + jstring JNICALL chatPackOutOfBandWaypointData(JNIEnv * env, jobject self, jstring target, jint position, jstring planet, jfloat x, jfloat z, jobject nameId, jstring name); + jstring JNICALL packOutOfBandProsePackage(JNIEnv * env, jobject self, jstring target, jint position, jobject stringId, jlong objActor, jlong objTarget, jlong objOther, jobject nameIdActor, jobject nameIdTarget, jobject nameIdOther, jstring nameActor, jstring nameTarget, jstring nameOther, jint digitInteger, jfloat digitFloat, jboolean complexGrammar); + void JNICALL chatRemoveModeratorFromRoom(JNIEnv * env, jobject self, jstring roomName, jstring moderatorName); + void JNICALL chatSendInstantMessage(JNIEnv * env, jobject self, jstring from, jstring to, jstring messageText, jstring outOfBand); + void JNICALL chatSendPersistentMessage(JNIEnv * env, jobject self, jstring from, jstring to, jstring messageText, jstring outOfBand, jstring subject); + void JNICALL chatSendToRoom(JNIEnv * env, jobject self, jstring from, jstring roomName, jstring messageText, jstring outOfBand); + void JNICALL chatSendSystemMessage(JNIEnv * env, jobject self, jstring to, jstring message, jstring oob); + void JNICALL chatSendSystemMessageObjId(JNIEnv * env, jobject self, jlong to, jstring message, jstring oob); + jstring JNICALL getEmoteFromCrc(JNIEnv * env, jobject self, jint crc); + void JNICALL chatSendQuestSystemMessage(JNIEnv * env, jobject self, jlong to, jstring message, jstring oob); + void JNICALL chatSendFactionalSystemMessagePlanet(JNIEnv * env, jobject self, jstring prosePackage, jobject loc, jfloat radius, jboolean notifyImperial, jboolean notifyRebel); +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsChatNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsChatNamespace::c)} + JF("_chatCreateRoom", "(Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;)V", chatCreateRoom), + JF("chatDestroyRoom", "(Ljava/lang/String;)V", chatDestroyRoom), + JF("_chatEnterRoom", "(Ljava/lang/String;Ljava/lang/String;)V", chatEnterRoom), + JF("_chatExitRoom", "(Ljava/lang/String;Ljava/lang/String;)V", chatExitRoom), + JF("chatAddModeratorToRoom", "(Ljava/lang/String;Ljava/lang/String;)V", chatAddModeratorToRoom), + JF("chatRemoveModeratorFromRoom", "(Ljava/lang/String;Ljava/lang/String;)V", chatRemoveModeratorFromRoom), + JF("_chatSendInstantMessage", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", chatSendInstantMessage), + JF("_chatSendPersistentMessage", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", chatSendPersistentMessage), + JF("_chatSendToRoom", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", chatSendToRoom), + JF("__packOutOfBandToken", "(JLjava/lang/String;I)Ljava/lang/String;", chatPackOutOfBandToken), + JF("__packOutOfBandWaypoint", "(JLjava/lang/String;I)Ljava/lang/String;", chatPackOutOfBandWaypoint), + JF("_packOutOfBandWaypointData", "(Ljava/lang/String;ILjava/lang/String;FFLscript/string_id;Ljava/lang/String;)Ljava/lang/String;", chatPackOutOfBandWaypointData), + JF("__packOutOfBandProsePackage", "(Ljava/lang/String;ILscript/string_id;JJJLscript/string_id;Lscript/string_id;Lscript/string_id;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IFZ)Ljava/lang/String;", packOutOfBandProsePackage), + JF("sendSystemMessage", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", chatSendSystemMessage), + JF("_sendSystemMessage", "(JLjava/lang/String;Ljava/lang/String;)V", chatSendSystemMessageObjId), + JF("getEmoteFromCrc", "(I)Ljava/lang/String;", getEmoteFromCrc), + JF("_sendQuestSystemMessage", "(JLjava/lang/String;Ljava/lang/String;)V", chatSendQuestSystemMessage), + JF("sendFactionalSystemMessagePlanet", "(Ljava/lang/String;Lscript/location;FZZ)V", chatSendFactionalSystemMessagePlanet), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +//----------------------------------------------------------------------- + +void JNICALL ScriptMethodsChatNamespace::chatAddModeratorToRoom(JNIEnv * env, jobject self, jstring roomName, jstring moderatorName) +{ + JavaStringParam jsprn(roomName); + std::string r; + if(! JavaLibrary::convert(jsprn, r)) + return; + + JavaStringParam jspmn(moderatorName); + std::string m; + if(! JavaLibrary::convert(jspmn, m)) + return; + + Chat::addModeratorToRoom(m, r); +} + +//----------------------------------------------------------------------- + +void JNICALL JNICALL ScriptMethodsChatNamespace::chatCreateRoom(JNIEnv * env, jobject self, jstring me, jboolean isPublic, jstring roomName, jstring roomTitle) +{ + JavaStringParam jspMe(me); + std::string m; + if(!JavaLibrary::convert(jspMe, m)) + return; + + JavaStringParam jsprn(roomName); + std::string r; + if(! JavaLibrary::convert(jsprn, r)) + return; + + JavaStringParam jspt(roomTitle); + std::string t; + if(! JavaLibrary::convert(jspt, t)) + return; + + Chat::createRoom(m, isPublic == JNI_TRUE, r, t); +} + +//----------------------------------------------------------------------- + +void JNICALL JNICALL ScriptMethodsChatNamespace::chatDestroyRoom(JNIEnv * env, jobject self, jstring roomName) +{ + JavaStringParam jsprn(roomName); + std::string r; + if(! JavaLibrary::convert(jsprn, r)) + return; + + Chat::destroyRoom(r); + +} + +//----------------------------------------------------------------------- + +void JNICALL ScriptMethodsChatNamespace::chatEnterRoom(JNIEnv * env, jobject self, jstring me, jstring roomName) +{ + JavaStringParam jspm(me); + std::string m; + if(! JavaLibrary::convert(jspm, m)) + return; + + JavaStringParam jspr(roomName); + std::string r; + if(! JavaLibrary::convert(jspr, r)) + return; + + Chat::enterRoom(m, r, true, false); +} + +//----------------------------------------------------------------------- + +void JNICALL ScriptMethodsChatNamespace::chatExitRoom(JNIEnv * env, jobject self, jstring me, jstring roomName) +{ + JavaStringParam jspm(me); + std::string m; + if(! JavaLibrary::convert(jspm, m)) + return; + + JavaStringParam jspr(roomName); + std::string r; + if(! JavaLibrary::convert(jspr, r)) + return; + + Chat::exitRoom(m, r); +} + +//----------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsChatNamespace::chatPackOutOfBandToken(JNIEnv * env, jobject self, jlong source, jstring target, jint position) +{ + UNREF(env); + UNREF(self); + UNREF(source); + UNREF(target); + UNREF(position); + + JavaString result("JavaLibrary::chatPackOutOfBandToken - FAILED Token archive not implemented"); + return result.getReturnValue(); + +#if 0 + JavaStringParam jt(target); + Unicode::String t; + if(! JavaLibrary::convert(jt, t)) + return 0; + + if(! source) + return 0; + + Token * token = 0; + if(!JavaLibrary::getObject(source, token)) + return 0; + + Archive::ByteStream bs; + Archive::put(bs, std::string(token->getObjectTemplateName())); + Archive::put(bs, *token); + + OutOfBandPackager::pack(bs, gs_Object, position, t); + + JavaString result(t); + return result.getReturnValue(); +#endif +} + +//---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsChatNamespace::chatPackOutOfBandWaypointData(JNIEnv * env, jobject self, jstring target, jint position, jstring planet, jfloat x, jfloat z, jobject nameId, jstring name) +{ + UNREF(env); + UNREF(self); + + Unicode::String t; //target + std::string p; //planet + Unicode::String n; //name + StringId nid; //nameId + + //-- target may be null, we'll just start a new string + if (target) + { + const JavaStringParam jtarget(target); + if (!JavaLibrary::convert(jtarget, t)) + { + DEBUG_WARNING (true, ("ScriptMethodsChat JavaLibrary::chatPackOutOfBandWaypointData failed bad target string")); + return 0; + } + } + + //-- if planet is null, just use the current sceneId + if (planet) + { + const JavaStringParam jplanet(planet); + Unicode::String p_tmp; + if (!JavaLibrary::convert(jplanet, p_tmp)) + { + DEBUG_WARNING (true, ("ScriptMethodsChat JavaLibrary::chatPackOutOfBandWaypointData failed bad planet string")); + return 0; + } + + p = Unicode::wideToNarrow (p_tmp); + } + else + { + p = ServerWorld::getSceneId (); + } + + if (!name && !nameId) + { + DEBUG_WARNING (true, ("ScriptMethodsChat JavaLibrary::chatPackOutOfBandWaypointData failed bad nameId")); + return 0; + + } + + if (nameId) + { + if (!ScriptConversion::convert (nameId, nid)) + { + DEBUG_WARNING (true, ("ScriptMethodsChat JavaLibrary::chatPackOutOfBandWaypointData failed bad nameId")); + return 0; + } + } + + if (name) + { + const JavaStringParam jname (name); + if (!JavaLibrary::convert(jname, n)) + { + DEBUG_WARNING (true, ("ScriptMethodsChat JavaLibrary::chatPackOutOfBandWaypointData failed bad name string")); + return 0; + } + } + + WaypointDataBase wd; + wd.m_location = Location(Vector(x, 0, z), NetworkId::cms_invalid, Location::getCrcBySceneName(p)); + wd.setName(n); + + OutOfBandPackager::pack (wd, position, t); + + JavaString result(t); + return result.getReturnValue(); +} + +//----------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsChatNamespace::chatPackOutOfBandWaypoint(JNIEnv * env, jobject self, jlong source, jstring target, jint position) +{ + UNREF(env); + UNREF(self); + + Unicode::String t; + + if (target) + { + const JavaStringParam jt(target); + if (!JavaLibrary::convert(jt, t)) + { + DEBUG_WARNING (true, ("ScriptMethodsChat JavaLibrary::chatPackOutOfBandWaypoint failed bad target string")); + return 0; + } + } + + if (!source) + { + DEBUG_WARNING (true, ("ScriptMethodsChat JavaLibrary::chatPackOutOfBandWaypoint failed null source")); + return 0; + } + + NetworkId id(source); + const Waypoint waypoint = Waypoint::getWaypointById(id); + if (waypoint.isValid()) + { + OutOfBandPackager::pack (waypoint.getWaypointDataBase(), position, t); + } + else + { + ServerObject * obj = 0; + if (JavaLibrary::getObject(source, obj) && obj) + { + WaypointDataBase wd; + wd.m_location = Location(obj->getPosition_w(), NetworkId::cms_invalid, Location::getCrcBySceneName(ServerWorld::getSceneId())); + wd.setName(obj->getAssignedObjectName()); + + OutOfBandPackager::pack (wd, position, t); + } + } + + JavaString result(t); + return result.getReturnValue(); +} + +//---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsChatNamespace::packOutOfBandProsePackage(JNIEnv * env, jobject self, jstring target, jint position, jobject stringId, jlong objActor, jlong objTarget, jlong objOther, jobject nameIdActor, jobject nameIdTarget, jobject nameIdOther, jstring nameActor, jstring nameTarget, jstring nameOther, jint digitInteger, jfloat digitFloat, jboolean complexGrammar) +{ + UNREF(env); + UNREF(self); + + if (!stringId) + { + DEBUG_WARNING (true, ("JavaLibrary::packOutOfBandProsePackage attempt to pack prose package with null stringId")); + return 0; + } + + Unicode::String t; + + if (target) + { + JavaStringParam jt(target); + if(! JavaLibrary::convert(jt, t)) + { + DEBUG_WARNING (true, ("JavaLibrary::packOutOfBandProsePackage unable to convert target string")); + return 0; + } + } + + ProsePackage pp (complexGrammar); + + if (!ScriptConversion::convert (stringId, pp.stringId)) + { + DEBUG_WARNING (true, ("JavaLibrary::packOutOfBandProsePackage unable to convert StringId")); + return 0; + } + + pp.actor.id = NetworkId(objActor); + if (objActor && pp.actor.id == NetworkId::cms_invalid) + { + DEBUG_WARNING (true, ("JavaLibrary::packOutOfBandProsePackage unable to convert actor id")); + return 0; + } + + pp.target.id = NetworkId(objTarget); + if (objTarget && pp.target.id == NetworkId::cms_invalid) + { + DEBUG_WARNING (true, ("JavaLibrary::packOutOfBandProsePackage unable to convert target id")); + return 0; + } + + pp.other.id = NetworkId(objOther); + if (objOther && pp.other.id == NetworkId::cms_invalid) + { + DEBUG_WARNING (true, ("JavaLibrary::packOutOfBandProsePackage unable to convert other id")); + return 0; + } + + if (nameIdActor) + { + if (!ScriptConversion::convert(nameIdActor, pp.actor.stringId)) + { + DEBUG_WARNING (true, ("JavaLibrary::packOutOfBandProsePackage unable to convert actor id")); + return 0; + } + } + else if (nameActor) + { + const JavaStringParam jt(nameActor); + if(! JavaLibrary::convert(jt, pp.actor.str)) + { + DEBUG_WARNING (true, ("JavaLibrary::packOutOfBandProsePackage unable to convert actor name")); + return 0; + } + } + + if (nameIdTarget) + { + if (!ScriptConversion::convert(nameIdTarget, pp.target.stringId)) + { + DEBUG_WARNING (true, ("JavaLibrary::packOutOfBandProsePackage unable to convert target id")); + return 0; + } + } + else if (nameTarget) + { + const JavaStringParam jt(nameTarget); + if(! JavaLibrary::convert(jt, pp.target.str)) + { + DEBUG_WARNING (true, ("JavaLibrary::packOutOfBandProsePackage unable to convert target name")); + return 0; + } + } + + if (nameIdOther) + { + if (!ScriptConversion::convert(nameIdOther, pp.other.stringId)) + { + DEBUG_WARNING (true, ("JavaLibrary::packOutOfBandProsePackage unable to convert other id")); + return 0; + } + } + else if (nameOther) + { + const JavaStringParam jt(nameOther); + if(! JavaLibrary::convert(jt, pp.other.str)) + { + DEBUG_WARNING (true, ("JavaLibrary::packOutOfBandProsePackage unable to convert other name")); + return 0; + } + } + + pp.digitInteger = digitInteger; + pp.digitFloat = digitFloat; + + Archive::ByteStream bs; + Archive::put(bs, pp); + + OutOfBandPackager::pack(bs, OutOfBandPackager::OT_prosePackage, position, t); + + JavaString result(t); + return result.getReturnValue(); +} + + +//----------------------------------------------------------------------- + +void JNICALL ScriptMethodsChatNamespace::chatSendToRoom(JNIEnv * env, jobject self, jstring from, jstring roomName, jstring message, jstring outOfBand) +{ + JavaStringParam jspf(from); + std::string f; + if(! JavaLibrary::convert(jspf, f)) + return; + + JavaStringParam jsprn(roomName); + std::string r; + if(! JavaLibrary::convert(jsprn, r)) + return; + + Unicode::String m; + if (message) + { + JavaStringParam jspm(message); + if(! JavaLibrary::convert(jspm, m)) + return; + } + + Unicode::String o; + if (outOfBand) + { + JavaStringParam jspo(outOfBand); + if(! JavaLibrary::convert(jspo, o)) + return; + } + + if (o.empty () && m.empty ()) + { + DEBUG_WARNING (true, ("chatSendToRoom with empty message _and_ oob")); + return; + } + + Chat::sendToRoom(f, r, m, o); +} + +//----------------------------------------------------------------------- + +void JNICALL ScriptMethodsChatNamespace::chatRemoveModeratorFromRoom(JNIEnv * env, jobject self, jstring roomName, jstring moderatorName) +{ + JavaStringParam jsprn(roomName); + std::string r; + if(! JavaLibrary::convert(jsprn, r)) + return; + + JavaStringParam jspmn(moderatorName); + std::string m; + if(! JavaLibrary::convert(jspmn, m)) + return; + + Chat::removeModeratorFromRoom(m, r); +} + +//----------------------------------------------------------------------- + +void JNICALL ScriptMethodsChatNamespace::chatSendInstantMessage(JNIEnv * env, jobject self, jstring from, jstring to, jstring message, jstring outOfBand) +{ + JavaStringParam jspf(from); + std::string f; + if(! JavaLibrary::convert(jspf, f)) + return; + + JavaStringParam jspt(to); + std::string t; + if(! JavaLibrary::convert(jspt, t)) + return; + + Unicode::String m; + if (message) + { + JavaStringParam jspm(message); + if(! JavaLibrary::convert(jspm, m)) + return; + } + + Unicode::String o; + if (outOfBand) + { + JavaStringParam jspo(outOfBand); + if(! JavaLibrary::convert(jspo, o)) + return; + } + + if (o.empty () && m.empty ()) + { + DEBUG_WARNING (true, ("chatSendInstantMessage with empty message _and_ oob")); + return; + } + + Chat::sendInstantMessage(f, t, m, o); +} + +//----------------------------------------------------------------------- + +void JNICALL ScriptMethodsChatNamespace::chatSendPersistentMessage(JNIEnv * env, jobject self, jstring from, jstring to, jstring message, jstring outOfBand, jstring subject) +{ + JavaStringParam jspf(from); + std::string f; + if(! JavaLibrary::convert(jspf, f)) + return; + + JavaStringParam jspt(to); + std::string t; + if(! JavaLibrary::convert(jspt, t)) + return; + + Unicode::String m; + if (message) + { + JavaStringParam jspm(message); + if(! JavaLibrary::convert(jspm, m)) + return; + } + + Unicode::String o; + if (outOfBand) + { + JavaStringParam jspo(outOfBand); + if(! JavaLibrary::convert(jspo, o)) + return; + } + + Unicode::String s; + if (subject) + { + JavaStringParam jsps(subject); + if(! JavaLibrary::convert(jsps, s)) + return; + } + + Chat::sendPersistentMessage(f, t, s, m, o); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsChatNamespace::chatSendSystemMessage(JNIEnv * env, jobject self, jstring _to, jstring _message, jstring _oob) +{ + UNREF(self); + + if (!_to) + return; + + Unicode::String to; + { + const JavaStringParam jt(_to); + if(!JavaLibrary::convert(jt, to)) + return; + } + + Unicode::String message; + + if (_message) + { + const JavaStringParam jt(_message); + if (!JavaLibrary::convert(jt, message)) + return; + } + + Unicode::String oob; + + if (_oob) + { + const JavaStringParam jt(_oob); + if (!JavaLibrary::convert(jt, oob)) + return; + } + + if (message.empty () && oob.empty ()) + { + DEBUG_WARNING (true, ("chatSendSystemMessage with empty message _and_ oob")); + } + + Chat::sendSystemMessage(Unicode::wideToNarrow (to), message, oob); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsChatNamespace::chatSendSystemMessageObjId(JNIEnv * env, jobject self, jlong _to, jstring _message, jstring _oob) +{ + UNREF(self); + + if (!_to) + return; + + + const ServerObject * player = 0; + + if(!JavaLibrary::getObject(_to, player)) + { + DEBUG_WARNING (true, ("ScriptMethodsChat JavaLibrary::chatSendSystemMessageObjId failed bad source object (not null)")); + if (ConfigServerScript::allowDebugConsoleMessages()) + { + fprintf(stderr, "WARNING: JavaLibrary::chatSendSystemMessageObjId: failed bad source object (not null)\n"); + JavaLibrary::printJavaStack(); + } + return; + } + + Unicode::String message; + + if (_message) + { + const JavaStringParam jt(_message); + if (!JavaLibrary::convert(jt, message)) + return; + } + + Unicode::String oob; + + if (_oob) + { + const JavaStringParam jt(_oob); + if (!JavaLibrary::convert(jt, oob)) + return; + } + + if (message.empty () && oob.empty ()) + { + DEBUG_WARNING (true, ("chatSendSystemMessage with empty message _and_ oob")); + } + + Chat::sendSystemMessage(*player, message, oob); +} + +//---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsChatNamespace::getEmoteFromCrc(JNIEnv * env, jobject self, jint crc) +{ + std::string emoteName; + if (!SocialsManager::getSocialNameByCrc(crc, emoteName)) + return 0; + + return JavaString(emoteName).getReturnValue(); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsChatNamespace::chatSendQuestSystemMessage(JNIEnv * /*env*/, jobject /*self*/, jlong jobject_networkId, jstring jstring_message, jstring jstring_oob) +{ + ServerObject const * serverObject = 0; + { + if (!JavaLibrary::getObject(jobject_networkId, serverObject)) + { + //@TODO: this function should not be used with object ids of players that are not on the server, however right + // now we have no other method. when we have a method that reliably sends these messages across server, use it and put this back in + + //JAVA_THROW_SCRIPT_EXCEPTION(true, ("WARNING: ScriptMethodsChat JavaLibrary::chatSendQuestSystemMessage: could not convert parameter 1 to a valid networkId\n")); + //printJavaStack(); + return; + } + } + + Unicode::String message; + { + JavaStringParam const jt(jstring_message); + IGNORE_RETURN(JavaLibrary::convert(jt, message)); + } + + Unicode::String oob; + { + JavaStringParam const jt(jstring_oob); + IGNORE_RETURN(!JavaLibrary::convert(jt, oob)); + } + + JAVA_THROW_SCRIPT_EXCEPTION(message.empty() && oob.empty(), ("ScriptMethodsChat JavaLibrary::chatSendQuestSystemMessage: all parameters were valid, but empty")); + + Chat::sendQuestSystemMessage(*serverObject, message, oob); +} + +//----------------------------------------------------------------------- + +void JNICALL ScriptMethodsChatNamespace::chatSendFactionalSystemMessagePlanet(JNIEnv * env, jobject self, jstring prosePackage, jobject loc, jfloat radius, jboolean notifyImperial, jboolean notifyRebel) +{ + if (!prosePackage) + return; + + JavaStringParam jsProsePackage(prosePackage); + Unicode::String strProsePackage; + if(! JavaLibrary::convert(jsProsePackage, strProsePackage)) + return; + + Vector vectorLocation; + if (loc) + { + if (!ScriptConversion::convertWorld(loc, vectorLocation)) + return; + } + + if (!notifyImperial && !notifyRebel) + return; + + // send to planet server for distribution to all game servers + // running this planet; each game server will then check for + // all players within the range and send the player the message; + // we need to do this because the range could cover multiple game servers + FactionalSystemMessage m(strProsePackage, vectorLocation, (loc ? radius : -1.0f), notifyImperial, notifyRebel); + GameServer::getInstance().sendToPlanetServer(m); +} + +//---------------------------------------------------------------------- diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsCity.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsCity.cpp new file mode 100644 index 00000000..6843dc85 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsCity.cpp @@ -0,0 +1,1045 @@ +// ====================================================================== +// +// ScriptMethodsCity.cpp +// +// Copyright 2003 Sony Online Entertainment +// +// ====================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "serverGame/ConfigServerGame.h" +#include "serverGame/CreatureObject.h" +#include "serverGame/CityInterface.h" +#include "serverGame/CityObject.h" +#include "serverGame/ServerUniverse.h" +#include "sharedGame/CitizenRankDataTable.h" + +using namespace JNIWrappersNamespace; + + +// ====================================================================== + +static int closestInt(float f) +{ + if (f < 0.0f) + return static_cast(f-0.5f); + else + return static_cast(f+0.5f); +} + +// ====================================================================== +// ScriptMethodsCityNamespace +// ====================================================================== + +namespace ScriptMethodsCityNamespace +{ + bool install(); + + jint JNICALL getCitizenOfCityId(JNIEnv *env, jobject self, jlong target); + jint JNICALL getLocatedInCityId(JNIEnv *env, jobject self, jlong target); + jint JNICALL getMilitiaOfCityId(JNIEnv *env, jobject self, jlong target); + jintArray JNICALL getAllCityIds(JNIEnv *env, jobject self); + jlong JNICALL getMasterCityObject(JNIEnv *env, jobject self); + jint JNICALL findCityByName(JNIEnv *env, jobject self, jstring cityName); + jint JNICALL findCityByCityHall(JNIEnv *env, jobject self, jlong cityHallId); + jint JNICALL getCityAtLocation(JNIEnv *env, jobject self, jobject cityLocation, jint radius); + jint JNICALL createCity(JNIEnv *env, jobject self, jstring cityName, jlong cityHallId, jobject cityLocation, jint radius, jlong leaderId, jint incomeTax, jint propertyTax, jint salesTax, jobject travelLocation, jint travelCost, jboolean travelInterplanetary, jobject cloneLoc, jobject cloneRespawn, jlong cloneId); + void JNICALL removeCity(JNIEnv *env, jobject self, jint cityId); + jboolean JNICALL cityExists(JNIEnv *env, jobject self, jint cityId); + jstring JNICALL cityGetName(JNIEnv *env, jobject self, jint cityId); + jlong JNICALL cityGetCityHall(JNIEnv *env, jobject self, jint cityId); + jobject JNICALL cityGetLocation(JNIEnv *env, jobject self, jint cityId); + jint JNICALL cityGetRadius(JNIEnv *env, jobject self, jint cityId); + jint JNICALL cityGetFaction(JNIEnv *env, jobject self, jint cityId); + jstring JNICALL cityGetGcwDefenderRegion(JNIEnv *env, jobject self, jint cityId); + jint JNICALL cityGetTimeJoinedGcwDefenderRegion(JNIEnv *env, jobject self, jint cityId); + jint JNICALL cityGetCreationTime(JNIEnv *env, jobject self, jint cityId); + jlong JNICALL cityGetLeader(JNIEnv *env, jobject self, jint cityId); + jint JNICALL cityGetIncomeTax(JNIEnv *env, jobject self, jint cityId); + jint JNICALL cityGetPropertyTax(JNIEnv *env, jobject self, jint cityId); + jint JNICALL cityGetSalesTax(JNIEnv *env, jobject self, jint cityId); + jobject JNICALL cityGetTravelLocation(JNIEnv *env, jobject self, jint cityId); + jint JNICALL cityGetTravelCost(JNIEnv *env, jobject self, jint cityId); + jboolean JNICALL cityGetTravelInterplanetary(JNIEnv *env, jobject self, jint cityId); + jobject JNICALL cityGetCloneLoc(JNIEnv *env, jobject self, jint cityId); + jobject JNICALL cityGetCloneRespawn(JNIEnv *env, jobject self, jint cityId); + jlong JNICALL cityGetCloneId(JNIEnv *env, jobject self, jint cityId); + jlongArray JNICALL cityGetCitizenIds(JNIEnv *env, jobject self, jint cityId); + jint JNICALL cityGetCitizenCount(JNIEnv *env, jobject self, jint cityId); + jstring JNICALL cityGetCitizenName(JNIEnv *env, jobject self, jint cityId, jlong citizenId); + jstring JNICALL cityGetCitizenProfession(JNIEnv *env, jobject self, jint cityId, jlong citizenId); + jint JNICALL cityGetCitizenLevel(JNIEnv *env, jobject self, jint cityId, jlong citizenId); + jstring JNICALL cityGetCitizenTitle(JNIEnv *env, jobject self, jint cityId, jlong citizenId); + jlong JNICALL cityGetCitizenAllegiance(JNIEnv *env, jobject self, jint cityId, jlong citizenId); + jint JNICALL cityGetCitizenPermissions(JNIEnv *env, jobject self, jint cityId, jlong citizenId); + jlongArray JNICALL cityGetStructureIds(JNIEnv *env, jobject self, jint cityId); + jint JNICALL cityGetStructureType(JNIEnv *env, jobject self, jint cityId, jlong structureId); + jboolean JNICALL cityGetStructureValid(JNIEnv *env, jobject self, jint cityId, jlong structureId); + void JNICALL citySetName(JNIEnv *env, jobject self, jint cityId, jstring cityName); + void JNICALL citySetCityHall(JNIEnv *env, jobject self, jint cityId, jlong cityHallId); + void JNICALL citySetLocation(JNIEnv *env, jobject self, jint cityId, jobject cityLocation); + void JNICALL citySetRadius(JNIEnv *env, jobject self, jint cityId, jint radius); + void JNICALL citySetFaction(JNIEnv *env, jobject self, jint cityId, jint factionId, jboolean notifyCitizens); + void JNICALL citySetGcwDefenderRegion(JNIEnv *env, jobject self, jint cityId, jstring gcwDefenderRegion, jint timeJoined, jboolean notifyCitizens); + void JNICALL citySetLeader(JNIEnv *env, jobject self, jint cityId, jlong leaderId); + void JNICALL citySetIncomeTax(JNIEnv *env, jobject self, jint cityId, jint incomeTax); + void JNICALL citySetPropertyTax(JNIEnv *env, jobject self, jint cityId, jint propertyTax); + void JNICALL citySetSalesTax(JNIEnv *env, jobject self, jint cityId, jint salesTax); + void JNICALL citySetTravelInfo(JNIEnv *env, jobject self, jint cityId, jobject travelLocation, jint travelCost, jboolean travelInterplanetary); + void JNICALL citySetCloneInfo(JNIEnv *env, jobject self, jint cityId, jobject cloneLoc, jobject cloneRespawn, jlong cloneId); + void JNICALL citySetCitizenInfo(JNIEnv *env, jobject self, jint cityId, jlong citizenId, jstring citizenName, jlong allegiance, jint permissions); + void JNICALL citySetCitizenTitle(JNIEnv *env, jobject self, jint cityId, jlong citizenId, jstring title); + jobjectArray JNICALL cityGetAllCitizenRanks(JNIEnv *env, jobject self); + jobjectArray JNICALL cityGetTitleForCitizenRank(JNIEnv *env, jobject self, jstring rank); + jobjectArray JNICALL cityGetCitizenRank(JNIEnv *env, jobject self, jint cityId, jlong citizenId); + jboolean JNICALL cityHasCitizenRank(JNIEnv *env, jobject self, jint cityId, jlong citizenId, jstring rank); + void JNICALL cityAddCitizenRank(JNIEnv *env, jobject self, jint cityId, jlong citizenId, jstring rank); + void JNICALL cityRemoveCitizenRank(JNIEnv *env, jobject self, jint cityId, jlong citizenId, jstring rank); + void JNICALL citySetStructureInfo(JNIEnv *env, jobject self, jint cityId, jlong structureId, jint structureType, jboolean structureValid); + void JNICALL cityRemoveCitizen(JNIEnv *env, jobject self, jint cityId, jlong citizenId); + void JNICALL cityRemoveStructure(JNIEnv *env, jobject self, jint cityId, jlong structureId); + jboolean JNICALL cityIsInactivePackupActive(JNIEnv *env, jobject self); + jint JNICALL cityGetInactivePackupInactiveTimeSeconds(JNIEnv *env, jobject self); + jlongArray JNICALL pgcGetChroniclerId(JNIEnv *env, jobject self, jstring chroniclerName); + jstring JNICALL pgcGetChroniclerName(JNIEnv *env, jobject self, jlong chroniclerId); + jintArray JNICALL pgcGetRating(JNIEnv *env, jobject self, jlong chroniclerId); + void JNICALL pgcAdjustRating(JNIEnv *env, jobject self, jlong chroniclerId, jstring chroniclerName, jint adjustment); + jintArray JNICALL pgcGetRatingData(JNIEnv *env, jobject self, jlong chroniclerId); + void JNICALL pgcAdjustRatingData(JNIEnv *env, jobject self, jlong chroniclerId, jstring chroniclerName, jint index, jint adjustment); + void JNICALL pgcSetRatingData(JNIEnv *env, jobject self, jlong chroniclerId, jstring chroniclerName, jint index, jint value); +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsCityNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsCityNamespace::c)} + JF("_getCitizenOfCityId", "(J)I", getCitizenOfCityId), + JF("_getLocatedInCityId", "(J)I", getLocatedInCityId), + JF("_getMilitiaOfCityId", "(J)I", getMilitiaOfCityId), + JF("getAllCityIds", "()[I", getAllCityIds), + JF("_getMasterCityObject", "()J", getMasterCityObject), + JF("findCityByName", "(Ljava/lang/String;)I", findCityByName), + JF("_findCityByCityHall", "(J)I", findCityByCityHall), + JF("getCityAtLocation", "(Lscript/location;I)I", getCityAtLocation), + JF("_createCity", "(Ljava/lang/String;JLscript/location;IJIIILscript/location;IZLscript/location;Lscript/location;J)I", createCity), + JF("removeCity", "(I)V", removeCity), + JF("cityExists", "(I)Z", cityExists), + JF("cityGetName", "(I)Ljava/lang/String;", cityGetName), + JF("_cityGetCityHall", "(I)J", cityGetCityHall), + JF("cityGetLocation", "(I)Lscript/location;", cityGetLocation), + JF("cityGetRadius", "(I)I", cityGetRadius), + JF("cityGetFaction", "(I)I", cityGetFaction), + JF("cityGetGcwDefenderRegion", "(I)Ljava/lang/String;", cityGetGcwDefenderRegion), + JF("cityGetTimeJoinedGcwDefenderRegion", "(I)I", cityGetTimeJoinedGcwDefenderRegion), + JF("cityGetCreationTime", "(I)I", cityGetCreationTime), + JF("_cityGetLeader", "(I)J", cityGetLeader), + JF("cityGetIncomeTax", "(I)I", cityGetIncomeTax), + JF("cityGetPropertyTax", "(I)I", cityGetPropertyTax), + JF("cityGetSalesTax", "(I)I", cityGetSalesTax), + JF("cityGetTravelLocation", "(I)Lscript/location;", cityGetTravelLocation), + JF("cityGetTravelCost", "(I)I", cityGetTravelCost), + JF("cityGetTravelInterplanetary", "(I)Z", cityGetTravelInterplanetary), + JF("cityGetCloneLoc", "(I)Lscript/location;", cityGetCloneLoc), + JF("cityGetCloneRespawn", "(I)Lscript/location;", cityGetCloneRespawn), + JF("_cityGetCloneId", "(I)J", cityGetCloneId), + JF("_cityGetCitizenIds", "(I)[J", cityGetCitizenIds), + JF("cityGetCitizenCount", "(I)I", cityGetCitizenCount), + JF("_cityGetCitizenName", "(IJ)Ljava/lang/String;", cityGetCitizenName), + JF("_cityGetCitizenProfession", "(IJ)Ljava/lang/String;", cityGetCitizenProfession), + JF("_cityGetCitizenLevel", "(IJ)I", cityGetCitizenLevel), + JF("_cityGetCitizenTitle", "(IJ)Ljava/lang/String;", cityGetCitizenTitle), + JF("_cityGetCitizenAllegiance", "(IJ)J", cityGetCitizenAllegiance), + JF("_cityGetCitizenPermissions", "(IJ)I", cityGetCitizenPermissions), + JF("_cityGetStructureIds", "(I)[J", cityGetStructureIds), + JF("_cityGetStructureType", "(IJ)I", cityGetStructureType), + JF("_cityGetStructureValid", "(IJ)Z", cityGetStructureValid), + JF("citySetName", "(ILjava/lang/String;)V", citySetName), + JF("_citySetCityHall", "(IJ)V", citySetCityHall), + JF("citySetLocation", "(ILscript/location;)V", citySetLocation), + JF("citySetRadius", "(II)V", citySetRadius), + JF("citySetFaction", "(IIZ)V", citySetFaction), + JF("citySetGcwDefenderRegion", "(ILjava/lang/String;IZ)V", citySetGcwDefenderRegion), + JF("_citySetLeader", "(IJ)V", citySetLeader), + JF("citySetIncomeTax", "(II)V", citySetIncomeTax), + JF("citySetPropertyTax", "(II)V", citySetPropertyTax), + JF("citySetSalesTax", "(II)V", citySetSalesTax), + JF("citySetTravelInfo", "(ILscript/location;IZ)V", citySetTravelInfo), + JF("_citySetCloneInfo", "(ILscript/location;Lscript/location;J)V", citySetCloneInfo), + JF("_citySetCitizenInfo", "(IJLjava/lang/String;JI)V", citySetCitizenInfo), + JF("_citySetCitizenTitle", "(IJLjava/lang/String;)V", citySetCitizenTitle), + JF("cityGetAllCitizenRanks", "()[Ljava/lang/String;", cityGetAllCitizenRanks), + JF("cityGetTitleForCitizenRank", "(Ljava/lang/String;)[Ljava/lang/String;", cityGetTitleForCitizenRank), + JF("_cityGetCitizenRank", "(IJ)[Ljava/lang/String;", cityGetCitizenRank), + JF("_cityHasCitizenRank", "(IJLjava/lang/String;)Z", cityHasCitizenRank), + JF("_cityAddCitizenRank", "(IJLjava/lang/String;)V", cityAddCitizenRank), + JF("_cityRemoveCitizenRank", "(IJLjava/lang/String;)V", cityRemoveCitizenRank), + JF("_citySetStructureInfo", "(IJIZ)V", citySetStructureInfo), + JF("_cityRemoveCitizen", "(IJ)V", cityRemoveCitizen), + JF("_cityRemoveStructure", "(IJ)V", cityRemoveStructure), + JF("cityIsInactivePackupActive", "()Z", cityIsInactivePackupActive), + JF("cityGetInactivePackupInactiveTimeSeconds", "()I", cityGetInactivePackupInactiveTimeSeconds), + JF("_pgcGetChroniclerId", "(Ljava/lang/String;)[J", pgcGetChroniclerId), + JF("_pgcGetChroniclerName", "(J)Ljava/lang/String;", pgcGetChroniclerName), + JF("_pgcGetRating", "(J)[I", pgcGetRating), + JF("_pgcAdjustRating", "(JLjava/lang/String;I)V", pgcAdjustRating), + JF("_pgcGetRatingData", "(J)[I", pgcGetRatingData), + JF("_pgcAdjustRatingData", "(JLjava/lang/String;II)V", pgcAdjustRatingData), + JF("_pgcSetRatingData", "(JLjava/lang/String;II)V", pgcSetRatingData), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +// ====================================================================== + +jint JNICALL ScriptMethodsCityNamespace::getCitizenOfCityId(JNIEnv *env, jobject self, jlong target) +{ + std::vector const & cityId = CityInterface::getCitizenOfCityId(NetworkId(target)); + if (!cityId.empty()) + return cityId.front(); + + return 0; +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsCityNamespace::getLocatedInCityId(JNIEnv *env, jobject self, jlong target) +{ + CreatureObject *targetObj = 0; + if (JavaLibrary::getObject(target, targetObj)) + return targetObj->getLocatedInCityId(); + return 0; +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsCityNamespace::getMilitiaOfCityId(JNIEnv *env, jobject self, jlong target) +{ + CreatureObject *targetObj = 0; + if (JavaLibrary::getObject(target, targetObj)) + return targetObj->getMilitiaOfCityId(); + return 0; +} + +// ---------------------------------------------------------------------- + +jintArray JNICALL ScriptMethodsCityNamespace::getAllCityIds(JNIEnv *env, jobject self) +{ + std::vector cityIds; + CityInterface::getAllCityIds(cityIds); + LocalIntArrayRefPtr ret = createNewIntArray(cityIds.size()); + if (!cityIds.empty()) + setIntArrayRegion(*ret, 0, cityIds.size(), reinterpret_cast(&cityIds[0])); + return ret->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsCityNamespace::getMasterCityObject(JNIEnv *env, jobject self) +{ + CityObject *masterCityObject = ServerUniverse::getInstance().getMasterCityObject(); + return masterCityObject ? (masterCityObject->getNetworkId()).getValue() : (NetworkId::cms_invalid).getValue(); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsCityNamespace::findCityByName(JNIEnv *env, jobject self, jstring cityName) +{ + JavaStringParam localNameStr(cityName); + std::string cityNameStr; + if (JavaLibrary::convert(localNameStr, cityNameStr)) + return CityInterface::findCityByName(cityNameStr); + return 0; +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsCityNamespace::findCityByCityHall(JNIEnv *env, jobject self, jlong cityHallId) +{ + return CityInterface::findCityByCityHall(NetworkId(cityHallId)); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsCityNamespace::getCityAtLocation(JNIEnv *env, jobject self, jobject cityLocation, jint radius) +{ + Vector cityPosition; + std::string cityPlanet; + NetworkId cell; + ScriptConversion::convert(cityLocation, cityPosition, cityPlanet, cell); + if (cell == NetworkId::cms_invalid) + return CityInterface::getCityAtLocation(cityPlanet, closestInt(cityPosition.x), closestInt(cityPosition.z), radius); + return 0; +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsCityNamespace::createCity(JNIEnv *env, jobject self, jstring cityName, jlong cityHallId, jobject cityLocation, jint radius, jlong leaderId, jint incomeTax, jint propertyTax, jint salesTax, jobject travelLocation, jint travelCost, jboolean travelInterplanetary, jobject cloneLoc, jobject cloneRespawn, jlong cloneId) +{ + JavaStringParam localNameStr(cityName); + std::string cityNameStr; + if (JavaLibrary::convert(localNameStr, cityNameStr)) + { + Vector cityPosition; + std::string cityPlanet; + NetworkId cityCell; + ScriptConversion::convert(cityLocation, cityPosition, cityPlanet, cityCell); + if (cityCell != NetworkId::cms_invalid) + return 0; + Vector travelPosition(Vector::zero); + std::string travelPlanet; + NetworkId travelCell; + if (travelCost > 0) + { + ScriptConversion::convert(travelLocation, travelPosition, travelPlanet, travelCell); + if (travelCell != NetworkId::cms_invalid) + { + travelCost = 0; + travelPosition = Vector::zero; + } + } + Vector cloneLocPosition(Vector::zero); + std::string cloneLocPlanet; + NetworkId cloneLocCell; + ScriptConversion::convert(cloneLoc, cloneLocPosition, cloneLocPlanet, cloneLocCell); + Vector cloneRespawnPosition(Vector::zero); + std::string cloneRespawnPlanet; + NetworkId cloneRespawnCell; + ScriptConversion::convert(cloneRespawn, cloneRespawnPosition, cloneRespawnPlanet, cloneRespawnCell); + + return CityInterface::createCity( + cityNameStr, NetworkId(cityHallId), + cityPlanet, closestInt(cityPosition.x), closestInt(cityPosition.z), radius, + NetworkId(leaderId), + incomeTax, propertyTax, salesTax, + travelPosition, travelCost, travelInterplanetary, + cloneLocPosition, cloneRespawnPosition, cloneRespawnCell, NetworkId(cloneId)); + } + return 0; +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsCityNamespace::removeCity(JNIEnv *env, jobject self, jint cityId) +{ + CityInterface::removeCity(cityId); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsCityNamespace::cityExists(JNIEnv *env, jobject self, jint cityId) +{ + return CityInterface::cityExists(cityId); +} + +// ---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsCityNamespace::cityGetName(JNIEnv *env, jobject self, jint cityId) +{ + return JavaString(CityInterface::getCityInfo(cityId).getCityName().c_str()).getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsCityNamespace::cityGetCityHall(JNIEnv *env, jobject self, jint cityId) +{ + return (CityInterface::getCityInfo(cityId).getCityHallId()).getValue(); +} + +// ---------------------------------------------------------------------- + +jobject JNICALL ScriptMethodsCityNamespace::cityGetLocation(JNIEnv *env, jobject self, jint cityId) +{ + CityInfo const &ci = CityInterface::getCityInfo(cityId); + LocalRefPtr location; + if (ScriptConversion::convert( + Vector(static_cast(ci.getX()), 0.0f, static_cast(ci.getZ())), + ci.getPlanet(), + NetworkId::cms_invalid, + location)) + { + return location->getReturnValue(); + } + return 0; +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsCityNamespace::cityGetRadius(JNIEnv *env, jobject self, jint cityId) +{ + return CityInterface::getCityInfo(cityId).getRadius(); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsCityNamespace::cityGetFaction(JNIEnv *env, jobject self, jint cityId) +{ + return static_cast(CityInterface::getCityInfo(cityId).getFaction()); +} + +// ---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsCityNamespace::cityGetGcwDefenderRegion(JNIEnv *env, jobject self, jint cityId) +{ + return JavaString(CityInterface::getCityInfo(cityId).getGcwDefenderRegion().c_str()).getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsCityNamespace::cityGetTimeJoinedGcwDefenderRegion(JNIEnv *env, jobject self, jint cityId) +{ + return CityInterface::getCityInfo(cityId).getTimeJoinedGcwDefenderRegion(); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsCityNamespace::cityGetCreationTime(JNIEnv *env, jobject self, jint cityId) +{ + return CityInterface::getCityInfo(cityId).getCreationTime(); +} + +// ---------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsCityNamespace::cityGetLeader(JNIEnv *env, jobject self, jint cityId) +{ + return (CityInterface::getCityInfo(cityId).getLeaderId()).getValue(); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsCityNamespace::cityGetIncomeTax(JNIEnv *env, jobject self, jint cityId) +{ + return CityInterface::getCityInfo(cityId).getIncomeTax(); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsCityNamespace::cityGetPropertyTax(JNIEnv *env, jobject self, jint cityId) +{ + return CityInterface::getCityInfo(cityId).getPropertyTax(); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsCityNamespace::cityGetSalesTax(JNIEnv *env, jobject self, jint cityId) +{ + return CityInterface::getCityInfo(cityId).getSalesTax(); +} + +// ---------------------------------------------------------------------- + +jobject JNICALL ScriptMethodsCityNamespace::cityGetTravelLocation(JNIEnv *env, jobject self, jint cityId) +{ + CityInfo const &ci = CityInterface::getCityInfo(cityId); + LocalRefPtr location; + if (ScriptConversion::convert( + ci.getTravelLoc(), + ci.getPlanet(), + NetworkId::cms_invalid, + location)) + { + return location->getReturnValue(); + } + return 0; +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsCityNamespace::cityGetTravelCost(JNIEnv *env, jobject self, jint cityId) +{ + return CityInterface::getCityInfo(cityId).getTravelCost(); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsCityNamespace::cityGetTravelInterplanetary(JNIEnv *env, jobject self, jint cityId) +{ + return CityInterface::getCityInfo(cityId).getTravelInterplanetary(); +} + +// ---------------------------------------------------------------------- + +jobject JNICALL ScriptMethodsCityNamespace::cityGetCloneLoc(JNIEnv *env, jobject self, jint cityId) +{ + CityInfo const &ci = CityInterface::getCityInfo(cityId); + LocalRefPtr location; + if (ScriptConversion::convert( + ci.getCloneLoc(), + ci.getPlanet(), + NetworkId::cms_invalid, + location)) + { + return location->getReturnValue(); + } + return 0; +} + +// ---------------------------------------------------------------------- + +jobject JNICALL ScriptMethodsCityNamespace::cityGetCloneRespawn(JNIEnv *env, jobject self, jint cityId) +{ + CityInfo const &ci = CityInterface::getCityInfo(cityId); + LocalRefPtr location; + if (ScriptConversion::convert( + ci.getCloneRespawn(), + ci.getPlanet(), + ci.getCloneRespawnCell(), + location)) + { + return location->getReturnValue(); + } + return 0; +} + +// ---------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsCityNamespace::cityGetCloneId(JNIEnv *env, jobject self, jint cityId) +{ + return (CityInterface::getCityInfo(cityId).getCloneId()).getValue(); +} + +// ---------------------------------------------------------------------- + +jlongArray JNICALL ScriptMethodsCityNamespace::cityGetCitizenIds(JNIEnv *env, jobject self, jint cityId) +{ + std::vector results; + CityInterface::getCitizenIds(cityId, results); + LocalLongArrayRefPtr rv; + if (ScriptConversion::convert(results, rv)) + return rv->getReturnValue(); + return 0; +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsCityNamespace::cityGetCitizenCount(JNIEnv *env, jobject self, jint cityId) +{ + return CityInterface::getCitizenCount(cityId); +} + +// ---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsCityNamespace::cityGetCitizenName(JNIEnv *env, jobject self, jint cityId, jlong citizenId) +{ + CitizenInfo const *ci = CityInterface::getCitizenInfo(cityId, NetworkId(citizenId)); + if (ci) + return JavaString(ci->m_citizenName).getReturnValue(); + return 0; +} + +// ---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsCityNamespace::cityGetCitizenProfession(JNIEnv *env, jobject self, jint cityId, jlong citizenId) +{ + CitizenInfo const *ci = CityInterface::getCitizenInfo(cityId, NetworkId(citizenId)); + if (ci) + return JavaString(ci->m_citizenProfessionSkillTemplate).getReturnValue(); + return 0; +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsCityNamespace::cityGetCitizenLevel(JNIEnv *env, jobject self, jint cityId, jlong citizenId) +{ + CitizenInfo const *ci = CityInterface::getCitizenInfo(cityId, NetworkId(citizenId)); + if (ci) + return ci->m_citizenLevel; + return 0; +} + +// ---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsCityNamespace::cityGetCitizenTitle(JNIEnv *env, jobject self, jint cityId, jlong citizenId) +{ + CitizenInfo const *ci = CityInterface::getCitizenInfo(cityId, NetworkId(citizenId)); + if (ci) + return JavaString(ci->m_citizenTitle).getReturnValue(); + return 0; +} + +// ---------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsCityNamespace::cityGetCitizenAllegiance(JNIEnv *env, jobject self, jint cityId, jlong citizenId) +{ + CitizenInfo const *ci = CityInterface::getCitizenInfo(cityId, NetworkId(citizenId)); + if (ci) + return (ci->m_citizenAllegiance).getValue(); + return 0; +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsCityNamespace::cityGetCitizenPermissions(JNIEnv *env, jobject self, jint cityId, jlong citizenId) +{ + CitizenInfo const *ci = CityInterface::getCitizenInfo(cityId, NetworkId(citizenId)); + if (ci) + return ci->m_citizenPermissions; + return 0; +} + +// ---------------------------------------------------------------------- + +jlongArray JNICALL ScriptMethodsCityNamespace::cityGetStructureIds(JNIEnv *env, jobject self, jint cityId) +{ + std::vector results; + CityInterface::getCityStructureIds(cityId, results); + LocalLongArrayRefPtr rv; + if (ScriptConversion::convert(results, rv)) + return rv->getReturnValue(); + return 0; +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsCityNamespace::cityGetStructureType(JNIEnv *env, jobject self, jint cityId, jlong structureId) +{ + CityStructureInfo const *csi = CityInterface::getCityStructureInfo(cityId, NetworkId(structureId)); + if (csi) + return csi->getStructureType(); + return 0; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsCityNamespace::cityGetStructureValid(JNIEnv *env, jobject self, jint cityId, jlong structureId) +{ + CityStructureInfo const *csi = CityInterface::getCityStructureInfo(cityId, NetworkId(structureId)); + if (csi) + return csi->getStructureValid(); + return JNI_FALSE; +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsCityNamespace::citySetName(JNIEnv *env, jobject self, jint cityId, jstring cityName) +{ + JavaStringParam localNameStr(cityName); + std::string cityNameStr; + if (!JavaLibrary::convert(localNameStr, cityNameStr)) + JavaLibrary::throwInternalScriptError("JavaLibrary::citySetName: invalid cityName"); + else + CityInterface::setCityName(cityId, cityNameStr); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsCityNamespace::citySetCityHall(JNIEnv *env, jobject self, jint cityId, jlong cityHallId) +{ + CityInterface::setCityHall(cityId, NetworkId(cityHallId)); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsCityNamespace::citySetLocation(JNIEnv *env, jobject self, jint cityId, jobject cityLocation) +{ + Vector cityPosition; + std::string cityPlanet; + NetworkId cell; + if (!ScriptConversion::convert(cityLocation, cityPosition, cityPlanet, cell)) + JavaLibrary::throwInternalScriptError("JavaLibrary::citySetLocation: bad location"); + else if (cell != NetworkId::cms_invalid) + JavaLibrary::throwInternalScriptError("JavaLibrary::citySetLocation: tried to set a location in an interior"); + else + CityInterface::setCityLocation(cityId, cityPlanet, closestInt(cityPosition.x), closestInt(cityPosition.z)); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsCityNamespace::citySetRadius(JNIEnv *env, jobject self, jint cityId, jint radius) +{ + if (radius <= 0) + JavaLibrary::throwInternalScriptError("JavaLibrary::citySetLocation: tried to set a nonpositive radius"); + else + CityInterface::setCityRadius(cityId, radius); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsCityNamespace::citySetFaction(JNIEnv *env, jobject self, jint cityId, jint factionId, jboolean notifyCitizens) +{ + CityInterface::setCityFaction(cityId, static_cast(factionId), (notifyCitizens != JNI_FALSE)); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsCityNamespace::citySetGcwDefenderRegion(JNIEnv *env, jobject self, jint cityId, jstring gcwDefenderRegion, jint timeJoined, jboolean notifyCitizens) +{ + JavaStringParam localGcwDefenderRegionStr(gcwDefenderRegion); + std::string gcwDefenderRegionStr; + if (JavaLibrary::convert(localGcwDefenderRegionStr, gcwDefenderRegionStr)) + { + if (!gcwDefenderRegionStr.empty()) + { + Pvp::GcwScoreCategory const * const gcwCategory = Pvp::getGcwScoreCategory(gcwDefenderRegionStr); + if (!gcwCategory) + { + DEBUG_WARNING(true, ("JavaLibrary::citySetGcwDefenderRegion: invalid GCW score category (%s)", gcwDefenderRegionStr.c_str())); + return; + } + + if (!gcwCategory->gcwRegionDefender) + { + DEBUG_WARNING(true, ("JavaLibrary::citySetGcwDefenderRegion: GCW score category (%s) is not flagged as GcwRegionDefender", gcwDefenderRegionStr.c_str())); + return; + } + } + } + else + { + gcwDefenderRegionStr.clear(); + } + + CityInterface::setCityGcwDefenderRegion(cityId, gcwDefenderRegionStr, timeJoined, (notifyCitizens != JNI_FALSE)); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsCityNamespace::citySetLeader(JNIEnv *env, jobject self, jint cityId, jlong leaderId) +{ + CityInterface::setCityLeader(cityId, NetworkId(leaderId)); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsCityNamespace::citySetIncomeTax(JNIEnv *env, jobject self, jint cityId, jint incomeTax) +{ + CityInterface::setCityIncomeTax(cityId, incomeTax); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsCityNamespace::citySetPropertyTax(JNIEnv *env, jobject self, jint cityId, jint propertyTax) +{ + CityInterface::setCityPropertyTax(cityId, propertyTax); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsCityNamespace::citySetSalesTax(JNIEnv *env, jobject self, jint cityId, jint salesTax) +{ + CityInterface::setCitySalesTax(cityId, salesTax); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsCityNamespace::citySetTravelInfo(JNIEnv *env, jobject self, jint cityId, jobject travelLocation, jint travelCost, jboolean travelInterplanetary) +{ + Vector travelPosition(Vector::zero); + std::string travelPlanet; + NetworkId travelCell; + if (!ScriptConversion::convert(travelLocation, travelPosition, travelPlanet, travelCell)) + JavaLibrary::throwInternalScriptError("JavaLibrary::citySetTravelInfo: bad location"); + else if (travelCell != NetworkId::cms_invalid) + JavaLibrary::throwInternalScriptError("JavaLibrary::citySetTravelInfo: tried to set a location in an interior"); + else + CityInterface::setCityTravelInfo(cityId, travelPosition, travelCost, travelInterplanetary ? true : false); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsCityNamespace::citySetCloneInfo(JNIEnv *env, jobject self, jint cityId, jobject cloneLoc, jobject cloneRespawn, jlong cloneId) +{ + Vector cloneLocPosition(Vector::zero); + std::string cloneLocPlanet; + NetworkId cloneLocCell; + ScriptConversion::convert(cloneLoc, cloneLocPosition, cloneLocPlanet, cloneLocCell); + Vector cloneRespawnPosition(Vector::zero); + std::string cloneRespawnPlanet; + NetworkId cloneRespawnCell; + ScriptConversion::convert(cloneRespawn, cloneRespawnPosition, cloneRespawnPlanet, cloneRespawnCell); + CityInterface::setCityCloneInfo(cityId, cloneLocPosition, cloneRespawnPosition, cloneRespawnCell, NetworkId(cloneId)); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsCityNamespace::citySetCitizenInfo(JNIEnv *env, jobject self, jint cityId, jlong citizenId, jstring citizenName, jlong allegiance, jint permissions) +{ + JavaStringParam localNameStr(citizenName); + std::string citizenNameStr; + if (JavaLibrary::convert(localNameStr, citizenNameStr)) + CityInterface::setCitizenInfo(cityId, NetworkId(citizenId), citizenNameStr, NetworkId(allegiance), permissions); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsCityNamespace::citySetCitizenTitle(JNIEnv *env, jobject self, jint cityId, jlong citizenId, jstring title) +{ + JavaStringParam localTitleStr(title); + std::string titleStr; + if (JavaLibrary::convert(localTitleStr, titleStr)) + CityInterface::setCitizenTitle(cityId, NetworkId(citizenId), titleStr); +} + +// ---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsCityNamespace::cityGetAllCitizenRanks(JNIEnv *env, jobject self) +{ + std::vector const & ranks = CitizenRankDataTable::getAllRanks(); + if (ranks.empty()) + return 0; + + int i = 0; + LocalObjectArrayRefPtr valueArray = createNewObjectArray(ranks.size(), JavaLibrary::getClsString()); + for (std::vector::const_iterator iter = ranks.begin(); iter != ranks.end(); ++iter) + { + JavaString jval((*iter)->name); + setObjectArrayElement(*valueArray, i++, jval); + } + + return valueArray->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsCityNamespace::cityGetTitleForCitizenRank(JNIEnv *env, jobject self, jstring rank) +{ + JavaStringParam localRankStr(rank); + std::string rankStr; + if (!JavaLibrary::convert(localRankStr, rankStr)) + { + DEBUG_WARNING(true, ("JavaLibrary::cityGetTitleForCitizenRank: invalid rank")); + return 0; + } + + CitizenRankDataTable::CitizenRank const * rankInfo = CitizenRankDataTable::getRank(rankStr); + if (!rankInfo || rankInfo->titles.empty()) + return 0; + + int i = 0; + LocalObjectArrayRefPtr valueArray = createNewObjectArray(rankInfo->titles.size(), JavaLibrary::getClsString()); + for (std::vector::const_iterator iter = rankInfo->titles.begin(); iter != rankInfo->titles.end(); ++iter) + { + JavaString jval(*iter); + setObjectArrayElement(*valueArray, i++, jval); + } + + return valueArray->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsCityNamespace::cityGetCitizenRank(JNIEnv *env, jobject self, jint cityId, jlong citizenId) +{ + std::vector ranks; + CityInterface::getCitizenRank(cityId, NetworkId(static_cast(citizenId)), ranks); + if (ranks.empty()) + return 0; + + int i = 0; + LocalObjectArrayRefPtr valueArray = createNewObjectArray(ranks.size(), JavaLibrary::getClsString()); + for (std::vector::const_iterator iter = ranks.begin(); iter != ranks.end(); ++iter) + { + JavaString jval(*iter); + setObjectArrayElement(*valueArray, i++, jval); + } + + return valueArray->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsCityNamespace::cityHasCitizenRank(JNIEnv *env, jobject self, jint cityId, jlong citizenId, jstring rank) +{ + NetworkId citizen(citizenId); + + JavaStringParam localRankStr(rank); + std::string rankStr; + if (!JavaLibrary::convert(localRankStr, rankStr)) + { + DEBUG_WARNING(true, ("JavaLibrary::cityHasCitizenRank: invalid rank")); + return JNI_FALSE; + } + + return CityInterface::hasCitizenRank(cityId, citizen, rankStr); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsCityNamespace::cityAddCitizenRank(JNIEnv *env, jobject self, jint cityId, jlong citizenId, jstring rank) +{ + NetworkId citizen(citizenId); + + JavaStringParam localRankStr(rank); + std::string rankStr; + if (!JavaLibrary::convert(localRankStr, rankStr)) + { + DEBUG_WARNING(true, ("JavaLibrary::cityAddCitizenRank: invalid rank")); + return; + } + + CityInterface::addCitizenRank(cityId, citizen, rankStr); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsCityNamespace::cityRemoveCitizenRank(JNIEnv *env, jobject self, jint cityId, jlong citizenId, jstring rank) +{ + NetworkId citizen(citizenId); + + JavaStringParam localRankStr(rank); + std::string rankStr; + if (!JavaLibrary::convert(localRankStr, rankStr)) + { + DEBUG_WARNING(true, ("JavaLibrary::cityRemoveCitizenRank: invalid rank")); + return; + } + + CityInterface::removeCitizenRank(cityId, citizen, rankStr); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsCityNamespace::citySetStructureInfo(JNIEnv *env, jobject self, jint cityId, jlong structureId, jint structureType, jboolean structureValid) +{ + CityInterface::setCityStructureInfo(cityId, NetworkId(structureId), structureType, structureValid); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsCityNamespace::cityRemoveCitizen(JNIEnv *env, jobject self, jint cityId, jlong citizenId) +{ + CityInterface::removeCitizen(cityId, NetworkId(citizenId)); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsCityNamespace::cityRemoveStructure(JNIEnv *env, jobject self, jint cityId, jlong structureId) +{ + CityInterface::removeCityStructure(cityId, NetworkId(structureId)); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsCityNamespace::cityIsInactivePackupActive(JNIEnv *env, jobject self) +{ + return (ConfigServerGame::getCityCitizenshipInactivePackupStartTimeEpoch() <= static_cast(::time(NULL))); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsCityNamespace::cityGetInactivePackupInactiveTimeSeconds(JNIEnv *env, jobject self) +{ + return ConfigServerGame::getCityCitizenshipInactivePackupInactiveTimeSeconds(); +} + +// ---------------------------------------------------------------------- + +jlongArray JNICALL ScriptMethodsCityNamespace::pgcGetChroniclerId(JNIEnv *env, jobject self, jstring chroniclerName) +{ + JavaStringParam localChroniclerNameStr(chroniclerName); + std::string chroniclerNameStr; + if (!JavaLibrary::convert(localChroniclerNameStr, chroniclerNameStr) || chroniclerNameStr.empty()) + return 0; + + std::vector chroniclerIds; + CityInterface::getPgcChroniclerId(chroniclerNameStr, chroniclerIds); + + if (chroniclerIds.empty()) + return 0; + + LocalLongArrayRefPtr idArray; + if (!ScriptConversion::convert(chroniclerIds, idArray)) + return 0; + + return idArray->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsCityNamespace::pgcGetChroniclerName(JNIEnv *env, jobject self, jlong chroniclerId) +{ + PgcRatingInfo const * const pgcRating = CityInterface::getPgcRating(NetworkId(chroniclerId)); + if (pgcRating) + return JavaString(pgcRating->m_chroniclerName).getReturnValue(); + return 0; +} + +// ---------------------------------------------------------------------- + +jintArray JNICALL ScriptMethodsCityNamespace::pgcGetRating(JNIEnv *env, jobject self, jlong chroniclerId) +{ + PgcRatingInfo const * const pgcRating = CityInterface::getPgcRating(NetworkId(chroniclerId)); + if (pgcRating) + { + std::vector result(3); + result[0] = static_cast(pgcRating->m_ratingCount); + result[1] = static_cast(pgcRating->m_ratingTotal); + result[2] = pgcRating->m_lastRatingTime; + + LocalIntArrayRefPtr ret = createNewIntArray(result.size()); + setIntArrayRegion(*ret, 0, result.size(), reinterpret_cast(&result[0])); + return ret->getReturnValue(); + } + + return 0; +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsCityNamespace::pgcAdjustRating(JNIEnv *env, jobject self, jlong chroniclerId, jstring chroniclerName, jint adjustment) +{ + std::string chroniclerNameStr; + if (chroniclerName != 0) + { + JavaStringParam localChroniclerNameStr(chroniclerName); + if (!JavaLibrary::convert(localChroniclerNameStr, chroniclerNameStr)) + return; + } + + CityInterface::adjustPgcRating(NetworkId(chroniclerId), chroniclerNameStr, adjustment); +} + +// ---------------------------------------------------------------------- + +jintArray JNICALL ScriptMethodsCityNamespace::pgcGetRatingData(JNIEnv *env, jobject self, jlong chroniclerId) +{ + PgcRatingInfo const * const pgcRating = CityInterface::getPgcRating(NetworkId(chroniclerId)); + if (pgcRating && !pgcRating->m_data.empty()) + { + LocalIntArrayRefPtr ret = createNewIntArray(pgcRating->m_data.size()); + setIntArrayRegion(*ret, 0, pgcRating->m_data.size(), reinterpret_cast(const_cast(&pgcRating->m_data[0]))); + return ret->getReturnValue(); + } + + return 0; +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsCityNamespace::pgcAdjustRatingData(JNIEnv *env, jobject self, jlong chroniclerId, jstring chroniclerName, jint index, jint adjustment) +{ + std::string chroniclerNameStr; + if (chroniclerName != 0) + { + JavaStringParam localChroniclerNameStr(chroniclerName); + if (!JavaLibrary::convert(localChroniclerNameStr, chroniclerNameStr)) + return; + } + + CityInterface::adjustPgcRatingData(NetworkId(chroniclerId), chroniclerNameStr, index, adjustment); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsCityNamespace::pgcSetRatingData(JNIEnv *env, jobject self, jlong chroniclerId, jstring chroniclerName, jint index, jint value) +{ + std::string chroniclerNameStr; + if (chroniclerName != 0) + { + JavaStringParam localChroniclerNameStr(chroniclerName); + if (!JavaLibrary::convert(localChroniclerNameStr, chroniclerNameStr)) + return; + } + + CityInterface::setPgcRatingData(NetworkId(chroniclerId), chroniclerNameStr, index, value); +} + +// ====================================================================== diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsClientEffect.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsClientEffect.cpp new file mode 100644 index 00000000..ed91aacc --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsClientEffect.cpp @@ -0,0 +1,963 @@ +//----------------------------------------------------------------------- +// ScriptMethodsClientEffect.cpp +// Copyright 2002, Sony Online Entertainment Inc., all rights reserved. +//----------------------------------------------------------------------- + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "serverGame/GameServer.h" +#include "serverGame/ServerObject.h" +#include "serverGame/TangibleObject.h" +#include "sharedObject/CellProperty.h" +#include "sharedMath/PackedArgb.h" +#include "sharedNetworkMessages/ClientEffectMessages.h" +#include "sharedNetworkMessages/MessageQueueGenericValueType.h" +#include "sharedNetworkMessages/PlayMusicMessage.h" + + +// ====================================================================== +// ScriptMethodsClientEffectNamespace +// ====================================================================== + +namespace ScriptMethodsClientEffectNamespace +{ + bool install(); + + jboolean JNICALL playClientEventObj(JNIEnv *env, jobject self, jlong client, jstring eventType, jlong obj, jstring hardpoint, jobject jTransform); + jboolean JNICALL playClientEventObjLimited(JNIEnv *env, jobject self, jlongArray clients, jstring eventType, jlong obj, jstring hardpoint, jobject jTransform); + jboolean JNICALL playClientEventLoc(JNIEnv *env, jobject self, jlong client, jstring eventSourceType, jstring eventDestType, jobject loc, jfloat terrainDelta); + jboolean JNICALL playClientEventLocLimited(JNIEnv *env, jobject self, jlongArray client, jstring eventSourceType, jstring eventDestType, jobject loc, jfloat terrainDelta); + jboolean JNICALL playUiEffect(JNIEnv *env, jobject self, jlong client, jstring uiEffectString); + jboolean JNICALL playClientEffectObj(JNIEnv *env, jobject self, jlong client, jstring effectName, jlong obj, jstring hardpoint, jobject jTransform, jstring labelName); + jboolean JNICALL playClientEffectObjLimited(JNIEnv *env, jobject self, jlongArray clients, jstring effectName, jlong obj, jstring hardpoint, jobject jTransform, jstring labelName); + jboolean JNICALL playClientEffectLoc(JNIEnv *env, jobject self, jlong client, jstring effectName, jobject loc, jfloat terrainDelta, jstring labelName); + jboolean JNICALL playClientEffectLocLimited(JNIEnv *env, jobject self, jlongArray clients, jstring effectName, jobject loc, jfloat terrainDelta, jstring labelName); + jboolean JNICALL stopClientEffectObjByLabel(JNIEnv *env, jobject self, jlong client, jlong objectEffectIsOn, jstring labelName, jboolean softTerminate); + jboolean JNICALL stopClientEffectObjByLabelLimited(JNIEnv *env, jobject self, jlongArray clients, jlong objectEffectIsOn, jstring labelName, jboolean softTerminate); + jboolean JNICALL play2dNonLoopingMusic(JNIEnv *env, jobject self, jlong client, jstring musicName); + jboolean JNICALL play2dNonLoopingSound(JNIEnv *env, jobject self, jlong client, jstring musicName); + jboolean JNICALL playMusicWithParms(JNIEnv *env, jobject self, jlong client, jlong source, jstring musicName, jint playtype, bool loop); + void JNICALL sendMusicFlourish(JNIEnv *env, jobject self, jlong performer, jint flourishIndex); + jboolean JNICALL createClientProjectile(JNIEnv *env, jobject self, jlong client, jstring weaponObjectTemplateName, jobject start, jobject end, jfloat speed, jfloat expiration, jboolean trail, jint r, jint g, jint b, jint a); + jboolean JNICALL createClientProjectileObjectToObject(JNIEnv *env, jobject self, jlong client, jstring weaponObjectTemplateName, jlong source, jstring sourceHardpoint, jlong target, jstring targetHardpoint, jfloat speed, jfloat expiration, jboolean trail, jint r, jint g, jint b, jint a); + jboolean JNICALL createClientProjectileLocationToObject(JNIEnv *env, jobject self, jlong client, jstring weaponObjectTemplateName, jobject source, jlong target, jstring targetHardpoint, jfloat speed, jfloat expiration, jboolean trail, jint r, jint g, jint b, jint a); + jboolean JNICALL createClientProjectileObjectToLocation(JNIEnv *env, jobject self, jlong client, jstring weaponObjectTemplateName, jlong source, jstring sourceHardpoint, jobject target, jfloat speed, jfloat expiration, jboolean trail, jint r, jint g, jint b, jint a); + void JNICALL addObjectEffect(JNIEnv * env, jobject self, jlong obj, jstring filename, jstring hardpoint, jobject offset, jfloat scale, jstring label); + void JNICALL removeObjectEffect(JNIEnv * env, jobject self, jlong obj, jstring label); + void JNICALL removeAllObjectEffects(JNIEnv * env, jobject self, jlong obj); + jboolean JNICALL hasObjectEffect(JNIEnv * env, jobject self, jlong obj, jstring label); +} + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsClientEffectNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsClientEffectNamespace::c)} + JF("_playClientEventObj", "(JLjava/lang/String;JLjava/lang/String;Lscript/transform;)Z", playClientEventObj), + JF("_playClientEventObj", "([JLjava/lang/String;JLjava/lang/String;Lscript/transform;)Z", playClientEventObjLimited), + JF("_playClientEventLoc", "(JLjava/lang/String;Ljava/lang/String;Lscript/location;F)Z", playClientEventLoc), + JF("_playClientEventLoc", "([JLjava/lang/String;Ljava/lang/String;Lscript/location;F)Z", playClientEventLocLimited), + JF("_playUiEffect", "(JLjava/lang/String;)Z", playUiEffect), + JF("_playClientEffectObj", "(JLjava/lang/String;JLjava/lang/String;Lscript/transform;Ljava/lang/String;)Z", playClientEffectObj), + JF("_playClientEffectObj", "([JLjava/lang/String;JLjava/lang/String;Lscript/transform;Ljava/lang/String;)Z", playClientEffectObjLimited), + JF("_playClientEffectLoc", "(JLjava/lang/String;Lscript/location;FLjava/lang/String;)Z", playClientEffectLoc), + JF("_playClientEffectLoc", "([JLjava/lang/String;Lscript/location;FLjava/lang/String;)Z", playClientEffectLocLimited), + JF("_stopClientEffectObjByLabel", "(JJLjava/lang/String;Z)Z", stopClientEffectObjByLabel), + JF("_stopClientEffectObjByLabel", "([JJLjava/lang/String;Z)Z", stopClientEffectObjByLabelLimited), + JF("_play2dNonLoopingMusic", "(JLjava/lang/String;)Z", play2dNonLoopingMusic), + JF("_play2dNonLoopingSound", "(JLjava/lang/String;)Z", play2dNonLoopingSound), + JF("_playMusic", "(JJLjava/lang/String;IZ)Z", playMusicWithParms), + JF("_createClientProjectile", "(JLjava/lang/String;Lscript/location;Lscript/location;FFZIIII)Z", createClientProjectile), + JF("_createClientProjectileObjectToObject", "(JLjava/lang/String;JLjava/lang/String;JLjava/lang/String;FFZIIII)Z", createClientProjectileObjectToObject), + JF("_createClientProjectileLocationToObject", "(JLjava/lang/String;Lscript/location;JLjava/lang/String;FFZIIII)Z", createClientProjectileLocationToObject), + JF("_createClientProjectileObjectToLocation", "(JLjava/lang/String;JLjava/lang/String;Lscript/location;FFZIIII)Z", createClientProjectileObjectToLocation), + JF("_addObjectEffect", "(JLjava/lang/String;Ljava/lang/String;Lscript/vector;FLjava/lang/String;)V", addObjectEffect), + JF("_removeObjectEffect", "(JLjava/lang/String;)V", removeObjectEffect), + JF("_removeAllObjectEffects", "(J)V", removeAllObjectEffects), + JF("_hasObjectEffect", "(JLjava/lang/String;)Z", hasObjectEffect), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsClientEffectNamespace::playClientEventObj(JNIEnv *env, jobject self, jlong client, jstring eventType, jlong objectToPlayEventOn, jstring jHardpoint, jobject jTransform) +{ + JavaStringParam localEventType(eventType); + + ServerObject* so = NULL; + if(!JavaLibrary::getObject(client, so)) + return JNI_FALSE; + Client* c = so->getClient(); + if(!c) + return JNI_FALSE; + if (!objectToPlayEventOn) + return JNI_FALSE; + + ServerObject* target = NULL; + if(!JavaLibrary::getObject(objectToPlayEventOn, target)) + return JNI_FALSE; + if(!target) + return JNI_FALSE; + + //get the event + std::string event; + JavaLibrary::convert(localEventType, event); + if (event == "") + return JNI_FALSE; + + //get the hardpoint + std::string hp; + if (NULL != jHardpoint) + { + JavaStringParam localHardpoint(jHardpoint); + JavaLibrary::convert(localHardpoint, hp); + } + + //get the transform + Transform transform; + if (NULL != jTransform) + { + ScriptConversion::convert(jTransform, transform); + } + + JAVA_THROW_SCRIPT_EXCEPTION(!hp.empty() && transform != Transform::identity, ("playClientEventObj received valid hardpoint AND valid transform.")); + + const NetworkId nid(objectToPlayEventOn); + + if (hp.empty() && transform != Transform::identity) + { + PlayClientEventObjectTransformMessage const pceotm(nid, event, transform); + so->sendToClientsInUpdateRange(pceotm, true); + } + else + { + PlayClientEventObjectMessage const pceom(nid, event, hp); + so->sendToClientsInUpdateRange(pceom, true); + } + + return JNI_TRUE; +} + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsClientEffectNamespace::playClientEventObjLimited(JNIEnv *env, jobject self, jlongArray clients, jstring eventType, jlong objectToPlayEventOn, jstring jHardpoint, jobject jTransform) +{ + JavaStringParam localEventType(eventType); + + std::vector clientIds; + if (!ScriptConversion::convert(clients, clientIds)) + return JNI_FALSE; + + if (!objectToPlayEventOn) + return JNI_FALSE; + + ServerObject* target = NULL; + if(!JavaLibrary::getObject(objectToPlayEventOn, target)) + return JNI_FALSE; + if(!target) + return JNI_FALSE; + + //get the event + std::string event; + JavaLibrary::convert(localEventType, event); + if (event == "") + return JNI_FALSE; + + //get the hardpoint + std::string hp; + if (NULL != jHardpoint) + { + JavaStringParam localHardpoint(jHardpoint); + JavaLibrary::convert(localHardpoint, hp); + } + + //get the transform + Transform transform; + if (NULL != jTransform) + { + ScriptConversion::convert(jTransform, transform); + } + + JAVA_THROW_SCRIPT_EXCEPTION(!hp.empty() && transform != Transform::identity, ("playClientEventObj received valid hardpoint AND valid transform.")); + + const NetworkId nid(objectToPlayEventOn); + + if (hp.empty() && transform != Transform::identity) + { + PlayClientEventObjectTransformMessage const pceotm(nid, event, transform); + ServerObject::sendToSpecifiedClients(pceotm, true, clientIds); + } + else + { + PlayClientEventObjectMessage const pceom(nid, event, hp); + ServerObject::sendToSpecifiedClients(pceom, true, clientIds); + } + + return JNI_TRUE; +} + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsClientEffectNamespace::playClientEventLoc(JNIEnv *env, jobject self, jlong client, jstring eventSourceType, jstring eventDestType, jobject loc, jfloat terrainDelta) +{ + JavaStringParam localEventSourceType(eventSourceType); + JavaStringParam localEventDestType(eventDestType); + + ServerObject* so = NULL; + if(!JavaLibrary::getObject(client, so)) + return JNI_FALSE; + Client* c = so->getClient(); + if(!c) + return JNI_FALSE; + //get the events + std::string eventSource; + JavaLibrary::convert(localEventSourceType, eventSource); + if(eventSource == "") + return JNI_FALSE; + std::string eventDest; + JavaLibrary::convert(localEventDestType, eventDest); + if(eventDest == "") + return JNI_FALSE; + + //get the location + Vector locationVec; + std::string sceneId; + NetworkId cell; + if (!ScriptConversion::convert(loc, locationVec, sceneId, cell)) + return JNI_FALSE; + + PlayClientEventLocMessage const pcelm(eventSource, eventDest, locationVec, sceneId, cell, terrainDelta); + + so->sendToClientsInUpdateRange(pcelm, true); + + return JNI_TRUE; +} + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsClientEffectNamespace::playClientEventLocLimited(JNIEnv *env, jobject self, jlongArray clients, jstring eventSourceType, jstring eventDestType, jobject loc, jfloat terrainDelta) +{ + JavaStringParam localEventSourceType(eventSourceType); + JavaStringParam localEventDestType(eventDestType); + + std::vector clientIds; + if (!ScriptConversion::convert(clients, clientIds)) + return JNI_FALSE; + + //get the events + std::string eventSource; + JavaLibrary::convert(localEventSourceType, eventSource); + if(eventSource == "") + return JNI_FALSE; + std::string eventDest; + JavaLibrary::convert(localEventDestType, eventDest); + if(eventDest == "") + return JNI_FALSE; + + //get the location + Vector locationVec; + std::string sceneId; + NetworkId cell; + if (!ScriptConversion::convert(loc, locationVec, sceneId, cell)) + return JNI_FALSE; + + PlayClientEventLocMessage const pcelm(eventSource, eventDest, locationVec, sceneId, cell, terrainDelta); + + ServerObject::sendToSpecifiedClients(pcelm, true, clientIds); + + return JNI_TRUE; +} + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsClientEffectNamespace::playClientEffectObj(JNIEnv *env, jobject self, jlong client, jstring effectName, jlong objectToPlayEffectOn, jstring jHardpoint, jobject jTransform, jstring labelName) +{ + JavaStringParam localEffectName(effectName); + + ServerObject* so = NULL; + if(!JavaLibrary::getObject(objectToPlayEffectOn, so)) + return JNI_FALSE; + /* TPERRY - This isn't used + @TODO: We should take the client parameter out of this function and only use objectToPlayEffectOn + Client* c = so->getClient(); + if(!c) + return JNI_FALSE; + */ + if (!objectToPlayEffectOn) + return JNI_FALSE; + + ServerObject* target = NULL; + if(!JavaLibrary::getObject(objectToPlayEffectOn, target)) + return JNI_FALSE; + if(!target) + return JNI_FALSE; + + //get the effect + std::string effect; + JavaLibrary::convert(localEffectName, effect); + if(effect == "") + return JNI_FALSE; + + //get the hardpoint + std::string hp; + if (NULL != jHardpoint) + { + JavaStringParam localHardpoint(jHardpoint); + JavaLibrary::convert(localHardpoint, hp); + } + + //get the transform + Transform transform; + if (NULL != jTransform) + { + ScriptConversion::convert(jTransform, transform); + } + + //get the optional labelName + std::string strLabelName; + if (NULL != labelName) + { + JavaStringParam localLabel(labelName); + JavaLibrary::convert(localLabel, strLabelName); + } + + JAVA_THROW_SCRIPT_EXCEPTION(!hp.empty() && transform != Transform::identity, ("playClientEffectObj received valid hardpoint AND valid transform.")); + + + const NetworkId nid(objectToPlayEffectOn); + + if (hp.empty() && transform != Transform::identity) + { + PlayClientEffectObjectTransformMessage const pceotm(nid, effect, transform, strLabelName); + so->sendToClientsInUpdateRange(pceotm, true); + } + else + { + PlayClientEffectObjectMessage const pceom(nid, effect, hp, strLabelName); + so->sendToClientsInUpdateRange(pceom, true); + } + + return JNI_TRUE; +} + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsClientEffectNamespace::playClientEffectObjLimited(JNIEnv *env, jobject self, jlongArray clients, jstring effectName, jlong objectToPlayEffectOn, jstring jHardpoint, jobject jTransform, jstring labelName) +{ + JavaStringParam localEffectName(effectName); + + std::vector clientIds; + if (!ScriptConversion::convert(clients, clientIds)) + return JNI_FALSE; + + if (!objectToPlayEffectOn) + return JNI_FALSE; + + ServerObject* target = NULL; + if(!JavaLibrary::getObject(objectToPlayEffectOn, target)) + return JNI_FALSE; + if(!target) + return JNI_FALSE; + + //get the effect + std::string effect; + JavaLibrary::convert(localEffectName, effect); + if(effect == "") + return JNI_FALSE; + + //get the hardpoint + std::string hp; + if (NULL != jHardpoint) + { + JavaStringParam localHardpoint(jHardpoint); + JavaLibrary::convert(localHardpoint, hp); + } + + //get the transform + Transform transform; + if (NULL != jTransform) + { + ScriptConversion::convert(jTransform, transform); + } + + //get the optional labelName + std::string strLabelName; + if (NULL != labelName) + { + JavaStringParam localLabel(labelName); + JavaLibrary::convert(localLabel, strLabelName); + } + + JAVA_THROW_SCRIPT_EXCEPTION(!hp.empty() && transform != Transform::identity, ("playClientEffectObj received valid hardpoint AND valid transform.")); + + const NetworkId nid(objectToPlayEffectOn); + + if (hp.empty() && transform != Transform::identity) + { + PlayClientEffectObjectTransformMessage const pceotm(nid, effect, transform, strLabelName); + ServerObject::sendToSpecifiedClients(pceotm, true, clientIds); + } + else + { + PlayClientEffectObjectMessage const pceom(nid, effect, hp, strLabelName); + ServerObject::sendToSpecifiedClients(pceom, true, clientIds); + } + + return JNI_TRUE; +} + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsClientEffectNamespace::playClientEffectLoc(JNIEnv *env, jobject self, jlong client, jstring effectName, jobject loc, jfloat terrainDelta, jstring labelName) +{ + JavaStringParam localEffectName(effectName); + + ServerObject* so = NULL; + if(!JavaLibrary::getObject(client, so)) + return JNI_FALSE; + + /* TPERRY - This isn't used + @TODO: We should take the client parameter out of this function and only use objectToPlayEffectOn + Client* c = so->getClient(); + if(!c) + return JNI_FALSE; + */ + //get the effect + std::string effect; + JavaLibrary::convert(localEffectName, effect); + if(effect == "") + return JNI_FALSE; + + //get the location + Vector locationVec; + std::string sceneId; + NetworkId cell; + if (!ScriptConversion::convert(loc, locationVec, sceneId, cell)) + return JNI_FALSE; + + //get the optional labelName + std::string strLabelName; + if (NULL != labelName) + { + JavaStringParam localLabel(labelName); + JavaLibrary::convert(localLabel, strLabelName); + } + + PlayClientEffectLocMessage const pcelm(effect, locationVec, sceneId, cell, terrainDelta, strLabelName); + + so->sendToClientsInUpdateRange(pcelm, true); + + return JNI_TRUE; +} + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsClientEffectNamespace::playClientEffectLocLimited(JNIEnv *env, jobject self, jlongArray clients, jstring effectName, jobject loc, jfloat terrainDelta, jstring labelName) +{ + JavaStringParam localEffectName(effectName); + + std::vector clientIds; + if (!ScriptConversion::convert(clients, clientIds)) + return JNI_FALSE; + + //get the effect + std::string effect; + JavaLibrary::convert(localEffectName, effect); + if(effect == "") + return JNI_FALSE; + + //get the location + Vector locationVec; + std::string sceneId; + NetworkId cell; + if (!ScriptConversion::convert(loc, locationVec, sceneId, cell)) + return JNI_FALSE; + + //get the optional labelName + std::string strLabelName; + if (NULL != labelName) + { + JavaStringParam localLabel(labelName); + JavaLibrary::convert(localLabel, strLabelName); + } + + PlayClientEffectLocMessage const pcelm(effect, locationVec, sceneId, cell, terrainDelta, strLabelName); + + ServerObject::sendToSpecifiedClients(pcelm, true, clientIds); + + return JNI_TRUE; +} + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsClientEffectNamespace::playUiEffect(JNIEnv * /*env*/, jobject /*self*/, jlong client, jstring uiEffectString) +{ + JavaStringParam localUiEffectString(uiEffectString); + + ServerObject* so = NULL; + if(!JavaLibrary::getObject(client, so)) + { + NetworkId const networkId(client); + JAVA_THROW_SCRIPT_EXCEPTION(true, ("playUiEffect - could not find player %s.", networkId.getValueString().c_str())); + return JNI_FALSE; + } + + //get the event + std::string uiEffect; + JavaLibrary::convert(localUiEffectString, uiEffect); + if (uiEffect.empty()) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("playUiEffect - empty effect string for %s.", so->getDebugInformation().c_str())); + return JNI_FALSE; + } + + //format the message. + MessageQueueGenericValueType > * const msg = new MessageQueueGenericValueType >(std::make_pair(so->getNetworkId(), uiEffect)); + so->appendMessage(CM_uiPlayEffect, 0.0f, msg); + + return JNI_TRUE; +} + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsClientEffectNamespace::stopClientEffectObjByLabel(JNIEnv *env, jobject self, jlong client, jlong objectEffectIsOn, jstring labelName, jboolean softTerminate) +{ + JavaStringParam localLabel(labelName); + + ServerObject* so = NULL; + if(!JavaLibrary::getObject(objectEffectIsOn, so)) + return JNI_FALSE; + + /* TPERRY - This isn't used + @TODO: We should take the client parameter out of this function and only use objectToPlayEffectOn + Client* c = so->getClient(); + if(!c) + return JNI_FALSE; + */ + + if (!objectEffectIsOn) + return JNI_FALSE; + + ServerObject* target = NULL; + if(!JavaLibrary::getObject(objectEffectIsOn, target)) + return JNI_FALSE; + if(!target) + return JNI_FALSE; + + //get the effect + std::string strLabelName; + JavaLibrary::convert(localLabel, strLabelName); + if(strLabelName == "") + return JNI_FALSE; + + const NetworkId nid(objectEffectIsOn); + + StopClientEffectObjectByLabelMessage const pceotm(nid, strLabelName, softTerminate); + so->sendToClientsInUpdateRange(pceotm, true); + + return JNI_TRUE; +} + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsClientEffectNamespace::stopClientEffectObjByLabelLimited(JNIEnv *env, jobject self, jlongArray clients, jlong objectEffectIsOn, jstring labelName, jboolean softTerminate) +{ + JavaStringParam localLabel(labelName); + + std::vector clientIds; + if (!ScriptConversion::convert(clients, clientIds)) + return JNI_FALSE; + + if (!objectEffectIsOn) + return JNI_FALSE; + + ServerObject* target = NULL; + if(!JavaLibrary::getObject(objectEffectIsOn, target)) + return JNI_FALSE; + if(!target) + return JNI_FALSE; + + //get the effect + std::string strLabelName; + JavaLibrary::convert(localLabel, strLabelName); + if(strLabelName == "") + return JNI_FALSE; + + const NetworkId nid(objectEffectIsOn); + + StopClientEffectObjectByLabelMessage const pceotm(nid, strLabelName, softTerminate); + ServerObject::sendToSpecifiedClients(pceotm, true, clientIds); + + return JNI_TRUE; +} + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsClientEffectNamespace::play2dNonLoopingMusic(JNIEnv *env, jobject self, jlong client, jstring musicName) +{ + JavaStringParam localMusicName(musicName); + + ServerObject* so = NULL; + if (!JavaLibrary::getObject(client, so)) + return JNI_FALSE; + Client* c = so->getClient(); + if (!c) + return JNI_FALSE; + + std::string music; + JavaLibrary::convert(localMusicName, music); + if (music == "") + return JNI_FALSE; + + PlayMusicMessage const msg(music, NetworkId::cms_invalid, 0, false); + c->send(msg, true); + + return JNI_TRUE; +} + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsClientEffectNamespace::play2dNonLoopingSound(JNIEnv *env, jobject self, jlong client, jstring musicName) +{ + JavaStringParam localMusicName(musicName); + + ServerObject* so = NULL; + if (!JavaLibrary::getObject(client, so)) + return JNI_FALSE; + Client* c = so->getClient(); + if (!c) + return JNI_FALSE; + + std::string music; + JavaLibrary::convert(localMusicName, music); + if (music == "") + return JNI_FALSE; + + PlayMusicMessage const msg(music, NetworkId::cms_invalid, 1, false); + c->send(msg, true); + + return JNI_TRUE; +} + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsClientEffectNamespace::playMusicWithParms(JNIEnv *env, jobject self, jlong client, jlong source, jstring musicName, jint playType, bool loop) +{ + JavaStringParam localMusicName(musicName); + + ServerObject* so = NULL; + if (!JavaLibrary::getObject(client, so)) + return JNI_FALSE; + Client* c = so->getClient(); + if (!c) + return JNI_FALSE; + + std::string music; + JavaLibrary::convert(localMusicName, music); + if (music == "") + return JNI_FALSE; + + PlayMusicMessage const msg(music, NetworkId(source), playType, loop); + c->send(msg, true); + + return JNI_TRUE; +} + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsClientEffectNamespace::createClientProjectile(JNIEnv *env, jobject self, jlong client, jstring weaponObjectTemplateName, jobject start, jobject end, jfloat speed, jfloat expiration, jboolean trail, jint r, jint g, jint b, jint a) +{ + JavaStringParam localWeaponObjectTemplateName(weaponObjectTemplateName); + + ServerObject* so = NULL; + if (!JavaLibrary::getObject(client, so)) + return JNI_FALSE; + + // verify a client exists + Client * c = so->getClient(); + if (!c) + return JNI_FALSE; + + // get the weapon object template name string + std::string weaponObjectTemplateNameString; + JavaLibrary::convert(localWeaponObjectTemplateName, weaponObjectTemplateNameString); + if (weaponObjectTemplateNameString == "") + return JNI_FALSE; + + // get the start location + Vector startLocationVec; + std::string startSceneId; + NetworkId startCell; + if (!ScriptConversion::convert(start, startLocationVec, startSceneId, startCell)) + return JNI_FALSE; + + // get the end location + Vector endLocationVec; + std::string endSceneId; + NetworkId endCell; + if (!ScriptConversion::convert(end, endLocationVec, endSceneId, endCell)) + return JNI_FALSE; + + CreateClientProjectileMessage const ccpm(weaponObjectTemplateNameString, startLocationVec, startCell, endLocationVec, + speed, expiration, trail, PackedArgb(static_cast(a), static_cast(r), static_cast(g), static_cast(b)).getArgb()); + + so->sendToClientsInUpdateRange(ccpm, true); + + return JNI_TRUE; +} +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsClientEffectNamespace::createClientProjectileObjectToObject(JNIEnv *env, jobject self, jlong client, jstring weaponObjectTemplateName, jlong source, jstring sourceHardpoint, jlong target, jstring targetHardpoint, jfloat speed, jfloat expiration, jboolean trail, jint r, jint g, jint b, jint a) +{ + JavaStringParam localWeaponObjectTemplateName(weaponObjectTemplateName); + + ServerObject* so = NULL; + if (!JavaLibrary::getObject(client, so)) + return JNI_FALSE; + + // verify a client exists + Client * c = so->getClient(); + if (!c) + return JNI_FALSE; + + // get the weapon object template name string + std::string weaponObjectTemplateNameString; + JavaLibrary::convert(localWeaponObjectTemplateName, weaponObjectTemplateNameString); + if (weaponObjectTemplateNameString == "") + return JNI_FALSE; + + // Get our source object + ServerObject* sourceObject = NULL; + if (!JavaLibrary::getObject(source, sourceObject)) + return JNI_FALSE; + + NetworkId sourceId = sourceObject->getNetworkId(); + + // The target of our effect + ServerObject* targetObject = NULL; + if (!JavaLibrary::getObject(target, targetObject)) + return JNI_FALSE; + + NetworkId targetId = targetObject->getNetworkId(); + + // Optional Source hardpoint + JavaStringParam localSourceHardpointName(sourceHardpoint); + std::string sourceHardpointString; + JavaLibrary::convert(localSourceHardpointName, sourceHardpointString); + + // Optional Target hardpoint + JavaStringParam localTargetHardpointName(targetHardpoint); + std::string targetHardpointString; + JavaLibrary::convert(localTargetHardpointName, targetHardpointString); + + // Source's Cell ID + CellProperty const * const cellProperty = sourceObject->getParentCell(); + Object const * const cellObject = (cellProperty != NULL) ? &cellProperty->getOwner() : NULL; + NetworkId const & networkIdForCellOrWorld = (cellObject != NULL) ? cellObject->getNetworkId() : NetworkId::cms_invalid; + + CreateClientProjectileObjectToObjectMessage const ccpmoto(weaponObjectTemplateNameString, sourceId, sourceHardpointString, networkIdForCellOrWorld, targetId, targetHardpointString, + speed, expiration, trail, PackedArgb(static_cast(a), static_cast(r), static_cast(g), static_cast(b)).getArgb()); + + so->sendToClientsInUpdateRange(ccpmoto, true); + + return JNI_TRUE; +} + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsClientEffectNamespace::createClientProjectileObjectToLocation(JNIEnv *env, jobject self, jlong client, jstring weaponObjectTemplateName, jlong source, jstring sourceHardpoint, jobject target, jfloat speed, jfloat expiration, jboolean trail, jint r, jint g, jint b, jint a) +{ + JavaStringParam localWeaponObjectTemplateName(weaponObjectTemplateName); + + ServerObject* so = NULL; + if (!JavaLibrary::getObject(client, so)) + return JNI_FALSE; + + // verify a client exists + Client * c = so->getClient(); + if (!c) + return JNI_FALSE; + + // get the weapon object template name string + std::string weaponObjectTemplateNameString; + JavaLibrary::convert(localWeaponObjectTemplateName, weaponObjectTemplateNameString); + if (weaponObjectTemplateNameString == "") + return JNI_FALSE; + + // Get our source object + ServerObject* sourceObject = NULL; + if (!JavaLibrary::getObject(source, sourceObject)) + return JNI_FALSE; + + NetworkId sourceId = sourceObject->getNetworkId(); + + // Optional Source hardpoint + JavaStringParam localSourceHardpointName(sourceHardpoint); + std::string sourceHardpointString; + JavaLibrary::convert(localSourceHardpointName, sourceHardpointString); + + // The target of our effect + Vector targetLocationVec; + std::string startSceneId; + NetworkId startCell; + if (!ScriptConversion::convert(target, targetLocationVec, startSceneId, startCell)) + return JNI_FALSE; + + // Source's Cell ID + CellProperty const * const cellProperty = sourceObject->getParentCell(); + Object const * const cellObject = (cellProperty != NULL) ? &cellProperty->getOwner() : NULL; + NetworkId const & networkIdForCellOrWorld = (cellObject != NULL) ? cellObject->getNetworkId() : NetworkId::cms_invalid; + + CreateClientProjectileObjectToLocationMessage const ccpmotl(weaponObjectTemplateNameString, sourceId, sourceHardpointString, networkIdForCellOrWorld, targetLocationVec, + speed, expiration, trail, PackedArgb(static_cast(a), static_cast(r), static_cast(g), static_cast(b)).getArgb()); + + so->sendToClientsInUpdateRange(ccpmotl, true); + + return JNI_TRUE; +} + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsClientEffectNamespace::createClientProjectileLocationToObject(JNIEnv *env, jobject self, jlong client, jstring weaponObjectTemplateName, jobject source, jlong target, jstring targetHardpoint, jfloat speed, jfloat expiration, jboolean trail, jint r, jint g, jint b, jint a) +{ + JavaStringParam localWeaponObjectTemplateName(weaponObjectTemplateName); + + ServerObject* so = NULL; + if (!JavaLibrary::getObject(client, so)) + return JNI_FALSE; + + // verify a client exists + Client * c = so->getClient(); + if (!c) + return JNI_FALSE; + + // get the weapon object template name string + std::string weaponObjectTemplateNameString; + JavaLibrary::convert(localWeaponObjectTemplateName, weaponObjectTemplateNameString); + if (weaponObjectTemplateNameString == "") + return JNI_FALSE; + + // Get our target object + ServerObject* targetObject = NULL; + if (!JavaLibrary::getObject(target, targetObject)) + return JNI_FALSE; + + NetworkId targetId = targetObject->getNetworkId(); + + + // Optional Target hardpoint + JavaStringParam localTargetHardpointName(targetHardpoint); + std::string targetHardpointString; + JavaLibrary::convert(localTargetHardpointName, targetHardpointString); + + Vector sourceLocationVec; + std::string startSceneId; + NetworkId startCell; + if (!ScriptConversion::convert(source, sourceLocationVec, startSceneId, startCell)) + return JNI_FALSE; + + // Target's Cell ID + CellProperty const * const cellProperty = targetObject->getParentCell(); + Object const * const cellObject = (cellProperty != NULL) ? &cellProperty->getOwner() : NULL; + NetworkId const & networkIdForCellOrWorld = (cellObject != NULL) ? cellObject->getNetworkId() : NetworkId::cms_invalid; + + CreateClientProjectileLocationToObjectMessage const ccpmlto(weaponObjectTemplateNameString, sourceLocationVec, networkIdForCellOrWorld, targetId, targetHardpointString, + speed, expiration, trail, PackedArgb(static_cast(a), static_cast(r), static_cast(g), static_cast(b)).getArgb()); + + so->sendToClientsInUpdateRange(ccpmlto, true); + + return JNI_TRUE; +} + +void JNICALL ScriptMethodsClientEffectNamespace::addObjectEffect(JNIEnv * env, jobject self, jlong obj, jstring filename, jstring hardpoint, jobject offset, jfloat scale, jstring label) +{ + ServerObject* so = NULL; + if (!JavaLibrary::getObject(obj, so)) + return; + + TangibleObject * tang = so->asTangibleObject(); + if(!tang) + return; + + JavaStringParam javaFilename(filename); + std::string localFilename; + JavaLibrary::convert(javaFilename, localFilename); + + JavaStringParam javaLabel(label); + std::string localLabel; + JavaLibrary::convert(javaLabel, localLabel); + + JavaStringParam javaHardpoint(hardpoint); + std::string localHardpoint; + JavaLibrary::convert(javaHardpoint, localHardpoint); + + Vector offsetVector; + ScriptConversion::convert(offset, offsetVector); + + if(localLabel.empty() || localFilename.empty()) + return; + + tang->addObjectEffect(localFilename, localHardpoint, offsetVector, scale, localLabel); + +} +void JNICALL ScriptMethodsClientEffectNamespace::removeObjectEffect(JNIEnv * env, jobject self, jlong obj, jstring label) +{ + ServerObject* so = NULL; + if (!JavaLibrary::getObject(obj, so)) + return; + + TangibleObject * tang = so->asTangibleObject(); + if(!tang) + return; + + JavaStringParam javaLabel(label); + std::string localLabel; + JavaLibrary::convert(javaLabel, localLabel); + + if(localLabel.empty()) + return; + + tang->removeObjectEffect(localLabel); +} + +void JNICALL ScriptMethodsClientEffectNamespace::removeAllObjectEffects(JNIEnv * env, jobject self, jlong obj) +{ + ServerObject* so = NULL; + if (!JavaLibrary::getObject(obj, so)) + return; + + TangibleObject * tang = so->asTangibleObject(); + if(!tang) + return; + + tang->removeAllObjectEffects(); +} + +jboolean JNICALL ScriptMethodsClientEffectNamespace::hasObjectEffect(JNIEnv * env, jobject self, jlong obj, jstring label) +{ + ServerObject* so = NULL; + if (!JavaLibrary::getObject(obj, so)) + return JNI_FALSE; + + TangibleObject * tang = so->asTangibleObject(); + if(!tang) + return JNI_FALSE; + + JavaStringParam javaLabel(label); + std::string localLabel; + JavaLibrary::convert(javaLabel, localLabel); + + if(localLabel.empty()) + return JNI_FALSE; + + return tang->hasObjectEffect(localLabel); +} + +//----------------------------------------------------------------------- diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsClusterWideData.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsClusterWideData.cpp new file mode 100644 index 00000000..19df09ef --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsClusterWideData.cpp @@ -0,0 +1,301 @@ +//======================================================================== +// +// ScriptMethodsClusterWideData.cpp - implements script methods dealing +// with cluster wide data management +// +// copyright 2001 Sony Online Entertainment +// +//======================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "serverGame/ClusterWideDataClient.h" +#include "sharedUtility/ValueDictionary.h" +#include "sharedUtility/ValueTypeBool.h" +#include "sharedUtility/ValueTypeFloat.h" +#include "sharedUtility/ValueTypeObjId.h" +#include "sharedUtility/ValueTypeSignedInt.h" +#include "sharedUtility/ValueTypeString.h" + +using namespace JNIWrappersNamespace; + + +// ====================================================================== +// ScriptMethodsClusterWideDataNamespace +// ====================================================================== + +namespace ScriptMethodsClusterWideDataNamespace +{ + bool install(); + + jint JNICALL getClusterWideData(JNIEnv *env, jobject self, jstring managerName, jstring elementNameRegex, jboolean lockElements, jlong callbackObject); + void JNICALL releaseClusterWideDataLock(JNIEnv *env, jobject self, jstring managerName, jint lockKey); + void JNICALL removeClusterWideData(JNIEnv *env, jobject self, jstring managerName, jstring elementNameRegex, jint lockKey); + void JNICALL updateClusterWideData(JNIEnv *env, jobject self, jstring managerName, jstring elementNameRegex, jobject data, jint lockKey); + void JNICALL replaceClusterWideData(JNIEnv *env, jobject self, jstring managerName, jstring elementNameRegex, jobject data, jboolean autoRemove, jint lockKey); +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsClusterWideDataNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsClusterWideDataNamespace::c)} + JF("_getClusterWideData", "(Ljava/lang/String;Ljava/lang/String;ZJ)I", getClusterWideData), + JF("releaseClusterWideDataLock", "(Ljava/lang/String;I)V", releaseClusterWideDataLock), + JF("removeClusterWideData", "(Ljava/lang/String;Ljava/lang/String;I)V", removeClusterWideData), + JF("updateClusterWideData", "(Ljava/lang/String;Ljava/lang/String;Lscript/dictionary;I)V", updateClusterWideData), + JF("replaceClusterWideData", "(Ljava/lang/String;Ljava/lang/String;Lscript/dictionary;ZI)V", replaceClusterWideData), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +//======================================================================== +// class JavaLibrary JNI conversion methods +//======================================================================== + +/** + * Converts a C++ ValueDictionary to a Java dictionary + * + * @param source the ValueDictionary to convert + * + * @return a new dictionary object + */ +LocalRefPtr JavaLibrary::convert(const ValueDictionary & source) +{ + if (ms_env == NULL) + return LocalRef::cms_nullPtr; + + // create the dictionary + LocalRefPtr target = createNewObject(ms_clsDictionary, ms_midDictionary); + if (target == LocalRef::cms_nullPtr) + return LocalRef::cms_nullPtr; + + for (DictionaryValueMap::const_iterator iter = source.get().begin(); iter != source.get().end(); ++iter) + { + JavaString paramName(iter->first.c_str()); + + if (iter->second->getType() == ValueTypeBool::ms_type) + { + const ValueTypeBool * value = static_cast(iter->second); + + callObjectMethod(*target, + ms_midDictionaryPutBool, paramName.getValue(), + value->getValue()); + } + else if (iter->second->getType() == ValueTypeFloat::ms_type) + { + const ValueTypeFloat * value = static_cast(iter->second); + + callObjectMethod(*target, + ms_midDictionaryPutFloat, paramName.getValue(), + value->getValue()); + } + else if (iter->second->getType() == ValueTypeObjId::ms_type) + { + const ValueTypeObjId * value = static_cast(iter->second); + + LocalRefPtr arg = getObjId(value->getValue()); + if (arg == LocalRef::cms_nullPtr) + return LocalRef::cms_nullPtr; + + callObjectMethod(*target, + ms_midDictionaryPut, paramName.getValue(), arg->getValue()); + } + else if (iter->second->getType() == ValueTypeSignedInt::ms_type) + { + const ValueTypeSignedInt * value = static_cast(iter->second); + + callObjectMethod(*target, + ms_midDictionaryPutInt, paramName.getValue(), + value->getValue()); + + } + else if (iter->second->getType() == ValueTypeString::ms_type) + { + const ValueTypeString * value = static_cast(iter->second); + + JavaString jvString(value->getValue().c_str()); + callObjectMethod(*target, + ms_midDictionaryPut, paramName.getValue(), jvString.getValue()); + } + else + { + DEBUG_REPORT_LOG(true, ("Unknown/unhandled data type " + "(%s) while parsing ValueDictionary\n", iter->second->getType().c_str())); + return LocalRef::cms_nullPtr; + } + } + + return target; +} // JavaLibrary::convert(const ValueDictionary &) + +// ---------------------------------------------------------------------- + +/** + * Converts a Java dictionary to a C++ ValueDictionary + * + * @param source the ValueDictionary to convert + * + * @return a new dictionary object + */ +void JavaLibrary::convert(const jobject & source, ValueDictionary & target) +{ + target.clear(); + + JNIEnv * env = getEnv(); + if (env == NULL) + return; + + if (!env->IsInstanceOf(source, ms_clsDictionary)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::convert from dictionary to ValueDictionary has a bad dictionary")); + return; + } + + // get the list of keys in the dictionary + LocalRefPtr keyEnumeration = callObjectMethod(LocalRefParam(source), ms_midDictionaryKeys); + + while (callBooleanMethod(*keyEnumeration, ms_midEnumerationHasMoreElements)) + { + LocalRefPtr key = callObjectMethod(*keyEnumeration, ms_midEnumerationNextElement); + + if (!isInstanceOf(*key, ms_clsString)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::convert from dictionary to ValueDictionary has a bad key")); + return; + } + + JavaStringParam localKeyStr(*key); + std::string keyStr; + IGNORE_RETURN(convert(localKeyStr, keyStr)); + + // convert the value into a C++ ValueType object + LocalRefPtr value = callObjectMethod(LocalRefParam(source), ms_midDictionaryGet, key->getValue()); + + if (isInstanceOf(*value, ms_clsBoolean)) + { + jboolean booleanValue = callBooleanMethod(*value, ms_midBooleanBooleanValue); + target.insert(keyStr, ValueTypeBool(booleanValue ? true : false)); + } + else if (isInstanceOf(*value, ms_clsFloat)) + { + jfloat floatValue = callFloatMethod(*value, ms_midFloatFloatValue); + target.insert(keyStr, ValueTypeFloat(static_cast(floatValue))); + } + else if (isInstanceOf(*value, ms_clsObjId)) + { + NetworkId networkId(getNetworkId(*value)); + target.insert(keyStr, ValueTypeObjId(networkId)); + } + else if (isInstanceOf(*value, ms_clsInteger)) + { + jint intValue = callIntMethod(*value, ms_midIntegerIntValue); + target.insert(keyStr, ValueTypeSignedInt(static_cast(intValue))); + } + else if (isInstanceOf(*value, ms_clsString)) + { + JavaStringParam localValueStr(*value); + std::string valueStr; + IGNORE_RETURN(convert(localValueStr, valueStr)); + + target.insert(keyStr, ValueTypeString(valueStr)); + } + else + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::convert from dictionary to ValueDictionary - key (%s) is an unsupported type", keyStr.c_str())); + return; + } + } +} + +//-------------------------------------------------------------------------------------- + +jint JNICALL ScriptMethodsClusterWideDataNamespace::getClusterWideData(JNIEnv *, jobject, jstring managerName, jstring elementNameRegex, jboolean lockElements, jlong callbackObject) +{ + JavaStringParam localJstringManagerName(managerName); + std::string localManagerName; + IGNORE_RETURN(JavaLibrary::convert(localJstringManagerName, localManagerName)); + + JavaStringParam localJstringElementNameRegex(elementNameRegex); + std::string localElementNameRegex; + IGNORE_RETURN(JavaLibrary::convert(localJstringElementNameRegex, localElementNameRegex)); + + return static_cast(ClusterWideDataClient::getClusterWideData(localManagerName, localElementNameRegex, (lockElements == JNI_TRUE), NetworkId(callbackObject))); +} + +//-------------------------------------------------------------------------------------- + +void JNICALL ScriptMethodsClusterWideDataNamespace::releaseClusterWideDataLock(JNIEnv *, jobject, jstring managerName, jint lockKey) +{ + JavaStringParam localJstringManagerName(managerName); + std::string localManagerName; + IGNORE_RETURN(JavaLibrary::convert(localJstringManagerName, localManagerName)); + + ClusterWideDataClient::releaseClusterWideDataLock(localManagerName, static_cast(lockKey)); + + return; +} + +//-------------------------------------------------------------------------------------- + +void JNICALL ScriptMethodsClusterWideDataNamespace::removeClusterWideData(JNIEnv *, jobject, jstring managerName, jstring elementNameRegex, jint lockKey) +{ + JavaStringParam localJstringManagerName(managerName); + std::string localManagerName; + IGNORE_RETURN(JavaLibrary::convert(localJstringManagerName, localManagerName)); + + JavaStringParam localJstringElementNameRegex(elementNameRegex); + std::string localElementNameRegex; + IGNORE_RETURN(JavaLibrary::convert(localJstringElementNameRegex, localElementNameRegex)); + + ClusterWideDataClient::removeClusterWideData(localManagerName, localElementNameRegex, static_cast(lockKey)); + + return; +} + +//-------------------------------------------------------------------------------------- + +void JNICALL ScriptMethodsClusterWideDataNamespace::updateClusterWideData(JNIEnv *, jobject, jstring managerName, jstring elementNameRegex, jobject data, jint lockKey) +{ + JavaStringParam localJstringManagerName(managerName); + std::string localManagerName; + IGNORE_RETURN(JavaLibrary::convert(localJstringManagerName, localManagerName)); + + JavaStringParam localJstringElementNameRegex(elementNameRegex); + std::string localElementNameRegex; + IGNORE_RETURN(JavaLibrary::convert(localJstringElementNameRegex, localElementNameRegex)); + + ValueDictionary valueDictionary; + JavaLibrary::convert(data, valueDictionary); + + ClusterWideDataClient::updateClusterWideData(localManagerName, localElementNameRegex, valueDictionary, static_cast(lockKey)); + + return; +} + +//-------------------------------------------------------------------------------------- + +void JNICALL ScriptMethodsClusterWideDataNamespace::replaceClusterWideData(JNIEnv *, jobject, jstring managerName, jstring elementNameRegex, jobject data, jboolean autoRemove, jint lockKey) +{ + JavaStringParam localJstringManagerName(managerName); + std::string localManagerName; + IGNORE_RETURN(JavaLibrary::convert(localJstringManagerName, localManagerName)); + + JavaStringParam localJstringElementNameRegex(elementNameRegex); + std::string localElementNameRegex; + IGNORE_RETURN(JavaLibrary::convert(localJstringElementNameRegex, localElementNameRegex)); + + ValueDictionary valueDictionary; + JavaLibrary::convert(data, valueDictionary); + + ClusterWideDataClient::replaceClusterWideData(localManagerName, localElementNameRegex, valueDictionary, (autoRemove == JNI_TRUE), static_cast(lockKey)); + + return; +} diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsCollection.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsCollection.cpp new file mode 100644 index 00000000..69c08716 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsCollection.cpp @@ -0,0 +1,1012 @@ +//======================================================================== +// +// ScriptMethodsCollection.cpp - implements script methods dealing with collection +// +// copyright 2001 Sony Online Entertainment +// +//======================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "serverGame/CreatureObject.h" +#include "serverGame/PlayerCreatureController.h" +#include "serverGame/PlayerObject.h" + +using namespace JNIWrappersNamespace; + +// ====================================================================== +// ScriptMethodsCollectionNamespace +// ====================================================================== + +namespace ScriptMethodsCollectionNamespace +{ + bool install(); + jboolean JNICALL modifyCollectionSlotValue(JNIEnv *env, jobject self, jlong player, jstring slotName, jlong delta); + jlong JNICALL getCollectionSlotValue(JNIEnv *env, jobject self, jlong player, jstring slotName); + jboolean JNICALL hasCompletedCollectionSlotPrereq(JNIEnv *env, jobject self, jlong player, jstring slotName); + jboolean JNICALL hasCompletedCollectionSlot(JNIEnv *env, jobject self, jlong player, jstring slotName); + jboolean JNICALL hasCompletedCollection(JNIEnv *env, jobject self, jlong player, jstring collectionName); + jboolean JNICALL hasCompletedCollectionPage(JNIEnv *env, jobject self, jlong player, jstring pageName); + jboolean JNICALL hasCompletedCollectionBook(JNIEnv *env, jobject self, jlong player, jstring bookName); + jobjectArray JNICALL getCompletedCollectionSlotsInCollection(JNIEnv *env, jobject self, jlong player, jstring collectionName); + jobjectArray JNICALL getCompletedCollectionSlotsInPage(JNIEnv *env, jobject self, jlong player, jstring pageName); + jobjectArray JNICALL getCompletedCollectionsInPage(JNIEnv *env, jobject self, jlong player, jstring pageName); + jobjectArray JNICALL getCompletedCollectionSlotsInBook(JNIEnv *env, jobject self, jlong player, jstring bookName); + jobjectArray JNICALL getCompletedCollectionsInBook(JNIEnv *env, jobject self, jlong player, jstring bookName); + jobjectArray JNICALL getCompletedCollectionPagesInBook(JNIEnv *env, jobject self, jlong player, jstring bookName); + jobjectArray JNICALL getCompletedCollectionBooks(JNIEnv *env, jobject self, jlong player); + jobjectArray JNICALL getCollectionSlotInfo(JNIEnv *env, jobject self, jstring slotName); + jboolean JNICALL isCollectionSlotATitle(JNIEnv *env, jobject self, jstring slotName); + jboolean JNICALL isCollectionATitle(JNIEnv *env, jobject self, jstring collectionName); + jboolean JNICALL isCollectionPageATitle(JNIEnv *env, jobject self, jstring pageName); + jobjectArray JNICALL getCollectionSlotCategoryInfo(JNIEnv *env, jobject self, jstring slotName); + jobjectArray JNICALL getCollectionSlotPrereqInfo(JNIEnv *env, jobject self, jstring slotName); + jstring JNICALL getCollectionSlotName(JNIEnv *env, jobject self, jint collectionSlotId); + jobjectArray JNICALL getAllCollectionSlotsInCollection(JNIEnv *env, jobject self, jstring collectionName); + jobjectArray JNICALL getAllCollectionSlotsInPage(JNIEnv *env, jobject self, jstring pageName); + jobjectArray JNICALL getAllCollectionsInPage(JNIEnv *env, jobject self, jstring pageName); + jobjectArray JNICALL getAllCollectionSlotsInBook(JNIEnv *env, jobject self, jstring bookName); + jobjectArray JNICALL getAllCollectionsInBook(JNIEnv *env, jobject self, jstring bookName); + jobjectArray JNICALL getAllCollectionPagesInBook(JNIEnv *env, jobject self, jstring bookName); + jobjectArray JNICALL getAllCollectionBooks(JNIEnv *env, jobject self); + jobjectArray JNICALL getAllCollectionSlotsInCategory(JNIEnv *env, jobject self, jstring categoryName); + jobjectArray JNICALL getAllCollectionSlotsInCategoryInCollection(JNIEnv *env, jobject self, jstring collectionName, jstring categoryName); + jobjectArray JNICALL getAllCollectionSlotsInCategoryInPage(JNIEnv *env, jobject self, jstring pageName, jstring categoryName); + jobjectArray JNICALL getAllCollectionSlotsInCategoryInBook(JNIEnv *env, jobject self, jstring bookName, jstring categoryName); + jobjectArray JNICALL getAllCollectionSlotCategoriesInCollection(JNIEnv *env, jobject self, jstring collectionName); + jobjectArray JNICALL getAllCollectionSlotCategoriesInPage(JNIEnv *env, jobject self, jstring pageName); + jobjectArray JNICALL getAllCollectionSlotCategoriesInBook(JNIEnv *env, jobject self, jstring bookName); + jobjectArray JNICALL getAllCollectionSlotCategories(JNIEnv *env, jobject self); +} + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsCollectionNamespace::install() +{ + const JNINativeMethod NATIVES[] = { +#define JF(a,b,c) {a,b,(void*)(ScriptMethodsCollectionNamespace::c)} + JF("_modifyCollectionSlotValue", "(JLjava/lang/String;J)Z", modifyCollectionSlotValue), + JF("_getCollectionSlotValue", "(JLjava/lang/String;)J", getCollectionSlotValue), + JF("_hasCompletedCollectionSlotPrereq", "(JLjava/lang/String;)Z", hasCompletedCollectionSlotPrereq), + JF("_hasCompletedCollectionSlot", "(JLjava/lang/String;)Z", hasCompletedCollectionSlot), + JF("_hasCompletedCollection", "(JLjava/lang/String;)Z", hasCompletedCollection), + JF("_hasCompletedCollectionPage", "(JLjava/lang/String;)Z", hasCompletedCollectionPage), + JF("_hasCompletedCollectionBook", "(JLjava/lang/String;)Z", hasCompletedCollectionBook), + JF("_getCompletedCollectionSlotsInCollection", "(JLjava/lang/String;)[Ljava/lang/String;", getCompletedCollectionSlotsInCollection), + JF("_getCompletedCollectionSlotsInPage", "(JLjava/lang/String;)[Ljava/lang/String;", getCompletedCollectionSlotsInPage), + JF("_getCompletedCollectionsInPage", "(JLjava/lang/String;)[Ljava/lang/String;", getCompletedCollectionsInPage), + JF("_getCompletedCollectionSlotsInBook", "(JLjava/lang/String;)[Ljava/lang/String;", getCompletedCollectionSlotsInBook), + JF("_getCompletedCollectionsInBook", "(JLjava/lang/String;)[Ljava/lang/String;", getCompletedCollectionsInBook), + JF("_getCompletedCollectionPagesInBook", "(JLjava/lang/String;)[Ljava/lang/String;", getCompletedCollectionPagesInBook), + JF("_getCompletedCollectionBooks", "(J)[Ljava/lang/String;", getCompletedCollectionBooks), + JF("getCollectionSlotInfo", "(Ljava/lang/String;)[Ljava/lang/String;", getCollectionSlotInfo), + JF("isCollectionSlotATitle", "(Ljava/lang/String;)Z", isCollectionSlotATitle), + JF("isCollectionATitle", "(Ljava/lang/String;)Z", isCollectionATitle), + JF("isCollectionPageATitle", "(Ljava/lang/String;)Z", isCollectionPageATitle), + JF("getCollectionSlotCategoryInfo", "(Ljava/lang/String;)[Ljava/lang/String;", getCollectionSlotCategoryInfo), + JF("getCollectionSlotPrereqInfo", "(Ljava/lang/String;)[Ljava/lang/String;", getCollectionSlotPrereqInfo), + JF("getCollectionSlotName", "(I)Ljava/lang/String;", getCollectionSlotName), + JF("getAllCollectionSlotsInCollection", "(Ljava/lang/String;)[Ljava/lang/String;", getAllCollectionSlotsInCollection), + JF("getAllCollectionSlotsInPage", "(Ljava/lang/String;)[Ljava/lang/String;", getAllCollectionSlotsInPage), + JF("getAllCollectionsInPage", "(Ljava/lang/String;)[Ljava/lang/String;", getAllCollectionsInPage), + JF("getAllCollectionSlotsInBook", "(Ljava/lang/String;)[Ljava/lang/String;", getAllCollectionSlotsInBook), + JF("getAllCollectionsInBook", "(Ljava/lang/String;)[Ljava/lang/String;", getAllCollectionsInBook), + JF("getAllCollectionPagesInBook", "(Ljava/lang/String;)[Ljava/lang/String;", getAllCollectionPagesInBook), + JF("getAllCollectionBooks", "()[Ljava/lang/String;", getAllCollectionBooks), + JF("getAllCollectionSlotsInCategory", "(Ljava/lang/String;)[Ljava/lang/String;", getAllCollectionSlotsInCategory), + JF("getAllCollectionSlotsInCategoryInCollection", "(Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;", getAllCollectionSlotsInCategoryInCollection), + JF("getAllCollectionSlotsInCategoryInPage", "(Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;", getAllCollectionSlotsInCategoryInPage), + JF("getAllCollectionSlotsInCategoryInBook", "(Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;", getAllCollectionSlotsInCategoryInBook), + JF("getAllCollectionSlotCategoriesInCollection", "(Ljava/lang/String;)[Ljava/lang/String;", getAllCollectionSlotCategoriesInCollection), + JF("getAllCollectionSlotCategoriesInPage", "(Ljava/lang/String;)[Ljava/lang/String;", getAllCollectionSlotCategoriesInPage), + JF("getAllCollectionSlotCategoriesInBook", "(Ljava/lang/String;)[Ljava/lang/String;", getAllCollectionSlotCategoriesInBook), + JF("getAllCollectionSlotCategories", "()[Ljava/lang/String;", getAllCollectionSlotCategories), + }; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsCollectionNamespace::modifyCollectionSlotValue(JNIEnv *env, jobject self, jlong player, jstring slotName, jlong delta) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(player, creature)) + return JNI_FALSE; + + PlayerObject * const playerObject = PlayerCreatureController::getPlayerObject(creature); + if (!playerObject) + return JNI_FALSE; + + JavaStringParam localSlotName(slotName); + std::string slotNameString; + JavaLibrary::convert(localSlotName, slotNameString); + + return playerObject->modifyCollectionSlotValue(slotNameString, static_cast(delta)); +} + +// ---------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsCollectionNamespace::getCollectionSlotValue(JNIEnv *env, jobject self, jlong player, jstring slotName) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(player, creature)) + return static_cast(-1); + + PlayerObject * const playerObject = PlayerCreatureController::getPlayerObject(creature); + if (!playerObject) + return static_cast(-1); + + JavaStringParam localSlotName(slotName); + std::string slotNameString; + JavaLibrary::convert(localSlotName, slotNameString); + + unsigned long value; + if (!playerObject->getCollectionSlotValue(slotNameString, value)) + return static_cast(-1); + + return static_cast(value); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsCollectionNamespace::hasCompletedCollectionSlotPrereq(JNIEnv *env, jobject self, jlong player, jstring slotName) +{ + UNREF(self); + + CreatureObject const * creature = 0; + if (!JavaLibrary::getObject(player, creature)) + return JNI_FALSE; + + PlayerObject const * const playerObject = PlayerCreatureController::getPlayerObject(creature); + if (!playerObject) + return JNI_FALSE; + + JavaStringParam localSlotName(slotName); + std::string slotNameString; + JavaLibrary::convert(localSlotName, slotNameString); + + return playerObject->hasCompletedCollectionSlotPrereq(slotNameString); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsCollectionNamespace::hasCompletedCollectionSlot(JNIEnv *env, jobject self, jlong player, jstring slotName) +{ + UNREF(self); + + CreatureObject const * creature = 0; + if (!JavaLibrary::getObject(player, creature)) + return JNI_FALSE; + + PlayerObject const * const playerObject = PlayerCreatureController::getPlayerObject(creature); + if (!playerObject) + return JNI_FALSE; + + JavaStringParam localSlotName(slotName); + std::string slotNameString; + JavaLibrary::convert(localSlotName, slotNameString); + + return playerObject->hasCompletedCollectionSlot(slotNameString); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsCollectionNamespace::hasCompletedCollection(JNIEnv *env, jobject self, jlong player, jstring collectionName) +{ + UNREF(self); + + CreatureObject const * creature = 0; + if (!JavaLibrary::getObject(player, creature)) + return JNI_FALSE; + + PlayerObject const * const playerObject = PlayerCreatureController::getPlayerObject(creature); + if (!playerObject) + return JNI_FALSE; + + JavaStringParam localCollectionName(collectionName); + std::string collectionNameString; + JavaLibrary::convert(localCollectionName, collectionNameString); + + return playerObject->hasCompletedCollection(collectionNameString); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsCollectionNamespace::hasCompletedCollectionPage(JNIEnv *env, jobject self, jlong player, jstring pageName) +{ + UNREF(self); + + CreatureObject const * creature = 0; + if (!JavaLibrary::getObject(player, creature)) + return JNI_FALSE; + + PlayerObject const * const playerObject = PlayerCreatureController::getPlayerObject(creature); + if (!playerObject) + return JNI_FALSE; + + JavaStringParam localPageName(pageName); + std::string pageNameString; + JavaLibrary::convert(localPageName, pageNameString); + + return playerObject->hasCompletedCollectionPage(pageNameString); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsCollectionNamespace::hasCompletedCollectionBook(JNIEnv *env, jobject self, jlong player, jstring bookName) +{ + UNREF(self); + + CreatureObject const * creature = 0; + if (!JavaLibrary::getObject(player, creature)) + return JNI_FALSE; + + PlayerObject const * const playerObject = PlayerCreatureController::getPlayerObject(creature); + if (!playerObject) + return JNI_FALSE; + + JavaStringParam localBookName(bookName); + std::string bookNameString; + JavaLibrary::convert(localBookName, bookNameString); + + return playerObject->hasCompletedCollectionBook(bookNameString); +} + +// ---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsCollectionNamespace::getCompletedCollectionSlotsInCollection(JNIEnv *env, jobject self, jlong player, jstring collectionName) +{ + UNREF(self); + + CreatureObject const * creature = 0; + if (!JavaLibrary::getObject(player, creature)) + return 0; + + PlayerObject const * const playerObject = PlayerCreatureController::getPlayerObject(creature); + if (!playerObject) + return 0; + + JavaStringParam localCollectionName(collectionName); + std::string collectionNameString; + JavaLibrary::convert(localCollectionName, collectionNameString); + + std::vector collectionInfo; + IGNORE_RETURN(playerObject->getCompletedCollectionSlotCountInCollection(collectionNameString, &collectionInfo)); + if (collectionInfo.empty()) + return 0; + + int i = 0; + LocalObjectArrayRefPtr valueArray = createNewObjectArray(collectionInfo.size(), JavaLibrary::getClsString()); + for (std::vector::const_iterator iter = collectionInfo.begin(); iter != collectionInfo.end(); ++iter) + { + JavaString jval((*iter)->name); + setObjectArrayElement(*valueArray, i++, jval); + } + + return valueArray->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsCollectionNamespace::getCompletedCollectionSlotsInPage(JNIEnv *env, jobject self, jlong player, jstring pageName) +{ + UNREF(self); + + CreatureObject const * creature = 0; + if (!JavaLibrary::getObject(player, creature)) + return 0; + + PlayerObject const * const playerObject = PlayerCreatureController::getPlayerObject(creature); + if (!playerObject) + return 0; + + JavaStringParam localPageName(pageName); + std::string pageNameString; + JavaLibrary::convert(localPageName, pageNameString); + + std::vector collectionInfo; + IGNORE_RETURN(playerObject->getCompletedCollectionSlotCountInPage(pageNameString, &collectionInfo)); + if (collectionInfo.empty()) + return 0; + + int i = 0; + LocalObjectArrayRefPtr valueArray = createNewObjectArray(collectionInfo.size(), JavaLibrary::getClsString()); + for (std::vector::const_iterator iter = collectionInfo.begin(); iter != collectionInfo.end(); ++iter) + { + JavaString jval((*iter)->name); + setObjectArrayElement(*valueArray, i++, jval); + } + + return valueArray->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsCollectionNamespace::getCompletedCollectionsInPage(JNIEnv *env, jobject self, jlong player, jstring pageName) +{ + UNREF(self); + + CreatureObject const * creature = 0; + if (!JavaLibrary::getObject(player, creature)) + return 0; + + PlayerObject const * const playerObject = PlayerCreatureController::getPlayerObject(creature); + if (!playerObject) + return 0; + + JavaStringParam localPageName(pageName); + std::string pageNameString; + JavaLibrary::convert(localPageName, pageNameString); + + std::vector collectionInfo; + IGNORE_RETURN(playerObject->getCompletedCollectionCountInPage(pageNameString, &collectionInfo)); + if (collectionInfo.empty()) + return 0; + + int i = 0; + LocalObjectArrayRefPtr valueArray = createNewObjectArray(collectionInfo.size(), JavaLibrary::getClsString()); + for (std::vector::const_iterator iter = collectionInfo.begin(); iter != collectionInfo.end(); ++iter) + { + JavaString jval((*iter)->name); + setObjectArrayElement(*valueArray, i++, jval); + } + + return valueArray->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsCollectionNamespace::getCompletedCollectionSlotsInBook(JNIEnv *env, jobject self, jlong player, jstring bookName) +{ + UNREF(self); + + CreatureObject const * creature = 0; + if (!JavaLibrary::getObject(player, creature)) + return 0; + + PlayerObject const * const playerObject = PlayerCreatureController::getPlayerObject(creature); + if (!playerObject) + return 0; + + JavaStringParam localBookName(bookName); + std::string bookNameString; + JavaLibrary::convert(localBookName, bookNameString); + + std::vector collectionInfo; + IGNORE_RETURN(playerObject->getCompletedCollectionSlotCountInBook(bookNameString, &collectionInfo)); + if (collectionInfo.empty()) + return 0; + + int i = 0; + LocalObjectArrayRefPtr valueArray = createNewObjectArray(collectionInfo.size(), JavaLibrary::getClsString()); + for (std::vector::const_iterator iter = collectionInfo.begin(); iter != collectionInfo.end(); ++iter) + { + JavaString jval((*iter)->name); + setObjectArrayElement(*valueArray, i++, jval); + } + + return valueArray->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsCollectionNamespace::getCompletedCollectionsInBook(JNIEnv *env, jobject self, jlong player, jstring bookName) +{ + UNREF(self); + + CreatureObject const * creature = 0; + if (!JavaLibrary::getObject(player, creature)) + return 0; + + PlayerObject const * const playerObject = PlayerCreatureController::getPlayerObject(creature); + if (!playerObject) + return 0; + + JavaStringParam localBookName(bookName); + std::string bookNameString; + JavaLibrary::convert(localBookName, bookNameString); + + std::vector collectionInfo; + IGNORE_RETURN(playerObject->getCompletedCollectionCountInBook(bookNameString, &collectionInfo)); + if (collectionInfo.empty()) + return 0; + + int i = 0; + LocalObjectArrayRefPtr valueArray = createNewObjectArray(collectionInfo.size(), JavaLibrary::getClsString()); + for (std::vector::const_iterator iter = collectionInfo.begin(); iter != collectionInfo.end(); ++iter) + { + JavaString jval((*iter)->name); + setObjectArrayElement(*valueArray, i++, jval); + } + + return valueArray->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsCollectionNamespace::getCompletedCollectionPagesInBook(JNIEnv *env, jobject self, jlong player, jstring bookName) +{ + UNREF(self); + + CreatureObject const * creature = 0; + if (!JavaLibrary::getObject(player, creature)) + return 0; + + PlayerObject const * const playerObject = PlayerCreatureController::getPlayerObject(creature); + if (!playerObject) + return 0; + + JavaStringParam localBookName(bookName); + std::string bookNameString; + JavaLibrary::convert(localBookName, bookNameString); + + std::vector collectionInfo; + IGNORE_RETURN(playerObject->getCompletedCollectionPageCountInBook(bookNameString, &collectionInfo)); + if (collectionInfo.empty()) + return 0; + + int i = 0; + LocalObjectArrayRefPtr valueArray = createNewObjectArray(collectionInfo.size(), JavaLibrary::getClsString()); + for (std::vector::const_iterator iter = collectionInfo.begin(); iter != collectionInfo.end(); ++iter) + { + JavaString jval((*iter)->name); + setObjectArrayElement(*valueArray, i++, jval); + } + + return valueArray->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsCollectionNamespace::getCompletedCollectionBooks(JNIEnv *env, jobject self, jlong player) +{ + UNREF(self); + + CreatureObject const * creature = 0; + if (!JavaLibrary::getObject(player, creature)) + return 0; + + PlayerObject const * const playerObject = PlayerCreatureController::getPlayerObject(creature); + if (!playerObject) + return 0; + + std::vector collectionInfo; + IGNORE_RETURN(playerObject->getCompletedCollectionBookCount(&collectionInfo)); + if (collectionInfo.empty()) + return 0; + + int i = 0; + LocalObjectArrayRefPtr valueArray = createNewObjectArray(collectionInfo.size(), JavaLibrary::getClsString()); + for (std::vector::const_iterator iter = collectionInfo.begin(); iter != collectionInfo.end(); ++iter) + { + JavaString jval((*iter)->name); + setObjectArrayElement(*valueArray, i++, jval); + } + + return valueArray->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsCollectionNamespace::getCollectionSlotInfo(JNIEnv *env, jobject self, jstring slotName) +{ + UNREF(self); + + JavaStringParam localSlotName(slotName); + std::string slotNameString; + JavaLibrary::convert(localSlotName, slotNameString); + + CollectionsDataTable::CollectionInfoSlot const * slot = CollectionsDataTable::getSlotByName(slotNameString); + if (!slot) + return 0; + + LocalObjectArrayRefPtr valueArray = createNewObjectArray(4, JavaLibrary::getClsString()); + setObjectArrayElement(*valueArray, 0, JavaString(slot->collection.page.book.name)); + setObjectArrayElement(*valueArray, 1, JavaString(slot->collection.page.name)); + setObjectArrayElement(*valueArray, 2, JavaString(slot->collection.name)); + setObjectArrayElement(*valueArray, 3, JavaString(slot->music)); + + return valueArray->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsCollectionNamespace::isCollectionSlotATitle(JNIEnv *env, jobject self, jstring slotName) +{ + UNREF(self); + + JavaStringParam localSlotName(slotName); + std::string slotNameString; + JavaLibrary::convert(localSlotName, slotNameString); + + CollectionsDataTable::CollectionInfoSlot const * const slot = CollectionsDataTable::getSlotByName(slotNameString); + return (slot && !slot->titles.empty()); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsCollectionNamespace::isCollectionATitle(JNIEnv *env, jobject self, jstring collectionName) +{ + UNREF(self); + + JavaStringParam localCollectionName(collectionName); + std::string collectionNameString; + JavaLibrary::convert(localCollectionName, collectionNameString); + + CollectionsDataTable::CollectionInfoCollection const * const collection = CollectionsDataTable::getCollectionByName(collectionNameString); + + return (collection && !collection->titles.empty()); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsCollectionNamespace::isCollectionPageATitle(JNIEnv *env, jobject self, jstring pageName) +{ + UNREF(self); + + JavaStringParam localPageName(pageName); + std::string pageNameString; + JavaLibrary::convert(localPageName, pageNameString); + + CollectionsDataTable::CollectionInfoPage const * const page = CollectionsDataTable::getPageByName(pageNameString); + + return (page && !page->titles.empty()); +} + +// ---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsCollectionNamespace::getCollectionSlotCategoryInfo(JNIEnv *env, jobject self, jstring slotName) +{ + UNREF(self); + + JavaStringParam localSlotName(slotName); + std::string slotNameString; + JavaLibrary::convert(localSlotName, slotNameString); + + CollectionsDataTable::CollectionInfoSlot const * slot = CollectionsDataTable::getSlotByName(slotNameString); + if (!slot) + return 0; + + if (slot->categories.empty()) + return 0; + + int i = 0; + LocalObjectArrayRefPtr valueArray = createNewObjectArray(slot->categories.size(), JavaLibrary::getClsString()); + for (std::vector::const_iterator iter = slot->categories.begin(); iter != slot->categories.end(); ++iter) + { + JavaString jval(*iter); + setObjectArrayElement(*valueArray, i++, jval); + } + + return valueArray->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsCollectionNamespace::getCollectionSlotPrereqInfo(JNIEnv *env, jobject self, jstring slotName) +{ + UNREF(self); + + JavaStringParam localSlotName(slotName); + std::string slotNameString; + JavaLibrary::convert(localSlotName, slotNameString); + + CollectionsDataTable::CollectionInfoSlot const * slot = CollectionsDataTable::getSlotByName(slotNameString); + if (!slot) + return 0; + + if (slot->prereqsPtr.empty()) + return 0; + + int i = 0; + LocalObjectArrayRefPtr valueArray = createNewObjectArray(slot->prereqsPtr.size(), JavaLibrary::getClsString()); + for (std::vector::const_iterator iter = slot->prereqsPtr.begin(); iter != slot->prereqsPtr.end(); ++iter) + { + JavaString jval((*iter)->name); + setObjectArrayElement(*valueArray, i++, jval); + } + + return valueArray->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsCollectionNamespace::getCollectionSlotName(JNIEnv *env, jobject self, jint collectionSlotId) +{ + UNREF(self); + + CollectionsDataTable::CollectionInfoSlot const * slot = CollectionsDataTable::getSlotByBeginSlotId(collectionSlotId); + if (!slot) + return 0; + + return JavaString(slot->name).getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsCollectionNamespace::getAllCollectionSlotsInCollection(JNIEnv *env, jobject self, jstring collectionName) +{ + UNREF(self); + + JavaStringParam localCollectionName(collectionName); + std::string collectionNameString; + JavaLibrary::convert(localCollectionName, collectionNameString); + + std::vector const & slots = CollectionsDataTable::getSlotsInCollection(collectionNameString); + if (slots.empty()) + return 0; + + int i = 0; + LocalObjectArrayRefPtr valueArray = createNewObjectArray(slots.size(), JavaLibrary::getClsString()); + for (std::vector::const_iterator iter = slots.begin(); iter != slots.end(); ++iter) + { + JavaString jval((*iter)->name); + setObjectArrayElement(*valueArray, i++, jval); + } + + return valueArray->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsCollectionNamespace::getAllCollectionSlotsInPage(JNIEnv *env, jobject self, jstring pageName) +{ + UNREF(self); + + JavaStringParam localPageName(pageName); + std::string pageNameString; + JavaLibrary::convert(localPageName, pageNameString); + + std::vector const & slots = CollectionsDataTable::getSlotsInPage(pageNameString); + if (slots.empty()) + return 0; + + int i = 0; + LocalObjectArrayRefPtr valueArray = createNewObjectArray(slots.size(), JavaLibrary::getClsString()); + for (std::vector::const_iterator iter = slots.begin(); iter != slots.end(); ++iter) + { + JavaString jval((*iter)->name); + setObjectArrayElement(*valueArray, i++, jval); + } + + return valueArray->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsCollectionNamespace::getAllCollectionsInPage(JNIEnv *env, jobject self, jstring pageName) +{ + UNREF(self); + + JavaStringParam localPageName(pageName); + std::string pageNameString; + JavaLibrary::convert(localPageName, pageNameString); + + std::vector const & collections = CollectionsDataTable::getCollectionsInPage(pageNameString); + if (collections.empty()) + return 0; + + int i = 0; + LocalObjectArrayRefPtr valueArray = createNewObjectArray(collections.size(), JavaLibrary::getClsString()); + for (std::vector::const_iterator iter = collections.begin(); iter != collections.end(); ++iter) + { + JavaString jval((*iter)->name); + setObjectArrayElement(*valueArray, i++, jval); + } + + return valueArray->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsCollectionNamespace::getAllCollectionSlotsInBook(JNIEnv *env, jobject self, jstring bookName) +{ + UNREF(self); + + JavaStringParam localBookName(bookName); + std::string bookNameString; + JavaLibrary::convert(localBookName, bookNameString); + + std::vector const & slots = CollectionsDataTable::getSlotsInBook(bookNameString); + if (slots.empty()) + return 0; + + int i = 0; + LocalObjectArrayRefPtr valueArray = createNewObjectArray(slots.size(), JavaLibrary::getClsString()); + for (std::vector::const_iterator iter = slots.begin(); iter != slots.end(); ++iter) + { + JavaString jval((*iter)->name); + setObjectArrayElement(*valueArray, i++, jval); + } + + return valueArray->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsCollectionNamespace::getAllCollectionsInBook(JNIEnv *env, jobject self, jstring bookName) +{ + UNREF(self); + + JavaStringParam localBookName(bookName); + std::string bookNameString; + JavaLibrary::convert(localBookName, bookNameString); + + std::vector const & collections = CollectionsDataTable::getCollectionsInBook(bookNameString); + if (collections.empty()) + return 0; + + int i = 0; + LocalObjectArrayRefPtr valueArray = createNewObjectArray(collections.size(), JavaLibrary::getClsString()); + for (std::vector::const_iterator iter = collections.begin(); iter != collections.end(); ++iter) + { + JavaString jval((*iter)->name); + setObjectArrayElement(*valueArray, i++, jval); + } + + return valueArray->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsCollectionNamespace::getAllCollectionPagesInBook(JNIEnv *env, jobject self, jstring bookName) +{ + UNREF(self); + + JavaStringParam localBookName(bookName); + std::string bookNameString; + JavaLibrary::convert(localBookName, bookNameString); + + std::vector const & pages = CollectionsDataTable::getPagesInBook(bookNameString); + if (pages.empty()) + return 0; + + int i = 0; + LocalObjectArrayRefPtr valueArray = createNewObjectArray(pages.size(), JavaLibrary::getClsString()); + for (std::vector::const_iterator iter = pages.begin(); iter != pages.end(); ++iter) + { + JavaString jval((*iter)->name); + setObjectArrayElement(*valueArray, i++, jval); + } + + return valueArray->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsCollectionNamespace::getAllCollectionBooks(JNIEnv *env, jobject self) +{ + UNREF(self); + + std::vector const & books = CollectionsDataTable::getAllBooks(); + if (books.empty()) + return 0; + + int i = 0; + LocalObjectArrayRefPtr valueArray = createNewObjectArray(books.size(), JavaLibrary::getClsString()); + for (std::vector::const_iterator iter = books.begin(); iter != books.end(); ++iter) + { + JavaString jval((*iter)->name); + setObjectArrayElement(*valueArray, i++, jval); + } + + return valueArray->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsCollectionNamespace::getAllCollectionSlotsInCategory(JNIEnv *env, jobject self, jstring categoryName) +{ + UNREF(self); + + JavaStringParam localCategoryName(categoryName); + std::string categoryNameString; + JavaLibrary::convert(localCategoryName, categoryNameString); + + std::vector const & slots = CollectionsDataTable::getSlotsInCategory(categoryNameString); + if (slots.empty()) + return 0; + + int i = 0; + LocalObjectArrayRefPtr valueArray = createNewObjectArray(slots.size(), JavaLibrary::getClsString()); + for (std::vector::const_iterator iter = slots.begin(); iter != slots.end(); ++iter) + { + JavaString jval((*iter)->name); + setObjectArrayElement(*valueArray, i++, jval); + } + + return valueArray->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsCollectionNamespace::getAllCollectionSlotsInCategoryInCollection(JNIEnv *env, jobject self, jstring collectionName, jstring categoryName) +{ + UNREF(self); + + JavaStringParam localCollectionName(collectionName); + std::string collectionNameString; + JavaLibrary::convert(localCollectionName, collectionNameString); + + JavaStringParam localCategoryName(categoryName); + std::string categoryNameString; + JavaLibrary::convert(localCategoryName, categoryNameString); + + std::vector const & slots = CollectionsDataTable::getSlotsInCategoryByCollection(collectionNameString, categoryNameString); + if (slots.empty()) + return 0; + + int i = 0; + LocalObjectArrayRefPtr valueArray = createNewObjectArray(slots.size(), JavaLibrary::getClsString()); + for (std::vector::const_iterator iter = slots.begin(); iter != slots.end(); ++iter) + { + JavaString jval((*iter)->name); + setObjectArrayElement(*valueArray, i++, jval); + } + + return valueArray->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsCollectionNamespace::getAllCollectionSlotsInCategoryInPage(JNIEnv *env, jobject self, jstring pageName, jstring categoryName) +{ + UNREF(self); + + JavaStringParam localPageName(pageName); + std::string pageNameString; + JavaLibrary::convert(localPageName, pageNameString); + + JavaStringParam localCategoryName(categoryName); + std::string categoryNameString; + JavaLibrary::convert(localCategoryName, categoryNameString); + + std::vector const & slots = CollectionsDataTable::getSlotsInCategoryByPage(pageNameString, categoryNameString); + if (slots.empty()) + return 0; + + int i = 0; + LocalObjectArrayRefPtr valueArray = createNewObjectArray(slots.size(), JavaLibrary::getClsString()); + for (std::vector::const_iterator iter = slots.begin(); iter != slots.end(); ++iter) + { + JavaString jval((*iter)->name); + setObjectArrayElement(*valueArray, i++, jval); + } + + return valueArray->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsCollectionNamespace::getAllCollectionSlotsInCategoryInBook(JNIEnv *env, jobject self, jstring bookName, jstring categoryName) +{ + UNREF(self); + + JavaStringParam localBookName(bookName); + std::string bookNameString; + JavaLibrary::convert(localBookName, bookNameString); + + JavaStringParam localCategoryName(categoryName); + std::string categoryNameString; + JavaLibrary::convert(localCategoryName, categoryNameString); + + std::vector const & slots = CollectionsDataTable::getSlotsInCategoryByBook(bookNameString, categoryNameString); + if (slots.empty()) + return 0; + + int i = 0; + LocalObjectArrayRefPtr valueArray = createNewObjectArray(slots.size(), JavaLibrary::getClsString()); + for (std::vector::const_iterator iter = slots.begin(); iter != slots.end(); ++iter) + { + JavaString jval((*iter)->name); + setObjectArrayElement(*valueArray, i++, jval); + } + + return valueArray->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsCollectionNamespace::getAllCollectionSlotCategoriesInCollection(JNIEnv *env, jobject self, jstring collectionName) +{ + UNREF(self); + + JavaStringParam localCollectionName(collectionName); + std::string collectionNameString; + JavaLibrary::convert(localCollectionName, collectionNameString); + + std::set const & categories = CollectionsDataTable::getAllSlotCategoriesInCollection(collectionNameString); + if (categories.empty()) + return 0; + + int i = 0; + LocalObjectArrayRefPtr valueArray = createNewObjectArray(categories.size(), JavaLibrary::getClsString()); + for (std::set::const_iterator iter = categories.begin(); iter != categories.end(); ++iter) + { + JavaString jval(*iter); + setObjectArrayElement(*valueArray, i++, jval); + } + + return valueArray->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsCollectionNamespace::getAllCollectionSlotCategoriesInPage(JNIEnv *env, jobject self, jstring pageName) +{ + UNREF(self); + + JavaStringParam localPageName(pageName); + std::string pageNameString; + JavaLibrary::convert(localPageName, pageNameString); + + std::set const & categories = CollectionsDataTable::getAllSlotCategoriesInPage(pageNameString); + if (categories.empty()) + return 0; + + int i = 0; + LocalObjectArrayRefPtr valueArray = createNewObjectArray(categories.size(), JavaLibrary::getClsString()); + for (std::set::const_iterator iter = categories.begin(); iter != categories.end(); ++iter) + { + JavaString jval(*iter); + setObjectArrayElement(*valueArray, i++, jval); + } + + return valueArray->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsCollectionNamespace::getAllCollectionSlotCategoriesInBook(JNIEnv *env, jobject self, jstring bookName) +{ + UNREF(self); + + JavaStringParam localBookName(bookName); + std::string bookNameString; + JavaLibrary::convert(localBookName, bookNameString); + + std::set const & categories = CollectionsDataTable::getAllSlotCategoriesInBook(bookNameString); + if (categories.empty()) + return 0; + + int i = 0; + LocalObjectArrayRefPtr valueArray = createNewObjectArray(categories.size(), JavaLibrary::getClsString()); + for (std::set::const_iterator iter = categories.begin(); iter != categories.end(); ++iter) + { + JavaString jval(*iter); + setObjectArrayElement(*valueArray, i++, jval); + } + + return valueArray->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsCollectionNamespace::getAllCollectionSlotCategories(JNIEnv *env, jobject self) +{ + UNREF(self); + + std::set const & categories = CollectionsDataTable::getAllSlotCategories(); + if (categories.empty()) + return 0; + + int i = 0; + LocalObjectArrayRefPtr valueArray = createNewObjectArray(categories.size(), JavaLibrary::getClsString()); + for (std::set::const_iterator iter = categories.begin(); iter != categories.end(); ++iter) + { + JavaString jval(*iter); + setObjectArrayElement(*valueArray, i++, jval); + } + + return valueArray->getReturnValue(); +} + +//======================================================================== diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsCombat.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsCombat.cpp new file mode 100644 index 00000000..0bbf8cca --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsCombat.cpp @@ -0,0 +1,2468 @@ +//======================================================================== +// +// ScriptMethodsCombat.cpp - implements script methods dealing with general +// object info. +// +// copyright 2001 Sony Online Entertainment +// +//======================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "serverGame/AiLogManager.h" +#include "serverGame/ConfigServerGame.h" +#include "serverGame/ContainerInterface.h" +#include "serverGame/CreatureController.h" +#include "serverGame/CreatureObject.h" +#include "serverGame/PlayerCreatureController.h" +#include "serverGame/PlayerObject.h" +#include "serverGame/ServerWorld.h" +#include "serverGame/WeaponObject.h" +#include "serverScript/GameScriptObject.h" +#include "serverScript/ScriptParameters.h" +#include "serverUtility/ServerClock.h" +#include "sharedGame/CommandTable.h" +#include "sharedGame/ClientCombatManagerSupport.h" +#include "sharedFoundation/ConstCharCrcLowerString.h" +#include "sharedFoundation/GameControllerMessage.h" +#include "sharedFoundation/TemporaryCrcString.h" +#include "sharedLog/Log.h" +#include "sharedNetworkMessages/MessageQueueCombatSpam.h" +#include "sharedObject/CellProperty.h" +#include "sharedObject/NetworkIdManager.h" +#include "sharedObject/ObjectTemplateList.h" +#include "SwgGameServer/CombatEngine.h" +#include "SwgGameServer/ConfigCombatEngine.h" +#include "swgSharedUtility/CombatEngineData.h" +#include "swgSharedNetworkMessages/MessageQueueCombatAction.h" +#include "UnicodeUtils.h" + +using namespace JNIWrappersNamespace; + +static const std::string UNSKILLED_COMMAND("unskilled"); + + +// ====================================================================== +// ScriptMethodsCombatNamespace +// ====================================================================== + +namespace ScriptMethodsCombatNamespace +{ + bool install(); + + jint JNICALL getCombatDuration(JNIEnv * env, jobject self, jlong object); + jlong JNICALL getCurrentWeapon(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL setCurrentWeapon(JNIEnv *env, jobject self, jlong target, jlong targetWeapon); + jlong JNICALL getHeldWeapon(JNIEnv *env, jobject self, jlong target); + jlong JNICALL getDefaultWeapon(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL swapDefaultWeapons(JNIEnv *env, jobject self, jlong jcreature, jlong jweapon, jlong jcontainer); + jboolean JNICALL isWeapon(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL isDefaultWeapon(JNIEnv *env, jobject self, jlong target); + jfloat JNICALL getMinRange(JNIEnv *env, jobject self, jlong weaponId); + jfloat JNICALL getMaxRange(JNIEnv *env, jobject self, jlong weaponId); + jfloat JNICALL getAverageDamage(JNIEnv *env, jobject self, jlong weaponId); + jint JNICALL getWeaponType(JNIEnv *env, jobject self, jlong weaponId); + jint JNICALL getWeaponAttackType(JNIEnv *env, jobject self, jlong weaponId); + jint JNICALL getWeaponDamageType(JNIEnv *env, jobject self, jlong weapon); + jboolean JNICALL setWeaponDamageType(JNIEnv *env, jobject self, jlong weaponId, jint type); + jint JNICALL getWeaponMinDamage(JNIEnv *env, jobject self, jlong weapon); + jboolean JNICALL setWeaponMinDamage(JNIEnv *env, jobject self, jlong weapon, jint damage); + jint JNICALL getWeaponMaxDamage(JNIEnv *env, jobject self, jlong weapon); + jboolean JNICALL setWeaponMaxDamage(JNIEnv *env, jobject self, jlong weapon, jint damage); + jfloat JNICALL getWeaponAttackSpeed(JNIEnv *env, jobject self, jlong weapon); + jboolean JNICALL setWeaponAttackSpeed(JNIEnv *env, jobject self, jlong weapon, jfloat speed); + jobject JNICALL getWeaponRangeInfo(JNIEnv *env, jobject self, jlong weapon); + jboolean JNICALL setWeaponRangeInfo(JNIEnv *env, jobject self, jlong weapon, jobject info); + jfloat JNICALL getWeaponWoundChance(JNIEnv *env, jobject self, jlong weapon); + jboolean JNICALL setWeaponWoundChance(JNIEnv *env, jobject self, jlong weapon, jfloat chance); + jfloat JNICALL getWeaponDamageRadius(JNIEnv *env, jobject self, jlong weapon); + jboolean JNICALL setWeaponDamageRadius(JNIEnv *env, jobject self, jlong weapon, jfloat radius); + jfloat JNICALL getAudibleRange(JNIEnv *env, jobject self, jlong mob); + jint JNICALL getWeaponAttackCost(JNIEnv *env, jobject self, jlong weaponId); + jboolean JNICALL setWeaponAttackCost(JNIEnv *env, jobject self, jlong weaponId, jint cost); + jint JNICALL getWeaponAccuracy(JNIEnv *env, jobject self, jlong weaponId); + jboolean JNICALL setWeaponAccuracy(JNIEnv *env, jobject self, jlong weaponId, jint accuracy); + jint JNICALL getWeaponElementalType(JNIEnv *env, jobject self, jlong weaponId); + jboolean JNICALL setWeaponElementalType(JNIEnv *env, jobject self, jlong weaponId, jint type); + jint JNICALL getWeaponElementalValue(JNIEnv *env, jobject self, jlong weaponId); + jboolean JNICALL setWeaponElementalValue(JNIEnv *env, jobject self, jlong weaponId, jint value); + jboolean JNICALL isCombatEnabled(JNIEnv *env, jobject self); + jboolean JNICALL directDamage(JNIEnv *env, jobject self, jlong targetId, jint type, jint location, jint amount); + jboolean JNICALL directWeaponDamage(JNIEnv *env, jobject self, jlong targetId, jlong weaponId, jint amount, jint location); + jboolean JNICALL directAreaDamageObject(JNIEnv *env, jobject self, jlong targetId, jfloat radius, jint type, jint amount); + jboolean JNICALL directAreaDamageLocation(JNIEnv *env, jobject self, jobject center, jfloat radius, jint type, jint amount); + void JNICALL startCombat(JNIEnv *env, jobject self, jlong attacker, jlong defender); + void JNICALL startCombatWithAssist(JNIEnv *env, jobject self, jlong attacker, jlong defender); + void JNICALL stopCombat(JNIEnv *env, jobject self, jlong object); + jboolean JNICALL getCombatData(JNIEnv *env, jobject self, jlongArray attackers, jlongArray defenders, jobjectArray attackersData, jobjectArray defendersData, jobjectArray weaponsData); + jboolean JNICALL getWeaponData(JNIEnv *env, jobject self, jlong weapon, jobject weaponData); + jboolean JNICALL doDamage(JNIEnv *env, jobject self, jlong attacker, jlong defender, jlong weapon, jint damage, jint hitLocation); + jboolean JNICALL doDamageNoWeapon(JNIEnv *env, jobject self, jlong attacker, jlong defender, jint damage, jint hitLocation); + jboolean JNICALL doCombatResults(JNIEnv *env, jobject self, jstring animationId, jobject attackerResult, jobjectArray defenderResult); + jboolean JNICALL callDefenderCombatAction(JNIEnv *env, jobject self, jlongArray defenders, jintArray results, jlong attacker, jlong weapon); + void JNICALL setWantSawAttackTriggers(JNIEnv *env, jobject self, jlong obj, jboolean enable); + jboolean JNICALL addSlowDownEffect(JNIEnv *env, jobject self, jlong attacker, jlong defender, jfloat coneLength, jfloat coneAngle, jfloat slopeAngle, jfloat effectTime); + jboolean JNICALL removeSlowDownEffect(JNIEnv *env, jobject self, jlong attacker); + void JNICALL sendCombatSpam(JNIEnv *env, jobject self, jlong attacker, jlong defender, jlong weapon, jobject result, jobject attackName, jboolean sendToAttacker, jboolean sendToDefender, jboolean sendToBystanders, jint spamType); + void JNICALL sendCombatSpamWeaponString(JNIEnv *env, jobject self, jlong attacker, jlong defender, jobject weaponName, jobject result, jobject attackName, jboolean sendToAttacker, jboolean sendToDefender, jboolean sendToBystanders, jint spamType); + void JNICALL sendCombatSpamMessage(JNIEnv *env, jobject self, jlong attacker, jlong defender, jobject message, jboolean sendToAttacker, jboolean sendToDefender, jboolean sendToBystanders, jint spamType); + void JNICALL sendCombatSpamMessageCGP(JNIEnv *env, jobject self, jlong attacker, jlong defender, jobject message, jboolean sendToAttacker, jboolean sendToDefender, jboolean sendToBystanders, jboolean critical, jboolean glancing, jboolean proc, jint spamType); + void JNICALL sendCombatSpamMessageOob(JNIEnv *env, jobject self, jlong attacker, jlong defender, jstring oob, jboolean sendToAttacker, jboolean sendToDefender, jboolean sendToBystanders, jint spamType); + void JNICALL incrementKillMeter(JNIEnv *env, jobject self, jlong player, jint amount); + jint JNICALL getKillMeter(JNIEnv *env, jobject self, jlong player); + jboolean JNICALL overrideDefaultAttack(JNIEnv *env, jobject self, jlong player, jstring attack); + jboolean JNICALL removeDefaultAttackOverride(JNIEnv *env, jobject self, jlong player); + jstring JNICALL getDefaultAttackOverrideActionName(JNIEnv *env, jobject self, jlong player); + + int const totalWildcards = 2; + std::string const s_wildcardReplacements[totalWildcards] = { "medium", "light" }; +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsCombatNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsCombatNamespace::c)} + JF("_getCombatDuration", "(J)I", getCombatDuration), + JF("_getCurrentWeapon", "(J)J", getCurrentWeapon), + JF("_setCurrentWeapon", "(JJ)Z", setCurrentWeapon), + JF("_getHeldWeapon", "(J)J", getHeldWeapon), + JF("_getDefaultWeapon", "(J)J", getDefaultWeapon), + JF("_swapDefaultWeapons", "(JJJ)Z", swapDefaultWeapons), + JF("_isWeapon", "(J)Z", isWeapon), + JF("_isDefaultWeapon", "(J)Z", isDefaultWeapon), + JF("_getMinRange", "(J)F", getMinRange), + JF("_getMaxRange", "(J)F", getMaxRange), + JF("_getAverageDamage", "(J)F", getAverageDamage), + JF("_getWeaponType", "(J)I", getWeaponType), + JF("_getWeaponAttackType", "(J)I", getWeaponAttackType), + JF("_getWeaponDamageType", "(J)I", getWeaponDamageType), + JF("_setWeaponDamageType", "(JI)Z", setWeaponDamageType), + JF("_getWeaponMinDamage", "(J)I", getWeaponMinDamage), + JF("_setWeaponMinDamage", "(JI)Z", setWeaponMinDamage), + JF("_getWeaponMaxDamage", "(J)I", getWeaponMaxDamage), + JF("_setWeaponMaxDamage", "(JI)Z", setWeaponMaxDamage), + JF("_getWeaponAttackSpeed", "(J)F", getWeaponAttackSpeed), + JF("_setWeaponAttackSpeed", "(JF)Z", setWeaponAttackSpeed), + JF("_getWeaponRangeInfo", "(J)Lscript/base_class$range_info;", getWeaponRangeInfo), + JF("_setWeaponRangeInfo", "(JLscript/base_class$range_info;)Z", setWeaponRangeInfo), + JF("_getWeaponWoundChance", "(J)F", getWeaponWoundChance), + JF("_setWeaponWoundChance", "(JF)Z", setWeaponWoundChance), + JF("_getWeaponDamageRadius", "(J)F", getWeaponDamageRadius), + JF("_setWeaponDamageRadius", "(JF)Z", setWeaponDamageRadius), + JF("_getWeaponAudibleRange", "(J)F",getAudibleRange), + JF("_getWeaponAttackCost", "(J)I", getWeaponAttackCost), + JF("_setWeaponAttackCost", "(JI)Z", setWeaponAttackCost), + JF("_getWeaponAccuracy", "(J)I", getWeaponAccuracy), + JF("_setWeaponAccuracy", "(JI)Z", setWeaponAccuracy), + JF("_getWeaponElementalType", "(J)I", getWeaponElementalType), + JF("_setWeaponElementalType", "(JI)Z", setWeaponElementalType), + JF("_getWeaponElementalValue", "(J)I", getWeaponElementalValue), + JF("_setWeaponElementalValue", "(JI)Z", setWeaponElementalValue), + JF("isCombatEnabled", "()Z", isCombatEnabled), + JF("_damage", "(JIII)Z", directDamage), + JF("_damage", "(JJII)Z", directWeaponDamage), + JF("_damage", "(JFII)Z", directAreaDamageObject), + JF("damage", "(Lscript/location;FII)Z", directAreaDamageLocation), + JF("_startCombat", "(JJ)V", startCombat), + JF("_startCombatWithAssist", "(JJ)V", startCombatWithAssist), + JF("_stopCombat", "(J)V", stopCombat), + JF("__getCombatData", "([J[J[Lscript/combat_engine$attacker_data;[Lscript/combat_engine$defender_data;[Lscript/combat_engine$weapon_data;)Z", getCombatData), + JF("__getWeaponData", "(JLscript/combat_engine$weapon_data;)Z", getWeaponData), + JF("__doDamage", "(JJJII)Z", doDamage), + JF("__doDamageNoWeapon", "(JJII)Z", doDamageNoWeapon), + JF("doCombatResults", "(Ljava/lang/String;Lscript/base_class$attacker_results;[Lscript/base_class$defender_results;)Z", doCombatResults), + JF("_callDefenderCombatAction", "([J[IJJ)Z", callDefenderCombatAction), + JF("_setWantSawAttackTriggers", "(JZ)V", setWantSawAttackTriggers), + JF("_addSlowDownEffect", "(JJFFFF)Z", addSlowDownEffect), + JF("_removeSlowDownEffect", "(J)Z", removeSlowDownEffect), + JF("_sendCombatSpam", "(JJJLscript/combat_engine$hit_result;Lscript/string_id;ZZZI)V", sendCombatSpam), + JF("_sendCombatSpam", "(JJLscript/string_id;Lscript/combat_engine$hit_result;Lscript/string_id;ZZZI)V", sendCombatSpamWeaponString), + JF("_sendCombatSpamMessage", "(JJLscript/string_id;ZZZI)V", sendCombatSpamMessage), + JF("_sendCombatSpamMessageCGP", "(JJLscript/string_id;ZZZZZZI)V", sendCombatSpamMessageCGP), + JF("_sendCombatSpamMessageOob", "(JJLjava/lang/String;ZZZI)V", sendCombatSpamMessageOob), + JF("_incrementKillMeter", "(JI)V", incrementKillMeter), + JF("_getKillMeter", "(J)I", getKillMeter), + JF("_overrideDefaultAttack", "(JLjava/lang/String;)Z", overrideDefaultAttack), + JF("_removeDefaultAttackOverride", "(J)Z", removeDefaultAttackOverride), + JF("_getDefaultAttackOverrideActionName", "(J)Ljava/lang/String;", getDefaultAttackOverrideActionName) +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +//======================================================================== +// local utility functions +//======================================================================== + +/** + * Fills in a Java combat_engine.weapon_data structure with data from a weapon. + * + * @param env Java environment + * @param weapon weapon to get the data from + * @param weaponData data to fill in + */ +void JavaLibrary::setupWeaponCombatData(JNIEnv *env, const WeaponObject * weapon, + jobject weaponData) +{ + if (env == NULL || weaponData == NULL) + return; + + if (weapon == NULL) + { + env->SetObjectField(weaponData, ms_fidCombatEngineWeaponDataId, NULL); + return; + } + + LocalRefParam jweaponData(weaponData); + LocalRefPtr weaponId = getObjId(weapon->getNetworkId()); + + // set up base weapon data + setObjectField(jweaponData, ms_fidCombatEngineWeaponDataId, *weaponId); + setIntField(jweaponData, ms_fidCombatEngineWeaponDataMinDamage, weapon->getMinDamage()); + setIntField(jweaponData, ms_fidCombatEngineWeaponDataMaxDamage, weapon->getMaxDamage()); + setIntField(jweaponData, ms_fidCombatEngineWeaponDataWeaponType, weapon->getWeaponType()); + setIntField(jweaponData, ms_fidCombatEngineWeaponDataAttackType, weapon->getAttackType()); + setIntField(jweaponData, ms_fidCombatEngineWeaponDataDamageType, weapon->getDamageType()); + setIntField(jweaponData, ms_fidCombatEngineWeaponDataElementalType, weapon->getElementalType()); + setIntField(jweaponData, ms_fidCombatEngineWeaponDataElementalValue, weapon->getElementalValue()); + setFloatField(jweaponData, ms_fidCombatEngineWeaponDataAttackSpeed, weapon->getAttackTime()); + setFloatField(jweaponData, ms_fidCombatEngineWeaponDataWoundChance, weapon->getWoundChance()); + setIntField(jweaponData, ms_fidCombatEngineWeaponDataAccuracy, weapon->getAccuracy()); + setFloatField(jweaponData, ms_fidCombatEngineWeaponDataMinRange, weapon->getMinRange()); + setFloatField(jweaponData, ms_fidCombatEngineWeaponDataMaxRange, weapon->getMaxRange()); + setFloatField(jweaponData, ms_fidCombatEngineWeaponDataDamageRadius, weapon->getDamageRadius()); + setIntField(jweaponData, ms_fidCombatEngineWeaponDataAttackCost, weapon->getAttackCost()); + setBooleanField(jweaponData, ms_fidCombatEngineWeaponDataIsDisabled, weapon->isDisabled()); +} // setupWeaponCombatData + + +//======================================================================== +// class JavaLibrary JNI weapon callback methods +//======================================================================== + +jint JNICALL ScriptMethodsCombatNamespace::getCombatDuration(JNIEnv * /*env*/, jobject /*self*/, jlong object) +{ + NetworkId const networkId(object); + TangibleObject const * const tangibleObject = TangibleObject::getTangibleObject(networkId); + + if (tangibleObject == NULL) + { + return 0; + } + + return tangibleObject->getCombatDuration(); +} + +/** + * Returns the current weapon a creature is using for combat. + * + * @param env Java environment + * @param self class calling this function + * @param target id of the creature + * + * @return the object id of the weapon, or NULL on error + */ +jlong JNICALL ScriptMethodsCombatNamespace::getCurrentWeapon(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return 0; + + const WeaponObject * weapon = creature->getCurrentWeapon(); + if (weapon == NULL) + return 0; + + return (weapon->getNetworkId()).getValue(); +} // JavaLibrary::getCurrentWeapon + +/** + * Sets the weapon a creature will use for combat. + * @param target id of the object + * @param weapon id of the weapon + * @return JNI_TRUE on success, JNI_FALSE on fail + */ +jboolean JNICALL ScriptMethodsCombatNamespace::setCurrentWeapon(JNIEnv *env, jobject self, jlong target, jlong targetWeapon) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + WeaponObject * weapon = 0; + if (!JavaLibrary::getObject(targetWeapon, weapon)) + return JNI_FALSE; + + creature->setCurrentWeapon(*weapon); + return JNI_TRUE; +} // JavaLibrary::setCurrentWeapon + +/** + * Returns the current weapon a creature has equipped. + * + * @param env Java environment + * @param self class calling this function + * @param target id of the creature + * + * @return the object id of the weapon, or NULL on error + */ +jlong JNICALL ScriptMethodsCombatNamespace::getHeldWeapon(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + const CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return 0; + + const WeaponObject * weapon = creature->getReadiedWeapon(); + if (weapon == NULL) + return 0; + + return (weapon->getNetworkId()).getValue(); +} // JavaLibrary::getHeldWeapon + +/** + * Returns the default weapon of a creature. + * + * @param env Java environment + * @param self class calling this function + * @param target id of the creature + * + * @return the object id of the default weapon, or NULL on error + */ +jlong JNICALL ScriptMethodsCombatNamespace::getDefaultWeapon(JNIEnv *env, jobject self, jlong target) +{ +UNREF(self); + + const CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return 0; + + const WeaponObject * weapon = creature->getDefaultWeapon(); + if (weapon == NULL) + return 0; + + return (weapon->getNetworkId()).getValue(); +} // JavaLibrary::getDefaultWeapon + +/** + * Replaces the default weapon of a creature. + * + * @param env Java environment + * @param self class calling this function + * @param creature id of the creature + * @param weapon id of the new default weapon + * @param container id of the container to put the old weapon in + * + * @return true on success, false on error + */ +jboolean JNICALL ScriptMethodsCombatNamespace::swapDefaultWeapons(JNIEnv *env, jobject, jlong jcreature, jlong jweapon, jlong jcontainer) +{ + CreatureObject *creature = 0; + if (!JavaLibrary::getObject(jcreature, creature)) + return JNI_FALSE; + + WeaponObject *newDefaultWeapon = 0; + if (!JavaLibrary::getObject(jweapon, newDefaultWeapon)) + return JNI_FALSE; + + ServerObject *weaponContainer = 0; + if (!JavaLibrary::getObject(jcontainer, weaponContainer)) + return JNI_FALSE; + + if (!creature->swapDefaultWeapons(*newDefaultWeapon, *weaponContainer)) + return JNI_FALSE; + + return JNI_TRUE; +} + +/** + * Tests to see if an object is a weapon. + * + * @param env Java environment + * @param self class calling this function + * @param target id of object we want to check + * + * @return true if the object is a weapon, false if not + */ +jboolean JNICALL ScriptMethodsCombatNamespace::isWeapon(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + const WeaponObject *weapon = 0; + if (!JavaLibrary::getObject(target, weapon)) + return JNI_FALSE; + return JNI_TRUE; +} // JavaLibrary::isWeapon + +/** + * Tests to see if an object is a default weapon. + * + * @param env Java environment + * @param self class calling this function + * @param target id of object we want to check + * + * @return true if the object is a default weapon, false if not + */ +jboolean JNICALL ScriptMethodsCombatNamespace::isDefaultWeapon(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + const WeaponObject *weapon = 0; + if (!JavaLibrary::getObject(target, weapon)) + return JNI_FALSE; + + const CreatureObject * owner = dynamic_cast(ContainerInterface::getContainedByObject(*weapon)); + if (owner == NULL || owner->getDefaultWeapon() != weapon) + return JNI_FALSE; + + return JNI_TRUE; +} // JavaLibrary::isDefaultWeapon + +/** + * Returns the minimum attack range of a weapon. + * + * @param env Java environment + * @param self class calling this function + * @param weaponId id of weapon + * + * @return the range, or -1 on error + */ +jfloat JNICALL ScriptMethodsCombatNamespace::getMinRange(JNIEnv *env, jobject self, jlong weaponId) +{ + UNREF(self); + + const WeaponObject *weapon = NULL; + if (!JavaLibrary::getObject(weaponId, weapon)) + return -1.0f; + + jfloat range = weapon->getMinRange(); + return range; +} // JavaLibrary::getMinRange + +/** + * Returns the maximum attack range of a weapon. + * + * @param env Java environment + * @param self class calling this function + * @param weaponId id of weapon + * + * @return the range, or -1 on error + */ +jfloat JNICALL ScriptMethodsCombatNamespace::getMaxRange(JNIEnv *env, jobject self, jlong weaponId) +{ + UNREF(self); + + const WeaponObject *weapon = NULL; + if (!JavaLibrary::getObject(weaponId, weapon)) + return -1.0f; + + jfloat range = weapon->getMaxRange(); + return range; +} // JavaLibrary::getMaxRange + +/** + * Returns the average damage a weapon will do + * + * @param env Java environment + * @param self class calling this function + * @param weaponId id of weapon + * + * @return the damage, or 0 on error + */ +jfloat JNICALL ScriptMethodsCombatNamespace::getAverageDamage(JNIEnv *env, jobject self, jlong weaponId) +{ + UNREF(self); + + const WeaponObject *weapon = NULL; + if (!JavaLibrary::getObject(weaponId, weapon)) + return 0; + + jfloat damage = weapon->getMinDamage() + (weapon->getMaxDamage() - + weapon->getMinDamage()) / 2.0f; + + return damage; +} // JavaLibrary::getAverageDamage + +/** + * Returns a weapon's type. + * + * @param env Java environment + * @param self class calling this function + * @param weaponId id of weapon + * + * @return the type, or -1 on error + */ +jint JNICALL ScriptMethodsCombatNamespace::getWeaponType(JNIEnv *env, jobject self, jlong weaponId) +{ + UNREF(self); + + const WeaponObject *weapon = NULL; + if (!JavaLibrary::getObject(weaponId, weapon)) + return -1; + + jint type = weapon->getWeaponType(); + return type; +} // JavaLibrary::getWeaponType + +/** + * Returns a weapon's attack type. + * + * @param env Java environment + * @param self class calling this function + * @param weaponId id of weapon + * + * @return the type, or -1 on error + */ +jint JNICALL ScriptMethodsCombatNamespace::getWeaponAttackType(JNIEnv *env, jobject self, jlong weaponId) +{ + UNREF(self); + + const WeaponObject *weapon = NULL; + if (!JavaLibrary::getObject(weaponId, weapon)) + return -1; + + jint type = weapon->getAttackType(); + return type; +} // JavaLibrary::getWeaponAttackType + +/** + * Gets the damage type of a weapon. + * + * @param weapon the id of the weapon + * + * @return the damage type, or -1 on error + */ +jint JNICALL ScriptMethodsCombatNamespace::getWeaponDamageType(JNIEnv *env, jobject self, jlong weaponId) +{ + UNREF(self); + + const WeaponObject *weapon = NULL; + if (!JavaLibrary::getObject(weaponId, weapon)) + return -1; + + jint type = weapon->getDamageType(); + return type; +} // JavaLibrary::getWeaponDamageType + +/** + * Sets the ddamage type for a weapon. + * + * @param env Java environment + * @param self class calling this function + * @param weaponId the id of the weapon + * @param cost damage type for the weapon + * + * @return true on success, false if there was an error + */ +jboolean JNICALL ScriptMethodsCombatNamespace::setWeaponDamageType(JNIEnv *env, jobject self, jlong weaponId, jint type) +{ + UNREF(self); + + WeaponObject *weapon = 0; + if (!JavaLibrary::getObject(weaponId, weapon)) + return JNI_FALSE; + + weapon->setDamageType(type); + + return JNI_TRUE; +} // JavaLibrary::setWeaponDamageType + + /** + * Gets the minimum damage a weapon does. + * + * @param env Java environment + * @param self class calling this function + * @param weaponId the id of the weapon + * + * @return the damage, or -1 on error + */ +jint JNICALL ScriptMethodsCombatNamespace::getWeaponMinDamage(JNIEnv *env, jobject self, jlong weaponId) +{ + UNREF(self); + + const WeaponObject *weapon = NULL; + if (!JavaLibrary::getObject(weaponId, weapon)) + return -1; + + jint damage = weapon->getMinDamage(); + return damage; +} // JavaLibrary::getWeaponMinDamage + +/** + * Sets the minimum damage a weapon does. + * + * @param env Java environment + * @param self class calling this function + * @param weaponId the id of the weapon + * @param damage the minimum damage + * + * @return true on success, false if there was an error + */ +jboolean JNICALL ScriptMethodsCombatNamespace::setWeaponMinDamage(JNIEnv *env, jobject self, jlong weaponId, jint damage) +{ + UNREF(self); + + WeaponObject *weapon = 0; + if (!JavaLibrary::getObject(weaponId, weapon)) + return JNI_FALSE; + + if (damage < 0) + return JNI_FALSE; + + weapon->setMinDamage(damage); + return JNI_TRUE; +} // JavaLibrary::setWeaponMinDamage + +/** + * Gets the maximum damage a weapon does. + * + * @param env Java environment + * @param self class calling this function + * @param weaponId the id of the weapon + * + * @return the damage, or -1 on error + */ +jint JNICALL ScriptMethodsCombatNamespace::getWeaponMaxDamage(JNIEnv *env, jobject self, jlong weaponId) +{ + UNREF(self); + + const WeaponObject *weapon = NULL; + if (!JavaLibrary::getObject(weaponId, weapon)) + return -1; + + jint damage = weapon->getMaxDamage(); + return damage; +} // JavaLibrary::getWeaponMaxDamage + +/** + * Sets the maximum damage a weapon does. + * + * @param env Java environment + * @param self class calling this function + * @param weaponId the id of the weapon + * @param damage the maximum damage + * + * @return true on success, false if there was an error + */ +jboolean JNICALL ScriptMethodsCombatNamespace::setWeaponMaxDamage(JNIEnv *env, jobject self, jlong weaponId, jint damage) +{ + UNREF(self); + + WeaponObject *weapon = 0; + if (!JavaLibrary::getObject(weaponId, weapon)) + return JNI_FALSE; + + if (damage < 0) + return JNI_FALSE; + + weapon->setMaxDamage(damage); + return JNI_TRUE; +} // JavaLibrary::setWeaponMaxDamage + +/** + * Gets the attack speed of a weapon. + * + * @param env Java environment + * @param self class calling this function + * @param weaponId the id of the weapon + * + * @return the attack speed, or -1 on error + */ +jfloat JNICALL ScriptMethodsCombatNamespace::getWeaponAttackSpeed(JNIEnv *env, jobject self, jlong weaponId) +{ + UNREF(self); + + const WeaponObject *weapon = NULL; + if (!JavaLibrary::getObject(weaponId, weapon)) + return -1.0f; + + jfloat speed = weapon->getAttackTime(); + return speed; +} // JavaLibrary::getWeaponAttackSpeed + +/** + * Sets the attack speed of a weapon. + * + * @param env Java environment + * @param self class calling this function + * @param weaponId the id of the weapon + * @param speed the attack speed + * + * @return true on success, false if there was an error + */ +jboolean JNICALL ScriptMethodsCombatNamespace::setWeaponAttackSpeed(JNIEnv *env, jobject self, jlong weaponId, jfloat speed) +{ + UNREF(self); + + WeaponObject *weapon = 0; + if (!JavaLibrary::getObject(weaponId, weapon)) + return JNI_FALSE; + + if (speed < 0) + return JNI_FALSE; + + weapon->setAttackTime(speed); + return JNI_TRUE; +} // JavaLibrary::setWeaponAttackSpeed + +/** + * Gets the % change that a weapon will cause a wound. + * + * @param env Java environment + * @param self class calling this function + * @param weaponId the id of the weapon + * + * @return the wound chance, or -1 on error + */ +jfloat JNICALL ScriptMethodsCombatNamespace::getWeaponWoundChance(JNIEnv *env, jobject self, jlong weaponId) +{ + UNREF(self); + + const WeaponObject *weapon = NULL; + if (!JavaLibrary::getObject(weaponId, weapon)) + return -1.0f; + + jfloat chance = weapon->getWoundChance(); + return chance; +} // JavaLibrary::getWeaponWoundChance + +/** + * Gets the range info of a weapon. + * + * @param env Java environment + * @param self class calling this function + * @param weaponId the id of the weapon + * + * @return the range info, or null on error + */ +jobject JNICALL ScriptMethodsCombatNamespace::getWeaponRangeInfo(JNIEnv *env, jobject self, jlong weaponId) +{ + UNREF(self); + + const WeaponObject *weapon = NULL; + if (!JavaLibrary::getObject(weaponId, weapon)) + return 0; + + LocalRefPtr range = allocObject(JavaLibrary::getClsBaseClassRangeInfo()); + if (range == LocalRef::cms_nullPtr) + return 0; + + setFloatField(*range, JavaLibrary::getFidBaseClassRangeInfoMinRange(), weapon->getMinRange()); + setFloatField(*range, JavaLibrary::getFidBaseClassRangeInfoMaxRange(), weapon->getMaxRange()); + return range->getReturnValue(); +} // JavaLibrary::getWeaponRangeInfo + +/** + * Sets all the range info of a weapon. + * + * @param env Java environment + * @param self class calling this function + * @param weaponId the id of the weapon + * @param info the new range info + * + * @return true on success, false if there was an error + */ +jboolean JNICALL ScriptMethodsCombatNamespace::setWeaponRangeInfo(JNIEnv *env, jobject self, jlong weaponId, jobject info) +{ + UNREF(self); + + if (info == 0) + return JNI_FALSE; + + WeaponObject *weapon = 0; + if (!JavaLibrary::getObject(weaponId, weapon)) + return JNI_FALSE; + + weapon->setMinRange(env->GetFloatField(info, JavaLibrary::getFidBaseClassRangeInfoMinRange())); + weapon->setMaxRange(env->GetFloatField(info, JavaLibrary::getFidBaseClassRangeInfoMaxRange())); + + return JNI_TRUE; +} // JavaLibrary::setWeaponRangeInfo + +/** + * Sets the % change that a weapon will cause a wound. + * + * @param env Java environment + * @param self class calling this function + * @param weaponId the id of the weapon + * @param chance the wound % chance + * + * @return true on success, false if there was an error + */ +jboolean JNICALL ScriptMethodsCombatNamespace::setWeaponWoundChance(JNIEnv *env, jobject self, jlong weaponId, jfloat chance) +{ + UNREF(self); + + WeaponObject *weapon = 0; + if (!JavaLibrary::getObject(weaponId, weapon)) + return JNI_FALSE; + + if (chance < 0) + return JNI_FALSE; + + weapon->setWoundChance(chance); + return JNI_TRUE; +} // JavaLibrary::setWeaponWoundChance + +/** + * Gets the damage radius for area-effect weapons. + * + * @param env Java environment + * @param self class calling this function + * @param weaponId the id of the weapon + * + * @return the damage radius, or -1 on error + */ +jfloat JNICALL ScriptMethodsCombatNamespace::getWeaponDamageRadius(JNIEnv *env, jobject self, jlong weaponId) +{ + UNREF(self); + + const WeaponObject *weapon = NULL; + if (!JavaLibrary::getObject(weaponId, weapon)) + return -1.0f; + + jfloat radius = weapon->getDamageRadius(); + return radius; +} // JavaLibrary::getWeaponDamageRadius + +/** + * Sets the damage radius for area-effect weapons. + * + * @param env Java environment + * @param self class calling this function + * @param weaponId the id of the weapon + * @param radius the damage radius + * + * @return true on success, false if there was an error + */ +jboolean JNICALL ScriptMethodsCombatNamespace::setWeaponDamageRadius(JNIEnv *env, jobject self, jlong weaponId, jfloat radius) +{ + UNREF(self); + + WeaponObject *weapon = 0; + if (!JavaLibrary::getObject(weaponId, weapon)) + return JNI_FALSE; + + if (radius < 0) + return JNI_FALSE; + + weapon->setDamageRadius(radius); + return JNI_TRUE; +} // JavaLibrary::setWeaponDamageRadius + +/** + * + */ +jfloat JNICALL ScriptMethodsCombatNamespace::getAudibleRange(JNIEnv *env, jobject self, jlong weaponId) +{ + const WeaponObject *weapon = NULL; + if (!JavaLibrary::getObject(weaponId, weapon)) + return -1; + + jfloat range = weapon->getAudibleRange(); + + return range; +} + +/** + * Gets the attack cost for a weapon. + * + * @param env Java environment + * @param self class calling this function + * @param weaponId the id of the weapon + * + * @return the attack costs, or 0 on error + */ +jint JNICALL ScriptMethodsCombatNamespace::getWeaponAttackCost(JNIEnv *env, jobject self, jlong weaponId) +{ + UNREF(self); + + const WeaponObject *weapon = NULL; + if (!JavaLibrary::getObject(weaponId, weapon)) + return 0; + + jint cost = weapon->getAttackCost(); + return cost; + +} // JavaLibrary::getWeaponAttackCost + +/** + * Sets the attack cost for a weapon. + * + * @param env Java environment + * @param self class calling this function + * @param weaponId the id of the weapon + * @param cost attack cost for the weapon + * + * @return true on success, false if there was an error + */ +jboolean JNICALL ScriptMethodsCombatNamespace::setWeaponAttackCost(JNIEnv *env, jobject self, jlong weaponId, jint cost) +{ + UNREF(self); + + WeaponObject *weapon = 0; + if (!JavaLibrary::getObject(weaponId, weapon)) + return JNI_FALSE; + + weapon->setAttackCost(cost); + + return JNI_TRUE; +} // JavaLibrary::setWeaponAttackCost + +/** + * Gets the accuracy for a weapon. + * + * @param env Java environment + * @param self class calling this function + * @param weaponId the id of the weapon + * + * @return the accuracy, or 0 on error + */ +jint JNICALL ScriptMethodsCombatNamespace::getWeaponAccuracy(JNIEnv *env, jobject self, jlong weaponId) +{ + UNREF(self); + + const WeaponObject *weapon = NULL; + if (!JavaLibrary::getObject(weaponId, weapon)) + return 0; + + jint accuracy = weapon->getAccuracy(); + return accuracy; + +} // JavaLibrary::getWeaponAccuracy + +/** + * Sets the accuracy for a weapon. + * + * @param env Java environment + * @param self class calling this function + * @param weaponId the id of the weapon + * @param accuracy accuracy for the weapon + * + * @return true on success, false if there was an error + */ +jboolean JNICALL ScriptMethodsCombatNamespace::setWeaponAccuracy(JNIEnv *env, jobject self, jlong weaponId, jint accuracy) +{ + UNREF(self); + + WeaponObject *weapon = 0; + if (!JavaLibrary::getObject(weaponId, weapon)) + return JNI_FALSE; + + weapon->setAccuracy(accuracy); + + return JNI_TRUE; +} // JavaLibrary::setWeaponAccuracy + +/** + * Gets the elemantal damage type of a weapon. + * + * @param env Java environment + * @param self class calling this function + * @param weaponId the id of the weapon + * + * @return the elemantal damage type, or 0 on error + */ +jint JNICALL ScriptMethodsCombatNamespace::getWeaponElementalType(JNIEnv *env, jobject self, jlong weaponId) +{ + UNREF(self); + + const WeaponObject *weapon = NULL; + if (!JavaLibrary::getObject(weaponId, weapon)) + return 0; + + jint eleType = weapon->getElementalType(); + return eleType; + +} // JavaLibrary::getWeaponElementalType + +/** + * Sets the elemental damage type for a weapon. + * + * @param env Java environment + * @param self class calling this function + * @param weaponId the id of the weapon + * @param cost elemental damage type for the weapon + * + * @return true on success, false if there was an error + */ +jboolean JNICALL ScriptMethodsCombatNamespace::setWeaponElementalType(JNIEnv *env, jobject self, jlong weaponId, jint type) +{ + UNREF(self); + + WeaponObject *weapon = 0; + if (!JavaLibrary::getObject(weaponId, weapon)) + return JNI_FALSE; + + weapon->setElementalType(type); + + return JNI_TRUE; +} // JavaLibrary::setWeaponElementalType + +/** + * Gets the elemantal damage value of a weapon. + * + * @param env Java environment + * @param self class calling this function + * @param weaponId the id of the weapon + * + * @return the elemantal damage value, or 0 on error + */ +jint JNICALL ScriptMethodsCombatNamespace::getWeaponElementalValue(JNIEnv *env, jobject self, jlong weaponId) +{ + UNREF(self); + + const WeaponObject *weapon = NULL; + if (!JavaLibrary::getObject(weaponId, weapon)) + return 0; + + jint value = weapon->getElementalValue(); + return value; + +} // JavaLibrary::getWeaponElementalValue + +/** + * Sets the elemental damage value for a weapon. + * + * @param env Java environment + * @param self class calling this function + * @param weaponId the id of the weapon + * @param cost elemental damage value for the weapon + * + * @return true on success, false if there was an error + */ +jboolean JNICALL ScriptMethodsCombatNamespace::setWeaponElementalValue(JNIEnv *env, jobject self, jlong weaponId, jint value) +{ + UNREF(self); + + WeaponObject *weapon = 0; + if (!JavaLibrary::getObject(weaponId, weapon)) + return JNI_FALSE; + + weapon->setElementalValue(value); + + return JNI_TRUE; +} // JavaLibrary::setWeaponElementalValue + + +//======================================================================== +// class JavaLibrary JNI combat callback methods +//======================================================================== + +/** + * Returns if the combat engine is enabled. + * + * @param env Java environment + * @param self class calling this function + * + * @return JNI_TRUE if combat is enabled, JNI_FALSE if not + */ +jboolean JNICALL ScriptMethodsCombatNamespace::isCombatEnabled(JNIEnv *env, jobject self) +{ + UNREF(env); + UNREF(self); + + if (ConfigServerGame::getDisableCombat()) + return JNI_FALSE; + return JNI_TRUE; +} // JavaLibrary::isCombatEnabled + + +/** + * Applies damage to an object. + * + * @param env Java environment + * @param self class calling this function + * @param targetId id of the object to damage + * @param type damage type being done + * @param location the hit location of the damage + * @param amount amount of damage to do + * + * @return the true on success, false on error + */ +jboolean JNICALL ScriptMethodsCombatNamespace::directDamage(JNIEnv *env, jobject self, jlong targetId, jint type, jint location, jint amount) +{ + UNREF(self); + + TangibleObject *target = 0; + if (!JavaLibrary::getObject(targetId, target)) + return JNI_FALSE; + + // make sure the parameters are valid + if (type < ServerObjectTemplate::DT_kinetic || + type > ServerObjectTemplate::DamageType_Last) + { + return JNI_FALSE; + } + + ServerWeaponObjectTemplate::DamageType damageType = static_cast(type); + CombatEngine::damage(*target, damageType, static_cast(location), amount); + return JNI_TRUE; +} // JavaLibrary::directDamage + +/** + * Applies weapon-based damage to an object. + * + * @param env Java environment + * @param self class calling this function + * @param targetId id of the object to damage + * @param weaponId id of the weapon doing the damage + * @param amount amount of damage to do + * @param location where to do the damage + * + * @return the true on success, false on error + */ +jboolean JNICALL ScriptMethodsCombatNamespace::directWeaponDamage(JNIEnv *env, jobject self, jlong targetId, jlong weaponId, jint amount, jint location) +{ + UNREF(self); + + TangibleObject *target = 0; + if (!JavaLibrary::getObject(targetId, target)) + return JNI_FALSE; + + WeaponObject * weapon = 0; + if (!JavaLibrary::getObject(weaponId, weapon)) + return JNI_FALSE; + + CombatEngine::damage(*target, *weapon, amount, location); + return JNI_TRUE; +} // JavaLibrary::directWeaponDamage + +/** + * Applies damage to all objects in a given area. + * + * @param env Java environment + * @param self class calling this function + * @param targetId id of the object to use as the center of the damage area + * @param radius radius of the damage area + * @param type damage type being done + * @param amount amount of damage to do + * + * @return the true on success, false on error + */ +jboolean JNICALL ScriptMethodsCombatNamespace::directAreaDamageObject(JNIEnv *env, jobject self, jlong targetId, jfloat radius, jint type, jint amount) +{ + UNREF(self); + + TangibleObject *target = 0; + if (!JavaLibrary::getObject(targetId, target)) + return JNI_FALSE; + + // make sure the damage type and subtype are valid + if (type < ServerObjectTemplate::DT_kinetic || + type > ServerObjectTemplate::DamageType_Last) + { + return JNI_FALSE; + } + + ServerWeaponObjectTemplate::DamageType damageType = static_cast< + ServerWeaponObjectTemplate::DamageType>(type); + CombatEngine::damage(target->getPosition_w(), radius, damageType, amount); + + return JNI_TRUE; +} // JavaLibrary::directAreaDamageObject + +/** + * Applies damage to all objects in a given area. + * + * @param env Java environment + * @param self class calling this function + * @param center the center of the damage area + * @param radius radius of the damage area + * @param type damage type being done + * @param amount amount of damage to do + * + * @return the true on success, false on error + */ +jboolean JNICALL ScriptMethodsCombatNamespace::directAreaDamageLocation(JNIEnv *env, jobject self, + jobject center, jfloat radius, jint type, jint amount) +{ + UNREF(self); + + if (center == 0) + return JNI_FALSE; + + // @todo: can center.area be a different planet that the one this gameserver + // handles? + + Vector centerPos; + if (!ScriptConversion::convertWorld(center, centerPos)) + return JNI_FALSE; + + // make sure the damage type and subtype are valid + if (type < ServerObjectTemplate::DT_kinetic || + type > ServerObjectTemplate::DamageType_Last) + { + return JNI_FALSE; + } + + ServerWeaponObjectTemplate::DamageType damageType = static_cast< + ServerWeaponObjectTemplate::DamageType>(type); + CombatEngine::damage(centerPos, radius, damageType, amount); + + return JNI_TRUE; +} // JavaLibrary::directAreaDamageLocation + +void _startCombat(char const * const functionName, jlong attacker, jlong defender, bool const assist) +{ + NetworkId const attackerId(attacker); + TangibleObject * const attackerTangibleObject = TangibleObject::getTangibleObject(attackerId); + + if (attackerTangibleObject == NULL) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsCombat::%s() Unable to resolve the attacker(%s) to a TangibleObject.", functionName, attackerId.getValueString().c_str())); + return; + } + + NetworkId const defenderId(defender); + TangibleObject * const defenderTangibleObject = TangibleObject::getTangibleObject(defenderId); + + if (defenderTangibleObject == NULL) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsCombat::%s() attacker(%s) Unable to resolve the defender(%s) to a TangibleObject.", functionName, attackerId.getValueString().c_str(), defenderId.getValueString().c_str())); + return; + } + + if (attackerId == defenderId) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsCombat::%s() The attacker(%s) is trying to start combat with himself.", functionName, attackerTangibleObject->getDebugInformation().c_str())); + return; + } + + // Do not reset the attacker's hate list timer if the defender is already in the hate list + + if (!attackerTangibleObject->isOnHateList(defenderId)) + { + float const hate = assist ? 1.0f : 0.0f; + attackerTangibleObject->addHate(defenderId, hate); + } + + // If the defender is a player, immediatelly let them know they are being attacked. This check is only for players + // because sending an AI on an AI (pets) instantly causes both parties to enter combat. That behavior is not + // desired because a pet could pull a AI from any distance without the pet having to attack the AI or get within + // the AI's aggro range. + + if ( defenderTangibleObject->isPlayerControlled() + && !defenderTangibleObject->isOnHateList(attackerId)) + { + float const hate = assist ? 1.0f : 0.0f; + defenderTangibleObject->addHate(attackerId, hate); + } +} + +/** + * Puts the attacker in combat towards the defender + * + * @param env Java environment + * @param self class calling this function + * @param attacker the object you want to start combat + * @param defender the object you want the attacker to be in combat towards + * + */ +void JNICALL ScriptMethodsCombatNamespace::startCombat(JNIEnv * /*env*/, jobject /*self*/, jlong attacker, jlong defender) +{ + _startCombat("startCombat", attacker, defender, false); +} + +/** + * Puts the attacker in combat towards the defender while notifying the nearby attacker's + * friends of the defender. + * + * @param env Java environment + * @param self class calling this function + * @param attacker the object you want to start combat + * @param target the object you want the attacker to be in combat towards + * + */ +void JNICALL ScriptMethodsCombatNamespace::startCombatWithAssist(JNIEnv * /*env*/, jobject /*self*/, jlong attacker, jlong defender) +{ + _startCombat("startCombatWithAssist", attacker, defender, true); +} + +/** + * Removes the object from combat + * + * @param env Java environment + * @param self class calling this function + * @param object the object you want to stop combat + * + */ +void JNICALL ScriptMethodsCombatNamespace::stopCombat(JNIEnv * /*env*/, jobject /*self*/, jlong object) +{ + NetworkId const objectId(object); + TangibleObject * const tangibleObject = TangibleObject::getTangibleObject(objectId); + + if (tangibleObject == NULL) + { + return; + } + + tangibleObject->clearHateList(); +} + +// ------------------------------------------------------------------------------------ + +/** + * Gets data needed for combat for given attackers and defenders. + * + * @param env Java environment + * @param self class calling this function + * @param attackers ids of the attackers we want data for + * @param defenders ids of the defenders we want data for + * @param attackerData data for each attacker + * @param defenderData data for each defender + * @param weaponData data for each attackers' weapon + * + * @return JNI_TRUE on success, JNI_FALSE on error + */ +jboolean JNICALL ScriptMethodsCombatNamespace::getCombatData(JNIEnv *env, jobject self, jlongArray attackers, jlongArray defenders, jobjectArray attackersData, jobjectArray defendersData, jobjectArray weaponsData) +{ +int i; + + UNREF(self); + + int attackerCount = 0; + int defenderCount = 0; + + if (attackers != NULL) + attackerCount = env->GetArrayLength(attackers); + if (defenders != NULL) + defenderCount = env->GetArrayLength(defenders); + + // get the attacker and weapon data + for (i = 0; i < attackerCount; ++i) + { + jlong attackerId; + env->GetLongArrayRegion(attackers, i, 1, &attackerId); + LocalRefPtr attackerData = getObjectArrayElement(LocalObjectArrayRefParam(attackersData), i); + LocalRefPtr weaponData = getObjectArrayElement(LocalObjectArrayRefParam(weaponsData), i); + if (!attackerId) + { + WARNING(true, ("JavaLibrary::getCombatData got null attacker id")); + return JNI_FALSE; + } + if (attackerData == LocalRef::cms_nullPtr) + { + WARNING(true, ("JavaLibrary::getCombatData got null attacker data")); + return JNI_FALSE; + } + if (weaponData == LocalRef::cms_nullPtr) + { + WARNING(true, ("JavaLibrary::getCombatData got null weapon data")); + return JNI_FALSE; + } + + // set up the attacker data + const TangibleObject * attacker = NULL; + if (!JavaLibrary::getObject(attackerId, attacker)) + { + WARNING(true, ("JavaLibrary::getCombatData cannot get attacker object")); + return JNI_FALSE; + } + + // get the attacker's position in local and world coordinates + LocalRefPtr location; + LocalRefPtr worldLocation; + const Object * attackerCell = ContainerInterface::getContainedByObject(*attacker); + ScriptConversion::convert(attacker->getPosition_p(), attacker->getSceneId(), + attackerCell ? attackerCell->getNetworkId() : NetworkId::cms_invalid, + location); + if (location.get() == NULL || location == LocalRef::cms_nullPtr) + { + WARNING(true, ("JavaLibrary::getCombatData cannot convert local position " + "of attacker %s to Java", attacker->getNetworkId().getValueString().c_str())); + return JNI_FALSE; + } + if (attacker->isInWorldCell()) + worldLocation = location; + else + { + ScriptConversion::convert(attacker->getPosition_w(), attacker->getSceneId(), + CellProperty::getWorldCellProperty()->getOwner().getNetworkId(), + worldLocation); + if (worldLocation.get() == NULL || worldLocation == LocalRef::cms_nullPtr) + { + WARNING(true, ("JavaLibrary::getCombatData cannot convert world position " + "of attacker %s to Java", attacker->getNetworkId().getValueString().c_str())); + return JNI_FALSE; + } + } + + const WeaponObject * weapon = NULL; + bool isCreature = false; + int posture = 0; + int locomotion = 0; + int weaponSkill = 0; + int aims = 0; + const CreatureObject * creature = dynamic_cast(attacker); + if (creature != NULL) + { + isCreature = true; + posture = creature->getPosture(); + locomotion = creature->getLocomotion(); + weapon = (const_cast(creature))->getCurrentWeapon(); + } + else + { + weapon = dynamic_cast(attacker); + } + + CombatEngineData::CombatData const * combatData = attacker->getCombatData(); + + if (combatData != NULL) + { + aims = combatData->attackData.aims; + } + + setObjectField(*attackerData, JavaLibrary::getFidCombatEngineCombatantDataPos(), *location); + setObjectField(*attackerData, JavaLibrary::getFidCombatEngineCombatantDataWorldPos(), *worldLocation); + setFloatField(*attackerData, JavaLibrary::getFidCombatEngineCombatantDataRadius(), attacker->getRadius()); + setBooleanField(*attackerData, JavaLibrary::getFidCombatEngineCombatantDataIsCreature(), isCreature); + setIntField(*attackerData, JavaLibrary::getFidCombatEngineCombatantDataPosture(), posture); + setIntField(*attackerData, JavaLibrary::getFidCombatEngineCombatantDataLocomotion(), locomotion); + setIntField(*attackerData, JavaLibrary::getFidCombatEngineCombatantDataScriptMod(), 0); + setIntField(*attackerData, JavaLibrary::getFidCombatEngineAttackerDataWeaponSkill(), weaponSkill); + setIntField(*attackerData, JavaLibrary::getFidCombatEngineAttackerDataAims(), aims); + + // set up the weapon data + JavaLibrary::setupWeaponCombatData(env, weapon, weaponData->getValue()); + } + + // get the defender data + for (i = 0; i < defenderCount; ++i) + { + jlong defenderId; + env->GetLongArrayRegion(defenders, i, 1, &defenderId); + LocalRefPtr defenderData = getObjectArrayElement(LocalObjectArrayRefParam(defendersData), i); + if (!defenderId) + { + WARNING(true, ("JavaLibrary::getCombatData got null defender id")); + return JNI_FALSE; + } + if (defenderData == LocalRef::cms_nullPtr) + { + WARNING(true, ("JavaLibrary::getCombatData got null defender data")); + return JNI_FALSE; + } + + // set up the defender data + const TangibleObject * defender = NULL; + if (!JavaLibrary::getObject(defenderId, defender)) + { + WARNING(true, ("JavaLibrary::getCombatData cannot get defender object")); + return JNI_FALSE; + } + + // get the defender's position in local and world coordinates + LocalRefPtr location; + LocalRefPtr worldLocation; + const Object * defenderCell = ContainerInterface::getContainedByObject(*defender); + ScriptConversion::convert(defender->getPosition_p(), defender->getSceneId(), + defenderCell ? defenderCell->getNetworkId() : NetworkId::cms_invalid, + location); + if (location.get() == NULL || location == LocalRef::cms_nullPtr) + { + WARNING(true, ("JavaLibrary::getCombatData cannot convert local position " + "of defender %s to Java", defender->getNetworkId().getValueString().c_str())); + return JNI_FALSE; + } + if (defender->isInWorldCell()) + worldLocation = location; + else + { + ScriptConversion::convert(defender->getPosition_w(), defender->getSceneId(), + CellProperty::getWorldCellProperty()->getOwner().getNetworkId(), + worldLocation); + if (worldLocation.get() == NULL || worldLocation == LocalRef::cms_nullPtr) + { + WARNING(true, ("JavaLibrary::getCombatData cannot convert world position " + "of defender %s to Java", defender->getNetworkId().getValueString().c_str())); + return JNI_FALSE; + } + } + + bool isCreature = false; + int posture = 0; + int locomotion = 0; + int combatSkeleton = defender->getCombatSkeleton(); + int cover = 0; + const CreatureObject * creature = dynamic_cast(defender); + if (creature != NULL) + { + isCreature = true; + posture = creature->getPosture(); + locomotion = creature->getLocomotion(); + cover = creature->getCover(); + } + + // set the defender's hit location chances + const ConfigCombatEngine::SkeletonAttackMod & attackMods = ConfigCombatEngine::getSkeletonAttackMod(static_cast(defender->getCombatSkeleton())); + int numBones = attackMods.numHitLocations; + if (numBones == 0) + { + WARNING_STRICT_FATAL(true, ("JavaLibrary::getCombatData, defender " + "combat skeleton %d returned 0 bones!", combatSkeleton)); + return JNI_FALSE; + } + LocalIntArrayRefPtr chances = createNewIntArray(numBones); + if (chances == LocalIntArrayRef::cms_nullPtr) + return JNI_FALSE; + std::vector hitChances; + for (int j = 0; j < numBones; ++j) + hitChances.push_back(attackMods.attackMods[j].toHitChance); + setIntArrayRegion(*chances, 0, numBones, &hitChances[0]); + setObjectField(*defenderData, JavaLibrary::getFidCombatEngineDefenderDataHitLocationChances(), *chances); + + // set the rest of the defender data + setObjectField(*defenderData, JavaLibrary::getFidCombatEngineCombatantDataPos(), *location); + setObjectField(*defenderData, JavaLibrary::getFidCombatEngineCombatantDataWorldPos(), *worldLocation); + setFloatField(*defenderData, JavaLibrary::getFidCombatEngineCombatantDataRadius(), defender->getRadius()); + setBooleanField(*defenderData, JavaLibrary::getFidCombatEngineCombatantDataIsCreature(), isCreature); + setIntField(*defenderData, JavaLibrary::getFidCombatEngineCombatantDataPosture(), posture); + setIntField(*defenderData, JavaLibrary::getFidCombatEngineCombatantDataLocomotion(), locomotion); + setIntField(*defenderData, JavaLibrary::getFidCombatEngineCombatantDataScriptMod(), 0); + setIntField(*defenderData, JavaLibrary::getFidCombatEngineDefenderDataCombatSkeleton(), combatSkeleton); + setIntField(*defenderData, JavaLibrary::getFidCombatEngineDefenderDataCover(), cover); + } + + return JNI_TRUE; +} // JavaLibrary::getCombatData + +// ------------------------------------------------------------------------------------ + +/** + * Gets data needed for combat for a given weapon. + * + * @param env Java environment + * @param self class calling this function + * @param weapon the weapon to get data for + * @param weaponData data for the weapon + * + * @return JNI_TRUE on success, JNI_FALSE on error + */ +jboolean JNICALL ScriptMethodsCombatNamespace::getWeaponData(JNIEnv *env, jobject self, jlong weapon, jobject weaponData) +{ + UNREF(self); + + if (weapon == 0 || weaponData == 0) + return JNI_FALSE; + + const WeaponObject * localWeapon = NULL; + if (!JavaLibrary::getObject(weapon, localWeapon)) + return JNI_FALSE; + + JavaLibrary::setupWeaponCombatData(env, localWeapon, weaponData); + return JNI_TRUE; +} // JavaLibrary::getWeaponData + +// ------------------------------------------------------------------------------------ + +/** + * Applies damage to an object being attacked. + * + * @param env Java environment + * @param self class calling this function + * @param attackerId the attacker + * @param defenderId the defender + * @param weaponId the attacker's weapon + * @param damage amount of damage done + * @param hitLocation where the defender was hit + * + * @return JNI_TRUE on success, JNI_FALSE on error + */ +jboolean JNICALL ScriptMethodsCombatNamespace::doDamage(JNIEnv *env, jobject self, jlong attackerId, jlong defenderId, jlong weaponId, jint damage, jint hitLocation) +{ + UNREF(self); + + if (damage <= 0) + return JNI_TRUE; + + TangibleObject * attacker = NULL; + if (!JavaLibrary::getObject(attackerId, attacker)) + return JNI_FALSE; + + TangibleObject * defender = NULL; + if (!JavaLibrary::getObject(defenderId, defender)) + return JNI_FALSE; + + WeaponObject * weapon = NULL; + if (!JavaLibrary::getObject(weaponId, weapon)) + return JNI_FALSE; + + bool result = CombatEngine::onSuccessfulAttack(*attacker, *defender, *weapon, + damage, hitLocation); + if (result) + return JNI_TRUE; + return JNI_FALSE; +} // JavaLibrary::doDamage + +// ------------------------------------------------------------------------------------ + +/** + * Applies damage to an object being attacked. + * + * @param env Java environment + * @param self class calling this function + * @param attackerId the attacker + * @param defenderId the defender + * @param damage amount of damage done + * @param hitLocation where the defender was hit + * + * @return JNI_TRUE on success, JNI_FALSE on error + */ +jboolean JNICALL ScriptMethodsCombatNamespace::doDamageNoWeapon(JNIEnv *env, jobject self, jlong attackerId, jlong defenderId, jint damage, jint hitLocation) +{ + UNREF(self); + + if (damage <= 0) + return JNI_TRUE; + + TangibleObject * attacker = NULL; + if (!JavaLibrary::getObject(attackerId, attacker)) + return JNI_FALSE; + + TangibleObject * defender = NULL; + if (!JavaLibrary::getObject(defenderId, defender)) + return JNI_FALSE; + + bool result = CombatEngine::onSuccessfulAttack(*attacker, *defender, damage, hitLocation); + if (result) + return JNI_TRUE; + return JNI_FALSE; +} // JavaLibrary::doDamage + +// ------------------------------------------------------------------------------------ + +/** + * Creates a package to be sent to the client for displaying combat results. + * + * @param env Java environment + * @param self class calling this function + * @param animationId name of animation script to play + * @param attackerResult info about the attacker + * @param defenderResult info about the defender(s) + * + * @return JNI_TRUE on success, JNI_FALSE on error + */ +jboolean JNICALL ScriptMethodsCombatNamespace::doCombatResults(JNIEnv *env, jobject self, + jstring animationId, jobject attackerResult, jobjectArray defenderResult) +{ + UNREF(self); + + if (animationId == 0 || attackerResult == 0) + return JNI_FALSE; + + JavaStringParam animationIdString(animationId); + std::string animationString; + if (!JavaLibrary::convert(animationIdString, animationString)) + return JNI_FALSE; + + unsigned int replaceWildcardIndex = animationString.find('^'); + + if( replaceWildcardIndex != std::string::npos) + { + std::string newString = animationString.substr(0, replaceWildcardIndex); + + newString += s_wildcardReplacements[Random::random(0, totalWildcards-1)]; + + animationString = newString; + } + + if (!ClientCombatManagerSupport::doesCombatActionNameExist(TemporaryCrcString(animationString.c_str(), true))) + { + WARNING(true, ("doCombatResults(): caller passed in unsupported combat action name [%s]! Continuing to send combat action. Call stack follows in stdout.", animationString.c_str())); + // @todo make this go to the log rather than stdout; otherwise, we're going to have to do a lot more work to see this info. + JavaLibrary::printJavaStack(); + } + + // create a CombatAction message and fill it in + MessageQueueCombatAction * message = new MessageQueueCombatAction(); + if (message == NULL) + return JNI_FALSE; + message->setActionId(animationString); + // @todo: change set postures to set locomotions + + // set attacker data + LocalRefPtr attackerId = getObjectField(LocalRefParam(attackerResult), JavaLibrary::getFidBaseClassAttackerResultsId()); + CachedNetworkId attacker(JavaLibrary::getNetworkId(*attackerId)); + LocalRefPtr weaponId = getObjectField(LocalRefParam(attackerResult), JavaLibrary::getFidBaseClassAttackerResultsWeapon()); + CachedNetworkId weapon(JavaLibrary::getNetworkId(*weaponId)); + if (attacker != CachedNetworkId::cms_invalid && attacker.getObject()) + { + message->setAttacker(attacker, weapon); + CreatureObject * creature = dynamic_cast(attacker.getObject()); + if (creature != NULL) + { + Postures::Enumerator posture = static_cast( + env->GetIntField(attackerResult, JavaLibrary::getFidBaseClassAttackerResultsPosture())); + if (posture >= 0 && posture < Postures::NumberOfPostures) + { + if (!creature->isIncapacitated()) + creature->setPosture(posture); + else + posture = creature->getPosture(); + } + else + { + WARNING(true, ("JavaLibrary::doCombatResults called with an invalid " + "posture %d for attacker %s", posture, attacker.getValueString().c_str())); + } + } + // Set the client trails special effects bitfield. + message->setAttackerTrailBits(env->GetIntField(attackerResult, + JavaLibrary::getFidBaseClassAttackerResultsTrailBits())); + // Set the attacker client effect id. + message->setAttackerClientEffectId(env->GetIntField(attackerResult, + JavaLibrary::getFidBaseClassAttackerResultsClientEffectId())); + + // Set the attacker action name + message->setAttackerActionNameCrc(env->GetIntField(attackerResult, + JavaLibrary::getFidBaseClassAttackerResultsActionName())); + + // Get the attacker useLocation field + bool useLocation = env->GetBooleanField(attackerResult, + JavaLibrary::getFidBaseClassAttackerResultsUseLocation()); + Vector targetLocation; + if(useLocation) + { + LocalRefPtr targetLocationRef = getObjectField(LocalRefParam(attackerResult), JavaLibrary::getFidBaseClassAttackerResultsTargetLocation()); + if (!ScriptConversion::convert((*targetLocationRef).getValue(), targetLocation)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::doCombatResults bad location target")); + LocalRefPtr targetCellRef = getObjectField(LocalRefParam(attackerResult), JavaLibrary::getFidBaseClassAttackerResultsTargetCell()); + CachedNetworkId targetCell(JavaLibrary::getNetworkId(*targetCellRef)); + message->setAttackerTargetLocation(targetLocation, targetCell, useLocation); + } + else + { + message->setAttackerTargetLocation(targetLocation, NetworkId::cms_invalid, useLocation); + } + } + else + { + JavaLibrary::throwInternalScriptError("JavaLibrary::doCombatResult() was passed an invalid attacker (not found on server)"); + WARNING(true, ("JavaLibrary::doCombatResources called with invalid attacker %s",attacker.getValueString().c_str())); + delete message; + return JNI_FALSE; + } + + // set defender(s) data + jsize defenderCount = 0; + if (defenderResult != 0) + defenderCount = env->GetArrayLength(defenderResult); + for (jsize i = 0; i < defenderCount; ++i) + { + LocalRefPtr defenderData = getObjectArrayElement(LocalObjectArrayRefParam(defenderResult), i); + if (defenderData != LocalRef::cms_nullPtr) + { + LocalRefPtr defenderId = getObjectField(*defenderData, JavaLibrary::getFidBaseClassDefenderResultsId()); + CachedNetworkId defender(JavaLibrary::getNetworkId(*defenderId)); + + CombatEngineData::CombatDefense combatResult = + static_cast( + getIntField(*defenderData, + JavaLibrary::getFidBaseClassDefenderResultsResult())); + + if (combatResult >= CombatEngineData::CD_numCombatDefense) + { + WARNING(true, ("doCombatResults(): caller passed in an invalid defender result [%d]! Setting result to COMBAT_RESULT_MISS. Call stack follows in stdout.", combatResult)); + combatResult = CombatEngineData::CD_miss; + // @todo make this go to the log rather than stdout; otherwise, we're going to have to do a lot more work to see this info. + JavaLibrary::printJavaStack(); + } + + const int defenderClientEffectId = getIntField(*defenderData, + JavaLibrary::getFidBaseClassDefenderResultsClientEffectId()); + Postures::Enumerator endPosture = static_cast( + getIntField(*defenderData, JavaLibrary::getFidBaseClassDefenderResultsPosture())); + + const int defenderHitLocation = getIntField(*defenderData, + JavaLibrary::getFidBaseClassDefenderResultsHitLocation()); + + CreatureObject * creature = dynamic_cast( + defender.getObject()); + if (creature) + { + if (endPosture >= 0 && endPosture < Postures::NumberOfPostures) + { + if (!creature->isIncapacitated()) + creature->setPosture(endPosture); + else + endPosture = creature->getPosture(); + } + else + { + WARNING(true, ("JavaLibrary::doCombatResults called with an " + "invalid posture %d for defender %s", endPosture, + defender.getValueString().c_str())); + } + } + + const int defenderDamageAmount = getIntField(*defenderData, + JavaLibrary::getFidBaseClassDefenderDamageAmount()); + + message->addDefender(defender, combatResult, endPosture, + defenderClientEffectId, defenderHitLocation, defenderDamageAmount); + } + } + + // send the message + + Controller *const controller = attacker.getObject()->getController(); + if (controller != NULL) + { + float f_hold_ms = ConfigServerGame::getCombatDamageDelaySeconds() * 1000.0f; + if ( f_hold_ms < 1.0 ) // 0 hold time (allowing for rounding error) + { + controller->appendMessage( + CM_combatAction, + 0.0f, + message, + GameControllerMessageFlags::SEND | + GameControllerMessageFlags::RELIABLE | + GameControllerMessageFlags::DEST_ALL_CLIENT + ); + } + else + { + MessageQueueCombatAction *held = (MessageQueueCombatAction*)controller->peekHeldMessage( CM_combatAction ); + bool b_merge = true; + if ( held == NULL ) + b_merge = false; + else if ( held->getComparisonChecksum() != message->getComparisonChecksum() ) + b_merge = false; + + if ( b_merge == false ) // can't merge, so hold for later sending + { + controller->holdMessage( int(f_hold_ms), CM_combatAction, 0.0f, message, + GameControllerMessageFlags::SEND | + GameControllerMessageFlags::RELIABLE | + GameControllerMessageFlags::DEST_ALL_CLIENT + ); + } + else // do the merge + { + held->mergePacket( message ); + delete( message ); + } + } + } + else + { + delete message; + return JNI_FALSE; + } + + return JNI_TRUE; +} // JavaLibrary::doCombatResults + +// ------------------------------------------------------------------------------------ + +/** + * Triggers OnDefenderCombatAction for a list of defenders. + * + * @param env Java environment + * @param self class calling this function + * @param defenders list of defenders to be triggered + * @param results list of combat results for each defender + * @param attacker the attacker + * @param weapon the attacker's weapon + * + * @return JNI_TRUE on success, JNI_FALSE on error + */ +jboolean JNICALL ScriptMethodsCombatNamespace::callDefenderCombatAction(JNIEnv *env, jobject self, jlongArray defenders, jintArray results, jlong attacker, jlong weapon) +{ + UNREF(self); + + if (defenders == 0 || results == 0 || attacker == 0) + return JNI_FALSE; + + jsize defenderCount = env->GetArrayLength(defenders); + jsize resultCount = env->GetArrayLength(results); + if (defenderCount != resultCount) + return JNI_FALSE; + + // get the attacker info + CachedNetworkId attackerId(attacker); + NetworkId weaponId; + if (weapon != 0) + { + weaponId = NetworkId(weapon); + } + else + { + // use the attacker's current weapon + CreatureObject * creatureAttacker = dynamic_cast(attackerId.getObject()); + if (creatureAttacker != NULL) + { + const WeaponObject * weaponObject = creatureAttacker->getCurrentWeapon(); + if (weaponObject != NULL) + weaponId = weaponObject->getNetworkId(); + } + else + { + const WeaponObject * weaponAttacker = dynamic_cast( + attackerId.getObject()); + if (weaponAttacker != NULL) + weaponId = weaponAttacker->getNetworkId(); + } + } + + // call the trigger for each defender + jint * resultsArray = env->GetIntArrayElements(results, NULL); + if (resultsArray == NULL) + return JNI_FALSE; + + for (jsize i = 0; i < defenderCount; ++i) + { + jlong defender; + env->GetLongArrayRegion(defenders, i, 1, &defender); + if (defender) + { + CachedNetworkId defenderId(defender); + if (defenderId.getObject() != NULL) + { + ServerObject * defenderObject = safe_cast( + defenderId.getObject()); + if (defenderObject->getScriptObject() != NULL) + { + ScriptParams params; + params.addParam(attackerId); + params.addParam(weaponId); + params.addParam(static_cast(resultsArray[i])); + defenderObject->getScriptObject()->trigAllScripts( + Scripting::TRIG_DEFENDER_COMBAT_ACTION, params); + } + } + } + } + + env->ReleaseIntArrayElements(results, resultsArray, JNI_ABORT); + + return JNI_TRUE; +} // JavaLibrary::callDefenderCombatAction + +// ------------------------------------------------------------------------------------ + +/** + * sets whether an object is interested in OnSawAttack triggers + * + * @param env Java environment + * @param self class calling this function + * @param obj the object in question + * @param enable whether OnSawAttack triggers should be enabled for the object + */ +void JNICALL ScriptMethodsCombatNamespace::setWantSawAttackTriggers(JNIEnv *env, jobject self, jlong obj, jboolean enable) +{ + TangibleObject * tangible = NULL; + + if (!JavaLibrary::getObject(obj, tangible)) + { + JavaLibrary::throwInternalScriptError("JavaLibrary::setWantSawAttackTriggers - invalid object"); + } + else + { + tangible->setWantSawAttackTriggers(enable == JNI_TRUE); + LOGC(AiLogManager::isLogging(tangible->getNetworkId()), "debug_ai", ("ScriptMethodsCombat::setWantSawAttackTriggers() object(%s) enable(%s)", tangible->getDebugInformation().c_str(), enable ? "yes" : "no")); + } +} + +// ------------------------------------------------------------------------------------ + +/** + * Creates a "slow down" effect between an attacker and defender. The effect acts as if + * there was a hill between the combatants, with the attacker at the top and the defender + * at the bottom. The area of the effect is a cone between the attacker and defender. + * The "hill" will be maintained between the combatants even if they move. + * + * @param env Java environment + * @param self class calling this function + * @param attacker who is at the top of the hill + * @param defender who is at the bottom of the hill + * @param coneLength the length of the effect cone + * @param coneAngle the angle of the effect cone, in degrees; 0 < angle <= 180 + * @param slopeAngle the effective angle of the slope in degrees; 1 <= slope < 90 + * @param effectTime how long the effect will last, in secs + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsCombatNamespace::addSlowDownEffect(JNIEnv *env, jobject self, jlong attacker, jlong defender, jfloat coneLength, jfloat coneAngle, jfloat slopeAngle, jfloat effectTime) +{ + if (coneLength <= 0) + { + WARNING(true, ("[script bug] JavaLibrary::addSlowDownEffect called " + "with invalid cone length %f", coneLength)); + return JNI_FALSE; + } + if (coneAngle <= 0 || coneAngle > 180) + { + WARNING(true, ("[script bug] JavaLibrary::addSlowDownEffect called " + "with invalid cone angle %f", coneAngle)); + return JNI_FALSE; + } + if (slopeAngle < 1 || slopeAngle >= 90) + { + WARNING(true, ("[script bug] JavaLibrary::addSlowDownEffect called " + "with invalid slope angle %f", slopeAngle)); + return JNI_FALSE; + } + + if (effectTime <= 0) + { + WARNING(true, ("[script bug] JavaLibrary::addSlowDownEffect called " + "with invalid time %f", effectTime)); + return JNI_FALSE; + } + + CreatureObject * attackerObject = NULL; + if (!JavaLibrary::getObject(attacker, attackerObject)) + { + WARNING(true, ("[script bug] JavaLibrary::addSlowDownEffect called " + "with invalid attacker")); + return JNI_FALSE; + } + + const TangibleObject * defenderObject = NULL; + if (!JavaLibrary::getObject(defender, defenderObject)) + { + WARNING(true, ("[script bug] JavaLibrary::addSlowDownEffect called " + "with invalid defender")); + return JNI_FALSE; + } + + unsigned long expireTime = static_cast(effectTime) + ServerClock::getInstance().getGameTimeSeconds(); + attackerObject->addSlowDownEffect(*defenderObject, coneLength, + convertDegreesToRadians(coneAngle), convertDegreesToRadians(slopeAngle), + expireTime); + return JNI_TRUE; +} // JavaLibrary::addSlowDownEffect + +// ------------------------------------------------------------------------------------ + +/** + * Causes a slow down effect being used by an attacker to be canceled early. + * + * @param env Java environment + * @param self class calling this function + * @param attacker the attacker who is using the effect + * + * @return true on success, false on error (bad attacker) + */ +jboolean JNICALL ScriptMethodsCombatNamespace::removeSlowDownEffect(JNIEnv *env, jobject self, jlong attacker) +{ + CreatureObject * attackerObject = NULL; + if (!JavaLibrary::getObject(attacker, attackerObject)) + { + WARNING(true, ("[script bug] JavaLibrary::removeSlowDownEffect called " + "with invalid attacker")); + return JNI_FALSE; + } + + attackerObject->removeSlowDownEffect(); + return JNI_TRUE; +} // JavaLibrary::removeSlowDownEffect + +// ------------------------------------------------------------------------------------ + +/** + * Sends standard combat spam info to players. + * + * @param env Java environment + * @param self class calling this function + * @param attacker who the attacker was + * @param defender who the defender was + * @param weapon what weapon was used + * @param result structure with the numerical data for the attack + * @param attackName the name of the attack + * @param sendToAttacker flag to send the spam to the attacker + * @param sendToDefender flag to send the spam to the defender + * @param sendToBystanders flag to send the spam to other players near the combat + * @param spamType flag that sets what color the spam will be show as + */ +void JNICALL ScriptMethodsCombatNamespace::sendCombatSpam(JNIEnv *env, jobject self, jlong attacker, jlong defender, jlong weapon, jobject result, jobject attackName, jboolean sendToAttacker, jboolean sendToDefender, jboolean sendToBystanders, jint spamType) +{ + NetworkId attackerId(attacker); + ServerObject * attackerObj = safe_cast(NetworkIdManager::getObjectById(attackerId)); + if (attackerObj == NULL) + { + WARNING(true, ("WARNING: JavaLibrary::sendCombatSpam could not find attacker for id %s", attackerId.getValueString().c_str())); + return; + } + + NetworkId defenderId(defender); + Object const * const defenderObj = (defenderId.isValid() ? NetworkIdManager::getObjectById(defenderId) : NULL); + + NetworkId weaponId(weapon); + StringId attackNameSid; + if (!ScriptConversion::convert(attackName, attackNameSid)) + return; + + int rawDamage = 0; + int damageType = 0; + int elementalDamage = 0; + int elementalDamageType = 0; + int bleedDamage = 0; + int critDamage = 0; + int blockedDamage = 0; + int finalDamage = 0; + int hitLocation = 0; + jboolean success = false; + jboolean critical = false; + jboolean glancing = false; + jboolean crushing = false; + jboolean strikethrough = false; + float strikethroughAmmount = 0.0f; + jboolean evadeResult = false; + float evadeAmmount = 0.0f; + jboolean blockResult = false; + int block = 0; + jboolean dodge = false; + jboolean parry = false; + jboolean proc = false; + NetworkId armorId; + + if (result != 0) + { + LocalRefParam jresult(result); + success = getBooleanField(jresult, JavaLibrary::getFidCombatEngineHitResultSuccess()); + critical = getBooleanField(jresult, JavaLibrary::getFidCombatEngineHitResultCritical()); + glancing = getBooleanField(jresult, JavaLibrary::getFidCombatEngineHitResultGlancing()); + proc = getBooleanField(jresult, JavaLibrary::getFidCombatEngineHitResultProc()); + + if (success) + { + LocalRefPtr armor = getObjectField(jresult, JavaLibrary::getFidCombatEngineHitResultBlockingArmor()); + armorId = JavaLibrary::getNetworkId(*armor); + + rawDamage = getIntField(jresult, JavaLibrary::getFidCombatEngineHitResultRawDamage()); + damageType = getIntField(jresult, JavaLibrary::getFidCombatEngineHitResultDamageType()); + elementalDamage = getIntField(jresult, JavaLibrary::getFidCombatEngineHitResultElementalDamage()); + elementalDamageType = getIntField(jresult, JavaLibrary::getFidCombatEngineHitResultElementalDamageType()); + bleedDamage = getIntField(jresult, JavaLibrary::getFidCombatEngineHitResultBleedDamage()); + critDamage = getIntField(jresult, JavaLibrary::getFidCombatEngineHitResultCritDamage()); + blockedDamage = getIntField(jresult, JavaLibrary::getFidCombatEngineHitResultBlockedDamage()); + finalDamage = getIntField(jresult, JavaLibrary::getFidCombatEngineHitResultDamage()); + hitLocation = getIntField(jresult, JavaLibrary::getFidCombatEngineHitResultHitLocation()); + crushing = getBooleanField(jresult, JavaLibrary::getFidCombatEngineHitResultCrushing()); + strikethrough = getBooleanField(jresult, JavaLibrary::getFidCombatEngineHitResultStrikethrough()); + strikethroughAmmount = getFloatField(jresult, JavaLibrary::getFidCombatEngineHitResultStrikethroughAmount()); + evadeResult = getBooleanField(jresult, JavaLibrary::getFidCombatEngineHitResultEvadeResult()); + evadeAmmount = getFloatField(jresult, JavaLibrary::getFidCombatEngineHitResultEvadeAmount()); + blockResult = getBooleanField(jresult, JavaLibrary::getFidCombatEngineHitResultBlockResult()); + block = getIntField(jresult, JavaLibrary::getFidCombatEngineHitResultBlock()); + } + else + { + dodge = getBooleanField(jresult, JavaLibrary::getFidCombatEngineHitResultDodge()); + parry = getBooleanField(jresult, JavaLibrary::getFidCombatEngineHitResultParry()); + } + } + + MessageQueueCombatSpam spam(attackerId, attackerObj->getPosition_w(), defenderId, (defenderObj ? defenderObj->getPosition_w() : Vector::zero), weaponId, armorId, attackNameSid, rawDamage, damageType, elementalDamage, elementalDamageType, bleedDamage, critDamage, blockedDamage, finalDamage, hitLocation, success, critical, glancing, crushing, strikethrough, strikethroughAmmount, evadeResult, evadeAmmount, blockResult, block, dodge, parry, proc, spamType); + attackerObj->performCombatSpam(spam, sendToAttacker, sendToDefender, sendToBystanders); +} // JavaLibrary::sendCombatSpam + +/** + * Sends standard combat spam info to players. The weapon is a string id instead + * of an object. + * + * @param env Java environment + * @param self class calling this function + * @param attacker who the attacker was + * @param defender who the defender was + * @param weaponName the name of the weapon used + * @param result structure with the numerical data for the attack + * @param attackName the name of the attack + * @param sendToAttacker flag to send the spam to the attacker + * @param sendToDefender flag to send the spam to the defender + * @param sendToBystanders flag to send the spam to other players near the combat + * @param spamType flag that sets what color the spam will be show as + */ +void JNICALL ScriptMethodsCombatNamespace::sendCombatSpamWeaponString(JNIEnv *env, jobject self, jlong attacker, jlong defender, jobject weaponName, jobject result, jobject attackName, jboolean sendToAttacker, jboolean sendToDefender, jboolean sendToBystanders, jint spamType) +{ + NetworkId attackerId(attacker); + ServerObject * attackerObj = safe_cast(NetworkIdManager::getObjectById(attackerId)); + if (attackerObj == NULL) + { + WARNING(true, ("WARNING: JavaLibrary::sendCombatSpam could not find attacker for id %s", attackerId.getValueString().c_str())); + return; + } + + NetworkId defenderId(defender); + Object const * const defenderObj = (defenderId.isValid() ? NetworkIdManager::getObjectById(defenderId) : NULL); + + StringId weaponNameSid; + if (!ScriptConversion::convert(weaponName, weaponNameSid)) + return; + StringId attackNameSid; + if (!ScriptConversion::convert(attackName, attackNameSid)) + return; + + int rawDamage = 0; + int damageType = 0; + int elementalDamage = 0; + int elementalDamageType = 0; + int bleedDamage = 0; + int critDamage = 0; + int blockedDamage = 0; + int finalDamage = 0; + int hitLocation = 0; + jboolean success = false; + jboolean critical = false; + jboolean glancing = false; + jboolean crushing = false; + jboolean strikethrough = false; + float strikethroughAmmount = 0.0f; + jboolean evadeResult = false; + float evadeAmmount = 0.0f; + jboolean blockResult = false; + int block = 0; + jboolean dodge = false; + jboolean parry = false; + jboolean proc = false; + NetworkId armorId; + + if (result != 0) + { + LocalRefParam jresult(result); + success = getBooleanField(jresult, JavaLibrary::getFidCombatEngineHitResultSuccess()); + critical = getBooleanField(jresult, JavaLibrary::getFidCombatEngineHitResultCritical()); + glancing = getBooleanField(jresult, JavaLibrary::getFidCombatEngineHitResultGlancing()); + proc = getBooleanField(jresult, JavaLibrary::getFidCombatEngineHitResultProc()); + + if (success) + { + LocalRefPtr armor = getObjectField(jresult, JavaLibrary::getFidCombatEngineHitResultBlockingArmor()); + armorId = JavaLibrary::getNetworkId(*armor); + + rawDamage = getIntField(jresult, JavaLibrary::getFidCombatEngineHitResultRawDamage()); + damageType = getIntField(jresult, JavaLibrary::getFidCombatEngineHitResultDamageType()); + elementalDamage = getIntField(jresult, JavaLibrary::getFidCombatEngineHitResultElementalDamage()); + elementalDamageType = getIntField(jresult, JavaLibrary::getFidCombatEngineHitResultElementalDamageType()); + bleedDamage = getIntField(jresult, JavaLibrary::getFidCombatEngineHitResultBleedDamage()); + critDamage = getIntField(jresult, JavaLibrary::getFidCombatEngineHitResultCritDamage()); + blockedDamage = getIntField(jresult, JavaLibrary::getFidCombatEngineHitResultBlockedDamage()); + finalDamage = getIntField(jresult, JavaLibrary::getFidCombatEngineHitResultDamage()); + hitLocation = getIntField(jresult, JavaLibrary::getFidCombatEngineHitResultHitLocation()); + crushing = getBooleanField(jresult, JavaLibrary::getFidCombatEngineHitResultCrushing()); + strikethrough = getBooleanField(jresult, JavaLibrary::getFidCombatEngineHitResultStrikethrough()); + strikethroughAmmount = getFloatField(jresult, JavaLibrary::getFidCombatEngineHitResultStrikethroughAmount()); + evadeResult = getBooleanField(jresult, JavaLibrary::getFidCombatEngineHitResultEvadeResult()); + evadeAmmount = getFloatField(jresult, JavaLibrary::getFidCombatEngineHitResultEvadeAmount()); + blockResult = getBooleanField(jresult, JavaLibrary::getFidCombatEngineHitResultBlockResult()); + block = getIntField(jresult, JavaLibrary::getFidCombatEngineHitResultBlock()); + } + else + { + dodge = getBooleanField(jresult, JavaLibrary::getFidCombatEngineHitResultDodge()); + parry = getBooleanField(jresult, JavaLibrary::getFidCombatEngineHitResultParry()); + } + } + + MessageQueueCombatSpam spam(attackerId, attackerObj->getPosition_w(), defenderId, (defenderObj ? defenderObj->getPosition_w() : Vector::zero), weaponNameSid, armorId, attackNameSid, rawDamage, damageType, elementalDamage, elementalDamageType, bleedDamage, critDamage, blockedDamage, finalDamage, hitLocation, success, critical, glancing, crushing, strikethrough, strikethroughAmmount, evadeResult, evadeAmmount, blockResult, block, dodge, parry, proc, spamType); + attackerObj->performCombatSpam(spam, sendToAttacker, sendToDefender, sendToBystanders); +} // JavaLibrary::sendCombatSpamWeaponString + +// ------------------------------------------------------------------------------------ + +/** + * Send a string id to a player in the combat spam window. + * + * @param env Java environment + * @param self class calling this function + * @param attacker the main player associated with the spam + * @param defender who the attacker is interacting with + * @param message the message + * @param sendToAttacker flag to send the message to the attacker + * @param sendToDefender flag to send the message to the defender + * @param sendToBystanders flag to send the message to anyone else in the area + * @param spamType flag that sets what color the spam will be show as + */ +void JNICALL ScriptMethodsCombatNamespace::sendCombatSpamMessage(JNIEnv *env, jobject self, jlong attacker, jlong defender, jobject message, jboolean sendToAttacker, jboolean sendToDefender, jboolean sendToBystanders, jint spamType) +{ + ServerObject * attackerObj = NULL; + if (!JavaLibrary::getObject(attacker, attackerObj)) + return; + + NetworkId defenderId(defender); + Object const * const defenderObj = (defenderId.isValid() ? NetworkIdManager::getObjectById(defenderId) : NULL); + + StringId messageSid; + if (!ScriptConversion::convert(message, messageSid)) + return; + + MessageQueueCombatSpam spam(attackerObj->getNetworkId(), attackerObj->getPosition_w(), defenderId, (defenderObj ? defenderObj->getPosition_w() : Vector::zero), Unicode::narrowToWide("@" + messageSid.getCanonicalRepresentation()), false, false, false, spamType); + attackerObj->performCombatSpam(spam, sendToAttacker, sendToDefender, sendToBystanders); +} // JavaLibrary::sendCombatSpamMessage + +// ------------------------------------------------------------------------------------ + +/** +* Send a string id to a player in the combat spam window. +* +* @param env Java environment +* @param self class calling this function +* @param attacker the main player associated with the spam +* @param defender who the attacker is interacting with +* @param message the message +* @param sendToAttacker flag to send the message to the attacker +* @param sendToDefender flag to send the message to the defender +* @param sendToBystanders flag to send the message to anyone else in the area +* @param critical changes spam on client +* @param glancing changes spam on client +* @param proc changes spam on client +* @param spamType flag that sets what color the spam will be show as +*/ +void JNICALL ScriptMethodsCombatNamespace::sendCombatSpamMessageCGP(JNIEnv *env, jobject self, jlong attacker, jlong defender, jobject message, jboolean sendToAttacker, jboolean sendToDefender, jboolean sendToBystanders, jboolean critical, jboolean glancing, jboolean proc, jint spamType) +{ + ServerObject * attackerObj = NULL; + if (!JavaLibrary::getObject(attacker, attackerObj)) + return; + + NetworkId defenderId(defender); + Object const * const defenderObj = (defenderId.isValid() ? NetworkIdManager::getObjectById(defenderId) : NULL); + + StringId messageSid; + if (!ScriptConversion::convert(message, messageSid)) + return; + + MessageQueueCombatSpam spam(attackerObj->getNetworkId(), attackerObj->getPosition_w(), defenderId, (defenderObj ? defenderObj->getPosition_w() : Vector::zero), Unicode::narrowToWide("@" + messageSid.getCanonicalRepresentation()), critical, glancing, proc, spamType); + attackerObj->performCombatSpam(spam, sendToAttacker, sendToDefender, sendToBystanders); +} // JavaLibrary::sendCombatSpamMessage + +// ------------------------------------------------------------------------------------ +/** + * Send an out-of-band package to a player in the combat spam window. + * + * @param env Java environment + * @param self class calling this function + * @param attacker the main player associated with the spam + * @param defender who the attacker is interacting with + * @param message the message + * @param sendToAttacker flag to send the message to the attacker + * @param sendToDefender flag to send the message to the defender + * @param sendToBystanders flag to send the message to anyone else in the area + * @param spamType flag that sets what color the spam will be show as + */ +void JNICALL ScriptMethodsCombatNamespace::sendCombatSpamMessageOob(JNIEnv *env, jobject self, jlong attacker, jlong defender, jstring oob, jboolean sendToAttacker, jboolean sendToDefender, jboolean sendToBystanders, jint spamType) +{ + ServerObject * attackerObj = NULL; + if (!JavaLibrary::getObject(attacker, attackerObj)) + return; + + NetworkId defenderId(defender); + Object const * const defenderObj = (defenderId.isValid() ? NetworkIdManager::getObjectById(defenderId) : NULL); + + Unicode::String oobString; + if (!JavaLibrary::convert(JavaStringParam(oob), oobString)) + return; + + MessageQueueCombatSpam spam(attackerObj->getNetworkId(), attackerObj->getPosition_w(), defenderId, (defenderObj ? defenderObj->getPosition_w() : Vector::zero), oobString, false, false, false, spamType); + attackerObj->performCombatSpam(spam, sendToAttacker, sendToDefender, sendToBystanders); +} // JavaLibrary::sendCombatSpamMessageOob + + +// ------------------------------------------------------------------------------------ +void JNICALL ScriptMethodsCombatNamespace::incrementKillMeter(JNIEnv *env, jobject self, jlong player, jint amount ) +{ + CreatureObject* playerCreature = 0; + if (!JavaLibrary::getObject(player, playerCreature)) + return; + if (!playerCreature->isPlayerControlled()) + return; + + PlayerObject* playerObject = PlayerCreatureController::getPlayerObject(playerCreature); + if (!playerObject) + return; + + playerObject->incrementKillMeter(amount); +} + +// ------------------------------------------------------------------------------------ + +jint JNICALL ScriptMethodsCombatNamespace::getKillMeter(JNIEnv *env, jobject self, jlong player ) +{ + CreatureObject* playerCreature = 0; + if (!JavaLibrary::getObject(player, playerCreature)) + return 0; + if (!playerCreature->isPlayerControlled()) + return 0; + + PlayerObject* playerObject = PlayerCreatureController::getPlayerObject(playerCreature); + if (!playerObject) + return 0; + + return playerObject->getKillMeter(); +} + +// ------------------------------------------------------------------------------------ + +jboolean JNICALL ScriptMethodsCombatNamespace::overrideDefaultAttack(JNIEnv *env, jobject self, jlong player, jstring attack) +{ + CreatureObject* playerCreature = 0; + if (!JavaLibrary::getObject(player, playerCreature)) + return JNI_FALSE; + if (!playerCreature->isPlayerControlled()) + return JNI_FALSE; + + PlayerObject* playerObject = PlayerCreatureController::getPlayerObject(playerCreature); + if (!playerObject) + return JNI_FALSE; + + JavaStringParam javaAttack(attack); + std::string convertAttack; + if (!JavaLibrary::convert(javaAttack, convertAttack)) + return JNI_FALSE; + + playerObject->overrideDefaultAttack(convertAttack); + + return JNI_TRUE; +} + +// ------------------------------------------------------------------------------------ + +jboolean JNICALL ScriptMethodsCombatNamespace::removeDefaultAttackOverride(JNIEnv *env, jobject self, jlong player) +{ + CreatureObject* playerCreature = 0; + if (!JavaLibrary::getObject(player, playerCreature)) + return JNI_FALSE; + if (!playerCreature->isPlayerControlled()) + return JNI_FALSE; + + PlayerObject* playerObject = PlayerCreatureController::getPlayerObject(playerCreature); + if (!playerObject) + return JNI_FALSE; + + // Setting the attack override to an empty string removes the effect on the client. + playerObject->overrideDefaultAttack(std::string()); + + return JNI_TRUE; +} + +// ------------------------------------------------------------------------------------ + +jstring JNICALL ScriptMethodsCombatNamespace::getDefaultAttackOverrideActionName(JNIEnv *env, jobject self, jlong player) +{ + CreatureObject* playerCreature = 0; + if (!JavaLibrary::getObject(player, playerCreature)) + return JNI_FALSE; + if (!playerCreature->isPlayerControlled()) + return JNI_FALSE; + + PlayerObject* playerObject = PlayerCreatureController::getPlayerObject(playerCreature); + if (!playerObject) + return JNI_FALSE; + + return JavaString(playerObject->getDefaultAttackOverride()).getValue(); +} +// ====================================================================== + diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsCommandQueue.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsCommandQueue.cpp new file mode 100644 index 00000000..2e400a0b --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsCommandQueue.cpp @@ -0,0 +1,422 @@ +// ====================================================================== +// +// ScriptMethodsCommandQueue.cpp - implements script methods dealing with +// creature command queues. +// +// Copyright 2002 Sony Online Entertainment +// +// ====================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "serverGame/CommandQueue.h" +#include "serverGame/CommandQueueEntry.h" +#include "serverGame/ConfigServerGame.h" +#include "serverGame/CreatureObject.h" +#include "serverGame/PlayerCreatureController.h" +#include "serverUtility/ServerClock.h" +#include "sharedDebug/Profiler.h" +#include "sharedGame/CommandTable.h" +#include "sharedNetworkMessages/MessageQueueCommandTimer.h" + +using namespace JNIWrappersNamespace; + + +// ====================================================================== +// ScriptMethodsCommandQueueNamespace +// ====================================================================== + +namespace ScriptMethodsCommandQueueNamespace +{ + bool install(); + + jboolean JNICALL queueCommand(JNIEnv *env, jobject self, jlong actor, jint commandHash, jlong target, jstring params, jint priority); + jboolean JNICALL queueClear(JNIEnv *env, jobject self, jlong actor); + jboolean JNICALL queueHasCommandFromGroup(JNIEnv *env, jobject self, jlong actor, jint group); + jboolean JNICALL queueClearCommandsFromGroup(JNIEnv *env, jobject self, jlong actor, jint group); + jfloat JNICALL getCommandMaxRange(JNIEnv *env, jobject self, jint commandHash); + jboolean JNICALL setCommandTimerValue( JNIEnv *env, jobject self, jlong actor, jint timerClass, jfloat newTime ); + jint JNICALL getCommandQueueSize( JNIEnv *env, jobject self, jobject actor, jboolean combatOnly ); + jfloat JNICALL getCooldownTimeLeft( JNIEnv *env, jobject self, jlong actor, jint cooldownTimer ); + jfloat JNICALL getCooldownTimeLeftString( JNIEnv *env, jobject self, jlong actor, jstring command ); + jint JNICALL getCurrentCommand( JNIEnv *env, jobject self, jlong actor ); + static void JNICALL sendCooldownGroupTimingOnly(JNIEnv * env, jobject self, jlong actor, jint cooldownGroupCrc, jfloat time); +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsCommandQueueNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsCommandQueueNamespace::c)} + JF("_queueCommand", "(JIJLjava/lang/String;I)Z", queueCommand), + JF("_queueClear", "(J)Z", queueClear), + JF("_queueHasCommandFromGroup", "(JI)Z", queueHasCommandFromGroup), + JF("_queueClearCommandsFromGroup", "(JI)Z", queueClearCommandsFromGroup), + JF("getCommandMaxRange", "(I)F", getCommandMaxRange), + JF("_setCommandTimerValue", "(JIF)Z", setCommandTimerValue), + JF("_getCooldownTimeLeft", "(JI)F", getCooldownTimeLeft), + JF("_getCooldownTimeLeft", "(JLjava/lang/String;)F", getCooldownTimeLeftString ), + JF("_getCurrentCommand", "(J)I", getCurrentCommand), + JF("_sendCooldownGroupTimingOnly", "(JIF)V", sendCooldownGroupTimingOnly), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +// ====================================================================== +// class JavaLibrary JNI command table methods +// ====================================================================== + +/** + * Enqueues a command on a creature's command queue. + * + * @param env Java Environment + * @param self class calling this function + * @param actor creature we wish to enqueue the command for + * @param command command to enqueue + * @param target object on which the command is targeted + * @param params string of any additional parameters to pass to the command + * @param priority priority at which to execute the command (may be default) + * + * @return true on success, false on error + */ +jboolean JNICALL ScriptMethodsCommandQueueNamespace::queueCommand(JNIEnv *env, jobject self, jlong actor, jint commandHash, jlong target, jstring params, jint priority) +{ + PROFILER_AUTO_BLOCK_DEFINE("queueCommand"); + JavaStringParam localParamsStr(params); + + if (priority < 0 || priority >= Command::CP_NumberOfPriorities) + return JNI_FALSE; + + NetworkId actorId(actor); + TangibleObject * const actorTangibleObject = TangibleObject::getTangibleObject(actorId); + + if (actorTangibleObject == NULL) + { + WARNING(true, ("JavaLibrary::queueCommand() Unable to resolve actor(%s) to a TangibleObject", actorId.getValueString().c_str())); + return JNI_FALSE; + } + + NetworkId targetId(target); + if (targetId != NetworkId::cms_invalid) + { + ServerObject const * const targetServerObject = ServerObject::getServerObject(targetId); + + //If script specified a target id, make sure it can be resolved. + if (!targetServerObject) + return JNI_FALSE; + + } + + const Command &command = CommandTable::getCommand(static_cast(commandHash)); + if (command.isNull()) + return JNI_FALSE; + + Unicode::String strParams; + if (!JavaLibrary::convert(localParamsStr, strParams)) + return JNI_FALSE; + + actorTangibleObject->commandQueueEnqueue(command, targetId, strParams, 0, false, static_cast(priority), true); + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +/** + * Clears a creature's command queue (only the clearable commands). + * + * @param env Java Environment + * @param self class calling this function + * @param actor creature we wish to clear the queue on + * + * @return true on success, false on error + */ +jboolean JNICALL ScriptMethodsCommandQueueNamespace::queueClear(JNIEnv *env, jobject self, jlong actor) +{ + NetworkId actorId(actor); + TangibleObject * const actorTangibleObject = TangibleObject::getTangibleObject(actorId); + + if (actorTangibleObject == NULL) + { + WARNING(true, ("JavaLibrary::queueClear() Unable to resolve actor(%s) to a TangibleObject", actorId.getValueString().c_str())); + return JNI_FALSE; + } + + actorTangibleObject->commandQueueClear(); + + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +/** + * Check if a creature has commands from a command group in its queue. + * + * @param env Java Environment + * @param self class calling this function + * @param actor creature we wish to check the queue on + * @param group hash of the group we are checking for + * + * @return true if commands are present, false if not or on error + */ +jboolean JNICALL ScriptMethodsCommandQueueNamespace::queueHasCommandFromGroup(JNIEnv *env, jobject self, jlong actor, jint group) +{ + NetworkId actorId(actor); + TangibleObject * const actorTangibleObject = TangibleObject::getTangibleObject(actorId); + + if (actorTangibleObject == NULL) + { + WARNING(true, ("JavaLibrary::queueHasCommandFromGroup() Unable to resolve actor(%s) to a TangibleObject", actorId.getValueString().c_str())); + return JNI_FALSE; + } + + return actorTangibleObject->commandQueueHasCommandFromGroup(static_cast(group)); +} + +// ---------------------------------------------------------------------- + +/** + * Clear commands of a specified group from a creature's command queue. + * + * @param env Java Environment + * @param self class calling this function + * @param actor creature we wish to clear commands from the queue on + * @param group hash of the group we are checking for + * + * @return true on success, false on error + */ +jboolean JNICALL ScriptMethodsCommandQueueNamespace::queueClearCommandsFromGroup(JNIEnv *env, jobject self, jlong actor, jint group) +{ + NetworkId actorId(actor); + TangibleObject * const actorTangibleObject = TangibleObject::getTangibleObject(actorId); + + if (actorTangibleObject == NULL) + { + WARNING(true, ("JavaLibrary::queueClearCommandsFromGroup() Unable to resolve actor(%s) to a TangibleObject", actorId.getValueString().c_str())); + return JNI_FALSE; + } + + actorTangibleObject->commandQueueClearCommandsFromGroup(group, true); + + return JNI_TRUE; +} + +/** + * Returns the max range a player can be from a target to execute a given command. + * + * @param env Java Environment + * @param self class calling this function + * @param commandHash the command to get the range for + * + * @return the range, or -1 if an unknown command + */ +jfloat JNICALL ScriptMethodsCommandQueueNamespace::getCommandMaxRange(JNIEnv * /*env*/, jobject /*self*/, jint commandHash) +{ + const Command & command = CommandTable::getCommand(commandHash); + if (&command == &CommandTable::getNullCommand()) + return -1; + + return command.m_maxRangeToTarget; +} // JavaLibrary::getCommandMaxRange + +/** + * Sets the specified duration timer for the currently executing command + * + * @param env Java Environment + * @param self call calling this function + * @param actor creature who's command queue we're going to access + * @param timerClass the class of the timer we're going to change + * @param newTime the new time for this command. + */ +jboolean JNICALL ScriptMethodsCommandQueueNamespace::setCommandTimerValue( JNIEnv *env, jobject, jlong actor, jint timerClass, jfloat newTime ) +{ + NetworkId actorId(actor); + TangibleObject * const actorTangibleObject = TangibleObject::getTangibleObject(actorId); + + if (actorTangibleObject == NULL) + { + WARNING(true, ("JavaLibrary::setCommandTimerValue() Unable to resolve actor(%s) to a TangibleObject", actorId.getValueString().c_str())); + return JNI_FALSE; + } + CommandQueue * const queue = actorTangibleObject->getCommandQueue(); + + if (queue == NULL) + { + WARNING(true, ("JavaLibrary::setCommandTimerValue() object(%s) does not have a CommandQueue", actorTangibleObject->getDebugInformation().c_str())); + return JNI_FALSE; + } + + return queue->setCommandTimerValue(static_cast(timerClass), newTime); +} + +/** + * Returns the crc32 of the current command + * + * @param env Java Environment + * @param self call calling this function + * @param actor creature who's command queue we're going to access, or 0 on error + */ +jint JNICALL ScriptMethodsCommandQueueNamespace::getCurrentCommand( JNIEnv *env, jobject, jlong actor ) +{ + NetworkId actorId(actor); + TangibleObject * const actorTangibleObject = TangibleObject::getTangibleObject(actorId); + + if (actorTangibleObject == NULL) + { + WARNING(true, ("JavaLibrary::getCurrentCommand() Unable to resolve actor(%s) to a TangibleObject", actorId.getValueString().c_str())); + return 0; + } + + CommandQueue const * const queue = actorTangibleObject->getCommandQueue(); + + if (queue == NULL) + { + WARNING(true, ("JavaLibrary::getCurrentCommand() object(%s) does not have a CommandQueue", actorTangibleObject->getDebugInformation().c_str())); + return 0; + } + + return queue->getCurrentCommand(); +} + +/** + * Returns the time left in a specified cooldown timer group + * + * @param env Java Environment + * @param self call calling this function + * @param actor creature who's command queue we're going to access + * @param group the cooldown timer group + * @return the time left in the cooldown group. + */ +jfloat JNICALL ScriptMethodsCommandQueueNamespace::getCooldownTimeLeft( JNIEnv *env, jobject, jlong actor, jint group ) +{ + NetworkId actorId(actor); + TangibleObject * const actorTangibleObject = TangibleObject::getTangibleObject(actorId); + + if (actorTangibleObject == NULL) + { + WARNING(true, ("JavaLibrary::getCooldownTimeLeft() Unable to resolve actor(%s) to a TangibleObject", actorId.getValueString().c_str())); + return 0.0f; + } + + CommandQueue const * const queue = actorTangibleObject->getCommandQueue(); + + if (queue == NULL) + { + WARNING(true, ("JavaLibrary::getCooldownTimeLeft() object(%s) does not have a CommandQueue", actorTangibleObject->getDebugInformation().c_str())); + return 0.0f; + } + + return queue->getCooldownTimeLeft(group); +} + +/** + * Returns the time left in a specified cooldown timer group + * + * @param env Java Environment + * @param self call calling this function + * @param actor creature who's command queue we're going to access + * @param command the cooldown timer group + * @return the time left in the cooldown group. + */ +jfloat JNICALL ScriptMethodsCommandQueueNamespace::getCooldownTimeLeftString( JNIEnv *env, jobject, jlong actor, jstring command ) +{ + NetworkId actorId(actor); + TangibleObject * const actorTangibleObject = TangibleObject::getTangibleObject(actorId); + + if (actorTangibleObject == NULL) + { + WARNING(true, ("JavaLibrary::getCooldownTimeLeftString() Unable to resolve actor(%s) to a TangibleObject", actorId.getValueString().c_str())); + return 0.0f; + } + + JavaStringParam s( command ); + Unicode::NarrowString out; + + if ( !JavaLibrary::convert( s, out ) ) + { + WARNING( true, ( "unable to convert string.\n" ) ); + return 0.f; + } + + CommandQueue const * const queue = actorTangibleObject->getCommandQueue(); + float value = 0.0f; + + if (queue == NULL) + { + WARNING(true, ("JavaLibrary::getCooldownTimeLeftString() object(%s) does not have a CommandQueue", actorTangibleObject->getDebugInformation().c_str())); + return 0.0f; + } + + if (queue != NULL) + { + value = queue->getCooldownTimeLeft( out ); + } + return value; +} + +/** + * send the client information about a cooldown group, without associated command info. + * we use this for things that cooldown but have no command, e.g. stimpacks + */ +void JNICALL ScriptMethodsCommandQueueNamespace::sendCooldownGroupTimingOnly(JNIEnv *env, jobject, jlong actor, jint cooldownGroupCrc, jfloat time) +{ + NetworkId actorId(actor); + CreatureObject * const actorCreatureObject = CreatureObject::getCreatureObject(actorId); + + if (actorCreatureObject == NULL) + { + WARNING(true, ("JavaLibrary::sendCooldownGroupTimingOnly() Unable to resolve actor(%s) to a CreatureObject", actorId.getValueString().c_str())); + return; + } + + CreatureController *controller = actorCreatureObject->getCreatureController(); + if(!controller) + return; + + MessageQueueCommandTimer *msg = new MessageQueueCommandTimer( + 0, + cooldownGroupCrc, + -1, + 0 ); + msg->setCurrentTime( MessageQueueCommandTimer::F_cooldown, 0.0f ); + msg->setMaxTime ( MessageQueueCommandTimer::F_cooldown, time ); + + // if the cool down value is large enough, we want to cache/persist it so + // that if the client is restarted, we can provide an accurate representation + // of where the cool down is at; if the cool down value is small, don't bother + // because by the time the client is back up and running, the cool down probably + // has already finished + if (static_cast(time) >= ConfigServerGame::getCoolDownPersistThresholdSeconds()) + { + int const currentGameTime = static_cast(ServerClock::getInstance().getGameTimeSeconds()); + + char buffer[256]; + + snprintf(buffer, sizeof(buffer)-1, "visualCooldown.beginTime.%d", static_cast(cooldownGroupCrc)); + buffer[sizeof(buffer)-1] = '\0'; + std::string const coolDownBeginTime = buffer; + + snprintf(buffer, sizeof(buffer)-1, "visualCooldown.endTime.%d", static_cast(cooldownGroupCrc)); + buffer[sizeof(buffer)-1] = '\0'; + std::string const coolDownEndTime = buffer; + + IGNORE_RETURN(actorCreatureObject->setObjVarItem(coolDownBeginTime, currentGameTime)); + IGNORE_RETURN(actorCreatureObject->setObjVarItem(coolDownEndTime, (currentGameTime + static_cast(time)))); + } + + controller->appendMessage( + static_cast< int >( CM_commandTimer ), + 0.0f, + msg, + GameControllerMessageFlags::SEND | + GameControllerMessageFlags::RELIABLE | + GameControllerMessageFlags::DEST_AUTH_CLIENT ); +} + +// ====================================================================== diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsConsole.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsConsole.cpp new file mode 100644 index 00000000..9392677f --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsConsole.cpp @@ -0,0 +1,81 @@ +// ScriptMethodsConsole.cpp +// Copyright 2000-05, Sony Online Entertainment Inc., all rights reserved. +// Author: Roy Fleck + +//----------------------------------------------------------------------- + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "UnicodeUtils.h" +#include "serverGame/ConsoleManager.h" +#include "serverGame/ServerObject.h" +#include "serverScript/ConfigServerScript.h" + + +// ====================================================================== +// ScriptMethodsConsoleNamespace +// ====================================================================== + +namespace ScriptMethodsConsoleNamespace +{ + bool install(); + + void JNICALL consoleSendMessageObjId(JNIEnv * env, jobject self, jlong _to, jstring _message); +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsConsoleNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsConsoleNamespace::c)} + JF("_sendConsoleMessage", "(JLjava/lang/String;)V", consoleSendMessageObjId), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsConsoleNamespace::consoleSendMessageObjId(JNIEnv * env, jobject self, jlong _to, jstring _message) +{ + UNREF(self); + + if (!_to) + return; + + const ServerObject* player = 0; + if(!JavaLibrary::getObject(_to, player)) + { + DEBUG_WARNING (true, ("ScriptMethodsConsole JavaLibrary::consoleSendMessageObjId failed bad source object (not null)")); + if (ConfigServerScript::allowDebugConsoleMessages()) + { + fprintf(stderr, "WARNING: ScriptMethodsConsole JavaLibrary::consoleSendMessageObjId: failed bad source object (not null)\n"); + JavaLibrary::printJavaStack(); + } + return; + } + + std::string message; + if (_message) + { + const JavaStringParam jt(_message); + if (!JavaLibrary::convert(jt, message)) + return; + } + + if (message.empty()) + { + DEBUG_WARNING (true, ("consoleSendMessageObjId with empty message")); + } + + ConsoleMgr::broadcastString(message, player->getNetworkId()); +} + +//---------------------------------------------------------------------- + diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsContainers.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsContainers.cpp new file mode 100644 index 00000000..12a63612 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsContainers.cpp @@ -0,0 +1,1007 @@ +//======================================================================== +// +// ScriptMethodsContainers.cpp - implements script methods dealing with object +// creation/destruction. +// +// copyright 2001 Sony Online Entertainment +// +//======================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "serverGame/ContainerInterface.h" +#include "serverGame/GameServer.h" +#include "serverGame/NameManager.h" +#include "serverGame/ServerObject.h" +#include "serverGame/ServerWorld.h" +#include "serverGame/TangibleObject.h" +#include "sharedFoundation/CrcLowerString.h" +#include "sharedNetworkMessages/GenericValueTypeMessage.h" +#include "sharedObject/Container.h" +#include "sharedObject/SlotId.h" +#include "sharedObject/SlotIdManager.h" +#include "sharedObject/SlottedContainer.h" +#include "sharedObject/SlottedContainmentProperty.h" +#include "sharedObject/VolumeContainer.h" + +using namespace JNIWrappersNamespace; + + +// ====================================================================== +// ScriptMethodsContainersNamespace +// ====================================================================== + +namespace ScriptMethodsContainersNamespace +{ + bool install(); + + jint JNICALL getContainerType(JNIEnv *env, jobject self, jlong container); + jlongArray JNICALL getContents(JNIEnv *env, jobject self, jlong container); + jlong JNICALL getContainedBy(JNIEnv *env, jobject self, jlong item); + jboolean JNICALL contains(JNIEnv *env, jobject self, jlong container, jlong item); + jlong JNICALL getObjectInSlot(JNIEnv *env, jobject self, jlong container, jstring slot); + jlong JNICALL getFirstParentInWorld(JNIEnv *env, jobject self, jlong item); + jlong JNICALL getTopMostContainer(JNIEnv *env, jobject self, jlong item); + jint JNICALL getNumItemsIn(JNIEnv *env, jobject self, jlong container); + void JNICALL destroyContents(JNIEnv *env, jobject self, jlong container); + jboolean JNICALL putIn(JNIEnv *env, jobject self, jlong item, jlong container); + jboolean JNICALL putInPosition(JNIEnv *env, jobject self, jlong item, jlong container, jobject pos); + jboolean JNICALL putInAndSendError(JNIEnv *env, jobject self, jlong item, jlong container, jlong player); + jboolean JNICALL putInOverloaded(JNIEnv *env, jobject self, jlong item, jlong container); + jboolean JNICALL equip(JNIEnv *env, jobject self, jlong item, jlong container); + jboolean JNICALL equipIn(JNIEnv *env, jobject self, jlong item, jlong container, jstring slot); + jboolean JNICALL equipOverride(JNIEnv *env, jobject self, jlong item, jlong container); + jint JNICALL getVolume(JNIEnv *env, jobject self, jlong target); + jint JNICALL getFilledVolume(JNIEnv *env, jobject self, jlong container); + jint JNICALL getTotalVolume(JNIEnv *env, jobject self, jlong container); + jint JNICALL canPutIn(JNIEnv *env, jobject self, jlong item, jlong container); + jint JNICALL canPutInSlot(JNIEnv *env, jobject self, jlong item, jlong container, jstring slot); + void JNICALL sendContainerErrorToClient(JNIEnv *env, jobject self, jlong player, jint errorCode); + void JNICALL moveToOfflinePlayerInventoryAndUnload(JNIEnv *env, jobject self, jlong target, jlong player); + void JNICALL moveToOfflinePlayerBankAndUnload(JNIEnv *env, jobject self, jlong target, jlong player); + void JNICALL moveToOfflinePlayerDatapadAndUnload(JNIEnv *env, jobject self, jlong target, jlong player, jint maxDepth); + jint JNICALL moveContents(JNIEnv *env, jobject self, jlong containerA, jlong containerB); + jint JNICALL moveObjects(JNIEnv *env, jobject self, jlongArray targets, jlong container); + jint JNICALL getVolumeFree(JNIEnv *env, jobject self, jlong container); + jboolean JNICALL isInSecureTrade(JNIEnv *env, jobject self, jlong item); + void JNICALL fixLoadWith(JNIEnv *env, jobject self, jlong topmostObject, jlong startingLoadWith, jint maxDepth); + jboolean JNICALL addUserToAccessList(JNIEnv *env, jobject self, jlong object, jlong user); + jboolean JNICALL removeUserFromAccessList(JNIEnv * env, jobject self, jlong object, jlong user); + jboolean JNICALL clearUserAccessList(JNIEnv * env, jobject self, jlong object); + jboolean JNICALL addGuildToAccessList(JNIEnv *env, jobject self, jlong object, jint guild); + jboolean JNICALL removeGuildFromAccessList(JNIEnv * env, jobject self, jlong object, jint guild); + jboolean JNICALL clearGuildAccessList(JNIEnv * env, jobject self, jlong object); + jlongArray JNICALL getUserAccessList(JNIEnv * env, jobject self, jlong object); + jintArray JNICALL getGuildAccessList(JNIEnv * env, jobject self, jlong object); +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsContainersNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsContainersNamespace::c)} + JF("_getContainerType", "(J)I", getContainerType), + JF("_getContents", "(J)[J", getContents), + JF("_getContainedBy", "(J)J", getContainedBy), + JF("_contains", "(JJ)Z", contains), + JF("_getObjectInSlot", "(JLjava/lang/String;)J", getObjectInSlot), + JF("_getFirstParentInWorld", "(J)J", getFirstParentInWorld), + JF("_getTopMostContainer", "(J)J", getTopMostContainer), + JF("_getNumItemsIn", "(J)I",getNumItemsIn), + JF("_destroyContents", "(J)V", destroyContents), + JF("_putIn", "(JJ)Z", putIn), + JF("_putInPosition", "(JJLscript/location;)Z", putInPosition), + JF("_putIn", "(JJJ)Z", putInAndSendError), + JF("_putInOverloaded", "(JJ)Z", putInOverloaded), + JF("_canPutIn", "(JJ)I",canPutIn), + JF("_canPutInSlot", "(JJLjava/lang/String;)I",canPutInSlot), + JF("_sendContainerErrorToClient", "(JI)V",sendContainerErrorToClient), + JF("_equip", "(JJ)Z", equip), + JF("_equip", "(JJLjava/lang/String;)Z", equipIn), + JF("_equipOverride", "(JJ)Z", equipOverride), + JF("_moveToOfflinePlayerInventoryAndUnload","(JJ)V", moveToOfflinePlayerInventoryAndUnload), + JF("_moveToOfflinePlayerBankAndUnload","(JJ)V", moveToOfflinePlayerBankAndUnload), + JF("_moveToOfflinePlayerDatapadAndUnload","(JJI)V", moveToOfflinePlayerDatapadAndUnload), + JF("_moveContents", "(JJ)I",moveContents), + JF("_moveObjects", "([JJ)I",moveObjects), + JF("_getVolumeFree", "(J)I",getVolumeFree), + JF("_getFilledVolume", "(J)I",getFilledVolume), + JF("_getTotalVolume", "(J)I",getTotalVolume), + JF("_isInSecureTrade", "(J)Z",isInSecureTrade), + JF("_fixLoadWith","(JJI)V", fixLoadWith), + JF("_addUserToAccessList", "(JJ)Z", addUserToAccessList), + JF("_removeUserFromAccessList", "(JJ)Z", removeUserFromAccessList), + JF("_clearUserAccessList", "(J)Z", clearUserAccessList), + JF("_addGuildToAccessList", "(JI)Z", addGuildToAccessList), + JF("_removeGuildFromAccessList", "(JI)Z", removeGuildFromAccessList), + JF("_clearGuildAccessList", "(J)Z", clearGuildAccessList), + JF("_getUserAccessList", "(J)[J", getUserAccessList), + JF("_getGuildAccessList", "(J)[I", getGuildAccessList), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +//======================================================================== +// class JavaLibrary JNI Container methods +//======================================================================== + + +jint JNICALL ScriptMethodsContainersNamespace::getContainerType(JNIEnv *env, jobject self, jlong container) +{ + //@todo use enum + ServerObject * containerOwner = NULL; + if (!JavaLibrary::getObject(container, containerOwner)) + return 0; + + if (ContainerInterface::getSlottedContainer(*containerOwner)) + return 1; + if (ContainerInterface::getVolumeContainer(*containerOwner)) + return 2; + return 0; +} + +//-------------------------------------------------------------------------------------- + +jlongArray JNICALL ScriptMethodsContainersNamespace::getContents(JNIEnv *env, jobject self, jlong containerObj) +{ + ServerObject * containerOwner = NULL; + if (!JavaLibrary::getObject(containerObj, containerOwner)) + return 0; + + Container* container = ContainerInterface::getContainer(*containerOwner); + + if (!container) + return 0; + + int numContents = container->getNumberOfItems(); + + // create the objId array + LocalLongArrayRefPtr idArray = createNewLongArray(numContents); + if (idArray == LocalLongArrayRef::cms_nullPtr) + { + if (env->ExceptionCheck()) + env->ExceptionDescribe(); + return 0; + } + + ContainerIterator iter = container->begin(); + for (int count = 0; iter != container->end(); ++iter, ++count) + { + if (*iter == NetworkId::cms_invalid) + { + WARNING_STRICT_FATAL(true, ("Iteration through a container should never return 0\n")); + continue; + } + + jlong jlongTmp = (*iter).getValue(); + setLongArrayRegion(*idArray, count, 1, &jlongTmp); + } + return idArray->getReturnValue(); +} + +//-------------------------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsContainersNamespace::getContainedBy(JNIEnv *env, jobject self, jlong item) +{ + ServerObject * itemObj = NULL; + if (!JavaLibrary::getObject(item, itemObj)) + return 0; + + ServerObject * target = dynamic_cast(ContainerInterface::getContainedByObject(*itemObj)); + if (!target) + return 0; + + return (target->getNetworkId()).getValue(); +} + +//-------------------------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsContainersNamespace::contains(JNIEnv *env, jobject self, jlong container, jlong item) +{ + if (!container) + return 0; + NetworkId container_id(container); + if (container_id.getValue() == 0) + return JNI_FALSE; + + ServerObject * itemObj = NULL; + if (!JavaLibrary::getObject(item, itemObj)) + return JNI_FALSE; + + ServerObject * target = dynamic_cast(ContainerInterface::getContainedByObject(*itemObj)); + if (!target) + return JNI_FALSE; + + return (target->getNetworkId() == container_id); +} + +//-------------------------------------------------------------------------------------- +jint JNICALL ScriptMethodsContainersNamespace::canPutIn(JNIEnv *env, jobject self, jlong target, jlong jcontainer) +{ + const int unknownError = static_cast(Container::CEC_Unknown); + ServerObject * containerOwner = NULL; + if (!JavaLibrary::getObject(jcontainer, containerOwner)) + return unknownError; + + ServerObject * item = NULL; + if (!JavaLibrary::getObject(target, item)) + return unknownError; + + Container* container = ContainerInterface::getContainer(*containerOwner); + if (!container) + return unknownError; + + Container::ContainerErrorCode tmp = Container::CEC_Success; + IGNORE_RETURN (container->mayAdd(*item, tmp) ); + return static_cast(tmp); +} + +//-------------------------------------------------------------------------------------- + +jint JNICALL ScriptMethodsContainersNamespace::canPutInSlot(JNIEnv *env, jobject self, jlong target, jlong jcontainer, jstring slot) +{ + const int unknownError = static_cast(Container::CEC_Unknown); + ServerObject * containerOwner = NULL; + if (!JavaLibrary::getObject(jcontainer, containerOwner)) + return unknownError; + + ServerObject * item = NULL; + if (!JavaLibrary::getObject(target, item)) + return unknownError; + + Container::ContainerErrorCode tmp = Container::CEC_Success; + + JavaStringParam localSlot(slot); + std::string slotString; + if (!JavaLibrary::convert(localSlot, slotString)) + return static_cast(Container::CEC_NoSlot); + + + SlotId slotId = SlotIdManager::findSlotId(CrcLowerString(slotString.c_str())); + if (slotId == SlotId::invalid) + return static_cast(Container::CEC_NoSlot); + + IGNORE_RETURN(ContainerInterface::canTransferToSlot(*containerOwner, *item, slotId, NULL, tmp)); + + return static_cast(tmp); +} + +//-------------------------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsContainersNamespace::getObjectInSlot(JNIEnv *env, jobject self, jlong container, jstring slot) +{ + JavaStringParam localSlot(slot); + + ServerObject * containerOwner = NULL; + if (!JavaLibrary::getObject(container, containerOwner)) + return 0; + + SlottedContainer * const slotContainer = ContainerInterface::getSlottedContainer(*containerOwner); + + if (!slotContainer) + return 0; + + std::string localName; + if (!JavaLibrary::convert(localSlot, localName)) + return 0; + + Container::ContainerErrorCode tmp = Container::CEC_Success; + const SlotId slotName = SlotIdManager::findSlotId(CrcLowerString(localName.c_str())); + return (slotContainer->getObjectInSlot(slotName, tmp)).getValue(); +} + +//-------------------------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsContainersNamespace::getFirstParentInWorld(JNIEnv *env, jobject self, jlong item) +{ + ServerObject * itemObj = NULL; + if (!JavaLibrary::getObject(item, itemObj)) + return 0; + + ServerObject * target = dynamic_cast(ContainerInterface::getFirstParentInWorld(*itemObj)); + if (!target) + return 0; + + return (target->getNetworkId()).getValue(); +} + +//-------------------------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsContainersNamespace::getTopMostContainer(JNIEnv *env, jobject self, jlong item) +{ + ServerObject * itemObj = NULL; + if (!JavaLibrary::getObject(item, itemObj)) + return 0; + + ServerObject * target = dynamic_cast(ContainerInterface::getTopmostContainer(*itemObj)); + if (!target) + return 0; + + return (target->getNetworkId()).getValue(); +} + +//-------------------------------------------------------------------------------------- + +jint JNICALL ScriptMethodsContainersNamespace::getNumItemsIn(JNIEnv *env, jobject self, jlong container) +{ + ServerObject * containerOwner = NULL; + if (!JavaLibrary::getObject(container, containerOwner)) + return 0; + + Container* cont = ContainerInterface::getContainer(*containerOwner); + if (!cont) + return 0; + + return cont->getNumberOfItems(); +} + +//-------------------------------------------------------------------------------------- + +void JNICALL ScriptMethodsContainersNamespace::destroyContents(JNIEnv *env, jobject self, jlong container) +{ +#if 0 //@todo implement + ServerObject * containerOwner = NULL; + if (!JavaLibrary::getObject(container, containerOwner)) + return; + + //call an engine function to do this. +#endif +} + +//-------------------------------------------------------------------------------------- + +jint JNICALL ScriptMethodsContainersNamespace::moveContents(JNIEnv *env, jobject self, jlong containerA, jlong containerB) +{ + ServerObject * containerOwner = NULL; + if (!JavaLibrary::getObject(containerA, containerOwner)) + return 0; + + ServerObject * targetContainer = NULL; + if (!JavaLibrary::getObject(containerB, targetContainer)) + return 0; + + Container * container = ContainerInterface::getContainer(*containerOwner); + if (!container) + return 0; + + int count = 0; + ContainerIterator iter = container->begin(); + Container::ContainerErrorCode tmp = Container::CEC_Success; + for (; iter != container->end(); ++iter) + { + ServerObject* item = safe_cast((*iter).getObject()); + if (item && ContainerInterface::transferItemToGeneralContainer(*targetContainer, *item, NULL, tmp)) + { + ++count; + } + } + return count; +} + +//-------------------------------------------------------------------------------------- + +jint JNICALL ScriptMethodsContainersNamespace::moveObjects(JNIEnv *env, jobject self, jlongArray targets, jlong container) +{ + ServerObject * containerOwner = NULL; + if (!JavaLibrary::getObject(container, containerOwner)) + return 0; + + int count = 0; + for (int i = 0; i < env->GetArrayLength(targets); ++i) + { + ServerObject * itemObj = NULL; + jlong jlongTmp; + env->GetLongArrayRegion(targets, i, 1, &jlongTmp); + if (JavaLibrary::getObject(jlongTmp, itemObj)) + { + Container::ContainerErrorCode tmp = Container::CEC_Success; + if (ContainerInterface::transferItemToGeneralContainer(*containerOwner, *itemObj, NULL, tmp)) + { + ++count; + } + } + } + return count; +} + +//-------------------------------------------------------------------------------------- + + + +jboolean JNICALL ScriptMethodsContainersNamespace::putIn(JNIEnv *env, jobject self, jlong item, jlong container) +{ + ServerObject * containerOwner = NULL; + if (!JavaLibrary::getObject(container, containerOwner)) + return JNI_FALSE; + + ServerObject * itemObj = NULL; + if (!JavaLibrary::getObject(item, itemObj)) + return JNI_FALSE; + Container::ContainerErrorCode tmp = Container::CEC_Success; + return ContainerInterface::transferItemToGeneralContainer(*containerOwner, *itemObj, NULL, tmp); + +} + +//-------------------------------------------------------------------------------------- + + +jboolean JNICALL ScriptMethodsContainersNamespace::putInPosition(JNIEnv *env, jobject self, jlong item, jlong container, jobject pos) +{ + ServerObject * containerOwner = NULL; + if (!JavaLibrary::getObject(container, containerOwner)) + return JNI_FALSE; + + ServerObject * itemObj = NULL; + if (!JavaLibrary::getObject(item, itemObj)) + return JNI_FALSE; + + Vector newPos; + NetworkId newCell; + ScriptConversion::convert(pos, newPos, newCell); + UNREF(newCell); + + Transform tr; + tr.setPosition_p(newPos); + + Container::ContainerErrorCode tmp = Container::CEC_Success; + return ContainerInterface::transferItemToCell(*containerOwner, *itemObj, tr, NULL, tmp); +} + +//-------------------------------------------------------------------------------------- + + +jboolean JNICALL ScriptMethodsContainersNamespace::putInAndSendError(JNIEnv *env, jobject self, jlong item, jlong container, jlong player) +{ + ServerObject * containerOwner = NULL; + if (!JavaLibrary::getObject(container, containerOwner)) + return JNI_FALSE; + + ServerObject * itemObj = NULL; + if (!JavaLibrary::getObject(item, itemObj)) + return JNI_FALSE; + + + Container::ContainerErrorCode tmp = Container::CEC_Success; + bool retval = ContainerInterface::transferItemToGeneralContainer(*containerOwner, *itemObj, NULL, tmp); + if (!retval) + { + ServerObject * playerObj = NULL; + if (!JavaLibrary::getObject(player, playerObj)) + return JNI_FALSE; + ContainerInterface::sendContainerMessageToClient(*playerObj, tmp); + } + return retval; +} + +//-------------------------------------------------------------------------------------- +jboolean JNICALL ScriptMethodsContainersNamespace::putInOverloaded(JNIEnv *env, jobject self, jlong item, jlong container) +{ + ServerObject * containerOwner = NULL; + if (!JavaLibrary::getObject(container, containerOwner)) + return JNI_FALSE; + + ServerObject * itemObj = NULL; + if (!JavaLibrary::getObject(item, itemObj)) + return JNI_FALSE; + + Container::ContainerErrorCode tmp = Container::CEC_Success; + bool retval = false; + if (!ContainerInterface::getVolumeContainer(*containerOwner)) + { + DEBUG_WARNING(true, ("putInOverloaded only works on volume containers")); + retval = false; + } + else + { + retval = ContainerInterface::transferItemToVolumeContainer(*containerOwner, *itemObj, NULL, tmp, true); + } + + return retval; +} + +//-------------------------------------------------------------------------------------- +jboolean JNICALL ScriptMethodsContainersNamespace::equip(JNIEnv *env, jobject self, jlong item, jlong container) +{ + ServerObject * containerOwner = NULL; + if (!JavaLibrary::getObject(container, containerOwner)) + return JNI_FALSE; + + ServerObject * itemObj = NULL; + if (!JavaLibrary::getObject(item, itemObj)) + return JNI_FALSE; + + SlottedContainer * const test = ContainerInterface::getSlottedContainer(*containerOwner); + if (!test) + return JNI_FALSE; + Container::ContainerErrorCode tmp = Container::CEC_Success; + return ContainerInterface::transferItemToGeneralContainer(*containerOwner, *itemObj, NULL, tmp); + +} + +//-------------------------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsContainersNamespace::equipIn(JNIEnv *env, jobject self, jlong item, jlong container, jstring slot) +{ + JavaStringParam localSlot(slot); + + //@todo better error checking for invalid slot name. Do it above too. + ServerObject * containerOwner = NULL; + if (!JavaLibrary::getObject(container, containerOwner)) + return JNI_FALSE; + + ServerObject * itemObj = NULL; + if (!JavaLibrary::getObject(item, itemObj)) + return JNI_FALSE; + + SlottedContainer * const test = ContainerInterface::getSlottedContainer(*containerOwner); + if (!test) + return JNI_FALSE; + + std::string localName; + if (!JavaLibrary::convert(localSlot, localName)) + return JNI_FALSE; + + const SlotId slotName = SlotIdManager::findSlotId(CrcLowerString(localName.c_str())); + + SlottedContainmentProperty * slotted = ContainerInterface::getSlottedContainmentProperty(*itemObj); + Container::ContainerErrorCode tmp = Container::CEC_Success; + int arrangement = slotted ? slotted->getBestArrangementForSlot(slotName) : -1; + + return ContainerInterface::transferItemToSlottedContainer(*containerOwner, *itemObj, arrangement, NULL, tmp); + +} + +//-------------------------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsContainersNamespace::equipOverride(JNIEnv *env, jobject self, jlong item, jlong container) +{ + //This function will equip and object into the first valid arrangement, deleting objects if necessary. + //Before it deletes things, it looks for a valid unoccupied arrangement. + + ServerObject * containerOwner = NULL; + if (!JavaLibrary::getObject(container, containerOwner)) + { + DEBUG_WARNING(true, ("JNI: EquipOverride param container could not be found")); + return JNI_FALSE; + } + + ServerObject * itemObj = NULL; + if (!JavaLibrary::getObject(item, itemObj)) + { + DEBUG_WARNING(true, ("JNI: EquipOverride param item could not be found")); + return JNI_FALSE; + } + + SlottedContainer * const slotContainer = ContainerInterface::getSlottedContainer(*containerOwner); + if (!slotContainer) + { + DEBUG_WARNING(true, ("JNI: EquipOverride param container was not slotted")); + return JNI_FALSE; + } + + //First check for a valid unoccupied arrangement + int arrangement = -1; + Container::ContainerErrorCode tmp = Container::CEC_Success; + if (slotContainer->getFirstUnoccupiedArrangement(*itemObj, arrangement, tmp)) + { + //Found one + return ContainerInterface::transferItemToSlottedContainer(*containerOwner, *itemObj, arrangement, NULL, tmp); + } + + //Couldn't find an unoccupied arrangement, so it's time to delete objects to make room for this one + + //-- get list of valid arrangements + std::vector vtmp; + slotContainer->getValidArrangements(*itemObj, vtmp, tmp, true, false); + + if (vtmp.empty()) + { + //In this case there was no valid arrangement + DEBUG_WARNING(true, ("JNI: EquipOverride item could not ever fit into this container")); + return JNI_FALSE; + } + arrangement = vtmp.front(); + if (arrangement < 0) + { + DEBUG_WARNING(true, ("JNI: EquipOverride item system error")); + return JNI_FALSE; + } + + SlottedContainmentProperty * scp = ContainerInterface::getSlottedContainmentProperty(*itemObj); + if (!scp) + { + DEBUG_WARNING(true, ("JNI: EquipOverride invalid item")); + return JNI_FALSE; + } + + const SlottedContainmentProperty::SlotArrangement & slotList = scp->getSlotArrangement(arrangement); + + for (SlottedContainmentProperty::SlotArrangement::const_iterator i = slotList.begin(); i != slotList.end(); ++i) + { + const CachedNetworkId & id = slotContainer->getObjectInSlot(*i, tmp); + if (id != NetworkId::cms_invalid) + { + ServerObject* objectToDelete = safe_cast(id.getObject()); + if (objectToDelete) + objectToDelete->permanentlyDestroy(DeleteReasons::Script); + } + } + + return ContainerInterface::transferItemToSlottedContainer(*containerOwner, *itemObj, arrangement, NULL, tmp); + +} + +//-------------------------------------------------------------------------------------- +jint JNICALL ScriptMethodsContainersNamespace::getFilledVolume(JNIEnv *env, jobject self, jlong container) +{ + ServerObject * containerOwner = NULL; + if (!JavaLibrary::getObject(container, containerOwner)) + return 0; + + VolumeContainer* volContainer = ContainerInterface::getVolumeContainer(*containerOwner); + if (!volContainer) + return 0; + + return volContainer->getCurrentVolume(); +} + +//-------------------------------------------------------------------------------------- + +jint JNICALL ScriptMethodsContainersNamespace::getTotalVolume(JNIEnv *env, jobject self, jlong container) +{ + ServerObject * containerOwner = NULL; + if (!JavaLibrary::getObject(container, containerOwner)) + return 0; + + VolumeContainer* volContainer = ContainerInterface::getVolumeContainer(*containerOwner); + if (!volContainer) + return 0; + + return volContainer->getTotalVolume(); +} + + +//-------------------------------------------------------------------------------------- + +jint JNICALL ScriptMethodsContainersNamespace::getVolumeFree(JNIEnv *env, jobject self, jlong container) +{ + ServerObject * containerOwner = NULL; + if (!JavaLibrary::getObject(container, containerOwner)) + return 0; + + VolumeContainer* volContainer = ContainerInterface::getVolumeContainer(*containerOwner); + if (!volContainer) + return 0; + + return volContainer->getTotalVolume() - volContainer->getCurrentVolume(); +} + +//-------------------------------------------------------------------------------------- + +void JNICALL ScriptMethodsContainersNamespace::sendContainerErrorToClient(JNIEnv *env, jobject self, jlong player, jint errorCode) +{ + //If there is no error, do nothing. + if (errorCode == 0) + return; + + ServerObject * playerObject = NULL; + if (!JavaLibrary::getObject(player, playerObject)) + { + DEBUG_WARNING(true, ("Player object not found in sendContainerErrorToClient")); + return; + } + + + if (errorCode < 0 || errorCode >= static_cast(Container::CEC_Last)) + { + DEBUG_WARNING(true, ("sendContainerErrorCodeToClient called with invalid error code")); + return; + } + + Container::ContainerErrorCode code = static_cast(errorCode); + ContainerInterface::sendContainerMessageToClient(*playerObject, code); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsContainersNamespace::moveToOfflinePlayerInventoryAndUnload(JNIEnv *env, jobject self, jlong target, jlong player) +{ + ServerObject *object = 0; + if (!JavaLibrary::getObject(target, object)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("moveToOfflinePlayerInventoryAndUnload - could not find target object %s", NetworkId(target).getValueString().c_str())); + else + { + NetworkId playerId(player); + if (!NameManager::getInstance().isPlayer(playerId)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("moveToOfflinePlayerInventoryAndUnload - target %s was not a valid player", playerId.getValueString().c_str())); + else + object->moveToPlayerAndUnload(playerId); + } +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsContainersNamespace::moveToOfflinePlayerBankAndUnload(JNIEnv *env, jobject self, jlong target, jlong player) +{ + ServerObject *object = 0; + if (!JavaLibrary::getObject(target, object)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("moveToOfflinePlayerBankAndUnload - could not find target object %s", NetworkId(target).getValueString().c_str())); + else + { + NetworkId playerId(player); + if (!NameManager::getInstance().isPlayer(playerId)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("moveToOfflinePlayerBankAndUnload - target %s was not a valid player", playerId.getValueString().c_str())); + else + object->moveToPlayerBankAndUnload(playerId); + } +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsContainersNamespace::moveToOfflinePlayerDatapadAndUnload(JNIEnv *env, jobject self, jlong target, jlong player, jint maxDepth) +{ + ServerObject *object = 0; + if (!JavaLibrary::getObject(target, object)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("moveToOfflinePlayerDatapadAndUnload - could not find target object %s", NetworkId(target).getValueString().c_str())); + else + { + NetworkId playerId(player); + if (!NameManager::getInstance().isPlayer(playerId)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("moveToOfflinePlayerDatapadAndUnload - player %s was not a valid player", playerId.getValueString().c_str())); + else + { + object->moveToPlayerDatapadAndUnload(playerId, maxDepth); + } + } +} + + +//-------------------------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsContainersNamespace::isInSecureTrade(JNIEnv *env, jobject self, jlong item) +{ + ServerObject * itemObj = NULL; + if (!JavaLibrary::getObject(item, itemObj)) + return JNI_FALSE; + + bool const secureTradeFlag = itemObj ? itemObj->isInSecureTrade() : false; + + return secureTradeFlag; +} + +// ---------------------------------------------------------------------- + +/** + * Fix the load_with for topmostObject and its contents by setting them to startingLoadWith + */ +void JNICALL ScriptMethodsContainersNamespace::fixLoadWith(JNIEnv *env, jobject self, jlong topmostObject, jlong startingLoadWith, jint maxDepth) +{ + NetworkId topmostObjectId(topmostObject); + if (!topmostObjectId.isValid()) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("fixLoadWith - topmostObject %s is not valid", topmostObjectId.getValueString().c_str())); + return; + } + + NetworkId startingLoadWithId(startingLoadWith); + if (!startingLoadWithId.isValid()) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("fixLoadWith - startingLoadWith %s is not valid", startingLoadWithId.getValueString().c_str())); + return; + } + + GenericValueTypeMessage, int> > const FixLoadWithMessage( + "FixLoadWith", + std::make_pair(std::make_pair(topmostObjectId, startingLoadWithId), maxDepth)); + GameServer::getInstance().sendToDatabaseServer(FixLoadWithMessage); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsContainersNamespace::addUserToAccessList(JNIEnv *env, jobject self, jlong object, jlong user) +{ + ServerObject * itemObj = NULL; + if (!JavaLibrary::getObject(object, itemObj)) + return JNI_FALSE; + + TangibleObject * tangibleObj = itemObj->asTangibleObject(); + if(!tangibleObj) + { + DEBUG_WARNING(true, ("AddUserToAccessList: Source Object must be a Tangible Object.")); + return JNI_FALSE; + } + + NetworkId userNetworkId(user); + + tangibleObj->addUserToAccessList(userNetworkId); + + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsContainersNamespace::removeUserFromAccessList(JNIEnv * env, jobject self, jlong object, jlong user) +{ + ServerObject * itemObj = NULL; + if (!JavaLibrary::getObject(object, itemObj)) + return JNI_FALSE; + + TangibleObject * tangibleObj = itemObj->asTangibleObject(); + if(!tangibleObj) + { + DEBUG_WARNING(true, ("RemoveUserFromAccessList: Source Object must be a Tangible Object.")); + return JNI_FALSE; + } + + NetworkId userNetworkId(user); + + tangibleObj->removeUserFromAccessList(userNetworkId); + + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsContainersNamespace::clearUserAccessList(JNIEnv * env, jobject self, jlong object) +{ + ServerObject * itemObj = NULL; + if (!JavaLibrary::getObject(object, itemObj)) + return JNI_FALSE; + + TangibleObject * tangibleObj = itemObj->asTangibleObject(); + if(!tangibleObj) + { + DEBUG_WARNING(true, ("ClearUserAccessList: Source Object must be a Tangible Object.")); + return JNI_FALSE; + } + + tangibleObj->clearUserAccessList(); + + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsContainersNamespace::addGuildToAccessList(JNIEnv *env, jobject self, jlong object, jint guild) +{ + ServerObject * itemObj = NULL; + if (!JavaLibrary::getObject(object, itemObj)) + return JNI_FALSE; + + TangibleObject * tangibleObj = itemObj->asTangibleObject(); + if(!tangibleObj) + { + DEBUG_WARNING(true, ("AddUserToAccessList: Source Object must be a Tangible Object.")); + return JNI_FALSE; + } + + tangibleObj->addGuildToAccessList(guild); + + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsContainersNamespace::removeGuildFromAccessList(JNIEnv * env, jobject self, jlong object, jint guild) +{ + ServerObject * itemObj = NULL; + if (!JavaLibrary::getObject(object, itemObj)) + return JNI_FALSE; + + TangibleObject * tangibleObj = itemObj->asTangibleObject(); + if(!tangibleObj) + { + DEBUG_WARNING(true, ("RemoveUserFromAccessList: Source Object must be a Tangible Object.")); + return JNI_FALSE; + } + + tangibleObj->removeGuildFromAccessList(guild); + + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsContainersNamespace::clearGuildAccessList(JNIEnv * env, jobject self, jlong object) +{ + ServerObject * itemObj = NULL; + if (!JavaLibrary::getObject(object, itemObj)) + return JNI_FALSE; + + TangibleObject * tangibleObj = itemObj->asTangibleObject(); + if(!tangibleObj) + { + DEBUG_WARNING(true, ("ClearUserAccessList: Source Object must be a Tangible Object.")); + return JNI_FALSE; + } + + tangibleObj->clearGuildAccessList(); + + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +jlongArray JNICALL ScriptMethodsContainersNamespace::getUserAccessList(JNIEnv * env, jobject self, jlong object) +{ + ServerObject * itemObj = NULL; + if (!JavaLibrary::getObject(object, itemObj)) + return JNI_FALSE; + + TangibleObject * tangibleObj = itemObj->asTangibleObject(); + if(!tangibleObj) + { + DEBUG_WARNING(true, ("getUserAccessList: Source Object must be a Tangible Object.")); + return JNI_FALSE; + } + + std::vector users; + tangibleObj->getUserAccessList(users); + + // create the objId array + LocalLongArrayRefPtr idArray = createNewLongArray(users.size()); + if (idArray == LocalLongArrayRef::cms_nullPtr) + { + if (env->ExceptionCheck()) + env->ExceptionDescribe(); + return 0; + } + + std::vector::iterator iter = users.begin(); + int count = 0; + for (; iter != users.end(); ++iter) + { + jlong jlongTmp = (*iter).getValue(); + setLongArrayRegion(*idArray, count, 1, &jlongTmp); + ++count; + } + + return idArray->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jintArray JNICALL ScriptMethodsContainersNamespace::getGuildAccessList(JNIEnv * env, jobject self, jlong object) +{ + ServerObject * itemObj = NULL; + if (!JavaLibrary::getObject(object, itemObj)) + return JNI_FALSE; + + TangibleObject * tangibleObj = itemObj->asTangibleObject(); + if(!tangibleObj) + { + DEBUG_WARNING(true, ("getUserAccessList: Source Object must be a Tangible Object.")); + return JNI_FALSE; + } + + std::vector guilds; + tangibleObj->getGuildAccessList(guilds); + + LocalIntArrayRefPtr idArray = createNewIntArray(guilds.size()); + if (idArray == LocalIntArrayRef::cms_nullPtr) + { + if (env->ExceptionCheck()) + env->ExceptionDescribe(); + return 0; + } + + std::vector::iterator iter = guilds.begin(); + int count = 0; + for (; iter != guilds.end(); ++iter) + { + jint jintTemp = (*iter); + setIntArrayRegion(*idArray, count, 1, &jintTemp); + ++count; + } + + return idArray->getReturnValue(); +} + +// ====================================================================== diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsCrafting.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsCrafting.cpp new file mode 100644 index 00000000..45860e43 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsCrafting.cpp @@ -0,0 +1,2808 @@ +//======================================================================== +// +// ScriptMethodsCrafting.cpp - implements script methods dealing with crafting +// and manufacturing. +// +// copyright 2001 Sony Online Entertainment +// +//======================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "UnicodeUtils.h" +#include "serverGame/ContainerInterface.h" +#include "serverGame/CreatureObject.h" +#include "serverGame/DraftSchematicObject.h" +#include "serverGame/FactoryObject.h" +#include "serverGame/ManufactureInstallationObject.h" +#include "serverGame/ManufactureObjectInterface.h" +#include "serverGame/ManufactureSchematicObject.h" +#include "serverGame/ObserveTracker.h" +#include "serverGame/PlayerCreatureController.h" +#include "serverGame/PlayerObject.h" +#include "serverGame/ResourceContainerObject.h" +#include "serverGame/ServerWorld.h" +#include "serverScript/GameScriptObject.h" +#include "serverScript/ScriptParameters.h" +#include "sharedFoundation/TemporaryCrcString.h" +#include "sharedGame/AssetCustomizationManager.h" +#include "sharedLog/Log.h" +#include "sharedObject/CustomizationData.h" +#include "sharedObject/MemoryBlockManagedObject.h" +#include "sharedObject/NetworkIdManager.h" +#include "sharedObject/ObjectTemplateList.h" +#include "sharedObject/PaletteColorCustomizationVariable.h" +#include "sharedObject/RangedIntCustomizationVariable.h" +#include "sharedObject/VolumeContainer.h" + +#include + +using namespace JNIWrappersNamespace; + + +// ====================================================================== + +namespace ScriptMethodsCraftingNamespace +{ + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + struct VariableInfo + { + VariableInfo(std::string const &newName, int newMinValueInclusive, int newSetValue, int newMaxValueExclusive); + + std::string name; + int minValueInclusive; + int value; + int maxValueExclusive; + }; + + typedef std::vector VariableInfoVector; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + bool install(); + void collectRangedIntVariableCallback(const std::string &fullVariablePathName, const CustomizationVariable *customizationVariable, void *context); + + jboolean JNICALL startCraftingSession(JNIEnv *env, jobject self, jlong player, jlong station); + jboolean JNICALL endCraftingSession(JNIEnv *env, jobject self, jlong crafter, jlong tool, jlong prototype); + jboolean JNICALL setCraftingLevelAndStation(JNIEnv *env, jobject self, jlong player, jint craftingLevel, jlong station); + jint JNICALL getCraftingLevel(JNIEnv *env, jobject self, jlong player); + jlong JNICALL getCraftingStation(JNIEnv *env, jobject self, jlong player); + jboolean JNICALL sendUseableDraftSchematics(JNIEnv *env, jobject self, jlong player, jintArray schematics); + jboolean JNICALL setSchematicAttribute(JNIEnv *env, jobject self, jlong manufacturingSchematic, jobject attribute, jboolean experiment); + jboolean JNICALL setSchematicAttributes(JNIEnv *env, jobject self, jlong manufacturingSchematic, jobjectArray attributes, jboolean experiment); + jobject JNICALL getSchematicAttribute(JNIEnv *env, jobject self, jlong manufacturingSchematic, jobject name, jboolean experiment); + jobjectArray JNICALL getSchematicAttributes(JNIEnv *env, jobject self, jlong manufacturingSchematic, jobjectArray names, jboolean experiment); + jobjectArray JNICALL getAllSchematicAttributes(JNIEnv *env, jobject self, jlong manufacturingSchematic, jboolean experiment); + jobject JNICALL getSchematicForExperimentalAttributes(JNIEnv *env, jobject self, jlong manufacturingSchematic, jobjectArray attributeNames); + jboolean JNICALL setSchematicExperimentMod(JNIEnv *env, jobject self, jlong manufacturingSchematic, jfloat experimentMod); + jboolean JNICALL setSchematicAppearances(JNIEnv *env, jobject self, jlong manufacturingSchematic, jobjectArray appearances); + jboolean JNICALL setSchematicCustomizations(JNIEnv *env, jobject self, jlong manufacturingSchematic, jobjectArray customizations); + jint JNICALL getSchematicItemCount(JNIEnv *env, jobject self, jlong manufacturingSchematic); + jboolean JNICALL setSchematicItemCount(JNIEnv *env, jobject self, jlong manufacturingSchematic, jint count); + jint JNICALL getSchematicItemsPerContainer(JNIEnv *env, jobject self, jlong manufacturingSchematic); + jboolean JNICALL setSchematicItemsPerContainer(JNIEnv *env, jobject self, jlong manufacturingSchematic, jint count); + jfloat JNICALL getSchematicManufactureTime(JNIEnv *env, jobject self, jlong manufacturingSchematic); + jboolean JNICALL setSchematicManufactureTime(JNIEnv *env, jobject self, jlong manufacturingSchematic, jfloat time); + jboolean JNICALL setCreatorXp(JNIEnv *env, jobject self, jlong object, jint xp); + void JNICALL getIngredientsForManufactureStation(JNIEnv *env, jobject self, jlong station, jobjectArray ingredients); + jlong JNICALL getManufactureStationInputHopper(JNIEnv *env, jobject self, jlong station); + jlong JNICALL getManufactureStationOutputHopper(JNIEnv *env, jobject self, jlong station); + jstring JNICALL getManufactureStationSchematic(JNIEnv *env, jobject self, jlong station); + void JNICALL getValidManufactureSchematicsForStation(JNIEnv *env, jobject self, jlong player, jlong station, jobjectArray schematics); + jboolean JNICALL hasValidManufactureSchematicsForStation(JNIEnv *env, jobject self, jlong player, jlong station); + jboolean JNICALL transferManufactureSchematicToPlayer(JNIEnv *env, jobject self, jlong station, jlong player); + jboolean JNICALL transferManufactureSchematicToStation(JNIEnv *env, jobject self, jlong schematic, jlong station); + void JNICALL getRepairableObjectsForTool(JNIEnv *env, jobject self, jlong player, jlong tool, jobjectArray objects); + jintArray JNICALL getAttributeBonuses(JNIEnv *env, jobject self, jlong target); + jint JNICALL getAttributeBonus(JNIEnv *env, jobject self, jlong target, jint attribute); + jboolean JNICALL setAttributeBonus(JNIEnv *env, jobject self, jlong target, jint attribute, jint bonus); + jboolean JNICALL setAttributeBonuses(JNIEnv *env, jobject self, jlong target, jintArray bonuses); + jobject JNICALL getSkillModBonuses(JNIEnv *env, jobject self, jlong target); + jint JNICALL getSkillModBonus(JNIEnv *env, jobject self, jlong target, jstring skillMod); + jboolean JNICALL setSkillModBonus(JNIEnv *env, jobject self, jlong target, jstring skillMod, jint bonus); + jboolean JNICALL setSkillModBonuses(JNIEnv *env, jobject self, jlong target, jobjectArray skillMod, jintArray bonus); + jboolean JNICALL setCategorizedSkillModBonus(JNIEnv *env, jobject self, jlong target, jstring category, jstring skillMod, jint bonus); + void JNICALL removeCategorizedSkillModBonuses(JNIEnv *env, jobject self, jlong target, jstring category); + jint JNICALL getSkillModSockets(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL setSkillModSockets(JNIEnv *env, jobject self, jlong target, jint sockets); + jlong JNICALL makeCraftedItem(JNIEnv *env, jobject self, jstring draftSchematic, jfloat qualityPercent, jlong container); + jobject JNICALL getSchematicData(JNIEnv *env, jobject self, jlong manufacturingSchematic); + jobject JNICALL getDraftSchematicData(JNIEnv *env, jobject self, jstring draftSchematic); + jobject JNICALL getDraftSchematicDataCrc(JNIEnv *env, jobject self, jint draftSchematicCrc); + void JNICALL recomputeCrateAttributes(JNIEnv *env, jobject self, jlong crate); +} + +using namespace ScriptMethodsCraftingNamespace; + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsCraftingNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsCraftingNamespace::c)} + JF("_startCraftingSession", "(JJ)Z", startCraftingSession), + JF("_endCraftingSession", "(JJJ)Z", endCraftingSession), + JF("_setCraftingLevelAndStation", "(JIJ)Z", setCraftingLevelAndStation), + JF("_getCraftingLevel", "(J)I", getCraftingLevel), + JF("_getCraftingStation", "(J)J", getCraftingStation), + JF("_sendUseableDraftSchematics", "(J[I)Z", sendUseableDraftSchematics), + JF("__setSchematicAttribute", "(JLscript/draft_schematic$attribute;Z)Z", setSchematicAttribute), + JF("__setSchematicAttributes", "(J[Lscript/draft_schematic$attribute;Z)Z", setSchematicAttributes), + JF("__getSchematicAttribute", "(JLscript/string_id;Z)Lscript/draft_schematic$attribute;", getSchematicAttribute), + JF("__getSchematicAttributes", "(J[Lscript/string_id;Z)[Lscript/draft_schematic$attribute;", getSchematicAttributes), + JF("__getAllSchematicAttributes", "(JZ)[Lscript/draft_schematic$attribute;", getAllSchematicAttributes), + JF("_getSchematicForExperimentalAttributes", "(J[Lscript/string_id;)Lscript/draft_schematic;", getSchematicForExperimentalAttributes), + JF("_setSchematicExperimentMod", "(JF)Z", setSchematicExperimentMod), + JF("_setSchematicAppearances", "(J[Ljava/lang/String;)Z", setSchematicAppearances), + JF("_setSchematicCustomizations", "(J[Lscript/draft_schematic$custom;)Z", setSchematicCustomizations), + JF("_getSchematicItemCount", "(J)I", getSchematicItemCount), + JF("_setSchematicItemCount", "(JI)Z", setSchematicItemCount), + JF("_getSchematicItemsPerContainer", "(J)I", getSchematicItemsPerContainer), + JF("_setSchematicItemsPerContainer", "(JI)Z", setSchematicItemsPerContainer), + JF("_getSchematicManufactureTime", "(J)F", getSchematicManufactureTime), + JF("_setSchematicManufactureTime", "(JF)Z", setSchematicManufactureTime), + JF("_setCreatorXp", "(JI)Z", setCreatorXp), + JF("_getIngredientsForManufactureStation", "(J[[Ljava/lang/String;)V", getIngredientsForManufactureStation), + JF("_getManufactureStationInputHopper", "(J)J", getManufactureStationInputHopper), + JF("_getManufactureStationOutputHopper", "(J)J", getManufactureStationOutputHopper), + JF("_getManufactureStationSchematic", "(J)Ljava/lang/String;", getManufactureStationSchematic), + JF("_getValidManufactureSchematicsForStation", "(JJ[[Ljava/lang/String;)V", getValidManufactureSchematicsForStation), + JF("_hasValidManufactureSchematicsForStation", "(JJ)Z", hasValidManufactureSchematicsForStation), + JF("_transferManufactureSchematicToPlayer", "(JJ)Z", transferManufactureSchematicToPlayer), + JF("_transferManufactureSchematicToStation", "(JJ)Z", transferManufactureSchematicToStation), + JF("_getRepairableObjectsForTool", "(JJ[[Ljava/lang/String;)V", getRepairableObjectsForTool), + JF("_getAttributeBonuses", "(J)[I", getAttributeBonuses), + JF("_getAttributeBonus", "(JI)I", getAttributeBonus), + JF("_setAttributeBonus", "(JII)Z", setAttributeBonus), + JF("_setAttributeBonuses", "(J[I)Z", setAttributeBonuses), + JF("_getSkillModBonuses", "(J)Lscript/dictionary;", getSkillModBonuses), + JF("_getSkillModBonus", "(JLjava/lang/String;)I", getSkillModBonus), + JF("_setSkillModBonus", "(JLjava/lang/String;I)Z", setSkillModBonus), + JF("_setSkillModBonuses", "(J[Ljava/lang/String;[I)Z", setSkillModBonuses), + JF("_setCategorizedSkillModBonus", "(JLjava/lang/String;Ljava/lang/String;I)Z", setCategorizedSkillModBonus), + JF("_removeCategorizedSkillModBonuses", "(JLjava/lang/String;)V", removeCategorizedSkillModBonuses), + JF("_getSkillModSockets", "(J)I", getSkillModSockets), + JF("_setSkillModSockets", "(JI)Z", setSkillModSockets), + JF("_makeCraftedItem", "(Ljava/lang/String;FJ)J", makeCraftedItem), + JF("_getSchematicData", "(J)Lscript/draft_schematic;", getSchematicData), + JF("getSchematicData", "(Ljava/lang/String;)Lscript/draft_schematic;", getDraftSchematicData), + JF("getSchematicData", "(I)Lscript/draft_schematic;", getDraftSchematicDataCrc), + JF("_recomputeCrateAttributes", "(J)V", recomputeCrateAttributes), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +// ====================================================================== +// namespace ScriptMethodsCraftingNamespace +// ====================================================================== + +ScriptMethodsCraftingNamespace::VariableInfo::VariableInfo(std::string const &newName, int newMinValueInclusive, int newSetValue, int newMaxValueExclusive): + name(newName), + minValueInclusive(newMinValueInclusive), + value(newSetValue), + maxValueExclusive(newMaxValueExclusive) +{ +} + +// ---------------------------------------------------------------------- + +void ScriptMethodsCraftingNamespace::collectRangedIntVariableCallback(const std::string &fullVariablePathName, const CustomizationVariable *customizationVariable, void *context) +{ + //-- Check if variable is a palette-color style variable. If not, ignore for now. + // NOTE: replace PaletteColorCustomizationVariable with RangedIntCustomizatoinVariable + // if you want any ranged int (including texture choice ranges and palette colors) to be + // passed to crafting. + PaletteColorCustomizationVariable const *const paletteColorVariable = dynamic_cast(customizationVariable); + if (!paletteColorVariable) + { + // Nothing to do. + return; + } + + //-- Check if variable is a ranged int style variable. + RangedIntCustomizationVariable const *const rangedIntVariable = paletteColorVariable; + + //-- Get variable info list from context. + NOT_NULL(context); + VariableInfoVector *const variableInfoVector = static_cast(context); + + //-- Add variable info to vector. + int minValueInclusive = 0; + int maxValueExclusive = 0; + + rangedIntVariable->getRange(minValueInclusive, maxValueExclusive); + variableInfoVector->push_back(VariableInfo(fullVariablePathName, minValueInclusive, rangedIntVariable->getValue(), maxValueExclusive)); +} + +//======================================================================== +// class JavaLibrary crafting utility functions +//======================================================================== + +/** + * Creates a Java draft_schematic.attribute instance from an object attribute. + * + * @param manfSchematic manufacture schematic the attribute belongs to + * @param draftSchematic draft schematic the attribute belongs to + * @param attribIndex index of the attribute + * + * @return the attribute instance, or NULL on error + */ +LocalRefPtr JavaLibrary::createObjectAttribute(const ManufactureObjectInterface & manfSchematic, + const DraftSchematicObject & draftSchematic, int attribIndex) +{ + if (attribIndex < 0 || attribIndex >= draftSchematic.getAttribsCount()) + return LocalRef::cms_nullPtr; + + const SharedDraftSchematicObjectTemplate::SchematicAttribute & + minAttrib = draftSchematic.getAttribMin(attribIndex); + const SharedDraftSchematicObjectTemplate::SchematicAttribute & + maxAttrib = draftSchematic.getAttribMax(attribIndex); + + if (minAttrib.name.getTable().empty() || minAttrib.name.getText().empty()) + return LocalRef::cms_nullPtr; + + // create the attribute object + LocalRefPtr attribute = allocObject(JavaLibrary::getClsDraftSchematicAttrib()); + if (attribute == LocalRef::cms_nullPtr) + return LocalRef::cms_nullPtr; + + // set the name + LocalRefPtr name; + if (!ScriptConversion::convert(minAttrib.name, name)) + return LocalRef::cms_nullPtr; + + setObjectField(*attribute, JavaLibrary::getFidDraftSchematicAttribName(), *name); + + // get the resourceMax and current values + float minValue = static_cast(minAttrib.value); + float maxValue = static_cast(maxAttrib.value); + float resourceMaxValue = maxValue; + float currentValue = minValue; + + std::map::const_iterator result = manfSchematic.getAttributes().find( + minAttrib.name); + if (result != manfSchematic.getAttributes().end()) + currentValue = (*result).second; + + result = manfSchematic.getResourceMaxAttributes().find( + minAttrib.name); + if (result != manfSchematic.getResourceMaxAttributes().end()) + resourceMaxValue = (*result).second; + + // set the other fields + setFloatField(*attribute, JavaLibrary::getFidDraftSchematicAttribMinValue(), minValue); + setFloatField(*attribute, JavaLibrary::getFidDraftSchematicAttribMaxValue(), maxValue); + setFloatField(*attribute, JavaLibrary::getFidDraftSchematicAttribResourceMaxValue(), resourceMaxValue); + setFloatField(*attribute, JavaLibrary::getFidDraftSchematicAttribCurrentValue(), currentValue); + + return attribute; +} // JavaLibrary::createObjectAttribute + +/** + * Creates a Java draft_schematic.attribute instance from an experimental attribute. + * + * @param manfSchematic manufacture schematic the attribute belongs to + * @param attribName name of the attribute + * + * @return the attribute instance, or NULL on error + */ +LocalRefPtr JavaLibrary::createExperimentAttribute(const ManufactureObjectInterface & manfSchematic, + const StringId & attribName) +{ + if (attribName.getTable().empty() || attribName.getText().empty()) + return LocalRef::cms_nullPtr; + + // create the attribute object + LocalRefPtr attribute = allocObject(JavaLibrary::getClsDraftSchematicAttrib()); + if (attribute == LocalRef::cms_nullPtr) + return LocalRef::cms_nullPtr; + + // set the name + LocalRefPtr name; + if (!ScriptConversion::convert(attribName, name)) + return LocalRef::cms_nullPtr; + + setObjectField(*attribute, JavaLibrary::getFidDraftSchematicAttribName(), *name); + + // set the other fields + float value, minValue, maxValue, resourceValue; + manfSchematic.getAllExperimentAttributeValues(attribName, value, minValue, maxValue, + resourceValue); + setFloatField(*attribute, JavaLibrary::getFidDraftSchematicAttribCurrentValue(), value); + setFloatField(*attribute, JavaLibrary::getFidDraftSchematicAttribMinValue(), minValue); + setFloatField(*attribute, JavaLibrary::getFidDraftSchematicAttribMaxValue(), maxValue); + setFloatField(*attribute, JavaLibrary::getFidDraftSchematicAttribResourceMaxValue(), resourceValue); + + return attribute; +} // JavaLibrary::createExperimentAttribute + + +//======================================================================== +// class JavaLibrary JNI conversion methods +//======================================================================== + +/** + * Converts a C++ ManufactureSchematicObject to a Java draft_schematic. + * + * @param source the ManufactureSchematicObject to convert + * + * @return a new draft_schematic object + */ +LocalRefPtr JavaLibrary::convert(const ManufactureObjectInterface & source) +{ +int i; + + const DraftSchematicObject * draft = DraftSchematicObject::getSchematic( + source.getDraftSchematic()); + if (draft == NULL) + return LocalRef::cms_nullPtr; + + LocalRefPtr target = allocObject(ms_clsDraftSchematic); + if (target == LocalRef::cms_nullPtr) + return LocalRef::cms_nullPtr; + + // set the ingredients + int numSlots = source.getSlotsCount(); + LocalObjectArrayRefPtr slots = createNewObjectArray(numSlots, ms_clsDraftSchematicSlot); + if (slots == LocalObjectArrayRef::cms_nullPtr) + return LocalRef::cms_nullPtr; + + Crafting::IngredientSlot sourceSlot; + ServerDraftSchematicObjectTemplate::IngredientSlot draftSlot; + for (i = 0; i < numSlots; ++i) + { + if (!source.getSlot(i, sourceSlot, true)) + { + WARNING(true, ("JavaLibrary::convert manf data: unable to get slot %d " + "from manf schematic %s", i, source.getDerivedNetworkId().getValueString().c_str())); + break; + } + + // get the amount of ingredient required from the draft schematic + if (!draft->getSlot(draftSlot, sourceSlot.name)) + { + WARNING(true, ("JavaLibrary::convert manf data: unable to get slot %s " + "from draft schematic %s", sourceSlot.name.getCanonicalRepresentation().c_str(), + draft->getObjectTemplateName())); + break; + } + int amountRequired = draftSlot.options[sourceSlot.draftSlotOption]. + ingredients[0].count; + + // create the ingredient object + LocalRefPtr slot = convert(source, sourceSlot, amountRequired, + draftSlot.appearance, draftSlot.options[0].ingredients[0].ingredient); + if (slot == LocalRef::cms_nullPtr) + { + WARNING(true, ("Unable to convert schematic slot %s to Java data", + sourceSlot.name.getCanonicalRepresentation().c_str())); + break; + } + + setObjectArrayElement(*slots, i, *slot); + } + if (i != numSlots) + { + return LocalRef::cms_nullPtr; + } + setObjectField(*target, ms_fidDraftSchematicSlots, *slots); + + // if we are converting the schematic in order to manufacture an object, + // just convert the object attributes and ingredient sources and exit + if (source.isMakingObject()) + { + int numObjectAttribs = draft->getAttribsCount(); + LocalObjectArrayRefPtr attributes = createNewObjectArray(numObjectAttribs, JavaLibrary::getClsDraftSchematicAttrib()); + if (attributes == LocalObjectArrayRef::cms_nullPtr) + { + return LocalRef::cms_nullPtr; + } + for (i = 0; i < numObjectAttribs; ++i) + { + // create the attribute object + LocalRefPtr attribute = JavaLibrary::createObjectAttribute(source, *draft, i); + if (attribute == LocalRef::cms_nullPtr) + break; + setObjectArrayElement(*attributes, i, *attribute); + } + if (i != numObjectAttribs) + { + return LocalRef::cms_nullPtr; + } + setObjectField(*target, ms_fidDraftSchematicAttribs, *attributes); + return target; + } + + // set the crafting category + setIntField(*target, ms_fidDraftSchematicCategory, draft->getCategory()); + // set the base complexity + setFloatField(*target, ms_fidDraftSchematicComplexity, draft->getComplexity()); + + // + // set the attributes, the experimental attributes, and the mapping between them + // + + LocalRefPtr attribMap = createNewObject(ms_clsHashtable, ms_midHashtable); + if (attribMap == LocalRef::cms_nullPtr) + return LocalRef::cms_nullPtr; + + // create a local frame reference big enough so we can keep around the + // references to the object attributes and experiment attributes + const std::vector & experimentNames = source.getExperimentAttributeNames(); + int numExperimentAttribs = experimentNames.size(); + int numObjectAttribs = draft->getAttribsCount(); + + // set the experimental attributes + std::vector experimentAttribRefs; + LocalObjectArrayRefPtr attributes = createNewObjectArray(numExperimentAttribs, JavaLibrary::getClsDraftSchematicAttrib()); + if (attributes == LocalObjectArrayRef::cms_nullPtr) + { + return LocalRef::cms_nullPtr; + } + for (i = 0; i < numExperimentAttribs; ++i) + { + // create the attribute object + LocalRefPtr attribute = JavaLibrary::createExperimentAttribute(source, experimentNames[i]); + if (attribute == LocalRef::cms_nullPtr) + break; + + setObjectArrayElement(*attributes, i, *attribute); + experimentAttribRefs.push_back(attribute); + } + if (i != numExperimentAttribs) + { + return LocalRef::cms_nullPtr; + } + setObjectField(*target, ms_fidDraftSchematicExperimentalAttribs, *attributes); + + // set the object attributes + attributes = createNewObjectArray(numObjectAttribs, JavaLibrary::getClsDraftSchematicAttrib()); + if (attributes == LocalObjectArrayRef::cms_nullPtr) + { + return LocalRef::cms_nullPtr; + } + for (i = 0; i < numObjectAttribs; ++i) + { + // create the attribute object + LocalRefPtr attribute = JavaLibrary::createObjectAttribute(source, *draft, i); + if (attribute == LocalRef::cms_nullPtr) + break; + setObjectArrayElement(*attributes, i, *attribute); + + // find the experimental attribute associated with the object attibute + // and add it to the attribute map + StringId expAttrib(draft->getExperimentalAttributeFromAttribute(i)); + for (int j = 0; j < numExperimentAttribs; ++j) + { + if (expAttrib == experimentNames[j]) + { + callObjectMethod(*attribMap, ms_midMapPut, + attribute->getValue(), experimentAttribRefs[j]->getValue()); + break; + } + } + } + if (i != numObjectAttribs) + { + return LocalRef::cms_nullPtr; + } + setObjectField(*target, JavaLibrary::getFidDraftSchematicAttribs(), *attributes); + setObjectField(*target, JavaLibrary::getFidDraftSchematicAttribMap(), *attribMap); + + // restore our frame reference + experimentAttribRefs.clear(); + + // set the customization info from the shared object template + const ServerObjectTemplate * objectTemplate = draft->getCraftedObjectTemplate(); + if (objectTemplate == NULL) + { + return LocalRef::cms_nullPtr; + } + const SharedObjectTemplate * sharedTemplate = safe_cast( + ObjectTemplateList::fetch(objectTemplate->getSharedTemplate())); + const SharedTangibleObjectTemplate * sharedTangibleTemplate = dynamic_cast< + const SharedTangibleObjectTemplate *>(sharedTemplate); + if (sharedTangibleTemplate != NULL) + { + // New method using the AssetCustomizationManager mechanism. + + //-- Retrieve customization declarations for the appearance asset associated with + // the crafted object's shared object template. + + // Create a dummy object. + Object *dummyObject = new MemoryBlockManagedObject(); + NOT_NULL(dummyObject); + + // Create a CustomizationData instance. + CustomizationData *customizationData = new CustomizationData(*dummyObject); + NOT_NULL(customizationData); + customizationData->fetch(); + + // Retrieve CustomizationData for crafted object's appearance template name. + bool const skipSharedOwnerVariables = true; + AssetCustomizationManager::addCustomizationVariablesForAsset(TemporaryCrcString(sharedTangibleTemplate->getAppearanceFilename().c_str(), true), *customizationData, skipSharedOwnerVariables); + + // Retrieve all ranged int customization variables from CusotmizationData. + VariableInfoVector variableInfoList; + bool const includeRemoveVariables = false; + customizationData->iterateOverConstVariables(collectRangedIntVariableCallback, &variableInfoList, includeRemoveVariables); + + int const count = static_cast(variableInfoList.size()); +#ifdef _DEBUG + LOG("crafting-customizations", ("customization variable count: %d for (%s)", count, sharedTangibleTemplate->getAppearanceFilename().c_str())); +#endif + + //-- Create the Java array to hold the ranged int customization entries. + LocalObjectArrayRefPtr customizations = createNewObjectArray(count, ms_clsDraftSchematicCustom); + if (customizations == LocalObjectArrayRef::cms_nullPtr) + { + customizationData->release(); + delete dummyObject; + return LocalRef::cms_nullPtr; + } + + //-- Fill in the Java array with customization entries. + int i; + + for (i = 0; i < count; ++i) + { + VariableInfo const &info = variableInfoList[static_cast(i)]; + + // create the customization object + LocalRefPtr customization = allocObject(ms_clsDraftSchematicCustom); + if (customization == LocalRef::cms_nullPtr) + break; + + // set the name + JavaString name(info.name.c_str()); + setObjectField(*customization, JavaLibrary::getFidDraftSchematicCustomName(), name); + + // set the values + setIntField(*customization, JavaLibrary::getFidDraftSchematicCustomValue(), info.value); + setIntField(*customization, JavaLibrary::getFidDraftSchematicCustomMinValue(), info.minValueInclusive); + setIntField(*customization, JavaLibrary::getFidDraftSchematicCustomMaxValue(), info.maxValueExclusive - 1); +// setBooleanField(*customization, ms_fidDraftSchematicCustomLocked, +// JNI_FALSE); + + setObjectArrayElement(*customizations, i, *customization); + } + if (i != count) + { + customizationData->release(); + delete dummyObject; + return LocalRef::cms_nullPtr; + } + setObjectField(*target, ms_fidDraftSchematicCustomizations, *customizations); + + //-- Cleanup. + customizationData->release(); + delete dummyObject; + } + else + setObjectField(*target, ms_fidDraftSchematicCustomizations, LocalRef(0)); + + return target; +} // JavaLibrary::convert(const ManufactureObjectInterface &) + +/** + * Converts a C++ Crafting::IngredientSlot to a Java draft_schematic$slot. + * + * @param schematic the manf schematic the slot belongs to + * @param source the IngredientSlot to convert + * @param amountRequired amount of ingredients required to fill the slot + * @param appearance appearance data associated with the slot + * @param requiredIngredient name of the ingredient needed for the slot + * + * @return a new draft_schematic object + */ +LocalRefPtr JavaLibrary::convert(const ManufactureObjectInterface & schematic, + const Crafting::IngredientSlot & source, int amountRequired, + const std::string & appearance, const std::string & requiredIngredient) +{ + int i; + + // create the slot object + LocalRefPtr slot = allocObject(ms_clsDraftSchematicSlot); + if (slot == LocalRef::cms_nullPtr) + return LocalRef::cms_nullPtr; + + // set the slot name + LocalRefPtr slotName; + if (!ScriptConversion::convert(source.name, slotName)) + { + return LocalRef::cms_nullPtr; + } + setObjectField(*slot, ms_fidDraftSchematicSlotName, *slotName); + + // set the slot appearance data + JavaString appearanceName(appearance.c_str()); + setObjectField(*slot, ms_fidDraftSchematicSlotAppearance, appearanceName); + + JavaString ingredientName(requiredIngredient); + if (ingredientName.getValue() == 0) + return LocalRef::cms_nullPtr; + + // set the slot data + setIntField(*slot, ms_fidDraftSchematicSlotOption, source.draftSlotOption); + setIntField(*slot, ms_fidDraftSchematicSlotIngredientType, source.ingredientType); + setFloatField(*slot, ms_fidDraftSchematicSlotComplexity, source.complexity); + setIntField(*slot, ms_fidDraftSchematicSlotAmountRequired, amountRequired); + setObjectField(*slot, ms_fidDraftSchematicSlotIngredientName, ingredientName); + + // create the ingredients array + int count = source.ingredients.size(); + LocalObjectArrayRefPtr ingredients = createNewObjectArray(count, ms_clsDraftSchematicSimpleIngredient); + if (ingredients == LocalObjectArrayRef::cms_nullPtr) + { + return LocalRef::cms_nullPtr; + } + for (i = 0; i < count; ++i) + { + // create the ingredient object + LocalRefPtr ingredient = allocObject(ms_clsDraftSchematicSimpleIngredient); + if (ingredient == LocalRef::cms_nullPtr) + { + WARNING(true, ("Unable to allocate Java memory for simple ingredient data")); + break; + } + + // set the ingredient source and xp type + LocalRefPtr sourceId = getObjId(source.ingredients[i]->source); + setObjectField(*ingredient, ms_fidDraftSchematicSimpleIngredientSource, + *sourceId); + setIntField(*ingredient, ms_fidDraftSchematicSimpleIngredientXpType, + source.ingredients[i]->xpType); + + + // set the ingredient id + if (source.ingredientType == Crafting::IT_resourceType || + source.ingredientType == Crafting::IT_resourceClass) + { + LocalRefPtr ingredientId = getObjId(source.ingredients[i]->ingredient); + if (ingredientId == LocalRef::cms_nullPtr) + { + WARNING(true, ("Unable to convert ingredient resource network id " + "%s to a Java obj_id", source.ingredients[i]->ingredient.getValueString().c_str())); + break; + } + setObjectField(*ingredient, ms_fidDraftSchematicSimpleIngredientIngredient, + *ingredientId); + } + else + { + const Crafting::ComponentIngredient * componentData = safe_cast< + const Crafting::ComponentIngredient *>(source.ingredients[i].get()); +// TangibleObject * component = schematic.getComponent(*componentData); +// NOT_NULL(component); +// LocalRef ingredientId(getObjId(component->getNetworkId())); + LocalRefPtr componentId = getObjId(componentData->ingredient); + if (componentId == LocalRef::cms_nullPtr) + { + WARNING(true, ("Unable to convert ingredient component network id " + "%s to a Java obj_id", componentData->ingredient.getValueString().c_str())); + break; + } + setObjectField(*ingredient, ms_fidDraftSchematicSimpleIngredientIngredient, + *componentId); + setIntField(*ingredient, ms_fidDraftSchematicSimpleIngredientXpAmount, + componentData->sourceXp); + } + + // set the ingredient count + setIntField(*ingredient, ms_fidDraftSchematicSimpleIngredientCount, + source.ingredients[i]->count); + + setObjectArrayElement(*ingredients, i, *ingredient); + } + if (i != count) + { + return LocalRef::cms_nullPtr; + } + setObjectField(*slot, ms_fidDraftSchematicSlotIngredients, *ingredients); + + return slot; +} // JavaLibrary::convert(const Crafting::IngredientSlot &) + +/** + * Converts a C++ DraftSchematicObject to a Java draft_schematic. + * + * @param source the DraftSchematicObject to convert + * + * @return a new draft_schematic object + */ +jobject JavaLibrary::convert(const DraftSchematicObject & source) +{ +int i; + + LocalRefPtr target = allocObject(ms_clsDraftSchematic); + if (target == LocalRef::cms_nullPtr) + return 0; + + // set the ingredients/slots + int numSlots = source.getSlotsCount(); + LocalObjectArrayRefPtr slots = createNewObjectArray(numSlots, ms_clsDraftSchematicSlot); + if (slots == LocalObjectArrayRef::cms_nullPtr) + return 0; + + ServerDraftSchematicObjectTemplate::IngredientSlot slot; + for (i = 0; i < numSlots; ++i) + { + if (!source.getSlot(slot, i)) + { + WARNING(true, ("JavaLibrary::convert draft data: unable to get slot %d " + "from draft schematic %s", i, source.getObjectTemplateName())); + break; + } + + if (slot.options.empty()) + { + WARNING(true, ("JavaLibrary::convert draft data: slot %d in draft " + "schematic %s has no options", i, source.getObjectTemplateName())); + break; + } + if (slot.options[0].ingredients.empty()) + { + WARNING(true, ("JavaLibrary::convert draft data: slot %d in draft " + "schematic %s has no ingredients", i, source.getObjectTemplateName())); + break; + } + + JavaString appearanceName(slot.appearance); + if (appearanceName.getValue() == 0) + break; + JavaString ingredientName(slot.options[0].ingredients[0].ingredient); + if (ingredientName.getValue() == 0) + break; + LocalRefPtr slotName; + if (!ScriptConversion::convert(slot.name, slotName)) + break; + + LocalRefPtr jslot = allocObject(ms_clsDraftSchematicSlot); + if (jslot == LocalRef::cms_nullPtr) + break; + + setObjectField(*jslot, ms_fidDraftSchematicSlotName, *slotName); + setObjectField(*jslot, ms_fidDraftSchematicSlotIngredientName, ingredientName); + setObjectField(*jslot, ms_fidDraftSchematicSlotIngredients, LocalRef(0)); + setObjectField(*jslot, ms_fidDraftSchematicSlotAppearance, appearanceName); + setIntField(*jslot, ms_fidDraftSchematicSlotOption, 0); + setIntField(*jslot, ms_fidDraftSchematicSlotIngredientType, slot.options[0].ingredientType); + setIntField(*jslot, ms_fidDraftSchematicSlotAmountRequired, slot.options[0].ingredients[0].count); + setFloatField(*jslot, ms_fidDraftSchematicSlotComplexity, slot.complexity); + setObjectArrayElement(*slots, i, *jslot); + } + if (i != numSlots) + { + return 0; + } + setObjectField(*target, ms_fidDraftSchematicSlots, *slots); + + // set the attributes + int numAttributes = source.getAttribsCount(); + LocalObjectArrayRefPtr attribs = createNewObjectArray(numAttributes, JavaLibrary::getClsDraftSchematicAttrib()); + if (attribs == LocalObjectArrayRef::cms_nullPtr) + return 0; + int minValue = 0; + int maxValue = 0; + for (i = 0; i < numAttributes; ++i) + { + const SharedDraftSchematicObjectTemplate::SchematicAttribute & attrib = + source.getAttrib(i); + source.getAttribMinMax(i, minValue, maxValue); + + LocalRefPtr attribName; + if (!ScriptConversion::convert(attrib.name, attribName)) + break; + + LocalRefPtr jattrib = allocObject(JavaLibrary::getClsDraftSchematicAttrib()); + if (jattrib == LocalRef::cms_nullPtr) + break; + + setObjectField(*jattrib, JavaLibrary::getFidDraftSchematicAttribName(), *attribName); + setFloatField(*jattrib, JavaLibrary::getFidDraftSchematicAttribMinValue(), static_cast(minValue)); + setFloatField(*jattrib, JavaLibrary::getFidDraftSchematicAttribMaxValue(), static_cast(maxValue)); + setFloatField(*jattrib, JavaLibrary::getFidDraftSchematicAttribResourceMaxValue(), 0); + setFloatField(*jattrib, JavaLibrary::getFidDraftSchematicAttribCurrentValue(), 0); + setObjectArrayElement(*attribs, i, *jattrib); + } + if (i != numAttributes) + { + return 0; + } + setObjectField(*target, JavaLibrary::getFidDraftSchematicAttribs(), *attribs); + + // set the created item template crc value + const ServerObjectTemplate * craftedTemplate = source.getCraftedObjectTemplate(); + if (craftedTemplate == NULL) + { + WARNING(true, ("JavaLibrary::convert DraftSchematicObject got null crafted " + "template for draft schematic %s", source.getObjectTemplateName())); + return 0; + } + setIntField(*target, ms_fidDraftSchematicObjectTemplateCreated, craftedTemplate->getCrcName().getCrc()); + + // set the script value + const ServerDraftSchematicObjectTemplate * const sourceSchematicTemplate = + safe_cast(source.getObjectTemplate()); + NOT_NULL(sourceSchematicTemplate); + if (sourceSchematicTemplate == NULL) + { + // emergency case for release mode + return 0; + } + const int numScripts = sourceSchematicTemplate->getManufactureScriptsCount(); + LocalObjectArrayRefPtr scripts = createNewObjectArray(numScripts, JavaLibrary::getClsString()); + if (scripts == LocalObjectArrayRef::cms_nullPtr) + { + WARNING(true, ("JavaLibrary::convert DraftSchematicObject could not allocate " + "script array for draft schematic %s", source.getObjectTemplateName())); + return 0; + } + for (i = 0; i < numScripts; ++i) + { + JavaString script(sourceSchematicTemplate->getManufactureScripts(i)); + setObjectArrayElement(*scripts, i, script); + } + setObjectField(*target, ms_fidDraftSchematicScripts, *scripts); + + return target->getReturnValue(); +} // JavaLibrary::convert(const DraftSchematicObject &) + + +//======================================================================== +// class JavaLibrary JNI crafting callback methods +//======================================================================== + +/** + * Starts a crafting session. + * + * @param env Java environment + * @param self class calling this function + * @param player the player who will be crafting + * @param station the design station a player will be using + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsCraftingNamespace::startCraftingSession(JNIEnv *env, jobject self, jlong player, jlong station) +{ + UNREF(env); + UNREF(self); + + CreatureObject* playerObj = NULL; + if (!JavaLibrary::getObject(player, playerObj)) + return JNI_FALSE; + + TangibleObject* stationObj = NULL; + if (!JavaLibrary::getObject(station, stationObj)) + return JNI_FALSE; + + if (!stationObj->startCraftingSession(*playerObj)) + return JNI_FALSE; + + return JNI_TRUE; +} // JavaLibrary::startCraftingSession + +/** + * Ends a crafting session. + * + * @param env Java environment + * @param self class calling this function + * @param crafter the player that was crafting + * @param tool the crafting tool that was being used + * @param prototype the prototype that was created (may be null) + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsCraftingNamespace::endCraftingSession(JNIEnv *env, jobject self, jlong crafter, jlong tool, jlong prototype) +{ + UNREF(env); + UNREF(self); + UNREF(tool); + + // we're only do things if there's a prototype + if (prototype == 0) + return JNI_TRUE; + + CreatureObject * crafterObj = NULL; + if (!JavaLibrary::getObject(crafter, crafterObj)) + return JNI_FALSE; + + TangibleObject * prototypeObj = NULL; + if (!JavaLibrary::getObject(prototype, prototypeObj)) + return JNI_FALSE; + + // tell the crafter to create the prototype + ObserveTracker::onCraftingEndCraftingSession(*crafterObj, *prototypeObj); + + return JNI_TRUE; +} // JavaLibrary::endCraftingSession + +/** + * Sets the crafting level and station of a player's crafting session. + * + * @param env Java environment + * @param self class calling this function + * @param player the player who's crafting + * @param craftingLevel the crafting level of the session + * @param station the crafting station of the session + * + * @return true if the data was set, false on error + */ +jboolean JNICALL ScriptMethodsCraftingNamespace::setCraftingLevelAndStation(JNIEnv *env, jobject self, jlong player, jint craftingLevel, jlong station) +{ + UNREF(self); + + CreatureObject* creatureObject = NULL; + if (!JavaLibrary::getObject(player, creatureObject)) + return JNI_FALSE; + PlayerObject * playerObject = PlayerCreatureController::getPlayerObject(creatureObject); + if (playerObject == NULL) + return JNI_FALSE; + + if (craftingLevel >= 0 && craftingLevel <= Crafting::MAX_CRAFTING_LEVEL) + playerObject->setCraftingLevel(craftingLevel); + + if (station != 0) + { + const TangibleObject * stationObject = NULL; + const NetworkId stationId(station); + if (stationId != NetworkId::cms_invalid) + { + stationObject = dynamic_cast(ServerWorld::findObjectByNetworkId(stationId)); + if (stationObject == NULL) + return JNI_FALSE; + } + playerObject->setCraftingStation(stationObject); + } + + return JNI_TRUE; +} // JavaLibrary::setCraftingLevelAndStation + +/** + * Gets the crafting level of a player's crafting session. + * + * @param env Java environment + * @param self class calling this function + * @param player the player who's crafting + * + * @return the crafting level, or -1 on error + */ +jint JNICALL ScriptMethodsCraftingNamespace::getCraftingLevel(JNIEnv *env, jobject self, jlong player) +{ + UNREF(self); + + const CreatureObject* creatureObject = NULL; + if (!JavaLibrary::getObject(player, creatureObject)) + return -1; + const PlayerObject * playerObject = PlayerCreatureController::getPlayerObject(creatureObject); + if (playerObject == NULL) + return -1; + + return playerObject->getCraftingLevel(); +} // JavaLibrary::getCraftingLevel + +/** + * Gets the crafting station of a player's crafting session. + * + * @param env Java environment + * @param self class calling this function + * @param player the player who's crafting + * + * @return the crafting station, or 0 on error + */ +jlong JNICALL ScriptMethodsCraftingNamespace::getCraftingStation(JNIEnv *env, jobject self, jlong player) +{ + UNREF(self); + + const CreatureObject* creatureObject = NULL; + if (!JavaLibrary::getObject(player, creatureObject)) + return 0; + const PlayerObject * playerObject = PlayerCreatureController::getPlayerObject(creatureObject); + if (playerObject == NULL) + return 0; + + return (playerObject->getCraftingStation()).getValue(); +} // JavaLibrary::getCraftingStation + +/** + * Sends a list of draft schematics to a player that he may select to craft an item. + * + * @param env Java environment + * @param self class calling this function + * @param player the player trying to use the station + * @param schematics list of schematic template name crcs the player may use to craft an item + * + * @return true on success, false if there was an error + **/ +jboolean JNICALL ScriptMethodsCraftingNamespace::sendUseableDraftSchematics(JNIEnv *env, jobject self, jlong player, jintArray schematics) +{ + UNREF(self); + + CreatureObject* creatureObject = NULL; + if (!JavaLibrary::getObject(player, creatureObject)) + return JNI_FALSE; + PlayerObject * playerObject = PlayerCreatureController::getPlayerObject(creatureObject); + if (playerObject == NULL) + { + DEBUG_WARNING(true, ("JavaLibrary::sendUseableDraftSchematics non-player " + "object %s\n", creatureObject->getNetworkId().getValueString().c_str())); + return JNI_FALSE; + } + + int count = env->GetArrayLength(schematics); + if (count == 0) + return JNI_FALSE; + + jint * schematicsArray = env->GetIntArrayElements(schematics, NULL); + if (schematicsArray != NULL) + { + std::vector schematicCrcs(schematicsArray, &schematicsArray[count]); + playerObject->sendUseableDraftSchematics(schematicCrcs); + env->ReleaseIntArrayElements(schematics, schematicsArray, JNI_ABORT); + } + else + { + std::vector schematicCrcs; + playerObject->sendUseableDraftSchematics(schematicCrcs); + } + + return JNI_TRUE; +} // JavaLibrary::sendUseableDraftSchematics + +/** + * Sets an attribute for a manufacturing schematic. + * + * @param env Java environment + * @param self class calling this function + * @param manufacturingSchematic the schematic + * @param attribute the attribute info to set + * @param experiment flag that these are experimental attributes + * + * @return true on success, false if there was an error + */ +jboolean JNICALL ScriptMethodsCraftingNamespace::setSchematicAttribute(JNIEnv *env, jobject self, jlong manufacturingSchematic, jobject attribute, jboolean experiment) +{ + UNREF(self); + + if (manufacturingSchematic == 0 || attribute == 0) + return JNI_FALSE; + + ManufactureObjectInterface * schematic = NULL; + if (!JavaLibrary::getObject(manufacturingSchematic, schematic)) + return JNI_FALSE; + + LocalRefPtr attrName = getObjectField(LocalRefParam(attribute), JavaLibrary::getFidDraftSchematicAttribName()); + jfloat value = env->GetFloatField(attribute, JavaLibrary::getFidDraftSchematicAttribCurrentValue()); + jfloat resourceValue = env->GetFloatField(attribute, JavaLibrary::getFidDraftSchematicAttribResourceMaxValue()); + + if (attrName == LocalRef::cms_nullPtr) + return JNI_FALSE; + + StringId name; + if (!ScriptConversion::convert(*attrName, name)) + return JNI_FALSE; + + if (experiment) + { + schematic->setExperimentAttribute(name, value); + jfloat minValue = env->GetFloatField(attribute, JavaLibrary::getFidDraftSchematicAttribMinValue()); + jfloat maxValue = env->GetFloatField(attribute, JavaLibrary::getFidDraftSchematicAttribMaxValue()); + schematic->setExperimentAttributeLimits(name, minValue, maxValue, resourceValue); + } + else + { + schematic->setAttribute(name, value); + schematic->setResourceMaxAttribute(name, resourceValue); + } + return JNI_TRUE; +} // JavaLibrary::setSchematicAttribute + +/** + * Sets attributes for a manufacturing schematic. + * + * @param env Java environment + * @param self class calling this function + * @param manufacturingSchematic the schematic + * @param attributes list of attribute info to set + * @param experiment flag that these are experimental attributes + * + * @return true on success, false if there was an error + */ +jboolean JNICALL ScriptMethodsCraftingNamespace::setSchematicAttributes(JNIEnv *env, jobject self, jlong manufacturingSchematic, jobjectArray attributes, jboolean experiment) +{ + UNREF(self); + + if (manufacturingSchematic == 0 || attributes == 0) + return JNI_FALSE; + + ManufactureObjectInterface * schematic = NULL; + if (!JavaLibrary::getObject(manufacturingSchematic, schematic)) + return JNI_FALSE; + + StringId name; + int count = env->GetArrayLength(attributes); + for (int i = 0; i < count; ++i) + { + LocalRefPtr attribute = getObjectArrayElement(LocalObjectArrayRefParam(attributes), i); + if (attribute != LocalRef::cms_nullPtr) + { + LocalRefPtr attrName = getObjectField(*attribute, JavaLibrary::getFidDraftSchematicAttribName()); + jfloat value = getFloatField(*attribute, JavaLibrary::getFidDraftSchematicAttribCurrentValue()); + jfloat resourceValue = getFloatField(*attribute, JavaLibrary::getFidDraftSchematicAttribResourceMaxValue()); + + if (attrName != LocalRef::cms_nullPtr) + { + if (ScriptConversion::convert(*attrName, name)) + { + if (experiment) + { + schematic->setExperimentAttribute(name, value); + jfloat minValue = getFloatField(*attribute, JavaLibrary::getFidDraftSchematicAttribMinValue()); + jfloat maxValue = getFloatField(*attribute, JavaLibrary::getFidDraftSchematicAttribMaxValue()); + schematic->setExperimentAttributeLimits(name, + minValue, maxValue, resourceValue); + } + else + { + schematic->setAttribute(name, value); + schematic->setResourceMaxAttribute(name, resourceValue); + } + } + } + } + } + + return JNI_TRUE; +} // JavaLibrary::setSchematicAttributes + +/** + * Gets an attribute of a manufacturing schematic. + * + * @param env Java environment + * @param self class calling this function + * @param manufacturingSchematic the schematic + * @param name name of the attribute to get + * @param experiment flag that these are experimental attributes + * + * @return the attribute, or null on error + */ +jobject JNICALL ScriptMethodsCraftingNamespace::getSchematicAttribute(JNIEnv *env, jobject self, jlong manufacturingSchematic, jobject name, jboolean experiment) +{ + UNREF(self); + + if (manufacturingSchematic == 0 || name == 0) + return 0; + + ManufactureObjectInterface * schematic = NULL; + if (!JavaLibrary::getObject(manufacturingSchematic, schematic)) + return 0; + + const DraftSchematicObject * draft = DraftSchematicObject::getSchematic( + schematic->getDraftSchematic()); + if (draft == NULL) + return 0; + + StringId nameId; + if (!ScriptConversion::convert(name, nameId)) + return 0; + + if (experiment) + { + return JavaLibrary::createExperimentAttribute(*schematic, nameId)->getReturnValue(); + } + else + { + return JavaLibrary::createObjectAttribute(*schematic, *draft, draft->getAttribIndex(nameId))->getReturnValue(); + } +} // JavaLibrary::getSchematicAttribute + +/** + * Gets a select list of the attributes of a manufacturing schematic. + * + * @param env Java environment + * @param self class calling this function + * @param manufacturingSchematic the schematic + * @param names names of the attributes to get + * @param experiment flag that these are experimental attributes + * + * @return the attributes, or null on error + */ +jobjectArray JNICALL ScriptMethodsCraftingNamespace::getSchematicAttributes(JNIEnv *env, jobject self, jlong manufacturingSchematic, jobjectArray names, jboolean experiment) +{ + UNREF(self); + + if (manufacturingSchematic == 0) + return 0; + + ManufactureObjectInterface * schematic = NULL; + if (!JavaLibrary::getObject(manufacturingSchematic, schematic)) + return 0; + + const DraftSchematicObject * draft = DraftSchematicObject::getSchematic( + schematic->getDraftSchematic()); + if (draft == NULL) + return 0; + + int numAttribs = env->GetArrayLength(names); + + // create the attribute array + LocalObjectArrayRefPtr attributes = createNewObjectArray(numAttribs, JavaLibrary::getClsDraftSchematicAttrib()); + if (attributes == LocalObjectArrayRef::cms_nullPtr) + return 0; + + int i; + StringId attribName; + for (i = 0; i < numAttribs; ++i) + { + LocalRefPtr name = getObjectArrayElement(LocalObjectArrayRefParam(names), i); + if (!ScriptConversion::convert(*name, attribName)) + break; + + // create the attribute object + LocalRefPtr attribute; + if (experiment) + { + attribute = JavaLibrary::createExperimentAttribute(*schematic, attribName); + } + else + { + attribute = JavaLibrary::createObjectAttribute(*schematic, *draft, draft->getAttribIndex( + attribName)); + } + if (attribute == LocalRef::cms_nullPtr) + break; + + setObjectArrayElement(*attributes, i, *attribute); + } + + if (i != numAttribs) + { + attributes = LocalObjectArrayRef::cms_nullPtr; + } + + return attributes->getReturnValue(); +} // JavaLibrary::getSchematicAttributes + +/** + * Gets all the attributes of a manufacturing schematic. + * + * @param env Java environment + * @param self class calling this function + * @param manufacturingSchematic the schematic + * @param experiment flag that these are experimental attributes + * + * @return the attributes, or null on error + */ +jobjectArray JNICALL ScriptMethodsCraftingNamespace::getAllSchematicAttributes(JNIEnv *env, jobject self, jlong manufacturingSchematic, jboolean experiment) +{ + UNREF(env); + UNREF(self); + + if (manufacturingSchematic == 0) + return 0; + + ManufactureObjectInterface * schematic = NULL; + if (!JavaLibrary::getObject(manufacturingSchematic, schematic)) + return 0; + + const DraftSchematicObject * draft = DraftSchematicObject::getSchematic( + schematic->getDraftSchematic()); + if (draft == NULL) + return 0; + + // set the attributes + int numAttribs = 0; + const std::vector & experimentNames = schematic->getExperimentAttributeNames(); + if (experiment) + numAttribs = experimentNames.size(); + else + numAttribs = draft->getAttribsCount(); + LocalObjectArrayRefPtr attributes = createNewObjectArray(numAttribs, JavaLibrary::getClsDraftSchematicAttrib()); + if (attributes == LocalObjectArrayRef::cms_nullPtr) + return 0; + + for (int i = 0; i < numAttribs; ++i) + { + // create the attribute object + LocalRefPtr attribute; + if (experiment) + { + attribute = JavaLibrary::createExperimentAttribute(*schematic, experimentNames[i]); + } + else + { + attribute = JavaLibrary::createObjectAttribute(*schematic, *draft, i); + } + + setObjectArrayElement(*attributes, i, *attribute); + } + + return attributes->getReturnValue(); +} // JavaLibrary::getAllSchematicAttributes + +//---------------------------------------------------------------------- + +/** + * Returns a draft_schematic structure filled in with info about requested + * experimental attributes. The info will consist of the experimentation attribute + * data, the object attributes associated with them, and a mapping between the two. + * + * @param env Java environment + * @param self class calling this function + * @param manufacturingSchematic the schematic to get the data from + * @param attributeNames the experimental attributes we're interested about + * + * @return the draft_schematic object, or null on error + */ +jobject JNICALL ScriptMethodsCraftingNamespace::getSchematicForExperimentalAttributes(JNIEnv *env, jobject self, jlong manufacturingSchematic, jobjectArray attributeNames) +{ +int i; + + UNREF(self); + + if (manufacturingSchematic == 0 || attributeNames == 0) + return 0; + + const ManufactureObjectInterface * manfSchematic = NULL; + if (!JavaLibrary::getObject(manufacturingSchematic, manfSchematic)) + return 0; + + const DraftSchematicObject * draftSchematic = DraftSchematicObject::getSchematic( + manfSchematic->getDraftSchematic()); + if (draftSchematic == NULL) + return 0; + + // create a draft_schematic object to return + LocalRefPtr target = allocObject(JavaLibrary::getClsDraftSchematic()); + if (target == LocalRef::cms_nullPtr) + return 0; + + // create the experimental attributes array + int numExperimentAttribs = env->GetArrayLength(attributeNames); + LocalObjectArrayRefPtr experimentalAttribs = createNewObjectArray(numExperimentAttribs, + JavaLibrary::getClsDraftSchematicAttrib()); + if (experimentalAttribs == LocalObjectArrayRef::cms_nullPtr) + return 0; + + // create the object attributes array + int numObjectAttribs = draftSchematic->getAttribsCount(); + LocalObjectArrayRefPtr objectAttribs = createNewObjectArray(numObjectAttribs, + JavaLibrary::getClsDraftSchematicAttrib()); + if (objectAttribs == LocalObjectArrayRef::cms_nullPtr) + return 0; + + // create a map of experimental attributes to object attributes + LocalRefPtr attribMap = createNewObject(JavaLibrary::getClsHashtable(), JavaLibrary::getMidHashtable()); + if (attribMap == LocalRef::cms_nullPtr) + return 0; + + std::vector objectAttribRefs; + + // create the object attributes objects + for (i = 0; i < numObjectAttribs; ++i) + { + // create the attribute object + LocalRefPtr attribute = JavaLibrary::createObjectAttribute(*manfSchematic, *draftSchematic, i); + if (attribute == LocalRef::cms_nullPtr) + { + objectAttribRefs.clear(); + return 0; + } + + setObjectArrayElement(*objectAttribs, i, *attribute); + objectAttribRefs.push_back(attribute); + } + setObjectField(*target, JavaLibrary::getFidDraftSchematicAttribs(), *objectAttribs); + + // create the experimental attribute objects + StringId experimentAttribName; + for (i = 0; i < numExperimentAttribs; ++i) + { + // get the experimental attribute name + LocalRefPtr name = getObjectArrayElement(LocalObjectArrayRefParam(attributeNames), i); + if (name == LocalRef::cms_nullPtr) + { + objectAttribRefs.clear(); + return 0; + } + + if (!ScriptConversion::convert(*name, experimentAttribName)) + { + objectAttribRefs.clear(); + return 0; + } + + // get the data for the experimental attribute + LocalRefPtr attribute = JavaLibrary::createExperimentAttribute(*manfSchematic, + experimentAttribName); + if (attribute == LocalRef::cms_nullPtr) + { + objectAttribRefs.clear(); + return 0; + } + + setObjectArrayElement(*experimentalAttribs, i, *attribute); + + // find all the object attributes associated with this experimental + // attribute and map them to each other + LocalObjectArrayRefPtr mappedObjectAttribs = createNewObjectArray(numObjectAttribs, + JavaLibrary::getClsDraftSchematicAttrib()); + if (mappedObjectAttribs == LocalObjectArrayRef::cms_nullPtr) + { + objectAttribRefs.clear(); + return 0; + } + + int j; + int mappedObjectIndex = 0; + for (j = 0; j < numObjectAttribs; ++j) + { + if (draftSchematic->getAttribMin(j).value != draftSchematic->getAttribMax(j).value) + { + const SharedDraftSchematicObjectTemplate::SchematicAttribute & + objectAttrib = draftSchematic->getAttribMin(j); + if (objectAttrib.experiment == experimentAttribName) + { + setObjectArrayElement(*mappedObjectAttribs, mappedObjectIndex++, *objectAttribRefs[j]); + } + } + } + for (j = mappedObjectIndex; j < numObjectAttribs; ++j) + { + setObjectArrayElement(*mappedObjectAttribs, j, LocalRef(0)); + } + callObjectMethod(*attribMap, JavaLibrary::getMidMapPut(), attribute->getValue(), mappedObjectAttribs->getValue()); + } + setObjectField(*target, JavaLibrary::getFidDraftSchematicExperimentalAttribs(), *experimentalAttribs); + setObjectField(*target, JavaLibrary::getFidDraftSchematicAttribMap(), *attribMap); + + objectAttribRefs.clear(); + + return target->getReturnValue(); +} // JavaLibrary::getSchematicForExperimentalAttributes + +//---------------------------------------------------------------------- + +/** + * Sets an approximate experiment mod for an assembled schematic so the player will have some idea of + * the risk experimenting with an item. + * + * @param manufacturingSchematic the schematic + * @param experimentMod approximent mod that will be applied during experimentation + * + * @return true on success, false if there was an error + */ +jboolean JNICALL ScriptMethodsCraftingNamespace::setSchematicExperimentMod(JNIEnv *env, jobject self, jlong manufacturingSchematic, jfloat experimentMod) +{ + UNREF(self); + + ManufactureSchematicObject * schematic = NULL; + if (!JavaLibrary::getObject(manufacturingSchematic, schematic)) + return JNI_FALSE; + + schematic->setExperimentMod(experimentMod); + + return JNI_TRUE; +} // JavaLibrary::setSchematicExperimentMod + +//---------------------------------------------------------------------- + +/** + * Sets the appearances that will be available to the player during customization. + * + * @param env Java environment + * @param self class calling this function + * @param manufacturingSchematic the schematic that will create the + * customized object + * @param appearances appearance filenames that the player may choose + * + * @return JNI_TRUE on success, JNI_FALSE on error + */ +jboolean JNICALL ScriptMethodsCraftingNamespace::setSchematicAppearances(JNIEnv *env, jobject self, jlong manufacturingSchematic, jobjectArray appearances) +{ + UNREF(self); + + if (manufacturingSchematic == 0 || appearances == 0) + return JNI_FALSE; + + ManufactureSchematicObject * schematic = NULL; + if (!JavaLibrary::getObject(manufacturingSchematic, schematic)) + return JNI_FALSE; + + std::string appearance; + int count = env->GetArrayLength(appearances); + for (int i = 0; i < count; ++i) + { + JavaString appearanceString(static_cast(env->GetObjectArrayElement( + appearances, i))); + if (JavaLibrary::convert(appearanceString, appearance)) + { + schematic->addAppearance(appearance); + } + } + return JNI_TRUE; +} // JavaLibrary::setSchematicAppearances + +//---------------------------------------------------------------------- + +/** + * Sets the customization parameters that a player is allowed to change, or + * differ in their default value from the template. You do not have to set + * fixed customization parameters that use their default value. + * + * @param env Java environment + * @param self class calling this function + * @param manufacturingSchematic the schematic that will create the + * customized object + * @param customizations customization info + * + * @return JNI_TRUE on success, JNI_FALSE if there was an error + */ +jboolean JNICALL ScriptMethodsCraftingNamespace::setSchematicCustomizations(JNIEnv *env, jobject self, jlong manufacturingSchematic, jobjectArray customizations) +{ + UNREF(self); + + if (manufacturingSchematic == 0 || customizations == 0) + return JNI_FALSE; + + ManufactureSchematicObject * schematic = NULL; + if (!JavaLibrary::getObject(manufacturingSchematic, schematic)) + return JNI_FALSE; + + std::string name; + int count = env->GetArrayLength(customizations); + for (int i = 0; i < count; ++i) + { + LocalRefPtr custom = getObjectArrayElement(LocalObjectArrayRefParam(customizations), i); + if (custom == LocalRef::cms_nullPtr) + continue; + + JavaStringPtr jname = getStringField(*custom, JavaLibrary::getFidDraftSchematicCustomName()); + if (jname == JavaString::cms_nullPtr) + continue; + if (!JavaLibrary::convert(*jname, name)) + return JNI_FALSE; + + int value = getIntField(*custom, JavaLibrary::getFidDraftSchematicCustomValue()); + int minValue = getIntField(*custom, JavaLibrary::getFidDraftSchematicCustomMinValue()); + int maxValue = getIntField(*custom, JavaLibrary::getFidDraftSchematicCustomMaxValue()); + + schematic->setCustomization(name, value, minValue, maxValue); + } + + return JNI_TRUE; +} // JavaLibrary::setSchematicCustomizations + +//---------------------------------------------------------------------- + +/** + * Returns the number of items a manufacturing schematic can create. + * + * @param env Java environment + * @param self class calling this function + * @param manufacturingSchematic the schematic + * + * @return the number of items, or -1 on error + */ +jint JNICALL ScriptMethodsCraftingNamespace::getSchematicItemCount(JNIEnv *env, jobject self, jlong manufacturingSchematic) +{ + UNREF(self); + + if (manufacturingSchematic == 0) + return -1; + + const ManufactureSchematicObject * schematic = NULL; + if (!JavaLibrary::getObject(manufacturingSchematic, schematic)) + return -1; + + return schematic->getCount(); +} // JavaLibrary::getSchematicItemCount + +//---------------------------------------------------------------------- + +/** + * Sets the number of items a manufacturing schematic can create. + * + * @param env Java environment + * @param self class calling this function + * @param manufacturingSchematic the schematic + * @param count the number of items + * + * @return true on success, false if there was an error + */ +jboolean JNICALL ScriptMethodsCraftingNamespace::setSchematicItemCount(JNIEnv *env, jobject self, jlong manufacturingSchematic, jint count) +{ + UNREF(self); + + if (manufacturingSchematic == 0) + return JNI_FALSE; + + ManufactureSchematicObject * schematic = NULL; + if (!JavaLibrary::getObject(manufacturingSchematic, schematic)) + return JNI_FALSE; + + schematic->setCount(count); + return JNI_TRUE; +} // JavaLibrary::setSchematicItemCount + +//---------------------------------------------------------------------- + +/** + * Returns the numer of items per container a manufacturing schematic will + * create. + * + * @param env Java environment + * @param self class calling this function + * @param manufacturingSchematic the schematic + * + * @return the number of items, or -1 on error + */ +jint JNICALL ScriptMethodsCraftingNamespace::getSchematicItemsPerContainer(JNIEnv *env, jobject self, jlong manufacturingSchematic) +{ + UNREF(self); + + if (manufacturingSchematic == 0) + return -1; + + const ManufactureSchematicObject * schematic = NULL; + if (!JavaLibrary::getObject(manufacturingSchematic, schematic)) + return -1; + + return schematic->getItemsPerContainer(); +} // JavaLibrary::getSchematicItemsPerContainer + +//---------------------------------------------------------------------- + +/** + * Sets the numer of items per container a manufacturing schematic will + * create. + * + * @param env Java environment + * @param self class calling this function + * @param manufacturingSchematic the schematic + * @param count the number of items + * + * @return true on success, false if there was an error + */ +jboolean JNICALL ScriptMethodsCraftingNamespace::setSchematicItemsPerContainer(JNIEnv *env, jobject self, jlong manufacturingSchematic, jint count) +{ + UNREF(self); + + if (manufacturingSchematic == 0) + return JNI_FALSE; + + ManufactureSchematicObject * schematic = NULL; + if (!JavaLibrary::getObject(manufacturingSchematic, schematic)) + return JNI_FALSE; + + schematic->setItemsPerContainer(count); + return JNI_TRUE; +} // JavaLibrary::setSchematicItemsPerContainer + +//---------------------------------------------------------------------- + +/** + * Returns the time per complexity point it takes to manufacture an item with + * a manufacturing schematic. + * + * @param env Java environment + * @param self class calling this function + * @param manufacturingSchematic the schematic + * + * @return the time, or -1 on error + */ +jfloat JNICALL ScriptMethodsCraftingNamespace::getSchematicManufactureTime(JNIEnv *env, jobject self, jlong manufacturingSchematic) +{ + UNREF(self); + + if (manufacturingSchematic == 0) + return -1.0f; + + const ManufactureSchematicObject * schematic = NULL; + if (!JavaLibrary::getObject(manufacturingSchematic, schematic)) + return -1.0f; + + return schematic->getManufactureTime(); +} // JavaLibrary::getSchematicManufactureTime + +//---------------------------------------------------------------------- + +/** + * Sets the time per complexity point it takes to manufacture an item with + * a manufacturing schematic. + * + * @param env Java environment + * @param self class calling this function + * @param manufacturingSchematic the schematic + * @param time the manufacturing time per complexity + * + * @return true on success, false if there was an error + */ +jboolean JNICALL ScriptMethodsCraftingNamespace::setSchematicManufactureTime(JNIEnv *env, jobject self, jlong manufacturingSchematic, jfloat time) +{ + UNREF(self); + + if (manufacturingSchematic == 0) + return JNI_FALSE; + + ManufactureSchematicObject * schematic = NULL; + if (!JavaLibrary::getObject(manufacturingSchematic, schematic)) + return JNI_FALSE; + + schematic->setManufactureTime(time); + return JNI_TRUE; +} // JavaLibrary::setSchematicManufactureTime + +//---------------------------------------------------------------------- + +/** + * Sets the amount of xp the creator of an object will get when an object is "used". + * + * @param env Java environment + * @param self class calling this function + * @param object the object that will grant the xp + * @param xp the amount of xp to grant + * + * @return true on success, false if there was an error + */ +jboolean JNICALL ScriptMethodsCraftingNamespace::setCreatorXp(JNIEnv *env, jobject self, jlong object, jint xp) +{ + UNREF(self); + + TangibleObject * target = NULL; + if (!JavaLibrary::getObject(object, target)) + return JNI_FALSE; + + target->setCreatorXp(xp); + return JNI_TRUE; +} // JavaLibrary::setCreatorXp + +/** + * Gets a list of ingredients needed to craft using the current manufacturing + * schematic in a manufacturing station. + * + * @param env Java environment + * @param self class calling this function + * @param station the manufacturing station id + * @param ingredients array to be filled in with a string array of ingredients + */ +void JNICALL ScriptMethodsCraftingNamespace::getIngredientsForManufactureStation(JNIEnv *env, jobject self, jlong station, jobjectArray ingredients) +{ + UNREF(self); + + if (station == 0 || ingredients == 0) + return; + + const ManufactureInstallationObject * manfStation = NULL; + if (!JavaLibrary::getObject(station, manfStation)) + return; + + if (env->GetArrayLength(ingredients) != 1) + return; + + const ManufactureSchematicObject * const schematic = manfStation->getSchematic(); + if (schematic == NULL) + return; + + static ManufactureSchematicObject::IngredientInfoVector iiv; + iiv.clear (); + + schematic->getIngredientInfo (iiv); + + if (iiv.empty ()) + return; + + const size_t count = iiv.size(); + + LocalObjectArrayRefPtr ingredientList = createNewObjectArray(count, JavaLibrary::getClsString()); + if (ingredientList == LocalObjectArrayRef::cms_nullPtr) + return; + + char buf [128]; + const size_t buf_size = sizeof (buf); + + for (size_t i = 0; i < count; ++i) + { + const ManufactureSchematicObject::IngredientInfo & info = iiv [i]; + + const Unicode::String & name = info.first; + const int numPerItem = info.second.second; + + if (name.empty ()) + continue; + + snprintf (buf, buf_size, ":\\>200%d", numPerItem); + + Unicode::String element = name; + + if (name [0] == '@') + element.push_back ('\0'); + + element += Unicode::narrowToWide (buf); + + JavaString jelement(element); + setObjectArrayElement(*ingredientList, i, jelement); + } + + setObjectArrayElement(LocalObjectArrayRefParam(ingredients), 0, *ingredientList); +} // JavaLibrary::getIngredientsForManufactureStation + +//---------------------------------------------------------------------- + +/** + * Gets the id of a manufacture station's input hopper. + * + * @param env Java environment + * @param self class calling this function + * @param station the station id + * + * @return the hopper id, or null on error + */ +jlong JNICALL ScriptMethodsCraftingNamespace::getManufactureStationInputHopper(JNIEnv *env, jobject self, jlong station) +{ + UNREF(self); + + if (station == 0) + return 0; + + const ManufactureInstallationObject * manfStation = NULL; + if (!JavaLibrary::getObject(station, manfStation)) + return 0; + + ServerObject * hopper = manfStation->getInputHopper(); + if (hopper == NULL) + return 0; + + return (hopper->getNetworkId()).getValue(); +} // JavaLibrary::getManufactureStationInputHopper + +//---------------------------------------------------------------------- + +/** + * Gets the id of a manufacture station's output hopper. + * + * @param env Java environment + * @param self class calling this function + * @param station the station id + * + * @return the hopper id, or null on error + */ +jlong JNICALL ScriptMethodsCraftingNamespace::getManufactureStationOutputHopper(JNIEnv *env, jobject self, jlong station) +{ + UNREF(self); + + if (station == 0) + return 0; + + const ManufactureInstallationObject * manfStation = NULL; + if (!JavaLibrary::getObject(station, manfStation)) + return 0; + + ServerObject * hopper = manfStation->getOutputHopper(); + if (hopper == NULL) + return 0; + + return (hopper->getNetworkId()).getValue(); +} // JavaLibrary::getManufactureStationOutputHopper + +//---------------------------------------------------------------------- + +/** + * Gets the id and name of the schematic in a manufacture station. + * + * @param env Java environment + * @param self class calling this function + * @param station the station id + * + * @return a string of the form "*" , or null if the station has no schematic + */ +jstring JNICALL ScriptMethodsCraftingNamespace::getManufactureStationSchematic(JNIEnv *env, jobject self, jlong station) +{ + static const Unicode::String SEPARATOR(Unicode::narrowToWide("*")); + + UNREF(self); + + const ManufactureInstallationObject * manfStation = NULL; + if (!JavaLibrary::getObject(station, manfStation)) + return 0; + + const ManufactureSchematicObject * manfSchematic = manfStation->getSchematic(); + if (manfSchematic == NULL) + return 0; + + return JavaString( + Unicode::narrowToWide(manfSchematic->getNetworkId().getValueString()) + + SEPARATOR + + manfSchematic->getObjectName() + ).getReturnValue(); +} // JavaLibrary::getManufactureStationSchematic + +//---------------------------------------------------------------------- + +/** + * Gets a list of manufacture schematics that could be used at a given manufacturing + * station. + * + * @param env Java environment + * @param self class calling this function + * @param player the player whose schematics to get + * @param station the manufacturing station + * @param schematics array to be filled in with a string array of schematics + */ +void JNICALL ScriptMethodsCraftingNamespace::getValidManufactureSchematicsForStation(JNIEnv *env, jobject self, jlong player, jlong station, jobjectArray schematics) +{ + static const Unicode::String SEPARATOR(Unicode::narrowToWide("*")); + + UNREF(self); + + if (player == 0 || station == 0 || schematics == 0) + return; + + CreatureObject * playerCreature = NULL; + if (!JavaLibrary::getObject(player, playerCreature)) + return; + + const ManufactureInstallationObject * manfStation = NULL; + if (!JavaLibrary::getObject(station, manfStation)) + return; + + if (env->GetArrayLength(schematics) != 1) + return; + + std::vector manfSchematics; + uint32 stationTypes = manfStation->getValidSchematicTypes(); + playerCreature->getManufactureSchematics(manfSchematics, stationTypes); + + int count = manfSchematics.size(); + LocalObjectArrayRefPtr schematicList = createNewObjectArray(count, JavaLibrary::getClsString()); + if (schematicList == LocalObjectArrayRef::cms_nullPtr) + return; + + for (int i = 0; i < count; ++i) + { + const ManufactureSchematicObject * manfSchematic = manfSchematics[i]; + setObjectArrayElement(*schematicList, i, + JavaString( + Unicode::narrowToWide(manfSchematic->getNetworkId().getValueString()) + + SEPARATOR + + manfSchematic->getObjectName() + )); + } + + setObjectArrayElement(LocalObjectArrayRefParam(schematics), 0, *schematicList); +} // JavaLibrary::getValidManufactureSchematicsForStation + +//---------------------------------------------------------------------- + +/** + * Checks if a player has any manufacture schematics that could be used at a + * given manufacturing station. + * + * @param env Java environment + * @param self class calling this function + * @param player the player whose schematics to check + * @param station the manufacturing station + * + * @return true if the player has any schematics, false if not + */ +jboolean JNICALL ScriptMethodsCraftingNamespace::hasValidManufactureSchematicsForStation(JNIEnv *env, jobject self, jlong player, jlong station) +{ + static const Unicode::String SEPARATOR(Unicode::narrowToWide("*")); + + UNREF(self); + + if (player == 0 || station == 0) + return JNI_FALSE; + + CreatureObject * playerCreature = NULL; + if (!JavaLibrary::getObject(player, playerCreature)) + return JNI_FALSE; + + const ManufactureInstallationObject * manfStation = NULL; + if (!JavaLibrary::getObject(station, manfStation)) + return JNI_FALSE; + + std::vector manfSchematics; + playerCreature->getManufactureSchematics(manfSchematics, + manfStation->getValidSchematicTypes()); + + if (manfSchematics.empty()) + return JNI_FALSE; + return JNI_TRUE; +} // JavaLibrary::hasValidManufactureSchematicsForStation + +//---------------------------------------------------------------------- + +/** + * Transfers the manufacture schematic in a manufacturing station to a player. + * + * @param env Java environment + * @param self class calling this function + * @param station the manufacturing station id + * @param player the the player to transfer to + * + * @return true if the schematic was transferred, false if not + */ +jboolean JNICALL ScriptMethodsCraftingNamespace::transferManufactureSchematicToPlayer(JNIEnv *env, jobject self, jlong station, jlong player) +{ + UNREF(self); + + const ManufactureInstallationObject * manfStation = NULL; + if (!JavaLibrary::getObject(station, manfStation)) + return JNI_FALSE; + + ManufactureSchematicObject * schematic = manfStation->getSchematic(); + if (schematic == NULL) + return JNI_TRUE; + + CreatureObject * playerCreature = NULL; + if (!JavaLibrary::getObject(player, playerCreature)) + return JNI_FALSE; + + ServerObject * datapad = playerCreature->getDatapad(); + if (datapad == NULL) + return JNI_FALSE; + + Container::ContainerErrorCode tmp = Container::CEC_Success; + if (ContainerInterface::transferItemToVolumeContainer(*datapad, *schematic, NULL, tmp)) + return JNI_TRUE; + return JNI_FALSE; +} // JavaLibrary::transferManufactureSchematicToPlayer + +//---------------------------------------------------------------------- + +/** + * Transfers a manufacture schematic to a manufacturing station. + * + * @param env Java environment + * @param self class calling this function + * @param schematic the schematic id + * @param station the manufacturing station id + * + * @return true if the schematic was transferred, false if not + */ +jboolean JNICALL ScriptMethodsCraftingNamespace::transferManufactureSchematicToStation(JNIEnv *env, jobject self, jlong schematic, jlong station) +{ + UNREF(self); + + ManufactureSchematicObject * manfSchematic = NULL; + if (!JavaLibrary::getObject(schematic, manfSchematic)) + return JNI_FALSE; + + ManufactureInstallationObject * manfStation = NULL; + if (!JavaLibrary::getObject(station, manfStation)) + return JNI_FALSE; + + if (manfStation->addSchematic(*manfSchematic, NULL)) + return JNI_TRUE; + return JNI_FALSE; +} // JavaLibrary::transferManufactureSchematicToStation + +//---------------------------------------------------------------------- + +/** + * Gets a list of objects that can be repaired by a given repair tool. + * + * @param env Java environment + * @param self class calling this function + * @param player the player whose objects to get + * @param tool the repair tool + * @param objects array to be filled in with a string array of objects + */ +void JNICALL ScriptMethodsCraftingNamespace::getRepairableObjectsForTool(JNIEnv *env, jobject self, jlong player, jlong tool, jobjectArray objects) +{ + static const Unicode::String SEPARATOR(Unicode::narrowToWide("*")); + + if (player == 0 || tool == 0 || objects == 0) + return; + + CreatureObject * playerCreature = NULL; + if (!JavaLibrary::getObject(player, playerCreature)) + return; + + const TangibleObject * toolObject = NULL; + if (!JavaLibrary::getObject(tool, toolObject)) + return; + if (!toolObject->isRepairTool()) + return; + int toolType = toolObject->getCraftingType(); + + // determine if the repair tool repairs a specific GOT or a category + bool genericTool = false; + if ((toolType & 0x000000ff) == 0) + genericTool = true; + + if (env->GetArrayLength(objects) != 1) + return; + + // @todo: we need to get a list of things the player owns that are loaded, + // so non-inventory objects can be repaired. For now, just repair inventory + // objects + + const ServerObject * inventory = playerCreature->getInventory(); + if (inventory == NULL) + return; + + const VolumeContainer * inventoryContainer = ContainerInterface::getVolumeContainer(*inventory); + if (inventoryContainer == NULL) + return; + + std::vector objList; + for (ContainerConstIterator iter(inventoryContainer->begin()); + iter != inventoryContainer->end(); ++iter) + { + const CachedNetworkId & objId = (*iter); + const TangibleObject * obj = safe_cast(objId.getObject()); + if (obj != NULL && !obj->isCraftingTool() && !obj->isRepairTool() && + obj->getDamageTaken() > 0) + { + if ((genericTool && (toolType & obj->getGameObjectType()) != 0) || + (!genericTool && toolType == obj->getGameObjectType())) + { + objList.push_back( + Unicode::narrowToWide(obj->getNetworkId().getValueString()) + + SEPARATOR + + obj->getEncodedObjectName ()); + } + } + } + + int count = objList.size(); + LocalObjectArrayRefPtr objectStringList = createNewObjectArray(count, JavaLibrary::getClsString()); + if (objectStringList == LocalObjectArrayRef::cms_nullPtr) + return; + + for (int i = 0; i < count; ++i) + { + setObjectArrayElement(*objectStringList, i, JavaString(objList[i])); + } + + setObjectArrayElement(LocalObjectArrayRefParam(objects), 0, *objectStringList); +} // JavaLibrary::getRepairableObjectsForTool + +//---------------------------------------------------------------------- + +/** + * Returns the attribute bonuses an object grants when equipped. + * + * @param env Java environment + * @param self class calling this function + * @param target the object + * + * @return an array with the bonus for each attribute, or null on error + */ +jintArray JNICALL ScriptMethodsCraftingNamespace::getAttributeBonuses(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + const ServerObject * object = NULL; + if (!JavaLibrary::getObject(target, object)) + return 0; + + std::vector > bonuses; + if (object->asTangibleObject() != NULL) + { + object->asTangibleObject()->getAttribBonuses(bonuses); + } + else if (object->asManufactureSchematicObject() != NULL) + { + object->asManufactureSchematicObject()->getAttribBonuses(bonuses); + } + else + return 0; + + jint bonusesArray[Attributes::NumberOfAttributes]; + { + for (int i = 0; i < Attributes::NumberOfAttributes; ++i) + bonusesArray[i] = 0; + } + { + for (std::vector >::const_iterator i = bonuses.begin(); + i != bonuses.end(); ++i) + { + if ((*i).first >= 0 && (*i).first < Attributes::NumberOfAttributes) + bonusesArray[(*i).first] = (*i).second; + } + } + + LocalIntArrayRefPtr jbonuses = createNewIntArray(Attributes::NumberOfAttributes); + if (jbonuses == LocalIntArrayRef::cms_nullPtr) + return 0; + + setIntArrayRegion(*jbonuses, 0, Attributes::NumberOfAttributes, &bonusesArray[0]); + return jbonuses->getReturnValue(); +} // JavaLibrary::getAttributeBonuses + +//---------------------------------------------------------------------- + +/** + * Returns the attribute bonus of an object for a given attribute. + * + * @param env Java environment + * @param self class calling this function + * @param target the object + * @param attribute the attribute to get + * + * @return the attribute bonus + */ +jint JNICALL ScriptMethodsCraftingNamespace::getAttributeBonus(JNIEnv *env, jobject self, jlong target, jint attribute) +{ + UNREF(self); + + if (attribute < 0 || attribute >= Attributes::NumberOfAttributes) + return 0; + + const ServerObject * object = NULL; + if (!JavaLibrary::getObject(target, object)) + return 0; + + jint bonus = 0; + if (object->asTangibleObject() != NULL) + { + bonus = object->asTangibleObject()->getAttribBonus(attribute); + } + else if (object->asManufactureSchematicObject() != NULL) + { + bonus = object->asManufactureSchematicObject()->getAttribBonus(attribute); + } + return bonus; +} // JavaLibrary::getAttributeBonus + +//---------------------------------------------------------------------- + +/** + * Sets the attribute bonus an object applies when equipped. + * + * @param env Java environment + * @param self class calling this function + * @param target the object + * @param attribute the attribute to set + * @param bonus the attribute bonus value + * + * @return true on success, false on error + */ +jboolean JNICALL ScriptMethodsCraftingNamespace::setAttributeBonus(JNIEnv *env, jobject self, jlong target, jint attribute, jint bonus) +{ + UNREF(self); + + if (attribute < 0 || attribute >= Attributes::NumberOfAttributes) + return JNI_FALSE; + + ServerObject * object = NULL; + if (!JavaLibrary::getObject(target, object)) + return JNI_FALSE; + + if (object->asTangibleObject() != NULL) + { + object->asTangibleObject()->setAttribBonus(attribute, bonus); + } + else if (object->asManufactureSchematicObject() != NULL) + { + object->asManufactureSchematicObject()->setAttribBonus(attribute, bonus); + } + else + return JNI_FALSE; + return JNI_TRUE; +} // JavaLibrary::setAttributeBonus + +//---------------------------------------------------------------------- + +/** + * Sets the attribute bonuses an object applies when equipped. + * + * @param env Java environment + * @param self class calling this function + * @param target the object + * @param bonuses the attribute bonus values + * + * @return true on success, false on error + */ +jboolean JNICALL ScriptMethodsCraftingNamespace::setAttributeBonuses(JNIEnv *env, jobject self, jlong target, jintArray bonuses) +{ + UNREF(self); + + if (bonuses == 0) + return JNI_FALSE; + + ServerObject * object = NULL; + if (!JavaLibrary::getObject(target, object)) + return JNI_FALSE; + + jsize count = env->GetArrayLength(bonuses); + if (count != Attributes::NumberOfAttributes) + { + WARNING(true, ("JavaLibrary::setAttributeBonuses passed bad array of " + "size %u", count)); + return JNI_FALSE; + } + + jint buffer[Attributes::NumberOfAttributes]; + env->GetIntArrayRegion(bonuses, 0, count, buffer); + + if (object->asTangibleObject() != NULL) + { + TangibleObject * tangibleObject = object->asTangibleObject(); + for (jsize i = 0; i < count; ++i) + tangibleObject->setAttribBonus(i, buffer[i]); + } + else if (object->asManufactureSchematicObject() != NULL) + { + ManufactureSchematicObject * manufactureSchematicObject = object->asManufactureSchematicObject(); + for (jsize i = 0; i < count; ++i) + manufactureSchematicObject->setAttribBonus(i, buffer[i]); + } + else + return JNI_FALSE; + + return JNI_TRUE; +} // JavaLibrary::setAttributeBonus + +//---------------------------------------------------------------------- + +/** + * Returns the skill mod bonuses an object grants when equipped. + * + * @param env Java environment + * @param self class calling this function + * @param target the object + * + * @return a dictionary of skill mod names -> mod values, or null on error + */ +jobject JNICALL ScriptMethodsCraftingNamespace::getSkillModBonuses(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + const TangibleObject * object = NULL; + if (!JavaLibrary::getObject(target, object)) + return 0; + + std::vector > skillModBonuses; + object->getSkillModBonuses(skillModBonuses); + + // put the bonuses into ScriptParams, and then convert to a dictionary + ScriptParams params; + int count = skillModBonuses.size(); + for (int i = 0; i < count; ++i) + { + params.addParam(skillModBonuses[i].second, skillModBonuses[i].first); + } + JavaDictionaryPtr dictionary; + JavaLibrary::instance()->convert(params, dictionary); + + return dictionary->getReturnValue(); +} // JavaLibrary::getSkillModBonuses + +//---------------------------------------------------------------------- + +/** + * Returns the skill mod bonus of an object for a given skill mod. + * + * @param env Java environment + * @param self class calling this function + * @param target the object + * @param skillMod the skill mod to get + * + * @return the skill mod value + */ +jint JNICALL ScriptMethodsCraftingNamespace::getSkillModBonus(JNIEnv *env, jobject self, jlong target, jstring skillMod) +{ + UNREF(self); + + JavaStringParam jskillMod(skillMod); + + const TangibleObject * object = NULL; + if (!JavaLibrary::getObject(target, object)) + return 0; + + std::string skillModName; + if (!JavaLibrary::convert(jskillMod, skillModName)) + return 0; + + return object->getSkillModBonus(skillModName); +} // JavaLibrary::getSkillModBonus + +//---------------------------------------------------------------------- + +/** + * Sets the base skill mod bonus an object applies when equipped. + * + * @param env Java environment + * @param self class calling this function + * @param target the object + * @param skillMod the skill mod to set + * @param bonus the skill mod bonus value + * + * @return true on success, false on error + */ +jboolean JNICALL ScriptMethodsCraftingNamespace::setSkillModBonus(JNIEnv *env, jobject self, jlong target, jstring skillMod, jint bonus) +{ + UNREF(self); + + JavaStringParam jskillMod(skillMod); + + TangibleObject * object = NULL; + if (!JavaLibrary::getObject(target, object)) + return JNI_FALSE; + + std::string skillModName; + if (!JavaLibrary::convert(jskillMod, skillModName)) + return JNI_FALSE; + + object->setSkillModBonus(skillModName, bonus); + return JNI_TRUE; +} // JavaLibrary::setSkillModBonus + +//---------------------------------------------------------------------- + +/** + * Sets the base skill mod bonuses an object applies when equipped. + * + * @param env Java environment + * @param self class calling this function + * @param target the object + * @param skillMod the skill mods to set + * @param bonus the skill mod bonus values + * + * @return true on success, false on error + */ +jboolean JNICALL ScriptMethodsCraftingNamespace::setSkillModBonuses(JNIEnv *env, jobject self, jlong target, jobjectArray skillMod, jintArray bonus) +{ + UNREF(self); + + TangibleObject * object = NULL; + if (!JavaLibrary::getObject(target, object)) + return JNI_FALSE; + + if (skillMod == 0 || bonus == 0) + return JNI_FALSE; + + int skillModCount = env->GetArrayLength(skillMod); + int bonusCount = env->GetArrayLength(bonus); + if (skillModCount != bonusCount) + { + DEBUG_WARNING(true, ("[designer bug] setSkillModBonuses called with unequal " + "array sizes")); + return JNI_FALSE; + } + + std::string skillName; + const jint * bonusArray = env->GetIntArrayElements(bonus, NULL); + for (int i = 0; i < skillModCount; ++i) + { + JavaStringParam jskillName(static_cast(env->GetObjectArrayElement(skillMod, i))); + JavaLibrary::convert(jskillName, skillName); + object->setSkillModBonus(skillName, bonusArray[i]); + } + env->ReleaseIntArrayElements(bonus, const_cast(bonusArray), JNI_ABORT); + + return JNI_TRUE; +} // JavaLibrary::setSkillModBonuses + +//---------------------------------------------------------------------- + +/** +* Sets the base skill mod bonus an object applies when equipped. +* +* @param env Java environment +* @param self class calling this function +* @param target the object +* @param category the category of the skill mod bonus +* multiple/independent bonuses can be granted +* for a particular skill mod by putting them +* into different categories +* @param skillMod the skill mod to set +* @param bonus the skill mod bonus value +* +* @return true on success, false on error +*/ +jboolean JNICALL ScriptMethodsCraftingNamespace::setCategorizedSkillModBonus(JNIEnv *env, jobject self, jlong target, jstring category, jstring skillMod, jint bonus) +{ + UNREF(self); + + JavaStringParam jcategory(category); + JavaStringParam jskillMod(skillMod); + + TangibleObject * object = NULL; + if (!JavaLibrary::getObject(target, object)) + return JNI_FALSE; + + std::string categoryName; + if (!JavaLibrary::convert(jcategory, categoryName)) + return JNI_FALSE; + + std::string skillModName; + if (!JavaLibrary::convert(jskillMod, skillModName)) + return JNI_FALSE; + + object->setSkillModBonus(categoryName, skillModName, bonus); + return JNI_TRUE; +} + +//---------------------------------------------------------------------- + +/** +* Removes all skill mod bonuses in a particular category on an object. +* +* @param env Java environment +* @param self class calling this function +* @param target the object +* @param category the category of the skill mod bonus +* multiple/independent bonuses can be granted +* for a particular skill mod by putting them +* into different categories +*/ +void JNICALL ScriptMethodsCraftingNamespace::removeCategorizedSkillModBonuses(JNIEnv *env, jobject self, jlong target, jstring category) +{ + UNREF(self); + + JavaStringParam jcategory(category); + + TangibleObject * object = NULL; + if (!JavaLibrary::getObject(target, object)) + return; + + std::string categoryName; + if (!JavaLibrary::convert(jcategory, categoryName)) + return; + + object->removeCategorizedSkillModBonuses(categoryName); +} + +//---------------------------------------------------------------------- + +/** + * Returns the number of available skill mod sockets of an object. + * + * @param env Java environment + * @param self class calling this function + * @param target the object + * + * @return the number of sockets + */ +jint JNICALL ScriptMethodsCraftingNamespace::getSkillModSockets(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + const TangibleObject * object = NULL; + if (!JavaLibrary::getObject(target, object)) + return 0; + + return object->getSkillModSockets(); +} // JavaLibrary::getSkillModSockets + +//---------------------------------------------------------------------- + +/** + * Sets the number of available skill mod sockets for an object. + * + * @param env Java environment + * @param self class calling this function + * @param target the object + * @param sockets the number of sockets + * + * @return true on success, false on error + */ +jboolean JNICALL ScriptMethodsCraftingNamespace::setSkillModSockets(JNIEnv *env, jobject self, jlong target, jint sockets) +{ + UNREF(self); + + TangibleObject * object = NULL; + if (!JavaLibrary::getObject(target, object)) + return JNI_FALSE; + + object->setSkillModSockets(sockets); + return JNI_TRUE; +} // JavaLibrary::setSkillModSockets + +//---------------------------------------------------------------------- + +/** + * Creates a new item based on a draft schematic. The item will have stats + * based on a % value passed in (0 = worst possible stats, 100 = best possible + * stats). + * + * @param env Java environment + * @param self class calling this function + * @param draftSchematic draft schematic to make the object from + * @param qualityPercent % stat adjustment + * @param container the container to create the item in + * + * @return the item, or null on error + */ +jlong JNICALL ScriptMethodsCraftingNamespace::makeCraftedItem(JNIEnv *env, jobject self, jstring draftSchematic, jfloat qualityPercent, jlong container) +{ + UNREF(self); + + if (draftSchematic == 0 || container == 0) + { + WARNING(true, ("[script bug] null schematic or container passed to " + "makeCraftedItem")); + return 0; + } + + JavaStringParam jDraftSchematic(draftSchematic); + std::string draftSchematicName; + if (!JavaLibrary::convert(jDraftSchematic, draftSchematicName)) + { + WARNING(true, ("JavaLibrary::makeCraftedItem can't convert schematic " + "name to string")); + return 0; + } + + const DraftSchematicObject * schematic = DraftSchematicObject::getSchematic( + draftSchematicName); + if (schematic == NULL) + { + WARNING(true, ("[script bug] bad schematic name %s passed to " + "makeCraftedItem", draftSchematicName.c_str())); + return 0; + } + + ServerObject * target = NULL; + if (!JavaLibrary::getObject(container, target)) + { + WARNING(true, ("[script bug] bad container id passed to makeCraftedItem")); + return 0; + } + Object * targetParent = ContainerInterface::getFirstParentInWorld(*target); + if (targetParent == NULL) + { + WARNING(true, ("JavaLibrary::makeCraftedItem can't find parent in world " + "for container %s", target->getNetworkId().getValueString().c_str())); + return 0; + } + Vector createPos(targetParent->getPosition_w()); + createPos.y = -100000.0f; + + // create a manf schematic and prototype + ManufactureSchematicObject * manfSchematic = ServerWorld::createNewManufacturingSchematic( + *schematic, createPos, false); + if (manfSchematic == NULL) + { + WARNING(true, ("JavaLibrary::makeCraftedItem: error creating manf " + "schematic!")); + return 0; + } + ServerObject * prototype = manfSchematic->manufactureObject(createPos); + if (prototype == NULL) + { + WARNING(true, ("JavaLibrary::makeCraftedItem: error creating " + "prototype!")); + manfSchematic->permanentlyDestroy(DeleteReasons::SetupFailed); + return false; + } + + if (qualityPercent < 0.0f) + qualityPercent = 0.0f; + else if (qualityPercent > 100.0f) + qualityPercent = 100.0f; + + ScriptParams params; + params.addParam(prototype->getNetworkId()); + params.addParam(*manfSchematic); + params.addParam(qualityPercent); + IGNORE_RETURN(manfSchematic->getScriptObject()->trigAllScripts( + Scripting::TRIG_MAKE_CRAFTED_ITEM, params)); + + manfSchematic->permanentlyDestroy(DeleteReasons::Consumed); + Container::ContainerErrorCode error; + if (!ContainerInterface::transferItemToVolumeContainer (*target, *prototype, + NULL, error, true)) + { + WARNING(true, ("JavaLibrary::makeCraftedItem: error can't store prototype " + "in container, error = %d", error)); + prototype->permanentlyDestroy(DeleteReasons::BadContainerTransfer); + return 0; + } + + return (prototype->getNetworkId()).getValue(); +} // JavaLibrary::makeCraftedItem + +//---------------------------------------------------------------------- + +/** + * Returns a draft_schematic structure filled in with info used by a manufacturing + * schematic. + * + * @param env Java environment + * @param self class calling this function + * @param manufacturingSchematic the schematic to get the data from + * + * @return the draft_schematic object, or null on error + */ +jobject JNICALL ScriptMethodsCraftingNamespace::getSchematicData(JNIEnv *env, jobject self, jlong manufacturingSchematic) +{ + if (manufacturingSchematic == 0) + return 0; + + const ManufactureSchematicObject * schematicObject = NULL; + if (!JavaLibrary::getObject(manufacturingSchematic, schematicObject)) + return 0; + + return JavaLibrary::convert(*schematicObject)->getReturnValue(); +} // JavaLibrary::getSchematicData + +//---------------------------------------------------------------------- + +/** + * Returns a draft_schematic structure filled in with info used by a draft + * schematic. + * + * @param env Java environment + * @param self class calling this function + * @param draftSchematic the schematic to get the data from + * + * @return the draft_schematic object, or null on error + */ +jobject JNICALL ScriptMethodsCraftingNamespace::getDraftSchematicData(JNIEnv *env, jobject self, + jstring draftSchematic) +{ + if (draftSchematic == 0) + return 0; + + JavaStringParam jdraftSchematic(draftSchematic); + std::string schematicName; + if (!JavaLibrary::convert(jdraftSchematic, schematicName)) + return 0; + + const DraftSchematicObject * schematicObject = DraftSchematicObject::getSchematic(schematicName); + if (schematicObject == NULL) + return 0; + + return JavaLibrary::convert(*schematicObject); +} // JavaLibrary::getSchematicData + +//---------------------------------------------------------------------- + +/** + * Returns a draft_schematic structure filled in with info used by a draft + * schematic. + * + * @param env Java environment + * @param self class calling this function + * @param draftSchematicCrc the schematic to get the data from + * + * @return the draft_schematic object, or null on error + */ +jobject JNICALL ScriptMethodsCraftingNamespace::getDraftSchematicDataCrc(JNIEnv *env, jobject self, + jint draftSchematicCrc) +{ + if (draftSchematicCrc == 0) + return 0; + + const DraftSchematicObject * schematicObject = DraftSchematicObject::getSchematic(draftSchematicCrc); + if (schematicObject == NULL) + return 0; + + return JavaLibrary::convert(*schematicObject); +} // JavaLibrary::getSchematicDataCrc + +//---------------------------------------------------------------------- + +/** + * Causes the stats of a crate of manufactured objects to get recomputed from the + * crate's objvars. + * IMPORTANT: This only affects the stats of new objects that get pulled out of the + * crate! It is up to the caller to modify the "examine" item stored in the crate. + * + * @param env Java environment + * @param self class calling this function + * @param crate the crate to recompute the stats of + */ +void JNICALL ScriptMethodsCraftingNamespace::recomputeCrateAttributes(JNIEnv *env, jobject self, jlong crate) +{ + FactoryObject * factory = NULL; + if (!JavaLibrary::getObject(crate, factory)) + return; + + factory->calculateAttributes(); +} + +//---------------------------------------------------------------------- diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsDataTable.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsDataTable.cpp new file mode 100644 index 00000000..28e55e36 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsDataTable.cpp @@ -0,0 +1,1591 @@ +// ScriptMethodsDataTable.cpp +// +// copyright 2001 Sony Online Entertainment +// +//======================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "fileInterface/StdioFile.h" +#include "sharedDebug/Profiler.h" +#include "sharedUtility/DataTable.h" +#include "sharedUtility/DataTableManager.h" + +using namespace JNIWrappersNamespace; + + +//------------------------------------------------------------------------ +//lint -e818 //env could be declared const + +// ====================================================================== + +#ifdef _DEBUG +static char const *findNextChar(char const *s, char c) +{ + char const *tmp = s; + while (tmp && *tmp != '\0') + { + if (*tmp == c) + return tmp; + ++tmp; + } + return 0; +} +#endif + +// ---------------------------------------------------------------------- + +//ifdef out because this is currently only used in debug builds, and breaks the release build +#ifdef _DEBUG +static void parseTabbedLine(char const *line, int length, std::vector &results) +{ + char const *currentPos = line; + char const *tab = findNextChar(currentPos, '\t'); + char const *lineEnd = line+length; + if (lineEnd > line && *(lineEnd-1) == '\r') + --lineEnd; + while (tab && tab < lineEnd) + { + results.push_back(std::string(currentPos, tab-currentPos)); + currentPos = tab+1; + tab = findNextChar(currentPos, '\t'); + } + results.push_back(std::string(currentPos, lineEnd-currentPos)); +} +#endif + +// ====================================================================== +// ScriptMethodsDataTableNamespace +// ====================================================================== + +namespace ScriptMethodsDataTableNamespace +{ + bool install(); + + jint JNICALL dataTableGetInt(JNIEnv *env, jobject self, jstring table, jint row, jstring column); + jfloat JNICALL dataTableGetFloat(JNIEnv *env, jobject self, jstring table, jint row, jstring column); + jstring JNICALL dataTableGetString(JNIEnv *env, jobject self, jstring table, jint row, jstring column); + jintArray JNICALL dataTableGetIntColumnInternal(JNIEnv *env, jobject self, jstring table, jstring column, bool withDefaults); + jintArray JNICALL dataTableGetIntColumn(JNIEnv *env, jobject self, jstring table, jstring column); + jintArray JNICALL dataTableGetIntColumnNoDefaults(JNIEnv *env, jobject self, jstring table, jstring column); + jfloatArray JNICALL dataTableGetFloatColumnInternal(JNIEnv *env, jobject self, jstring table, jstring column, bool withDefaults); + jfloatArray JNICALL dataTableGetFloatColumn(JNIEnv *env, jobject self, jstring table, jstring column); + jfloatArray JNICALL dataTableGetFloatColumnNoDefaults(JNIEnv *env, jobject self, jstring table, jstring column); + jobjectArray JNICALL dataTableGetStringColumnInternal(JNIEnv *env, jobject self, jstring table, jstring column, bool withDefaults); + jobjectArray JNICALL dataTableGetStringColumn(JNIEnv *env, jobject self, jstring table, jstring column); + jobjectArray JNICALL dataTableGetStringColumnNoDefaults(JNIEnv *env, jobject self, jstring table, jstring column); + jint JNICALL dataTableGetIntA(JNIEnv *env, jobject self, jstring table, jint row, jint column); + jfloat JNICALL dataTableGetFloatA(JNIEnv *env, jobject self, jstring table, jint row, jint column); + jstring JNICALL dataTableGetStringA(JNIEnv *env, jobject self, jstring table, jint row, jint column); + jintArray JNICALL dataTableGetIntColumnAInternal(JNIEnv *env, jobject self, jstring table, jint column, bool withDefaults); + jintArray JNICALL dataTableGetIntColumnA(JNIEnv *env, jobject self, jstring table, jint column); + jintArray JNICALL dataTableGetIntColumnANoDefaults(JNIEnv *env, jobject self, jstring table, jint column); + jfloatArray JNICALL dataTableGetFloatColumnAInternal(JNIEnv *env, jobject self, jstring table, jint column, bool withDefaults); + jfloatArray JNICALL dataTableGetFloatColumnA(JNIEnv *env, jobject self, jstring table, jint column); + jfloatArray JNICALL dataTableGetFloatColumnANoDefaults(JNIEnv *env, jobject self, jstring table, jint column); + jobjectArray JNICALL dataTableGetStringColumnAInternal(JNIEnv *env, jobject self, jstring table, jint column, bool withDefaults); + jobjectArray JNICALL dataTableGetStringColumnA(JNIEnv *env, jobject self, jstring table, jint column); + jobjectArray JNICALL dataTableGetStringColumnANoDefaults(JNIEnv *env, jobject self, jstring table, jint column); + jboolean JNICALL dataTableOpen(JNIEnv *env, jobject self, jstring table); + jint JNICALL dataTableGetColumnType(JNIEnv *env, jobject self, jstring table, jstring column); + jint JNICALL dataTableGetColumnTypeA(JNIEnv *env, jobject self, jstring table, jint column); + jboolean JNICALL dataTableHasColumn(JNIEnv *env, jobject self, jstring table, jstring column); + jint JNICALL dataTableGetNumColumns (JNIEnv *env, jobject self, jstring table); + jint JNICALL dataTableGetNumRows (JNIEnv *env, jobject self, jstring table); + jobject JNICALL dataTableGetRow(JNIEnv *env, jobject self, jstring table, jint row); + jstring JNICALL dataTableGetColumnName(JNIEnv *env, jobject self, jstring table, jint column); + jobjectArray JNICALL dataTableGetColumnNames(JNIEnv *env, jobject self, jstring table); + jint JNICALL dataTableSearchColumnForString(JNIEnv *env, jobject self, jstring entry, jstring column, jstring table); + jint JNICALL dataTableSearchColumnForInt(JNIEnv *env, jobject self, jint entry, jstring column, jstring table); + jint JNICALL dataTableSearchColumnForStringA(JNIEnv *env, jobject self, jstring entry, jint column, jstring table); + jint JNICALL dataTableSearchColumnForIntA(JNIEnv *env, jobject self, jint entry, jint column, jstring table); + jint JNICALL dataTableFindColumnNumber(JNIEnv *env, jobject self, jstring table, jstring column); + void JNICALL dataTableAddRow(JNIEnv *env, jobject self, jstring table, jobject row); +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsDataTableNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsDataTableNamespace::c)} + JF("dataTableGetInt", "(Ljava/lang/String;ILjava/lang/String;)I", dataTableGetInt), + JF("dataTableGetFloat", "(Ljava/lang/String;ILjava/lang/String;)F", dataTableGetFloat), + JF("dataTableGetString", "(Ljava/lang/String;ILjava/lang/String;)Ljava/lang/String;", dataTableGetString), + JF("dataTableGetInt", "(Ljava/lang/String;II)I", dataTableGetIntA), + JF("dataTableGetFloat", "(Ljava/lang/String;II)F", dataTableGetFloatA), + JF("dataTableGetString", "(Ljava/lang/String;II)Ljava/lang/String;", dataTableGetStringA), + JF("dataTableGetIntColumn", "(Ljava/lang/String;Ljava/lang/String;)[I", dataTableGetIntColumn), + JF("dataTableGetIntColumnNoDefaults", "(Ljava/lang/String;Ljava/lang/String;)[I", dataTableGetIntColumnNoDefaults), + JF("dataTableGetFloatColumn", "(Ljava/lang/String;Ljava/lang/String;)[F", dataTableGetFloatColumn), + JF("dataTableGetFloatColumnNoDefaults", "(Ljava/lang/String;Ljava/lang/String;)[F", dataTableGetFloatColumnNoDefaults), + JF("dataTableGetStringColumn", "(Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;", dataTableGetStringColumn), + JF("dataTableGetStringColumnNoDefaults", "(Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;", dataTableGetStringColumnNoDefaults), + JF("dataTableGetIntColumn", "(Ljava/lang/String;I)[I", dataTableGetIntColumnA), + JF("dataTableGetIntColumnNoDefaults", "(Ljava/lang/String;I)[I", dataTableGetIntColumnANoDefaults), + JF("dataTableGetFloatColumn", "(Ljava/lang/String;I)[F", dataTableGetFloatColumnA), + JF("dataTableGetFloatColumnNoDefaults", "(Ljava/lang/String;I)[F", dataTableGetFloatColumnANoDefaults), + JF("dataTableGetStringColumn", "(Ljava/lang/String;I)[Ljava/lang/String;", dataTableGetStringColumnA), + JF("dataTableGetStringColumnNoDefaults", "(Ljava/lang/String;I)[Ljava/lang/String;", dataTableGetStringColumnANoDefaults), + JF("dataTableOpen", "(Ljava/lang/String;)Z", dataTableOpen), + JF("dataTableGetColumnType", "(Ljava/lang/String;Ljava/lang/String;)I", dataTableGetColumnType), + JF("dataTableGetColumnType", "(Ljava/lang/String;I)I", dataTableGetColumnTypeA), + JF("dataTableHasColumn", "(Ljava/lang/String;Ljava/lang/String;)Z", dataTableHasColumn), + JF("dataTableGetNumRows", "(Ljava/lang/String;)I", dataTableGetNumRows), + JF("dataTableGetNumColumns", "(Ljava/lang/String;)I", dataTableGetNumColumns), + JF("dataTableGetRow", "(Ljava/lang/String;I)Lscript/dictionary;", dataTableGetRow), + JF("dataTableGetColumnName", "(Ljava/lang/String;I)Ljava/lang/String;", dataTableGetColumnName), + JF("dataTableGetColumnNames", "(Ljava/lang/String;)[Ljava/lang/String;", dataTableGetColumnNames), + JF("dataTableSearchColumnForString", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I", dataTableSearchColumnForString), + JF("dataTableSearchColumnForInt", "(ILjava/lang/String;Ljava/lang/String;)I", dataTableSearchColumnForInt), + JF("dataTableSearchColumnForString", "(Ljava/lang/String;ILjava/lang/String;)I", dataTableSearchColumnForStringA), + JF("dataTableSearchColumnForInt", "(IILjava/lang/String;)I", dataTableSearchColumnForIntA), + JF("dataTableFindColumnNumber", "(Ljava/lang/String;Ljava/lang/String;)I", dataTableFindColumnNumber), + JF("dataTableAddRow", "(Ljava/lang/String;Lscript/dictionary;)V", dataTableAddRow), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +// ====================================================================== + +jint JNICALL ScriptMethodsDataTableNamespace::dataTableGetInt(JNIEnv *env, jobject self, jstring table, jint row, jstring column) +{ + PROFILER_AUTO_BLOCK_DEFINE("JNI::dataTableGetInt"); + + UNREF(env); + UNREF(self); + JavaStringParam localTable(table); + JavaStringParam localColumn(column); + + std::string tableNameString; + if (!JavaLibrary::convert(localTable, tableNameString)) + { + DEBUG_WARNING(true, ("Could not convert table name from java string to string.")); + return 0; + } + + std::string columnNameString; + if (!JavaLibrary::convert(localColumn, columnNameString)) + { + DEBUG_WARNING(true, ("Could not convert column name from java string to string.")); + return 0; + } + + DataTable* dt = DataTableManager::getTable(tableNameString, true); + if (!dt) + { + DEBUG_WARNING(true, ("JavaLibrary::dataTableGetInt - Could not find table %s.", tableNameString.c_str())); + return 0; + } + + if (row < 0 || dt->getNumRows() <= row) + { + DEBUG_WARNING(true, ("JavaLibaray::dataTableGetInt [%s] - Invalid row %d of table %s.", dt->getName().c_str(), row, tableNameString.c_str())); + return 0; + } + if (!dt->doesColumnExist(columnNameString)) + { + DEBUG_WARNING(true, ("JavaLibrary::dataTableGetInt [%s] - Invalid column name <%s> of table %s.", dt->getName().c_str(), columnNameString.c_str(), tableNameString.c_str())); + return 0; + } + + if (dt->getDataTypeForColumn(columnNameString).getBasicType() != DataTableColumnType::DT_Int) + { + DEBUG_WARNING(true, ("JavaLibrary::dataTableGetInt [%s] - Invalid type (not an int), column <%s> of table %s.", dt->getName().c_str(), columnNameString.c_str(), tableNameString.c_str())); + return 0; + } + + return dt->getIntValue(columnNameString, row); +} + +//------------------------------------------------------------------------ + +jfloat JNICALL ScriptMethodsDataTableNamespace::dataTableGetFloat(JNIEnv *env, jobject self, jstring table, jint row, jstring column) +{ + PROFILER_AUTO_BLOCK_DEFINE("JNI::dataTableGetFloat"); + UNREF(env); + UNREF(self); + JavaStringParam localTable(table); + JavaStringParam localColumn(column); + + std::string tableNameString; + if (!JavaLibrary::convert(localTable, tableNameString)) + { + DEBUG_WARNING(true, ("Could not convert table name from java string to string.")); + return 0; + } + + std::string columnNameString; + if (!JavaLibrary::convert(localColumn, columnNameString)) + { + DEBUG_WARNING(true, ("Could not convert column name from java string to string.")); + return 0; + } + + DataTable* dt = DataTableManager::getTable(tableNameString, true); + if (!dt) + { + DEBUG_WARNING(true, ("JavaLibrary::dataTableGetFloat - Could not find table %s.", tableNameString.c_str())); + return 0; + } + + if (row < 0 || dt->getNumRows() <= row) + { + DEBUG_WARNING(true, ("JavaLibaray::dataTableGetFloat [%s] - Invalid row %d of table %s.", dt->getName().c_str(), row, tableNameString.c_str())); + return 0; + } + if (!dt->doesColumnExist(columnNameString)) + { + DEBUG_WARNING(true, ("JavaLibrary::dataTableGetFloat [%s] - Invalid column name <%s> of table %s.", dt->getName().c_str(), columnNameString.c_str(), tableNameString.c_str())); + return 0; + } + + if (dt->getDataTypeForColumn(columnNameString).getBasicType() != DataTableColumnType::DT_Float) + { + DEBUG_WARNING(true, ("JavaLibrary::dataTableGetFloat [%s] - Invalid type (not a float), column <%s> of table %s.", dt->getName().c_str(), columnNameString.c_str(), tableNameString.c_str())); + return 0; + } + + return dt->getFloatValue(columnNameString, row); +} + +//------------------------------------------------------------------------ + +jstring JNICALL ScriptMethodsDataTableNamespace::dataTableGetString(JNIEnv *env, jobject self, jstring table, jint row, jstring column) +{ + PROFILER_AUTO_BLOCK_DEFINE("JNI::dataTableGetString"); + UNREF(env); + UNREF(self); + JavaStringParam localTable(table); + JavaStringParam localColumn(column); + + std::string tableNameString; + if (!JavaLibrary::convert(localTable, tableNameString)) + { + DEBUG_WARNING(true, ("Could not convert table name from java string to string.")); + return 0; + } + + std::string columnNameString; + if (!JavaLibrary::convert(localColumn, columnNameString)) + { + DEBUG_WARNING(true, ("Could not convert column name from java string to string.")); + return 0; + } + + DataTable* dt = DataTableManager::getTable(tableNameString, true); + if (!dt) + { + DEBUG_WARNING(true, ("JavaLibrary::dataTableGetString - Could not find table %s.", tableNameString.c_str())); + return 0; + } + + if (row < 0 || dt->getNumRows() <= row) + { + DEBUG_WARNING(true, ("JavaLibaray::dataTableGetString [%s] - Invalid row %d of table %s.", dt->getName().c_str(), row, tableNameString.c_str())); + return 0; + } + if (!dt->doesColumnExist(columnNameString)) + { + DEBUG_WARNING(true, ("JavaLibrary::dataTableGetString [%s] - Invalid column name <%s> of table %s.", dt->getName().c_str(), columnNameString.c_str(), tableNameString.c_str())); + return 0; + } + + if (dt->getDataTypeForColumn(columnNameString).getBasicType() != DataTableColumnType::DT_String) + { + DEBUG_WARNING(true, ("JavaLibrary::dataTableGetString [%s] - Invalid type (not a string), column <%s> of table %s.", dt->getName().c_str(), columnNameString.c_str(), tableNameString.c_str())); + return 0; + } + + JavaString javaString(dt->getStringValue(columnNameString, row)); + return javaString.getReturnValue(); +} + +//------------------------------------------------------------------------ + +jint JNICALL ScriptMethodsDataTableNamespace::dataTableGetIntA(JNIEnv *env, jobject self, jstring table, jint row, jint column) +{ + UNREF(env); + UNREF(self); + + PROFILER_AUTO_BLOCK_DEFINE("JNI::dataTableGetIntA"); + JavaStringParam localTable(table); + + std::string tableNameString; + if (!JavaLibrary::convert(localTable, tableNameString)) + { + DEBUG_WARNING(true, ("Could not convert table name from java string to string.")); + return 0; + } + + DataTable* dt = DataTableManager::getTable(tableNameString, true); + if (!dt) + { + DEBUG_WARNING(true, ("Could not find table %s.", tableNameString.c_str())); + return 0; + } + + if (row < 0 || dt->getNumRows() <= row) + { + DEBUG_WARNING(true, ("Invalid row %d.", row)); + return 0; + } + if (column < 0 || dt->getNumColumns() <= column) + { + DEBUG_WARNING(true, ("Invalid column %d.", column)); + return 0; + } + + if (dt->getDataTypeForColumn(column).getBasicType() != DataTableColumnType::DT_Int) + { + DEBUG_WARNING(true, ("Invalid type (not an int).")); + return 0; + } + + return dt->getIntValue(column, row); +} + +//------------------------------------------------------------------------ + +jfloat JNICALL ScriptMethodsDataTableNamespace::dataTableGetFloatA(JNIEnv *env, jobject self, jstring table, jint row, jint column) +{ + PROFILER_AUTO_BLOCK_DEFINE("JNI::dataTableGetFloatA"); + UNREF(env); + UNREF(self); + JavaStringParam localTable(table); + + std::string tableNameString; + if (!JavaLibrary::convert(localTable, tableNameString)) + { + DEBUG_WARNING(true, ("Could not convert table name from java string to string.")); + return 0; + } + + DataTable* dt = DataTableManager::getTable(tableNameString, true); + if (!dt) + { + DEBUG_WARNING(true, ("Could not find table %s.", tableNameString.c_str())); + return 0; + } + + if (row < 0 || dt->getNumRows() <= row) + { + DEBUG_WARNING(true, ("Invalid row %d.", row)); + return 0; + } + if (column < 0 || dt->getNumColumns() <= column) + { + DEBUG_WARNING(true, ("Invalid column %d.", column)); + return 0; + } + if (dt->getDataTypeForColumn(column).getBasicType() != DataTableColumnType::DT_Float) + { + DEBUG_WARNING(true, ("Invalid type (not an float).")); + return 0; + } + return dt->getFloatValue(column, row); +} + +//------------------------------------------------------------------------ + +jstring JNICALL ScriptMethodsDataTableNamespace::dataTableGetStringA(JNIEnv *env, jobject self, jstring table, jint row, jint column) +{ + PROFILER_AUTO_BLOCK_DEFINE("JNI::dataTableGetStringA"); + UNREF(env); + UNREF(self); + JavaStringParam localTable(table); + + + std::string tableNameString; + if (!JavaLibrary::convert(localTable, tableNameString)) + { + DEBUG_WARNING(true, ("Could not convert table name from java string to string.")); + return 0; + } + + DataTable* dt = DataTableManager::getTable(tableNameString, true); + if (!dt) + { + DEBUG_WARNING(true, ("Could not find table %s.", tableNameString.c_str())); + return 0; + } + + if (row < 0 || dt->getNumRows() <= row) + { + DEBUG_WARNING(true, ("Invalid row %d.", row)); + return 0; + } + if (column < 0 || dt->getNumColumns() <= column) + { + DEBUG_WARNING(true, ("Invalid column %d.", column)); + return 0; + } + if (dt->getDataTypeForColumn(column).getBasicType() != DataTableColumnType::DT_String) + { + DEBUG_WARNING(true, ("Invalid type (not a string).")); + return 0; + } + JavaString javaString(dt->getStringValue(column, row)); + return javaString.getReturnValue(); +} + +//------------------------------------------------------------------------ + +jintArray JNICALL ScriptMethodsDataTableNamespace::dataTableGetIntColumnInternal(JNIEnv *env, jobject self, jstring table, jstring column, bool withDefaults) +{ + PROFILER_AUTO_BLOCK_DEFINE("JNI::dataTableGetIntColInt"); + UNREF(env); + UNREF(self); + JavaStringParam localTable(table); + JavaStringParam localColumn(column); + + std::string tableNameString; + if (!JavaLibrary::convert(localTable, tableNameString)) + { + DEBUG_WARNING(true, ("Could not convert table name from java string to string.")); + return 0; + } + + std::string columnNameString; + if (!JavaLibrary::convert(localColumn, columnNameString)) + { + DEBUG_WARNING(true, ("Could not convert column name from java string to string.")); + return 0; + } + + DataTable* dt = DataTableManager::getTable(tableNameString, true); + if (!dt) + { + DEBUG_WARNING(true, ("Could not find table %s.", tableNameString.c_str())); + return 0; + } + + if (!dt->doesColumnExist(columnNameString)) + { + DEBUG_WARNING(true, ("[%s] Invalid column name <%s>.", dt->getName().c_str(), columnNameString.c_str())); + return 0; + } + + if (dt->getDataTypeForColumn(columnNameString).getBasicType() != DataTableColumnType::DT_Int) + { + DEBUG_WARNING(true, ("[%s] DataTable: Invalid type (not a int).", dt->getName().c_str())); + return 0; + } + + std::vector ret; + if (withDefaults) + { + dt->getIntColumn(columnNameString, ret); + } + else + { + int defaultValue = dt->getIntDefaultForColumn(columnNameString); + std::vector v; + dt->getIntColumn(columnNameString, v); + for (std::vector::const_iterator i = v.begin(); i != v.end(); ++i) + if ((*i) != defaultValue) + ret.push_back(*i); + } + + LocalIntArrayRefPtr valueArray = createNewIntArray(static_cast(ret.size())); + if (ret.size() > 0) + { + setIntArrayRegion(*valueArray, 0, static_cast(ret.size()), reinterpret_cast + (const_cast(&ret[0]))); + } + return valueArray->getReturnValue(); +} + +//------------------------------------------------------------------------ + +jintArray JNICALL ScriptMethodsDataTableNamespace::dataTableGetIntColumn(JNIEnv *env, jobject self, jstring table, jstring column) +{ + return dataTableGetIntColumnInternal(env, self, table, column, true); +} + +//------------------------------------------------------------------------ + +jintArray JNICALL ScriptMethodsDataTableNamespace::dataTableGetIntColumnNoDefaults(JNIEnv *env, jobject self, jstring table, jstring column) +{ + return dataTableGetIntColumnInternal(env, self, table, column, false); +} + +//------------------------------------------------------------------------ + +jfloatArray JNICALL ScriptMethodsDataTableNamespace::dataTableGetFloatColumnInternal(JNIEnv *env, jobject self, jstring table, jstring column, bool withDefaults) +{ + PROFILER_AUTO_BLOCK_DEFINE("JNI::dataTableGetFloatColInt"); + UNREF(env); + UNREF(self); + JavaStringParam localTable(table); + JavaStringParam localColumn(column); + + std::string tableNameString; + if (!JavaLibrary::convert(localTable, tableNameString)) + { + DEBUG_WARNING(true, ("Could not convert table name from java string to string.")); + return 0; + } + + std::string columnNameString; + if (!JavaLibrary::convert(localColumn, columnNameString)) + { + DEBUG_WARNING(true, ("Could not convert column name from java string to string.")); + return 0; + } + + DataTable* dt = DataTableManager::getTable(tableNameString, true); + if (!dt) + { + DEBUG_WARNING(true, ("Could not find table %s.", tableNameString.c_str())); + return 0; + } + + + if (!dt->doesColumnExist(columnNameString)) + { + DEBUG_WARNING(true, ("[%s] Invalid column name <%s>.", dt->getName().c_str(), columnNameString.c_str())); + return 0; + } + + if (dt->getDataTypeForColumn(columnNameString).getBasicType() != DataTableColumnType::DT_Float) + { + DEBUG_WARNING(true, ("[%s] Wrong type (not an float column)", dt->getName().c_str())); + return 0; + } + + std::vector ret; + if (withDefaults) + { + dt->getFloatColumn(columnNameString, ret); + } + else + { + float defaultValue = dt->getFloatDefaultForColumn(columnNameString); + std::vector v; + dt->getFloatColumn(columnNameString, v); + for (std::vector::const_iterator i = v.begin(); i != v.end(); ++i) + if ((*i) != defaultValue) //lint !e777 //testing floats for equality + ret.push_back(*i); + } + + LocalFloatArrayRefPtr valueArray = createNewFloatArray(static_cast(ret.size())); + if (ret.size() > 0 && valueArray != LocalFloatArrayRef::cms_nullPtr) + { + setFloatArrayRegion(*valueArray, 0, static_cast(ret.size()), reinterpret_cast + (const_cast(&ret[0]))); + } + return valueArray->getReturnValue(); + +} + +//------------------------------------------------------------------------ + +jfloatArray JNICALL ScriptMethodsDataTableNamespace::dataTableGetFloatColumn(JNIEnv *env, jobject self, jstring table, jstring column) +{ + return dataTableGetFloatColumnInternal(env, self, table, column, true); +} + +//------------------------------------------------------------------------ + +jfloatArray JNICALL ScriptMethodsDataTableNamespace::dataTableGetFloatColumnNoDefaults(JNIEnv *env, jobject self, jstring table, jstring column) +{ + return dataTableGetFloatColumnInternal(env, self, table, column, false); +} + +//------------------------------------------------------------------------ + +jobjectArray JNICALL ScriptMethodsDataTableNamespace::dataTableGetStringColumnInternal(JNIEnv *env, jobject self, jstring table, jstring column, bool withDefaults) +{ + PROFILER_AUTO_BLOCK_DEFINE("JNI::dataTableGetStringColInt"); + UNREF(env); + UNREF(self); + JavaStringParam localTable(table); + JavaStringParam localColumn(column); + + std::string tableNameString; + if (!JavaLibrary::convert(localTable, tableNameString)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::dataTableGetStringColumnInternal: could not convert table name from java string to string.")); + return 0; + } + + DataTable* dt = DataTableManager::getTable(tableNameString, true); + if (!dt) + { + DEBUG_WARNING(true, ("Could not find table %s.", tableNameString.c_str())); + return 0; + } + + std::string columnNameString; + if (!JavaLibrary::convert(localColumn, columnNameString)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::dataTableGetStringColumnInternal: could not convert column name from java string to string for table %s.", tableNameString.c_str())); + return 0; + } + + if (!dt->doesColumnExist(columnNameString)) + { + DEBUG_WARNING(true, ("[%s] Invalid column name <%s>.", dt->getName().c_str(), columnNameString.c_str())); + return 0; + } + + if (dt->getDataTypeForColumn(columnNameString).getBasicType() != DataTableColumnType::DT_String) + { + DEBUG_WARNING(true, ("[%s] Wrong type (not an string column)", dt->getName().c_str())); + return 0; + } + + std::vector ret; + if (withDefaults) + { + dt->getStringColumn(columnNameString, ret); + } + else + { + std::string defaultValue(dt->getStringDefaultForColumn(columnNameString)); + std::vector v; + dt->getStringColumn(columnNameString, v); + for (std::vector::const_iterator i = v.begin(); i != v.end(); ++i) + { + const char *const string = *i; + + if (strcmp(string, defaultValue.c_str())!=0) + { + ret.push_back(*i); + } + } + } + + size_t count = ret.size(); + LocalObjectArrayRefPtr valueArray = createNewObjectArray(static_cast(count), JavaLibrary::getClsString()); + for (size_t i = 0; i < count; ++i) + { + const char *const string = ret[i]; + JavaString jval(string); + setObjectArrayElement(*valueArray, static_cast(i), jval); + } + return valueArray->getReturnValue(); +} + +//------------------------------------------------------------------------ + +jobjectArray JNICALL ScriptMethodsDataTableNamespace::dataTableGetStringColumn(JNIEnv *env, jobject self, jstring table, jstring column) +{ + return dataTableGetStringColumnInternal(env, self, table, column, true); +} + +//------------------------------------------------------------------------ + +jobjectArray JNICALL ScriptMethodsDataTableNamespace::dataTableGetStringColumnNoDefaults(JNIEnv *env, jobject self, jstring table, jstring column) +{ + return dataTableGetStringColumnInternal(env, self, table, column, false); +} + +//------------------------------------------------------------------------ + +jintArray JNICALL ScriptMethodsDataTableNamespace::dataTableGetIntColumnAInternal(JNIEnv *env, jobject self, jstring table, jint column, bool withDefaults) +{ + PROFILER_AUTO_BLOCK_DEFINE("JNI::dataTableGetIntColIntA"); + UNREF(env); + UNREF(self); + JavaStringParam localTable(table); + + std::string tableNameString; + if (!JavaLibrary::convert(localTable, tableNameString)) + { + DEBUG_WARNING(true, ("Could not convert table name from java string to string.")); + return 0; + } + + DataTable* dt = DataTableManager::getTable(tableNameString, true); + if (!dt) + { + DEBUG_WARNING(true, ("Could not find table %s.", tableNameString.c_str())); + return 0; + } + + if (column < 0 || dt->getNumColumns() < column) + { + DEBUG_WARNING(true, ("Invalid column %d", column)); + return 0; + } + if (dt->getDataTypeForColumn(column).getBasicType() != DataTableColumnType::DT_Int) + { + DEBUG_WARNING(true, ("Wrong type (not an int column)")); + return 0; + } + + std::vector ret; + if (withDefaults) + { + dt->getIntColumn(column, ret); + } + else + { + int defaultValue = dt->getIntDefaultForColumn(column); + std::vector v; + dt->getIntColumn(column, v); + for (std::vector::const_iterator i = v.begin(); i != v.end(); ++i) + if ((*i) != defaultValue) + ret.push_back(*i); + } + + LocalIntArrayRefPtr valueArray = createNewIntArray(static_cast(ret.size())); + if (ret.size() > 0) + { + setIntArrayRegion(*valueArray, 0, static_cast(ret.size()), reinterpret_cast + (const_cast(&ret[0]))); + } + return valueArray->getReturnValue(); +} + +//------------------------------------------------------------------------ + +jintArray JNICALL ScriptMethodsDataTableNamespace::dataTableGetIntColumnA(JNIEnv *env, jobject self, jstring table, jint column) +{ + return dataTableGetIntColumnAInternal(env, self, table, column, true); +} + +//------------------------------------------------------------------------ + +jintArray JNICALL ScriptMethodsDataTableNamespace::dataTableGetIntColumnANoDefaults(JNIEnv *env, jobject self, jstring table, jint column) +{ + return dataTableGetIntColumnAInternal(env, self, table, column, false); +} + +//------------------------------------------------------------------------ + +jfloatArray JNICALL ScriptMethodsDataTableNamespace::dataTableGetFloatColumnAInternal(JNIEnv *env, jobject self, jstring table, jint column, bool withDefaults) +{ + PROFILER_AUTO_BLOCK_DEFINE("JNI::dataTableGetFloatColIntA"); + UNREF(env); + UNREF(self); + JavaStringParam localTable(table); + + std::string tableNameString; + if (!JavaLibrary::convert(localTable, tableNameString)) + { + DEBUG_WARNING(true, ("Could not convert table name from java string to string.")); + return 0; + } + + DataTable* dt = DataTableManager::getTable(tableNameString, true); + if (!dt) + { + DEBUG_WARNING(true, ("Could not find table %s.", tableNameString.c_str())); + return 0; + } + + if (column < 0 || dt->getNumColumns() < column) + { + DEBUG_WARNING(true, ("Invalid column %d", column)); + return 0; + } + if (dt->getDataTypeForColumn(column).getBasicType() != DataTableColumnType::DT_Float) + { + DEBUG_WARNING(true, ("Wrong type (not an float column)")); + return 0; + } + + std::vector ret; + if (withDefaults) + { + dt->getFloatColumn(column, ret); + } + else + { + float defaultValue = dt->getFloatDefaultForColumn(column); + std::vector v; + dt->getFloatColumn(column, v); + for (std::vector::const_iterator i = v.begin(); i != v.end(); ++i) + if ((*i) != defaultValue) //lint !e777 //testing floats for equality + ret.push_back(*i); + } + + LocalFloatArrayRefPtr valueArray = createNewFloatArray(static_cast(ret.size())); + if (ret.size() > 0 && valueArray != LocalFloatArrayRef::cms_nullPtr) + { + setFloatArrayRegion(*valueArray, 0, static_cast(ret.size()), reinterpret_cast + (const_cast(&ret[0]))); + } + return valueArray->getReturnValue(); +} + +//------------------------------------------------------------------------ + +jfloatArray JNICALL ScriptMethodsDataTableNamespace::dataTableGetFloatColumnA(JNIEnv *env, jobject self, jstring table, jint column) +{ + return dataTableGetFloatColumnAInternal(env, self, table, column, true); +} + +//------------------------------------------------------------------------ + +jfloatArray JNICALL ScriptMethodsDataTableNamespace::dataTableGetFloatColumnANoDefaults(JNIEnv *env, jobject self, jstring table, jint column) +{ + return dataTableGetFloatColumnAInternal(env, self, table, column, false); +} + +//------------------------------------------------------------------------ + +jobjectArray JNICALL ScriptMethodsDataTableNamespace::dataTableGetStringColumnAInternal(JNIEnv *env, jobject self, jstring table, jint column, bool withDefaults) +{ + PROFILER_AUTO_BLOCK_DEFINE("JNI::dataTableGetStringColIntA"); + UNREF(env); + UNREF(self); + JavaStringParam localTable(table); + + std::string tableNameString; + if (!JavaLibrary::convert(localTable, tableNameString)) + { + DEBUG_WARNING(true, ("Could not convert table name from java string to string.")); + return 0; + } + + DataTable* dt = DataTableManager::getTable(tableNameString, true); + if (!dt) + { + DEBUG_WARNING(true, ("Could not find table %s.", tableNameString.c_str())); + return 0; + } + + if (column < 0 || dt->getNumColumns() < column) + { + DEBUG_WARNING(true, ("Invalid column %d", column)); + return 0; + } + if (dt->getDataTypeForColumn(column).getBasicType() != DataTableColumnType::DT_String) + { + DEBUG_WARNING(true, ("Wrong type (not an string column)")); + return 0; + } + + std::vector ret; + if (withDefaults) + { + dt->getStringColumn(column, ret); + } + else + { + std::string defaultValue(dt->getStringDefaultForColumn(column)); + std::vector v; + dt->getStringColumn(column, v); + for (std::vector::const_iterator i = v.begin(); i != v.end(); ++i) + { + const char *const string = *i; + if (strcmp(string, defaultValue.c_str())!=0) + { + ret.push_back(*i); + } + } + } + + size_t count = ret.size(); + LocalObjectArrayRefPtr valueArray = createNewObjectArray(static_cast(count), JavaLibrary::getClsString()); + for (size_t i = 0; i < count; ++i) + { + const char *const string = ret[i]; + JavaString jval(string); + setObjectArrayElement(*valueArray, static_cast(i), jval); + } + return valueArray->getReturnValue(); +} + +//------------------------------------------------------------------------ + +jobjectArray JNICALL ScriptMethodsDataTableNamespace::dataTableGetStringColumnA(JNIEnv *env, jobject self, jstring table, jint column) +{ + return dataTableGetStringColumnAInternal(env, self, table, column, true); +} + +//------------------------------------------------------------------------ + +jobjectArray JNICALL ScriptMethodsDataTableNamespace::dataTableGetStringColumnANoDefaults(JNIEnv *env, jobject self, jstring table, jint column) +{ + return dataTableGetStringColumnAInternal(env, self, table, column, false); +} + +//------------------------------------------------------------------------ + +jboolean JNICALL ScriptMethodsDataTableNamespace::dataTableOpen(JNIEnv *env, jobject self, jstring table) +{ + PROFILER_AUTO_BLOCK_DEFINE("JNI::dataTableOpen"); + UNREF(env); + UNREF(self); + JavaStringParam localTable(table); + + std::string tableNameString; + if (!JavaLibrary::convert(localTable, tableNameString)) + { + DEBUG_WARNING(true, ("Could not convert table name from java string to string.")); + return JNI_FALSE; + } + + DataTable* dt = DataTableManager::getTable(tableNameString, true); + if (!dt) + { + DEBUG_WARNING(true, ("Could not find table %s.", tableNameString.c_str())); + return JNI_FALSE; + } + return JNI_TRUE; +} + +//------------------------------------------------------------------------ + +jint JNICALL ScriptMethodsDataTableNamespace::dataTableGetColumnType(JNIEnv *env, jobject self, jstring table, jstring column) +{ + PROFILER_AUTO_BLOCK_DEFINE("JNI::dataTableGetColType"); + UNREF(env); + UNREF(self); + JavaStringParam localTable(table); + JavaStringParam localColumn(column); + + std::string tableNameString; + if (!JavaLibrary::convert(localTable, tableNameString)) + { + DEBUG_WARNING(true, ("Could not convert table name from java string to string.")); + return 0; + } + + std::string columnNameString; + if (!JavaLibrary::convert(localColumn, columnNameString)) + { + DEBUG_WARNING(true, ("Could not convert table name from java string to string.")); + return 0; + } + + DataTable* dt = DataTableManager::getTable(tableNameString, true); + if (!dt) + { + DEBUG_WARNING(true, ("Could not find table %s.", tableNameString.c_str())); + return 0; + } + + if (!dt->doesColumnExist(columnNameString)) + { + DEBUG_WARNING(true, ("[%s] Invalid column name <%s>.", dt->getName().c_str(), columnNameString.c_str())); + return 0; + } + return static_cast(dt->getDataTypeForColumn(columnNameString).getBasicType()); +} + +//------------------------------------------------------------------------ + +jint JNICALL ScriptMethodsDataTableNamespace::dataTableGetColumnTypeA(JNIEnv *env, jobject self, jstring table, jint column) +{ + PROFILER_AUTO_BLOCK_DEFINE("JNI::dataTableGetColTypeA"); + UNREF(env); + UNREF(self); + JavaStringParam localTable(table); + + std::string tableNameString; + if (!JavaLibrary::convert(localTable, tableNameString)) + { + DEBUG_WARNING(true, ("Could not convert table name from java string to string.")); + return 0; + } + + DataTable* dt = DataTableManager::getTable(tableNameString, true); + if (!dt) + { + DEBUG_WARNING(true, ("Could not find table %s.", tableNameString.c_str())); + return 0; + } + if (column < 0 || dt->getNumColumns() < column) + { + DEBUG_WARNING(true, ("Invalid column %d", column)); + return -1; + } + return static_cast(dt->getDataTypeForColumn(column).getBasicType()); +} +//------------------------------------------------------------------------ + +jboolean JNICALL ScriptMethodsDataTableNamespace::dataTableHasColumn(JNIEnv *env, jobject self, jstring table, jstring column) +{ + PROFILER_AUTO_BLOCK_DEFINE("JNI::dataTableHasCol"); + UNREF(env); + UNREF(self); + + JavaStringParam localTable(table); + JavaStringParam localColumn(column); + + std::string tableNameString; + if (!JavaLibrary::convert(localTable, tableNameString)) + { + DEBUG_WARNING(true, ("Could not convert table name from java string to string.")); + return 0; + } + + std::string columnNameString; + if (!JavaLibrary::convert(localColumn, columnNameString)) + { + DEBUG_WARNING(true, ("Could not convert column name from java string to string.")); + return 0; + } + + DataTable* dt = DataTableManager::getTable(tableNameString, true); + if (!dt) + { + DEBUG_WARNING(true, ("Could not find table %s.", tableNameString.c_str())); + return 0; + } + return dt->doesColumnExist(columnNameString); +} +//------------------------------------------------------------------------ + +jint JNICALL ScriptMethodsDataTableNamespace::dataTableGetNumColumns (JNIEnv *env, jobject self, jstring table) +{ + PROFILER_AUTO_BLOCK_DEFINE("JNI::dataTableGetNumColumns"); + UNREF(env); + UNREF(self); + JavaStringParam localTable(table); + + std::string tableNameString; + if (!JavaLibrary::convert(localTable, tableNameString)) + { + DEBUG_WARNING(true, ("Could not convert table name from java string to string.")); + return 0; + } + + DataTable* dt = DataTableManager::getTable(tableNameString, true); + if (!dt) + { + DEBUG_WARNING(true, ("Could not find table %s.", tableNameString.c_str())); + return 0; + } + + return dt->getNumColumns(); +} +//------------------------------------------------------------------------ + +jint JNICALL ScriptMethodsDataTableNamespace::dataTableGetNumRows (JNIEnv *env, jobject self, jstring table) +{ + PROFILER_AUTO_BLOCK_DEFINE("JNI::dataTableGetNumRows"); + UNREF(env); + UNREF(self); + JavaStringParam localTable(table); + + std::string tableNameString; + if (!JavaLibrary::convert(localTable, tableNameString)) + { + DEBUG_WARNING(true, ("Could not convert table name from java string to string.")); + return 0; + } + + DataTable* dt = DataTableManager::getTable(tableNameString, true); + if (!dt) + { + DEBUG_WARNING(true, ("Could not find table %s.", tableNameString.c_str())); + return 0; + } + + return dt->getNumRows(); + +} +//------------------------------------------------------------------------ + +jobject JNICALL ScriptMethodsDataTableNamespace::dataTableGetRow(JNIEnv *env, jobject self, jstring table, jint row) +{ + PROFILER_AUTO_BLOCK_DEFINE("JNI::dataTableGetRow"); + UNREF(env); + UNREF(self); + JavaStringParam localTable(table); + + std::string tableNameString; + if (!JavaLibrary::convert(localTable, tableNameString)) + { + DEBUG_WARNING(true, ("Could not convert table name from java string to string.")); + return 0; + } + + DataTable* dt = DataTableManager::getTable(tableNameString, true); + if (!dt) + { + DEBUG_WARNING(true, ("Could not find table %s.", tableNameString.c_str())); + return 0; + } + + if (row < 0 || dt->getNumRows() <= row) + { + DEBUG_WARNING(true, ("Invalid row %d passed to dataTableGetInt.", row)); + JavaLibrary::throwInternalScriptError("Java script attempted to get an invalid row from a datatable"); + return 0; + } + + + LocalRefPtr target = createNewObject(JavaLibrary::getClsDictionary(), JavaLibrary::getMidDictionary()); + if (target == LocalRef::cms_nullPtr) + return false; + + for (int i = 0; i < dt->getNumColumns(); ++i) + { + JavaString jcolumnName(dt->getColumnName(i).c_str()); + switch (dt->getDataTypeForColumn(i).getBasicType()) + { + case DataTableColumnType::DT_HashString: + case DataTableColumnType::DT_Enum: + case DataTableColumnType::DT_Bool: + case DataTableColumnType::DT_Int: + case DataTableColumnType::DT_BitVector: + IGNORE_RETURN( callObjectMethod(*target, JavaLibrary::getMidDictionaryPutInt(), jcolumnName.getValue(), dt->getIntValue(i, row)) ); + break; + case DataTableColumnType::DT_Float: + IGNORE_RETURN( callObjectMethod(*target, JavaLibrary::getMidDictionaryPutFloat(), jcolumnName.getValue(), dt->getFloatValue(i, row)) ); + break; + case DataTableColumnType::DT_String: + { + JavaString jtmpString(dt->getStringValue(i, row)); + IGNORE_RETURN ( callObjectMethod(*target, JavaLibrary::getMidDictionaryPut(), jcolumnName.getValue(), jtmpString.getValue()) ); + break; + } + case DataTableColumnType::DT_Unknown: + case DataTableColumnType::DT_Comment: + default: + WARNING_STRICT_FATAL(true, ("Unhandled type in table %s row %d col %d", tableNameString.c_str(), row, i)); + return 0; + break; //lint !e527 //-- unreachable statement + } + } + return target->getReturnValue(); +} + +//------------------------------------------------------------------------ + +jstring JNICALL ScriptMethodsDataTableNamespace::dataTableGetColumnName(JNIEnv *env, jobject self, jstring table, jint column) +{ + PROFILER_AUTO_BLOCK_DEFINE("JNI::dataTableGetColName"); + UNREF(env); + UNREF(self); + JavaStringParam localTable(table); + + std::string tableNameString; + if (!JavaLibrary::convert(localTable, tableNameString)) + { + DEBUG_WARNING(true, ("Could not convert table name from java string to string.")); + return 0; + } + + DataTable* dt = DataTableManager::getTable(tableNameString, true); + if (!dt) + { + DEBUG_WARNING(true, ("Could not find table %s.", tableNameString.c_str())); + return 0; + } + + if (column < 0 || dt->getNumColumns() <= column) + { + DEBUG_WARNING(true, ("Invalid column %d", column)); + return 0; + } + JavaString javaString(dt->getColumnName(column).c_str()); + return javaString.getReturnValue(); +} + +//------------------------------------------------------------------------ + +jobjectArray JNICALL ScriptMethodsDataTableNamespace::dataTableGetColumnNames(JNIEnv *env, jobject self, jstring table) +{ + PROFILER_AUTO_BLOCK_DEFINE("JNI::dataTableGetColNames"); + UNREF(env); + UNREF(self); + JavaStringParam localTable(table); + + std::string tableNameString; + if (!JavaLibrary::convert(localTable, tableNameString)) + { + DEBUG_WARNING(true, ("Could not convert table name from java string to string.")); + return 0; + } + DataTable* dt = DataTableManager::getTable(tableNameString, true); + if (!dt) + { + DEBUG_WARNING(true, ("Could not find table %s.", tableNameString.c_str())); + return 0; + } + + int numColumns = dt->getNumColumns(); + LocalObjectArrayRefPtr valueArray = createNewObjectArray(numColumns, JavaLibrary::getClsString()); + for (int i = 0; i < numColumns; ++i) + { + const std::string & string = dt->getColumnName(i); + JavaString jval(string.c_str()); + setObjectArrayElement(*valueArray, i, jval); + } + return valueArray->getReturnValue(); +} + +//------------------------------------------------------------------------ + +jint JNICALL ScriptMethodsDataTableNamespace::dataTableSearchColumnForString(JNIEnv *env, jobject self, jstring entry, jstring column, jstring table) +{ + PROFILER_AUTO_BLOCK_DEFINE("JNI::dataTableGetSearchForString"); + UNREF(env); + UNREF(self); + JavaStringParam localTable(table); + std::string tableNameString; + if (!JavaLibrary::convert(localTable, tableNameString)) + { + DEBUG_WARNING(true, ("Could not convert table name from java string to string.")); + return -1; + } + + JavaStringParam localColumn(column); + std::string columnNameString; + if (!JavaLibrary::convert(localColumn, columnNameString)) + { + DEBUG_WARNING(true, ("Could not convert column name from java string to string.")); + return -1; + } + + JavaStringParam localEntry(entry); + std::string target; + if (!JavaLibrary::convert(localEntry, target)) + { + DEBUG_WARNING(true, ("Could not convert search name from java string to string.")); + return -1; + } + + DataTable* dt = DataTableManager::getTable(tableNameString, true); + if (!dt) + { + DEBUG_WARNING(true, ("Could not find table %s.", tableNameString.c_str())); + return -1; + } + + if (!dt->doesColumnExist(columnNameString)) + { + DEBUG_WARNING(true, ("[%s] Invalid column name <%s>.", dt->getName().c_str(), columnNameString.c_str())); + return -1; + } + + return dt->searchColumnString(dt->findColumnNumber(columnNameString), target); +} + +//------------------------------------------------------------------------ + +jint JNICALL ScriptMethodsDataTableNamespace::dataTableSearchColumnForStringA(JNIEnv *env, jobject self, jstring entry, jint column, jstring table) +{ + PROFILER_AUTO_BLOCK_DEFINE("JNI::dataTableSearchForStringA"); + UNREF(env); + UNREF(self); + JavaStringParam localTable(table); + std::string tableNameString; + if (!JavaLibrary::convert(localTable, tableNameString)) + { + DEBUG_WARNING(true, ("Could not convert table name from java string to string.")); + return -1; + } + + JavaStringParam localEntry(entry); + std::string target; + if (!JavaLibrary::convert(localEntry, target)) + { + DEBUG_WARNING(true, ("Could not convert search name from java string to string.")); + return -1; + } + + DataTable* dt = DataTableManager::getTable(tableNameString, true); + if (!dt) + { + DEBUG_WARNING(true, ("Could not find table %s.", tableNameString.c_str())); + return -1; + } + + return dt->searchColumnString(column, target); +} + +//------------------------------------------------------------------------ +jint JNICALL ScriptMethodsDataTableNamespace::dataTableSearchColumnForInt(JNIEnv *env, jobject self, jint entry, jstring column, jstring table) +{ + PROFILER_AUTO_BLOCK_DEFINE("JNI::dataTableSearchForInt"); + UNREF(env); + UNREF(self); + JavaStringParam localTable(table); + std::string tableNameString; + if (!JavaLibrary::convert(localTable, tableNameString)) + { + DEBUG_WARNING(true, ("Could not convert table name from java string to string.")); + return -1; + } + + JavaStringParam localColumn(column); + std::string columnNameString; + if (!JavaLibrary::convert(localColumn, columnNameString)) + { + DEBUG_WARNING(true, ("Could not convert column name from java string to string.")); + return -1; + } + + DataTable* dt = DataTableManager::getTable(tableNameString, true); + if (!dt) + { + DEBUG_WARNING(true, ("Could not find table %s.", tableNameString.c_str())); + return -1; + } + + if (!dt->doesColumnExist(columnNameString)) + { + DEBUG_WARNING(true, ("[%s] Invalid column name <%s>.", dt->getName().c_str(), columnNameString.c_str())); + return -1; + } + + return dt->searchColumnInt(dt->findColumnNumber(columnNameString), entry); +} + +//------------------------------------------------------------------------ + +jint JNICALL ScriptMethodsDataTableNamespace::dataTableSearchColumnForIntA(JNIEnv *env, jobject self, jint entry, jint column, jstring table) +{ + PROFILER_AUTO_BLOCK_DEFINE("JNI::dataTableSearchForIntA"); + UNREF(env); + UNREF(self); + JavaStringParam localTable(table); + std::string tableNameString; + if (!JavaLibrary::convert(localTable, tableNameString)) + { + DEBUG_WARNING(true, ("Could not convert table name from java string to string.")); + return -1; + } + + DataTable* dt = DataTableManager::getTable(tableNameString, true); + if (!dt) + { + DEBUG_WARNING(true, ("Could not find table %s.", tableNameString.c_str())); + return -1; + } + + return dt->searchColumnInt(column, entry); +} + +//------------------------------------------------------------------------ + +jint JNICALL ScriptMethodsDataTableNamespace::dataTableFindColumnNumber(JNIEnv *env, jobject self, jstring table, jstring column) +{ + JavaStringParam localTable(table); + std::string tableNameString; + if (!JavaLibrary::convert(localTable, tableNameString)) + { + DEBUG_WARNING(true, ("Could not convert table name from java string to string.")); + return -1; + } + + JavaStringParam localColumn(column); + std::string columnNameString; + if (!JavaLibrary::convert(localColumn, columnNameString)) + { + DEBUG_WARNING(true, ("Could not convert column name from java string to string.")); + return -1; + } + + DataTable* dt = DataTableManager::getTable(tableNameString, true); + if (!dt) + { + DEBUG_WARNING(true, ("Could not find table %s.", tableNameString.c_str())); + return -1; + } + + if (!dt->doesColumnExist(columnNameString)) + { + DEBUG_WARNING(true, ("[%s] Invalid column name <%s>.", dt->getName().c_str(), columnNameString.c_str())); + return -1; + } + + return dt->findColumnNumber(columnNameString); +} + +//------------------------------------------------------------------------ + +void JNICALL ScriptMethodsDataTableNamespace::dataTableAddRow(JNIEnv *env, jobject self, jstring table, jobject row) +{ +#ifndef _DEBUG + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::dataTableAddRow is not allowed except in debug mode!")); + return; +#else + JavaStringParam localTable(table); + std::string tableNameStr; + if (!JavaLibrary::convert(localTable, tableNameStr)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::dataTableAddRow bad table name")); + return; + } + if (!env->IsInstanceOf(row, JavaLibrary::getClsDictionary())) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::dataTableAddRow bad row dictionary, table %s", tableNameStr.c_str())); + return; + } + + std::vector columnNames; + std::vector columnTypes; + + std::string fileName(tableNameStr); + bool dosLinefeeds = false; + + // locate the table file and load column names and types + { + StdioFile inputFile(fileName.c_str(), "r"); + if (!inputFile.isOpen()) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::dataTableAddRow failed to open datatable file %s for reading", fileName.c_str())); + return; + } + int fileLength = inputFile.length(); + char *buffer = new char[fileLength+2]; // assure at least 2 '\0's on the end so we always have 2 strings + memset(buffer, 0, fileLength+2); + int bytes_read = inputFile.read(buffer, fileLength); + memset(buffer + bytes_read, 0, fileLength - bytes_read + 2); + char const *namesLineEnd = findNextChar(buffer, '\n'); + if (namesLineEnd > buffer && *(namesLineEnd-1) == '\r') + dosLinefeeds = true; + if (!namesLineEnd) + { + delete [] buffer; + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::dataTableAddRow malformed column names row in datatable %s", tableNameStr.c_str())); + return; + } + parseTabbedLine(buffer, namesLineEnd-buffer, columnNames); + char const *typesLineEnd = findNextChar(namesLineEnd+1, '\n'); + if (!typesLineEnd) + { + delete [] buffer; + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::dataTableAddRow malformed column types row in datatable %s", tableNameStr.c_str())); + return; + } + parseTabbedLine(namesLineEnd+1, typesLineEnd-namesLineEnd-1, columnTypes); + delete [] buffer; + } + + // pull the column names and types from the table file + std::vector addRowValues; + + if (columnNames.size() != columnTypes.size()) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::dataTableAddRow datatable column name or type is missing, table %s", tableNameStr.c_str())); + return; + } + + // resize the row values appropriately to account for the real number of columns + addRowValues.resize(columnNames.size()); + + LocalRefPtr keyEnumeration = callObjectMethod(LocalRefParam(row), JavaLibrary::getMidDictionaryKeys()); + while (callBooleanMethod(*keyEnumeration, JavaLibrary::getMidEnumerationHasMoreElements())) + { + LocalRefPtr key = callObjectMethod(*keyEnumeration, JavaLibrary::getMidEnumerationNextElement()); + if (!isInstanceOf(*key, JavaLibrary::getClsString())) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::dataTableAddRow dictionary has bad key, table %s", tableNameStr.c_str())); + return; + } + JavaStringParam localKeyStr(*key); + std::string keyStr; + JavaLibrary::convert(localKeyStr, keyStr); + // find the column + unsigned int column; + for (column = 0; column < columnNames.size(); ++column) + if (columnNames[column] == keyStr) + break; + if (column == columnNames.size()) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::dataTableAddRow unknown column %s for datatable %s", keyStr.c_str(), tableNameStr.c_str())); + return; + } + LocalRefPtr value = callObjectMethod(LocalRefParam(row), JavaLibrary::getMidDictionaryGet(), key->getValue()); + // verify the value is of an appropriate type, and set appropriately in the new row + switch (columnTypes[column].c_str()[0]) + { + case 'e': + // TODO: validate enumerations here if desired + case 'i': + { + if (!isInstanceOf(*value, JavaLibrary::getClsInteger())) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::dataTableAddRow non-int value for column %s of datatable %s", keyStr.c_str(), tableNameStr.c_str())); + return; + } + jint intValue = callIntMethod(*value, JavaLibrary::getMidIntegerIntValue()); + char buf[64]; + snprintf(buf, sizeof(buf)-1, "%d", intValue); + buf[sizeof(buf)-1] = '\0'; + addRowValues[column] = buf; + } + break; + case 'f': + { + if (!isInstanceOf(*value, JavaLibrary::getClsFloat())) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::dataTableAddRow non-float value for column %s of datatable %s", keyStr.c_str(), tableNameStr.c_str())); + return; + } + jfloat floatValue = callFloatMethod(*value, JavaLibrary::getMidFloatFloatValue()); + char buf[64]; + snprintf(buf, sizeof(buf)-1, "%12g", static_cast(floatValue)); + buf[sizeof(buf)-1] = '\0'; + addRowValues[column] = buf; + } + break; + case 'b': + { + if (!isInstanceOf(*value, JavaLibrary::getClsBoolean())) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::dataTableAddRow non-float value for column %s of datatable %s", keyStr.c_str(), tableNameStr.c_str())); + return; + } + jboolean booleanValue = callBooleanMethod(*value, JavaLibrary::getMidBooleanBooleanValue()); + addRowValues[column] = booleanValue ? "1" : "0"; + } + break; + case 's': + case 'h': + case 'c': + case 'p': + { + if (!isInstanceOf(*value, JavaLibrary::getClsString())) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::dataTableAddRow non-string value for column %s of datatable %s", keyStr.c_str(), tableNameStr.c_str())); + return; + } + JavaStringParam localValueStr(*value); + std::string valueStr; + JavaLibrary::convert(localValueStr, valueStr); + addRowValues[column] = valueStr; + } + break; + default: + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::dataTableAddRow unsupported type %s for column %s of datatable %s", columnTypes[column].c_str(), keyStr.c_str(), tableNameStr.c_str())); + } + return; + } + } + + // append the new row to the datatable + { + StdioFile outputFile(fileName.c_str(), "a"); + if (!outputFile.isOpen()) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::dataTableAddRow failed to open datatable file %s for appending", fileName.c_str())); + return; + } + + for (unsigned int i = 0; i < addRowValues.size(); ++i) + { + int len = addRowValues[i].length(); + if (len) + outputFile.write(len, addRowValues[i].c_str()); + if (i < addRowValues.size()-1) + outputFile.write(1, "\t"); + } + if (dosLinefeeds) + outputFile.write(1, "\r"); + outputFile.write(1, "\n"); + } +#endif +} + +//------------------------------------------------------------------------ + diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsDebug.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsDebug.cpp new file mode 100644 index 00000000..9946fc28 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsDebug.cpp @@ -0,0 +1,414 @@ +//======================================================================= +// +// ScriptMethodsDebug.cpp +// Copyright 2000-05, Sony Online Entertainment Inc., all rights reserved. +// +//======================================================================= + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "serverGame/ConfigServerGame.h" +#include "serverGame/ConsoleManager.h" +#include "serverGame/GameServer.h" +#include "serverGame/PlayerObject.h" +#include "serverGame/ServerObject.h" +#include "serverScript/ConfigServerScript.h" +#include "sharedDebug/Profiler.h" +#include "sharedDebug/ProfilerTimer.h" +#include "sharedLog/Log.h" +#include "sharedObject/NetworkIdManager.h" + +#ifdef linux +#include +#endif + +using namespace JNIWrappersNamespace; + + +// ====================================================================== +// ScriptMethodsDebugNamespace +// ====================================================================== + +namespace ScriptMethodsDebugNamespace +{ + std::set s_profileSections; + + bool install(); + + void JNICALL debugConsoleMsg(JNIEnv *env, jobject self, jlong objId, jstring msg); + void JNICALL debugSpeakMsg(JNIEnv *env, jobject self, jlong objId, jstring msg); + void JNICALL debugServerConsoleMsg(JNIEnv *env, jobject self, jlong objId, jstring msg); + void JNICALL log(JNIEnv *env, jobject self, jstring channel, jstring msg, jlong logger, jlong player1, jlong player2, jboolean alwaysLog); + void JNICALL logBalance(JNIEnv *env, jobject self, jstring msg); + void JNICALL profilerStart(JNIEnv *env, jobject self, jstring sectionName); + void JNICALL profilerStop(JNIEnv *env, jobject self, jstring sectionName); + void JNICALL profilerStartAccum(JNIEnv *env, jobject self, jstring sectionName); + void JNICALL profilerStopAccum(JNIEnv *env, jobject self, jstring sectionName); + void JNICALL disableGameMemoryDump(JNIEnv *env, jobject self); + void JNICALL debugMemoryReport(JNIEnv *env, jobject self); + void JNICALL debugMemoryReportMap(JNIEnv *env, jobject self); + void JNICALL generateJavacore(JNIEnv *env, jobject self); + jlong JNICALL queryPerformanceCounter( JNIEnv * env, jobject self); + jlong JNICALL queryPerformanceCounterFrequency(JNIEnv * env, jobject self); +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsDebugNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsDebugNamespace::c)} + JF("_debugConsoleMsg", "(JLjava/lang/String;)V", debugConsoleMsg), + JF("_debugSpeakMsg", "(JLjava/lang/String;)V", debugSpeakMsg), + JF("_debugServerConsoleMsg", "(JLjava/lang/String;)V", debugServerConsoleMsg), + JF("__LOG", "(Ljava/lang/String;Ljava/lang/String;JJJZ)V", log), + JF("logBalance", "(Ljava/lang/String;)V", logBalance), + JF("PROFILER_START", "(Ljava/lang/String;)V", profilerStart), + JF("PROFILER_STOP", "(Ljava/lang/String;)V", profilerStop), + JF("PROFILER_START_ACCUM", "(Ljava/lang/String;)V", profilerStartAccum), + JF("PROFILER_STOP_ACCUM", "(Ljava/lang/String;)V", profilerStopAccum), + JF("disableGameMemoryDump", "()V", disableGameMemoryDump), + JF("debugMemoryReport", "()V", debugMemoryReport), + JF("debugMemoryReportMap", "()V", debugMemoryReportMap), + JF("generateJavacore", "()V", generateJavacore), + JF("queryPerformanceCounter", "()J", queryPerformanceCounter), + JF("queryPerformanceCounterFrequency", "()J", queryPerformanceCounterFrequency) +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +//---------------------------------------------------------------------- + +/** + * Prints a debugging message to a player's console. + * + * @param env Java environment + * @param self class calling this function + * @param objId the player's avatar object id + * @param msg the message to print + */ +void JNICALL ScriptMethodsDebugNamespace::debugConsoleMsg(JNIEnv *env, jobject self, jlong objId, jstring msg) +{ + UNREF(self); + + JavaStringParam localMsg(msg); + + if (!ConfigServerScript::allowDebugConsoleMessages()) + { + return; + } + + ServerObject * object = 0; + if (!JavaLibrary::getObject(objId, object)) + { + return; + } + std::string msgString; + JavaLibrary::convert(localMsg, msgString); + if (ConfigServerGame::getJavaConsoleDebugMessages()) + { + DEBUG_REPORT_LOG(true, ("debugConsoleMsg (%s): %s\n", + object->getNetworkId().getValueString().c_str(), msgString.c_str())); + } + Client *client = object->getClient(); + if (client) + { + ConsoleMgr::broadcastString(msgString, client); + return; + } +} + +//---------------------------------------------------------------------- + +/** + * Prints a debugging message as if a creature spoke it. + * + * @param env Java environment + * @param self class calling this function + * @param objId the id of the object "speaking" + * @param msg the message to print + */ +void JNICALL ScriptMethodsDebugNamespace::debugSpeakMsg(JNIEnv *env, jobject self, jlong objId, jstring msg) +{ + UNREF(self); + + if (!ConfigServerScript::allowDebugSpeakMessages()) + { + return; + } + + JavaStringParam localMsg(msg); + + ServerObject * object = 0; + if (!JavaLibrary::getObject(objId, object)) + { + DEBUG_REPORT_LOG(true, ("JavaLibrary::debugSpeakMsg invalid object\n")); + return; + } + + Unicode::String msgString; + JavaLibrary::convert(localMsg, msgString); + if (ConfigServerGame::getJavaConsoleDebugMessages()) + { + DEBUG_REPORT_LOG(true, ("debugSpeakMsg (%s): %s\n", + object->getNetworkId().getValueString().c_str(), + Unicode::wideToNarrow(msgString).c_str())); + } + + object->speakText(NetworkId::cms_invalid, 0, 0, 0, msgString, 0, Unicode::emptyString); +} // JavaLibrary::debugSpeakMsg + +//---------------------------------------------------------------------- + +/** + * Prints a debugging message to the server console. + * + * @param env Java environment + * @param self class calling this function + * @param objId the player's avatar object id + * @param msg the message to print + */ +void JNICALL ScriptMethodsDebugNamespace::debugServerConsoleMsg(JNIEnv *env, jobject self, jlong objId, jstring msg) +{ + if(!ConfigServerGame::getJavaConsoleDebugMessages()) + return; + + UNREF(self); + + JavaStringParam localMsg(msg); + std::string msgString; + JavaLibrary::convert(localMsg, msgString); + + ServerObject * object = 0; + JavaLibrary::getObject(objId, object); + + if (object == NULL) + { + DEBUG_REPORT_LOG(true, ("debugServerConsoleMsg from : %s\n", + msgString.c_str())); + } + else + { + DEBUG_REPORT_LOG(true, ("debugServerConsoleMsg from %s: %s\n", + object->getNetworkId().getValueString().c_str(), msgString.c_str())); + } +} // JavaLibrary::debugServerConsoleMsg + +//---------------------------------------------------------------------- + +/** + * Logs a message involving two players. The info for player one will replace the tag %TU in + * the message, and the info for player two will replace the tag %TT in the message. + * (The tags should match the prose package tag for user and target). + * + * @param env Java environment + * @param self class calling this function + * @param channel the channel to log to + * @param msg the message to log + * @param logger id of the object where the log is coming from + * @param player1 the 1st player for the message (may be null) + * @param player2 the 2nd player for the message (may be null) + * @param alwaysLog flag to ignore the disableScriptLogs flag and always log this message + */ +void JNICALL ScriptMethodsDebugNamespace::log(JNIEnv *env, jobject self, jstring channel, jstring msg, jlong logger, jlong player1, jlong player2, jboolean alwaysLog) +{ + UNREF(self); + + if (channel == 0 || msg == 0) + { + JavaLibrary::throwInternalScriptError("[designer bug] JavaLibrary::log called with null channel or message"); + return; + } + + if (alwaysLog || !ConfigServerScript::getDisableScriptLogs()) + { + JavaStringParam localChan(channel); + std::string chanStr; + if (!JavaLibrary::convert(localChan, chanStr)) + { + JavaLibrary::throwInternalScriptError("JavaLibrary::log could not convert channel to C string"); + return; + } + + JavaStringParam localMsg(msg); + std::string msgStr; + if (!JavaLibrary::convert(localMsg, msgStr)) + { + JavaLibrary::throwInternalScriptError("JavaLibrary::log could not convert message to C string"); + return; + } + + NetworkId loggerId(logger); + + if (player1 != 0) + { + const ServerObject * playerObject = NULL; + if (JavaLibrary::getObject(player1, playerObject)) + { + std::string::size_type p = msgStr.find("%TU"); + if (p != std::string::npos) + msgStr.replace(p, 3, PlayerObject::getAccountDescription(playerObject)); + } + else + { + WARNING(true, ("JavaLibrary::log could not get object for " + "player1 passed for message %s", msgStr.c_str())); + } + } + + if (player2 != 0) + { + const ServerObject * playerObject = NULL; + if (JavaLibrary::getObject(player2, playerObject)) + { + std::string::size_type p = msgStr.find("%TT"); + if (p != std::string::npos) + msgStr.replace(p, 3, PlayerObject::getAccountDescription(playerObject)); + } + else + { + WARNING(true, ("JavaLibrary::log could not get object for " + "player2 passed for message %s", msgStr.c_str())); + } + } + + LOG(chanStr.c_str(), ("%s (from %s)", msgStr.c_str(), loggerId.getValueString().c_str())); + } +} // JavaLibrary::log + +//---------------------------------------------------------------------- + +/** + * Logs a message. To the GameBalance channel + * + * @param env Java environment + * @param self class calling this function + * @param msg the message to log + */ +void JNICALL ScriptMethodsDebugNamespace::logBalance(JNIEnv *env, jobject self, jstring msg) +{ + UNREF(self); + + if (ConfigServerScript::getLogBalance()) + { + JavaStringParam localMsg(msg); + std::string msgStr; + JavaLibrary::convert(localMsg, msgStr); + LOG("GameBalance", ("balancelog:%d:%s", static_cast(GameServer::getInstance().getProcessId()), msgStr.c_str())); + } +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsDebugNamespace::profilerStart(JNIEnv *env, jobject self, jstring sectionName) +{ + UNREF(self); + std::string sectionNameStr; + JavaLibrary::convert(JavaStringParam(sectionName), sectionNameStr); + PROFILER_BLOCK_DEFINE(p, (*s_profileSections.insert(sectionNameStr).first).c_str()); + PROFILER_BLOCK_ENTER(p); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsDebugNamespace::profilerStop(JNIEnv *env, jobject self, jstring sectionName) +{ + UNREF(self); + std::string sectionNameStr; + JavaLibrary::convert(JavaStringParam(sectionName), sectionNameStr); + PROFILER_BLOCK_DEFINE(p, (*s_profileSections.insert(sectionNameStr).first).c_str()); + PROFILER_BLOCK_LOST_CHECK(p); + PROFILER_BLOCK_LEAVE(p); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsDebugNamespace::profilerStartAccum(JNIEnv *env, jobject self, jstring sectionName) +{ + UNREF(self); + std::string sectionNameStr; + JavaLibrary::convert(JavaStringParam(sectionName), sectionNameStr); + PROFILER_BLOCK_DEFINE(p, (*s_profileSections.insert(sectionNameStr).first).c_str()); + PROFILER_BLOCK_ENTER(p); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsDebugNamespace::profilerStopAccum(JNIEnv *env, jobject self, jstring sectionName) +{ + UNREF(self); + std::string sectionNameStr; + JavaLibrary::convert(JavaStringParam(sectionName), sectionNameStr); + PROFILER_BLOCK_DEFINE(p, (*s_profileSections.insert(sectionNameStr).first).c_str()); + PROFILER_BLOCK_LOST_CHECK(p); + PROFILER_BLOCK_LEAVE(p); +} + +// ---------------------------------------------------------------------- +void JNICALL ScriptMethodsDebugNamespace::disableGameMemoryDump(JNIEnv *env, jobject self) +{ + UNREF(self); + MemoryManager::setReportAllocations(false); + NetworkIdManager::setReportObjectLeaks(false); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsDebugNamespace::debugMemoryReport(JNIEnv *env, jobject self) +{ + UNREF(self); + MemoryManager::debugReport(); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsDebugNamespace::debugMemoryReportMap(JNIEnv *env, jobject self) +{ + UNREF(self); + MemoryManager::debugReportMap(); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsDebugNamespace::generateJavacore(JNIEnv *env, jobject self) +{ + UNREF(self); + UNREF(env); + +#ifdef linux + if (JavaLibrary::getJavaVmType() == JavaLibrary::JV_ibm) + { + ::kill(0, SIGQUIT); + } +#endif +} + +// ---------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsDebugNamespace::queryPerformanceCounter(JNIEnv * env, jobject self) +{ + UNREF(env); + UNREF(self); + ProfilerTimer::Type time; + ProfilerTimer::getTime(time); + + return static_cast(time); +} +// ---------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsDebugNamespace::queryPerformanceCounterFrequency(JNIEnv * env, jobject self) +{ + UNREF(env); + UNREF(self); + ProfilerTimer::Type freq; + ProfilerTimer::getFrequency(freq); + + return static_cast(freq); +} + diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsDynamicVariable.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsDynamicVariable.cpp new file mode 100644 index 00000000..dbf13ac0 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsDynamicVariable.cpp @@ -0,0 +1,2298 @@ +//======================================================================== +// +// ScriptMethodsDynamicVariable.cpp - implements script methods dealing with objvars. +// +// copyright 2001 Sony Online Entertainment +// +//======================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "serverGame/ConfigServerGame.h" +#include "serverGame/ServerObject.h" +#include "serverGame/ServerWorld.h" +#include "serverUtility/ServerClock.h" +#include "sharedFoundation/DynamicVariable.h" +#include "sharedFoundation/DynamicVariableList.h" +#include "sharedFoundation/DynamicVariableLocationData.h" +#include "sharedFoundation/GameControllerMessage.h" +#include "sharedNetworkMessages/MessageQueueGenericValueType.h" +#include "UnicodeUtils.h" + +using namespace JNIWrappersNamespace; + + +//======================================================================== +// debugging non-authoritative objvar stuff +// +// we keep track of any objvars we set on a non-authoritative object in a frame, +// and warn/fatal if we try to read the objvar back in the same frame + +namespace NonAuthObjvarNamespace +{ + unsigned long lastObjvarSetFrame = 0; + std::map > ObjvarsSet; + + void addSetObjvar(const ServerObject & obj, const char * name) + { + if (!ConfigServerGame::getTrackNonAuthoritativeObjvarSets()) + return; + + if (name == NULL || *name == '\0') + return; + if (obj.isAuthoritative()) + return; + + unsigned long currentFrame = ServerClock::getInstance().getServerFrame(); + if (currentFrame > lastObjvarSetFrame) + { + // new frame, reset our data + lastObjvarSetFrame = currentFrame; + ObjvarsSet.clear(); + } + ObjvarsSet[obj.getNetworkId()].insert(name); + } + + void testIsSafeToReadObjvar(const ServerObject & obj, const std::string & name) + { + if (!ConfigServerGame::getTrackNonAuthoritativeObjvarSets()) + return; + + // we can read if the object is authoritative + if (obj.isAuthoritative()) + return; + + // we can read if we're on a different frame than the last time an objvar + // set + unsigned long currentFrame = ServerClock::getInstance().getServerFrame(); + if (currentFrame > lastObjvarSetFrame) + return; + + // we can read if we haven't set the objvar + std::map >::const_iterator found = ObjvarsSet.find( + obj.getNetworkId()); + if (found == ObjvarsSet.end()) + return; + + if ((*found).second.find(name) == (*found).second.end()) + return; + + // !!! we are trying to read an objvar on a non-authoritative object we + // have set this frame !!! + fprintf(stderr, "Trying to read objvar %s on non-authoritative " + "object %s that we have set this frame!\n", name.c_str(), + obj.getNetworkId().getValueString().c_str()); + JavaLibrary::printJavaStack(); + WARNING_STRICT_FATAL(true, ("Trying to read objvar %s on non-authoritative object %s that we have set this frame!", + name.c_str(), obj.getNetworkId().getValueString().c_str())); + } +} +using namespace NonAuthObjvarNamespace; + + +// ====================================================================== +// ScriptMethodsDynamicVariableNamespace +// ====================================================================== + +namespace ScriptMethodsDynamicVariableNamespace +{ + bool install(); + LocalRefPtr convertDynamicVariableListToObject(JNIEnv *env, const DynamicVariableListNestedList &list); + ServerObject * getObjectAndName(JNIEnv *env, jlong objId, jstring name, char * buffer, size_t bufferSize); + const DynamicVariableList * getObjvarsAndName(JNIEnv *env, jlong objId, jstring name, char * buffer, size_t bufferSize); + + jobject JNICALL getDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name); + jint JNICALL getIntDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name); + jintArray JNICALL getIntArrayDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name); + jfloat JNICALL getFloatDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name); + jfloatArray JNICALL getFloatArrayDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name); + jstring JNICALL getStringDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name); + jobjectArray JNICALL getStringArrayDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name); + jlong JNICALL getObjIdDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name); + jlongArray JNICALL getObjIdArrayDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name); + jobject JNICALL getLocationDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name); + jobjectArray JNICALL getLocationArrayDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name); + jobject JNICALL getStringIdDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name); + jobjectArray JNICALL getStringIdArrayDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name); + jobject JNICALL getTransformDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name); + jobjectArray JNICALL getTransformArrayDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name); + jobject JNICALL getVectorDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name); + jobjectArray JNICALL getVectorArrayDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name); + jobject JNICALL getDynamicVariableList(JNIEnv *env, jobject self, jlong objId, jstring name); + void JNICALL removeDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name); + void JNICALL removeAllDynamicVariables(JNIEnv *env, jobject self, jlong objId); + jboolean JNICALL hasDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name); + jboolean JNICALL setDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name, jobject data); + jboolean JNICALL setIntDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name, jint data); + jboolean JNICALL setIntArrayDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name, jintArray data); + jboolean JNICALL setFloatDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name, jfloat data); + jboolean JNICALL setFloatArrayDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name, jfloatArray data); + jboolean JNICALL setStringDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name, jstring data); + jboolean JNICALL setStringArrayDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name, jobjectArray data); + jboolean JNICALL setObjIdDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name, jlong data); + jboolean JNICALL setObjIdArrayDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name, jlongArray data); + jboolean JNICALL setLocationDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name, jobject data); + jboolean JNICALL setLocationArrayDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name, jobjectArray data); + jboolean JNICALL setStringIdDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name, jobject data); + jboolean JNICALL setStringIdArrayDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name, jobjectArray data); + jboolean JNICALL setTransformDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name, jobject data); + jboolean JNICALL setTransformArrayDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name, jobjectArray data); + jboolean JNICALL setVectorDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name, jobject data); + jboolean JNICALL setVectorArrayDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name, jobjectArray data); + jboolean JNICALL setDynamicVariableList(JNIEnv *env, jobject self, jlong objId, jstring name); + jboolean JNICALL copyDynamicVariable(JNIEnv *env, jobject self, jlong fromId, jlong toId, jstring name); + jstring JNICALL getPackedObjvars(JNIEnv *env, jobject self, jlong source, jstring jprefix); + void JNICALL setPackedObjvars(JNIEnv *env, jobject self, jlong target, jstring packedVars); +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsDynamicVariableNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsDynamicVariableNamespace::c)} + JF("_getObjVar", "(JLjava/lang/String;)Lscript/obj_var;", getDynamicVariable), + JF("_getIntObjVar", "(JLjava/lang/String;)I", getIntDynamicVariable), + JF("_getIntArrayObjVar", "(JLjava/lang/String;)[I", getIntArrayDynamicVariable), + JF("_getFloatObjVar", "(JLjava/lang/String;)F", getFloatDynamicVariable), + JF("_getFloatArrayObjVar", "(JLjava/lang/String;)[F", getFloatArrayDynamicVariable), + JF("_getStringObjVar", "(JLjava/lang/String;)Ljava/lang/String;", getStringDynamicVariable), + JF("_getStringArrayObjVar", "(JLjava/lang/String;)[Ljava/lang/String;", getStringArrayDynamicVariable), + JF("_getObjIdObjVar", "(JLjava/lang/String;)J", getObjIdDynamicVariable), + JF("_getObjIdArrayObjVar", "(JLjava/lang/String;)[J", getObjIdArrayDynamicVariable), + JF("_getLocationObjVar", "(JLjava/lang/String;)Lscript/location;", getLocationDynamicVariable), + JF("_getLocationArrayObjVar", "(JLjava/lang/String;)[Lscript/location;", getLocationArrayDynamicVariable), + JF("_getStringIdObjVar", "(JLjava/lang/String;)Lscript/string_id;", getStringIdDynamicVariable), + JF("_getStringIdArrayObjVar", "(JLjava/lang/String;)[Lscript/string_id;", getStringIdArrayDynamicVariable), + JF("_getTransformObjVar", "(JLjava/lang/String;)Lscript/transform;", getTransformDynamicVariable), + JF("_getTransformArrayObjVar", "(JLjava/lang/String;)[Lscript/transform;", getTransformArrayDynamicVariable), + JF("_getVectorObjVar", "(JLjava/lang/String;)Lscript/vector;", getVectorDynamicVariable), + JF("_getVectorArrayObjVar", "(JLjava/lang/String;)[Lscript/vector;", getVectorArrayDynamicVariable), + JF("_getObjVarList", "(JLjava/lang/String;)Lscript/obj_var_list;", getDynamicVariableList), + JF("_removeObjVar", "(JLjava/lang/String;)V", removeDynamicVariable), + JF("_removeAllObjVars", "(J)V", removeAllDynamicVariables), + JF("_hasObjVar", "(JLjava/lang/String;)Z", hasDynamicVariable), + JF("_setObjVar", "(JLjava/lang/String;Lscript/obj_var;)Z", setDynamicVariable), + JF("_setObjVar", "(JLjava/lang/String;I)Z", setIntDynamicVariable), + JF("_setObjVar", "(JLjava/lang/String;[I)Z", setIntArrayDynamicVariable), + JF("_setObjVar", "(JLjava/lang/String;F)Z", setFloatDynamicVariable), + JF("_setObjVar", "(JLjava/lang/String;[F)Z", setFloatArrayDynamicVariable), + JF("_setObjVar", "(JLjava/lang/String;Ljava/lang/String;)Z", setStringDynamicVariable), + JF("_setObjVar", "(JLjava/lang/String;[Ljava/lang/String;)Z", setStringArrayDynamicVariable), + JF("_setObjVar", "(JLjava/lang/String;J)Z", setObjIdDynamicVariable), + JF("_setObjVar", "(JLjava/lang/String;[J)Z", setObjIdArrayDynamicVariable), + JF("_setObjVar", "(JLjava/lang/String;Lscript/location;)Z", setLocationDynamicVariable), + JF("_setObjVar", "(JLjava/lang/String;[Lscript/location;)Z", setLocationArrayDynamicVariable), + JF("_setObjVar", "(JLjava/lang/String;Lscript/string_id;)Z", setStringIdDynamicVariable), + JF("_setObjVar", "(JLjava/lang/String;[Lscript/string_id;)Z", setStringIdArrayDynamicVariable), + JF("_setObjVar", "(JLjava/lang/String;Lscript/transform;)Z", setTransformDynamicVariable), + JF("_setObjVar", "(JLjava/lang/String;[Lscript/transform;)Z", setTransformArrayDynamicVariable), + JF("_setObjVar", "(JLjava/lang/String;Lscript/vector;)Z", setVectorDynamicVariable), + JF("_setObjVar", "(JLjava/lang/String;[Lscript/vector;)Z", setVectorArrayDynamicVariable), + JF("_setObjVarList", "(JLjava/lang/String;)Z", setDynamicVariableList), + JF("_copyObjVar", "(JJLjava/lang/String;)Z", copyDynamicVariable), + JF("_getPackedObjvars", "(JLjava/lang/String;)Ljava/lang/String;", getPackedObjvars), + JF("_setPackedObjvars", "(JLjava/lang/String;)V", setPackedObjvars), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +//======================================================================== +// class JavaLibrary objVar functions +//======================================================================== + +// ---------------------------------------------------------------------- + +/** + * Converts an DynamicVariableList to a jobject. + * + * @param env Java environment + * @param list the list to convert + * + * @return the converted object + */ +LocalRefPtr ScriptMethodsDynamicVariableNamespace::convertDynamicVariableListToObject(JNIEnv *env, const DynamicVariableList::NestedList &list) +{ + int count = list.getCount(); + + JavaString listName(list.getName().c_str()); + + LocalRefPtr newDynamicVariableList = createNewObject(JavaLibrary::getClsDynamicVariableList(), JavaLibrary::getMidDynamicVariableList(), + listName.getValue(), count); + if (env->ExceptionCheck()) + { + env->ExceptionDescribe(); + newDynamicVariableList = LocalRef::cms_nullPtr; + } + if (newDynamicVariableList == LocalRef::cms_nullPtr) + return LocalRef::cms_nullPtr; + + jboolean result; + for (DynamicVariableList::NestedList::const_iterator objvar(list.begin()); objvar != list.end(); ++objvar) + { + result = JNI_FALSE; + switch (objvar.getType()) + { + case DynamicVariable::INT: + { + int value; + objvar.getValue(value); + JavaString name(objvar.getName().c_str()); + result = callNonvirtualBooleanMethod(*newDynamicVariableList, + JavaLibrary::getClsDynamicVariableList(), JavaLibrary::getMidDynamicVariableListSetInt(), + name.getValue(), value); + } + break; + case DynamicVariable::INT_ARRAY: + { + std::vector value; + objvar.getValue(value); + LocalIntArrayRefPtr valueArray = createNewIntArray(value.size()); + if (value.size() > 0) + setIntArrayRegion(*valueArray, 0, value.size(), reinterpret_cast(const_cast(&value[0]))); + JavaString name(objvar.getName().c_str()); + result = callNonvirtualBooleanMethod(*newDynamicVariableList, + JavaLibrary::getClsDynamicVariableList(), JavaLibrary::getMidDynamicVariableListSetIntArray(), + name.getValue(), valueArray->getValue()); + } + break; + case DynamicVariable::REAL: + { + real value = 0; + objvar.getValue(value); + JavaString name(objvar.getName().c_str()); + result = callNonvirtualBooleanMethod(*newDynamicVariableList, + JavaLibrary::getClsDynamicVariableList(), JavaLibrary::getMidDynamicVariableListSetFloat(), + name.getValue(), value); + } + break; + case DynamicVariable::REAL_ARRAY: + { + std::vector value; + objvar.getValue(value); + LocalFloatArrayRefPtr valueArray = createNewFloatArray(value.size()); + if (value.size() > 0 && valueArray != LocalFloatArrayRef::cms_nullPtr) + setFloatArrayRegion(*valueArray, 0, value.size(), const_cast(&value[0])); + JavaString name(objvar.getName().c_str()); + result = callNonvirtualBooleanMethod(*newDynamicVariableList, + JavaLibrary::getClsDynamicVariableList(), JavaLibrary::getMidDynamicVariableListSetFloatArray(), + name.getValue(), valueArray->getValue()); + } + break; + case DynamicVariable::STRING: + { + Unicode::String value; + objvar.getValue(value); + // convert the Unicode string to a JavaString + JavaString jval(value); + JavaString name(objvar.getName().c_str()); + result = callNonvirtualBooleanMethod(*newDynamicVariableList, + JavaLibrary::getClsDynamicVariableList(), JavaLibrary::getMidDynamicVariableListSetString(), + name.getValue(), jval.getValue()); + } + break; + case DynamicVariable::STRING_ARRAY: + { + std::vector value; + objvar.getValue(value); + size_t count = value.size(); + LocalObjectArrayRefPtr valueArray = createNewObjectArray(count, JavaLibrary::getClsString()); + for (size_t i = 0; i < count; ++i) + { + JavaString jval(value[i]); + setObjectArrayElement(*valueArray, i, jval); + } + JavaString name(objvar.getName().c_str()); + result = callNonvirtualBooleanMethod(*newDynamicVariableList, + JavaLibrary::getClsDynamicVariableList(), JavaLibrary::getMidDynamicVariableListSetStringArray(), + name.getValue(), valueArray->getValue()); + } + break; + case DynamicVariable::NETWORK_ID: + { + NetworkId value; + objvar.getValue(value); + JavaString name(objvar.getName().c_str()); + result = callNonvirtualBooleanMethod(*newDynamicVariableList, + JavaLibrary::getClsDynamicVariableList(), JavaLibrary::getMidDynamicVariableListSetObjId(), + name.getValue(), value.getValue()); + } + break; + case DynamicVariable::NETWORK_ID_ARRAY: + { + std::vector value; + objvar.getValue(value); + size_t count = value.size(); + LocalLongArrayRefPtr valueArray = createNewLongArray(count); + for (size_t i = 0; i < count; ++i) + { + jlong jvalue = value[i].getValue(); + setLongArrayRegion(*valueArray, i, 1, &jvalue); + } + JavaString name(objvar.getName().c_str()); + result = callNonvirtualBooleanMethod(*newDynamicVariableList, + JavaLibrary::getClsDynamicVariableList(), JavaLibrary::getMidDynamicVariableListSetObjIdArray(), + name.getValue(), valueArray->getValue()); + } + break; + case DynamicVariable::LOCATION: + { + DynamicVariableLocationData value; + objvar.getValue(value); + LocalRefPtr jvalue; + if (ScriptConversion::convert(value.pos, value.scene, value.cell, jvalue)) + { + JavaString name(objvar.getName().c_str()); + result = callNonvirtualBooleanMethod(*newDynamicVariableList, + JavaLibrary::getClsDynamicVariableList(), JavaLibrary::getMidDynamicVariableListSetLocation(), + name.getValue(), jvalue->getValue()); + } + } + break; + case DynamicVariable::LOCATION_ARRAY: + { + std::vector value; + objvar.getValue(value); + size_t count = value.size(); + LocalObjectArrayRefPtr valueArray = createNewObjectArray(count, + JavaLibrary::getClsLocation()); + LocalRefPtr jvalue; + for (size_t i = 0; i < count; ++i) + { + const DynamicVariableLocationData &valueItem = value[i]; + if (ScriptConversion::convert(valueItem.pos, valueItem.scene, + valueItem.cell, jvalue)) + { + setObjectArrayElement(*valueArray, i, *jvalue); + } + } + JavaString name(objvar.getName().c_str()); + result = callNonvirtualBooleanMethod(*newDynamicVariableList, + JavaLibrary::getClsDynamicVariableList(), JavaLibrary::getMidDynamicVariableListSetLocationArray(), + name.getValue(), valueArray->getValue()); + } + break; + case DynamicVariable::LIST: + { + DynamicVariableList::NestedList nested(objvar.getNestedList()); + LocalRefPtr newDynamicVariable = convertDynamicVariableListToObject(env,nested); + if (newDynamicVariable != LocalRef::cms_nullPtr) + { + result = callNonvirtualBooleanMethod(*newDynamicVariableList, + JavaLibrary::getClsDynamicVariableList(), JavaLibrary::getMidDynamicVariableListSet(), + newDynamicVariable->getValue()); + } + } + break; + case DynamicVariable::STRING_ID: + { + StringId value; + objvar.getValue(value); + LocalRefPtr jvalue; + if (ScriptConversion::convert(value, jvalue)) + { + JavaString name(objvar.getName().c_str()); + result = callNonvirtualBooleanMethod(*newDynamicVariableList, + JavaLibrary::getClsDynamicVariableList(), JavaLibrary::getMidDynamicVariableListSetStringId(), + name.getValue(), jvalue->getValue()); + } + } + break; + case DynamicVariable::STRING_ID_ARRAY: + { + std::vector value; + objvar.getValue(value); + size_t count = value.size(); + LocalObjectArrayRefPtr valueArray = createNewObjectArray(count, + JavaLibrary::getClsStringId()); + for (size_t i = 0; i < count; ++i) + { + LocalRefPtr jvalue; + if (ScriptConversion::convert(value[i], jvalue)) + setObjectArrayElement(*valueArray, i, *jvalue); + } + JavaString name(objvar.getName().c_str()); + result = callNonvirtualBooleanMethod(*newDynamicVariableList, + JavaLibrary::getClsDynamicVariableList(), JavaLibrary::getMidDynamicVariableListSetStringIdArray(), + name.getValue(), valueArray->getValue()); + } + break; + case DynamicVariable::TRANSFORM: + { + Transform value; + objvar.getValue(value); + LocalRefPtr jvalue; + if (ScriptConversion::convert(value, jvalue)) + { + JavaString name(objvar.getName().c_str()); + result = callNonvirtualBooleanMethod(*newDynamicVariableList, JavaLibrary::getClsDynamicVariableList(), JavaLibrary::getMidDynamicVariableListSetTransform(), name.getValue(), jvalue->getValue()); + } + } + break; + case DynamicVariable::TRANSFORM_ARRAY: + { + std::vector value; + objvar.getValue(value); + size_t count = value.size(); + LocalObjectArrayRefPtr valueArray = createNewObjectArray(count, JavaLibrary::getClsTransform()); + for (size_t i = 0; i < count; ++i) + { + LocalRefPtr jvalue; + if (ScriptConversion::convert(value[i], jvalue)) + setObjectArrayElement(*valueArray, i, *jvalue); + } + JavaString name(objvar.getName().c_str()); + result = callNonvirtualBooleanMethod(*newDynamicVariableList, JavaLibrary::getClsDynamicVariableList(), JavaLibrary::getMidDynamicVariableListSetTransformArray(), name.getValue(), valueArray->getValue()); + } + break; + case DynamicVariable::VECTOR: + { + Vector value; + objvar.getValue(value); + LocalRefPtr jvalue; + if (ScriptConversion::convert(value, jvalue)) + { + JavaString name(objvar.getName().c_str()); + result = callNonvirtualBooleanMethod(*newDynamicVariableList, JavaLibrary::getClsDynamicVariableList(), JavaLibrary::getMidDynamicVariableListSetVector(), name.getValue(), jvalue->getValue()); + } + } + break; + case DynamicVariable::VECTOR_ARRAY: + { + std::vector value; + objvar.getValue(value); + size_t count = value.size(); + LocalObjectArrayRefPtr valueArray = createNewObjectArray(count, JavaLibrary::getClsVector()); + for (size_t i = 0; i < count; ++i) + { + LocalRefPtr jvalue; + if (ScriptConversion::convert(value[i], jvalue)) + setObjectArrayElement(*valueArray, i, *jvalue); + } + JavaString name(objvar.getName().c_str()); + result = callNonvirtualBooleanMethod(*newDynamicVariableList, JavaLibrary::getClsDynamicVariableList(), JavaLibrary::getMidDynamicVariableListSetVectorArray(), name.getValue(), valueArray->getValue()); + } + break; + } + if (env->ExceptionCheck()) + { + env->ExceptionDescribe(); + result = JNI_FALSE; + } + if (result == JNI_FALSE) + { + return LocalRef::cms_nullPtr; + } + } + return newDynamicVariableList; +} // JavaLibrary::convertDynamicVariableListToObject + +/** + * Given a Java obj_id and objvar name, converts them to a C ServerObject * + * and string. If there is an error we do a Java stack dump to help find which script + * made the bad call. + * + * @param env Java environment + * @param jlong the obj_id to convert to a ServerObject * + * @param name the Java objvar name to convert to C + * @param buffer a buffer to be filled in with the converted C name + * @param bufferSize the length of buffer + * + * @return the ServerObject * for the obj_id, or null on error + */ +ServerObject * ScriptMethodsDynamicVariableNamespace::getObjectAndName(JNIEnv *env, jlong objId, jstring name, char * buffer, size_t bufferSize) +{ + NOT_NULL(buffer); + + ServerObject * object = NULL; + JavaStringParam localName(name); + if (localName.fillBuffer(buffer, bufferSize) > 1) + { + if (!JavaLibrary::getObject(objId, object) && !ConfigServerGame::getDisableObjvarNullCheck()) + { + fprintf(stderr, "WARNING: Could not get object for objvar %s call\n", buffer); + } + } + else + { + fprintf(stderr, "WARNING: Could not get objvar name\n"); + } + if (object == NULL && !ConfigServerGame::getDisableObjvarNullCheck()) + JavaLibrary::printJavaStack(); + + return object; +} + +/** + * Given a Java obj_id and objvar name, converts them to a C DynamicVariableList * + * and string. If there is an error we do a Java stack dump to help find which script + * made the bad call. + * + * @param env Java environment + * @param jlong the obj_id to convert to a ServerObject * + * @param name the Java objvar name to convert to C + * @param buffer a buffer to be filled in with the converted C name + * @param bufferSize the length of buffer + * + * @return the DynamicVariableList * for the obj_id, or null on error + */ +const DynamicVariableList * ScriptMethodsDynamicVariableNamespace::getObjvarsAndName(JNIEnv *env, jlong objId, jstring name, char * buffer, size_t bufferSize) +{ + NOT_NULL(buffer); + + const DynamicVariableList * objvars = NULL; + const ServerObject * object = getObjectAndName(env, objId, name, buffer, bufferSize); + if (object != NULL) + { + testIsSafeToReadObjvar(*object, buffer); + objvars = &object->getObjVars(); + } + return objvars; +} + + +//======================================================================== +// class JavaLibrary JNI objvar callback methods +//======================================================================== + +/** + * Gets an objvar. + * + * @param env Java environment + * @param self class calling this function + * @param objId id of class containing the objvar + * @param name name of the objvar + * + * @return the objvar value + * + * @todo add support for objvar lists + */ +jobject JNICALL ScriptMethodsDynamicVariableNamespace::getDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name) +{ + UNREF(self); + + if (objId == 0 || name == 0) + return 0; + + char buffer[DynamicVariable::MAX_DYNAMIC_VARIABLE_NAME_LEN]; + const DynamicVariableList * objvars = getObjvarsAndName(env, objId, name, buffer, sizeof(buffer)); + if (objvars == NULL) + return 0; + const std::string objvarName(buffer); + + if (!objvars->hasItem(objvarName)) + return 0; + + // create the parameters for the java objVar constructor and create it + LocalRefPtr newDynamicVariable; + switch (objvars->getType(objvarName)) + { + case DynamicVariable::INT: + { + int value; + objvars->getItem(objvarName,value); + newDynamicVariable = createNewObject(JavaLibrary::getClsDynamicVariable(), + JavaLibrary::getMidDynamicVariableInt(), name, value); + } + break; + case DynamicVariable::INT_ARRAY: + { + std::vector value; + objvars->getItem(objvarName,value); + LocalIntArrayRefPtr valueArray = createNewIntArray(value.size()); + if (value.size() > 0) + { + setIntArrayRegion(*valueArray, 0, value.size(), + reinterpret_cast(const_cast(&value[0]))); + } + newDynamicVariable = createNewObject(JavaLibrary::getClsDynamicVariable(), + JavaLibrary::getMidDynamicVariableIntArray(), name, valueArray->getValue()); + } + break; + case DynamicVariable::REAL: + { + float value; + objvars->getItem(objvarName,value); + newDynamicVariable = createNewObject(JavaLibrary::getClsDynamicVariable(), + JavaLibrary::getMidDynamicVariableFloat(), name, value); + } + break; + case DynamicVariable::REAL_ARRAY: + { + std::vector value; + objvars->getItem(objvarName,value); + LocalFloatArrayRefPtr valueArray = createNewFloatArray(value.size()); + if (value.size() > 0 && valueArray != LocalFloatArrayRef::cms_nullPtr) + { + setFloatArrayRegion(*valueArray, 0, value.size(), + const_cast(&value[0])); + } + newDynamicVariable = createNewObject(JavaLibrary::getClsDynamicVariable(), + JavaLibrary::getMidDynamicVariableFloatArray(), name, valueArray->getValue()); + } + break; + case DynamicVariable::STRING: + { + Unicode::String value; + objvars->getItem(objvarName,value); + // convert the Unicode string to a jstring + JavaString jval(value); + newDynamicVariable = createNewObject(JavaLibrary::getClsDynamicVariable(), + JavaLibrary::getMidDynamicVariableString(), name, jval.getValue()); + } + break; + case DynamicVariable::STRING_ARRAY: + { + std::vector value; + objvars->getItem(objvarName,value); + size_t count = value.size(); + LocalObjectArrayRefPtr valueArray = createNewObjectArray(count, JavaLibrary::getClsString()); + for (size_t i = 0; i < count; ++i) + { + JavaString jval(value[i]); + setObjectArrayElement(*valueArray, i, jval); + } + newDynamicVariable = createNewObject(JavaLibrary::getClsDynamicVariable(), + JavaLibrary::getMidDynamicVariableStringArray(), name, valueArray->getValue()); + } + break; + case DynamicVariable::NETWORK_ID: + { + NetworkId value; + objvars->getItem(objvarName,value); + newDynamicVariable = createNewObject(JavaLibrary::getClsDynamicVariable(), + JavaLibrary::getMidDynamicVariableObjId(), name, value.getValue()); + } + break; + case DynamicVariable::NETWORK_ID_ARRAY: + { + std::vector value; + objvars->getItem(objvarName,value); + size_t count = value.size(); + LocalLongArrayRefPtr valueArray = createNewLongArray(count); + for (size_t i = 0; i < count; ++i) + { + jlong jval = value[i].getValue(); + setLongArrayRegion(*valueArray, i, 1, &jval); + } + newDynamicVariable = createNewObject(JavaLibrary::getClsDynamicVariable(), + JavaLibrary::getMidDynamicVariableObjIdArray(), name, valueArray->getValue()); + } + break; + case DynamicVariable::LOCATION: + { + DynamicVariableLocationData value; + objvars->getItem(objvarName,value); + LocalRefPtr jvalue; + if (ScriptConversion::convert(value.pos, value.scene, value.cell, jvalue)) + { + newDynamicVariable = createNewObject(JavaLibrary::getClsDynamicVariable(), + JavaLibrary::getMidDynamicVariableLocation(), name, jvalue->getValue()); + } + } + break; + case DynamicVariable::LOCATION_ARRAY: + { + std::vector value; + objvars->getItem(objvarName,value); + size_t count = value.size(); + LocalObjectArrayRefPtr valueArray = createNewObjectArray(count, JavaLibrary::getClsLocation()); + LocalRefPtr jvalue; + for (size_t i = 0; i < count; ++i) + { + const DynamicVariableLocationData &valueItem = value[i]; + if (ScriptConversion::convert(valueItem.pos, valueItem.scene, + valueItem.cell, jvalue)) + { + setObjectArrayElement(*valueArray, i, *jvalue); + } + } + newDynamicVariable = createNewObject(JavaLibrary::getClsDynamicVariable(), + JavaLibrary::getMidDynamicVariableLocationArray(), name, valueArray->getValue()); + } + break; + case DynamicVariable::LIST: + newDynamicVariable = convertDynamicVariableListToObject(env, DynamicVariableList::NestedList(*objvars, objvarName)); + break; + default: + newDynamicVariable = LocalRef::cms_nullPtr; + break; + } + if (env->ExceptionCheck()) + { + env->ExceptionDescribe(); + return 0; + } + return newDynamicVariable->getReturnValue(); +} // JavaLibrary::getDynamicVariable + +/** + * Gets an objvar of type int. + * + * @param env Java environment + * @param self class calling this function + * @param objId id of class containing the objvar + * @param name name of the objvar + * + * @return the objvar value + */ +jint JNICALL ScriptMethodsDynamicVariableNamespace::getIntDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name) +{ + UNREF(self); + + if (objId == 0 || name == 0) + return 0; + + char buffer[DynamicVariable::MAX_DYNAMIC_VARIABLE_NAME_LEN]; + const DynamicVariableList * objvarList = getObjvarsAndName(env, objId, name, buffer, sizeof(buffer)); + if (objvarList == NULL) + return 0; + + int localValue=0; + if (!objvarList->getItem(buffer,localValue)) + return 0; + + jint value = localValue; + return value; +} // JavaLibrary::getIntDynamicVariable + +/** + * Gets an objvar of type int[]. + * + * @param env Java environment + * @param self class calling this function + * @param objId id of class containing the objvar + * @param name name of the objvar + * + * @return the objvar value + */ +jintArray JNICALL ScriptMethodsDynamicVariableNamespace::getIntArrayDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name) +{ + UNREF(self); + + if (objId == 0 || name == 0) + return 0; + + char buffer[DynamicVariable::MAX_DYNAMIC_VARIABLE_NAME_LEN]; + const DynamicVariableList * objvarList = getObjvarsAndName(env, objId, name, buffer, sizeof(buffer)); + if (objvarList == NULL) + return 0; + + std::vector value; + if (!objvarList->getItem(buffer,value)) + return 0; + + LocalIntArrayRefPtr valueArray = createNewIntArray(value.size()); + if (value.size() > 0) + { + setIntArrayRegion(*valueArray, 0, value.size(), reinterpret_cast + (const_cast(&value[0]))); + } + return valueArray->getReturnValue(); +} // JavaLibrary::getIntArrayDynamicVariable + +/** + * Gets an objvar of type float. + * + * @param env Java environment + * @param self class calling this function + * @param objId id of class containing the objvar + * @param name name of the objvar + * + * @return the objvar value + */ +jfloat JNICALL ScriptMethodsDynamicVariableNamespace::getFloatDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name) +{ + UNREF(self); + + if (objId == 0 || name == 0) + return 0; + + char buffer[DynamicVariable::MAX_DYNAMIC_VARIABLE_NAME_LEN]; + const DynamicVariableList * objvarList = getObjvarsAndName(env, objId, name, buffer, sizeof(buffer)); + if (objvarList == NULL) + return 0; + + float localValue = 0; + if (!objvarList->getItem(buffer,localValue)) + return 0; + + jfloat value = localValue; + return value; +} // JavaLibrary::getFloatDynamicVariable + +/** + * Gets an objvar of type float[]. + * + * @param env Java environment + * @param self class calling this function + * @param objId id of class containing the objvar + * @param name name of the objvar + * + * @return the objvar value + */ +jfloatArray JNICALL ScriptMethodsDynamicVariableNamespace::getFloatArrayDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name) +{ + UNREF(self); + + if (objId == 0 || name == 0) + return 0; + + char buffer[DynamicVariable::MAX_DYNAMIC_VARIABLE_NAME_LEN]; + const DynamicVariableList * objvarList = getObjvarsAndName(env, objId, name, buffer, sizeof(buffer)); + if (objvarList == NULL) + return 0; + + std::vector value; + if (!objvarList->getItem(buffer,value)) + return 0; + + LocalFloatArrayRefPtr valueArray = createNewFloatArray(value.size()); + if (value.size() > 0 && valueArray != LocalFloatArrayRef::cms_nullPtr) + setFloatArrayRegion(*valueArray, 0, value.size(), const_cast(&value[0])); + return valueArray->getReturnValue(); +} // JavaLibrary::getFloatArrayDynamicVariable + +/** + * Gets an objvar of type string. + * + * @param env Java environment + * @param self class calling this function + * @param objId id of class containing the objvar + * @param name name of the objvar + * + * @return the objvar value + */ +jstring JNICALL ScriptMethodsDynamicVariableNamespace::getStringDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name) +{ + UNREF(self); + + if (objId == 0 || name == 0) + return 0; + + char buffer[DynamicVariable::MAX_DYNAMIC_VARIABLE_NAME_LEN]; + const DynamicVariableList * objvarList = getObjvarsAndName(env, objId, name, buffer, sizeof(buffer)); + if (objvarList == NULL) + return 0; + + Unicode::String value; + if (!objvarList->getItem(buffer,value)) + return 0; + + // convert EString to jstring + return JavaString(value).getReturnValue(); +} // JavaLibrary::getStringDynamicVariable + +/** + * Gets an objvar of type string[]. + * + * @param env Java environment + * @param self class calling this function + * @param objId id of class containing the objvar + * @param name name of the objvar + * + * @return the objvar value + */ +jobjectArray JNICALL ScriptMethodsDynamicVariableNamespace::getStringArrayDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name) +{ + UNREF(self); + + if (objId == 0 || name == 0) + return 0; + + char buffer[DynamicVariable::MAX_DYNAMIC_VARIABLE_NAME_LEN]; + const DynamicVariableList * objvarList = getObjvarsAndName(env, objId, name, buffer, sizeof(buffer)); + if (objvarList == NULL) + return 0; + + std::vector value; + if (!objvarList->getItem(buffer,value)) + return 0; + + size_t count = value.size(); + LocalObjectArrayRefPtr valueArray = createNewObjectArray(count, JavaLibrary::getClsString()); + for (size_t i = 0; i < count; ++i) + { + JavaString jval(value[i]); + setObjectArrayElement(*valueArray, i, jval); + } + return valueArray->getReturnValue(); +} // JavaLibrary::getStringArrayDynamicVariable + +/** + * Gets an objvar of type obj_id. + * + * @param env Java environment + * @param self class calling this function + * @param objId id of class containing the objvar + * @param name name of the objvar + * + * @return the objvar value + */ +jlong JNICALL ScriptMethodsDynamicVariableNamespace::getObjIdDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name) +{ + UNREF(self); + + if (objId == 0 || name == 0) + return 0; + + char buffer[DynamicVariable::MAX_DYNAMIC_VARIABLE_NAME_LEN]; + const DynamicVariableList * objvarList = getObjvarsAndName(env, objId, name, buffer, sizeof(buffer)); + if (objvarList == NULL) + return 0; + + NetworkId localValue; + if (!objvarList->getItem(buffer,localValue)) + return 0; + return localValue.getValue(); +} // JavaLibrary::getObjIdDynamicVariable + +/** + * Gets an objvar of type obj_id[]. + * + * @param env Java environment + * @param self class calling this function + * @param objId id of class containing the objvar + * @param name name of the objvar + * + * @return the objvar value + */ +jlongArray JNICALL ScriptMethodsDynamicVariableNamespace::getObjIdArrayDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name) +{ + UNREF(self); + + if (objId == 0 || name == 0) + return 0; + + char buffer[DynamicVariable::MAX_DYNAMIC_VARIABLE_NAME_LEN]; + const DynamicVariableList *objvarList = getObjvarsAndName(env, objId, name, buffer, sizeof(buffer)); + if (objvarList == NULL) + return 0; + + std::vector value; + if (!objvarList->getItem(buffer,value)) + return 0; + + size_t count = value.size(); + LocalLongArrayRefPtr valueArray = createNewLongArray(count); + jlong jlongTmp; + if (valueArray != LocalLongArrayRef::cms_nullPtr) + { + for (size_t i = 0; i < count; ++i) + { + jlongTmp = value[i].getValue(); + setLongArrayRegion(*valueArray, i, 1, &jlongTmp); + } + } + + return valueArray->getReturnValue(); +} // JavaLibrary::getObjIdArrayDynamicVariable + +/** + * Gets an objvar of type location. + * + * @param env Java environment + * @param self class calling this function + * @param objId id of class containing the objvar + * @param name name of the objvar + * + * @return the objvar value + */ +jobject JNICALL ScriptMethodsDynamicVariableNamespace::getLocationDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name) +{ + UNREF(self); + + if (objId == 0 || name == 0) + return 0; + + char buffer[DynamicVariable::MAX_DYNAMIC_VARIABLE_NAME_LEN]; + const DynamicVariableList * objvarList = getObjvarsAndName(env, objId, name, buffer, sizeof(buffer)); + if (objvarList == NULL) + return 0; + + DynamicVariableLocationData value; + if (!objvarList->getItem(buffer,value)) + return 0; + + LocalRefPtr jloc; + if (!ScriptConversion::convert(value.pos, value.scene, value.cell, jloc)) + return 0; + + return jloc->getReturnValue(); +} // JavaLibrary::getLocationDynamicVariable + +/** + * Gets an objvar of type location[]. + * + * @param env Java environment + * @param self class calling this function + * @param objId id of class containing the objvar + * @param name name of the objvar + * + * @return the objvar value + */ +jobjectArray JNICALL ScriptMethodsDynamicVariableNamespace::getLocationArrayDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name) +{ + UNREF(self); + + if (objId == 0 || name == 0) + return 0; + + char buffer[DynamicVariable::MAX_DYNAMIC_VARIABLE_NAME_LEN]; + const DynamicVariableList * objvarList = getObjvarsAndName(env, objId, name, buffer, sizeof(buffer)); + if (objvarList == NULL) + return 0; + + std::vector value; + if (!objvarList->getItem(buffer,value)) + return 0; + + size_t count = value.size(); + LocalObjectArrayRefPtr valueArray = createNewObjectArray(count, JavaLibrary::getClsLocation()); + if (valueArray == LocalObjectArrayRef::cms_nullPtr) + return 0; + + LocalRefPtr jvalue; + for (size_t i = 0; i < count; ++i) + { + const DynamicVariableLocationData &valueItem = value[i]; + if (ScriptConversion::convert(valueItem.pos, valueItem.scene, valueItem.cell, + jvalue)) + { + setObjectArrayElement(*valueArray, i, *jvalue); + } + else + setObjectArrayElement(*valueArray, i, LocalRef(0)); + } + return valueArray->getReturnValue(); +} // JavaLibrary::getLocationArrayDynamicVariable + +/** + * Gets an objvar of type string_id. + * + * @param env Java environment + * @param self class calling this function + * @param objId id of class containing the objvar + * @param name name of the objvar + * + * @return the objvar value + */ +jobject JNICALL ScriptMethodsDynamicVariableNamespace::getStringIdDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name) +{ + UNREF(self); + + if (objId == 0 || name == 0) + return 0; + + char buffer[DynamicVariable::MAX_DYNAMIC_VARIABLE_NAME_LEN]; + const DynamicVariableList * objvarList = getObjvarsAndName(env, objId, name, buffer, sizeof(buffer)); + if (objvarList == NULL) + return 0; + + StringId value; + if (!objvarList->getItem(buffer,value)) + return 0; + + LocalRefPtr string_id; + if (!ScriptConversion::convert(value, string_id)) + return 0; + + return string_id->getReturnValue(); +} // JavaLibrary::getStringIdDynamicVariable + +/** + * Gets an objvar of type string_id[]. + * + * @param env Java environment + * @param self class calling this function + * @param objId id of class containing the objvar + * @param name name of the objvar + * + * @return the objvar value + */ +jobjectArray JNICALL ScriptMethodsDynamicVariableNamespace::getStringIdArrayDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name) +{ + UNREF(self); + + if (objId == 0 || name == 0) + return 0; + + char buffer[DynamicVariable::MAX_DYNAMIC_VARIABLE_NAME_LEN]; + const DynamicVariableList * objvarList = getObjvarsAndName(env, objId, name, buffer, sizeof(buffer)); + if (objvarList == NULL) + return 0; + + std::vector value; + if (!objvarList->getItem(buffer,value)) + return 0; + + size_t count = value.size(); + LocalObjectArrayRefPtr valueArray = createNewObjectArray(count, JavaLibrary::getClsStringId()); + if (valueArray == LocalObjectArrayRef::cms_nullPtr) + return 0; + + LocalRefPtr jvalue; + for (size_t i = 0; i < count; ++i) + { + const StringId & valueItem = value[i]; + if (ScriptConversion::convert(valueItem, jvalue)) + setObjectArrayElement(*valueArray, i, *jvalue); + else + setObjectArrayElement(*valueArray, i, LocalRef(0)); + } + return valueArray->getReturnValue(); +} // JavaLibrary::getStringIdArrayDynamicVariable + +/** + * Gets an objvar of type transform. + * + * @param env Java environment + * @param self class calling this function + * @param objId id of class containing the objvar + * @param name name of the objvar + * + * @return the objvar value + */ +jobject JNICALL ScriptMethodsDynamicVariableNamespace::getTransformDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name) +{ + UNREF(self); + + if (objId == 0 || name == 0) + return 0; + + char buffer[DynamicVariable::MAX_DYNAMIC_VARIABLE_NAME_LEN]; + const DynamicVariableList * objvarList = getObjvarsAndName(env, objId, name, buffer, sizeof(buffer)); + if (objvarList == NULL) + return 0; + + Transform value; + if (!objvarList->getItem(buffer, value)) + return 0; + + LocalRefPtr transform; + if (!ScriptConversion::convert(value, transform)) + return 0; + + return transform->getReturnValue(); +} + +/** + * Gets an objvar of type transform[]. + * + * @param env Java environment + * @param self class calling this function + * @param objId id of class containing the objvar + * @param name name of the objvar + * + * @return the objvar value + */ +jobjectArray JNICALL ScriptMethodsDynamicVariableNamespace::getTransformArrayDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name) +{ + UNREF(self); + + if (objId == 0 || name == 0) + return 0; + + char buffer[DynamicVariable::MAX_DYNAMIC_VARIABLE_NAME_LEN]; + const DynamicVariableList * objvarList = getObjvarsAndName(env, objId, name, buffer, sizeof(buffer)); + if (objvarList == NULL) + return 0; + + std::vector value; + if (!objvarList->getItem(buffer,value)) + return 0; + + size_t count = value.size(); + LocalObjectArrayRefPtr valueArray = createNewObjectArray(count, JavaLibrary::getClsTransform()); + if (valueArray == LocalObjectArrayRef::cms_nullPtr) + return 0; + + LocalRefPtr jvalue; + for (size_t i = 0; i < count; ++i) + { + Transform const &valueItem = value[i]; + if (ScriptConversion::convert(valueItem, jvalue)) + setObjectArrayElement(*valueArray, i, *jvalue); + else + setObjectArrayElement(*valueArray, i, LocalRef(0)); + } + return valueArray->getReturnValue(); +} + +/** + * Gets an objvar of type vector. + * + * @param env Java environment + * @param self class calling this function + * @param objId id of class containing the objvar + * @param name name of the objvar + * + * @return the objvar value + */ +jobject JNICALL ScriptMethodsDynamicVariableNamespace::getVectorDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name) +{ + UNREF(self); + + if (objId == 0 || name == 0) + return 0; + + char buffer[DynamicVariable::MAX_DYNAMIC_VARIABLE_NAME_LEN]; + const DynamicVariableList * objvarList = getObjvarsAndName(env, objId, name, buffer, sizeof(buffer)); + if (objvarList == NULL) + return 0; + + Vector value; + if (!objvarList->getItem(buffer, value)) + return 0; + + LocalRefPtr vec; + if (!ScriptConversion::convert(value, vec)) + return 0; + + return vec->getReturnValue(); +} + +/** + * Gets an objvar of type vector[]. + * + * @param env Java environment + * @param self class calling this function + * @param objId id of class containing the objvar + * @param name name of the objvar + * + * @return the objvar value + */ +jobjectArray JNICALL ScriptMethodsDynamicVariableNamespace::getVectorArrayDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name) +{ + UNREF(self); + + if (objId == 0 || name == 0) + return 0; + + char buffer[DynamicVariable::MAX_DYNAMIC_VARIABLE_NAME_LEN]; + const DynamicVariableList * objvarList = getObjvarsAndName(env, objId, name, buffer, sizeof(buffer)); + if (objvarList == NULL) + return 0; + + std::vector value; + if (!objvarList->getItem(buffer,value)) + return 0; + + size_t count = value.size(); + LocalObjectArrayRefPtr valueArray = createNewObjectArray(count, JavaLibrary::getClsVector()); + if (valueArray == LocalObjectArrayRef::cms_nullPtr) + return 0; + + LocalRefPtr jvalue; + for (size_t i = 0; i < count; ++i) + { + Vector const &valueItem = value[i]; + if (ScriptConversion::convert(valueItem, jvalue)) + setObjectArrayElement(*valueArray, i, *jvalue); + else + setObjectArrayElement(*valueArray, i, LocalRef(0)); + } + return valueArray->getReturnValue(); +} + +/** + * Returns an objvar list. + * + * @param env Java environment + * @param self class calling this function + * @param objId id of class to get the list from + * @param name name of the list + * + * @return the objvar list + */ +jobject JNICALL ScriptMethodsDynamicVariableNamespace::getDynamicVariableList(JNIEnv *env, jobject self, jlong objId, jstring name) +{ + UNREF(self); + + if (objId == 0 || name == 0) + return 0; + + JavaStringParam localName(name); + + const ServerObject* object = NULL; + if (!JavaLibrary::getObject(objId, object)) + return 0; + + const DynamicVariableList &objvarList = object->getObjVars(); + + LocalRefPtr result; + if (name == 0 || getStringLength(localName) == 0) + { + // do the whole list + result = convertDynamicVariableListToObject(env, DynamicVariableList::NestedList(objvarList)); + } + else + { + // convert jstrings to stl strings + char buffer[DynamicVariable::MAX_DYNAMIC_VARIABLE_NAME_LEN]; + if (localName.fillBuffer(buffer, sizeof(buffer)) > 0 && objvarList.hasItem(buffer)) + { + result = convertDynamicVariableListToObject(env, DynamicVariableList::NestedList(objvarList, buffer)); + } + } + + if (result.get() == NULL) + return 0; + return result->getReturnValue(); +} // JavaLibrary::getDynamicVariableList + +/** + * Removes an objvar from an object. + * + * @param env Java environment + * @param self class calling this function + * @param objId id of object containing the objvar + * @param name name of the objvar + */ +void JNICALL ScriptMethodsDynamicVariableNamespace::removeDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name) +{ + UNREF(self); + + if (objId == 0 || name == 0) + return; + + char buffer[DynamicVariable::MAX_DYNAMIC_VARIABLE_NAME_LEN]; + ServerObject * object = getObjectAndName(env, objId, name, buffer, sizeof(buffer)); + if (object == NULL) + return; + + object->removeObjVarItem(buffer); +} // JavaLibrary::removeDynamicVariable + +/** + * Removes all the objvars from an object. + * + * @param env Java environment + * @param self class calling this function + * @param objId the object + */ +void JNICALL ScriptMethodsDynamicVariableNamespace::removeAllDynamicVariables(JNIEnv *env, jobject self, jlong objId) +{ + UNREF(self); + + if (objId == 0) + return; + + ServerObject* object = NULL; + if (!JavaLibrary::getObject(objId, object)) + return; + + object->eraseObjVarListEntries("."); +} // JavaLibrary::removeAllDynamicVariables + +/** + * Determines if an object has an objvar. + * + * @param env Java environment + * @param self class calling this function + * @param objId id of class containing the objvar + * @param name name of the objvar + * + * @return true if the objvar exists, false if not + */ +jboolean JNICALL ScriptMethodsDynamicVariableNamespace::hasDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name) +{ + UNREF(self); + + if (objId == 0 || name == 0) + return JNI_FALSE; + + char buffer[DynamicVariable::MAX_DYNAMIC_VARIABLE_NAME_LEN]; + const ServerObject * object = getObjectAndName(env, objId, name, buffer, sizeof(buffer)); + if (object == NULL) + return 0; + + const DynamicVariableList &objvarList = object->getObjVars(); + + if (objvarList.hasItem(buffer)) + return JNI_TRUE; + else + return JNI_FALSE; +} // JavaLibrary::hasDynamicVariable + +/** + * Sets an objvar of type obj_var. + * + * @param env Java environment + * @param self class calling this function + * @param objId id of class containing the objvar + * @param name name of the objvar + * @param value value to set the objvar to + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsDynamicVariableNamespace::setDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name, jobject data) +{ + UNREF(self); + + if (objId == 0 || name == 0 || data == 0) + return JNI_FALSE; + + char buffer[DynamicVariable::MAX_DYNAMIC_VARIABLE_NAME_LEN]; + ServerObject * object = getObjectAndName(env, objId, name, buffer, sizeof(buffer)); + if (object == NULL) + return JNI_FALSE; + + const DynamicVariableList *objvarList = &(object->getObjVars()); + if (objvarList == NULL) + return JNI_FALSE; + + // determine what type the data is +/* + if (env->IsInstanceOf(data, JavaLibrary::getClsDynamicVariable()) == JNI_TRUE) + { + // name is the name of an objvar list we will add data to + DynamicVariable *objvar = objvarList->getItemByName(localName); + if (objvar == NULL) + objvar = objvarList->addNestedList(localName); + if (objvar != NULL && objvar->getType() == DynamicVariable::LIST) + return updateDynamicVariableList(env, *dynamic_cast(objvar), data); + return JNI_FALSE; + } + else if (env->IsInstanceOf(data, ms_clsInteger) == JNI_TRUE) + { + if (objvarList->setItem(localName, static_cast(env->CallIntMethod(data, ms_midIntegerIntValue)))) + return JNI_TRUE; + return JNI_FALSE; + } + else if (env->IsInstanceOf(data, ms_clsFloat) == JNI_TRUE) + { + if (objvarList->setItem(localName, env->CallFloatMethod(data, ms_midFloatFloatValue))) + return JNI_TRUE; + return JNI_FALSE; + } + else if (env->IsInstanceOf(data, ms_clsString) == JNI_TRUE) + { + if (objvarList->setItem(localName, Unicode::String(env->GetStringChars(static_cast(data), NULL)))) + #error must release characters + return JNI_TRUE; + return JNI_FALSE; + } +*/ + return JNI_FALSE; +} // JavaLibrary::setDynamicVariable + +/** + * Sets an objvar of type int. + * + * @param env Java environment + * @param self class calling this function + * @param objId id of class containing the objvar + * @param name name of the objvar + * @param value value to set the objvar to + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsDynamicVariableNamespace::setIntDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name, jint value) +{ + UNREF(self); + + if (objId == 0 || name == 0) + return JNI_FALSE; + + char buffer[DynamicVariable::MAX_DYNAMIC_VARIABLE_NAME_LEN]; + ServerObject * object = getObjectAndName(env, objId, name, buffer, sizeof(buffer)); + if (object == NULL) + return JNI_FALSE; + + addSetObjvar(*object, buffer); + + return object->setObjVarItem(buffer, static_cast(value)); +} // JavaLibrary::setIntDynamicVariable + +/** + * Sets an objvar of type int[]. + * + * @param env Java environment + * @param self class calling this function + * @param objId id of class containing the objvar + * @param name name of the objvar + * @param value value to set the objvar to + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsDynamicVariableNamespace::setIntArrayDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name, jintArray value) +{ + UNREF(self); + + if (objId == 0 || name == 0 || value == 0) + return JNI_FALSE; + + char buffer[DynamicVariable::MAX_DYNAMIC_VARIABLE_NAME_LEN]; + ServerObject * object = getObjectAndName(env, objId, name, buffer, sizeof(buffer)); + if (object == NULL) + return JNI_FALSE; + + size_t size = env->GetArrayLength(value); + if (size == 0) + { + object->removeObjVarItem(buffer); + if (ConfigServerGame::getExceptionOnObjVarZeroLengthArray()) + { + JavaLibrary::throwInternalScriptError("JavaLibrary::setIntArrayDynamicVariable " + "trying to set an array objvar to 0 length. The objvar has been removed instead."); + } + return JNI_FALSE; + } + + addSetObjvar(*object, buffer); + + std::vector valueArray; + valueArray.resize(size); + env->GetIntArrayRegion(value, 0, size, reinterpret_cast(&valueArray[0])); + return object->setObjVarItem(buffer, valueArray); +} // JavaLibrary::setIntArrayDynamicVariable + +/** + * Sets an objvar of type float. + * + * @param env Java environment + * @param self class calling this function + * @param objId id of class containing the objvar + * @param name name of the objvar + * @param value value to set the objvar to + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsDynamicVariableNamespace::setFloatDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name, jfloat value) +{ + UNREF(self); + + if (objId == 0 || name == 0) + return JNI_FALSE; + + char buffer[DynamicVariable::MAX_DYNAMIC_VARIABLE_NAME_LEN]; + ServerObject * object = getObjectAndName(env, objId, name, buffer, sizeof(buffer)); + if (object == NULL) + return JNI_FALSE; + + addSetObjvar(*object, buffer); + + return object->setObjVarItem(buffer, value); +} // JavaLibrary::setFloatDynamicVariable + +/** + * Sets an objvar of type float[]. + * + * @param env Java environment + * @param self class calling this function + * @param objId id of class containing the objvar + * @param name name of the objvar + * @param value value to set the objvar to + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsDynamicVariableNamespace::setFloatArrayDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name, jfloatArray value) +{ + UNREF(self); + + if (objId == 0 || name == 0 || value == 0) + return JNI_FALSE; + + char buffer[DynamicVariable::MAX_DYNAMIC_VARIABLE_NAME_LEN]; + ServerObject * object = getObjectAndName(env, objId, name, buffer, sizeof(buffer)); + if (object == NULL) + return JNI_FALSE; + + size_t size = env->GetArrayLength(value); + if (size == 0) + { + object->removeObjVarItem(buffer); + if (ConfigServerGame::getExceptionOnObjVarZeroLengthArray()) + { + JavaLibrary::throwInternalScriptError("JavaLibrary::setFloatArrayDynamicVariable " + "trying to set an array objvar to 0 length. The objvar has been removed instead."); + } + return false; + } + + addSetObjvar(*object, buffer); + + std::vector valueArray; + valueArray.resize(size); + env->GetFloatArrayRegion(value, 0, size, &valueArray[0]); + return object->setObjVarItem(buffer, valueArray); +} // JavaLibrary::setFloatArrayDynamicVariable + +/** + * Sets an objvar of type string. + * + * @param env Java environment + * @param self class calling this function + * @param objId id of class containing the objvar + * @param name name of the objvar + * @param value value to set the objvar to + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsDynamicVariableNamespace::setStringDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name, jstring value) +{ + UNREF(self); + + if (objId == 0) + return JNI_FALSE; + + if (name == 0) + { + DEBUG_WARNING(true, ("NULL name passed from script to JavaLibrary::setStringDynamicValue")); + return JNI_FALSE; + } + + JavaStringParam localValue(value); + + char buffer[DynamicVariable::MAX_DYNAMIC_VARIABLE_NAME_LEN]; + ServerObject * object = getObjectAndName(env, objId, name, buffer, sizeof(buffer)); + if (object == NULL) + return JNI_FALSE; + + if (value == 0) + { + DEBUG_WARNING(true, ("NULL string passed from script to JavaLibrary::setStringDynamicValue (%s)",buffer)); + return JNI_FALSE; + } + + const DynamicVariableList *objvarList = &(object->getObjVars()); + if (objvarList == NULL) + return JNI_FALSE; + + Unicode::String valueString; + if (!JavaLibrary::convert(localValue, valueString)) + return JNI_FALSE; + + addSetObjvar(*object, buffer); + + return object->setObjVarItem(buffer, valueString); +} // JavaLibrary::setStringDynamicVariable + +/** + * Sets an objvar of type string[]. + * + * @param env Java environment + * @param self class calling this function + * @param objId id of class containing the objvar + * @param name name of the objvar + * @param value value to set the objvar to + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsDynamicVariableNamespace::setStringArrayDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name, jobjectArray value) +{ + UNREF(self); + + if (objId == 0 || name == 0 || value == 0) + return JNI_FALSE; + + if (env->IsInstanceOf(value, JavaLibrary::getClsStringArray()) == JNI_FALSE) + return JNI_FALSE; + + char buffer[DynamicVariable::MAX_DYNAMIC_VARIABLE_NAME_LEN]; + ServerObject * object = getObjectAndName(env, objId, name, buffer, sizeof(buffer)); + if (object == NULL) + return JNI_FALSE; + + std::vector valueArray; + size_t size = env->GetArrayLength(value); + if (size == 0) + { + object->removeObjVarItem(buffer); + if (ConfigServerGame::getExceptionOnObjVarZeroLengthArray()) + { + JavaLibrary::throwInternalScriptError("JavaLibrary::setStringArrayDynamicVariable " + "trying to set an array objvar to 0 length. The objvar has been removed instead."); + } + return JNI_FALSE; + } + + valueArray.resize(size); + for (size_t i = 0; i < size; ++i) + { + JavaStringPtr item = getStringArrayElement(LocalObjectArrayRefParam(value), i); + if (item != JavaString::cms_nullPtr) + JavaLibrary::convert(*item, valueArray[i]); + else + valueArray[i] = Unicode::String(); + } + + addSetObjvar(*object, buffer); + + // For some reason, returning the value directly from the function call here + // makes gcc 2.95.3 think the end of the function can be reached without + // returning a value in release builds, so we assign the result and return + // it to work around the bug. + bool const ret = object->setObjVarItem(buffer, valueArray); + return static_cast(ret); +} // JavaLibrary::setStringArrayDynamicVariable + +/** + * Sets an objvar of type obj_id. + * + * @param env Java environment + * @param self class calling this function + * @param objId id of class containing the objvar + * @param name name of the objvar + * @param value value to set the objvar to + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsDynamicVariableNamespace::setObjIdDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name, jlong value) +{ + UNREF(self); + + if (objId == 0 || name == 0 || value == 0) + return JNI_FALSE; + + char buffer[DynamicVariable::MAX_DYNAMIC_VARIABLE_NAME_LEN]; + ServerObject * object = getObjectAndName(env, objId, name, buffer, sizeof(buffer)); + if (object == NULL) + return JNI_FALSE; + + NetworkId oidValue(static_cast + (env->CallLongMethod(JavaLibrary::getObjId(value)->getReturnValue(), JavaLibrary::getMidObjIdGetValue()))); + + addSetObjvar(*object, buffer); + + return object->setObjVarItem(buffer, oidValue); +} // JavaLibrary::setObjIdDynamicVariable + +/** + * Sets an objvar of type obj_id[]. + * + * @param env Java environment + * @param self class calling this function + * @param objId id of class containing the objvar + * @param name name of the objvar + * @param value value to set the objvar to + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsDynamicVariableNamespace::setObjIdArrayDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name, jlongArray value) +{ + UNREF(self); + + if (objId == 0 || name == 0 || value == 0) + return JNI_FALSE; + + char buffer[DynamicVariable::MAX_DYNAMIC_VARIABLE_NAME_LEN]; + ServerObject * object = getObjectAndName(env, objId, name, buffer, sizeof(buffer)); + if (object == NULL) + return JNI_FALSE; + + std::vector valueArray; + size_t size = env->GetArrayLength(value); + if (size == 0) + { + object->removeObjVarItem(buffer); + if (ConfigServerGame::getExceptionOnObjVarZeroLengthArray()) + { + JavaLibrary::throwInternalScriptError("JavaLibrary::setObjIdArrayDynamicVariable " + "trying to set an array objvar to 0 length. The objvar has been removed instead."); + } + return JNI_FALSE; + } + + valueArray.resize(size); + jlong jlongTmp; + for (size_t i = 0; i < size; ++i) + { + env->GetLongArrayRegion(value, i, 1, &jlongTmp); + valueArray[i] = NetworkId(static_cast(jlongTmp)); + } + + addSetObjvar(*object, buffer); + + bool result = object->setObjVarItem(buffer, valueArray); + return result; +} // JavaLibrary::setObjIdArrayDynamicVariable + +/** + * Sets an objvar of type location. + * + * @param env Java environment + * @param self class calling this function + * @param objId id of class containing the objvar + * @param name name of the objvar + * @param value value to set the objvar to + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsDynamicVariableNamespace::setLocationDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name, jobject value) +{ + UNREF(self); + + if (objId == 0 || name == 0 || value == 0) + return JNI_FALSE; + + if (env->IsInstanceOf(value, JavaLibrary::getClsLocation()) == JNI_FALSE) + return JNI_FALSE; + + char buffer[DynamicVariable::MAX_DYNAMIC_VARIABLE_NAME_LEN]; + ServerObject * object = getObjectAndName(env, objId, name, buffer, sizeof(buffer)); + if (object == NULL) + return JNI_FALSE; + + DynamicVariableLocationData locValue; + locValue.pos.x = env->GetFloatField(value, JavaLibrary::getFidLocationX()); + locValue.pos.y = env->GetFloatField(value, JavaLibrary::getFidLocationY()); + locValue.pos.z = env->GetFloatField(value, JavaLibrary::getFidLocationZ()); + JavaStringPtr area = getStringField(LocalRefParam(value), JavaLibrary::getFidLocationArea()); + JavaLibrary::convert(*area, locValue.scene); + LocalRefPtr cell = getObjectField(LocalRefParam(value), JavaLibrary::getFidLocationCell()); + locValue.cell = JavaLibrary::getNetworkId(*cell); + + addSetObjvar(*object, buffer); + + return object->setObjVarItem(buffer, locValue); +} // JavaLibrary::setLocationDynamicVariable + +/** + * Sets an objvar of type location[]. + * + * @param env Java environment + * @param self class calling this function + * @param objId id of class containing the objvar + * @param name name of the objvar + * @param value value to set the objvar to + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsDynamicVariableNamespace::setLocationArrayDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name, jobjectArray value) +{ + UNREF(self); + + if (objId == 0 || name == 0 || value == 0) + return JNI_FALSE; + + if (env->IsInstanceOf(value, JavaLibrary::getClsLocationArray()) == JNI_FALSE) + return JNI_FALSE; + + char buffer[DynamicVariable::MAX_DYNAMIC_VARIABLE_NAME_LEN]; + ServerObject * object = getObjectAndName(env, objId, name, buffer, sizeof(buffer)); + if (object == NULL) + return JNI_FALSE; + + std::vector valueArray; + size_t size = env->GetArrayLength(value); + if (size == 0) + { + object->removeObjVarItem(buffer); + if (ConfigServerGame::getExceptionOnObjVarZeroLengthArray()) + { + JavaLibrary::throwInternalScriptError("JavaLibrary::setLocationArrayDynamicVariable " + "trying to set an array objvar to 0 length. The objvar has been removed instead."); + } + return JNI_FALSE; + } + + valueArray.resize(size); + for (size_t i = 0; i < size; ++i) + { + LocalRefPtr item = getObjectArrayElement(LocalObjectArrayRefParam(value), i); + if (item != LocalRef::cms_nullPtr) + { + DynamicVariableLocationData &valueItem = valueArray[i]; + valueItem.pos.x = getFloatField(*item, JavaLibrary::getFidLocationX()); + valueItem.pos.y = getFloatField(*item, JavaLibrary::getFidLocationY()); + valueItem.pos.z = getFloatField(*item, JavaLibrary::getFidLocationZ()); + JavaStringPtr area = getStringField(*item, JavaLibrary::getFidLocationArea()); + JavaLibrary::convert(*area, valueItem.scene); + LocalRefPtr cell = getObjectField(*item, JavaLibrary::getFidLocationCell()); + valueItem.cell = JavaLibrary::getNetworkId(*cell); + } + else + valueArray[i] = DynamicVariableLocationData(); + } + + addSetObjvar(*object, buffer); + + bool result = object->setObjVarItem(buffer, valueArray); + return result; +} // JavaLibrary::setLocationArrayDynamicVariable + +/** + * Sets an objvar of type string_id. + * + * @param env Java environment + * @param self class calling this function + * @param objId id of class containing the objvar + * @param name name of the objvar + * @param value value to set the objvar to + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsDynamicVariableNamespace::setStringIdDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name, jobject value) +{ + UNREF(self); + + if (objId == 0 || name == 0 || value == 0) + return JNI_FALSE; + + if (env->IsInstanceOf(value, JavaLibrary::getClsStringId()) == JNI_FALSE) + return JNI_FALSE; + + char buffer[DynamicVariable::MAX_DYNAMIC_VARIABLE_NAME_LEN]; + ServerObject * object = getObjectAndName(env, objId, name, buffer, sizeof(buffer)); + if (object == NULL) + return JNI_FALSE; + + StringId locValue; + if (!ScriptConversion::convert(value, locValue)) + return JNI_FALSE; + + addSetObjvar(*object, buffer); + + return object->setObjVarItem(buffer, locValue); +} // JavaLibrary::setStringIdDynamicVariable + +/** + * Sets an objvar of type string_id[]. + * + * @param env Java environment + * @param self class calling this function + * @param objId id of class containing the objvar + * @param name name of the objvar + * @param value value to set the objvar to + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsDynamicVariableNamespace::setStringIdArrayDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name, jobjectArray value) +{ + UNREF(self); + + if (objId == 0 || name == 0 || value == 0) + return JNI_FALSE; + + if (env->IsInstanceOf(value, JavaLibrary::getClsStringIdArray()) == JNI_FALSE) + return JNI_FALSE; + + char buffer[DynamicVariable::MAX_DYNAMIC_VARIABLE_NAME_LEN]; + ServerObject * object = getObjectAndName(env, objId, name, buffer, sizeof(buffer)); + if (object == NULL) + return JNI_FALSE; + + std::vector valueArray; + size_t size = env->GetArrayLength(value); + if (size == 0) + { + object->removeObjVarItem(buffer); + if (ConfigServerGame::getExceptionOnObjVarZeroLengthArray()) + { + JavaLibrary::throwInternalScriptError("JavaLibrary::setStringIdArrayDynamicVariable " + "trying to set an array objvar to 0 length. The objvar has been removed instead."); + } + return false; + } + + valueArray.resize(size); + for (size_t i = 0; i < size; ++i) + { + LocalRefPtr item = getObjectArrayElement(LocalObjectArrayRefParam(value), i); + if (item == LocalRef::cms_nullPtr) + return JNI_FALSE; + StringId &valueItem = valueArray[i]; + if (!ScriptConversion::convert(*item, valueItem)) + return JNI_FALSE; + } + + addSetObjvar(*object, buffer); + + bool result = object->setObjVarItem(buffer, valueArray); + return result; +} // JavaLibrary::setStringIdArrayDynamicVariable + +/** + * Sets an objvar of type transform. + * + * @param env Java environment + * @param self class calling this function + * @param objId id of class containing the objvar + * @param name name of the objvar + * @param value value to set the objvar to + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsDynamicVariableNamespace::setTransformDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name, jobject value) +{ + UNREF(self); + + if (objId == 0 || name == 0 || value == 0) + return JNI_FALSE; + + if (env->IsInstanceOf(value, JavaLibrary::getClsTransform()) == JNI_FALSE) + return JNI_FALSE; + + char buffer[DynamicVariable::MAX_DYNAMIC_VARIABLE_NAME_LEN]; + ServerObject * object = getObjectAndName(env, objId, name, buffer, sizeof(buffer)); + if (object == NULL) + return JNI_FALSE; + + Transform locValue; + if (!ScriptConversion::convert(value, locValue)) + return JNI_FALSE; + + addSetObjvar(*object, buffer); + + return object->setObjVarItem(buffer, locValue); +} + +/** + * Sets an objvar of type transform[]. + * + * @param env Java environment + * @param self class calling this function + * @param objId id of class containing the objvar + * @param name name of the objvar + * @param value value to set the objvar to + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsDynamicVariableNamespace::setTransformArrayDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name, jobjectArray value) +{ + UNREF(self); + + if (objId == 0 || name == 0 || value == 0) + return JNI_FALSE; + + if (env->IsInstanceOf(value, JavaLibrary::getClsTransformArray()) == JNI_FALSE) + return JNI_FALSE; + + char buffer[DynamicVariable::MAX_DYNAMIC_VARIABLE_NAME_LEN]; + ServerObject * object = getObjectAndName(env, objId, name, buffer, sizeof(buffer)); + if (object == NULL) + return JNI_FALSE; + + std::vector valueArray; + size_t size = env->GetArrayLength(value); + if (size == 0) + { + object->removeObjVarItem(buffer); + JavaLibrary::throwInternalScriptError("JavaLibrary::setTransformArrayDynamicVariable trying to set an array objvar to 0 length. The objvar has been removed instead."); + return false; + } + + valueArray.resize(size); + for (size_t i = 0; i < size; ++i) + { + LocalRefPtr item = getObjectArrayElement(LocalObjectArrayRefParam(value), i); + if (item == LocalRef::cms_nullPtr) + return JNI_FALSE; + Transform &valueItem = valueArray[i]; + if (!ScriptConversion::convert(*item, valueItem)) + return JNI_FALSE; + } + + addSetObjvar(*object, buffer); + + bool result = object->setObjVarItem(buffer, valueArray); + return result; +} + +/** + * Sets an objvar of type vector. + * + * @param env Java environment + * @param self class calling this function + * @param objId id of class containing the objvar + * @param name name of the objvar + * @param value value to set the objvar to + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsDynamicVariableNamespace::setVectorDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name, jobject value) +{ + UNREF(self); + + if (objId == 0 || name == 0 || value == 0) + return JNI_FALSE; + + if (env->IsInstanceOf(value, JavaLibrary::getClsVector()) == JNI_FALSE) + return JNI_FALSE; + + char buffer[DynamicVariable::MAX_DYNAMIC_VARIABLE_NAME_LEN]; + ServerObject * object = getObjectAndName(env, objId, name, buffer, sizeof(buffer)); + if (object == NULL) + return JNI_FALSE; + + Vector locValue; + if (!ScriptConversion::convert(value, locValue)) + return JNI_FALSE; + + addSetObjvar(*object, buffer); + + return object->setObjVarItem(buffer, locValue); +} + +/** + * Sets an objvar of type vector[]. + * + * @param env Java environment + * @param self class calling this function + * @param objId id of class containing the objvar + * @param name name of the objvar + * @param value value to set the objvar to + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsDynamicVariableNamespace::setVectorArrayDynamicVariable(JNIEnv *env, jobject self, jlong objId, jstring name, jobjectArray value) +{ + UNREF(self); + + if (objId == 0 || name == 0 || value == 0) + return JNI_FALSE; + + if (env->IsInstanceOf(value, JavaLibrary::getClsVectorArray()) == JNI_FALSE) + return JNI_FALSE; + + char buffer[DynamicVariable::MAX_DYNAMIC_VARIABLE_NAME_LEN]; + ServerObject * object = getObjectAndName(env, objId, name, buffer, sizeof(buffer)); + if (object == NULL) + return JNI_FALSE; + + std::vector valueArray; + size_t size = env->GetArrayLength(value); + if (size == 0) + { + object->removeObjVarItem(buffer); + JavaLibrary::throwInternalScriptError("JavaLibrary::setVectorArrayDynamicVariable trying to set an array objvar to 0 length. The objvar has been removed instead."); + return false; + } + + valueArray.resize(size); + for (size_t i = 0; i < size; ++i) + { + LocalRefPtr item = getObjectArrayElement(LocalObjectArrayRefParam(value), i); + if (item == LocalRef::cms_nullPtr) + return JNI_FALSE; + Vector &valueItem = valueArray[i]; + if (!ScriptConversion::convert(*item, valueItem)) + return JNI_FALSE; + } + + addSetObjvar(*object, buffer); + + bool result = object->setObjVarItem(buffer, valueArray); + return result; +} + +/** + * Creates an objvar list. + * + * @param env Java environment + * @param self class calling this function + * @param objId id of class containing the objvar + * @param name name of the list + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsDynamicVariableNamespace::setDynamicVariableList(JNIEnv *, jobject, jlong, jstring) +{ + // This is now a no-op, left for compatibility with older scripts. + return JNI_TRUE; +} // JavaLibrary::setDynamicVariableList + +/** + * Copies an objvar from one object to another. + * + * @param env Java environment + * @param self class calling this function + * @param fromId id of object to copy from + * @param toId id of object to copy to + * @param name name of the objvar to copy + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsDynamicVariableNamespace::copyDynamicVariable(JNIEnv *env, jobject self, jlong fromId, jlong toId, jstring name) +{ + UNREF(self); + + JavaStringParam localName(name); + + if (fromId == 0 || toId == 0 || name == 0) + return JNI_FALSE; + + CachedNetworkId from(fromId); + CachedNetworkId to(toId); + + if (from == to) + return JNI_TRUE; + + ServerObject* fromObject = dynamic_cast(from.getObject()); + if (fromObject == NULL) + return JNI_FALSE; + ServerObject* toObject = dynamic_cast(to.getObject()); + if (toObject == NULL) + return JNI_FALSE; + + char buffer[DynamicVariable::MAX_DYNAMIC_VARIABLE_NAME_LEN]; + if (localName.fillBuffer(buffer, sizeof(buffer)) <= 0) + return JNI_FALSE; + + if(toObject->isAuthoritative()) + { + toObject->copyObjVars(buffer, *fromObject, buffer); + } + else + { + std::string stringBuffer(buffer); + toObject->sendControllerMessageToAuthServer(CM_copyDynamicVariable, new MessageQueueGenericValueType > >(std::make_pair(stringBuffer, std::make_pair(from, to)))); + } + return JNI_TRUE; +} // JavaLibrary::copyDynamicVariable + +// ---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsDynamicVariableNamespace::getPackedObjvars(JNIEnv *env, jobject self, jlong source, jstring jprefix) +{ + ServerObject *sourceObj = 0; + if (!JavaLibrary::getObject(source, sourceObj)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::getPackedObjvars: could not find source object")); + else + { + std::string prefix; + if (jprefix) + { + JavaStringParam prefixParam(jprefix); + if (!JavaLibrary::convert(prefixParam, prefix)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::getPackedObjvars: bad prefix string")); + return 0; + } + } + + std::string const &result = sourceObj->getPackedObjVars(prefix); + + return JavaString(result).getReturnValue(); + } + return 0; +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsDynamicVariableNamespace::setPackedObjvars(JNIEnv *env, jobject self, jlong target, jstring packedVars) +{ + ServerObject *targetObj = 0; + if (!JavaLibrary::getObject(target, targetObj)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setPackedObjvars: could not find target object")); + else + { + JavaStringParam localPackedVars(packedVars); + std::string packedVarString; + if (!JavaLibrary::convert(localPackedVars, packedVarString)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setPackedObjvars: bad packed var string")); + else if (!targetObj->setPackedObjVars(packedVarString)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setPackedObjvars: bad packed var string")); + } +} + +// ====================================================================== + diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsForm.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsForm.cpp new file mode 100644 index 00000000..3ca7c226 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsForm.cpp @@ -0,0 +1,149 @@ +// ====================================================================== +// +// ScriptMethodsForm.cpp +// +// Copyright 2003 Sony Online Entertainment +// +// ====================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "serverGame/CreatureObject.h" +#include "serverGame/FormManagerServer.h" +#include "serverGame/ServerObject.h" + +using namespace JNIWrappersNamespace; + + +// ====================================================================== +// ScriptMethodsFormNamespace +// ====================================================================== + +namespace ScriptMethodsFormNamespace +{ + bool install(); + + jboolean JNICALL editFormData(JNIEnv * env, jobject self, jlong player, jlong objectToEdit, jobjectArray keys, jobjectArray values); +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsFormNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsFormNamespace::c)} + JF("_editFormData", "(JJ[Ljava/lang/String;[Ljava/lang/String;)Z", editFormData), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +// ====================================================================== + +jboolean JNICALL ScriptMethodsFormNamespace::editFormData(JNIEnv * env, jobject self, jlong player, jlong jObjectToEdit, jobjectArray jKeys, jobjectArray jValues) +{ + UNREF(self); + ServerObject * playerServerObject = NULL; + if (!JavaLibrary::getObject(player, playerServerObject) || !playerServerObject) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("[script bug] can't get player in editFormData")); + return JNI_FALSE; + } + + CreatureObject * const playerCreatureObject = playerServerObject->asCreatureObject();; + if (!playerCreatureObject) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("[script bug] player is not a CreatureObject in editFormData")); + return JNI_FALSE; + } + + ServerObject * objectToEditServerObject = NULL; + if (!JavaLibrary::getObject(jObjectToEdit, objectToEditServerObject) || !objectToEditServerObject) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("[script bug] objectToEdit is not a ServerObject in editFormData")); + return JNI_FALSE; + } + + int const keysCount = env->GetArrayLength(jKeys); + int const valuesCount = env->GetArrayLength(jValues); + + if(keysCount != valuesCount) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("[script bug] keys and values vectors are different sizes in editFormData")); + return JNI_FALSE; + } + + FormManager::UnpackedFormData dataMap; + + std::string key; + std::string value; + std::vector values; + for (int i = 0; i < keysCount; ++i) + { + JavaString jKey(static_cast(env->GetObjectArrayElement(jKeys, i))); + if (jKey.getValue() != 0) + { + if (!JavaLibrary::convert(jKey, key)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("[script bug] can't convert key value in editFormData")); + return JNI_FALSE; + } + } + JavaString jValue(static_cast(env->GetObjectArrayElement(jValues, i))); + if (jValue.getValue() != 0) + { + if (!JavaLibrary::convert(jValue, value)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("[script bug] can't convert value in editFormData")); + return JNI_FALSE; + } + } + values.clear(); + values.push_back(value); + /*TODO handle lists*/ + dataMap[key] = values; + } + + //override what we've been given with data from any appropriate objvar bindings + + //get matching form + FormManager::Form const * const form = FormManagerServer::getFormForServerObjectTemplate(objectToEditServerObject->getTemplateName()); + if(!form) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("[script bug] objectToEdit does not have a form binding, cannot modify")); + return JNI_FALSE; + } + + + //build a list of all the fields that DON'T have objvar bindings (since script will need to tell us about them in JavaLibrary::editFormData + DynamicVariableList const & objvars = objectToEditServerObject->getObjVars(); + std::vector const & fields = form->getOrderedFieldList(); + for(std::vector::const_iterator i2 = fields.begin(); i2 != fields.end(); ++i2) + { + FormManager::Field const * const field = *i2; + if(!field) + continue; + + std::string const & objvarBinding = field->getObjvarBinding(); + if(!objvarBinding.empty()) + { + //TODO handle non-strings + objvars.getItem(objvarBinding, value); + } + values.clear(); + values.push_back(value); + /*TODO handle lists*/ + dataMap[field->getName()] = values; + } + + FormManagerServer::sendEditObjectDataToClient(playerCreatureObject->getNetworkId(),objectToEditServerObject->getNetworkId(), dataMap); + return JNI_TRUE; +} + +// ====================================================================== + diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsGlobalQuery.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsGlobalQuery.cpp new file mode 100644 index 00000000..8d910f2f --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsGlobalQuery.cpp @@ -0,0 +1,82 @@ +// ====================================================================== +// +// ScriptMethodsGlobalQuery.cpp +// +// Copyright 2002 Sony Online Entertainment +// +// ====================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "serverGame/GameServer.h" +#include "serverGame/NameManager.h" +#include "sharedFoundation/NetworkId.h" +#include "sharedFoundation/NetworkIdArchive.h" + +using namespace JNIWrappersNamespace; + + +// ====================================================================== +// ScriptMethodsGlobalQueryNamespace +// ====================================================================== + +namespace ScriptMethodsGlobalQueryNamespace +{ + bool install(); + + jlong JNICALL getPlayerIdFromFirstName(JNIEnv *env, jobject self, jstring firstName); + jboolean JNICALL playerExists(JNIEnv *env, jobject self, jlong playerId); + jstring JNICALL localize(JNIEnv *env, jobject self, jobject id); +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsGlobalQueryNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsGlobalQueryNamespace::c)} + JF("_getPlayerIdFromFirstName", "(Ljava/lang/String;)J", getPlayerIdFromFirstName), + JF("_playerExists", "(J)Z", playerExists), + JF("localize", "(Lscript/string_id;)Ljava/lang/String;", localize), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +// ====================================================================== + +jlong JNICALL ScriptMethodsGlobalQueryNamespace::getPlayerIdFromFirstName(JNIEnv *env, jobject self, jstring firstName) +{ + std::string firstNameString; + JavaLibrary::convert(JavaStringParam(firstName), firstNameString); + return (NameManager::getInstance().getPlayerId(NameManager::normalizeName(firstNameString))).getValue(); +} + +// ---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsGlobalQueryNamespace::localize(JNIEnv *env, jobject self, jobject id) +{ + StringId textStringId; + if (!ScriptConversion::convert(id, textStringId)) + return 0; + Unicode::String textString; + if (!textStringId.localize(textString)) + return 0; + return JavaString(textString).getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsGlobalQueryNamespace::playerExists(JNIEnv *env, jobject self, jlong playerId) +{ + NetworkId playerNetworkId(playerId); + return !NameManager::getInstance().getPlayerName(playerNetworkId).empty(); +} + +// ====================================================================== + diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsGuild.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsGuild.cpp new file mode 100644 index 00000000..ae008fcf --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsGuild.cpp @@ -0,0 +1,832 @@ +// ====================================================================== +// +// ScriptMethodsGuild.cpp +// +// Copyright 2002 Sony Online Entertainment +// +// ====================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" +#include "serverGame/CreatureObject.h" +#include "serverGame/GuildInterface.h" +#include "serverGame/GuildMemberInfo.h" +#include "serverGame/GuildObject.h" +#include "serverGame/ServerUniverse.h" +#include "sharedGame/GuildRankDataTable.h" + +using namespace JNIWrappersNamespace; + + +// ====================================================================== +// ScriptMethodsGuildNamespace +// ====================================================================== + +namespace ScriptMethodsGuildNamespace +{ + bool install(); + + jint JNICALL getGuildId(JNIEnv *env, jobject self, jlong target); + jintArray JNICALL getAllGuildIds(JNIEnv *env, jobject self); + jlong JNICALL getMasterGuildObject(JNIEnv *env, jobject self); + jintArray JNICALL getGuildsAtWarWith(JNIEnv *env, jobject self, jint guildId); + jobject JNICALL getMasterGuildWarTableDictionary(JNIEnv * env, jobject self); + jobject JNICALL getInactiveGuildWarTableDictionary(JNIEnv * env, jobject self); + jint JNICALL findGuild(JNIEnv *env, jobject self, jstring name); + jint JNICALL createGuild(JNIEnv *env, jobject self, jstring name, jstring abbrev); + void JNICALL disbandGuild(JNIEnv *env, jobject self, jint guildId); + jboolean JNICALL guildExists(JNIEnv *env, jobject self, jint guildId); + jstring JNICALL guildGetName(JNIEnv *env, jobject self, jint guildId); + jstring JNICALL guildGetAbbrev(JNIEnv *env, jobject self, jint guildId); + jlong JNICALL guildGetLeader(JNIEnv *env, jobject self, jint guildId); + jint JNICALL guildGetElectionPreviousEndTime(JNIEnv *env, jobject self, jint guildId); + jint JNICALL guildGetElectionNextEndTime(JNIEnv *env, jobject self, jint guildId); + jint JNICALL guildGetCurrentFaction(JNIEnv *env, jobject self, jint guildId); + jint JNICALL guildGetPreviousFaction(JNIEnv *env, jobject self, jint guildId); + jint JNICALL guildGetTimeLeftPreviousFaction(JNIEnv *env, jobject self, jint guildId); + jstring JNICALL guildGetCurrentGcwDefenderRegion(JNIEnv *env, jobject self, jint guildId); + jint JNICALL guildGetTimeJoinedCurrentGcwDefenderRegion(JNIEnv *env, jobject self, jint guildId); + jstring JNICALL guildGetPreviousGcwDefenderRegion(JNIEnv *env, jobject self, jint guildId); + jint JNICALL guildGetTimeLeftPreviousGcwDefenderRegion(JNIEnv *env, jobject self, jint guildId); + jlongArray JNICALL guildGetMemberIds(JNIEnv *env, jobject self, jint guildId); + jlongArray JNICALL guildGetMemberIdsWithPermissions(JNIEnv *env, jobject self, jint guildId, jint permissions); + jint JNICALL guildGetCountMembersOnly(JNIEnv *env, jobject self, jint guildId); + jint JNICALL guildGetCountSponsoredOnly(JNIEnv *env, jobject self, jint guildId); + jint JNICALL guildGetCountMembersAndSponsored(JNIEnv *env, jobject self, jint guildId); + jint JNICALL guildGetCountMembersGuildWarPvPEnabled(JNIEnv *env, jobject self, jint guildId); + jstring JNICALL guildGetMemberName(JNIEnv *env, jobject self, jint guildId, jlong member); + jstring JNICALL guildGetMemberProfession(JNIEnv *env, jobject self, jint guildId, jlong member); + jint JNICALL guildGetMemberLevel(JNIEnv *env, jobject self, jint guildId, jlong member); + jint JNICALL guildGetMemberPermissions(JNIEnv *env, jobject self, jint guildId, jlong member); + jstring JNICALL guildGetMemberTitle(JNIEnv *env, jobject self, jint guildId, jlong member); + jlong JNICALL guildGetMemberAllegiance(JNIEnv *env, jobject self, jint guildId, jlong member); + jintArray JNICALL guildGetEnemies(JNIEnv *env, jobject self, jint guildId); + void JNICALL guildRemoveMember(JNIEnv *env, jobject self, jint guildId, jlong member); + void JNICALL guildAddCreatorMember(JNIEnv *env, jobject self, jint guildId, jlong member); + void JNICALL guildAddSponsorMember(JNIEnv *env, jobject self, jint guildId, jlong member); + void JNICALL guildSetMemberPermission(JNIEnv *env, jobject self, jint guildId, jlong member, jint permissions); + void JNICALL guildSetMemberTitle(JNIEnv *env, jobject self, jint guildId, jlong member, jstring title); + void JNICALL guildSetMemberAllegiance(JNIEnv *env, jobject self, jint guildId, jlong member, jlong allegiance); + void JNICALL guildSetMemberPermissionAndAllegiance(JNIEnv *env, jobject self, jint guildId, jlong member, jint permissions, jlong allegiance); + jobjectArray JNICALL guildGetAllRanks(JNIEnv *env, jobject self); + jobjectArray JNICALL guildGetTitleForRank(JNIEnv *env, jobject self, jstring rank); + jobjectArray JNICALL guildGetMemberRank(JNIEnv *env, jobject self, jint guildId, jlong member); + jboolean JNICALL guildHasMemberRank(JNIEnv *env, jobject self, jint guildId, jlong member, jstring rank); + void JNICALL guildAddMemberRank(JNIEnv *env, jobject self, jint guildId, jlong member, jstring rank); + void JNICALL guildRemoveMemberRank(JNIEnv *env, jobject self, jint guildId, jlong member, jstring rank); + void JNICALL guildSetLeader(JNIEnv *env, jobject self, jint guildId, jlong leader); + void JNICALL guildSetElectionEndTime(JNIEnv *env, jobject self, jint guildId, jint electionPreviousEndTime, jint electionNextEndTime); + void JNICALL guildSetFaction(JNIEnv *env, jobject self, jint guildId, jint factionId); + void JNICALL guildSetGcwDefenderRegion(JNIEnv *env, jobject self, jint guildId, jstring gcwDefenderRegion); + void JNICALL guildRemoveEnemy(JNIEnv *env, jobject self, jint guildId, jint enemyId); + void JNICALL guildSetEnemy(JNIEnv *env, jobject self, jint guildId, jint enemyId); + void JNICALL guildUpdateGuildWarKillTracking(JNIEnv *env, jobject self, jlong killer, jlong victim); + jint JNICALL guildGetGuildWarKillCount(JNIEnv *env, jobject self, jint guildIdA, jint guildIdB); + jint JNICALL guildGetGuildWarKillCountUpdateTime(JNIEnv *env, jobject self, jint guildIdA, jint guildIdB); + void JNICALL guildSetName(JNIEnv *env, jobject self, jint guildId, jstring name); + void JNICALL guildSetAbbrev(JNIEnv *env, jobject self, jint guildId, jstring abbrev); +} + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsGuildNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsGuildNamespace::c)} + JF("_getGuildId", "(J)I", getGuildId), + JF("getAllGuildIds", "()[I", getAllGuildIds), + JF("_getMasterGuildObject", "()J", getMasterGuildObject), + JF("findGuild", "(Ljava/lang/String;)I", findGuild), + JF("createGuild", "(Ljava/lang/String;Ljava/lang/String;)I", createGuild), + JF("disbandGuild", "(I)V", disbandGuild), + JF("guildExists", "(I)Z", guildExists), + JF("guildGetName", "(I)Ljava/lang/String;", guildGetName), + JF("guildGetAbbrev", "(I)Ljava/lang/String;", guildGetAbbrev), + JF("_guildGetLeader", "(I)J", guildGetLeader), + JF("guildGetElectionPreviousEndTime", "(I)I", guildGetElectionPreviousEndTime), + JF("guildGetElectionNextEndTime", "(I)I", guildGetElectionNextEndTime), + JF("guildGetCurrentFaction", "(I)I", guildGetCurrentFaction), + JF("guildGetPreviousFaction", "(I)I", guildGetPreviousFaction), + JF("guildGetTimeLeftPreviousFaction", "(I)I", guildGetTimeLeftPreviousFaction), + JF("guildGetCurrentGcwDefenderRegion", "(I)Ljava/lang/String;", guildGetCurrentGcwDefenderRegion), + JF("guildGetTimeJoinedCurrentGcwDefenderRegion", "(I)I", guildGetTimeJoinedCurrentGcwDefenderRegion), + JF("guildGetPreviousGcwDefenderRegion", "(I)Ljava/lang/String;", guildGetPreviousGcwDefenderRegion), + JF("guildGetTimeLeftPreviousGcwDefenderRegion", "(I)I", guildGetTimeLeftPreviousGcwDefenderRegion), + JF("_guildGetMemberIds", "(I)[J", guildGetMemberIds), + JF("_guildGetMemberIdsWithPermissions", "(II)[J", guildGetMemberIdsWithPermissions), + JF("guildGetCountMembersOnly", "(I)I", guildGetCountMembersOnly), + JF("guildGetCountSponsoredOnly", "(I)I", guildGetCountSponsoredOnly), + JF("guildGetCountMembersAndSponsored", "(I)I", guildGetCountMembersAndSponsored), + JF("guildGetCountMembersGuildWarPvPEnabled", "(I)I", guildGetCountMembersGuildWarPvPEnabled), + JF("_guildGetMemberName", "(IJ)Ljava/lang/String;", guildGetMemberName), + JF("_guildGetMemberProfession", "(IJ)Ljava/lang/String;", guildGetMemberProfession), + JF("_guildGetMemberLevel", "(IJ)I", guildGetMemberLevel), + JF("_guildGetMemberPermissions", "(IJ)I", guildGetMemberPermissions), + JF("_guildGetMemberTitle", "(IJ)Ljava/lang/String;", guildGetMemberTitle), + JF("_guildGetMemberAllegiance", "(IJ)J", guildGetMemberAllegiance), + JF("guildGetEnemies", "(I)[I", guildGetEnemies), + JF("getGuildsAtWarWith", "(I)[I", getGuildsAtWarWith), + JF("getMasterGuildWarTableDictionary", "()Lscript/dictionary;", getMasterGuildWarTableDictionary), + JF("getInactiveGuildWarTableDictionary", "()Lscript/dictionary;", getInactiveGuildWarTableDictionary), + JF("_guildRemoveMember", "(IJ)V", guildRemoveMember), + JF("_guildAddCreatorMember", "(IJ)V", guildAddCreatorMember), + JF("_guildAddSponsorMember", "(IJ)V", guildAddSponsorMember), + JF("_guildSetMemberPermission", "(IJI)V", guildSetMemberPermission), + JF("_guildSetMemberTitle", "(IJLjava/lang/String;)V", guildSetMemberTitle), + JF("_guildSetMemberAllegiance", "(IJJ)V", guildSetMemberAllegiance), + JF("_guildSetMemberPermissionAndAllegiance", "(IJIJ)V", guildSetMemberPermissionAndAllegiance), + JF("guildGetAllRanks", "()[Ljava/lang/String;", guildGetAllRanks), + JF("guildGetTitleForRank", "(Ljava/lang/String;)[Ljava/lang/String;", guildGetTitleForRank), + JF("_guildGetMemberRank", "(IJ)[Ljava/lang/String;", guildGetMemberRank), + JF("_guildHasMemberRank", "(IJLjava/lang/String;)Z", guildHasMemberRank), + JF("_guildAddMemberRank", "(IJLjava/lang/String;)V", guildAddMemberRank), + JF("_guildRemoveMemberRank", "(IJLjava/lang/String;)V", guildRemoveMemberRank), + JF("_guildSetLeader", "(IJ)V", guildSetLeader), + JF("guildSetElectionEndTime", "(III)V", guildSetElectionEndTime), + JF("guildSetFaction", "(II)V", guildSetFaction), + JF("guildSetGcwDefenderRegion", "(ILjava/lang/String;)V", guildSetGcwDefenderRegion), + JF("guildRemoveEnemy", "(II)V", guildRemoveEnemy), + JF("guildSetEnemy", "(II)V", guildSetEnemy), + JF("_guildUpdateGuildWarKillTracking", "(JJ)V", guildUpdateGuildWarKillTracking), + JF("guildGetGuildWarKillCount", "(II)I", guildGetGuildWarKillCount), + JF("guildGetGuildWarKillCountUpdateTime", "(II)I", guildGetGuildWarKillCountUpdateTime), + JF("guildSetName", "(ILjava/lang/String;)V", guildSetName), + JF("guildSetAbbrev", "(ILjava/lang/String;)V", guildSetAbbrev), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +// ====================================================================== + +jint JNICALL ScriptMethodsGuildNamespace::getGuildId(JNIEnv *env, jobject self, jlong target) +{ + CreatureObject *targetObj = 0; + if (!JavaLibrary::getObject(target, targetObj)) + { + DEBUG_WARNING(true, ("JavaLibrary::getGuildId: called with invalid target")); + return 0; + } + return targetObj->getGuildId(); +} + +// ---------------------------------------------------------------------- + +jintArray JNICALL ScriptMethodsGuildNamespace::getAllGuildIds(JNIEnv *env, jobject self) +{ + std::vector guildIds; + GuildInterface::getAllGuildIds(guildIds); + LocalIntArrayRefPtr ret = createNewIntArray(guildIds.size()); + if (!guildIds.empty()) + setIntArrayRegion(*ret, 0, guildIds.size(), reinterpret_cast(&guildIds[0])); + return ret->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsGuildNamespace::getMasterGuildObject(JNIEnv *env, jobject self) +{ + GuildObject *masterGuildObject = ServerUniverse::getInstance().getMasterGuildObject(); + return masterGuildObject ? (masterGuildObject->getNetworkId()).getValue() : (NetworkId::cms_invalid).getValue(); +} + +// ---------------------------------------------------------------------- + +jintArray JNICALL ScriptMethodsGuildNamespace::getGuildsAtWarWith(JNIEnv *env, jobject self, jint guildId) +{ + std::vector const &enemies = GuildInterface::getGuildsAtWarWith(guildId); + LocalIntArrayRefPtr ret = createNewIntArray(enemies.size()); + if (!enemies.empty()) + setIntArrayRegion(*ret, 0, enemies.size(), const_cast(reinterpret_cast(&enemies[0]))); + return ret->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jobject JNICALL ScriptMethodsGuildNamespace::getMasterGuildWarTableDictionary(JNIEnv * env, jobject self) +{ + ScriptParams const * scriptParams = GuildInterface::getMasterGuildWarTableDictionary(); + if (!scriptParams) + return 0; + + JavaDictionaryPtr dictionary; + JavaLibrary::instance()->convert(*scriptParams, dictionary); + return dictionary->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jobject JNICALL ScriptMethodsGuildNamespace::getInactiveGuildWarTableDictionary(JNIEnv * env, jobject self) +{ + ScriptParams const * scriptParams = GuildInterface::getInactiveGuildWarTableDictionary(); + if (!scriptParams) + return 0; + + JavaDictionaryPtr dictionary; + JavaLibrary::instance()->convert(*scriptParams, dictionary); + return dictionary->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsGuildNamespace::findGuild(JNIEnv *env, jobject self, jstring name) +{ + JavaStringParam localNameStr(name); + std::string nameStr; + if (!JavaLibrary::convert(localNameStr, nameStr)) + { + DEBUG_WARNING(true, ("JavaLibrary::findGuild: invalid name")); + return 0; + } + return GuildInterface::findGuild(nameStr); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsGuildNamespace::createGuild(JNIEnv *env, jobject self, jstring name, jstring abbrev) +{ + JavaStringParam localNameStr(name); + std::string nameStr; + if (!JavaLibrary::convert(localNameStr, nameStr)) + { + DEBUG_WARNING(true, ("JavaLibrary::createGuild: invalid name")); + return 0; + } + + JavaStringParam localAbbrevStr(abbrev); + std::string abbrevStr; + if (!JavaLibrary::convert(localAbbrevStr, abbrevStr)) + { + DEBUG_WARNING(true, ("JavaLibrary::createGuild: invalid abbrev")); + return 0; + } + + return GuildInterface::createGuild(nameStr, abbrevStr); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsGuildNamespace::disbandGuild(JNIEnv *env, jobject self, jint guildId) +{ + GuildInterface::disbandGuild(guildId); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsGuildNamespace::guildExists(JNIEnv *env, jobject self, jint guildId) +{ + return GuildInterface::guildExists(guildId); +} + +// ---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsGuildNamespace::guildGetName(JNIEnv *env, jobject self, jint guildId) +{ + JavaString str(GuildInterface::getGuildName(guildId).c_str()); + return str.getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsGuildNamespace::guildGetAbbrev(JNIEnv *env, jobject self, jint guildId) +{ + JavaString str(GuildInterface::getGuildAbbrev(guildId).c_str()); + return str.getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsGuildNamespace::guildGetLeader(JNIEnv *env, jobject self, jint guildId) +{ + return (GuildInterface::getGuildLeaderId(guildId)).getValue(); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsGuildNamespace::guildGetElectionPreviousEndTime(JNIEnv *env, jobject self, jint guildId) +{ + return GuildInterface::getGuildElectionPreviousEndTime(guildId); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsGuildNamespace::guildGetElectionNextEndTime(JNIEnv *env, jobject self, jint guildId) +{ + return GuildInterface::getGuildElectionNextEndTime(guildId); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsGuildNamespace::guildGetCurrentFaction(JNIEnv *env, jobject self, jint guildId) +{ + return static_cast(GuildInterface::getGuildCurrentFaction(guildId)); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsGuildNamespace::guildGetPreviousFaction(JNIEnv *env, jobject self, jint guildId) +{ + return static_cast(GuildInterface::getGuildPreviousFaction(guildId)); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsGuildNamespace::guildGetTimeLeftPreviousFaction(JNIEnv *env, jobject self, jint guildId) +{ + return GuildInterface::getTimeLeftGuildPreviousFaction(guildId); +} + +// ---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsGuildNamespace::guildGetCurrentGcwDefenderRegion(JNIEnv *env, jobject self, jint guildId) +{ + JavaString str(GuildInterface::getGuildCurrentGcwDefenderRegion(guildId).c_str()); + return str.getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsGuildNamespace::guildGetTimeJoinedCurrentGcwDefenderRegion(JNIEnv *env, jobject self, jint guildId) +{ + return GuildInterface::getTimeJoinedGuildCurrentGcwDefenderRegion(guildId); +} + +// ---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsGuildNamespace::guildGetPreviousGcwDefenderRegion(JNIEnv *env, jobject self, jint guildId) +{ + JavaString str(GuildInterface::getGuildPreviousGcwDefenderRegion(guildId).c_str()); + return str.getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsGuildNamespace::guildGetTimeLeftPreviousGcwDefenderRegion(JNIEnv *env, jobject self, jint guildId) +{ + return GuildInterface::getTimeLeftGuildPreviousGcwDefenderRegion(guildId); +} + +// ---------------------------------------------------------------------- + +jlongArray JNICALL ScriptMethodsGuildNamespace::guildGetMemberIds(JNIEnv *env, jobject self, jint guildId) +{ + std::vector results; + GuildInterface::getGuildMemberIds(guildId, results); + LocalLongArrayRefPtr rv; + if (ScriptConversion::convert(results, rv)) + return rv->getReturnValue(); + return 0; +} + +// ---------------------------------------------------------------------- + +jlongArray JNICALL ScriptMethodsGuildNamespace::guildGetMemberIdsWithPermissions(JNIEnv *env, jobject self, jint guildId, jint permissions) +{ + std::vector results; + GuildInterface::getGuildMemberIdsWithPermissions(guildId, permissions, results); + if (results.empty()) + return 0; + + LocalLongArrayRefPtr rv; + if (ScriptConversion::convert(results, rv)) + return rv->getReturnValue(); + + return 0; +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsGuildNamespace::guildGetCountMembersOnly(JNIEnv *env, jobject self, jint guildId) +{ + return GuildInterface::getGuildCountMembersOnly(guildId); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsGuildNamespace::guildGetCountSponsoredOnly(JNIEnv *env, jobject self, jint guildId) +{ + return GuildInterface::getGuildCountSponsoredOnly(guildId); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsGuildNamespace::guildGetCountMembersAndSponsored(JNIEnv *env, jobject self, jint guildId) +{ + return GuildInterface::getGuildCountMembersAndSponsored(guildId); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsGuildNamespace::guildGetCountMembersGuildWarPvPEnabled(JNIEnv *env, jobject self, jint guildId) +{ + return GuildInterface::getGuildCountMembersGuildWarPvPEnabled(guildId); +} + +// ---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsGuildNamespace::guildGetMemberName(JNIEnv *env, jobject self, jint guildId, jlong member) +{ + NetworkId memberId(member); + GuildMemberInfo const *memberInfo = GuildInterface::getGuildMemberInfo(guildId, memberId); + if (memberInfo) + { + JavaString str(memberInfo->m_name.c_str()); + return str.getReturnValue(); + } + DEBUG_WARNING(true, ("JavaLibrary::guildGetMemberName called with invalid info (guildId=%d memberId=%s)", guildId, memberId.getValueString().c_str())); + return 0; +} + +// ---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsGuildNamespace::guildGetMemberProfession(JNIEnv *env, jobject self, jint guildId, jlong member) +{ + NetworkId memberId(member); + GuildMemberInfo const *memberInfo = GuildInterface::getGuildMemberInfo(guildId, memberId); + if (memberInfo) + { + JavaString str(memberInfo->m_professionSkillTemplate.c_str()); + return str.getReturnValue(); + } + DEBUG_WARNING(true, ("JavaLibrary::guildGetMemberProfession called with invalid info (guildId=%d memberId=%s)", guildId, memberId.getValueString().c_str())); + return 0; +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsGuildNamespace::guildGetMemberLevel(JNIEnv *env, jobject self, jint guildId, jlong member) +{ + NetworkId memberId(member); + GuildMemberInfo const *memberInfo = GuildInterface::getGuildMemberInfo(guildId, memberId); + if (memberInfo) + return memberInfo->m_level; + DEBUG_WARNING(true, ("JavaLibrary::guildGetMemberLevel called with invalid info (guildId=%d memberId=%s)", guildId, memberId.getValueString().c_str())); + return 0; +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsGuildNamespace::guildGetMemberPermissions(JNIEnv *env, jobject self, jint guildId, jlong member) +{ + NetworkId memberId(member); + GuildMemberInfo const *memberInfo = GuildInterface::getGuildMemberInfo(guildId, memberId); + if (memberInfo) + return memberInfo->m_permissions; + DEBUG_WARNING(true, ("JavaLibrary::guildGetMemberPermissions called with invalid info (guildId=%d memberId=%s)", guildId, memberId.getValueString().c_str())); + return 0; +} + +// ---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsGuildNamespace::guildGetMemberTitle(JNIEnv *env, jobject self, jint guildId, jlong member) +{ + NetworkId memberId(member); + GuildMemberInfo const *memberInfo = GuildInterface::getGuildMemberInfo(guildId, memberId); + if (memberInfo) + { + JavaString str(memberInfo->m_title.c_str()); + return str.getReturnValue(); + } + DEBUG_WARNING(true, ("JavaLibrary::guildGetMemberTitle called with invalid info (guildId=%d memberId=%s)", guildId, memberId.getValueString().c_str())); + return 0; +} + +// ---------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsGuildNamespace::guildGetMemberAllegiance(JNIEnv *env, jobject self, jint guildId, jlong member) +{ + NetworkId memberId(member); + GuildMemberInfo const *memberInfo = GuildInterface::getGuildMemberInfo(guildId, memberId); + if (memberInfo) + return (memberInfo->m_allegiance).getValue(); + DEBUG_WARNING(true, ("JavaLibrary::guildGetMemberAllegiance called with invalid info (guildId=%d memberId=%s)", guildId, memberId.getValueString().c_str())); + return 0; +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsGuildNamespace::guildRemoveMember(JNIEnv *env, jobject self, jint guildId, jlong member) +{ + NetworkId memberId(member); + GuildInterface::removeGuildMember(guildId, memberId); +} + +// ---------------------------------------------------------------------- + +jintArray JNICALL ScriptMethodsGuildNamespace::guildGetEnemies(JNIEnv *env, jobject self, jint guildId) +{ + std::vector const &enemies = GuildInterface::getGuildEnemies(guildId); + LocalIntArrayRefPtr ret = createNewIntArray(enemies.size()); + if (!enemies.empty()) + setIntArrayRegion(*ret, 0, enemies.size(), const_cast(reinterpret_cast(&enemies[0]))); + return ret->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsGuildNamespace::guildSetLeader(JNIEnv *env, jobject self, jint guildId, jlong leader) +{ + NetworkId leaderId(leader); + GuildInterface::setGuildLeader(guildId, leaderId); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsGuildNamespace::guildSetElectionEndTime(JNIEnv *env, jobject self, jint guildId, jint electionPreviousEndTime, jint electionNextEndTime) +{ + GuildInterface::setGuildElectionEndTime(guildId, electionPreviousEndTime, electionNextEndTime); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsGuildNamespace::guildSetFaction(JNIEnv *env, jobject self, jint guildId, jint factionId) +{ + GuildInterface::setGuildFaction(guildId, static_cast(factionId)); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsGuildNamespace::guildSetGcwDefenderRegion(JNIEnv *env, jobject self, jint guildId, jstring gcwDefenderRegion) +{ + JavaStringParam localGcwDefenderRegionStr(gcwDefenderRegion); + std::string gcwDefenderRegionStr; + if (JavaLibrary::convert(localGcwDefenderRegionStr, gcwDefenderRegionStr)) + { + if (!gcwDefenderRegionStr.empty()) + { + Pvp::GcwScoreCategory const * const gcwCategory = Pvp::getGcwScoreCategory(gcwDefenderRegionStr); + if (!gcwCategory) + { + DEBUG_WARNING(true, ("JavaLibrary::guildSetGcwDefenderRegion: invalid GCW score category (%s)", gcwDefenderRegionStr.c_str())); + return; + } + + if (!gcwCategory->gcwRegionDefender) + { + DEBUG_WARNING(true, ("JavaLibrary::guildSetGcwDefenderRegion: GCW score category (%s) is not flagged as GcwRegionDefender", gcwDefenderRegionStr.c_str())); + return; + } + } + } + else + { + gcwDefenderRegionStr.clear(); + } + + GuildInterface::setGuildGcwDefenderRegion(guildId, gcwDefenderRegionStr); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsGuildNamespace::guildAddCreatorMember(JNIEnv *env, jobject self, jint guildId, jlong member) +{ + NetworkId memberId(member); + GuildInterface::addGuildCreatorMember(guildId, memberId); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsGuildNamespace::guildAddSponsorMember(JNIEnv *env, jobject self, jint guildId, jlong member) +{ + NetworkId memberId(member); + GuildInterface::addGuildSponsorMember(guildId, memberId); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsGuildNamespace::guildSetMemberPermission(JNIEnv *env, jobject self, jint guildId, jlong member, jint permissions) +{ + NetworkId memberId(member); + GuildInterface::setGuildMemberPermission(guildId, memberId, permissions); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsGuildNamespace::guildSetMemberTitle(JNIEnv *env, jobject self, jint guildId, jlong member, jstring title) +{ + NetworkId memberId(member); + + JavaStringParam localTitleStr(title); + std::string titleStr; + if (!JavaLibrary::convert(localTitleStr, titleStr)) + { + DEBUG_WARNING(true, ("JavaLibrary::guildSetMemberTitle: invalid title")); + return; + } + + GuildInterface::setGuildMemberTitle(guildId, memberId, titleStr); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsGuildNamespace::guildSetMemberAllegiance(JNIEnv *env, jobject self, jint guildId, jlong member, jlong allegiance) +{ + NetworkId memberId(member); + NetworkId allegianceId(allegiance); + GuildInterface::setGuildMemberAllegiance(guildId, memberId, allegianceId); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsGuildNamespace::guildSetMemberPermissionAndAllegiance(JNIEnv *env, jobject self, jint guildId, jlong member, jint permissions, jlong allegiance) +{ + NetworkId memberId(member); + NetworkId allegianceId(allegiance); + GuildInterface::setGuildMemberPermissionAndAllegiance(guildId, memberId, permissions, allegianceId); +} + +// ---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsGuildNamespace::guildGetAllRanks(JNIEnv *env, jobject self) +{ + std::vector const & ranks = GuildRankDataTable::getAllRanks(); + if (ranks.empty()) + return 0; + + int i = 0; + LocalObjectArrayRefPtr valueArray = createNewObjectArray(ranks.size(), JavaLibrary::getClsString()); + for (std::vector::const_iterator iter = ranks.begin(); iter != ranks.end(); ++iter) + { + JavaString jval((*iter)->name); + setObjectArrayElement(*valueArray, i++, jval); + } + + return valueArray->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsGuildNamespace::guildGetTitleForRank(JNIEnv *env, jobject self, jstring rank) +{ + JavaStringParam localRankStr(rank); + std::string rankStr; + if (!JavaLibrary::convert(localRankStr, rankStr)) + { + DEBUG_WARNING(true, ("JavaLibrary::guildGetTitleForRank: invalid rank")); + return 0; + } + + GuildRankDataTable::GuildRank const * rankInfo = GuildRankDataTable::getRank(rankStr); + if (!rankInfo || rankInfo->titles.empty()) + return 0; + + int i = 0; + LocalObjectArrayRefPtr valueArray = createNewObjectArray(rankInfo->titles.size(), JavaLibrary::getClsString()); + for (std::vector::const_iterator iter = rankInfo->titles.begin(); iter != rankInfo->titles.end(); ++iter) + { + JavaString jval(*iter); + setObjectArrayElement(*valueArray, i++, jval); + } + + return valueArray->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsGuildNamespace::guildGetMemberRank(JNIEnv *env, jobject self, jint guildId, jlong member) +{ + std::vector ranks; + GuildInterface::getGuildMemberRank(guildId, NetworkId(static_cast(member)), ranks); + if (ranks.empty()) + return 0; + + int i = 0; + LocalObjectArrayRefPtr valueArray = createNewObjectArray(ranks.size(), JavaLibrary::getClsString()); + for (std::vector::const_iterator iter = ranks.begin(); iter != ranks.end(); ++iter) + { + JavaString jval(*iter); + setObjectArrayElement(*valueArray, i++, jval); + } + + return valueArray->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsGuildNamespace::guildHasMemberRank(JNIEnv *env, jobject self, jint guildId, jlong member, jstring rank) +{ + NetworkId memberId(member); + + JavaStringParam localRankStr(rank); + std::string rankStr; + if (!JavaLibrary::convert(localRankStr, rankStr)) + { + DEBUG_WARNING(true, ("JavaLibrary::guildHasMemberRank: invalid rank")); + return JNI_FALSE; + } + + return GuildInterface::hasGuildMemberRank(guildId, memberId, rankStr); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsGuildNamespace::guildAddMemberRank(JNIEnv *env, jobject self, jint guildId, jlong member, jstring rank) +{ + NetworkId memberId(member); + + JavaStringParam localRankStr(rank); + std::string rankStr; + if (!JavaLibrary::convert(localRankStr, rankStr)) + { + DEBUG_WARNING(true, ("JavaLibrary::guildAddMemberRank: invalid rank")); + return; + } + + GuildInterface::addGuildMemberRank(guildId, memberId, rankStr); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsGuildNamespace::guildRemoveMemberRank(JNIEnv *env, jobject self, jint guildId, jlong member, jstring rank) +{ + NetworkId memberId(member); + + JavaStringParam localRankStr(rank); + std::string rankStr; + if (!JavaLibrary::convert(localRankStr, rankStr)) + { + DEBUG_WARNING(true, ("JavaLibrary::guildRemoveMemberRank: invalid rank")); + return; + } + + GuildInterface::removeGuildMemberRank(guildId, memberId, rankStr); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsGuildNamespace::guildRemoveEnemy(JNIEnv *env, jobject self, jint guildId, jint enemyId) +{ + GuildInterface::removeGuildEnemy(guildId, enemyId); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsGuildNamespace::guildSetEnemy(JNIEnv *env, jobject self, jint guildId, jint enemyId) +{ + GuildInterface::setGuildEnemy(guildId, enemyId); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsGuildNamespace::guildUpdateGuildWarKillTracking(JNIEnv *env, jobject self, jlong killer, jlong victim) +{ + CreatureObject const *killerObj = 0; + if (!JavaLibrary::getObject(killer, killerObj)) + return; + + CreatureObject const *victimObj = 0; + if (!JavaLibrary::getObject(victim, victimObj)) + return; + + if (killerObj && victimObj) + GuildInterface::updateGuildWarKillTracking(*killerObj, *victimObj); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsGuildNamespace::guildGetGuildWarKillCount(JNIEnv *env, jobject self, jint guildIdA, jint guildIdB) +{ + return GuildInterface::getGuildEnemyKillInfo(guildIdA, guildIdB).first; +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsGuildNamespace::guildGetGuildWarKillCountUpdateTime(JNIEnv *env, jobject self, jint guildIdA, jint guildIdB) +{ + return GuildInterface::getGuildEnemyKillInfo(guildIdA, guildIdB).second; +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsGuildNamespace::guildSetName(JNIEnv *env, jobject self, jint guildId, jstring name) +{ + JavaStringParam localNewNameStr(name); + std::string newNameStr; + if (!JavaLibrary::convert(localNewNameStr, newNameStr)) + { + DEBUG_WARNING(true, ("JavaLibrary::guildSetName: invalid name")); + return; + } + GuildInterface::setGuildName(guildId, newNameStr); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsGuildNamespace::guildSetAbbrev(JNIEnv *env, jobject self, jint guildId, jstring abbrev) +{ + JavaStringParam localNewAbbrevStr(abbrev); + std::string newAbbrevStr; + if (!JavaLibrary::convert(localNewAbbrevStr, newAbbrevStr)) + { + DEBUG_WARNING(true, ("JavaLibrary::guildSetAbbrev: invalid abbrev")); + return; + } + GuildInterface::setGuildAbbrev(guildId, newAbbrevStr); +} + +// ====================================================================== + + diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsHateList.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsHateList.cpp new file mode 100644 index 00000000..324d719e --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsHateList.cpp @@ -0,0 +1,460 @@ +// ====================================================================== +// +// ScriptMethodsHateList.cpp +// Copyright 2005 Sony Online Eentertainment, Inc. +// All rights reserved. +// +// ====================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "serverGame/AiLogManager.h" +#include "serverGame/ConfigServerGame.h" +#include "serverGame/CreatureObject.h" +#include "serverGame/HateList.h" +#include "serverGame/PlayerCreatureController.h" +#include "serverGame/PlayerObject.h" +#include "serverGame/TangibleObject.h" +#include "sharedLog/Log.h" + +using namespace JNIWrappersNamespace; + + +// ====================================================================== +// ScriptMethodsHateListNamespace +// ====================================================================== + +namespace ScriptMethodsHateListNamespace +{ + bool install(); + + void JNICALL setAggroImmuneDuration(JNIEnv * env, jobject self, jlong player, jint duration); + jboolean JNICALL isAggroImmune(JNIEnv * env, jobject self, jlong player); + void JNICALL addHate(JNIEnv * env, jobject self, jlong object, jlong hateTarget, jfloat hate); + void JNICALL addHateDot(JNIEnv * env, jobject self, jlong object, jlong hateTarget, jfloat hate, jint seconds); + void JNICALL setHate(JNIEnv * env, jobject self, jlong object, jlong hateTarget, jfloat hate); + void JNICALL removeHateTarget(JNIEnv * env, jobject self, jlong object, jlong hateTarget); + jfloat JNICALL getHate(JNIEnv * env, jobject self, jlong object, jlong hateTarget); + jfloat JNICALL getMaxHate(JNIEnv * env, jobject self, jlong object); + void JNICALL clearHateList(JNIEnv * env, jobject self, jlong object); + jlong JNICALL getHateTarget(JNIEnv * env, jobject self, jlong object); + jlongArray JNICALL getHateList(JNIEnv * env, jobject self, jlong object); + jboolean JNICALL isOnHateList(JNIEnv * env, jobject self, jlong object, jlong target); + void JNICALL resetHateTimer(JNIEnv * env, jobject self, jlong object); + void JNICALL setAILeashTime(JNIEnv * env, jobject self, jlong object, jfloat time); + jfloat JNICALL getAILeashTime(JNIEnv * env, jobject self, jlong object); + void JNICALL forceHateTarget(JNIEnv * env, jobject self, jlong object, jlong target); +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsHateListNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsHateListNamespace::c)} + JF("_setAggroImmuneDuration", "(JI)V", setAggroImmuneDuration), + JF("_isAggroImmune", "(J)Z", isAggroImmune), + JF("_addHate", "(JJF)V", addHate), + JF("_addHateDot", "(JJFI)V", addHateDot), + JF("_setHate", "(JJF)V", setHate), + JF("_removeHateTarget", "(JJ)V", removeHateTarget), + JF("_getHate", "(JJ)F", getHate), + JF("_getMaxHate", "(J)F", getMaxHate), + JF("_clearHateList", "(J)V", clearHateList), + JF("_getHateTarget", "(J)J", getHateTarget), + JF("_getHateList", "(J)[J", getHateList), + JF("_isOnHateList", "(JJ)Z", isOnHateList), + JF("_resetHateTimer", "(J)V", resetHateTimer), + JF("_setAILeashTime", "(JF)V", setAILeashTime), + JF("_getAILeashTime", "(J)F", getAILeashTime), + JF("_forceHateTarget", "(JJ)V", forceHateTarget), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +// ====================================================================== +// +// ScriptMethodsHateList +// +// ====================================================================== + +// ---------------------------------------------------------------------- +void JNICALL ScriptMethodsHateListNamespace::setAggroImmuneDuration(JNIEnv * /*env*/, jobject /*self*/, jlong player, jint duration) +{ + NetworkId const playerNetworkId(player); + PlayerObject * const playerObject = PlayerCreatureController::getPlayerObject(CreatureObject::getCreatureObject(playerNetworkId)); + + if (playerObject == NULL) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsHateList::setAggroImmuneDuration() player(%s) Unable to resolve the object to a PlayerObject.", playerNetworkId.getValueString().c_str())); + return; + } + + playerObject->setAggroImmuneDuration(duration); +} + +// ---------------------------------------------------------------------- +jboolean JNICALL ScriptMethodsHateListNamespace::isAggroImmune(JNIEnv * /*env*/, jobject /*self*/, jlong player) +{ + NetworkId const playerNetworkId(player); + PlayerObject * const playerObject = PlayerCreatureController::getPlayerObject(CreatureObject::getCreatureObject(playerNetworkId)); + + if (playerObject == NULL) + { + return JNI_FALSE; + } + + return playerObject->isAggroImmune(); +} + +// ---------------------------------------------------------------------- +void JNICALL ScriptMethodsHateListNamespace::addHate(JNIEnv * /*env*/, jobject /*self*/, jlong object, jlong hateTarget, jfloat hate) +{ + NetworkId const networkId(object); + NetworkId const hateTargetNetworkId(hateTarget); + TangibleObject * const objectTangibleObject = TangibleObject::getTangibleObject(networkId); + + if (objectTangibleObject == NULL) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsHateList::addHate() object(%s) hateTarget(%s) hate(%.2f) Unable to resolve the object to a TangibleObject.", networkId.getValueString().c_str(), hateTargetNetworkId.getValueString().c_str(), hate)); + return; + } + + if (hateTargetNetworkId == NetworkId::cms_invalid) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsHateList::addHate() object(%s) hate(%.2f) Unable to resolve the hateTarget(%s) to a NetworkId.", networkId.getValueString().c_str(), hate, hateTargetNetworkId.getValueString().c_str())); + return; + } + + if (networkId == hateTargetNetworkId) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsHateList::addHate() object(%s) hateTarget(%s) hate(%.2f) The object is trying to add itself to its hate list.", networkId.getValueString().c_str(), hateTargetNetworkId.getValueString().c_str(), hate)); + return; + } + + objectTangibleObject->addHate(hateTargetNetworkId, hate); +} + +// ---------------------------------------------------------------------- +void JNICALL ScriptMethodsHateListNamespace::addHateDot(JNIEnv * /*env*/, jobject /*self*/, jlong object, jlong hateTarget, jfloat hate, jint seconds) +{ + NetworkId const networkId(object); + NetworkId const hateTargetNetworkId(hateTarget); + TangibleObject * const objectTangibleObject = TangibleObject::getTangibleObject(networkId); + + if (objectTangibleObject == NULL) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsHateList::addHateDot() object(%s) hateTarget(%s) hate(%.2f) seconds(%d) Unable to resolve the object to a TangibleObject.", networkId.getValueString().c_str(), hateTargetNetworkId.getValueString().c_str(), hate, seconds)); + return; + } + + if (hateTargetNetworkId == NetworkId::cms_invalid) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsHateList::addHateDot() object(%s) hate(%.2f) seconds(%d) Unable to resolve the hateTarget(%s) to a NetworkId.", networkId.getValueString().c_str(), hateTargetNetworkId.getValueString().c_str(), hate, seconds)); + return; + } + + if (networkId == hateTargetNetworkId) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsHateList::addHateDot() object(%s) hateTarget(%s) hate(%.2f) seconds(%d) The object is trying to add itself to its hate list.", networkId.getValueString().c_str(), hateTargetNetworkId.getValueString().c_str(), hate, seconds)); + return; + } + + LOGC(AiLogManager::isLogging(networkId), "debug_ai", ("ScriptMethodsHateList::addHateDot() object(%s) hateTarget(%s) hate(%.2f+%.2f) seconds(%d)", networkId.getValueString().c_str(), hateTargetNetworkId.getValueString().c_str(), objectTangibleObject->getHate(hateTargetNetworkId), hate, seconds)); + + objectTangibleObject->addHateOverTime(hateTargetNetworkId, hate, seconds); +} + +// ---------------------------------------------------------------------- +void JNICALL ScriptMethodsHateListNamespace::setHate(JNIEnv * /*env*/, jobject /*self*/, jlong object, jlong hateTarget, jfloat hate) +{ + NetworkId const networkId(object); + NetworkId const hateTargetNetworkId(hateTarget); + TangibleObject * const objectTangibleObject = TangibleObject::getTangibleObject(networkId); + + if (objectTangibleObject == NULL) + { + WARNING(true, ("ScriptMethodsHateList::setHate() object(%s) hateTarget(%s) hate(%.2f) Unable to resolve the object to a TangibleObject.", networkId.getValueString().c_str(), hateTargetNetworkId.getValueString().c_str(), hate)); + return; + } + + if (hateTargetNetworkId == NetworkId::cms_invalid) + { + WARNING(true, ("ScriptMethodsHateList::setHate() object(%s) hateTarget(%s) hate(%.2f) Unable to resolve the hateTarget to a NetworkId.", networkId.getValueString().c_str(), hateTargetNetworkId.getValueString().c_str(), hate)); + return; + } + + if (networkId == hateTargetNetworkId) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsHateList::setHate() object(%s) hateTarget(%s) hate(%.2f) The object is trying to add itself to its hate list.", networkId.getValueString().c_str(), hateTargetNetworkId.getValueString().c_str(), hate)); + return; + } + + LOGC(AiLogManager::isLogging(networkId), "debug_ai", ("ScriptMethodsHateList::setHate() object(%s) hateTarget(%s) hate(%.2f)", networkId.getValueString().c_str(), hateTargetNetworkId.getValueString().c_str(), hate)); + + objectTangibleObject->setHate(hateTargetNetworkId, hate); +} + +// ---------------------------------------------------------------------- +void JNICALL ScriptMethodsHateListNamespace::removeHateTarget(JNIEnv * /*env*/, jobject /*self*/, jlong object, jlong hateTarget) +{ + NetworkId const networkId(object); + NetworkId const hateTargetNetworkId(hateTarget); + TangibleObject * const objectTangibleObject = TangibleObject::getTangibleObject(networkId); + + if (objectTangibleObject == NULL) + { + WARNING(true, ("ScriptMethodsHateList::removeHateTarget() object(%s) hateTarget(%s) Unable to resolve the object to a TangibleObject.", networkId.getValueString().c_str(), hateTargetNetworkId.getValueString().c_str())); + return; + } + + if (hateTargetNetworkId == NetworkId::cms_invalid) + { + WARNING(true, ("ScriptMethodsHateList::removeHateTarget() object(%s) Unable to resolve the hateTarget(%s) to a NetworkId.", networkId.getValueString().c_str(), hateTargetNetworkId.getValueString().c_str())); + return; + } + + if (networkId == hateTargetNetworkId) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsHateList::removeHateTarget() object(%s) hateTarget(%s) The object is trying to add itself to its hate list.", networkId.getValueString().c_str(), hateTargetNetworkId.getValueString().c_str())); + return; + } + + LOGC(AiLogManager::isLogging(networkId), "debug_ai", ("ScriptMethodsHateList::removeHateTarget() object(%s) hateTarget(%s)", networkId.getValueString().c_str(), hateTargetNetworkId.getValueString().c_str())); + + objectTangibleObject->removeHateTarget(hateTargetNetworkId); +} + +// ---------------------------------------------------------------------- +jfloat JNICALL ScriptMethodsHateListNamespace::getHate(JNIEnv * /*env*/, jobject /*self*/, jlong object, jlong hateTarget) +{ + NetworkId const networkId(object); + NetworkId const hateTargetNetworkId(hateTarget); + TangibleObject * const objectTangibleObject = TangibleObject::getTangibleObject(networkId); + + if (objectTangibleObject == NULL) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsHateList::getHate() object(%s) hateTarget(%s) Unable to resolve the object to a TangibleObject.", networkId.getValueString().c_str(), hateTargetNetworkId.getValueString().c_str())); + return 0.0f; + } + + if (hateTargetNetworkId == NetworkId::cms_invalid) + { + WARNING(true, ("ScriptMethodsHateList::getHate() object(%s) Unable to resolve the hateTarget(%s) to a NetworkId.", networkId.getValueString().c_str(), hateTargetNetworkId.getValueString().c_str())); + return 0.0f; + } + + if (networkId == hateTargetNetworkId) + { + return 0.0f; + } + + return objectTangibleObject->getHate(hateTargetNetworkId); +} + +// ---------------------------------------------------------------------- +jfloat JNICALL ScriptMethodsHateListNamespace::getMaxHate(JNIEnv * /*env*/, jobject /*self*/, jlong object) +{ + NetworkId const networkId(object); + TangibleObject * const objectTangibleObject = TangibleObject::getTangibleObject(networkId); + + if (objectTangibleObject == NULL) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsHateList::getMaxHate() object(%s) Unable to resolve the object to a TangibleObject.", networkId.getValueString().c_str())); + return 0.0f; + } + + float const maxHate = objectTangibleObject->getMaxHate(); + + return maxHate; +} + +// ---------------------------------------------------------------------- +void JNICALL ScriptMethodsHateListNamespace::clearHateList(JNIEnv * /*env*/, jobject /*self*/, jlong object) +{ + NetworkId const networkId(object); + TangibleObject * const objectTangibleObject = TangibleObject::getTangibleObject(networkId); + + if (objectTangibleObject == NULL) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsHateList::clearHateList() Unable to resolve the object(%s) to a TangibleObject.", networkId.getValueString().c_str())); + return; + } + + LOGC(AiLogManager::isLogging(networkId), "debug_ai", ("ScriptMethodsHateList::clearHateList() object(%s)", networkId.getValueString().c_str())); + + objectTangibleObject->clearHateList(); +} + +// ---------------------------------------------------------------------- +jlong JNICALL ScriptMethodsHateListNamespace::getHateTarget(JNIEnv * /*env*/, jobject /*self*/, jlong object) +{ + NetworkId const networkId(object); + TangibleObject * const objectTangibleObject = TangibleObject::getTangibleObject(networkId); + + if (objectTangibleObject == NULL) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsHateList::getHateTarget() Unable to resolve the object(%s) to a TangibleObject.", networkId.getValueString().c_str())); + return 0; + } + + CachedNetworkId const & hateTarget = objectTangibleObject->getHateTarget(); + + return hateTarget.getValue(); +} + +// ---------------------------------------------------------------------- +jlongArray JNICALL ScriptMethodsHateListNamespace::getHateList(JNIEnv * /*env*/, jobject /*self*/, jlong object) +{ + NetworkId const networkId(object); + TangibleObject * const objectTangibleObject = TangibleObject::getTangibleObject(networkId); + + LOGC(AiLogManager::isLogging(networkId), "debug_ai", ("ScriptMethodsHateList::getHateList() object(%s)", networkId.getValueString().c_str())); + + if (objectTangibleObject == NULL) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsHateList::getHateList() Unable to resolve the object(%s) to a TangibleObject.", networkId.getValueString().c_str())); + return 0; + } + + HateList::SortedList sortedHateList; + objectTangibleObject->getSortedHateList(sortedHateList); + + LocalLongArrayRefPtr hateList = createNewLongArray(static_cast(sortedHateList.size())); + HateList::SortedList::const_iterator iterSortedHateList = sortedHateList.begin(); + int index = 0; + + jlong jlongTmp; + for (; iterSortedHateList != sortedHateList.end(); ++iterSortedHateList) + { + jlongTmp = (iterSortedHateList->first).getValue(); + setLongArrayRegion(*hateList, index, 1, &jlongTmp); + ++index; + } + + return hateList->getReturnValue(); +} + +// ---------------------------------------------------------------------- +jboolean JNICALL ScriptMethodsHateListNamespace::isOnHateList(JNIEnv * /*env*/, jobject /*self*/, jlong object, jlong target) +{ + NetworkId const networkId(object); + NetworkId const targetNetworkId(target); + TangibleObject * const objectTangibleObject = TangibleObject::getTangibleObject(networkId); + + if (objectTangibleObject == NULL) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsHateList::isOnHateList() object(%s) target(%s) Unable to resolve the object to a TangibleObject.", networkId.getValueString().c_str(), targetNetworkId.getValueString().c_str())); + return JNI_FALSE; + } + + if (targetNetworkId == NetworkId::cms_invalid) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsHateList::isOnHateList() object(%s) Unable to resolve the target(%s) to a NetworkId.", networkId.getValueString().c_str(), targetNetworkId.getValueString().c_str())); + return JNI_FALSE; + } + + return objectTangibleObject->isOnHateList(targetNetworkId); +} + +// ---------------------------------------------------------------------- +void JNICALL ScriptMethodsHateListNamespace::resetHateTimer(JNIEnv * /*env*/, jobject /*self*/, jlong object) +{ + NetworkId const networkId(object); + TangibleObject * const objectTangibleObject = TangibleObject::getTangibleObject(networkId); + + if (objectTangibleObject == NULL) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsHateList::resetHateTimer() object(%s) Unable to resolve the object to a TangibleObject.", networkId.getValueString().c_str())); + return; + } + + objectTangibleObject->resetHateTimer(); +} + + +// ---------------------------------------------------------------------- +void JNICALL ScriptMethodsHateListNamespace::setAILeashTime(JNIEnv * /*env*/, jobject /*self*/, jlong object, jfloat time ) +{ + NetworkId const networkId(object); + TangibleObject * const objectTangibleObject = TangibleObject::getTangibleObject(networkId); + + if (objectTangibleObject == NULL) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsHateList::setAILeashTime() object(%s) time(%.2f) Unable to resolve the object to a TangibleObject.", networkId.getValueString().c_str(), time)); + return; + } + + LOGC(AiLogManager::isLogging(networkId), "debug_ai", + ("ScriptMethodsHateList::setAILeashTime() object(%s) time(%f)", + networkId.getValueString().c_str(), + time + )); + + objectTangibleObject->setAILeashTime(time); +} + + + +// ---------------------------------------------------------------------- +jfloat JNICALL ScriptMethodsHateListNamespace::getAILeashTime(JNIEnv * /*env*/, jobject /*self*/, jlong object ) +{ + NetworkId const networkId(object); + TangibleObject * const objectTangibleObject = TangibleObject::getTangibleObject(networkId); + + if (objectTangibleObject == NULL) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsHateList::setAILeashTime() object(%s) time(%.2f) Unable to resolve the object to a TangibleObject.", networkId.getValueString().c_str(), time)); + return 0.0; + } + + LOGC(AiLogManager::isLogging(networkId), "debug_ai", + ("ScriptMethodsHateList::setAILeashTime() object(%s) time(%f)", + networkId.getValueString().c_str(), + time + )); + + return objectTangibleObject->getAILeashTime(); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsHateListNamespace::forceHateTarget(JNIEnv * env, jobject self, jlong object, jlong target) +{ + UNREF(env); + UNREF(self); + + NetworkId const networkId(object); + NetworkId const hateTargetNetworkId(target); + TangibleObject * const objectTangibleObject = TangibleObject::getTangibleObject(networkId); + + if (objectTangibleObject == NULL) + { + WARNING(true, ("ScriptMethodsHateList::forceHateTarget() object(%s) hateTarget(%s) Unable to resolve the object to a TangibleObject.", networkId.getValueString().c_str(), hateTargetNetworkId.getValueString().c_str())); + return; + } + + if (hateTargetNetworkId == NetworkId::cms_invalid) + { + WARNING(true, ("ScriptMethodsHateList::forceHateTarget() object(%s) Unable to resolve the hateTarget(%s) to a NetworkId.", networkId.getValueString().c_str(), hateTargetNetworkId.getValueString().c_str())); + return; + } + + if (networkId == hateTargetNetworkId) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsHateList::forceHateTarget() object(%s) hateTarget(%s) The object is trying to add itself to its hate list.", networkId.getValueString().c_str(), hateTargetNetworkId.getValueString().c_str())); + return; + } + + LOGC(AiLogManager::isLogging(networkId), "debug_ai", ("ScriptMethodsHateList::forceHateTarget() object(%s) hateTarget(%s)", networkId.getValueString().c_str(), hateTargetNetworkId.getValueString().c_str())); + + objectTangibleObject->forceHateTarget(hateTargetNetworkId); +} + +// ====================================================================== diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsHolocube.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsHolocube.cpp new file mode 100644 index 00000000..51088b13 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsHolocube.cpp @@ -0,0 +1,100 @@ +//----------------------------------------------------------------------- +// ScriptMethodsHolocube.cpp +// Copyright 2002, Sony Online Entertainment Inc., all rights reserved. +//----------------------------------------------------------------------- + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "serverGame/GameServer.h" +#include "serverGame/ServerObject.h" +#include "sharedNetworkMessages/OpenHolocronToPageMessage.h" +#include "sharedNetworkMessages/CloseHolocronMessage.h" + + +// ====================================================================== +// ScriptMethodsHolocubeNamespace +// ====================================================================== + +namespace ScriptMethodsHolocubeNamespace +{ + bool install(); + + jboolean JNICALL openHolocronToPage(JNIEnv *env, jobject self, jlong client, jstring jpage); + jboolean JNICALL closeHolocron(JNIEnv *env, jobject self, jlong client); +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsHolocubeNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsHolocubeNamespace::c)} + JF("_openHolocronToPage", "(JLjava/lang/String;)Z", openHolocronToPage), + JF("_closeHolocron", "(J)Z", closeHolocron), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsHolocubeNamespace::openHolocronToPage(JNIEnv *env, jobject self, jlong client, jstring jpage) +{ + JavaStringParam localPage(jpage); + + ServerObject* so = NULL; + if(!JavaLibrary::getObject(client, so)) + { + WARNING (true, ("[Script bug] Could not get ServerObject for value passed in for paramter:client in JavaLibrary::openHolocronToPage")); + return JNI_FALSE; + } + Client* c = so->getClient(); + if(!c) + { + WARNING (true, ("[Script bug] Value given for paramter:client is not a player in JavaLibrary::openHolocronToPage, associated ServerObject NetworkId is: %s", so->getNetworkId().getValueString().c_str())); + return JNI_FALSE; + } + std::string page; + JavaLibrary::convert(localPage, page); + + //an empty page is fine, that tells the client just to open the holocube + + OpenHolocronToPageMessage ohtpm(page); + + if(c) + c->send(ohtpm, true); + + return JNI_TRUE; +} + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsHolocubeNamespace::closeHolocron(JNIEnv *env, jobject self, jlong client) +{ + ServerObject* so = NULL; + if(!JavaLibrary::getObject(client, so)) + { + WARNING (true, ("[Script bug] Could not get ServerObject for value passed in for paramter:client in JavaLibrary::closeHolocron")); + return JNI_FALSE; + } + Client* c = so->getClient(); + if(!c) + { + WARNING (true, ("[Script bug] Value given for paramter:client is not a player in JavaLibrary::closeHolocron, associated ServerObject NetworkId is: %s", so->getNetworkId().getValueString().c_str())); + return JNI_FALSE; + } + + CloseHolocronMessage chm; + + if(c) + c->send(chm, true); + + return JNI_TRUE; +} + +//----------------------------------------------------------------------- diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsHyperspace.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsHyperspace.cpp new file mode 100644 index 00000000..665f9460 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsHyperspace.cpp @@ -0,0 +1,534 @@ +//======================================================================== +// +// ScriptMethodsHyperspace.cpp - implements script methods dealing with hyperspace +// +// copyright 2001 Sony Online Entertainment +// +//======================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "sharedFoundation/MessageQueue.h" +#include "serverGame/Chat.h" +#include "serverGame/ConfigServerGame.h" +#include "serverGame/CreatureObject.h" +#include "serverGame/GameServer.h" +#include "serverGame/ServerObject.h" +#include "serverGame/ServerUniverse.h" +#include "serverGame/ServerWorld.h" +#include "serverGame/ShipController.h" +#include "serverGame/ShipObject.h" +#include "sharedGame/HyperspaceManager.h" +#include "sharedGame/SharedHyperspaceStringIds.h" +#include "sharedNetworkMessages/MessageQueueGenericValueType.h" +#include "sharedObject/CachedNetworkId.h" +#include "serverScript/GameScriptObject.h" +#include "serverScript/ScriptParameters.h" + +#include "UnicodeUtils.h" + +//======================================================================== +// constants +//======================================================================== + +namespace ScriptMethodsHyperspaceNamespace +{ + float const cs_hyperspaceDelayTime = 6.0f; + float const cs_hyperspaceInvulnerableTime = cs_hyperspaceDelayTime + 10.0f; + float const cs_hyperspaceMinDistance = 500.f; + + bool install(); + void sendUnlockPlayerShipInputOnClient(ShipObject * shipObject); + + void JNICALL hyperspacePlayerToLocation(JNIEnv *env, jobject self, jlong player, jstring scene, jfloat x_w, jfloat y_w, jfloat z_w, jlong cell, jfloat x_p, jfloat y_p, jfloat z_p, jstring callback, jboolean forceLoadScreen); + void JNICALL hyperspacePlayerToLocationCellName(JNIEnv *env, jobject self, jlong player, jstring scene, jfloat x_w, jfloat y_w, jfloat z_w, jlong building, jstring cell, jfloat x_p, jfloat y_p, jfloat z_p, jstring callback, jboolean forceLoadScreen); + void JNICALL hyperspacePlayerToHyperspacePoint(JNIEnv *env, jobject self, jlong player, jstring hyperspacePoint, jstring callback, jboolean forceLoadScreen, jboolean ignoreTooFull); + jboolean JNICALL isHyperspacePointOverpopulated(JNIEnv *env, jobject self, jstring jhyperspacePoint); + void JNICALL hyperspacePrepareShipOnClient(JNIEnv *env, jobject self, jlong player, jstring jhyperspacePoint); + void JNICALL hyperspaceRestoreShipOnClientFromAbortedHyperspace(JNIEnv *env, jobject self, jlong player); + jstring JNICALL getSceneForHyperspacePoint(JNIEnv *env, jobject self, jstring hyperspacePoint); +} + +void ScriptMethodsHyperspaceNamespace::sendUnlockPlayerShipInputOnClient(ShipObject * const shipObject) +{ + CreatureObject * const pilotCreature = (shipObject != 0) ? shipObject->getPilot() : 0; + Controller * const pilotController = (pilotCreature != 0) ? pilotCreature->getController() : 0; + + if (pilotController != 0) + { + pilotController->appendMessage( + CM_unlockPlayerShipInputOnClient, + 0.0f, + GameControllerMessageFlags::SEND | + GameControllerMessageFlags::RELIABLE | + GameControllerMessageFlags::DEST_AUTH_CLIENT); + } +} + +using namespace ScriptMethodsHyperspaceNamespace; + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsHyperspaceNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsHyperspaceNamespace::c)} + JF("_hyperspacePlayerToLocation", "(JLjava/lang/String;FFFJFFFLjava/lang/String;Z)V", hyperspacePlayerToLocation), + JF("_hyperspacePlayerToLocation", "(JLjava/lang/String;FFFJLjava/lang/String;FFFLjava/lang/String;Z)V", hyperspacePlayerToLocationCellName), + JF("_hyperspacePlayerToHyperspacePoint", "(JLjava/lang/String;Ljava/lang/String;ZZ)V", hyperspacePlayerToHyperspacePoint), + JF("isHyperspacePointOverpopulated", "(Ljava/lang/String;)Z", isHyperspacePointOverpopulated), + JF("_hyperspacePrepareShipOnClient", "(JLjava/lang/String;)V", hyperspacePrepareShipOnClient), + JF("_hyperspaceRestoreShipOnClientFromAbortedHyperspace","(J)V", hyperspaceRestoreShipOnClientFromAbortedHyperspace), + JF("getSceneForHyperspacePoint", "(Ljava/lang/String;)Ljava/lang/String;", getSceneForHyperspacePoint), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +//======================================================================== +// class JavaLibrary JNI action state callback methods +//======================================================================== + +void JNICALL ScriptMethodsHyperspaceNamespace::hyperspacePlayerToLocation(JNIEnv *env, jobject self, jlong player, jstring scene, jfloat x_w, jfloat y_w, jfloat z_w, jlong cell, jfloat x_p, jfloat y_p, jfloat z_p, jstring callback, jboolean forceLoadScreen) +{ + ServerObject *playerObject = 0; + if (!JavaLibrary::getObject(player, playerObject)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("hyperspacePlayerToLocation - could not get player")); + return; + } + + JavaStringParam localScene(scene); + std::string sceneName; + if (!JavaLibrary::convert(localScene, sceneName)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("hyperspacePlayerToLocation - could not get scene name")); + return; + } + std::string callbackName; + + if (callback) + { + JavaStringParam localCallback(callback); + if (!JavaLibrary::convert(localCallback, callbackName)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("hyperspacePlayerToLocation - could not get callback")); + return; + } + } + + ShipObject * const shipObject = ShipObject::getContainingShipObject(playerObject); + + if (!shipObject) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("hyperspacePlayerToLocation - Hyperspacing is only allowed for ShipObjects %s", playerObject->getDebugInformation().c_str())); + return; + } + + // Make sure the ship is not docking + + Controller const * const controller = (shipObject != NULL) ? shipObject->getController() : NULL; + ShipController const * const shipController = (controller != NULL) ? controller->asShipController() : NULL; + + if ( (shipController != NULL) + && shipController->isDocking()) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("hyperspacePlayerToLocation - Hyperspacing is not allowed on ships that are currently docking: %s", shipObject->getDebugInformation().c_str())); + return; + } + + shipObject->setInvulnerabilityTimer(cs_hyperspaceInvulnerableTime); + + NetworkId cellId(cell); + GameServer::getInstance().requestSceneWarpDelayed( + CachedNetworkId(*shipObject), + sceneName, + Vector(x_w, y_w, z_w), + cellId, + Vector(x_p, y_p, z_p), + cs_hyperspaceDelayTime, + callbackName.c_str(), + forceLoadScreen); +} + +//------------------------------------------------------------------------------------------------ + +void JNICALL ScriptMethodsHyperspaceNamespace::hyperspacePlayerToLocationCellName(JNIEnv *env, jobject self, jlong player, jstring scene, jfloat x_w, jfloat y_w, jfloat z_w, jlong building, jstring cell, jfloat x_p, jfloat y_p, jfloat z_p, jstring callback, jboolean forceLoadScreen) +{ + ServerObject *playerObject = 0; + if (!JavaLibrary::getObject(player, playerObject)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("hyperspacePlayerToLocation - could not get player")); + return; + } + + JavaStringParam localScene(scene); + std::string sceneName; + if (!JavaLibrary::convert(localScene, sceneName)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("hyperspacePlayerToLocation - could not get scene name")); + return; + } + std::string callbackName; + + if (callback) + { + JavaStringParam localCallback(callback); + if (!JavaLibrary::convert(localCallback, callbackName)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("hyperspacePlayerToLocation - could not get callback")); + return; + } + } + + JavaStringParam localCell(cell); + std::string cellName; + if (!JavaLibrary::convert(localCell, cellName)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("hyperspacePlayerToLocation - could not get call name")); + return; + } + + NetworkId buildingId(building); + if (buildingId == NetworkId::cms_invalid) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("hyperspacePlayerToLocation - could not get building id")); + return; + } + + + ShipObject * const shipObject = ShipObject::getContainingShipObject(playerObject); + + if (!shipObject) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("hyperspacePlayerToLocation - Hyperspacing is only allowed for ShipObjects %s", playerObject->getDebugInformation().c_str())); + return; + } + + // Make sure the ship is not docking + + Controller const * const controller = (shipObject != NULL) ? shipObject->getController() : NULL; + ShipController const * const shipController = (controller != NULL) ? controller->asShipController() : NULL; + + if ( (shipController != NULL) + && shipController->isDocking()) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("hyperspacePlayerToLocation - Hyperspacing is not allowed on ships that are currently docking: %s", shipObject->getDebugInformation().c_str())); + return; + } + + shipObject->setInvulnerabilityTimer(cs_hyperspaceInvulnerableTime); + + GameServer::getInstance().requestSceneWarpDelayed( + CachedNetworkId(*shipObject), + sceneName, + Vector(x_w, y_w, z_w), + buildingId, + cellName, + Vector(x_p, y_p, z_p), + cs_hyperspaceDelayTime, + callbackName.c_str(), + forceLoadScreen); +} + +//------------------------------------------------------------------------------------------------ + +jboolean JNICALL ScriptMethodsHyperspaceNamespace::isHyperspacePointOverpopulated(JNIEnv *env, jobject self, jstring jhyperspacePoint) +{ + JavaStringParam localHyperspacePoint(jhyperspacePoint); + std::string hyperspacePoint; + if (!JavaLibrary::convert(localHyperspacePoint, hyperspacePoint)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("isHyperspacePointAvailable - could not get hyperspace point name")); + return true; + } + + if(HyperspaceManager::isValidHyperspacePoint(hyperspacePoint)) + { + HyperspaceManager::HyperspaceLocation location; + bool const result = HyperspaceManager::getHyperspacePoint(hyperspacePoint, location); + + if (result) + { + int const population = ServerUniverse::getInstance().getPopulationAtLocation(location.sceneName, static_cast(location.location.x), static_cast(location.location.z)); + return (population > ConfigServerGame::getMaxPopulationForNewbieTravel()); + } + } + return true; // invalid points are always over-populated +} + +//------------------------------------------------------------------------------------------------ + +void JNICALL ScriptMethodsHyperspaceNamespace::hyperspacePlayerToHyperspacePoint(JNIEnv *env, jobject self, jlong player, jstring jhyperspacePoint, jstring callback, jboolean forceLoadScreen, jboolean ignoreTooFull) +{ + ServerObject *playerObject = 0; + if (!JavaLibrary::getObject(player, playerObject)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("hyperspacePlayerToHyperspacePoint - could not get player")); + return; + } + + CreatureObject * const playerCreature = playerObject ? playerObject->asCreatureObject() : NULL; + if(!playerCreature) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("hyperspacePlayerToHyperspacePoint - player is not a creature")); + return; + } + + JavaStringParam localHyperspacePoint(jhyperspacePoint); + std::string hyperspacePoint; + if (!JavaLibrary::convert(localHyperspacePoint, hyperspacePoint)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("hyperspacePlayerToHyperspacePoint - could not get hyperspace point name")); + return; + } + + std::string callbackName; + + if (callback) + { + JavaStringParam localCallback(callback); + if (!JavaLibrary::convert(localCallback, callbackName)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("hyperspacePlayerToHyperspacePoint - could not get callback")); + return; + } + } + + ShipObject * const shipObject = ShipObject::getContainingShipObject(playerObject); + + if (!shipObject) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("hyperspacePlayerToLocation - Hyperspacing is only allowed for ShipObjects %s", playerObject->getDebugInformation().c_str())); + return; + } + + // Make sure the ship is not docking + + Controller const * const controller = (shipObject != NULL) ? shipObject->getController() : NULL; + ShipController const * const shipController = (controller != NULL) ? controller->asShipController() : NULL; + + if ( (shipController != NULL) + && shipController->isDocking()) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("hyperspacePlayerToHyperspacePoint - Hyperspacing is not allowed on ships that are currently docking: %s", shipObject->getDebugInformation().c_str())); + return; + } + + if(HyperspaceManager::isValidHyperspacePoint(hyperspacePoint)) + { + // we first check if this hyperspace point is the home location - if so, call back into script to finish handling it. + if (hyperspacePoint == HyperspaceManager::getHomeLocationHyperspacePointName()) + { + ScriptParams params; + IGNORE_RETURN(playerCreature->getScriptObject()->trigAllScripts(Scripting::TRIG_HYPERSPACE_TO_HOME_LOCATION, params)); + return; + } + + HyperspaceManager::HyperspaceLocation location; + bool const result = HyperspaceManager::getHyperspacePoint(hyperspacePoint, location); + location.location += Vector::randomUnit() * ConfigServerGame::getHyperspaceRandomOffsetRange(); + if(result) + { + if(!location.requiredCommand.empty()) + { + if(!playerCreature->hasCommand(location.requiredCommand)) + { + Chat::sendSystemMessage(*playerCreature, SharedHyperspaceStringIds::not_cleared_for_point, Unicode::emptyString); + + // We need to unlock the pilot's controls here since we didn't end up hyperspacing + sendUnlockPlayerShipInputOnClient(shipObject); + return; + } + } + + if ( location.sceneName == ServerWorld::getSceneId() + && location.location.magnitudeBetweenSquared(playerCreature->findPosition_w()) < sqr(cs_hyperspaceMinDistance)) + { + Chat::sendSystemMessage(*playerCreature, SharedHyperspaceStringIds::already_at_point, Unicode::emptyString); + + // We need to unlock the pilot's controls here since we didn't end up hyperspacing + sendUnlockPlayerShipInputOnClient(shipObject); + return; + } + + if (!ignoreTooFull) + { + int const population = ServerUniverse::getInstance().getPopulationAtLocation(location.sceneName, static_cast(location.location.x), static_cast(location.location.z)); + if (population > ConfigServerGame::getMaxPopulationForNewbieTravel()) + { + Chat::sendSystemMessage(*playerCreature, SharedHyperspaceStringIds::zone_too_full, Unicode::emptyString); + + // We need to unlock the pilot's controls here since we didn't end up hyperspacing + sendUnlockPlayerShipInputOnClient(shipObject); + return; + } + } + + shipObject->setInvulnerabilityTimer(cs_hyperspaceInvulnerableTime); + + GameServer::getInstance().requestSceneWarpDelayed( + CachedNetworkId(*shipObject), + location.sceneName, + Vector(location.location.x, location.location.y, location.location.z), + NetworkId::cms_invalid, + Vector(location.location.z, location.location.y, location.location.z), + cs_hyperspaceDelayTime, + callbackName.c_str(), + forceLoadScreen); + } + } +} + +//------------------------------------------------------------------------------------------------ + +void JNICALL ScriptMethodsHyperspaceNamespace::hyperspacePrepareShipOnClient(JNIEnv *env, jobject self, jlong player, jstring jhyperspacePoint) +{ + ServerObject *playerObject = 0; + if (!JavaLibrary::getObject(player, playerObject)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("hyperspacePlayerToHyperspacePoint - could not get player")); + return; + } + + CreatureObject * const playerCreature = playerObject ? playerObject->asCreatureObject() : NULL; + if(playerCreature == 0) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("hyperspacePlayerToHyperspacePoint - player is not a creature")); + return; + } + + ShipObject * const shipObject = ShipObject::getContainingShipObject(playerObject); + + if (shipObject == 0) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("hyperspacePlayerToLocation - Hyperspacing is only allowed for ShipObjects %s", playerObject->getDebugInformation().c_str())); + return; + } + + JavaStringParam localHyperspacePoint(jhyperspacePoint); + std::string hyperspacePoint; + if (!JavaLibrary::convert(localHyperspacePoint, hyperspacePoint)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("hyperspacePlayerToHyperspacePoint - could not get hyperspace point name")); + return; + } + + + if(HyperspaceManager::isValidHyperspacePoint(hyperspacePoint)) + { + HyperspaceManager::HyperspaceLocation location; + + if (HyperspaceManager::getHyperspacePoint(hyperspacePoint, location)) + { + Controller const * const controller = (shipObject != NULL) ? shipObject->getController() : NULL; + ShipController const * const shipController = (controller != NULL) ? controller->asShipController() : NULL; + + if (shipController != 0) + { + // Make sure the ship is not docking + if (shipController->isDocking()) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("hyperspacePlayerToHyperspacePoint - Hyperspacing is not allowed on ships that are currently docking: %s", shipObject->getDebugInformation().c_str())); + return; + } + + CreatureObject * const pilotCreature = shipObject->getPilot(); + Controller * const pilotController = (pilotCreature != 0) ? pilotCreature->getController() : 0; + + if (pilotController != 0) + { + MessageQueueGenericValueType > * data = new MessageQueueGenericValueType >(std::make_pair(location.sceneName, location.location)); + + pilotController->appendMessage(CM_hyperspaceOrientShipToPointAndLockPlayerInput, + 0.0f, + data, + GameControllerMessageFlags::SEND | + GameControllerMessageFlags::RELIABLE | + GameControllerMessageFlags::DEST_AUTH_CLIENT); + } + } + } + } +} + +//------------------------------------------------------------------------------------------------ + +void JNICALL ScriptMethodsHyperspaceNamespace::hyperspaceRestoreShipOnClientFromAbortedHyperspace(JNIEnv *env, jobject self, jlong player) +{ + ServerObject *playerObject = 0; + if (!JavaLibrary::getObject(player, playerObject)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("hyperspacePlayerToHyperspacePoint - could not get player")); + return; + } + + CreatureObject * const playerCreature = playerObject ? playerObject->asCreatureObject() : NULL; + if(playerCreature == 0) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("hyperspacePlayerToHyperspacePoint - player is not a creature")); + return; + } + + ShipObject * const shipObject = ShipObject::getContainingShipObject(playerObject); + + if (shipObject == 0) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("hyperspacePlayerToLocation - Hyperspacing is only allowed for ShipObjects %s", playerObject->getDebugInformation().c_str())); + return; + } + + Controller const * const controller = (shipObject != NULL) ? shipObject->getController() : NULL; + ShipController const * const shipController = (controller != NULL) ? controller->asShipController() : NULL; + + if (shipController != 0) + { + // If the ship is docking, then unlocking the controls is not the correct thing to do. + if (shipController->isDocking()) + return; + + CreatureObject * const pilotCreature = shipObject->getPilot(); + Controller * const pilotController = (pilotCreature != 0) ? pilotCreature->getController() : 0; + + if (pilotController != 0) + { + pilotController->appendMessage(CM_unlockPlayerShipInputOnClient, + 0.0f, + GameControllerMessageFlags::SEND | + GameControllerMessageFlags::RELIABLE | + GameControllerMessageFlags::DEST_AUTH_CLIENT); + } + } +} + +//------------------------------------------------------------------------------------------------ + +jstring JNICALL ScriptMethodsHyperspaceNamespace::getSceneForHyperspacePoint(JNIEnv *env, jobject self, jstring jhyperspacePoint) +{ + JavaStringParam localHyperspacePoint(jhyperspacePoint); + std::string hyperspacePoint; + if (!JavaLibrary::convert(localHyperspacePoint, hyperspacePoint)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("getSceneForHyperspacePoint - could not get hyperspace point name")); + return NULL; + } + + if(HyperspaceManager::isValidHyperspacePoint(hyperspacePoint)) + { + HyperspaceManager::HyperspaceLocation location; + bool const result = HyperspaceManager::getHyperspacePoint(hyperspacePoint, location); + + if (result) + { + JavaString str(location.sceneName); + return str.getReturnValue(); + } + } + return NULL; +} + +//------------------------------------------------------------------------------------------------ diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsImageDesign.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsImageDesign.cpp new file mode 100644 index 00000000..b85f1516 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsImageDesign.cpp @@ -0,0 +1,254 @@ +//======================================================================== +// +// ScriptMethodsImageDesign.cpp - implements script methods dealing with imagedesigning. +// +// copyright 2001 Sony Online Entertainment +// +//======================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "serverGame/Chat.h" +#include "serverGame/ServerImageDesignerManager.h" +#include "serverGame/ServerObject.h" +#include "sharedFoundation/Os.h" +#include "sharedGame/SharedImageDesignerManager.h" +#include "sharedGame/SharedStringIds.h" +#include "sharedNetworkMessages/ImageDesignStartMessage.h" +#include "sharedObject/Controller.h" + + +// ====================================================================== +// ScriptMethodsImageDesignNamespace +// ====================================================================== + +namespace ScriptMethodsImageDesignNamespace +{ + bool install(); + + void JNICALL imagedesignStart(JNIEnv *env, jobject self, jlong jdesignerId, jlong jrecipientId, jlong jterminalId, jstring jCurrentHoloEmote); + jboolean JNICALL imagedesignValidated(JNIEnv *env, jobject self, jlong jdesignerId, jlong jrecipientId, jlong jterminalId, jint jstartingTime, jint jdesignType, jboolean jnewHairSet, jstring jnewHairAsset, jstring jhairCustomizationData, jint jdesignerRequiredCredits, jint jrecipientPaidCredits, jboolean jaccepted, jobjectArray jmorphChangesKeys, jfloatArray jmorphChangesValues, jobjectArray jindexChangesKeys, jintArray jindexChangesValues, jstring jholoEmote); +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsImageDesignNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsImageDesignNamespace::c)} + JF("_imagedesignStart", "(JJJLjava/lang/String;)V", imagedesignStart), + JF("_imagedesignValidated", "(JJJIIZLjava/lang/String;Ljava/lang/String;IIZ[Ljava/lang/String;[F[Ljava/lang/String;[ILjava/lang/String;)Z", imagedesignValidated), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +//======================================================================== +// class JavaLibrary JNI imagedesign callback methods +//======================================================================== + +void JNICALL ScriptMethodsImageDesignNamespace::imagedesignStart(JNIEnv *env, jobject self, jlong jdesignerId, jlong jrecipientId, jlong jterminalId, jstring jCurrentHoloEmote) +{ + UNREF(env); + UNREF(self); + ServerObject * designerObj = 0; + if (!JavaLibrary::getObject(jdesignerId, designerObj)) + { + WARNING(true, ("bad designer passed to JavaLibrary::imagedesignStart")); + return; + } + + ServerObject * recipientObj = 0; + if (!JavaLibrary::getObject(jrecipientId, recipientObj)) + { + WARNING(true, ("bad recipient passed to JavaLibrary::imagedesignStart")); + return; + } + + //the terminal can be NULL (that means no ID terminal is being used, which is fine) + ServerObject * terminalObj = 0; + JavaLibrary::getObject(jterminalId, terminalObj); + + if(!designerObj || !recipientObj) + { + WARNING(true, ("could not resolve targets for JavaLibrary::imagedesignStart")); + return; + } + + SharedImageDesignerManager::Session newSession; + newSession.designerId = designerObj->getNetworkId(); + newSession.recipientId = recipientObj->getNetworkId(); + newSession.startingTime = Os::getRealSystemTime(); + NetworkId const terminalId = terminalObj ? terminalObj->getNetworkId() : NetworkId::cms_invalid; + newSession.terminalId = terminalId; + SharedImageDesignerManager::startSession(newSession); + + std::string currentHoloEmote; + if(jCurrentHoloEmote) + { + JavaStringParam localCurrentHoloEmote(jCurrentHoloEmote); + IGNORE_RETURN(JavaLibrary::convert(localCurrentHoloEmote, currentHoloEmote)); + } + + Controller * const designerController = designerObj->getController(); + if(designerController) + { + ImageDesignStartMessage * const msg = new ImageDesignStartMessage(designerObj->getNetworkId(), recipientObj->getNetworkId(), terminalId, currentHoloEmote); + designerController->appendMessage(CM_imageDesignerStart, 0, msg, GameControllerMessageFlags::SEND | GameControllerMessageFlags::RELIABLE | GameControllerMessageFlags::DEST_AUTH_CLIENT); + } + + Controller * const recipientController = recipientObj->getController(); + if(recipientController && recipientController != designerController) + { + ImageDesignStartMessage * const msg = new ImageDesignStartMessage(designerObj->getNetworkId(), recipientObj->getNetworkId(), terminalId, currentHoloEmote); + recipientController->appendMessage(CM_imageDesignerStart, 0, msg, GameControllerMessageFlags::SEND | GameControllerMessageFlags::RELIABLE | GameControllerMessageFlags::DEST_AUTH_CLIENT); + } +} + +//------------------------------------------------------------------------ + +jboolean JNICALL ScriptMethodsImageDesignNamespace::imagedesignValidated(JNIEnv *env, jobject self, jlong jdesignerId, jlong jrecipientId, jlong jterminalId, jint jstartingTime, jint jdesignType, jboolean jnewHairSet, jstring jnewHairAsset, jstring jhairCustomizationData, jint jdesignerRequiredCredits, jint jrecipientPaidCredits, jboolean jaccepted, jobjectArray jmorphChangesKeys, jfloatArray jmorphChangesValues, jobjectArray jindexChangesKeys, jintArray jindexChangesValues, jstring jholoEmote) +{ + UNREF(self); + SharedImageDesignerManager::Session session; + ServerObject * designerObj = 0; + if (!JavaLibrary::getObject(jdesignerId, designerObj) || !designerObj) + { + WARNING(true, ("bad designer passed to JavaLibrary::imagedesignValidated")); + return JNI_FALSE; + } + + ServerObject * recipientObj = 0; + if (!JavaLibrary::getObject(jrecipientId, recipientObj) || !recipientObj) + { + WARNING(true, ("bad recipient passed to JavaLibrary::imagedesignValidated")); + return JNI_FALSE; + } + + ServerObject * terminalObj = 0; + JavaLibrary::getObject(jterminalId, terminalObj); + + session.designerId = designerObj->getNetworkId(); + session.recipientId = recipientObj->getNetworkId(); + session.terminalId = terminalObj ? terminalObj->getNetworkId() : NetworkId::cms_invalid; + session.startingTime = jstartingTime; + session.designType = static_cast(jdesignType); + session.newHairSet = jnewHairSet; + std::string newHairAsset; + if(jnewHairAsset) + { + JavaStringParam localNewHairAsset(jnewHairAsset); + IGNORE_RETURN(JavaLibrary::convert(localNewHairAsset, newHairAsset)); + } + session.newHairAsset = newHairAsset; + std::string hairCustomizationData; + if(jhairCustomizationData) + { + JavaStringParam localHairCustomizationData(jhairCustomizationData); + IGNORE_RETURN(JavaLibrary::convert(localHairCustomizationData, hairCustomizationData)); + } + session.hairCustomizationData = hairCustomizationData; + session.designerRequiredCredits = jdesignerRequiredCredits; + session.recipientPaidCredits = jrecipientPaidCredits; + session.accepted = jaccepted; + + //if the session isn't valid, cancel it and don't apply changes + if(!session.accepted) + { + Chat::sendSystemMessage(*designerObj, SharedStringIds::imagedesigner_session_not_valid, Unicode::emptyString); + if(designerObj != recipientObj) + Chat::sendSystemMessage(*recipientObj, SharedStringIds::imagedesigner_session_not_valid, Unicode::emptyString); + ServerImageDesignerManager::cancelSession(session.designerId, session.recipientId); + return JNI_TRUE; + } + + //ensure we validate against the server's skill mod data + SharedImageDesignerManager::SkillMods const & skillMods = ServerImageDesignerManager::getSkillModsForDesigner(session.designerId); + session.bodySkillMod = skillMods.bodySkillMod; + session.faceSkillMod = skillMods.faceSkillMod; + session.markingsSkillMod = skillMods.markingsSkillMod; + session.hairSkillMod = skillMods.hairSkillMod; + + std::string tempString; + + //get morph values + std::map morphChanges; + int countKeys = env->GetArrayLength(jmorphChangesKeys); + int countValues = env->GetArrayLength(jmorphChangesValues); + if(countKeys != countValues) + { + WARNING(true, ("morph keys and values arrays are of diffent sizes")); + return JNI_FALSE; + } + jfloat * const morphChangesValuesArray = env->GetFloatArrayElements(jmorphChangesValues, NULL); + if (morphChangesValuesArray == NULL) + { + return JNI_FALSE; + } + std::vector morphValues(morphChangesValuesArray, &morphChangesValuesArray[countValues]); + env->ReleaseFloatArrayElements(jmorphChangesValues, morphChangesValuesArray, JNI_ABORT); + for (int i = 0; i < countKeys; ++i) + { + JavaString jTempString(static_cast(env->GetObjectArrayElement(jmorphChangesKeys, i))); + if (JavaLibrary::convert(jTempString, tempString)) + { + morphChanges[tempString] = morphValues[static_cast(i)]; + } + } + session.morphChanges = morphChanges; + + //get index values + std::map indexChanges; + countKeys = env->GetArrayLength(jindexChangesKeys); + countValues = env->GetArrayLength(jindexChangesValues); + if(countKeys != countValues) + { + WARNING(true, ("index keys and values arrays are of diffent sizes")); + return JNI_FALSE; + } + jint * const indexChangesValuesArray = env->GetIntArrayElements(jindexChangesValues, NULL); + if (indexChangesValuesArray == NULL) + { + return JNI_FALSE; + } + std::vector indexValues(indexChangesValuesArray, &indexChangesValuesArray[countValues]); + env->ReleaseIntArrayElements(jindexChangesValues, indexChangesValuesArray, JNI_ABORT); + for (int j = 0; j < countKeys; ++j) + { + JavaString jTempString(static_cast(env->GetObjectArrayElement(jindexChangesKeys, j))); + if (JavaLibrary::convert(jTempString, tempString)) + { + indexChanges[tempString] = indexValues[static_cast(j)]; + } + } + session.indexChanges = indexChanges; + + //get holoemote values + std::string holoEmote; + if(jholoEmote) + { + JavaStringParam localHoloEmote(jholoEmote); + IGNORE_RETURN(JavaLibrary::convert(localHoloEmote, holoEmote)); + } + session.holoEmote = holoEmote; + + bool const result = ServerImageDesignerManager::makeChanges(session); + if(!result) + { + Chat::sendSystemMessage(*designerObj, SharedStringIds::imagedesigner_session_not_valid, Unicode::emptyString); + if(designerObj != recipientObj) + Chat::sendSystemMessage(*recipientObj, SharedStringIds::imagedesigner_session_not_valid, Unicode::emptyString); + ServerImageDesignerManager::cancelSession(session.designerId, session.recipientId); + } + if(result) + return JNI_TRUE; + else + return JNI_FALSE; +} + +//------------------------------------------------------------------------ diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsInstallation.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsInstallation.cpp new file mode 100644 index 00000000..b96b27d2 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsInstallation.cpp @@ -0,0 +1,401 @@ +//======================================================================== +// +// ScriptMethodsInstallation.cpp - implements script methods dealing with general +// object info. +// +// copyright 2001 Sony Online Entertainment +// +//======================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "serverGame/CreatureObject.h" +#include "serverGame/HarvesterInstallationObject.h" +#include "swgSharedNetworkMessages/PermissionListCreateMessage.h" + +using namespace JNIWrappersNamespace; + + +// ====================================================================== +// ScriptMethodsInstallationNamespace +// ====================================================================== + +namespace ScriptMethodsInstallationNamespace +{ + bool install(); + + jint JNICALL getInstalledExtractionRate(JNIEnv *env, jobject self, jlong installation); + jboolean JNICALL isHarvesterActive(JNIEnv *env, jobject self, jlong installation); + jboolean JNICALL isHarvesterEmpty(JNIEnv *env, jobject self, jlong installation); + jint JNICALL getMaxExtractionRate(JNIEnv *env, jobject self, jlong installation); + jboolean JNICALL setMaxExtractionRate(JNIEnv *env, jobject self, jlong installation, jint value); + jint JNICALL getCurrentExtractionRate(JNIEnv *env, jobject self, jlong installation); + jboolean JNICALL setCurrentExtractionRate(JNIEnv *env, jobject self, jlong installation, jint value); + jint JNICALL getMaxHopperAmount(JNIEnv *env, jobject self, jlong installation); + jboolean JNICALL setMaxHopperAmount(JNIEnv *env, jobject self, jlong installation, jint value); + jboolean JNICALL activate(JNIEnv *env, jobject self, jlong installation); + jboolean JNICALL deactivate(JNIEnv *env, jobject self, jlong installation); + void JNICALL displayStructurePermissionData(JNIEnv *env, jobject self, jlong player, jobjectArray currentMembers, jobjectArray nearbyPeople, jstring listName); + jfloat JNICALL getPowerValue(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL setPowerValue(JNIEnv *env, jobject self, jlong target, float value); + jboolean JNICALL incrementPowerValue(JNIEnv *env, jobject self, jlong target, float value); + jfloat JNICALL getPowerRate(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL setPowerRate(JNIEnv *env, jobject self, jlong target, float value); +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsInstallationNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsInstallationNamespace::c)} + JF("_getCurrentExtractionRate", "(J)I", getCurrentExtractionRate), + JF("_setCurrentExtractionRate", "(JI)Z", setCurrentExtractionRate), + JF("_getInstalledExtractionRate","(J)I",getInstalledExtractionRate), + JF("_isHarvesterActive","(J)Z",isHarvesterActive), + JF("_isHarvesterEmpty","(J)Z",isHarvesterEmpty), + JF("_getMaxExtractionRate","(J)I",getMaxExtractionRate), + JF("_setMaxExtractionRate","(JI)Z",setMaxExtractionRate), + JF("_getMaxHopperAmount","(J)I",getMaxHopperAmount), + JF("_setMaxHopperAmount","(JI)Z",setMaxHopperAmount), + JF("_activate","(J)Z",activate), + JF("_deactivate","(J)Z",deactivate), + JF("_displayStructurePermissionData","(J[Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)V",displayStructurePermissionData), + JF("_getPowerValue", "(J)F", getPowerValue), + JF("_setPowerValue", "(JF)Z", setPowerValue), + JF("_incrementPowerValue", "(JF)Z", incrementPowerValue), + JF("_getPowerRate", "(J)F", getPowerRate), + JF("_setPowerRate", "(JF)Z", setPowerRate), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +//---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsInstallationNamespace::getInstalledExtractionRate(JNIEnv *env, jobject self, jlong installation) +{ + UNREF(self); + HarvesterInstallationObject *obj=0; + if (!JavaLibrary::getObject(installation, obj)) + return -1; + return static_cast(obj->getInstalledExtractionRate()); //TODO: do we really want to round this for scripts? +} + +//---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsInstallationNamespace::isHarvesterActive(JNIEnv *env, jobject self, jlong installation) +{ + UNREF(self); + InstallationObject *obj=0; + if (!JavaLibrary::getObject(installation, obj)) + return JNI_FALSE; + return obj->isActive(); +} + +//---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsInstallationNamespace::isHarvesterEmpty(JNIEnv *env, jobject self, jlong installation) +{ + UNREF(self); + Object * obj = 0; + if (!JavaLibrary::getObject(installation, obj)) + { + DEBUG_WARNING (true, ("JavaLibrary::isHarvesterEmpty: could not get object for given obj_id")); + return JNI_FALSE; + } + if(!obj) + { + DEBUG_WARNING (true, ("JavaLibrary::isHarvesterEmpty: could not get an Object from the given obj_id")); + return JNI_FALSE; + } + HarvesterInstallationObject* harv = dynamic_cast(obj); + if(!harv) + { + DEBUG_WARNING (true, ("JavaLibrary::isHarvesterEmpty: obj_id %s does not point to a harvester", obj->getNetworkId().getValueString().c_str())); + return JNI_FALSE; + } + return harv->isEmpty(); +} + +//---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsInstallationNamespace::getMaxExtractionRate(JNIEnv *env, jobject self, jlong installation) +{ + UNREF(self); + HarvesterInstallationObject *obj=0; + if (!JavaLibrary::getObject(installation, obj)) + return -1; + return obj->getMaxExtractionRate(); +} + +//---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsInstallationNamespace::setMaxExtractionRate(JNIEnv *env, jobject self, jlong installation, jint value) +{ + UNREF(self); + HarvesterInstallationObject *obj=0; + if (!JavaLibrary::getObject(installation, obj)) + return JNI_FALSE; + obj->setMaxExtractionRate(value); + return JNI_TRUE; +} + +//---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsInstallationNamespace::getCurrentExtractionRate(JNIEnv *env, jobject self, jlong installation) +{ + UNREF(self); + HarvesterInstallationObject *obj=0; + if (!JavaLibrary::getObject(installation, obj)) + return -1; + return static_cast(obj->getCurrentExtractionRate()); //TODO: do we really want to round this for scripts? +} + +//---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsInstallationNamespace::setCurrentExtractionRate(JNIEnv *env, jobject self, jlong installation, jint value) +{ + UNREF(self); + HarvesterInstallationObject *obj=0; + if (!JavaLibrary::getObject(installation, obj)) + return JNI_FALSE; + obj->setCurrentExtractionRate(static_cast(value)); + return JNI_TRUE; +} + +//---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsInstallationNamespace::getMaxHopperAmount(JNIEnv *env, jobject self, jlong installation) +{ + UNREF(self); + HarvesterInstallationObject *obj=0; + if (!JavaLibrary::getObject(installation, obj)) + return -1; + return obj->getMaxHopperAmount(); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsInstallationNamespace::setMaxHopperAmount(JNIEnv *env, jobject self, jlong installation, jint value) +{ + UNREF(self); + HarvesterInstallationObject *obj=0; + if (!JavaLibrary::getObject(installation, obj)) + return JNI_FALSE; + obj->setMaxHopperAmount(value); + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsInstallationNamespace::activate(JNIEnv *env, jobject self, jlong installation) +{ + UNREF(self); + InstallationObject *obj=0; + if (!JavaLibrary::getObject(installation, obj)) + return JNI_FALSE; + obj->activate(NetworkId::cms_invalid); + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsInstallationNamespace::deactivate(JNIEnv *env, jobject self, jlong installation) +{ + UNREF(self); + InstallationObject *obj=0; + if (!JavaLibrary::getObject(installation, obj)) + return JNI_FALSE; + obj->deactivate(); + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsInstallationNamespace::displayStructurePermissionData(JNIEnv *env, jobject self, jlong player, jobjectArray currentMembers, jobjectArray nearbyPeople, jstring listName) +{ + UNREF(env); + UNREF(self); + + //get the player id from player + CreatureObject* creatureObject = NULL; + if (!JavaLibrary::getObject(player, creatureObject)) + return; + + //convert the jstring[] to a Unicode::String vector + Unicode::String tempMember; + std::vector memberVector; + jsize count = env->GetArrayLength(currentMembers); + for (jsize i = 0; i < count; ++i) + { + JavaStringPtr m = getStringArrayElement(LocalObjectArrayRefParam(currentMembers), i); + if (m != JavaString::cms_nullPtr) + { + if (JavaLibrary::convert(*m, tempMember)) + { + memberVector.push_back(tempMember); + } + } + } + + //convert the jstring[] to a Unicode::String vector + Unicode::String tempPerson; + std::vector nearbyVector; + count = env->GetArrayLength(nearbyPeople); + for (jsize j = 0; j < count; ++j) + { + JavaStringPtr person = getStringArrayElement(LocalObjectArrayRefParam(nearbyPeople), j); + if (person != JavaString::cms_nullPtr) + { + if (JavaLibrary::convert(*person, tempPerson)) + { + nearbyVector.push_back(tempPerson); + } + } + } + + //convert the listName to unicode + Unicode::String localListName; + JavaString l(listName); + JavaLibrary::convert(l, localListName); + + const Client * client = creatureObject->getClient(); + if (client) + { + PermissionListCreateMessage msg(memberVector, nearbyVector, localListName); + client->send(msg,true); + } +} + +// ---------------------------------------------------------------------- + +/** + * Returns an installation's power value. + * + * @param env Java environment + * @param self class calling this function + * @param target id of the installation + * + * @return the power value + */ +jfloat JNICALL ScriptMethodsInstallationNamespace::getPowerValue(JNIEnv *env, jobject self, jlong target) +{ + UNREF(env); + UNREF(self); + + //get the player id from player + const InstallationObject * installation = NULL; + if (!JavaLibrary::getObject(target, installation)) + return 0; + + return installation->getPower(); +} // JavaLibrary::getPowerValue + +// ---------------------------------------------------------------------- + +/** + * Sets an installation's power value. + * + * @param env Java environment + * @param self class calling this function + * @param target id of the installation + * + * @return true on success, false if there was an error + */ +jboolean JNICALL ScriptMethodsInstallationNamespace::setPowerValue(JNIEnv *env, jobject self, jlong target, float value) +{ + UNREF(env); + UNREF(self); + + //get the player id from player + InstallationObject * installation = NULL; + if (!JavaLibrary::getObject(target, installation)) + return JNI_FALSE; + + installation->setPower(value); + return JNI_TRUE; +} // JavaLibrary::setPowerValue + +// ---------------------------------------------------------------------- + +/** + * Changes an installation's power value. + * + * @param env Java environment + * @param self class calling this function + * @param target id of the installation + * @param value the amount to change the power by + * + * @return true on success, false if there was an error + */ +jboolean JNICALL ScriptMethodsInstallationNamespace::incrementPowerValue(JNIEnv *env, jobject self, jlong target, float value) +{ + UNREF(env); + UNREF(self); + + //get the player id from player + InstallationObject * installation = NULL; + if (!JavaLibrary::getObject(target, installation)) + return JNI_FALSE; + + installation->changePower(value); + return JNI_TRUE; +} // JavaLibrary::incrementPowerValue + +// ---------------------------------------------------------------------- + +/** + * Returns an installation's power consumption rate, in units/hour. + * + * @param env Java environment + * @param self class calling this function + * @param target id of the installation + * + * @return the power rate + */ +jfloat JNICALL ScriptMethodsInstallationNamespace::getPowerRate(JNIEnv *env, jobject self, jlong target) +{ + UNREF(env); + UNREF(self); + + //get the player id from player + const InstallationObject * installation = NULL; + if (!JavaLibrary::getObject(target, installation)) + return 0; + + return installation->getPowerRate(); +} // JavaLibrary::getPowerRate + +// ---------------------------------------------------------------------- + +/** + * Sets an installation's power consumption rate, in units/hour. + * + * @param env Java environment + * @param self class calling this function + * @param target id of the installation + * + * @return true on success, false if there was an error + */ +jboolean JNICALL ScriptMethodsInstallationNamespace::setPowerRate(JNIEnv *env, jobject self, jlong target, float value) +{ + UNREF(env); + UNREF(self); + + //get the player id from player + InstallationObject * installation = NULL; + if (!JavaLibrary::getObject(target, installation)) + return JNI_FALSE; + + installation->setPowerRate(value); + return JNI_TRUE; +} // JavaLibrary::setPowerRate + + +// ====================================================================== diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsInterest.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsInterest.cpp new file mode 100644 index 00000000..c668b8fc --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsInterest.cpp @@ -0,0 +1,168 @@ +//======================================================================== +// +// ScriptMethodsInterest.cpp - implements script methods dealing with bank +// +// copyright 2001 Sony Online Entertainment +// +//======================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "sharedFoundation/DynamicVariable.h" +#include "sharedFoundation/DynamicVariableList.h" +#include "sharedNetworkMessages/MapLocation.h" +#include "serverGame/ContainerInterface.h" +#include "serverGame/CreatureObject.h" +#include "serverGame/GameServer.h" +#include "serverGame/PlanetObject.h" +#include "serverGame/ServerObject.h" +#include "serverGame/ServerUniverse.h" +#include "sharedObject/NetworkIdManager.h" + + +// ====================================================================== +// ScriptMethodsInterestNamespace +// ====================================================================== + +namespace ScriptMethodsInterestNamespace +{ + bool install(); + + void JNICALL setAttributeAttained(JNIEnv *env, jobject script, jlong serverObject, jint attribute); + void JNICALL clearAttributeAttained(JNIEnv *env, jobject script, jlong serverObject, jint attribute); + bool JNICALL hasAttributeAttained(JNIEnv *env, jobject script, jlong serverObject, jint attribute); + void JNICALL setAttributeInterested(JNIEnv *env, jobject script, jlong serverObject, jint attribute); + void JNICALL clearAttributeInterested(JNIEnv *env, jobject script, jlong serverObject, jint attribute); + bool JNICALL hasAttributeInterested(JNIEnv *env, jobject script, jlong serverObject, jint attribute); + bool JNICALL isInterested(JNIEnv *env, jobject script, jlong serverObject, jlong serverObject2); +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsInterestNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsInterestNamespace::c)} + JF("_setAttributeAttained", "(JI)V",setAttributeAttained), + JF("_clearAttributeAttained", "(JI)V",clearAttributeAttained), + JF("_hasAttributeAttained", "(JI)Z",hasAttributeAttained), + JF("_setAttributeInterested", "(JI)V",setAttributeInterested), + JF("_clearAttributeInterested", "(JI)V",clearAttributeInterested), + JF("_hasAttributeInterested", "(JI)Z",hasAttributeInterested), + JF("_isInterested", "(JJ)Z",isInterested), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +//----------------------------------------------------------------- + +void JNICALL ScriptMethodsInterestNamespace::setAttributeAttained(JNIEnv *env, jobject script, jlong serverObject, jint attribute) +{ + ServerObject *obj1 = 0; + if(!JavaLibrary::getObject(serverObject, obj1)) + { + DEBUG_WARNING(true, ("[designer bug] JavaLibrary::setAttributeAttained object 1 is invalid")); + return; + } + + obj1->setAttributeAttained(attribute); +} + +//----------------------------------------------------------------- + +void JNICALL ScriptMethodsInterestNamespace::clearAttributeAttained(JNIEnv *env, jobject script, jlong serverObject, jint attribute) +{ + ServerObject *obj1 = 0; + if(!JavaLibrary::getObject(serverObject, obj1)) + { + DEBUG_WARNING(true, ("[designer bug] JavaLibrary::clearAttributeAttained object 1 is invalid")); + return; + } + + obj1->clearAttributeAttained(attribute); +} + +//----------------------------------------------------------------- + +bool JNICALL ScriptMethodsInterestNamespace::hasAttributeAttained(JNIEnv *env, jobject script, jlong serverObject, jint attribute) +{ + ServerObject *obj1 = 0; + if(!JavaLibrary::getObject(serverObject, obj1)) + { + DEBUG_WARNING(true, ("[designer bug] JavaLibrary::hasAttributeAttained object 1 is invalid")); + return false; + } + + return obj1->hasAttributeAttained(attribute); +} + +//----------------------------------------------------------------- + +void JNICALL ScriptMethodsInterestNamespace::setAttributeInterested(JNIEnv *env, jobject script, jlong serverObject, jint attribute) +{ + ServerObject *obj1 = 0; + if(!JavaLibrary::getObject(serverObject, obj1)) + { + DEBUG_WARNING(true, ("[designer bug] JavaLibrary::setAttributeInterested object 1 is invalid")); + return; + } + + obj1->setAttributeInterested(attribute); +} + +//----------------------------------------------------------------- + +void JNICALL ScriptMethodsInterestNamespace::clearAttributeInterested(JNIEnv *env, jobject script, jlong serverObject, jint attribute) +{ + ServerObject *obj1 = 0; + if(!JavaLibrary::getObject(serverObject, obj1)) + { + DEBUG_WARNING(true, ("[designer bug] JavaLibrary::clearAttributeInterested object 1 is invalid")); + return; + } + + obj1->clearAttributeInterested(attribute); +} + +//----------------------------------------------------------------- + +bool JNICALL ScriptMethodsInterestNamespace::hasAttributeInterested(JNIEnv *env, jobject script, jlong serverObject, jint attribute) +{ + ServerObject *obj1 = 0; + if(!JavaLibrary::getObject(serverObject, obj1)) + { + DEBUG_WARNING(true, ("[designer bug] JavaLibrary::hasAttributeInterested object 1 is invalid")); + return false; + } + + return obj1->hasAttributeInterest(attribute); +} + +//----------------------------------------------------------------- + +bool JNICALL ScriptMethodsInterestNamespace::isInterested(JNIEnv *env, jobject script, jlong serverObject, jlong serverObject2) +{ + ServerObject *obj1 = 0; + if(!JavaLibrary::getObject(serverObject, obj1)) + { + DEBUG_WARNING(true, ("[designer bug] JavaLibrary::isInterested object 1 is invalid")); + return false; + } + + ServerObject *obj2 = 0; + if(!JavaLibrary::getObject(serverObject2, obj2)) + { + DEBUG_WARNING(true, ("[designer bug] JavaLibrary::isInterested object 2 is invalid")); + return false; + } + + return obj1->isInterested(*obj2); +} + +//================================================================== diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsInteriors.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsInteriors.cpp new file mode 100644 index 00000000..e978bf6b --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsInteriors.cpp @@ -0,0 +1,861 @@ +//======================================================================== +// +// ScriptMethodsInteriors.cpp - implements script methods dealing with cells and interiors +// +// copyright 2002 Sony Online Entertainment +// +//======================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "serverGame/BuildingObject.h" +#include "serverGame/CellObject.h" +#include "serverGame/ContainerInterface.h" +#include "serverGame/CreatureObject.h" +#include "serverGame/GameServer.h" +#include "serverGame/ServerObject.h" +#include "serverGame/ServerWorld.h" +#include "sharedCollision/Floor.h" +#include "sharedCollision/FloorLocator.h" +#include "sharedMath/Ray3d.h" +#include "sharedObject/CellProperty.h" +#include "sharedObject/NetworkIdManager.h" +#include "sharedObject/PortalProperty.h" +#include "sharedObject/PortalPropertyTemplate.h" + +using namespace JNIWrappersNamespace; + + +// ====================================================================== +// ScriptMethodsInteriorsNamespace +// ====================================================================== + +namespace ScriptMethodsInteriorsNamespace +{ + bool install(); + + jlong JNICALL createObjectInCell(JNIEnv *env, jobject self, jlong source, jlong building, jstring cellName, jobject pos); + jlong JNICALL createObjectInCellString(JNIEnv *env, jobject self, jobject source, jlong building, jstring cellName, jobject pos); + jlong JNICALL _createObjectInCellInternal(JNIEnv *env, jobject self, std::string & templateName, jlong building, jstring cellName, jobject pos); + jlong JNICALL createObjectInCellAnywhere(JNIEnv *env, jobject self, jlong original, jlong building, jstring cellName); + jlong JNICALL createObjectInCellAnywhereString(JNIEnv *env, jobject self, jobject original, jlong building, jstring cellName); + jlong JNICALL _createObjectInCellAnywhereInternal(JNIEnv *env, jobject self, std::string & templateName, jlong building, jstring cellName); + jobjectArray JNICALL getCellNames(JNIEnv *env, jobject self, jlong target); + jstring JNICALL getCellName(JNIEnv *env, jobject self, jlong target); + jlongArray JNICALL getCellIds(JNIEnv *env, jobject self, jlong target); + jlong JNICALL getCellId(JNIEnv *env, jobject self, jlong building, jstring cellName); + jobject JNICALL getLocationForWorldCoordinate(JNIEnv *env, jobject self, jfloat x, jfloat y, jfloat z); + jboolean JNICALL hasCell(JNIEnv *env, jobject self, jlong building, jstring cellName); + jobject JNICALL getGoodLocationInterior(JNIEnv *env, jobject self, jlong building, jstring cellName); + jobject JNICALL getBuildingEjectLocation(JNIEnv *env, jobject self, jlong building); + jboolean JNICALL isValidInteriorLocation (JNIEnv * env, jobject self, jobject location); + jlong JNICALL moveHouseItemToPlayer(JNIEnv *env, jobject self, jlong building, jlong player, int index); + jlong JNICALL moveHouseItemToPlayer2(JNIEnv *env, jobject self, jlong building, jlong player, jlong item); + void JNICALL deleteAllHouseItems(JNIEnv *env, jobject self, jlong building, jlong player); + jboolean JNICALL areAllContentsLoaded(JNIEnv *env, jobject self, jlong building); + void JNICALL loadBuildingContents(JNIEnv *env, jobject self, jlong player, jlong building); + jint JNICALL getPobBaseItemLimit(JNIEnv *env, jobject self, jlong building); + jboolean JNICALL isAtPendingLoadRequestLimit(JNIEnv * env, jobject self); + + jstring JNICALL getCellLabel(JNIEnv * env, jobject self, jlong target); + jboolean JNICALL setCellLabel(JNIEnv * env, jobject self, jlong target, jstring cellLabel); + jboolean JNICALL setCellLabelOffset(JNIEnv * env, jobject self, jlong target, jfloat x, jfloat y, jfloat z); +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsInteriorsNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsInteriorsNamespace::c)} + JF("_createObjectInCell", "(Ljava/lang/String;JLjava/lang/String;Lscript/location;)J", createObjectInCellString), + JF("_createObjectInCell", "(JJLjava/lang/String;Lscript/location;)J", createObjectInCell), + JF("_createObjectInCell", "(Ljava/lang/String;JLjava/lang/String;)J", createObjectInCellAnywhereString), + JF("_createObjectInCell", "(JJLjava/lang/String;)J", createObjectInCellAnywhere), + JF("_getCellNames", "(J)[Ljava/lang/String;", getCellNames), + JF("_getCellName", "(J)Ljava/lang/String;", getCellName), + JF("_getCellIds", "(J)[J", getCellIds), + JF("_getCellId", "(JLjava/lang/String;)J", getCellId), + JF("getLocationForWorldCoordinate", "(FFF)Lscript/location;", getLocationForWorldCoordinate), + JF("_hasCell", "(JLjava/lang/String;)Z", hasCell), + JF("_getGoodLocation", "(JLjava/lang/String;)Lscript/location;", getGoodLocationInterior), + JF("_getBuildingEjectLocation", "(J)Lscript/location;", getBuildingEjectLocation), + JF("isValidInteriorLocation", "(Lscript/location;)Z", isValidInteriorLocation), + JF("_moveHouseItemToPlayer", "(JJI)J", moveHouseItemToPlayer), + JF("_moveHouseItemToPlayer", "(JJJ)J", moveHouseItemToPlayer2), + JF("_deleteAllHouseItems", "(JJ)V", deleteAllHouseItems), + JF("_areAllContentsLoaded", "(J)Z", areAllContentsLoaded), + JF("_loadBuildingContents", "(JJ)V", loadBuildingContents), + JF("_getPobBaseItemLimit", "(J)I", getPobBaseItemLimit), + JF("isAtPendingLoadRequestLimit", "()Z", isAtPendingLoadRequestLimit), + JF("_getCellLabel", "(J)Ljava/lang/String;", getCellLabel), + JF("_setCellLabel", "(JLjava/lang/String;)Z", setCellLabel), + JF("_setCellLabelOffset", "(JFFF)Z", setCellLabelOffset), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +//======================================================================== +// class JavaLibrary JNI Container methods +//======================================================================== + +jlong JNICALL ScriptMethodsInteriorsNamespace::createObjectInCellString(JNIEnv *env, jobject self, jobject source, jlong building, jstring cellName, jobject pos) +{ + UNREF(self); + NOT_NULL(env); + + if (source == 0) + return 0; + if (building == 0) + return 0; + + std::string templateName; + if (env->IsInstanceOf(source, JavaLibrary::getClsString()) == JNI_TRUE) + { + JavaStringParam localSource(static_cast(source)); + JavaLibrary::convert(localSource, templateName); + return _createObjectInCellInternal(env, self, templateName, building, cellName, pos); + } + else + return 0; +} + +jlong JNICALL ScriptMethodsInteriorsNamespace::createObjectInCell(JNIEnv *env, jobject self, jlong source, jlong building, jstring cellName, jobject pos) +{ + UNREF(self); + NOT_NULL(env); + + if (source == 0) + return 0; + if (building == 0) + return 0; + + std::string templateName; + ServerObject* sourceObject = NULL; + if (!JavaLibrary::getObject(source, sourceObject)) + return 0; + templateName = sourceObject->getTemplateName(); + + return _createObjectInCellInternal(env, self, templateName, building, cellName, pos); +} + +jlong JNICALL ScriptMethodsInteriorsNamespace::_createObjectInCellInternal(JNIEnv *env, jobject self, std::string & templateName, jlong building, jstring cellName, jobject pos) +{ + JavaStringParam localCellName(cellName); + + ServerObject * portallizedObject = NULL; + if (!JavaLibrary::getObject(building, portallizedObject)) + return 0; + + std::string cellNameString; + JavaLibrary::convert(localCellName, cellNameString); + + PortalProperty* portalProp = portallizedObject->getPortalProperty(); + if (!portalProp) + return 0; + + ServerObject* cellObject = (portalProp->getCell(cellNameString.c_str()))->getOwner().asServerObject(); + + if (!cellObject) + return 0; + + CellProperty * cellProperty = ContainerInterface::getCell(*cellObject); + + if (!cellProperty) + return 0; + + // This code is a little iffy - The position object we get contains a + // vector and a cell ID, but when we create the object we use the vector + // and a different cell ID. It's possible that we would need to transform + // newPos from the + + Vector newPos; + NetworkId newCell; + ScriptConversion::convert(pos, newPos, newCell); + UNREF(newCell); + + Transform tr; + tr.setPosition_p(newPos); + ServerObject *newObject = ServerWorld::createNewObject(templateName, tr, cellObject, false); + if (newObject == NULL) + return 0; + + //@todo do we need to snap to floor or something? + FloorLocator dropLoc; + Floor const * floor = cellProperty->getFloor(); + + if (!floor) + return 0; + + bool foundLoc = floor->findClosestLocation(newPos,dropLoc); + if(foundLoc) + { + newObject->setPosition_p(dropLoc.getPosition_p()); + } + else + { + DEBUG_REPORT_LOG(true, ("Danger, could not find floor under location in createNewObjectInCell\n")); + } + + // create an networkId to return + NetworkId netId = (newObject->getNetworkId()); + if (netId == NetworkId::cms_invalid) + { + delete newObject; + return 0; + } + return netId.getValue(); +} +//-------------------------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsInteriorsNamespace::createObjectInCellAnywhere(JNIEnv *env, jobject self, jlong source, jlong building, jstring cellName) +{ + //@todo need to find a way to get a good location in a cell. For now just use the coordinates of the cell? + UNREF(self); + NOT_NULL(env); + + if (source == 0) + return 0; + if (building == 0) + return 0; + + std::string templateName; + ServerObject* sourceObject = NULL; + if (!JavaLibrary::getObject(source, sourceObject)) + return 0; + templateName = sourceObject->getTemplateName(); + + return _createObjectInCellAnywhereInternal(env, self, templateName, building, cellName); +} + +jlong JNICALL ScriptMethodsInteriorsNamespace::createObjectInCellAnywhereString(JNIEnv *env, jobject self, jobject source, jlong building, jstring cellName) +{ + //@todo need to find a way to get a good location in a cell. For now just use the coordinates of the cell? + UNREF(self); + NOT_NULL(env); + + if (source == 0) + return 0; + if (building == 0) + return 0; + + std::string templateName; + if (env->IsInstanceOf(source, JavaLibrary::getClsString()) == JNI_TRUE) + { + JavaStringParam localSource(static_cast(source)); + JavaLibrary::convert(localSource, templateName); + return _createObjectInCellAnywhereInternal(env, self, templateName, building, cellName); + } + else + return 0; +} + +jlong JNICALL ScriptMethodsInteriorsNamespace::_createObjectInCellAnywhereInternal(JNIEnv *env, jobject self, std::string & templateName, jlong building, jstring cellName) +{ + //@todo need to find a way to get a good location in a cell. For now just use the coordinates of the cell? + JavaStringParam localCellName(cellName); + + ServerObject *portallizedObject = NULL; + if (!JavaLibrary::getObject(building, portallizedObject)) + return 0; + + std::string cellNameString; + JavaLibrary::convert(localCellName, cellNameString); + + PortalProperty* portalProp = portallizedObject->getPortalProperty(); + if (!portalProp) + return 0; + + CellProperty* cellProp = portalProp->getCell(cellNameString.c_str()); + if (!cellProp) + return 0; + + ServerObject* cellObject = cellProp->getOwner().asServerObject(); + if (!cellObject) + return 0; + + Vector createPosition; + Floor const * floor = cellProp->getFloor(); + bool foundLoc = floor->getGoodLocation(0.5f,createPosition); + if(!foundLoc) + return 0; + + Transform tr; + tr.setPosition_p(createPosition); + ServerObject *newObject = ServerWorld::createNewObject(templateName, tr, cellObject, false); + if (newObject == NULL) + return 0; + + // create an networkId to return + NetworkId netId = (newObject->getNetworkId()); + if (netId == NetworkId::cms_invalid) + { + delete newObject; + return 0; + } + return netId.getValue(); +} + +//-------------------------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsInteriorsNamespace::getCellNames(JNIEnv *env, jobject self, jlong target) +{ + ServerObject const *portallizedObject = NULL; + if (!JavaLibrary::getObject(target, portallizedObject)) + return 0; + + PortalProperty const *cellProp = portallizedObject->getPortalProperty(); + if (!cellProp) + return 0; + + PortalProperty::CellNameList const &nameList = cellProp->getCellNames(); + if (nameList.empty()) + return 0; + + LocalObjectArrayRefPtr nameArray; + if (!ScriptConversion::convert(nameList, nameArray)) + return 0; + + return nameArray->getReturnValue(); +} + +//-------------------------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsInteriorsNamespace::getCellName(JNIEnv *env, jobject self, jlong target) +{ + CellObject const *cellObject = NULL; + if (!JavaLibrary::getObject(target, cellObject)) + return 0; + + // remember: cell object indexes start with 1, but the cell names are 0-based + int cellIndex = cellObject->getCell(); + if (cellIndex <= 0) + { + // cell is uninitialized + return 0; + } + + ServerObject const * const portallizedObject = safe_cast(ContainerInterface::getContainedByObject(*cellObject)); + if (portallizedObject == NULL) + return 0; + + PortalProperty const * const cellProp = portallizedObject->getPortalProperty(); + if (!cellProp) + return 0; + + PortalProperty::CellNameList const &nameList = cellProp->getCellNames(); + if (nameList.empty()) + return 0; + + if (static_cast(cellIndex) > nameList.size()) + { + WARNING(true, ("JavaLibrary::getCellName cell %s has a cell index of %d" + "(base-1), when its owner building %s has only %u cells(base-0)", + cellObject->getNetworkId().getValueString().c_str(), cellIndex, + portallizedObject->getNetworkId().getValueString().c_str(), nameList.size())); + return 0; + } + + JavaString cellName(nameList[cellIndex-1]); + return cellName.getReturnValue(); +} + +//-------------------------------------------------------------------------------------- + +jlongArray JNICALL ScriptMethodsInteriorsNamespace::getCellIds(JNIEnv *env, jobject self, jlong target) +{ + ServerObject const *portallizedObject = NULL; + if (!JavaLibrary::getObject(target, portallizedObject)) + return 0; + + PortalProperty const * const portalProp = portallizedObject->getPortalProperty(); + if (!portalProp) + return 0; + + PortalProperty::CellNameList const &nameList = portalProp->getCellNames(); + if (nameList.empty()) + return 0; + + int count = nameList.size(); + std::vector cellIds; + cellIds.reserve(count); + for (int i = 0; i < count; ++i) + { + ServerObject const * cellObject = NULL; + CellProperty const * const cellProp = portalProp->getCell(nameList[i]); + if (cellProp != NULL) + cellObject = cellProp->getOwner().asServerObject(); + if (cellObject != NULL) + { + cellIds.push_back(cellObject->getNetworkId()); + } + else + cellIds.push_back(NetworkId::cms_invalid); + } + + LocalLongArrayRefPtr idArray; + if (!ScriptConversion::convert(cellIds, idArray)) + return 0; + + return idArray->getReturnValue(); +} + +//-------------------------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsInteriorsNamespace::hasCell(JNIEnv *env, jobject self, jlong portallizedObject, jstring cellName) +{ + JavaStringParam localCellName(cellName); + + ServerObject const * serverObject = NULL; + if (!JavaLibrary::getObject(portallizedObject, serverObject)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::hasCell passed invalid object")); + return 0; + } + + PortalProperty const * const portalProp = serverObject->getPortalProperty(); + if (!portalProp) + { + DEBUG_WARNING(true, ("JavaLibrary::hasCell server object %s has no portal property", serverObject->getDebugInformation().c_str())); + return 0; + } + + std::string cellNameString; + if (!JavaLibrary::convert(localCellName, cellNameString)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::hasCell error converting cell name to C string")); + return 0; + } + + bool found = false; + + CellProperty const * const cellProp = portalProp->getCell(cellNameString.c_str()); + if (cellProp && cellProp->getOwner().asServerObject()) + found = true; + + return static_cast(found); +} + +//-------------------------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsInteriorsNamespace::getCellId(JNIEnv *env, jobject self, jlong portallizedObject, jstring cellName) +{ + JavaStringParam localCellName(cellName); + + ServerObject const * serverObject = NULL; + if (!JavaLibrary::getObject(portallizedObject, serverObject)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("[script bug] JavaLibrary::getCellId passed invalid object")); + return 0; + } + + PortalProperty const * const portalProp = serverObject->getPortalProperty(); + if (!portalProp) + { + DEBUG_WARNING(true, ("[script bug] JavaLibrary::getCellId server object %s has no portal property", serverObject->getDebugInformation().c_str())); + return 0; + } + + std::string cellNameString; + if (!JavaLibrary::convert(localCellName, cellNameString)) + { + DEBUG_WARNING(true, ("[programmer bug] JavaLibrary::getCellId error converting cell name to C string")); + return 0; + } + + CellProperty const * const cellProp = portalProp->getCell(cellNameString.c_str()); + if (!cellProp) + { + DEBUG_WARNING(true, ("[script bug] JavaLibrary::getCellId passed bad cell name %s for portallized object %s", cellNameString.c_str(), serverObject->getDebugInformation().c_str())); + return 0; + } + + ServerObject const * const cellObject = cellProp->getOwner().asServerObject(); + if (!cellObject) + { + DEBUG_WARNING(true, ("[programmer bug] JavaLibrary::getCellId error getting cell object from cell property")); + return 0; + } + + return (cellObject->getNetworkId()).getValue(); +} + +// ---------------------------------------------------------------------- + +jobject JNICALL ScriptMethodsInteriorsNamespace::getLocationForWorldCoordinate(JNIEnv *env, jobject self, jfloat x, jfloat y, jfloat z) +{ + UNREF(self); + NOT_NULL(env); + + Vector position_w(x, y, z); + + LocalRefPtr location; + Vector position_l(position_w); + NetworkId cellId; + + CellProperty const * cellProperty = ServerWorld::findCellAtLocation(position_w); + if (cellProperty) + { + Object const & cellObject = cellProperty->getOwner(); + + position_l = cellObject.rotateTranslate_w2o(position_w); + cellId = cellObject.getNetworkId(); + + if (!ScriptConversion::convert(position_l, ServerWorld::getSceneId(), cellId, location)) + { + DEBUG_WARNING(true, ("getLocationForWorldCoordinate failed creating location object")); + return 0; + } + } + + return location->getReturnValue(); + +} + +// ---------------------------------------------------------------------- + +jobject JNICALL ScriptMethodsInteriorsNamespace::getGoodLocationInterior(JNIEnv *env, jobject self, jlong building, jstring cellName) +{ + UNREF(self); + NOT_NULL(env); + + JavaStringParam localCellName(cellName); + + if (building == 0) + return 0; + + ServerObject const *portallizedObject = 0; + if (!JavaLibrary::getObject(building, portallizedObject)) + return 0; + + std::string cellNameString; + JavaLibrary::convert(localCellName, cellNameString); + + PortalProperty const *portalProp = portallizedObject->getPortalProperty(); + if (!portalProp) + return 0; + + CellProperty const *cellProp = portalProp->getCell(cellNameString.c_str()); + if (!cellProp) + return 0; + + ServerObject const *cellObject = cellProp->getOwner().asServerObject(); + if (!cellObject) + return 0; + + Vector location; + Floor const *floor = cellProp->getFloor(); + bool foundLoc = floor->getGoodLocation(0.5f,location); + if (!foundLoc) + return 0; + + LocalRefPtr goodLocation; + if (!ScriptConversion::convert(location, cellObject->getSceneId(), cellObject->getNetworkId(), goodLocation)) + return 0; + + return goodLocation->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jobject JNICALL ScriptMethodsInteriorsNamespace::getBuildingEjectLocation(JNIEnv *env, jobject self, jlong building) +{ + UNREF(self); + NOT_NULL(env); + + if (building == 0) + { + DEBUG_WARNING(true, ("[designer bug] getBuildingEjectLocation was passed a NULL building objid")); + return 0; + } + + ServerObject const *portallizedObject = 0; + if (!JavaLibrary::getObject(building, portallizedObject)) + { + DEBUG_WARNING(true, ("[designer bug] getBuildingEjectLocation was passed a non-ServerObject objid")); + return 0; + } + + PortalProperty const *portalProp = portallizedObject->getPortalProperty(); + if (!portalProp) + { + DEBUG_WARNING(true, ("[designer bug] getBuildingEjectLocation was passed an objid (%s) of an object that has no PortalProperty", portallizedObject->getDebugInformation().c_str())); + return 0; + } + + PortalPropertyTemplate const &ppTemplate = portalProp->getPortalPropertyTemplate(); + + Transform ejectionTransform(Transform::IF_none); + ejectionTransform.multiply(portallizedObject->getTransform_o2w(), ppTemplate.getEjectionLocationTransform()); + + Vector ejectionWorldPos = ejectionTransform.getPosition_p(); + + CellProperty const *worldCell = CellProperty::getWorldCellProperty(); + if (!worldCell) + { + DEBUG_WARNING(true, ("getBuildingEjectLocation get a NULL worldCell back from CellProperty::getWorldCellProperty()")); + return 0; + } + + NetworkId const &worldCellId = worldCell->getOwner().getNetworkId(); + + LocalRefPtr goodLocation; + if (!ScriptConversion::convert(ejectionWorldPos, portallizedObject->getSceneId(), worldCellId, goodLocation)) + return 0; + + return goodLocation->getReturnValue(); +} + +//-------------------------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsInteriorsNamespace::isValidInteriorLocation (JNIEnv * /*env*/, jobject /*self*/, jobject jobject_location) +{ + NetworkId cellNetworkId; + Vector position_p; + if (!ScriptConversion::convert (jobject_location, position_p, cellNetworkId)) + { + DEBUG_WARNING (true, ("isValidInteriorLocation (): DB failed to convert parameter 1 (location) to cellNetworkId and position_w")); + return JNI_FALSE; + } + + Object const * const object = NetworkIdManager::getObjectById (cellNetworkId); + if (!object) + { + DEBUG_WARNING (true, ("isValidInteriorLocation (): DB could not find cell with object id=%s", cellNetworkId.getValueString ().c_str ())); + return JNI_FALSE; + } + + CellObject const * const cellObject = dynamic_cast (object); + if (!cellObject) + { + DEBUG_WARNING (true, ("isValidInteriorLocation (): DB object id=%s is not a cell", cellNetworkId.getValueString ().c_str ())); + return JNI_FALSE; + } + + CellProperty const * const cellProperty = cellObject->getCellProperty (); + if (!cellProperty) + { + DEBUG_WARNING (true, ("isValidInteriorLocation (): PB could not find cellProperty for cell id=%s name=%s", cellNetworkId.getValueString ().c_str (), cellProperty->getCellName ())); + return JNI_FALSE; + } + + Floor const * const floor = cellProperty->getFloor (); + if (!floor) + { + DEBUG_WARNING (true, ("isValidInteriorLocation (): DB could not find floor for cell id=%s name=%s", cellNetworkId.getValueString ().c_str (), cellProperty->getCellName ())); + return JNI_FALSE; + } + + FloorLocator result; + Vector const direction_p = Vector::negativeUnitY; + Ray3d ray_p (position_p + Vector::unitY, direction_p); + if (floor->intersectClosest (ray_p, result)) + return JNI_TRUE; + + return JNI_FALSE; +} + +//-------------------------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsInteriorsNamespace::moveHouseItemToPlayer(JNIEnv * /*env*/, jobject /*self*/, jlong building, jlong player, int index) +{ + if (building == 0) + { + DEBUG_WARNING(true, ("[designer bug] moveHouseItemToPlayer was passed a NULL building objid")); + return 0; + } + + TangibleObject *pob = 0; + if (!JavaLibrary::getObject(building, pob) || !pob->getPortalProperty()) + { + DEBUG_WARNING(true, ("[designer bug] moveHouseItemToPlayer was passed a non-tangible-pob building objid")); + return 0; + } + + CreatureObject *creatureObject = 0; + if (!JavaLibrary::getObject(player, creatureObject)) + { + DEBUG_WARNING(true, ("[designer bug] moveHouseItemToPlayer was passed a non-CreatureObject player")); + return 0; + } + + return pob->movePobItemToPlayer(*creatureObject, index, false).getValue(); +} + +//-------------------------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsInteriorsNamespace::moveHouseItemToPlayer2(JNIEnv * /*env*/, jobject /*self*/, jlong building, jlong player, jlong item) +{ + if (building == 0) + { + DEBUG_WARNING(true, ("[designer bug] moveHouseItemToPlayer2 was passed a NULL building objid")); + return 0; + } + + TangibleObject *pob = 0; + if (!JavaLibrary::getObject(building, pob) || !pob->getPortalProperty()) + { + DEBUG_WARNING(true, ("[designer bug] moveHouseItemToPlayer2 was passed a non-tangible-pob building objid")); + return 0; + } + + CreatureObject *creatureObject = 0; + if (!JavaLibrary::getObject(player, creatureObject)) + { + DEBUG_WARNING(true, ("[designer bug] moveHouseItemToPlayer2 was passed a non-CreatureObject player")); + return 0; + } + + return pob->movePobItemToPlayer(*creatureObject, NetworkId(static_cast(item)), false).getValue(); +} + +//-------------------------------------------------------------------------------------- + +void JNICALL ScriptMethodsInteriorsNamespace::deleteAllHouseItems(JNIEnv * /*env*/, jobject /*self*/, jlong building, jlong player) + +{ + if (building == 0) + { + DEBUG_WARNING(true, ("[designer bug] deleteAllHouseItems was passed a NULL building objid")); + return ; + } + + TangibleObject *pob = 0; + if (!JavaLibrary::getObject(building, pob) || !pob->getPortalProperty()) + { + DEBUG_WARNING(true, ("[designer bug] deleteAllHouseItems was passed a non-tangible-pob building objid")); + return; + } + + CreatureObject const *creatureObject = 0; + if (!JavaLibrary::getObject(player, creatureObject)) + { + DEBUG_WARNING(true, ("[designer bug] deleteAllHouseItems was passed a non-CreatereObject player")); + return; + } + pob->deletePobPersistedContents(creatureObject, DeleteReasons::Player); +} + +//-------------------------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsInteriorsNamespace::areAllContentsLoaded(JNIEnv * /*env*/, jobject /*self*/, jlong building) +{ + if (building == 0) + { + DEBUG_WARNING(true, ("[designer bug] areAllContentsLoaded was passed a NULL building objid")); + return JNI_FALSE; + } + + const BuildingObject * buildingObject = NULL; + if (!JavaLibrary::getObject(building, buildingObject)) + { + DEBUG_WARNING(true, ("[designer bug] areAllContentsLoaded was passed a non-ServerObject objid")); + return JNI_FALSE; + } + + return static_cast(buildingObject->getContentsLoaded() ? JNI_TRUE : JNI_FALSE); +} + +//-------------------------------------------------------------------------------------- + +void JNICALL ScriptMethodsInteriorsNamespace::loadBuildingContents(JNIEnv * /*env*/, jobject /*self*/, jlong player, jlong building) +{ + if (building == 0) + { + DEBUG_WARNING(true, ("[designer bug] loadBuildingContents was passed a NULL building objid")); + return; + } + + BuildingObject * buildingObject = NULL; + if (!JavaLibrary::getObject(building, buildingObject)) + { + DEBUG_WARNING(true, ("[designer bug] loadBuildingContents was passed a non-ServerObject objid")); + return; + } + + if (GameServer::isAtPendingLoadRequestLimit()) + { + WARNING(true, ("loadBuildingContents attempted to load building contents while at the request limit")); + return; + } + + GameServer::addPendingLoadRequest(buildingObject->getNetworkId()); + + // Check for loading objvar first + buildingObject->loadContents(); +} + +//-------------------------------------------------------------------------------------- + +jint JNICALL ScriptMethodsInteriorsNamespace::getPobBaseItemLimit(JNIEnv * /*env*/, jobject /*self*/, jlong building) +{ + TangibleObject *pob = 0; + if(!JavaLibrary::getObject(building, pob) || !pob->getPortalProperty()) + { + DEBUG_WARNING(true, ("[designer bug] getPobBaseItemLimit() was passed a non-tangible-pob building objid")); + return 0; + } + + return pob->getPobBaseItemLimit(); +} + +//-------------------------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsInteriorsNamespace::isAtPendingLoadRequestLimit(JNIEnv * /*env*/, jobject /*self*/) +{ + return GameServer::isAtPendingLoadRequestLimit(); +} + +//-------------------------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsInteriorsNamespace::getCellLabel(JNIEnv * env, jobject self, jlong target) +{ + CellObject const *cellObject = NULL; + if (!JavaLibrary::getObject(target, cellObject)) + return NULL; + + JavaString cellLabel(cellObject->getCellLabel()); + return cellLabel.getReturnValue(); +} + +//-------------------------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsInteriorsNamespace::setCellLabel(JNIEnv * env, jobject self, jlong target, jstring cellLabel) +{ + JavaStringParam localCellLabel(cellLabel); + + Unicode::String cellLabelString; + if (!JavaLibrary::convert(localCellLabel, cellLabelString)) + return JNI_FALSE; + + CellObject * cellObject = NULL; + if (!JavaLibrary::getObject(target, cellObject)) + return JNI_FALSE; + + cellObject->setCellLabel(cellLabelString); + + return JNI_TRUE; +} + +//-------------------------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsInteriorsNamespace::setCellLabelOffset(JNIEnv * env, jobject self, jlong target, jfloat x, jfloat y, jfloat z) +{ + CellObject * cellObject = NULL; + if (!JavaLibrary::getObject(target, cellObject)) + return JNI_FALSE; + + Vector offset(x, y, z); + + cellObject->setLabelLocationOffset(offset); + + return JNI_TRUE; +} + +//-------------------------------------------------------------------------------------- diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsJedi.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsJedi.cpp new file mode 100644 index 00000000..1afeec06 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsJedi.cpp @@ -0,0 +1,943 @@ +//======================================================================== +// +// ScriptMethodsJedi.cpp - implements script methods dealing with Jedi. +// +// copyright 2001 Sony Online Entertainment +// +//======================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" +#include "serverScript/GameScriptObject.h" +#include "serverScript/ScriptParameters.h" +#include "serverGame/CreatureObject.h" +#include "serverGame/MessageToQueue.h" +#include "serverGame/PlayerCreatureController.h" +#include "serverGame/PlayerObject.h" +#include "SwgGameServer/JediManagerObject.h" +#include "SwgGameServer/SwgCreatureObject.h" +#include "SwgGameServer/SwgPlayerObject.h" +#include "SwgGameServer/SwgServerUniverse.h" + +using namespace JNIWrappersNamespace; + + +// @todo: move these functions into SwgGameServer project + +// ====================================================================== +// ScriptMethodsJediNamespace +// ====================================================================== + +namespace ScriptMethodsJediNamespace +{ + bool install(); + + jint JNICALL getMaxForcePower(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL setMaxForcePower(JNIEnv *env, jobject self, jlong target, jint value); + jboolean JNICALL alterMaxForcePower(JNIEnv *env, jobject self, jlong target, jint delta); + jint JNICALL getForcePower(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL setForcePower(JNIEnv *env, jobject self, jlong target, jint value); + jboolean JNICALL alterForcePower(JNIEnv *env, jobject self, jlong target, jint delta); + jfloat JNICALL getForcePowerRegenRate(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL setForcePowerRegenRate(JNIEnv *env, jobject self, jlong target, jfloat rate); + jint JNICALL getJediState(JNIEnv *env, jobject self, jlong jedi); + jboolean JNICALL setJediState(JNIEnv *env, jobject self, jlong jedi, jint state); + jboolean JNICALL hasJediSlot(JNIEnv * env, jobject self, jlong target); + jboolean JNICALL addJediSlot(JNIEnv * env, jobject self, jlong target); + jboolean JNICALL isJedi(JNIEnv * env, jobject self, jlong target); + jint JNICALL getJediVisibility(JNIEnv * env, jobject self, jlong target); + jboolean JNICALL setJediVisibility(JNIEnv * env, jobject self, jlong target, jint visibility); + jboolean JNICALL changeJediVisibility(JNIEnv * env, jobject self, jlong target, jint delta); + jboolean JNICALL setJediBountyValue(JNIEnv * env, jobject self, jlong target, jint bountyValue); + jobject JNICALL requestJedi(JNIEnv * env, jobject self, jint visibility, jint bountyValue, jint minLevel, jint maxLevel, jint hoursAlive, jint state, jint bounties); + jobject JNICALL requestOneJedi(JNIEnv * env, jobject self, jlong target); + jboolean JNICALL requestJediBounty(JNIEnv * env, jobject self, jlong target, jlong hunter, jstring successCallback, jstring failCallback, jlong callbackobj); + jboolean JNICALL removeJediBounty(JNIEnv * env, jobject self, jlong target, jlong hunter); + jboolean JNICALL removeAllJediBounties(JNIEnv * env, jobject self, jlong target); + jlongArray JNICALL getBountyHunterBounties(JNIEnv * env, jobject self, jlong hunter); + jlongArray JNICALL getJediBounties(JNIEnv * env, jobject self, jlong target); + jboolean JNICALL isBeingHuntedByBountyHunter(JNIEnv * env, jobject self, jlong target, jlong hunter); + void JNICALL updateJediScriptData(JNIEnv * env, jobject self, jlong id, jstring name, jint value); + void JNICALL removeJediScriptData(JNIEnv * env, jobject self, jlong id, jstring name); +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsJediNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsJediNamespace::c)} + JF("_getMaxForcePower", "(J)I", getMaxForcePower), + JF("_setMaxForcePower", "(JI)Z", setMaxForcePower), + JF("_alterMaxForcePower", "(JI)Z", alterMaxForcePower), + JF("_getForcePower", "(J)I", getForcePower), + JF("_setForcePower", "(JI)Z", setForcePower), + JF("_alterForcePower", "(JI)Z", alterForcePower), + JF("_getForcePowerRegenRate", "(J)F", getForcePowerRegenRate), + JF("_setForcePowerRegenRate", "(JF)Z", setForcePowerRegenRate), + JF("_getJediState", "(J)I", getJediState), + JF("_setJediState", "(JI)Z", setJediState), + JF("_hasJediSlot", "(J)Z", hasJediSlot), + JF("_addJediSlot", "(J)Z", addJediSlot), + JF("_isJedi", "(J)Z", isJedi), + JF("_getJediVisibility", "(J)I", getJediVisibility), + JF("_setJediVisibility", "(JI)Z", setJediVisibility), + JF("_changeJediVisibility", "(JI)Z", changeJediVisibility), + JF("_setJediBountyValue", "(JI)Z", setJediBountyValue), + JF("_requestJedi", "(IIIIIII)Lscript/dictionary;", requestJedi), + JF("__requestJedi", "(J)Lscript/dictionary;", requestOneJedi), + JF("_requestJediBounty", "(JJLjava/lang/String;Ljava/lang/String;J)Z", requestJediBounty), + JF("_removeJediBounty", "(JJ)Z", removeJediBounty), + JF("_removeAllJediBounties", "(J)Z", removeAllJediBounties), + JF("_getJediBounties", "(J)[J", getJediBounties), + JF("_getBountyHunterBounties", "(J)[J", getBountyHunterBounties), + JF("_isBeingHuntedByBountyHunter", "(JJ)Z", isBeingHuntedByBountyHunter), + JF("_updateJediScriptData", "(JLjava/lang/String;I)V", updateJediScriptData), + JF("_removeJediScriptData", "(JLjava/lang/String;)V", removeJediScriptData), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +//======================================================================== +// class JavaLibrary JNI script callback methods +//======================================================================== + +/** + * Returns the maximum force power of a creature. + * + * @param env Java environment + * @param self class calling this function + * @param target the creature who's power to get + * + * @return the max force power + */ +jint JNICALL ScriptMethodsJediNamespace::getMaxForcePower(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + const CreatureObject * creature = NULL; + if (!JavaLibrary::getObject(target, creature)) + return 0; + + if (!creature->isPlayerControlled()) + return 0; + + PlayerObject const * const playerObject = PlayerCreatureController::getPlayerObject(creature); + if (playerObject == NULL) + return 0; + + return playerObject->getMaxForcePower(); +} // JavaLibrary::getMaxForcePower + +/** + * Sets the maximum force power of a creature. + * + * @param env Java environment + * @param self class calling this function + * @param target the creature who's power to set + * @param value the new maximum force power value + * + * @return true on success, false if the target isn't a creature + */ +jboolean JNICALL ScriptMethodsJediNamespace::setMaxForcePower(JNIEnv *env, jobject self, jlong target, jint value) +{ + UNREF(self); + + CreatureObject * creature = NULL; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + if (!creature->isPlayerControlled()) + { + // we want to have scripts think non-player creatures can have force + return JNI_TRUE; + } + + PlayerObject * playerObject = PlayerCreatureController::getPlayerObject(creature); + if (playerObject == NULL) + return JNI_FALSE; + + playerObject->setMaxForcePower(value); + return JNI_TRUE; +} // JavaLibrary::setMaxForcePower + +/** + * Changes the maximum force power of a creature. + * + * @param env Java environment + * @param self class calling this function + * @param target the creature who's power to change + * @param value the value to add to the creature's maximum force power + * + * @return true on success, false if the target isn't a creature + */ +jboolean JNICALL ScriptMethodsJediNamespace::alterMaxForcePower(JNIEnv *env, jobject self, jlong target, jint delta) +{ + UNREF(self); + + CreatureObject * creature = NULL; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + if (!creature->isPlayerControlled()) + { + // we want to have scripts think non-player creatures can have force + return JNI_TRUE; + } + + PlayerObject * playerObject = PlayerCreatureController::getPlayerObject(creature); + if (playerObject == NULL) + return JNI_FALSE; + + playerObject->setMaxForcePower(playerObject->getMaxForcePower() + delta); + return JNI_TRUE; +} // JavaLibrary::alterMaxForcePower + +/** + * Returns the force power of a creature. + * + * @param env Java environment + * @param self class calling this function + * @param target the creature who's power to get + * + * @return the force power + */ +jint JNICALL ScriptMethodsJediNamespace::getForcePower(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + const CreatureObject * creature = NULL; + if (!JavaLibrary::getObject(target, creature)) + return 0; + + if (!creature->isPlayerControlled()) + return 0; + + PlayerObject const * const playerObject = PlayerCreatureController::getPlayerObject(creature); + if (playerObject == NULL) + return 0; + + return playerObject->getForcePower(); +} // JavaLibrary::getForcePower + +/** + * Sets the force power of a creature. + * + * @param env Java environment + * @param self class calling this function + * @param target the creature who's power to set + * @param value the new force power value + * + * @return true on success, false if the target isn't a creature + */ +jboolean JNICALL ScriptMethodsJediNamespace::setForcePower(JNIEnv *env, jobject self, jlong target, jint value) +{ + UNREF(self); + + CreatureObject * creature = NULL; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + if (!creature->isPlayerControlled()) + { + // we want to have scripts think non-player creatures can have force + return JNI_TRUE; + } + + PlayerObject * playerObject = PlayerCreatureController::getPlayerObject(creature); + if (playerObject == NULL) + return JNI_FALSE; + + playerObject->setForcePower(value); + return JNI_TRUE; +} // JavaLibrary::setForcePower + +/** + * Changes the force power of a creature. + * + * @param env Java environment + * @param self class calling this function + * @param target the creature who's power to change + * @param value the value to add to the creature's force power + * + * @return true on success, false if the target isn't a creature + */ +jboolean JNICALL ScriptMethodsJediNamespace::alterForcePower(JNIEnv *env, jobject self, jlong target, jint delta) +{ + UNREF(self); + + CreatureObject * creature = NULL; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + if (!creature->isPlayerControlled()) + { + // we want to have scripts think non-player creatures can have force + return JNI_TRUE; + } + + PlayerObject * playerObject = PlayerCreatureController::getPlayerObject(creature); + if (playerObject == NULL) + return JNI_FALSE; + + playerObject->setForcePower(playerObject->getForcePower() + delta); + return JNI_TRUE; +} // JavaLibrary::alterForcePower + +/** + * Returns the regeneration rate for the force power of a creature. + * + * @param env Java environment + * @param self class calling this function + * @param target the creature who's regen rate to get + * + * @return the regen rate, in units/sec + */ +jfloat JNICALL ScriptMethodsJediNamespace::getForcePowerRegenRate(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + const CreatureObject * creature = NULL; + if (!JavaLibrary::getObject(target, creature)) + return 0; + + if (!creature->isPlayerControlled()) + return 0; + + PlayerObject const * const playerObject = PlayerCreatureController::getPlayerObject(creature); + if (playerObject == NULL) + return 0; + + return playerObject->getForcePowerRegenRate(); +} // JavaLibrary::getForcePowerRegenRate + +/** + * Sets the regeneration rate for the force power of a creature. + * + * @param env Java environment + * @param self class calling this function + * @param target the creature who's regen rate to set + * @param rate the regen rate, in units/sec + * + * @return true on success, false if the target wasn't a creature + */ +jboolean JNICALL ScriptMethodsJediNamespace::setForcePowerRegenRate(JNIEnv *env, jobject self, jlong target, jfloat rate) +{ + UNREF(self); + + CreatureObject * creature = NULL; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + if (!creature->isPlayerControlled()) + { + // we want to have scripts think non-player creatures can have force + return JNI_TRUE; + } + + PlayerObject * playerObject = PlayerCreatureController::getPlayerObject(creature); + if (playerObject == NULL) + return JNI_FALSE; + + playerObject->setForcePowerRegenRate(rate); + return JNI_TRUE; +} // JavaLibrary::setForcePowerRegenRate + +/** + * Returns the state of a Jedi. + * + * @param env Java environment + * @param self class calling this function + * @param jedi the Jedi to get + * + * @return the state, or -1 on error + */ +jint JNICALL ScriptMethodsJediNamespace::getJediState(JNIEnv *env, jobject self, jlong jedi) +{ + const CreatureObject * object = NULL; + if (!JavaLibrary::getObject(jedi, object)) + { + WARNING(true, ("JavaLibrary::getJediState did not find creature for id passed in")); + return -1; + } + + const SwgPlayerObject * player = safe_cast(PlayerCreatureController::getPlayerObject(object)); + if (player == NULL) + { + WARNING(true, ("JavaLibrary::getJediState did not find player for creature " + "%s", object->getNetworkId().getValueString().c_str())); + return -1; + } + + return player->getJediState(); +} // JavaLibrary::getJediState + +/** + * Sets the state of a Jedi. + * + * @param env Java environment + * @param self class calling this function + * @param jedi the Jedi to set + * @param state the state to set + * + * @return true on success, false on error + */ +jboolean JNICALL ScriptMethodsJediNamespace::setJediState(JNIEnv *env, jobject self, jlong jedi, jint state) +{ + CreatureObject * object = NULL; + if (!JavaLibrary::getObject(jedi, object)) + return JNI_FALSE; + + SwgPlayerObject * const player = safe_cast(PlayerCreatureController::getPlayerObject(object)); + if (player == NULL) + return JNI_FALSE; + + if (state == JS_none || + state == JS_forceSensitive || + state == JS_jedi || + state == JS_forceRankedLight || + state == JS_forceRankedDark + ) + { + player->setJediState(static_cast(state)); + return JNI_TRUE; + } + + WARNING(true, ("JavaLibrary::setJediState called for player %s with invalid " + "state %d", object->getNetworkId().getValueString().c_str(), state)); + return JNI_FALSE; +} // JavaLibrary::setJediState + +/** + * Returns if a player has a Jedi slot available to them. + * + * @param env Java environment + * @param self class calling this function + * @param player the player to test + * + * @return true if the player has a Jedi slot, false if not + */ +jboolean JNICALL ScriptMethodsJediNamespace::hasJediSlot(JNIEnv * env, jobject self, jlong target) +{ + const ServerObject * player = NULL; + if (!JavaLibrary::getObject(target, player)) + return JNI_FALSE; + + // @todo: implement function + + return JNI_FALSE; +} // JavaLibrary::hasJediSlot + +/** + * Adds a Jedi slot to a player's available character slots. + * + * @param env Java environment + * @param self class calling this function + * @param player the player to test + * + * @return true on success, false on error + */ +jboolean JNICALL ScriptMethodsJediNamespace::addJediSlot(JNIEnv * env, jobject self, jlong target) +{ + const CreatureObject * object = NULL; + if (!JavaLibrary::getObject(target, object)) + return JNI_FALSE; + + PlayerObject const * const player = PlayerCreatureController::getPlayerObject(object); + if (player == NULL) + return JNI_FALSE; + + player->addJediToAccount(); + // since we won't know if this function succeeds util we get the callback, + // set up a timed callback to re-call this function if addJediToAccountAck() + // never gets called + MessageToQueue::getInstance().sendMessageToC(object->getNetworkId(), + "C++AddJediSlot", "", 5 * 60, true); + + return JNI_FALSE; +} // JavaLibrary::addJediSlot + +/** + * Returns if a creature is a Jedi or not. + * + * @param env Java environment + * @param self class calling this function + * @param target the creature to test + * + * @return the true if the creature is a jedi, false if not + */ +jboolean JNICALL ScriptMethodsJediNamespace::isJedi(JNIEnv * env, jobject self, jlong target) +{ + UNREF(self); + + const CreatureObject * creature = NULL; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + const PlayerObject * player = PlayerCreatureController::getPlayerObject(creature); + if (player == NULL) + return JNI_FALSE; + const SwgPlayerObject * jedi = safe_cast(player); + + if (jedi->isJedi()) + return JNI_TRUE; + return JNI_FALSE; +} // JavaLibrary::isJedi + +/** + * Returns the visibility of a Jedi. + * + * @param env Java environment + * @param self class calling this function + * @param target the Jedi to get + * + * @return the visibility, or -1 on error + */ +jint JNICALL ScriptMethodsJediNamespace::getJediVisibility(JNIEnv * env, jobject self, jlong target) +{ + UNREF(self); + + const CreatureObject * creature = NULL; + if (!JavaLibrary::getObject(target, creature)) + return -1; + + const PlayerObject * player = PlayerCreatureController::getPlayerObject(creature); + if (player == NULL) + return JNI_FALSE; + const SwgPlayerObject * jedi = safe_cast(player); + + if (!jedi->isJedi()) + return -1; + + return jedi->getJediVisibility(); +} // JavaLibrary::getJediVisibility + +/** + * Sets the visibility of a Jedi. + * + * @param env Java environment + * @param self class calling this function + * @param target the Jedi to set + * @param visibility the visibility to set + * + * @return true on success, false on error + */ +jboolean JNICALL ScriptMethodsJediNamespace::setJediVisibility(JNIEnv * env, jobject self, jlong target, jint visibility) +{ + UNREF(self); + + CreatureObject * creature = NULL; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + PlayerObject * player = PlayerCreatureController::getPlayerObject(creature); + if (player == NULL) + return JNI_FALSE; + SwgPlayerObject * jedi = safe_cast(player); + + if (!jedi->isJedi()) + return JNI_FALSE; + + jedi->setJediVisibility(visibility); + return JNI_TRUE; +} // JavaLibrary::setJediVisibility + +/** + * Changes the current visibility of a Jedi. + * + * @param env Java environment + * @param self class calling this function + * @param target the Jedi to change + * @param delta the amount to add to the Jedi's current visibility + * + * @return true on success, false on error + */ +jboolean JNICALL ScriptMethodsJediNamespace::changeJediVisibility(JNIEnv * env, jobject self, jlong target, jint delta) +{ + UNREF(self); + + CreatureObject * creature = NULL; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + PlayerObject * player = PlayerCreatureController::getPlayerObject(creature); + if (player == NULL) + return JNI_FALSE; + SwgPlayerObject * jedi = safe_cast(player); + + if (!jedi->isJedi()) + return JNI_FALSE; + + jedi->setJediVisibility(jedi->getJediVisibility() + delta); + return JNI_TRUE; +} // JavaLibrary::changeJediVisibility + +/** + * Sets the bounty value of a Jedi. + * + * @param env Java environment + * @param self class calling this function + * @param target the Jedi to set + * @param bountyValue the bounty value to set + * + * @return true on success, false on error + */ +jboolean JNICALL ScriptMethodsJediNamespace::setJediBountyValue(JNIEnv * env, jobject self, jlong target, jint bountyValue) +{ + UNREF(self); + + CreatureObject * creature = NULL; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + SwgCreatureObject const * jediCreature = safe_cast(creature); + + PlayerObject const * player = PlayerCreatureController::getPlayerObject(creature); + if (player == NULL) + return JNI_FALSE; + SwgPlayerObject const * jediPlayer = safe_cast(player); + + JediManagerObject * jediManager = static_cast( + ServerUniverse::getInstance()).getJediManager(); + if (jediManager == NULL) + return JNI_FALSE; + + jediManager->addJedi(creature->getNetworkId(), creature->getObjectName(), + creature->getPosition_w(), creature->getSceneId(), jediPlayer->getJediVisibility(), + bountyValue, creature->getLevel(), + 0, jediPlayer->getJediState(), jediCreature->getSpentJediSkillPoints(), creature->getPvpFaction()); + + return JNI_TRUE; +} // JavaLibrary::setJediVisibility + +/** + * Sends a request to find Jedi characters. Limits are passed in for statistics + * that the caller is interested in; the Jedi returned will have the requested + * value or greater for the statistic if the value given is >= 0, or less than + * the statistic if the value given is < 0. If the statistic should be ignored, + * IGNORE_JEDI_STAT should be passed in as the limit value. + * + * @param env Java environment + * @param self class calling this function + * @param visibility limit for visibility statistic + * @param bountyValue limit for bounty value statistic + * @param minLevel minimum Jedi level (inclusive) + * @param maxLevel maximum Jedi level (inclusive) + * @param hoursAlive limit for hours alive statistic + * @param bounties limit for number of bounties on the Jedi statistic + * @param state what state(s) the Jedi should have + * + * @return a dictionary with the Jedi data on success, null on error + */ +jobject JNICALL ScriptMethodsJediNamespace::requestJedi(JNIEnv * env, jobject self, jint visibility, + jint bountyValue, jint minLevel, jint maxLevel, jint hoursAlive, jint bounties, jint state) +{ + UNREF(self); + + JediManagerObject * jediManager = static_cast( + ServerUniverse::getInstance()).getJediManager(); + if (jediManager == NULL) + return 0; + + ScriptParams params; + jediManager->getJedi(visibility, bountyValue, minLevel, maxLevel, hoursAlive, bounties, state, params); + + JavaDictionaryPtr dictionary; + JavaLibrary::instance()->convert(params, dictionary); + return dictionary->getReturnValue(); +} // JavaLibrary::requestJedi + +/** + * Sends a request to find a specific Jedi. + * + * @param env Java environment + * @param self class calling this function + * @param target the id of the Jedi + * + * @return a dictionary with the Jedi data on success, null on error + */ +jobject JNICALL ScriptMethodsJediNamespace::requestOneJedi(JNIEnv * env, jobject self, jlong target) +{ + UNREF(self); + + JediManagerObject * jediManager = static_cast( + ServerUniverse::getInstance()).getJediManager(); + if (jediManager == NULL) + return 0; + + const NetworkId id(target); + if (id == NetworkId::cms_invalid) + return 0; + + ScriptParams params; + jediManager->getJedi(id, params); + if (params.getParams().size() == 0) + return 0; + + JavaDictionaryPtr dictionary; + JavaLibrary::instance()->convert(params, dictionary); + return dictionary->getReturnValue(); +} // JavaLibrary::requestJedi + +/** + * Requests to assign a bounty hunter to track down a Jedi. + * + * @param env Java environment + * @param self class calling this function + * @param target the Jedi to hunt + * @param hunter the bounty hunter + * @param successCallback name of a messageHandler than will be called if the + * bounty was assigned + * @param failCallback name of a messageHandler than will be called if the + * bounty was not assigned + * @param callbackobj the object that will get the callback + * + * @return true if the request was sent, false if there was an error + */ +jboolean JNICALL ScriptMethodsJediNamespace::requestJediBounty(JNIEnv * env, jobject self, jlong target, jlong hunter, jstring successCallback, jstring failCallback, jlong callbackobj) +{ + UNREF(self); + + JediManagerObject * jediManager = static_cast( + ServerUniverse::getInstance()).getJediManager(); + if (jediManager == NULL) + return JNI_FALSE; + + const NetworkId targetId(target); + if (targetId == NetworkId::cms_invalid) + return JNI_FALSE; + + const NetworkId hunterId(hunter); + if (hunterId == NetworkId::cms_invalid) + return JNI_FALSE; + + JavaStringParam jsuccessCallback(successCallback); + std::string successCallbackString; + if (!JavaLibrary::convert(jsuccessCallback, successCallbackString)) + return JNI_FALSE; + + JavaStringParam jfailCallback(failCallback); + std::string failCallbackString; + if (!JavaLibrary::convert(jfailCallback, failCallbackString)) + return JNI_FALSE; + + const NetworkId callbackId(callbackobj); + if (callbackId == NetworkId::cms_invalid) + return JNI_FALSE; + + jediManager->requestJediBounty(targetId, hunterId, successCallbackString, + failCallbackString, callbackId); + + return JNI_TRUE; +} // JavaLibrary::requestJediBounty + +/** + * Removes a bounty hunter from a Jedi. + * + * @param env Java environment + * @param self class calling this function + * @param target the Jedi + * @param hunter the hunter's id + * + * @return true on success, false if there was an error + */ +jboolean JNICALL ScriptMethodsJediNamespace::removeJediBounty(JNIEnv * env, jobject self, jlong target, jlong hunter) +{ + UNREF(self); + + JediManagerObject * jediManager = static_cast( + ServerUniverse::getInstance()).getJediManager(); + if (jediManager == NULL) + return JNI_FALSE; + + const NetworkId targetId(target); + if (targetId == NetworkId::cms_invalid) + return JNI_FALSE; + + const NetworkId hunterId(hunter); + if (hunterId == NetworkId::cms_invalid) + return JNI_FALSE; + + jediManager->removeJediBounty(targetId, hunterId); + return JNI_TRUE; +} // JavaLibrary::removeJediBounty + +/** + * Removes all the bounties on a Jedi. + * + * @param env Java environment + * @param self class calling this function + * @param target the Jedi + * + * @return true on success, false if there was an error + */ +jboolean JNICALL ScriptMethodsJediNamespace::removeAllJediBounties(JNIEnv * env, jobject self, jlong target) +{ + UNREF(self); + + JediManagerObject * jediManager = static_cast( + ServerUniverse::getInstance()).getJediManager(); + if (jediManager == NULL) + return JNI_FALSE; + + const NetworkId targetId(target); + if (targetId == NetworkId::cms_invalid) + return JNI_FALSE; + + jediManager->removeAllJediBounties(targetId); + return JNI_TRUE; +} // JavaLibrary::removeAllJediBounties + +/** + * Returns a list of players who are hunting a Jedi. + * + * @param env Java environment + * @param self class calling this function + * @param target the Jedi + * + * @return an array of hunter ids, or null on error + */ +jlongArray JNICALL ScriptMethodsJediNamespace::getJediBounties(JNIEnv * env, jobject self, jlong target) +{ + UNREF(self); + + JediManagerObject * jediManager = static_cast( + ServerUniverse::getInstance()).getJediManager(); + if (jediManager == NULL) + return 0; + + const NetworkId targetId(target); + if (targetId == NetworkId::cms_invalid) + return 0; + + const std::vector & hunters = jediManager->getJediBounties(targetId); + + LocalLongArrayRefPtr returnArray; + if (!ScriptConversion::convert(hunters, returnArray)) + return 0; + + return returnArray->getReturnValue(); +} // JavaLibrary::getJediBounties + +/** +* Checks to see if a bounty hunter has a bounty on a target +* +* @param target the Jedi to hunt +* @param hunter the bounty hunter +* +* @return true or false +*/ +jboolean JNICALL ScriptMethodsJediNamespace::isBeingHuntedByBountyHunter(JNIEnv * env, jobject self, jlong target, jlong hunter) +{ + UNREF(self); + + JediManagerObject * jediManager = static_cast( + ServerUniverse::getInstance()).getJediManager(); + if (jediManager == NULL) + return JNI_FALSE; + + const NetworkId targetId(target); + if (targetId == NetworkId::cms_invalid) + return JNI_FALSE; + + const NetworkId hunterId(hunter); + if (hunterId == NetworkId::cms_invalid) + return JNI_FALSE; + + if (jediManager->hasBountyOnJedi(targetId, hunterId)) + return JNI_TRUE; + + return JNI_FALSE; +} // JavaLibrary::isBeingHuntedByBountyHunter + +/** + * Returns a list of Jedi being hunted by the bounty hunter. + * + * @param env Java environment + * @param self class calling this function + * @param hunter the bounty hunter + * + * @return an array of jedi ids, or null on error + */ +jlongArray JNICALL ScriptMethodsJediNamespace::getBountyHunterBounties(JNIEnv * env, jobject self, jlong hunter) +{ + UNREF(self); + + JediManagerObject * jediManager = static_cast( + ServerUniverse::getInstance()).getJediManager(); + if (jediManager == NULL) + return 0; + + const NetworkId hunterId(hunter); + if (hunterId == NetworkId::cms_invalid) + return 0; + + std::vector jedis; + jediManager->getBountyHunterBounties(hunterId, jedis); + + LocalLongArrayRefPtr returnArray; + if (!ScriptConversion::convert(jedis, returnArray)) + return 0; + + return returnArray->getReturnValue(); +} // JavaLibrary::getBountyHunterBounties + +/** + * Adds data about a Jedi to the Jedi manager. + * + * @param env Java environment + * @param self class calling this function + * @param target the Jedi + * @param name the data name + * @param value the data value + */ +void JNICALL ScriptMethodsJediNamespace::updateJediScriptData(JNIEnv * env, jobject self, jlong target, jstring name, jint value) +{ + JediManagerObject * jediManager = static_cast( + ServerUniverse::getInstance()).getJediManager(); + if (jediManager == NULL) + return; + + const NetworkId targetId(target); + if (targetId == NetworkId::cms_invalid) + return; + + std::string dataName; + if (!JavaLibrary::convert(JavaStringParam(name), dataName)) + return; + + jediManager->updateJediScriptData(targetId, dataName, value); +} // JavaLibrary::updateJediScriptData + +/** + * Removes data about a Jedi from the Jedi manager. + * + * @param env Java environment + * @param self class calling this function + * @param target the Jedi + * @param name the data name + * @param value the data value + */ +void JNICALL ScriptMethodsJediNamespace::removeJediScriptData(JNIEnv * env, jobject self, jlong target, jstring name) +{ + JediManagerObject * jediManager = static_cast( + ServerUniverse::getInstance()).getJediManager(); + if (jediManager == NULL) + return; + + const NetworkId targetId(target); + if (targetId == NetworkId::cms_invalid) + return; + + std::string dataName; + if (!JavaLibrary::convert(JavaStringParam(name), dataName)) + return; + + jediManager->removeJediScriptData(targetId, dataName); +} // JavaLibrary::removeJediScriptData + + diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsMap.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsMap.cpp new file mode 100644 index 00000000..9bcaa8d8 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsMap.cpp @@ -0,0 +1,382 @@ +//======================================================================== +// +// ScriptMethodsMap.cpp - implements script methods dealing with bank +// +// copyright 2001 Sony Online Entertainment +// +//======================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "serverGame/PlanetMapManagerServer.h" +#include "serverGame/ServerObject.h" +#include "sharedGame/PlanetMapManager.h" +#include "sharedNetworkMessages/MapLocation.h" +#include "UnicodeUtils.h" +#include + +using namespace JNIWrappersNamespace; + + +// ====================================================================== +// ScriptMethodsMapNamespace +// ====================================================================== + +namespace ScriptMethodsMapNamespace +{ + bool install(); + + bool JNICALL addPlanetaryMapLocation (JNIEnv *env, jobject script, jlong locationId, jstring locationName, jint xLoc, jint yLoc, jstring category, jstring subCategory, jint mapLocationType, jbyte flags); + bool JNICALL addPlanetaryMapLocationIgnoreLocationCountLimits(JNIEnv *env, jobject script, jlong locationId, jstring locationName, jint xLoc, jint yLoc, jstring category, jstring subCategory, jint mapLocationType, jbyte flags); + bool JNICALL removePlanetaryMapLocation (JNIEnv *env, jobject script, jlong locationId); + jobjectArray JNICALL getPlanetaryMapLocations (JNIEnv *env, jobject script, jstring category, jstring subCategory); + jobjectArray JNICALL getPlanetaryMapCategories (JNIEnv *env, jobject script, jstring category); + jobject JNICALL getPlanetaryMapLocation (JNIEnv *env, jobject script, jlong locationId); +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsMapNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsMapNamespace::c)} + JF("_addPlanetaryMapLocation", "(JLjava/lang/String;IILjava/lang/String;Ljava/lang/String;IB)Z",addPlanetaryMapLocation), + JF("_addPlanetaryMapLocationIgnoreLocationCountLimits", "(JLjava/lang/String;IILjava/lang/String;Ljava/lang/String;IB)Z",addPlanetaryMapLocationIgnoreLocationCountLimits), + JF("_removePlanetaryMapLocation", "(J)Z", removePlanetaryMapLocation), + JF("getPlanetaryMapLocations", "(Ljava/lang/String;Ljava/lang/String;)[Lscript/map_location;", getPlanetaryMapLocations), + JF("getPlanetaryMapCategories", "(Ljava/lang/String;)[Ljava/lang/String;", getPlanetaryMapCategories), + JF("_getPlanetaryMapLocation", "(J)Lscript/map_location;", getPlanetaryMapLocation), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +// ---------------------------------------------------------------------- + +bool JNICALL ScriptMethodsMapNamespace::addPlanetaryMapLocation( + JNIEnv *env, jobject script, jlong locationId, jstring locationName, jint xLoc, jint yLoc, jstring jCategoryName, jstring jSubCategoryName, jint mapLocationType, jbyte flags) +{ + + if (mapLocationType < 0 || mapLocationType >= PlanetMapManager::MLT_numTypes) + { + WARNING(true, ("[script bug] invalid mapLocationType [%d] passed to addPlanetaryMapLocation", mapLocationType)); + return false; + } + + NetworkId id(locationId); + if (id == NetworkId::cms_invalid) + { + DEBUG_WARNING(true, ("[script bug] invalid locationId passed to addPlanetaryMapLocation")); + return false; + } + + JavaStringParam localLocationName(locationName); + Unicode::String wideLocationName; + if(!JavaLibrary::convert(localLocationName, wideLocationName)) + { + DEBUG_WARNING(true, ("[script bug] invalid locationName passed to addPlanetaryMapLocation")); + return false; + } + + if (wideLocationName.empty ()) + { + DEBUG_WARNING (true, ("[script bug] empty locationName passed to addPlanetaryMapLocation")); + return false; + } + + JavaStringParam localCategory(jCategoryName); + std::string categoryName; + if(!JavaLibrary::convert(localCategory, categoryName)) + { + DEBUG_WARNING(true, ("[script bug] invalid category passed to addPlanetaryMapLocation")); + return false; + } + + std::string subCategoryName; + if (jSubCategoryName) + { + JavaStringParam localSubCategory(jSubCategoryName); + if(!JavaLibrary::convert(localSubCategory, subCategoryName)) + { + DEBUG_WARNING(true, ("[script bug] invalid SubCategory passed to addPlanetaryMapLocation")); + return false; + } + } + + const uint8 category = PlanetMapManager::findCategory (categoryName); + if (!category) + { + WARNING(true, ("[script bug] invalid category [%s] passed to addPlanetaryMapLocation", categoryName.c_str ())); + return false; + + } + + const uint8 subCategory = PlanetMapManager::findCategory (subCategoryName); + + if (!subCategory && !subCategoryName.empty ()) + { + WARNING(true, ("[script bug] invalid subcategory [%s] passed to addPlanetaryMapLocation", categoryName.c_str ())); + return false; + } + + const Vector2d v2d (static_cast(xLoc), static_cast(yLoc)); + + bool result = false; + const MapLocation loc = PlanetMapManager::makeMapLocation (id, wideLocationName, v2d, categoryName, subCategoryName, flags, result); + + if (!result) + { + WARNING(true, ("[script bug] invalid location passed to addPlanetaryMapLocation")); + return false; + } + + PlanetMapManagerServer::addMapLocation (loc, mapLocationType, true); + return true; +} + +// ---------------------------------------------------------------------- + +bool JNICALL ScriptMethodsMapNamespace::addPlanetaryMapLocationIgnoreLocationCountLimits( + JNIEnv *env, jobject script, jlong locationId, jstring locationName, jint xLoc, jint yLoc, jstring jCategoryName, jstring jSubCategoryName, jint mapLocationType, jbyte flags) +{ + + if (mapLocationType < 0 || mapLocationType >= PlanetMapManager::MLT_numTypes) + { + WARNING(true, ("[script bug] invalid mapLocationType [%d] passed to addPlanetaryMapLocationIgnoreLocationCountLimits", mapLocationType)); + return false; + } + + NetworkId id(locationId); + if (id == NetworkId::cms_invalid) + { + DEBUG_WARNING(true, ("[script bug] invalid locationId passed to addPlanetaryMapLocationIgnoreLocationCountLimits")); + return false; + } + + JavaStringParam localLocationName(locationName); + Unicode::String wideLocationName; + if(!JavaLibrary::convert(localLocationName, wideLocationName)) + { + DEBUG_WARNING(true, ("[script bug] invalid locationName passed to addPlanetaryMapLocationIgnoreLocationCountLimits")); + return false; + } + + if (wideLocationName.empty ()) + { + DEBUG_WARNING (true, ("[script bug] empty locationName passed to addPlanetaryMapLocationIgnoreLocationCountLimits")); + return false; + } + + JavaStringParam localCategory(jCategoryName); + std::string categoryName; + if(!JavaLibrary::convert(localCategory, categoryName)) + { + DEBUG_WARNING(true, ("[script bug] invalid category passed to addPlanetaryMapLocationIgnoreLocationCountLimits")); + return false; + } + + std::string subCategoryName; + if (jSubCategoryName) + { + JavaStringParam localSubCategory(jSubCategoryName); + if(!JavaLibrary::convert(localSubCategory, subCategoryName)) + { + DEBUG_WARNING(true, ("[script bug] invalid SubCategory passed to addPlanetaryMapLocationIgnoreLocationCountLimits")); + return false; + } + } + + const uint8 category = PlanetMapManager::findCategory (categoryName); + if (!category) + { + WARNING(true, ("[script bug] invalid category [%s] passed to addPlanetaryMapLocationIgnoreLocationCountLimits", categoryName.c_str ())); + return false; + + } + + const uint8 subCategory = PlanetMapManager::findCategory (subCategoryName); + + if (!subCategory && !subCategoryName.empty ()) + { + WARNING(true, ("[script bug] invalid subcategory [%s] passed to addPlanetaryMapLocationIgnoreLocationCountLimits", categoryName.c_str ())); + return false; + } + + const Vector2d v2d (static_cast(xLoc), static_cast(yLoc)); + + bool result = false; + const MapLocation loc = PlanetMapManager::makeMapLocation (id, wideLocationName, v2d, categoryName, subCategoryName, flags, result); + + if (!result) + { + WARNING(true, ("[script bug] invalid location passed to addPlanetaryMapLocationIgnoreLocationCountLimits")); + return false; + } + + PlanetMapManagerServer::addMapLocation (loc, mapLocationType, false); + return true; +} + +//---------------------------------------------------------------------- + +bool JNICALL ScriptMethodsMapNamespace::removePlanetaryMapLocation(JNIEnv *env, jobject script, jlong locationId) +{ + NetworkId id(locationId); + if (id == NetworkId::cms_invalid) + { + DEBUG_WARNING(true, ("[script bug] invalid locationId passed to removePlanetaryMapLocation")); + return false; + } + + PlanetMapManagerServer::removeMapLocation (id); + return true; +} + +// ---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsMapNamespace::getPlanetaryMapLocations( + JNIEnv *env, + jobject script, + jstring jCategoryName, + jstring jSubCategoryName) + +{ + std::string categoryName; + if (jCategoryName) + { + JavaStringParam localCategory(jCategoryName); + if(!JavaLibrary::convert(localCategory, categoryName)) + { + DEBUG_WARNING(true, ("[script bug] invalid category passed to getPlanetaryMapLocations")); + return NULL; + } + } + + std::string subCategoryName; + if (jSubCategoryName) + { + JavaStringParam localSubCategory(jSubCategoryName); + if(!JavaLibrary::convert(localSubCategory, subCategoryName)) + { + DEBUG_WARNING(true, ("[script bug] invalid SubCategory passed to getPlanetaryMapLocations")); + return NULL; + } + } + + static PlanetMapManagerServer::MapLocationVector locs; + locs.clear (); + //@todo: this must be passed in from script + PlanetMapManagerServer::getMapLocationsByCategories (PlanetMapManager::MLT_static, categoryName, subCategoryName, locs); + + LocalObjectArrayRefPtr jlocs = createNewObjectArray(locs.size(), JavaLibrary::getClsMapLocation()); + + int index = 0; + for (PlanetMapManagerServer::MapLocationVector::const_iterator i = locs.begin(); i < locs.end(); ++i, ++index) + { + const MapLocation & mapLocation = *i; + + jlong jLocationId = mapLocation.getLocationId().getValue(); + if (!jLocationId) + return NULL; + + JavaString jNameString(mapLocation.getLocationName()); + + if (jNameString.getValue() == 0) + return NULL; + + LocalRefPtr jMapLocation = createNewObject(JavaLibrary::getClsMapLocation(), + JavaLibrary::getMidMapLocation(), + jLocationId, jNameString.getValue(), + jCategoryName, + jSubCategoryName, + static_cast (mapLocation.getLocation().x), + static_cast (mapLocation.getLocation().y), + static_cast (mapLocation.getFlags())); + + if (jMapLocation == LocalRef::cms_nullPtr) + return NULL; + + setObjectArrayElement(*jlocs, index, *jMapLocation); + } + + return jlocs->getReturnValue(); +} + +//---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsMapNamespace::getPlanetaryMapCategories (JNIEnv *env, jobject , jstring jCategoryName) +{ + std::string categoryName; + if (jCategoryName) + { + JavaStringParam localCategory(jCategoryName); + if(!JavaLibrary::convert(localCategory, categoryName)) + { + DEBUG_WARNING(true, ("[script bug] invalid category passed to getPlanetaryMapCategories")); + return NULL; + } + } + + const int theCategory = PlanetMapManager::findCategory (categoryName); + + static PlanetMapManagerServer::IntVector iv; + iv.clear (); + PlanetMapManagerServer::getCategories (theCategory, iv); + + LocalObjectArrayRefPtr jcats = createNewObjectArray (iv.size (), JavaLibrary::getClsString()); + + size_t i = 0; + for (PlanetMapManagerServer::IntVector::const_iterator it = iv.begin (); it != iv.end (); ++it, ++i) + { + const int cat = *it; + const std::string & catName = PlanetMapManager::findCategoryName (static_cast(cat)); + const JavaString jval(catName); + setObjectArrayElement(*jcats, i, jval); + } + + return jcats->getReturnValue(); +} + +//---------------------------------------------------------------------- + +jobject JNICALL ScriptMethodsMapNamespace::getPlanetaryMapLocation (JNIEnv *env, jobject, jlong jLocationId) +{ + NetworkId id(jLocationId); + if (id == NetworkId::cms_invalid) + { + DEBUG_WARNING(true, ("[script bug] invalid locationId passed to getPlanetaryMapCategories")); + return NULL; + } + + int mlt = 0; + const MapLocation * const mapLocation = PlanetMapManagerServer::getLocation (id, mlt); + + if (!mapLocation) + return NULL; + + const JavaString jLocName (mapLocation->m_locationName); + const JavaString jLocCategoryName (PlanetMapManager::findCategoryName (mapLocation->m_category)); + const JavaString jLocSubCategoryName (PlanetMapManager::findCategoryName (mapLocation->m_subCategory)); + + LocalRefPtr jMapLocation = createNewObject(JavaLibrary::getClsMapLocation(), + JavaLibrary::getMidMapLocation(), + jLocationId, + + jLocName.getValue (), + jLocCategoryName.getValue (), + jLocSubCategoryName.getValue (), + + static_cast (mapLocation->getLocation().x), + static_cast (mapLocation->getLocation().y), + static_cast (mapLocation->getFlags())); + + return jMapLocation->getReturnValue(); + +} + +//---------------------------------------------------------------------- diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsMentalStates.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsMentalStates.cpp new file mode 100644 index 00000000..87d142d0 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsMentalStates.cpp @@ -0,0 +1,1139 @@ +//======================================================================== +// +// ScriptMethodsMentalStates.cpp - implements script methods dealing with mental states. +// +// copyright 2001 Sony Online Entertainment +// +//======================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "serverGame/AiCombatPulseQueue.h" +#include "serverGame/ConfigServerGame.h" +#include "serverGame/CreatureController.h" +#include "serverGame/CreatureObject.h" +#include "serverGame/ServerWorld.h" +#include "sharedDebug/Profiler.h" +#include "sharedLog/Log.h" + +using namespace JNIWrappersNamespace; + + +//======================================================================== +// constants +//======================================================================== + +static const float MENTAL_STATE_ERROR = -34359738368.0f; + +// ====================================================================== +// ScriptMethodsMentalStatesNamespace +// ====================================================================== + +namespace ScriptMethodsMentalStatesNamespace +{ + bool install(); + + jfloat JNICALL getMentalState(JNIEnv *env, jobject self, jlong mob, jint attrib); + jfloat JNICALL getMaxMentalState(JNIEnv *env, jobject self, jlong mob, jint attrib); + jfloat JNICALL getMentalStateDecay(JNIEnv *env, jobject self, jlong mob, jint attrib); + jboolean JNICALL setMentalState(JNIEnv *env, jobject self, jlong mob, jint attrib, jfloat value); + jboolean JNICALL setMentalStateDecay(JNIEnv *env, jobject self, jlong mob, jint attrib, jfloat value); + jboolean JNICALL addToMentalState(JNIEnv *env, jobject self, jlong mob, jint attrib, jfloat value); + jboolean JNICALL addMentalStateModifier(JNIEnv *env, jobject self, jlong mob, jint attrib, jfloat value, jfloat duration, jfloat attackRate, jfloat decayRate); + jobjectArray JNICALL getMentalStateModifiers(JNIEnv *env, jobject self, jlong mob, jint attrib); + jobjectArray JNICALL getMentalStates(JNIEnv *env, jobject self, jlong mob); + jobjectArray JNICALL getMaxMentalStates(JNIEnv *env, jobject self, jlong mob); + jboolean JNICALL setMentalStates(JNIEnv *env, jobject self, jlong mob, jobjectArray values); + jboolean JNICALL addToMentalStates(JNIEnv *env, jobject self, jlong mob, jobjectArray values); + jint JNICALL getBehavior(JNIEnv *env, jobject self, jlong mob); + jint JNICALL getBehaviorToward(JNIEnv *env, jobject self, jlong mob, jlong target); + jfloat JNICALL getMentalStateToward(JNIEnv *env, jobject self, jlong mob, jlong target, jint attrib); + jboolean JNICALL setMentalStateToward(JNIEnv *env, jobject self, jlong mob, jlong target, jint attrib, jfloat value); + jboolean JNICALL setMentalStateTowardClampBehavior(JNIEnv *env, jobject self, jlong mob, jlong target, jint attrib, jfloat value, jint behavior); + jboolean JNICALL addToMentalStateToward(JNIEnv *env, jobject self, jlong mob, jlong target, jint attrib, jfloat value); + jboolean JNICALL addToMentalStateTowardClampBehavior(JNIEnv *env, jobject self, jlong mob, jlong target, jint attrib, jfloat value, jint behavior); + jboolean JNICALL addMentalStateModifierToward(JNIEnv *env, jobject self, jlong mob, jlong target, jint attrib, jfloat value, jfloat duration, jfloat attackRate, jfloat decayRate); + jobjectArray JNICALL getMentalStateModifiersToward(JNIEnv *env, jobject self, jlong mob, jlong target, jint attrib); + jobjectArray JNICALL getMentalStatesToward(JNIEnv *env, jobject self, jlong mob, jlong target); + jboolean JNICALL setMentalStatesToward(JNIEnv *env, jobject self, jlong mob, jlong target, jobjectArray values); + jboolean JNICALL addToMentalStatesToward(JNIEnv *env, jobject self, jlong mob, jlong target, jobjectArray values); + jboolean JNICALL setMentalStateTowardArray(JNIEnv *env, jobject self, jlong mob, jlongArray target, jint attrib, jfloat value); + jboolean JNICALL addToMentalStateTowardArray(JNIEnv *env, jobject self, jlong mob, jlongArray target, jint attrib, jfloat value); + jboolean JNICALL addMentalStateModifierTowardArray(JNIEnv *env, jobject self, jlong mob, jlongArray target, jint attrib, jfloat value, jfloat duration, jfloat attackRate, jfloat decayRate); + jboolean JNICALL setMentalStatesTowardArray(JNIEnv *env, jobject self, jlong mob, jlongArray target, jobjectArray values); + jboolean JNICALL addToMentalStatesTowardArray(JNIEnv *env, jobject self, jlong mob, jlongArray target, jobjectArray values); + void JNICALL scheduleAiCombatPulse(JNIEnv *env, jobject self, jlong mob); + jlongArray JNICALL getBehaviorTargets(JNIEnv *env, jobject self, jlong mob, jint behavior); +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsMentalStatesNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsMentalStatesNamespace::c)} + JF("_getMentalState", "(JI)F", getMentalState), + JF("_getMaxMentalState", "(JI)F", getMaxMentalState), + JF("_getMentalStateDecay", "(JI)F", getMentalStateDecay), + JF("_setMentalState", "(JIF)Z", setMentalState), + JF("_setMentalStateDecay", "(JIF)Z", setMentalStateDecay), + JF("_addToMentalState", "(JIF)Z", addToMentalState), + JF("_addMentalStateModifier", "(JIFFFF)Z", addMentalStateModifier), + JF("_getMentalStateModifiers", "(JI)[Lscript/mental_state_mod;", getMentalStateModifiers), + JF("_getMentalStates", "(J)[Lscript/mental_state;", getMentalStates), + JF("_getMaxMentalStates", "(J)[Lscript/mental_state;", getMaxMentalStates), + JF("_setMentalStates", "(J[Lscript/mental_state;)Z", setMentalStates), + JF("_addToMentalStates", "(J[Lscript/mental_state;)Z", addToMentalStates), + JF("_getMentalStateToward", "(JJI)F", getMentalStateToward), + JF("_setMentalStateToward", "(JJIF)Z", setMentalStateToward), + JF("_setMentalStateToward", "(JJIFI)Z", setMentalStateTowardClampBehavior), + JF("_addToMentalStateToward", "(JJIF)Z", addToMentalStateToward), + JF("_addToMentalStateToward", "(JJIFI)Z", addToMentalStateTowardClampBehavior), + JF("_addMentalStateModifierToward", "(JJIFFFF)Z", addMentalStateModifierToward), + JF("_getMentalStateModifiersToward", "(JJI)[Lscript/mental_state_mod;", getMentalStateModifiersToward), + JF("_getMentalStatesToward", "(JJ)[Lscript/mental_state;", getMentalStatesToward), + JF("_setMentalStatesToward", "(JJ[Lscript/mental_state;)Z", setMentalStatesToward), + JF("_addToMentalStatesToward", "(JJ[Lscript/mental_state;)Z", addToMentalStatesToward), + JF("_setMentalStateToward", "(J[JIF)Z", setMentalStateTowardArray), + JF("_addToMentalStateToward", "(J[JIF)Z", addToMentalStateTowardArray), + JF("_addMentalStateModifierToward", "(J[JIFFFF)Z", addMentalStateModifierTowardArray), + JF("_setMentalStatesToward", "(J[J[Lscript/mental_state;)Z", setMentalStatesTowardArray), + JF("_addToMentalStatesToward", "(J[J[Lscript/mental_state;)Z", addToMentalStatesTowardArray), + JF("_getBehaviorTargets", "(JI)[J", getBehaviorTargets), + JF("_getBehavior", "(J)I", getBehavior), + JF("_getBehaviorToward", "(JJ)I", getBehaviorToward), + JF("_scheduleAiCombatPulse", "(J)V", scheduleAiCombatPulse), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +//======================================================================== +// class JavaLibrary JNI mental state callback methods +//======================================================================== + +/** +* Returns a creature's mental state. +* +* @param env Java environment +* @param self class calling this function +* @param mob id of creature to access +* @param mental state mental state we are interested in +* +* @return the mental state value, or MENTAL_STATE_ERROR on error +*/ +jfloat JNICALL ScriptMethodsMentalStatesNamespace::getMentalState(JNIEnv *env, jobject self, jlong mob, jint mentalState) +{ + UNREF(self); + + if (mentalState < 0 || mentalState >= MentalStates::NumberOfMentalStates) + return MENTAL_STATE_ERROR; + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(mob, creature)) + return MENTAL_STATE_ERROR; + + return creature->getMentalState(static_cast(mentalState)); +} // JavaLibrary::getMentalState + + /** + * Returns a creature's max mentalState. + * + * @param env Java environment + * @param self class calling this function + * @param mob id of creature to access + * @param mentalState mentalState we are interested in + * + * @return the max mental state value, or MENTAL_STATE_ERROR on error +*/ +jfloat JNICALL ScriptMethodsMentalStatesNamespace::getMaxMentalState(JNIEnv *env, jobject self, jlong mob, jint mentalState) +{ + UNREF(self); + + if (mentalState < 0 || mentalState >= MentalStates::NumberOfMentalStates) + return MENTAL_STATE_ERROR; + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(mob, creature)) + return MENTAL_STATE_ERROR; + + return creature->getMaxMentalState(static_cast(mentalState)); +} // JavaLibrary::getMaxMentalStates + + /** + * Returns a creature's mental state decay time. + * + * @param env Java environment + * @param self class calling this function + * @param mob id of creature to access + * @param mentalState mentalState we are interested in + * + * @return the max mental state value, or MENTAL_STATE_ERROR on error +*/ +jfloat JNICALL ScriptMethodsMentalStatesNamespace::getMentalStateDecay(JNIEnv *env, jobject self, jlong mob, jint mentalState) +{ + UNREF(self); + + if (mentalState < 0 || mentalState >= MentalStates::NumberOfMentalStates) + return MENTAL_STATE_ERROR; + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(mob, creature)) + return MENTAL_STATE_ERROR; + + return creature->getMentalStateDecay(static_cast(mentalState)); +} // JavaLibrary::getMaxMentalStates + + /** + * Sets a creatue's mental state. + * + * @param env Java environment + * @param self class calling this function + * @param target id of creature to access + * @param mentalState mental state we are interested in + * @param value value to set the mental state to + * + * @return true on success, false on fail +*/ +jboolean JNICALL ScriptMethodsMentalStatesNamespace::setMentalState(JNIEnv *env, jobject self, jlong mob, jint mentalState, jfloat value) +{ + UNREF(self); + + if (mentalState < 0 || mentalState >= MentalStates::NumberOfMentalStates) + return JNI_FALSE; + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(mob, creature)) + return JNI_FALSE; + + creature->setMentalState(static_cast(mentalState), + static_cast(value)); + return JNI_TRUE; +} // JavaLibrary::setAttrib + + /** + * Sets a creatue's mental state decay time. + * + * @param env Java environment + * @param self class calling this function + * @param mob id of creature to access + * @param mentalState mental state we are interested in + * @param value value to set the mental state to + * + * @return true on success, false on fail +*/ +jboolean JNICALL ScriptMethodsMentalStatesNamespace::setMentalStateDecay(JNIEnv *env, jobject self, jlong mob, jint mentalState, jfloat value) +{ + UNREF(self); + + if (mentalState < 0 || mentalState >= MentalStates::NumberOfMentalStates) + return JNI_FALSE; + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(mob, creature)) + return JNI_FALSE; + + creature->setMentalStateDecay(static_cast(mentalState), value); + return JNI_TRUE; +} // JavaLibrary::setMentalStateDecay + + /** + * Adds a value to a creature's mental state. + * + * @param env Java environment + * @param self class calling this function + * @param mob id of creature to access + * @param mentalState mental state we are interested in + * @param value value to add to the mental state + * + * @return true on success, false on fail +*/ +jboolean JNICALL ScriptMethodsMentalStatesNamespace::addToMentalState(JNIEnv *env, jobject self, jlong mob, jint mentalState, jfloat value) +{ + UNREF(self); + + if (mentalState < 0 || mentalState >= MentalStates::NumberOfMentalStates) + return JNI_FALSE; + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(mob, creature)) + return JNI_FALSE; + + creature->setMentalState(static_cast(mentalState), + static_cast((creature->getMentalState( + static_cast(mentalState)) + value))); + return JNI_TRUE; +} // JavaLibrary::addToMentalState + + /** + * Adds an mental state modifier to a creature. + * + * @param env Java environment + * @param self class calling this function + * @param mob id of creature to access + * @param mentalState mental state we are interested in + * @param value value of the modifier + * @param duration how long the modifier lasts (in sec) + * @param attackRate how long before the modifier reaches it's max value (in sec) + * @param decayRate how long before the modifier reaches 0 (in sec) + * + * @return true on success, false on fail +*/ +jboolean JNICALL ScriptMethodsMentalStatesNamespace::addMentalStateModifier(JNIEnv *env, jobject self, jlong mob, jint mentalState, jfloat value, jfloat duration, jfloat attackRate, jfloat decayRate) +{ + UNREF(self); + + if (mentalState < 0 || mentalState >= MentalStates::NumberOfMentalStates) + return JNI_FALSE; + + // @todo: wait for implementation on CreatureObject + UNREF(mob); + UNREF(mentalState); + UNREF(value); + UNREF(duration); + UNREF(attackRate); + UNREF(decayRate); + + return JNI_FALSE; +} // JavaLibrary::addMentalStateModifier + + /** + * Returns the mental state modifiers for a creature. + * + * @param env Java environment + * @param self class calling this function + * @param mob id of creature to access + * @param mentalState mental state we are interested in + * + * @return the mental state modifiers for the creature, or null if it has none +*/ +jobjectArray JNICALL ScriptMethodsMentalStatesNamespace::getMentalStateModifiers(JNIEnv *env, jobject self, jlong mob, jint mentalState) +{ + UNREF(self); + + if (mentalState < 0 || mentalState >= MentalStates::NumberOfMentalStates) + return 0; + + UNREF(mob); + UNREF(mentalState); + // @todo: wait for implementation on CreatureObject + return 0; +} // JavaLibrary::getMentalStateModifiers + + /** + * Returns all the mental states for a creature. + * + * @param env Java environment + * @param self class calling this function + * @param mob id of creature to access + * + * @return the mental states for the creature +*/ +jobjectArray JNICALL ScriptMethodsMentalStatesNamespace::getMentalStates(JNIEnv *env, jobject self, jlong mob) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(mob, creature)) + return 0; + + // create the array of mental states + LocalObjectArrayRefPtr attribs = createNewObjectArray( + MentalStates::NumberOfMentalStates, JavaLibrary::getClsMentalState()); + if (env->ExceptionCheck()) + { + env->ExceptionDescribe(); + return 0; + } + + // set the array elements + for (int i = 0; i < MentalStates::NumberOfMentalStates; ++i) + { + LocalRefPtr mentalState = createNewObject(JavaLibrary::getClsMentalState(), JavaLibrary::getMidMentalState(), + i, creature->getMentalState(static_cast(i))); + if (env->ExceptionCheck()) + { + env->ExceptionDescribe(); + return 0; + } + setObjectArrayElement(*attribs, i, *mentalState); + } + return attribs->getReturnValue(); +} // JavaLibrary::getMentalStates + + /** + * Returns all the max mental states for a creature. + * + * @param env Java environment + * @param self class calling this function + * @param mob id of creature to access + * + * @return the max mental states for the creature +*/ +jobjectArray JNICALL ScriptMethodsMentalStatesNamespace::getMaxMentalStates(JNIEnv *env, jobject self, jlong mob) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(mob, creature)) + return 0; + + // create the array of mental states + LocalObjectArrayRefPtr attribs = createNewObjectArray( + MentalStates::NumberOfMentalStates, JavaLibrary::getClsMentalState()); + if (env->ExceptionCheck()) + { + env->ExceptionDescribe(); + return 0; + } + + // set the array elements + for (int i = 0; i < MentalStates::NumberOfMentalStates; ++i) + { + LocalRefPtr mentalState = createNewObject(JavaLibrary::getClsMentalState(), JavaLibrary::getMidMentalState(), + i, creature->getMaxMentalState(static_cast(i))); + if (env->ExceptionCheck()) + { + env->ExceptionDescribe(); + return 0; + } + setObjectArrayElement(*attribs, i, *mentalState); + } + return attribs->getReturnValue(); +} // JavaLibrary::getMaxMentalStates + + /** + * Sets the mental states for a creature. + * + * @param env Java environment + * @param self class calling this function + * @param mob id of creature to access + * @param values mental state/value pairs to set + * + * @return true on success, false on fail +*/ +jboolean JNICALL ScriptMethodsMentalStatesNamespace::setMentalStates(JNIEnv *env, jobject self, jlong mob, jobjectArray values) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(mob, creature)) + return JNI_FALSE; + + int count = env->GetArrayLength(values); + for (int i = 0; i < count; ++i) + { + LocalRefPtr mentalState = getObjectArrayElement(LocalObjectArrayRefParam(values), i); + if (mentalState == LocalRef::cms_nullPtr) + return JNI_FALSE; + int type = getIntField(*mentalState, JavaLibrary::getFidMentalStateType()); + if (type < 0 || type >= MentalStates::NumberOfMentalStates) + return JNI_FALSE; + creature->setMentalState(static_cast(type), + static_cast(getFloatField(*mentalState, + JavaLibrary::getFidMentalStateValue()))); + } + return JNI_TRUE; +} // JavaLibrary::setMentalStates + + /** + * Adds values to the mental states for a creature. + * + * @param env Java environment + * @param self class calling this function + * @param mob id of creature to access + * @param values mental state/value pairs to add + * + * @return true on success, false on fail +*/ +jboolean JNICALL ScriptMethodsMentalStatesNamespace::addToMentalStates(JNIEnv *env, jobject self, jlong mob, jobjectArray values) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(mob, creature)) + return JNI_FALSE; + + int count = env->GetArrayLength(values); + for (int i = 0; i < count; ++i) + { + LocalRefPtr mentalState = getObjectArrayElement(LocalObjectArrayRefParam(values), i); + if (mentalState == LocalRef::cms_nullPtr) + return JNI_FALSE; + int type = getIntField(*mentalState, JavaLibrary::getFidMentalStateType()); + if (type < 0 || type >= MentalStates::NumberOfMentalStates) + return JNI_FALSE; + MentalStates::Value value = creature->getMentalState(static_cast(type)); + value += getFloatField(*mentalState, JavaLibrary::getFidMentalStateValue()); + creature->setMentalState(static_cast(type), + static_cast(value)); + } + return JNI_TRUE; +} // JavaLibrary::addToMentalStates + +//--------- + +/** +* Returns a creature's mental state. +* +* @param env Java environment +* @param self class calling this function +* @param mob id of creature to access +* @param mental state mental state we are interested in +* +* @return the mental state value, or MENTAL_STATE_ERROR on error +*/ +jfloat JNICALL ScriptMethodsMentalStatesNamespace::getMentalStateToward(JNIEnv *env, jobject self, jlong mob, jlong target, jint mentalState) +{ + UNREF(self); + + if (target == 0 || mentalState < 0 || mentalState >= MentalStates::NumberOfMentalStates) + return MENTAL_STATE_ERROR; + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(mob, creature)) + return MENTAL_STATE_ERROR; + + NetworkId targetId(target); + if (!targetId) + return MENTAL_STATE_ERROR; + + return creature->getMentalStateToward(targetId, static_cast(mentalState)); +} // JavaLibrary::getMentalState + + /** + * Sets a creatue's mental state. + * + * @param env Java environment + * @param self class calling this function + * @param target id of creature to access + * @param mentalState mental state we are interested in + * @param value value to set the mental state to + * + * @return true on success, false on fail +*/ +jboolean JNICALL ScriptMethodsMentalStatesNamespace::setMentalStateToward(JNIEnv *env, jobject self, jlong mob, jlong target, jint mentalState, jfloat value) +{ + PROFILER_AUTO_BLOCK_DEFINE("setMentalStateToward"); + UNREF(self); + + if (target == 0 || mentalState < 0 || mentalState >= MentalStates::NumberOfMentalStates) + return JNI_FALSE; + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(mob, creature)) + return JNI_FALSE; + + NetworkId targetId(target); + if (!targetId) + return JNI_FALSE; + + creature->setMentalStateToward(targetId, + static_cast(mentalState), + static_cast(value)); + + return JNI_TRUE; +} // JavaLibrary::setAttrib + + /** + * Sets a creatue's mental state. + * + * @param env Java environment + * @param self class calling this function + * @param target id of creature to access + * @param mentalState mental state we are interested in + * @param value value to set the mental state to + * + * @return true on success, false on fail +*/ +jboolean JNICALL ScriptMethodsMentalStatesNamespace::setMentalStateTowardClampBehavior(JNIEnv *env, jobject self, jlong mob, jlong target, jint mentalState, jfloat value, jint behavior) +{ + UNREF(self); + + if (target == 0 || mentalState < 0 || mentalState >= MentalStates::NumberOfMentalStates) + return JNI_FALSE; + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(mob, creature)) + return JNI_FALSE; + + NetworkId targetId(target); + if (!targetId) + return JNI_FALSE; + + creature->setMentalStateTowardClampBehavior(targetId, + static_cast(mentalState), + static_cast(value), + static_cast(behavior)); + + return JNI_TRUE; +} // JavaLibrary::setAttrib + + /** + * Adds a value to a creature's mental state. + * + * @param env Java environment + * @param self class calling this function + * @param mob id of creature to access + * @param mentalState mental state we are interested in + * @param value value to add to the mental state + * + * @return true on success, false on fail +*/ +jboolean JNICALL ScriptMethodsMentalStatesNamespace::addToMentalStateToward(JNIEnv *env, jobject self, jlong mob, jlong target, jint mentalState, jfloat value) +{ + UNREF(self); + + if (target == 0 || mentalState < 0 || mentalState >= MentalStates::NumberOfMentalStates) + { + LOGC(ConfigServerGame::isAiLoggingEnabled(), "debug_ai", ("ScriptMethodsMentalStates::addToMentalStateToward() error 1")); + return JNI_FALSE; + } + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(mob, creature)) + { + LOGC(ConfigServerGame::isAiLoggingEnabled(), "debug_ai", ("ScriptMethodsMentalStates::addToMentalStateToward() error 2")); + return JNI_FALSE; + } + + NetworkId targetId(target); + if (!targetId) + { + LOGC(ConfigServerGame::isAiLoggingEnabled(), "debug_ai", ("ScriptMethodsMentalStates::addToMentalStateToward() error 3")); + return JNI_FALSE; + } + + MentalStates::Value current = creature->getMentalStateToward(targetId, static_cast(mentalState)); + + LOGC(ConfigServerGame::isAiLoggingEnabled(), "debug_ai", ("ScriptMethodsMentalStates::addToMentalStateToward() %s->%s state(%s) value(%.0f+%.0f)", creature->getNetworkId().getValueString().c_str(), targetId.getValueString().c_str(), CreatureObject::getMentalStateString(mentalState), current, value)); + + creature->setMentalStateToward(targetId, static_cast(mentalState), static_cast(current + value)); + + return JNI_TRUE; +} // JavaLibrary::addToMentalState + + /** + * Adds a value to a creature's mental state. + * + * @param env Java environment + * @param self class calling this function + * @param mob id of creature to access + * @param mentalState mental state we are interested in + * @param value value to add to the mental state + * + * @return true on success, false on fail +*/ +jboolean JNICALL ScriptMethodsMentalStatesNamespace::addToMentalStateTowardClampBehavior(JNIEnv *env, jobject self, jlong mob, jlong target, jint mentalState, jfloat value, jint behavior) +{ + UNREF(self); + + if (target == 0 || mentalState < 0 || mentalState >= MentalStates::NumberOfMentalStates) + return JNI_FALSE; + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(mob, creature)) + return JNI_FALSE; + + NetworkId targetId(target); + if (!targetId) + return JNI_FALSE; + + MentalStates::Value current = creature->getMentalStateToward(targetId, static_cast(mentalState)); + + LOGC(ConfigServerGame::isAiLoggingEnabled(), "debug_ai", ("ScriptMethodsMentalStates::addToMentalStateTowardClampBehavior() %s->%s state(%s) value(%.0f+%.0f) behavior(%s)", creature->getNetworkId().getValueString().c_str(), targetId.getValueString().c_str(), CreatureObject::getMentalStateString(mentalState), current, value, CreatureObject::getBehaviorString(behavior))); + + creature->setMentalStateTowardClampBehavior(targetId, + static_cast(mentalState), + static_cast(current + value), + static_cast(behavior)); + + return JNI_TRUE; +} // JavaLibrary::addToMentalState + + /** + * Adds an mental state modifier to a creature. + * + * @param env Java environment + * @param self class calling this function + * @param mob id of creature to access + * @param mentalState mental state we are interested in + * @param value value of the modifier + * @param duration how long the modifier lasts (in sec) + * @param attackRate how long before the modifier reaches it's max value (in sec) + * @param decayRate how long before the modifier reaches 0 (in sec) + * + * @return true on success, false on fail +*/ +jboolean JNICALL ScriptMethodsMentalStatesNamespace::addMentalStateModifierToward(JNIEnv *env, jobject self, jlong mob, jlong target, jint mentalState, jfloat value, jfloat duration, jfloat attackRate, jfloat decayRate) +{ + UNREF(self); + + if (mentalState < 0 || mentalState >= MentalStates::NumberOfMentalStates) + return JNI_FALSE; + + // @todo: wait for implementation on CreatureObject + UNREF(mob); + UNREF(mentalState); + UNREF(value); + UNREF(duration); + UNREF(attackRate); + UNREF(decayRate); + UNREF(target); + + return JNI_FALSE; +} // JavaLibrary::addMentalStateModifier + + /** + * Returns the mental state modifiers for a creature. + * + * @param env Java environment + * @param self class calling this function + * @param mob id of creature to access + * @param mentalState mental state we are interested in + * + * @return the mental state modifiers for the creature, or null if it has none +*/ +jobjectArray JNICALL ScriptMethodsMentalStatesNamespace::getMentalStateModifiersToward(JNIEnv *env, jobject self, jlong mob, jlong target, jint mentalState) +{ + UNREF(self); + + if (mentalState < 0 || mentalState >= MentalStates::NumberOfMentalStates) + return 0; + + UNREF(mob); + UNREF(mentalState); + UNREF(target); + // @todo: wait for implementation on CreatureObject + return 0; +} // JavaLibrary::getMentalStateModifiers + + /** + * Returns all the mental states for a creature. + * + * @param env Java environment + * @param self class calling this function + * @param mob id of creature to access + * + * @return the mental states for the creature +*/ +jobjectArray JNICALL ScriptMethodsMentalStatesNamespace::getMentalStatesToward(JNIEnv *env, jobject self, jlong mob, jlong target) +{ + UNREF(self); + + if (target == 0) + return 0; + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(mob, creature)) + return 0; + + NetworkId targetId(target); + if (!targetId) + return 0; + + // create the array of mental states + LocalObjectArrayRefPtr attribs = createNewObjectArray( + MentalStates::NumberOfMentalStates, JavaLibrary::getClsMentalState()); + if (env->ExceptionCheck()) + { + env->ExceptionDescribe(); + return 0; + } + + // set the array elements + for (int i = 0; i < MentalStates::NumberOfMentalStates; ++i) + { + LocalRefPtr mentalState = createNewObject(JavaLibrary::getClsMentalState(), JavaLibrary::getMidMentalState(), + i, creature->getMentalStateToward(targetId, static_cast(i))); + if (env->ExceptionCheck()) + { + env->ExceptionDescribe(); + return 0; + } + setObjectArrayElement(*attribs, i, *mentalState); + } + return attribs->getReturnValue(); +} // JavaLibrary::getMentalStates + + /** + * Sets the mental states for a creature. + * + * @param env Java environment + * @param self class calling this function + * @param mob id of creature to access + * @param values mental state/value pairs to set + * + * @return true on success, false on fail +*/ +jboolean JNICALL ScriptMethodsMentalStatesNamespace::setMentalStatesToward(JNIEnv *env, jobject self, jlong mob, jlong target, jobjectArray values) +{ + UNREF(self); + + if (target == 0) + return JNI_FALSE; + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(mob, creature)) + return JNI_FALSE; + + NetworkId targetId(target); + if (!targetId) + return JNI_FALSE; + + int count = env->GetArrayLength(values); + for (int i = 0; i < count; ++i) + { + LocalRefPtr mentalState = getObjectArrayElement(LocalObjectArrayRefParam(values), i); + if (mentalState == LocalRef::cms_nullPtr) + return JNI_FALSE; + + int type = getIntField(*mentalState, JavaLibrary::getFidMentalStateType()); + float value = getFloatField(*mentalState, JavaLibrary::getFidMentalStateValue()); + if (type < 0 || type >= MentalStates::NumberOfMentalStates) + return JNI_FALSE; + + creature->setMentalStateToward(targetId, static_cast(type), + static_cast(value)); + } + return JNI_TRUE; +} // JavaLibrary::setMentalStates + + /** + * Adds values to the mental states for a creature. + * + * @param env Java environment + * @param self class calling this function + * @param mob id of creature to access + * @param values mental state/value pairs to add + * + * @return true on success, false on fail +*/ +jboolean JNICALL ScriptMethodsMentalStatesNamespace::addToMentalStatesToward(JNIEnv *env, jobject self, jlong mob, jlong target, jobjectArray values) +{ + UNREF(self); + + if (target == 0) + return JNI_FALSE; + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(mob, creature)) + return JNI_FALSE; + + NetworkId targetId(target); + if (!targetId) + return JNI_FALSE; + + int count = env->GetArrayLength(values); + for (int i = 0; i < count; ++i) + { + LocalRefPtr mentalState = getObjectArrayElement(LocalObjectArrayRefParam(values), i); + if (mentalState == LocalRef::cms_nullPtr) + return JNI_FALSE; + + int type = getIntField(*mentalState, JavaLibrary::getFidMentalStateType()); + float delta = getFloatField(*mentalState, JavaLibrary::getFidMentalStateValue()); + if (type < 0 || type >= MentalStates::NumberOfMentalStates) + return JNI_FALSE; + + MentalStates::Value value = creature->getMentalStateToward(targetId, static_cast(type)); + creature->setMentalStateToward(targetId, static_cast(type), + static_cast(value+delta)); + } + return JNI_TRUE; +} // JavaLibrary::addToMentalStates + +//----------------------- + +/** +* Sets a creatue's mental state. +* +* @param env Java environment +* @param self class calling this function +* @param target id of creature to access +* @param mentalState mental state we are interested in +* @param value value to set the mental state to +* +* @return true on success, false on fail +*/ +jboolean JNICALL ScriptMethodsMentalStatesNamespace::setMentalStateTowardArray(JNIEnv *env, jobject self, jlong mob, jlongArray target, jint mentalState, jfloat value) +{ + UNREF(self); + + if (mentalState < 0 || mentalState >= MentalStates::NumberOfMentalStates) + return JNI_FALSE; + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(mob, creature)) + return JNI_FALSE; + + std::vector targetIds; + if (!ScriptConversion::convert(target, targetIds)) + return JNI_FALSE; + + std::vector::iterator i; + for (i=targetIds.begin(); i!=targetIds.end(); ++i) + { + creature->setMentalStateToward(*i, static_cast(mentalState), + static_cast(value)); + } + return JNI_TRUE; +} // JavaLibrary::setAttrib + + /** + * Adds a value to a creature's mental state. + * + * @param env Java environment + * @param self class calling this function + * @param mob id of creature to access + * @param mentalState mental state we are interested in + * @param value value to add to the mental state + * + * @return true on success, false on fail +*/ +jboolean JNICALL ScriptMethodsMentalStatesNamespace::addToMentalStateTowardArray(JNIEnv *env, jobject self, jlong mob, jlongArray target, jint mentalState, jfloat value) +{ + UNREF(self); + + if (mentalState < 0 || mentalState >= MentalStates::NumberOfMentalStates) + return JNI_FALSE; + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(mob, creature)) + return JNI_FALSE; + + std::vector targetIds; + if (!ScriptConversion::convert(target, targetIds)) + return JNI_FALSE; + + std::vector::iterator i; + for (i=targetIds.begin(); i!=targetIds.end(); ++i) + { + MentalStates::Value current = creature->getMentalStateToward(*i, static_cast(mentalState)); + creature->setMentalStateToward(*i, static_cast(mentalState), static_cast(current + value)); + } + return JNI_TRUE; +} // JavaLibrary::addToMentalState + + /** + * Adds an mental state modifier to a creature. + * + * @param env Java environment + * @param self class calling this function + * @param mob id of creature to access + * @param mentalState mental state we are interested in + * @param value value of the modifier + * @param duration how long the modifier lasts (in sec) + * @param attackRate how long before the modifier reaches it's max value (in sec) + * @param decayRate how long before the modifier reaches 0 (in sec) + * + * @return true on success, false on fail +*/ +jboolean JNICALL ScriptMethodsMentalStatesNamespace::addMentalStateModifierTowardArray(JNIEnv *env, jobject self, jlong mob, jlongArray target, jint mentalState, jfloat value, jfloat duration, jfloat attackRate, jfloat decayRate) +{ + UNREF(self); + + if (mentalState < 0 || mentalState >= MentalStates::NumberOfMentalStates) + return JNI_FALSE; + + // @todo: wait for implementation on CreatureObject + UNREF(mob); + UNREF(mentalState); + UNREF(value); + UNREF(duration); + UNREF(attackRate); + UNREF(decayRate); + UNREF(target); + + return JNI_FALSE; +} // JavaLibrary::addMentalStateModifier + + /** + * Sets the mental states for a creature. + * + * @param env Java environment + * @param self class calling this function + * @param mob id of creature to access + * @param values mental state/value pairs to set + * + * @return true on success, false on fail +*/ +jboolean JNICALL ScriptMethodsMentalStatesNamespace::setMentalStatesTowardArray(JNIEnv *env, jobject self, jlong mob, jlongArray target, jobjectArray values) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(mob, creature)) + return JNI_FALSE; + + std::vector targetIds; + if (!ScriptConversion::convert(target, targetIds)) + return JNI_FALSE; + + jboolean result = JNI_TRUE; + std::vector::iterator iTarget; + int count = env->GetArrayLength(values); + for (int i = 0; i < count; ++i) + { + LocalRefPtr mentalState = getObjectArrayElement(LocalObjectArrayRefParam(values), i); + if (mentalState != LocalRef::cms_nullPtr) + { + int type = getIntField(*mentalState, JavaLibrary::getFidMentalStateType()); + float value = getFloatField(*mentalState, JavaLibrary::getFidMentalStateValue()); + if (type >= 0 && type < MentalStates::NumberOfMentalStates) + { + for (iTarget=targetIds.begin(); iTarget!=targetIds.end(); ++iTarget) + { + creature->setMentalStateToward(*iTarget, + static_cast(type), + static_cast(value)); + } + } + else + result = JNI_FALSE; + } + else + result = JNI_FALSE; + } + return result; +} // JavaLibrary::setMentalStates + + /** + * Adds values to the mental states for a creature. + * + * @param env Java environment + * @param self class calling this function + * @param mob id of creature to access + * @param values mental state/value pairs to add + * + * @return true on success, false on fail +*/ +jboolean JNICALL ScriptMethodsMentalStatesNamespace::addToMentalStatesTowardArray(JNIEnv *env, jobject self, jlong mob, jlongArray target, jobjectArray values) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(mob, creature)) + return JNI_FALSE; + + std::vector targetIds; + if (!ScriptConversion::convert(target, targetIds)) + return JNI_FALSE; + + jboolean result = JNI_TRUE; + std::vector::iterator iTarget; + int count = env->GetArrayLength(values); + for (int i = 0; i < count; ++i) + { + LocalRefPtr mentalState = getObjectArrayElement(LocalObjectArrayRefParam(values), i); + if (mentalState != LocalRef::cms_nullPtr) + { + int type = getIntField(*mentalState, JavaLibrary::getFidMentalStateType()); + float delta = getFloatField(*mentalState, JavaLibrary::getFidMentalStateValue()); + if (type >= 0 && type < MentalStates::NumberOfMentalStates) + { + for (iTarget=targetIds.begin(); iTarget!=targetIds.end(); ++iTarget) + { + MentalStates::Value value = creature->getMentalStateToward(*iTarget, static_cast(type)); + value += delta; + creature->setMentalStateToward(*iTarget, static_cast(type), + static_cast(value)); + } + } + else + result = JNI_FALSE; + } + else + result = JNI_FALSE; + } + return result; +} // JavaLibrary::addToMentalStates + + /** + * Get the mental states for a behavior. + * + * @param env Java environment + * @param self class calling this function + * @param behavior behavior to check + * + * @return an obj_id[] of the targets +*/ +jlongArray JNICALL ScriptMethodsMentalStatesNamespace::getBehaviorTargets(JNIEnv *env, jobject self, jlong mob, jint behavior) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(mob, creature)) + return 0; + + std::vector targetIds; + creature->getBehaviorTargets(behavior, targetIds); + + LocalLongArrayRefPtr result; + if (!ScriptConversion::convert(targetIds, result)) + return 0; + return result->getReturnValue(); +} + +/** +* Returns a creature's current behavior +* +* @param env Java environment +* @param self class calling this function +* @param mob id of creature to access +* +* @return the hehavior, or 0 on error +*/ +jint JNICALL ScriptMethodsMentalStatesNamespace::getBehavior(JNIEnv *env, jobject self, jlong mob) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(mob, creature)) + return 0; + + return creature->getBehavior(); +} // JavaLibrary::getBehavior + + /** + * Returns a creature's current behavior toward another + * + * @param env Java environment + * @param self class calling this function + * @param mob id of creature to access + * @param target id of creature to get mental state towrad + * + * @return the hehavior, or 0 on error +*/ +jint JNICALL ScriptMethodsMentalStatesNamespace::getBehaviorToward(JNIEnv *env, jobject self, jlong mob, jlong target) +{ + UNREF(self); + + if (target == 0) + return 0; + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(mob, creature)) + return 0; + + return creature->getBehaviorToward(NetworkId(target)); +} // JavaLibrary::getBehavior + +void JNICALL ScriptMethodsMentalStatesNamespace::scheduleAiCombatPulse(JNIEnv *env, jobject self, jlong mob) +{ + UNREF(self); + + if (mob == 0) + return; + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(mob, creature)) + return; + + //AiCombatPulseQueue::scheduleAiCombatPulse(creature->getNetworkId()); +} diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsMenu.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsMenu.cpp new file mode 100644 index 00000000..a7f27192 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsMenu.cpp @@ -0,0 +1,207 @@ +//======================================================================== +// +// ScriptMethodsMenu.cpp - implements script methods dealing with object +// movement. +// +// copyright 2001 Sony Online Entertainment +// +//======================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "sharedGame/RadialMenuManager.h" +#include "sharedNetworkMessages/ObjectMenuRequestData.h" +#include + +using namespace JNIWrappersNamespace; + + +// ====================================================================== +// ScriptMethodsMenuNamespace +// ====================================================================== + +namespace ScriptMethodsMenuNamespace +{ + bool install(); + + jfloat JNICALL getRangeForMenuType(JNIEnv *env, jobject self, jint menuType); +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsMenuNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsMenuNamespace::c)} + JF("getRangeForMenuType", "(I)F", getRangeForMenuType), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +//---------------------------------------------------------------------- +//-- todo move this into the proper implementation file + +/** +* Convert a java menu_info to a vector of C++ ObjectMenuRequestData objects +*/ +const bool JavaLibrary::convert(const LocalRefParamPtr & source, MenuDataVector & target) +{ + LocalObjectArrayRefPtr arrayOfMenuInfoDatas = callObjectArrayMethod (*source, ms_midMenuInfoGetMenuItemsInternal); + if (ms_env->ExceptionCheck()) + { + ms_env->ExceptionDescribe(); + return false; + } + + const int count = getArrayLength (*arrayOfMenuInfoDatas); + target.reserve (count); + + for (int j = 0; j < count; ++j) + { + ObjectMenuRequestData omrd; + LocalRefPtr element = getObjectArrayElement(*arrayOfMenuInfoDatas, j); + + //-- id + const int id = getIntField (*element, JavaLibrary::ms_fidMenuInfoDataId); + if (id < 0 || id >= 255) + return false; + + //-- parent + const int parent = getIntField (*element, JavaLibrary::ms_fidMenuInfoDataParent); + if (parent < 0 || parent >= 255) + return false; + + //-- type + const int type = getIntField (*element, JavaLibrary::ms_fidMenuInfoDataType); + if (type < 0 || type >= 65535) + return false; + + omrd.m_parent = static_cast(parent); + omrd.m_id = static_cast(id); + omrd.m_menuItemType = static_cast(type); + + //-- label + LocalRefPtr labelObject = getObjectField(*element, ms_fidMenuInfoDataLabel); + if (labelObject == LocalRef::cms_nullPtr) + return false; + StringId labelId; + if (ScriptConversion::convert (*labelObject, labelId)) + omrd.m_labelId = labelId; + else + WARNING (true, ("Unable to convert object menu labelId from Java string_id to C++ StringId.")); + + //-- flags (enabled, serverNotify) + + const bool enabled = getBooleanField (*element, ms_fidMenuInfoDataEnabled) != 0; + const bool serverNotify = getBooleanField (*element, ms_fidMenuInfoDataServerNotify) != 0; + + if (enabled) + omrd.m_flags |= ObjectMenuRequestData::F_enabled; + else + omrd.m_flags &= ~(ObjectMenuRequestData::F_enabled); + + if (serverNotify) + omrd.m_flags |= ObjectMenuRequestData::F_serverNotify; + else + omrd.m_flags &= ~(ObjectMenuRequestData::F_serverNotify); + + target.push_back (omrd); + } + + return true; +} + +//---------------------------------------------------------------------- +//-- todo move this into the proper implementation file + +/** +* Convert a C++ MenuDataVector to a java menu_info +*/ +const bool JavaLibrary::convert(const MenuDataVector & source, LocalRefParamPtr & target) +{ + const int count = static_cast(source.size ()); + + LocalObjectArrayRefPtr arrayOfMenuInfoDatas = createNewObjectArray(count, ms_clsMenuInfoData); + + if (arrayOfMenuInfoDatas == LocalObjectArrayRef::cms_nullPtr) + { + WARNING (true, ("java unable to create array of menu info datas.")); + return false; + } + + if (getArrayLength (*arrayOfMenuInfoDatas) != count) + { + WARNING (true, ("java created wrong size array.")); + return false; + } + + bool retval = true; + + for (int j = 0; j < count; ++j) + { + const ObjectMenuRequestData & omrd = source [j]; + + LocalRefPtr element = createNewObject(ms_clsMenuInfoData, ms_midMenuInfoData); + if (element == LocalRef::cms_nullPtr) + { + WARNING (true, ("java unable to create new menu array element %d from size %d array.", j, count)); + retval = false; + continue; + } + + setIntField (*element, JavaLibrary::ms_fidMenuInfoDataId, omrd.m_id); + setIntField (*element, JavaLibrary::ms_fidMenuInfoDataParent, omrd.m_parent); + setIntField (*element, JavaLibrary::ms_fidMenuInfoDataType, omrd.m_menuItemType); + setBooleanField (*element, JavaLibrary::ms_fidMenuInfoDataEnabled, omrd.hasFlag (ObjectMenuRequestData::F_enabled)); + setBooleanField (*element, JavaLibrary::ms_fidMenuInfoDataServerNotify, omrd.hasFlag (ObjectMenuRequestData::F_serverNotify)); + + LocalRefPtr labelIdObject; + if (ScriptConversion::convert (omrd.m_labelId, labelIdObject)) + { + setObjectField(*element, ms_fidMenuInfoDataLabel, *labelIdObject); + } + else + WARNING (true, ("Unable to convert object menu m_labelId from C++ StringId to Java string_id.")); + setObjectArrayElement (*arrayOfMenuInfoDatas, j, *element); + } + + if (retval) + { + retval = callBooleanMethod(*target, JavaLibrary::ms_midMenuInfoSetMenuItemsInternal, arrayOfMenuInfoDatas->getValue()) != 0; + } + + return retval; +} + +//---------------------------------------------------------------------- + +/** + * Returns the distance a player must be from a target to use a menu item. + * + * @param env Java environment + * @param self class calling this function + * @param menuType the id of the menu item (from menu_info_types.java) + * + * @return the distance, or -1 on unknown menu type + */ +jfloat JNICALL ScriptMethodsMenuNamespace::getRangeForMenuType(JNIEnv *env, jobject self, jint menuType) +{ + UNREF(env); + UNREF(self); + + float range = 0; + if (RadialMenuManager::getRangeForMenuType(menuType, range)) + return range; + + return -1.0f; +} // JavaLibrary::getRangeForMenuType + +//---------------------------------------------------------------------- + + diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsMission.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsMission.cpp new file mode 100644 index 00000000..815bb35a --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsMission.cpp @@ -0,0 +1,1102 @@ +// ScriptMethodsMission.cpp +// Copyright 2000-01, Sony Online Entertainment Inc., all rights reserved. +// Author: Justin Randall + +//----------------------------------------------------------------------- + +#include "serverScript/FirstServerScript.h" +#include "serverGame/ContainerInterface.h" +#include "serverGame/MissionObject.h" +#include "serverGame/PlanetObject.h" +#include "serverGame/Region.h" +#include "serverGame/RegionMaster.h" +#include "serverGame/ServerObject.h" +#include "serverGame/ServerUniverse.h" +#include "serverGame/ServerWorld.h" +#include "serverScript/JavaLibrary.h" +#include "sharedMath/Vector2d.h" +#include "sharedNetworkMessages/PopulateMissionBrowserMessage.h" +#include "sharedObject/ObjectTemplateList.h" + +using namespace JNIWrappersNamespace; + + +// ====================================================================== +// ScriptMethodsMissionNamespace +// ====================================================================== + +namespace ScriptMethodsMissionNamespace +{ + bool install(); + + jlong JNICALL createMissionObjectInCreatureMissionBag(JNIEnv * env, jobject self, jlong creature); + void JNICALL abortMission (JNIEnv * env, jobject self, jlong missionObject); + jobject JNICALL assignMission (JNIEnv * env, jobject self, jobject missionData, jobject playerCharacter); + void JNICALL endMission (JNIEnv * env, jobject self, jobject missionObject); + jlong JNICALL getMissionHolder (JNIEnv * env, jobject self, jlong missionObject); + jstring JNICALL getMissionCreator (JNIEnv * env, jobject self, jlong missionData); + jobject JNICALL getMissionDescription (JNIEnv * env, jobject self, jlong missionData); + jint JNICALL getMissionDifficulty (JNIEnv * env, jobject self, jlong missionData); + jobject JNICALL getMissionEndLocation (JNIEnv * env, jobject self, jlong missionData); + jint JNICALL getMissionReward (JNIEnv * env, jobject self, jlong missionData); + jstring JNICALL getMissionRootScriptName (JNIEnv * env, jobject self, jlong missionData); + jobject JNICALL getMissionStartLocation (JNIEnv * env, jobject self, jlong missionData); + jint JNICALL getMissionStatus (JNIEnv * env, jobject self, jlong missionObject); + jstring JNICALL getMissionTargetName (JNIEnv * env, jobject self, jlong missionData); + jobject JNICALL getMissionTitle (JNIEnv * env, jobject self, jlong missionData); + jstring JNICALL getMissionType (JNIEnv * env, jobject self, jlong missionData); + void JNICALL setMissionCreator (JNIEnv * env, jobject self, jlong missionData, jstring creator); + void JNICALL setMissionDescription (JNIEnv * env, jobject self, jlong missionData, jobject descriptionStringId); + void JNICALL setMissionDifficulty (JNIEnv * env, jobject self, jlong missionData, jint difficulty); + void JNICALL setMissionEndLocation (JNIEnv * env, jobject self, jlong missionData, jobject location); + void JNICALL setMissionReward (JNIEnv * env, jobject self, jlong missionData, jint reward); + void JNICALL setMissionRootScriptName (JNIEnv * env, jobject self, jlong missionData, jstring rootScriptName); + void JNICALL setMissionStartLocation (JNIEnv * env, jobject self, jlong missionData, jobject location); + void JNICALL setMissionStatus (JNIEnv * env, jobject self, jlong missionObject, jint newStatus); + void JNICALL startMission (JNIEnv * env, jobject self, jlong creature, jlong mission); + void JNICALL setMissionTargetAppearance (JNIEnv * env, jobject self, jlong missionData, jstring targetAppearance); + void JNICALL setMissionTargetName (JNIEnv * env, jobject self, jlong missionData, jstring targetName); + void JNICALL setMissionTitle (JNIEnv * env, jobject self, jlong missionData, jobject titleStringId); + void JNICALL setMissionType (JNIEnv * env, jobject self, jlong missionData, jstring typeName); + jlongArray JNICALL getMissionObjects (JNIEnv * env, jobject self, jlong playerCharacter); +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsMissionNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsMissionNamespace::c)} + JF("_abortMission", "(J)V", abortMission), + JF("_createMissionObjectInCreatureMissionBag", "(J)J", createMissionObjectInCreatureMissionBag), + JF("_getMissionStatus", "(J)I", getMissionStatus), + JF("_setMissionStatus", "(JI)V", setMissionStatus), + JF("_getMissionObjects", "(J)[J", getMissionObjects), + JF("_getMissionHolder", "(J)J", getMissionHolder), + JF("_getMissionCreator", "(J)Ljava/lang/String;", getMissionCreator), + JF("_getMissionDifficulty", "(J)I", getMissionDifficulty), + JF("_getMissionDescription", "(J)Lscript/string_id;", getMissionDescription), + JF("_getMissionEndLocation", "(J)Lscript/location;", getMissionEndLocation), + JF("_getMissionReward", "(J)I", getMissionReward), + JF("_getMissionRootScriptName", "(J)Ljava/lang/String;", getMissionRootScriptName), + JF("_getMissionStartLocation", "(J)Lscript/location;", getMissionStartLocation), + JF("_getMissionTargetName", "(J)Ljava/lang/String;", getMissionTargetName), + JF("_getMissionTitle", "(J)Lscript/string_id;", getMissionTitle), + JF("_getMissionType", "(J)Ljava/lang/String;", getMissionType), + JF("_setMissionCreator", "(JLjava/lang/String;)V", setMissionCreator), + JF("_setMissionDescription", "(JLscript/string_id;)V", setMissionDescription), + JF("_setMissionDifficulty", "(JI)V", setMissionDifficulty), + JF("_setMissionEndLocation", "(JLscript/location;)V", setMissionEndLocation), + JF("_setMissionRootScriptName", "(JLjava/lang/String;)V", setMissionRootScriptName), + JF("_setMissionReward", "(JI)V", setMissionReward), + JF("_setMissionStartLocation", "(JLscript/location;)V", setMissionStartLocation), + JF("_setMissionTitle", "(JLscript/string_id;)V", setMissionTitle), + JF("_setMissionTargetAppearance", "(JLjava/lang/String;)V", setMissionTargetAppearance), + JF("_setMissionTargetName", "(JLjava/lang/String;)V", setMissionTargetName), + JF("_setMissionType", "(JLjava/lang/String;)V", setMissionType), + JF("_startMission", "(JJ)V", startMission), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +//----------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsMissionNamespace::createMissionObjectInCreatureMissionBag(JNIEnv * env, jobject self, jlong creature) +{ + jlong result = 0; + if(! env) + return result; + if(! self) + return result; + if(! creature) + return result; + + CreatureObject * c = 0; + if(JavaLibrary::getObject(creature, c)) + { + ServerObject * missionBag = c->getMissionBag(); + if(missionBag) + { + Container * container = ContainerInterface::getContainer(*missionBag); + ContainerIterator iter; + for(iter = container->begin(); iter != container->end(); ++iter) + { + MissionObject * missionObject = safe_cast((*iter).getObject()); + if(missionObject) + { + result = (missionObject->getNetworkId()).getValue(); + break; + } + } + } + + if(! result) + { + MissionObject * missionObject = MissionObject::createMissionObjectInCreatureMissionBag(c); + if(missionObject) + { + result = (missionObject->getNetworkId()).getValue(); + } + } + } + return result; +} + +//----------------------------------------------------------------------- + +void JNICALL ScriptMethodsMissionNamespace::abortMission(JNIEnv * env, jobject self, jlong missionObject) +{ + if(env) + { + if(self) + { + if(missionObject) + { + MissionObject * m; + JavaLibrary::getObject(missionObject, m); + if(m) + { + m->abortMission(); + } + else + { + DEBUG_WARNING(true, ("[designer bug] abortMission() missionObject is invalid")); + } + } + else + { + DEBUG_WARNING(true, ("[designer bug] abortMission() missionObject is NULL")); + } + } + else + { + DEBUG_WARNING(true, ("[programmer bug] abortMission() self is NULL")); + } + } + else + { + DEBUG_WARNING(true, ("[programmer bug] abortMission() JNIEnv is NULL")); + } +} + +//----------------------------------------------------------------------- + +void JNICALL ScriptMethodsMissionNamespace::endMission(JNIEnv * env, jobject self, jobject missionObject) +{ + if(env) + { + if(self) + { + if(missionObject) + { + } + } + } +} + +//----------------------------------------------------------------------- + +jlongArray JNICALL ScriptMethodsMissionNamespace::getMissionObjects(JNIEnv * env, jobject self, jlong playerCharacter) +{ + if (!env) + { + DEBUG_REPORT_LOG(true, ("No env found in getMissionObjects\n")); + return 0; + } + if (!self) + { + DEBUG_REPORT_LOG(true, ("No self found in getMissionObjects\n")); + return 0; + } + if (!playerCharacter) + { + DEBUG_REPORT_LOG(true, ("No PC found in getMissionObjects\n")); + return 0; + } + + CreatureObject * pc = 0; + if(!JavaLibrary::getObject(playerCharacter, pc)) + { + DEBUG_REPORT_LOG(true, ("Could not get object for PC in getMissionObjects\n")); + return 0; + } + + if(!pc) + { + DEBUG_REPORT_LOG(true, ("Could not resolve PC in getMissionObjects\n")); + return 0; + } + + const std::vector & missions = pc->getMissions(); + if(missions.empty()) + { + DEBUG_REPORT_LOG(true, ("Mission list empty for getMissionObjects.\n")); + return 0; + } + + // build array + int count = missions.size(); + LocalLongArrayRefPtr result = createNewLongArray(count); + if (result != LocalLongArrayRef::cms_nullPtr) + { + int i; + + jlong jlongTmp; + for(i = 0; i < count; ++i) + { + jlongTmp = missions[i].getValue(); + setLongArrayRegion(*result, i, 1, &jlongTmp); + } + } + else + { + DEBUG_REPORT_LOG(true, ("Could not allocate new object array in getMissionObjects\n")); + } + return result->getReturnValue(); +} + +//----------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsMissionNamespace::getMissionCreator(JNIEnv * env, jobject self, jlong missionObject) +{ + jstring result = 0; + if(env) + { + if(self) + { + if(missionObject) + { + MissionObject * mo = 0; + if(JavaLibrary::getObject(missionObject, mo)) + { + result = JavaString(mo->getMissionCreator()).getReturnValue(); + } + else + { + DEBUG_WARNING(true, ("[designer bug] getMissionCreator() missionObject (parameter 1) is invalid")); + } + } + else + { + DEBUG_WARNING(true, ("[designer bug] getMissionCreator() missionObject (parameter 1) is NULL")); + } + } + else + { + DEBUG_WARNING(true, ("[programmer bug] getMissionCreator() self is NULL")); + } + } + else + { + DEBUG_WARNING(true, ("[programmer bug] getMissionCreator() JNIEnv is NULL")); + } + return result; +} + +//----------------------------------------------------------------------- + +jobject JNICALL ScriptMethodsMissionNamespace::getMissionDescription(JNIEnv * env, jobject self, jlong missionObject) +{ + if(! env) + { + DEBUG_WARNING(true, ("[programmer bug] getMissionDescription() JNIEnv is NULL")); + return 0; + } + + if(! missionObject) + { + DEBUG_WARNING(true, ("[designer bug] getMissionDescription() missionObject (parameter 1) is NULL")); + return 0; + } + + MissionObject * mo = 0; + if(JavaLibrary::getObject(missionObject, mo)) + { + LocalRefPtr result; + const StringId & descriptionStringId = mo->getDescription(); + if (ScriptConversion::convert(descriptionStringId, result)) + return result->getReturnValue(); + } + else + { + DEBUG_WARNING(true, ("[designer bug] getMissionDescription() missionObject (parameter 1) is invalid")); + } + return 0; +} + +//----------------------------------------------------------------------- + +jint JNICALL ScriptMethodsMissionNamespace::getMissionDifficulty(JNIEnv * env, jobject self, jlong missionObject) +{ + jint result = 0; + if(env) + { + if(self) + { + if(missionObject) + { + MissionObject * mo = 0; + if(JavaLibrary::getObject(missionObject, mo)) + { + result = static_cast(mo->getDifficulty()); + } + else + { + DEBUG_WARNING(true, ("[designer bug] getMissionDifficulty() missionObject (parameter 1) is invalid")); + } + } + else + { + DEBUG_WARNING(true, ("[designer bug] getMissionDifficulty() missionObject (parameter 1) is NULL")); + } + } + else + { + DEBUG_WARNING(true, ("[programmer bug] getMissionDifficulty() self is NULL")); + } + } + else + { + DEBUG_WARNING(true, ("[programmer bug] getMissionDifficulty() JNIEnv is NULL")); + } + return result; +} + +//----------------------------------------------------------------------- + +jobject JNICALL ScriptMethodsMissionNamespace::getMissionEndLocation(JNIEnv * env, jobject self, jlong missionObject) +{ + if(missionObject) + { + MissionObject * mo = 0; + if(JavaLibrary::getObject(missionObject, mo)) + { + Location loc = mo->getEndLocation(); + // @ todo : update location object in java to include planet, region and correct + // area so it is a float describing a radius + LocalRefPtr result; + if (ScriptConversion::convert(loc.getCoordinates(), Location::getSceneNameByCrc(loc.getSceneIdCrc()), loc.getCell(), result)) + return result->getReturnValue(); + } + else + { + DEBUG_WARNING(true, ("[designer bug] getMissionEndLocation() missionObject (parameter1) is invalid")); + } + } + else + { + DEBUG_WARNING(true, ("[designer bug] getMissionEndLocation() missionObject (parameter1) is NULL")); + } + return 0; +} + +//----------------------------------------------------------------------- + +jint JNICALL ScriptMethodsMissionNamespace::getMissionReward(JNIEnv * env, jobject self, jlong missionObject) +{ + jint result = 0; + if(env) + { + if(self) + { + if(missionObject) + { + MissionObject * md = 0; + if(JavaLibrary::getObject(missionObject, md)) + { + result = md->getReward(); + } + else + { + DEBUG_WARNING(true, ("[designer bug] getMissionReward() missionObject (parameter 1) is invalid")); + } + } + else + { + DEBUG_WARNING(true, ("[designer bug] getMissionReward() missionObject (parameter 1) is NULL")); + } + } + else + { + DEBUG_WARNING(true, ("[programmer bug] getMissionReward() self is NULL")); + } + } + else + { + DEBUG_WARNING(true, ("[programmer bug] getMissionReward() JNIEnv is NULL")); + } + return result; +} + +//----------------------------------------------------------------------- + +jobject JNICALL ScriptMethodsMissionNamespace::getMissionStartLocation(JNIEnv * env, jobject self, jlong missionObject) +{ + if(missionObject) + { + MissionObject * md = 0; + if(JavaLibrary::getObject(missionObject, md)) + { + LocalRefPtr result; + const Location & loc = md->getStartLocation(); + if (ScriptConversion::convert(loc.getCoordinates(), Location::getSceneNameByCrc(loc.getSceneIdCrc()), loc.getCell(), result)) + return result->getReturnValue(); + } + else + { + DEBUG_WARNING(true, ("[designer bug] getMissionStartLocation() missionObject (parameter 1) is invalid")); + } + } + else + { + DEBUG_WARNING(true, ("[designer bug] getMissionStartLocation() missionObject (parameter 1) is NULL")); + } + return 0; +} + +//----------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsMissionNamespace::getMissionTargetName(JNIEnv * env, jobject self, jlong missionObject) +{ + UNREF(env); + UNREF(self); + + if(missionObject) + { + MissionObject * md = 0; + if(JavaLibrary::getObject(missionObject, md)) + { + if(md) + { + return JavaString(md->getTargetName()).getReturnValue(); + } + } + else + { + DEBUG_WARNING(true, ("[designer bug] getMissionTargetName() missionObject (parameter 1) is invalid")); + } + } + else + { + DEBUG_WARNING(true, ("[designer bug] getMissionTargetName() missionObject (parameter 1) is NULL")); + } + return 0; +} + +//----------------------------------------------------------------------- + +jobject JNICALL ScriptMethodsMissionNamespace::getMissionTitle(JNIEnv * env, jobject self, jlong missionObject) +{ + if(! missionObject) + { + DEBUG_WARNING(true, ("[designer bug] getMissionTitle() missionObject (parameter 1) is NULL")); + return 0; + } + + MissionObject * md = 0; + if(JavaLibrary::getObject(missionObject, md)) + { + LocalRefPtr result; + const StringId & titleStringId = md->getTitle(); + if (ScriptConversion::convert(titleStringId, result)) + return result->getReturnValue(); + } + else + { + DEBUG_WARNING(true, ("[designer bug] getMissionTitle() missionObject (parameter 1) is invalid")); + } + return 0; +} + +//----------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsMissionNamespace::getMissionType(JNIEnv * env, jobject self, jlong missionObject) +{ + UNREF(env); + UNREF(self); + + if(missionObject) + { + MissionObject * md = 0; + if(JavaLibrary::getObject(missionObject, md)) + { + if(md) + { + return JavaString(md->getMissionTypeString()).getReturnValue(); + } + } + else + { + DEBUG_WARNING(true, ("[designer bug] getMissionType() missionObject (parameter 1) is invalid")); + } + } + else + { + DEBUG_WARNING(true, ("[designer bug] getMissionType() missionObject (parameter 1) is NULL")); + } + return 0; +} + +//----------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsMissionNamespace::getMissionHolder(JNIEnv * env, jobject self, jlong missionObject) +{ + jlong result = 0; + if(env) + { + if(self) + { + if(missionObject) + { + MissionObject * mo = 0; + if(JavaLibrary::getObject(missionObject, mo)) + { + if (mo != NULL && mo->getMissionHolderId() != NetworkId::cms_invalid) + { + result = (mo->getMissionHolderId()).getValue(); + } + else + { + DEBUG_WARNING(true, ("[designer bug] getMissionHolder() missionObject (parameter 1) has no mission holder")); + } + } + else + { + DEBUG_WARNING(true, ("[designer bug] getMissionHolder() missionObject (parameter 1) is invalid")); + } + } + else + { + DEBUG_WARNING(true, ("[designer bug] getMissionHolder() missionObject (parameter 1) is NULL")); + } + } + else + { + DEBUG_WARNING(true, ("[programmer bug] getMissionHolder() self is NULL")); + } + } + else + { + DEBUG_WARNING(true, ("[programmer bug] getMissionHolder() JNIEnv is NULL")); + } + return result; +} + +//----------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsMissionNamespace::getMissionRootScriptName(JNIEnv * env, jobject self, jlong missionObject) +{ + UNREF(env); + UNREF(self); + + if(missionObject) + { + MissionObject * md = 0; + if(JavaLibrary::getObject(missionObject, md)) + { + JavaString result(md->getRootScriptName().c_str()); + return result.getReturnValue(); + } + else + { + DEBUG_WARNING(true, ("[designer bug] getMissionRootScriptName() missionObject (parameter 1) is invalid")); + } + } + else + { + DEBUG_WARNING(true, ("[designer bug] getMissionRootScriptName() missionObject (parameter 1) is NULL")); + } + return 0; +} + +//----------------------------------------------------------------------- + +void JNICALL ScriptMethodsMissionNamespace::setMissionCreator(JNIEnv *env, jobject self, jlong missionObject, jstring creator) +{ + if(env) + { + if(self) + { + if(missionObject) + { + if(creator) + { + MissionObject * md = 0; + if(JavaLibrary::getObject(missionObject, md)) + { + JavaString c(creator); + Unicode::String s; + if(JavaLibrary::convert(c, s)) + md->setMissionCreator(s); + } + else + { + DEBUG_WARNING(true, ("[designer bug] setMissionCreator() missionObject (parameter 1) is invalid")); + } + } + else + { + DEBUG_WARNING(true, ("[designer bug] setMissionCreator() creator (parameter 2) is NULL")); + } + } + else + { + DEBUG_WARNING(true, ("[designer bug] setMissionCreator() missionObject (parameter 1) is NULL")); + } + } + else + { + DEBUG_WARNING(true, ("[programmer bug] setMissionCreator() self is NULL")); + } + } + else + { + DEBUG_WARNING(true, ("[programmer bug] setMissionCreator() JNIEnv is NULL")); + } +} + +//----------------------------------------------------------------------- + +void JNICALL ScriptMethodsMissionNamespace::setMissionDescription(JNIEnv * env, jobject self, jlong missionObject, jobject descriptionStringId) +{ + if(missionObject) + { + MissionObject * md = 0; + if(JavaLibrary::getObject(missionObject, md)) + { + StringId desc; + if(ScriptConversion::convert(descriptionStringId, desc)) + { + md->setDescription(desc); + } + else + { + DEBUG_WARNING(true, ("[designer bug] setMissionDescription() descriptionStringId (parameter 2) is invalid")); + } + } + else + { + DEBUG_WARNING(true, ("[designer bug] setMissionDescription() missionObject (parameter 1) is invalid")); + } + } + else + { + DEBUG_WARNING(true, ("[designer bug] setMissionDescription() missionObject (parameter 1) is NULL")); + } +} + +//----------------------------------------------------------------------- + +void JNICALL ScriptMethodsMissionNamespace::setMissionDifficulty(JNIEnv * env, jobject self, jlong missionObject, jint difficulty) +{ + if(missionObject) + { + MissionObject * md = 0; + if(JavaLibrary::getObject(missionObject, md)) + { + md->setDifficulty(static_cast(difficulty)); + } + else + { + DEBUG_WARNING(true, ("[designer bug] setMissionDifficulty() missionObject (parameter 1) is invalid")); + } + } + else + { + DEBUG_WARNING(true, ("[designer bug] setMissionDifficulty() missionObject (parameter 1) is NULL")); + } +} + +//----------------------------------------------------------------------- + +void JNICALL ScriptMethodsMissionNamespace::setMissionEndLocation(JNIEnv * env, jobject self, jlong missionObject, jobject location) +{ + if(env) + { + if(self) + { + if(missionObject) + { + MissionObject * md = 0; + if(JavaLibrary::getObject(missionObject, md)) + { + // @todo : flesh out java location class and set this appropriately! + JavaStringPtr p = getStringField(LocalRefParam(location), JavaLibrary::getFidLocationArea()); + if (p != JavaString::cms_nullPtr) + { + std::string s; + if (JavaLibrary::convert(*p, s)) + { + Location loc(Vector(env->GetFloatField(location, JavaLibrary::getFidLocationX()), env->GetFloatField(location, JavaLibrary::getFidLocationY()), env->GetFloatField(location, JavaLibrary::getFidLocationZ())), JavaLibrary::getNetworkId(env->GetObjectField(location, JavaLibrary::getFidLocationCell())), Location::getCrcBySceneName(s.c_str())); + md->setEndLocation(loc); + } + } + } + } + } + } +} + +//----------------------------------------------------------------------- + +void JNICALL ScriptMethodsMissionNamespace::setMissionReward(JNIEnv * env, jobject self, jlong missionObject, jint reward) +{ + if(env) + { + if(self) + { + if(missionObject) + { + MissionObject * md = 0; + if(JavaLibrary::getObject(missionObject, md)) + { + md->setReward(static_cast(reward)); + } + else + { + DEBUG_WARNING(true, ("[designer bug] setMissionProfessionRank() missionObject (parameter 1) is invalid")); + } + } + else + { + DEBUG_WARNING(true, ("[designer bug] setMissionProfessionRank() missionObject (parameter 1) is NULL")); + } + } + else + { + DEBUG_WARNING(true, ("[programmer bug] setMissionProfessionRank() self is NULL")); + } + } + else + { + DEBUG_WARNING(true, ("[programmer bug] setMissionProfessionRank() JNIEnv is NULL")); + } +} + +//----------------------------------------------------------------------- + +void JNICALL ScriptMethodsMissionNamespace::setMissionStartLocation(JNIEnv * env, jobject self, jlong missionObject, jobject location) +{ + if(env) + { + if(self) + { + if(missionObject) + { + MissionObject * md = 0; + if(JavaLibrary::getObject(missionObject, md)) + { + if (location) + { + JavaStringPtr p = getStringField(LocalRefParam(location), JavaLibrary::getFidLocationArea()); + if (p != JavaString::cms_nullPtr) + { + std::string s; + if (JavaLibrary::convert(*p, s)) + { + Location loc(Vector(env->GetFloatField(location, JavaLibrary::getFidLocationX()), env->GetFloatField(location, JavaLibrary::getFidLocationY()), env->GetFloatField(location, JavaLibrary::getFidLocationZ())), JavaLibrary::getNetworkId(env->GetObjectField(location, JavaLibrary::getFidLocationCell())), Location::getCrcBySceneName(s.c_str())); + md->setStartLocation(loc); + } + } + } + else + { + DEBUG_WARNING(true, ("[designer bug] setMissionStartLocation() location (parameter 2) is NULL")); + } + } + else + { + DEBUG_WARNING(true, ("[designer bug] setMissionStartLocation() missionObject (parameter 1) is invalid")); + } + } + else + { + DEBUG_WARNING(true, ("[designer bug] setMissionStartLocation() missionObject (parameter 1) is NULL")); + } + } + else + { + DEBUG_WARNING(true, ("[programmer bug] setMissionStartLocation() self is NULL")); + } + } + else + { + DEBUG_WARNING(true, ("[programmer bug] setMissionStartLocation() JNIEnv is NULL")); + } +} + +//----------------------------------------------------------------------- + +void JNICALL ScriptMethodsMissionNamespace::setMissionTargetAppearance(JNIEnv * env, jobject self, jlong missionObject, jstring appearanceName) +{ + if(env) + { + if(self) + { + if(missionObject) + { + MissionObject * md = 0; + if(JavaLibrary::getObject(missionObject, md)) + { + std::string s; + if(JavaLibrary::convert(JavaString(appearanceName), s)) + { + md->setTargetAppearance(s); + } + } + else + { + DEBUG_WARNING(true, ("[designer bug] setMissionTarget() missionObject (parameter 1) is invalid")); + } + } + else + { + DEBUG_WARNING(true, ("[designer bug] setMissionTarget() missionObject (parameter 1) is NULL")); + } + } + else + { + DEBUG_WARNING(true, ("[programmer bug] setMissionTarget() self is NULL")); + } + } + else + { + DEBUG_WARNING(true, ("[programmer bug] setMissionTarget() JNIEnv is NULL")); + } +} + +//----------------------------------------------------------------------- + +void JNICALL ScriptMethodsMissionNamespace::setMissionTargetName(JNIEnv * env, jobject self, jlong missionObject, jstring name) +{ + if(env) + { + if(self) + { + if(missionObject) + { + MissionObject * md = 0; + if(JavaLibrary::getObject(missionObject, md)) + { + std::string desc; + if(JavaLibrary::convert(JavaString(name), desc)) + { + md->setTargetName(desc); + } + } + else + { + DEBUG_WARNING(true, ("[designer bug] setMissionTarget() missionObject (parameter 1) is invalid")); + } + } + else + { + DEBUG_WARNING(true, ("[designer bug] setMissionTarget() missionObject (parameter 1) is NULL")); + } + } + else + { + DEBUG_WARNING(true, ("[programmer bug] setMissionTarget() self is NULL")); + } + } + else + { + DEBUG_WARNING(true, ("[programmer bug] setMissionTarget() JNIEnv is NULL")); + } +} + +//----------------------------------------------------------------------- + +void JNICALL ScriptMethodsMissionNamespace::setMissionTitle(JNIEnv * env, jobject self, jlong missionObject, jobject titleStringId) +{ + if(missionObject) + { + MissionObject * md = 0; + if(JavaLibrary::getObject(missionObject, md)) + { + StringId title; + if(ScriptConversion::convert(titleStringId, title)) + { + md->setTitle(title); + } + else + { + DEBUG_WARNING(true, ("[designer bug] setMissionTitle() titleStringId (parameter 2) is invalid")); + } + } + else + { + DEBUG_WARNING(true, ("[designer bug] setMissionTitle() missionObject (parameter 1) is invalid")); + } + } + else + { + DEBUG_WARNING(true, ("[designer bug] setMissionTitle() missionObject (parameter 1) is NULL")); + } +} + +//----------------------------------------------------------------------- + +void JNICALL ScriptMethodsMissionNamespace::setMissionType(JNIEnv *env, jobject self, jlong missionObject, jstring typeName) +{ + if(env) + { + if(self) + { + if(missionObject) + { + if(typeName) + { + MissionObject * md = 0; + if(JavaLibrary::getObject(missionObject, md)) + { + JavaStringParam localTypeName(typeName); + std::string n; + if(JavaLibrary::convert(localTypeName, n)) + { + md->setMissionType(n); + } + } + else + { + DEBUG_WARNING(true, ("[designer bug] setMissionType() missionObject (parameter 1) is invalid")); + } + } + else + { + DEBUG_WARNING(true, ("[designer bug] setMissionType() typeName (parameter 2) is NULL")); + } + } + else + { + DEBUG_WARNING(true, ("[designer bug] setMissionType() missionObject (parameter 1) is NULL")); + } + } + else + { + DEBUG_WARNING(true, ("[programmer bug] setMissionType() self is NULL")); + } + } + else + { + DEBUG_WARNING(true, ("[programmer bug] setMissionType() JNIEnv is NULL")); + } +} + +//----------------------------------------------------------------------- + +void JNICALL ScriptMethodsMissionNamespace::setMissionRootScriptName(JNIEnv *env, jobject self, jlong missionObject, jstring rootScriptName) +{ + JavaStringParam localRootScriptName(rootScriptName); + + if(env) + { + if(self) + { + if(missionObject) + { + if(rootScriptName) + { + MissionObject * md = 0; + if(JavaLibrary::getObject(missionObject, md)) + { + std::string n; + if(JavaLibrary::convert(localRootScriptName, n)) + { + md->setRootScriptName(n); + } + else + { + DEBUG_WARNING(true, ("[designer bug] setMissionRootScriptName() rootScriptName (parameter 2) is invalid")); + } + } + else + { + DEBUG_WARNING(true, ("[designer bug] setMissionRootScriptName() missionObject (parameter 1) is invalid")); + } + } + else + { + DEBUG_WARNING(true, ("[designer bug] setMissionRootScriptName() rootScriptName (parameter 2) is NULL")); + } + } + else + { + DEBUG_WARNING(true, ("[designer bug] setMissionRootScriptName() missionObject (parameter 1) is NULL")); + } + } + else + { + DEBUG_WARNING(true, ("[programmer bug] setMissionRootScriptName() self is NULL")); + } + } + else + { + DEBUG_WARNING(true, ("[programmer bug] setMissionRootScriptName() JNIEnv is NULL")); + } +} + +//----------------------------------------------------------------------- + +jint JNICALL ScriptMethodsMissionNamespace::getMissionStatus(JNIEnv * env, jobject self, jlong missionObject) +{ + jint result = 0; + if(! env) + return 0; + if(! self) + return 0; + + MissionObject * mo = 0; + if(JavaLibrary::getObject(missionObject, mo)) + { + result = mo->getStatus(); + } + return result; + +} + +//----------------------------------------------------------------------- + +void JNICALL ScriptMethodsMissionNamespace::setMissionStatus(JNIEnv * env, jobject self, jlong missionObject, jint status) +{ + if(! env) + return; + + if(! self) + return; + + MissionObject * mo = 0; + if(JavaLibrary::getObject(missionObject, mo)) + { + mo->setStatus(status); + } +} + +//----------------------------------------------------------------------- + +void JNICALL ScriptMethodsMissionNamespace::startMission(JNIEnv * env, jobject self, jlong creature, jlong mission) +{ + if(! env) + return; + + if(! self) + return; + + MissionObject * mo = 0; + if(JavaLibrary::getObject(mission, mo)) + { + CreatureObject * co = 0; + if(JavaLibrary::getObject(creature, co)) + { + co->assignMission(mo); + } + } +} + +//----------------------------------------------------------------------- + diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsMoney.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsMoney.cpp new file mode 100644 index 00000000..542b801e --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsMoney.cpp @@ -0,0 +1,480 @@ +//======================================================================== +// +// ScriptMethodsMoney.cpp - implements script methods dealing with money +// +// copyright 2001 Sony Online Entertainment +// +//======================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "serverGame/CreatureObject.h" +#include "serverGame/GameServer.h" +#include "serverGame/PlayerCreatureController.h" +#include "serverGame/PlayerObject.h" +#include "serverGame/ServerObject.h" +#include "serverGame/ServerWorld.h" +#include "serverNetworkMessages/GetMoneyFromOfflineObjectMessage.h" +#include "sharedLog/Log.h" +#include "sharedObject/NetworkIdManager.h" + +using namespace JNIWrappersNamespace; + + +// ====================================================================== +// ScriptMethodsMoneyNamespace +// ====================================================================== + +namespace ScriptMethodsMoneyNamespace +{ + bool install(); + + jboolean JNICALL transferCashTo (JNIEnv *env, jobject self, jlong source, jlong target, jint amount, jstring successCallbackFunction, jstring failCallbackFunction, jobject callbackData); + jboolean JNICALL transferBankCreditsTo (JNIEnv *env, jobject self, jlong source, jlong target, jint amount, jstring successCallbackFunction, jstring failCallbackFunction, jobject callbackData); + jboolean JNICALL transferBankCreditsToNamedAccount (JNIEnv *env, jobject self, jlong source, jstring target, jint amount, jstring successCallbackFunction, jstring failCallbackFunction, jobject callbackData); + jboolean JNICALL transferBankCreditsFromNamedAccount (JNIEnv *env, jobject self, jstring source, jlong target, jint amount, jstring successCallbackFunction, jstring failCallbackFunction, jobject callbackData); + jboolean JNICALL withdrawCashFromBank (JNIEnv *env, jobject self, jlong source, jint amount, jstring successCallbackFunction, jstring failCallbackFunction, jobject callbackData); + jboolean JNICALL depositCashToBank (JNIEnv *env, jobject self, jlong source, jint amount, jstring successCallbackFunction, jstring failCallbackFunction, jobject callbackData); + void JNICALL depositToGalacticReserve(JNIEnv *env, jobject self, jlong player); + void JNICALL withdrawFromGalacticReserve(JNIEnv *env, jobject self, jlong player); + jboolean JNICALL canAccessGalacticReserve(JNIEnv *env, jobject self, jlong player); + jint JNICALL getCashBalance (JNIEnv *env, jobject self, jlong source); + jint JNICALL getBankBalance (JNIEnv *env, jobject self, jlong source); + jint JNICALL getTotalMoney (JNIEnv *env, jobject self, jlong source); + void JNICALL getMoneyFromOfflineObject(JNIEnv *env, jobject self, jlong sourceObject, jint amount, jstring targetAccount, jstring successCallbackFunction, jstring failCallbackFunction, jobject callbackData); +} + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsMoneyNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsMoneyNamespace::c)} + JF("_transferCashTo", "(JJILjava/lang/String;Ljava/lang/String;Lscript/dictionary;)Z",transferCashTo), + JF("_transferBankCreditsTo", "(JJILjava/lang/String;Ljava/lang/String;Lscript/dictionary;)Z",transferBankCreditsTo), + JF("_transferBankCreditsToNamedAccount", "(JLjava/lang/String;ILjava/lang/String;Ljava/lang/String;Lscript/dictionary;)Z",transferBankCreditsToNamedAccount), + JF("_transferBankCreditsFromNamedAccount", "(Ljava/lang/String;JILjava/lang/String;Ljava/lang/String;Lscript/dictionary;)Z",transferBankCreditsFromNamedAccount), + JF("_withdrawCashFromBank", "(JILjava/lang/String;Ljava/lang/String;Lscript/dictionary;)Z",withdrawCashFromBank), + JF("_depositCashToBank", "(JILjava/lang/String;Ljava/lang/String;Lscript/dictionary;)Z",depositCashToBank), + JF("_depositToGalacticReserve", "(J)V",depositToGalacticReserve), + JF("_withdrawFromGalacticReserve", "(J)V",withdrawFromGalacticReserve), + JF("_canAccessGalacticReserve", "(J)Z",canAccessGalacticReserve), + JF("_getCashBalance", "(J)I",getCashBalance), + JF("_getBankBalance", "(J)I",getBankBalance), + JF("_getTotalMoney", "(J)I",getTotalMoney), + JF("_getMoneyFromOfflineObject", "(JILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Lscript/dictionary;)V",getMoneyFromOfflineObject), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +// ====================================================================== + +jboolean JNICALL ScriptMethodsMoneyNamespace::transferCashTo(JNIEnv *env, jobject self, jlong source, jlong target, jint amount, jstring successCallbackFunction, jstring failCallbackFunction, jobject callbackData) +{ + UNREF(self); + + // Check for missing/invalid parameters + + if (source == 0 || target == 0) + return JNI_FALSE; + if (successCallbackFunction != 0 || failCallbackFunction != 0) + { + if (callbackData == 0) + return JNI_FALSE; + if (!env->IsInstanceOf(callbackData, JavaLibrary::getClsDictionary())) + return JNI_FALSE; + } + + // Convert parameters from Java to C++ + + NetworkId sourceObjId(source); + NetworkId targetObjId(target); + NetworkId ownerOID(JavaLibrary::getNetworkId(*callStaticObjectMethod(JavaLibrary::getClsScriptEntry(), JavaLibrary::getMidScriptEntryGetOwnerContext()))); + std::vector packedDictionary; + std::string successCallback; + std::string failCallback; + + if (callbackData != 0) + { + JavaDictionary const javaDictionary(callbackData); + JavaLibrary::instance()->packDictionary(javaDictionary, packedDictionary); + } + if (successCallbackFunction != 0 && !JavaLibrary::convert(JavaStringParam(successCallbackFunction), successCallback)) + return JNI_FALSE; + if (failCallbackFunction != 0 && !JavaLibrary::convert(JavaStringParam(failCallbackFunction), failCallback)) + return JNI_FALSE; + ServerObject *sourceObj = ServerWorld::findObjectByNetworkId(sourceObjId); + + if (sourceObj == NULL || targetObjId == NetworkId::cms_invalid || ownerOID == NetworkId::cms_invalid) + return JNI_FALSE; + + // Do money transfer (will be forwarded if object is not authoritative) + + sourceObj->scriptTransferCashTo(targetObjId, amount, ownerOID, successCallback, failCallback, packedDictionary); + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsMoneyNamespace::transferBankCreditsTo(JNIEnv *env, jobject self, jlong source, jlong target, jint amount, jstring successCallbackFunction, jstring failCallbackFunction, jobject callbackData) +{ + UNREF(self); + + // Check for missing/invalid parameters + + if (source == 0 || target == 0) + return JNI_FALSE; + if (successCallbackFunction != 0 || failCallbackFunction != 0) + { + if (callbackData == 0) + return JNI_FALSE; + if (!env->IsInstanceOf(callbackData, JavaLibrary::getClsDictionary())) + return JNI_FALSE; + } + + // Convert parameters from Java to C++ + + NetworkId sourceObjId(source); + NetworkId targetObjId(target); + NetworkId ownerOID(JavaLibrary::getNetworkId(*callStaticObjectMethod(JavaLibrary::getClsScriptEntry(), JavaLibrary::getMidScriptEntryGetOwnerContext()))); + std::vector packedDictionary; + std::string successCallback; + std::string failCallback; + + if (callbackData != 0) + { + JavaDictionary const javaDictionary(callbackData); + JavaLibrary::instance()->packDictionary(javaDictionary, packedDictionary); + } + if (successCallbackFunction != 0 && !JavaLibrary::convert(JavaStringParam(successCallbackFunction), successCallback)) + return JNI_FALSE; + if (failCallbackFunction != 0 && !JavaLibrary::convert(JavaStringParam(failCallbackFunction), failCallback)) + return JNI_FALSE; + ServerObject *sourceObj = ServerWorld::findObjectByNetworkId(sourceObjId); + + if (sourceObj == NULL || targetObjId == NetworkId::cms_invalid || ownerOID == NetworkId::cms_invalid) + return JNI_FALSE; + + // Do money transfer (will be forwarded if object is not authoritative) + + sourceObj->scriptTransferBankCreditsTo(targetObjId, amount, ownerOID, successCallback, failCallback, packedDictionary); + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsMoneyNamespace::withdrawCashFromBank (JNIEnv *env, jobject self, jlong source, jint amount, jstring successCallbackFunction, jstring failCallbackFunction, jobject callbackData) +{ + UNREF(self); + + // Check for missing/invalid parameters + + if (source == 0) + return JNI_FALSE; + if (successCallbackFunction != 0 || failCallbackFunction != 0) + { + if (callbackData == 0) + return JNI_FALSE; + if (!env->IsInstanceOf(callbackData, JavaLibrary::getClsDictionary())) + return JNI_FALSE; + } + + // Convert parameters from Java to C++ + + NetworkId sourceObjId(source); + NetworkId ownerOID(JavaLibrary::getNetworkId(*callStaticObjectMethod(JavaLibrary::getClsScriptEntry(), JavaLibrary::getMidScriptEntryGetOwnerContext()))); + std::vector packedDictionary; + std::string successCallback; + std::string failCallback; + + if (callbackData != 0) + { + JavaDictionary const javaDictionary(callbackData); + JavaLibrary::instance()->packDictionary(javaDictionary, packedDictionary); + } + if (successCallbackFunction != 0 && !JavaLibrary::convert(JavaStringParam(successCallbackFunction), successCallback)) + return JNI_FALSE; + if (failCallbackFunction != 0 && !JavaLibrary::convert(JavaStringParam(failCallbackFunction), failCallback)) + return JNI_FALSE; + ServerObject *sourceObj = ServerWorld::findObjectByNetworkId(sourceObjId); + + if (sourceObj == NULL || ownerOID == NetworkId::cms_invalid) + return JNI_FALSE; + + // Do money transfer (will be forwarded if object is not authoritative) + + sourceObj->scriptWithdrawCashFromBank(amount, ownerOID, successCallback, failCallback, packedDictionary); + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsMoneyNamespace::depositCashToBank(JNIEnv *env, jobject self, jlong source, jint amount, jstring successCallbackFunction, jstring failCallbackFunction, jobject callbackData) +{ + UNREF(self); + + // Check for missing/invalid parameters + + if (source == 0) + return JNI_FALSE; + if (successCallbackFunction != 0 || failCallbackFunction != 0) + { + if (callbackData == 0) + return JNI_FALSE; + if (!env->IsInstanceOf(callbackData, JavaLibrary::getClsDictionary())) + return JNI_FALSE; + } + + // Convert parameters from Java to C++ + NetworkId ownerOID(JavaLibrary::getNetworkId(*callStaticObjectMethod(JavaLibrary::getClsScriptEntry(), JavaLibrary::getMidScriptEntryGetOwnerContext()))); + if (ownerOID == NetworkId::cms_invalid) + return JNI_FALSE; + + std::string successCallback; + if (successCallbackFunction != 0 && !JavaLibrary::convert(JavaStringParam(successCallbackFunction), successCallback)) + return JNI_FALSE; + + std::string failCallback; + if (failCallbackFunction != 0 && !JavaLibrary::convert(JavaStringParam(failCallbackFunction), failCallback)) + return JNI_FALSE; + + ServerObject *sourceObj = NULL; + if (!JavaLibrary::getObject(source, sourceObj)) + return JNI_FALSE; + + JavaDictionary callbackDictionary(callbackData); + callbackDictionary.serialize(); + + // Do money transfer (will be forwarded if object is not authoritative) + sourceObj->scriptDepositCashToBank(amount, ownerOID, successCallback, failCallback, + callbackDictionary.getSerializedData()); + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsMoneyNamespace::depositToGalacticReserve(JNIEnv *env, jobject self, jlong player) +{ + CreatureObject * objPlayer = NULL; + if (!JavaLibrary::getObject(player, objPlayer) || !objPlayer) + return; + + PlayerObject * const playerObject = PlayerCreatureController::getPlayerObject(objPlayer); + if (!playerObject) + return; + + playerObject->depositToGalacticReserve(false); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsMoneyNamespace::withdrawFromGalacticReserve(JNIEnv *env, jobject self, jlong player) +{ + CreatureObject * objPlayer = NULL; + if (!JavaLibrary::getObject(player, objPlayer) || !objPlayer) + return; + + PlayerObject * const playerObject = PlayerCreatureController::getPlayerObject(objPlayer); + if (!playerObject) + return; + + playerObject->withdrawFromGalacticReserve(); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsMoneyNamespace::canAccessGalacticReserve(JNIEnv *env, jobject self, jlong player) +{ + CreatureObject * objPlayer = NULL; + if (!JavaLibrary::getObject(player, objPlayer) || !objPlayer) + return JNI_FALSE; + + PlayerObject * const playerObject = PlayerCreatureController::getPlayerObject(objPlayer); + if (!playerObject) + return JNI_FALSE; + + Vector const positionW = objPlayer->getPosition_w(); + return PlayerObject::canAccessGalacticReserve(positionW.x, positionW.z); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsMoneyNamespace::getCashBalance(JNIEnv *env, jobject self, jlong source) +{ + ServerObject * sourceObj = 0; + if (!JavaLibrary::getObject(source, sourceObj)) + return JNI_FALSE; + + return sourceObj->getCashBalance(); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsMoneyNamespace::getBankBalance(JNIEnv *env, jobject self, jlong source) +{ + ServerObject * sourceObj = 0; + if (!JavaLibrary::getObject(source, sourceObj)) + return JNI_FALSE; + + return sourceObj->getBankBalance(); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsMoneyNamespace::getTotalMoney(JNIEnv *env, jobject self, jlong source) +{ + ServerObject * sourceObj = 0; + if (!JavaLibrary::getObject(source, sourceObj)) + return JNI_FALSE; + + return sourceObj->getTotalMoney(); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsMoneyNamespace::transferBankCreditsToNamedAccount(JNIEnv *env, jobject self, jlong source, jstring target, jint amount, jstring successCallbackFunction, jstring failCallbackFunction, jobject callbackData) +{ + UNREF(self); + + // Check for missing/invalid parameters + + if (source == 0 || target == 0) + return JNI_FALSE; + if (successCallbackFunction != 0 || failCallbackFunction != 0) + { + // if you specify a callback, data must be valid + if(callbackData == 0) + return JNI_FALSE; + if (!env->IsInstanceOf(callbackData, JavaLibrary::getClsDictionary())) + return JNI_FALSE; + } + + // Convert parameters from Java to C++ + + NetworkId sourceObjId(source); + std::string targetString; + NetworkId ownerOID(JavaLibrary::getNetworkId(*callStaticObjectMethod(JavaLibrary::getClsScriptEntry(), JavaLibrary::getMidScriptEntryGetOwnerContext()))); + std::vector packedDictionary; + std::string successCallback; + std::string failCallback; + + if (callbackData != 0) + { + JavaDictionary const javaDictionary(callbackData); + JavaLibrary::instance()->packDictionary(javaDictionary, packedDictionary); + } + if (successCallbackFunction != 0 && !JavaLibrary::convert(JavaStringParam(successCallbackFunction), successCallback)) + return JNI_FALSE; + if (failCallbackFunction != 0 && !JavaLibrary::convert(JavaStringParam(failCallbackFunction), failCallback)) + return JNI_FALSE; + if (!JavaLibrary::convert(JavaStringParam(target), targetString)) + return JNI_FALSE; + ServerObject *sourceObj = ServerWorld::findObjectByNetworkId(sourceObjId); + + if (sourceObj == NULL || targetString.size() == 0 || ownerOID == NetworkId::cms_invalid) + return JNI_FALSE; + + // Do money transfer (will be forwarded if object is not authoritative) + + sourceObj->scriptTransferBankCreditsTo(targetString, amount, ownerOID, successCallback, failCallback, packedDictionary); + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsMoneyNamespace::transferBankCreditsFromNamedAccount(JNIEnv *env, jobject self, jstring source, jlong target, jint amount, jstring successCallbackFunction, jstring failCallbackFunction, jobject callbackData) +{ + UNREF(self); + + // Check for missing/invalid parameters + + if (source == 0 || target == 0) + return JNI_FALSE; + if (successCallbackFunction != 0 || failCallbackFunction != 0) + { + // if you specify a callback, data must be valid + if(callbackData == 0) + return JNI_FALSE; + if (!env->IsInstanceOf(callbackData, JavaLibrary::getClsDictionary())) + return JNI_FALSE; + } + + // Convert parameters from Java to C++ + + std::string sourceString; + NetworkId targetObjId(target); + NetworkId ownerOID(JavaLibrary::getNetworkId(*callStaticObjectMethod(JavaLibrary::getClsScriptEntry(), JavaLibrary::getMidScriptEntryGetOwnerContext()))); + std::vector packedDictionary; + std::string successCallback; + std::string failCallback; + + if (callbackData != 0) + { + JavaDictionary const javaDictionary(callbackData); + JavaLibrary::instance()->packDictionary(javaDictionary, packedDictionary); + } + if (successCallbackFunction != 0 && !JavaLibrary::convert(JavaStringParam(successCallbackFunction), successCallback)) + return JNI_FALSE; + if (failCallbackFunction != 0 && !JavaLibrary::convert(JavaStringParam(failCallbackFunction), failCallback)) + return JNI_FALSE; + if (!JavaLibrary::convert(JavaStringParam(source), sourceString)) + return JNI_FALSE; + ServerObject *targetObj = ServerWorld::findObjectByNetworkId(targetObjId); + + if (targetObj == NULL || sourceString.size() == 0 || ownerOID == NetworkId::cms_invalid) + return JNI_FALSE; + + // Do money transfer (will be forwarded if object is not authoritative) + + targetObj->scriptTransferBankCreditsFrom(sourceString, amount, ownerOID, successCallback, failCallback, packedDictionary); + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsMoneyNamespace::getMoneyFromOfflineObject(JNIEnv *env, jobject self, jlong sourceObject, jint amount, jstring targetAccount, jstring successCallbackFunction, jstring failCallbackFunction, jobject callbackData) +{ + // Convert parameters from Java types to C types + DEBUG_REPORT_LOG(true,("getMoneyFromOfflineObject\n")); + + NetworkId const sourceObjectC(sourceObject); + NetworkId const replyToC(JavaLibrary::getNetworkId(*callStaticObjectMethod(JavaLibrary::getClsScriptEntry(), JavaLibrary::getMidScriptEntryGetOwnerContext()))); + std::string targetAccountC; + std::string successCallbackFunctionC; + std::string failCallbackFunctionC; + std::vector callbackDataC; + + if (targetAccount == 0 || !JavaLibrary::convert(JavaStringParam(targetAccount), targetAccountC)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("getMoneyFromOfflineObject: targetAccount was not specified or could not be converted to a string.")); + return; + } + if (successCallbackFunction != 0 && !JavaLibrary::convert(JavaStringParam(successCallbackFunction), successCallbackFunctionC)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("getMoneyFromOfflineObject: successCallbackFunction could not be converted to a string.")); + return; + } + if (failCallbackFunction != 0 && !JavaLibrary::convert(JavaStringParam(failCallbackFunction), failCallbackFunctionC)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("getMoneyFromOfflineObject: failCallbackFunction could not be converted to a string.")); + return; + } + if (callbackData != 0) + { + JavaDictionary const javaDictionary(callbackData); + JavaLibrary::instance()->packDictionary(javaDictionary, callbackDataC); + } + + // Do the money grab + GetMoneyFromOfflineObjectMessage msg(sourceObjectC, amount, replyToC, successCallbackFunctionC, failCallbackFunctionC, callbackDataC, false); + GameServer::getInstance().sendToDatabaseServer(msg); + + LOG("CustomerService", ("Money: offline transfer from %s to %s, amount %i", sourceObjectC.getValueString().c_str(), targetAccountC.c_str(), amount)); +} + +// ====================================================================== diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsMount.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsMount.cpp new file mode 100644 index 00000000..4f0e9c9f --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsMount.cpp @@ -0,0 +1,462 @@ +// ====================================================================== +// +// ScriptMethodsMount.cpp +// Copyright 2003, Sony Online Entertainment, Inc. +// All rights reserved. +// +// ====================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "serverGame/ConfigServerGame.h" +#include "serverGame/ContainerInterface.h" +#include "serverGame/CreatureObject.h" +#include "serverGame/GameServer.h" +#include "serverGame/ServerObjectTemplate.h" +#include "sharedGame/MountValidScaleRangeTable.h" +#include "sharedLog/Log.h" +#include "sharedObject/NetworkIdManager.h" +#include "sharedObject/ObjectTemplateList.h" + +using namespace JNIWrappersNamespace; + +#define LOCAL_LOG_CHANNEL "mount-script-interface" + + +// ====================================================================== +// ScriptMethodsMountNamespace +// ====================================================================== + +namespace ScriptMethodsMountNamespace +{ + bool install(); + + jboolean JNICALL getMountsEnabled(JNIEnv *env, jobject self); + jboolean JNICALL getMountsMultiSeaterEnabled(JNIEnv *env, jobject self); + jboolean JNICALL makePetMountable(JNIEnv *env, jobject self, jlong petId); + void JNICALL updateMountWearableVisuals(JNIEnv *env, jobject self, jlong mountId); + jboolean JNICALL mountCreature(JNIEnv *env, jobject self, jlong riderId, jlong mountId); + void JNICALL dismountCreature(JNIEnv *env, jobject self, jlong riderId); + jlong JNICALL getMountId(JNIEnv *env, jobject self, jlong riderId); + jlong JNICALL getRiderId(JNIEnv *env, jobject self, jlong mountId); + jint JNICALL couldPetBeMadeMountable(JNIEnv *env, jobject self, jlong petId); + jint JNICALL couldObjectTemplateBeMadeMountable(JNIEnv *env, jobject self, jstring serverObjectTemplateName, jfloat objectScale); + void JNICALL makeContainerStateInconsistentTestOnly(JNIEnv *env, jobject self, jlong containedObjectId); + jboolean JNICALL doesMountHaveRoom(JNIEnv * env, jobject self, jlong mountId); +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsMountNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsMountNamespace::c)} + JF("getMountsEnabled", "()Z", getMountsEnabled), + JF("getMountsMultiSeaterEnabled", "()Z", getMountsMultiSeaterEnabled), + JF("_makePetMountable", "(J)Z", makePetMountable), + JF("_updateMountWearableVisuals", "(J)V", updateMountWearableVisuals), + JF("_mountCreature", "(JJ)Z", mountCreature), + JF("_dismountCreature", "(J)V", dismountCreature), + JF("_getMountId", "(J)J", getMountId), + JF("_getRiderId", "(J)J", getRiderId), + JF("_couldPetBeMadeMountable", "(J)I", couldPetBeMadeMountable), + JF("couldObjectTemplateBeMadeMountable", "(Ljava/lang/String;F)I", couldObjectTemplateBeMadeMountable), + JF("_makeContainerStateInconsistentTestOnly", "(J)V", makeContainerStateInconsistentTestOnly), + JF("_doesMountHaveRoom", "(J)Z", doesMountHaveRoom), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +// ====================================================================== + +jboolean JNICALL ScriptMethodsMountNamespace::getMountsEnabled(JNIEnv *env, jobject self) +{ + UNREF(env); + UNREF(self); + return static_cast(ConfigServerGame::getMountsEnabled() ? JNI_TRUE : JNI_FALSE); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsMountNamespace::getMountsMultiSeaterEnabled(JNIEnv * /*env*/, jobject /*self*/) +{ + LOG(LOCAL_LOG_CHANNEL, ("JavaLibrary::getMountsMultiSeaterEnabled(): is a deprecated call.")); + + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsMountNamespace::makePetMountable(JNIEnv *env, jobject self, jlong petId) +{ + UNREF(self); + + //-- Ignore calls if mounts are disabled. + if (!ConfigServerGame::getMountsEnabled()) + { + LOG(LOCAL_LOG_CHANNEL, ("JavaLibrary::makePetMountable(): ignoring call, [GameServer] mountsEnabled is false.")); + return JNI_FALSE; + } + + //-- Get CreatureObject for pet. + CreatureObject *const petObject = JavaLibrary::getCreatureThrow(env, petId, "makePetMountable(): error in petId arg"); + if (!petObject) + return JNI_FALSE; + + //-- Check if creature can be converted to a mount. + if (petObject->getMountabilityStatus() != static_cast(MountValidScaleRangeTable::MS_creatureMountable)) + { + char buffer[512]; + IGNORE_RETURN(snprintf(buffer, sizeof(buffer) - 1, "makePetMountable(): creature id=[%s],object template=[%s] cannot be made mountable.", petObject->getNetworkId().getValueString().c_str(), petObject->getObjectTemplateName())); + buffer[sizeof(buffer) - 1] = '\0'; + JavaLibrary::throwInternalScriptError(buffer); + LOG(LOCAL_LOG_CHANNEL, (buffer)); + return JNI_FALSE; + } + + //-- Check if creature is already mountable. + if (petObject->isMountable()) + { + char buffer[512]; + IGNORE_RETURN(snprintf(buffer, sizeof(buffer) - 1, "makePetMountable(): creature id=[%s],object template=[%s] already is mountable.", petObject->getNetworkId().getValueString().c_str(), petObject->getObjectTemplateName())); + buffer[sizeof(buffer) - 1] = '\0'; + JavaLibrary::throwInternalScriptError(buffer); + LOG(LOCAL_LOG_CHANNEL, (buffer)); + return JNI_FALSE; + } + + //-- Do it. + petObject->makePetMountable(); + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsMountNamespace::updateMountWearableVisuals(JNIEnv *env, jobject self, jlong mountId) +{ + UNREF(env); + UNREF(self); + UNREF(mountId); + + LOG(LOCAL_LOG_CHANNEL, ("updateMountWearableVisuals called.")); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsMountNamespace::mountCreature(JNIEnv *env, jobject self, jlong riderId, jlong mountId) +{ + UNREF(self); + + //-- Ignore calls if mounts are disabled. + if (!ConfigServerGame::getMountsEnabled()) + { + LOG(LOCAL_LOG_CHANNEL, ("JavaLibrary::mountCreature(): ignoring call, [GameServer] mountsEnabled is false.")); + return JNI_FALSE; + } + + //-- Get the rider object. + CreatureObject *const riderObject = JavaLibrary::getCreatureThrow(env, riderId, "mountCreature(): error in riderId arg"); + if (!riderObject) + return JNI_FALSE; + + //-- Get the mount object. + CreatureObject *const mountObject = JavaLibrary::getCreatureThrow(env, mountId, "mountCreature(): error in mountId arg"); + if (!mountObject) + return JNI_FALSE; + + //-- Ensure that the rider is not already riding a mount. + if (riderObject->getState(States::RidingMount)) + { + char buffer[512]; + + IGNORE_RETURN(snprintf(buffer, sizeof(buffer) - 1, "JavaLibrary::mountCreature(): rider id=[%s] is already riding a mount.", riderObject->getNetworkId().getValueString().c_str())); + buffer[sizeof(buffer) - 1] = '\0'; + JavaLibrary::throwInternalScriptError(buffer); + LOG(LOCAL_LOG_CHANNEL, (buffer)); + return JNI_FALSE; + } + + //-- Check if mount is mountable. + if (!mountObject->isMountable()) + { + char buffer[512]; + IGNORE_RETURN(snprintf(buffer, sizeof(buffer) - 1, "mountCreature(): creature id=[%s],object template=[%s] is not a mount.", mountObject->getNetworkId().getValueString().c_str(), mountObject->getObjectTemplateName())); + buffer[sizeof(buffer) - 1] = '\0'; + JavaLibrary::throwInternalScriptError(buffer); + LOG(LOCAL_LOG_CHANNEL, (buffer)); + return JNI_FALSE; + } + + //-- Check if mount has room; + if (mountObject->isMountableAndHasRoomForAnother()) + { + //-- Have the rider mount the creature. + bool const mountResult = riderObject->mountCreature(*mountObject); + return static_cast(mountResult); + } + + return JNI_FALSE; +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsMountNamespace::dismountCreature(JNIEnv *env, jobject self, jlong riderId) +{ + UNREF(env); + UNREF(self); + UNREF(riderId); + + //-- Ignore calls if mounts are disabled. + if (!ConfigServerGame::getMountsEnabled()) + { + LOG(LOCAL_LOG_CHANNEL, ("JavaLibrary::dismountCreature(): ignoring call, [GameServer] mountsEnabled is false.")); + return; + } + + //-- Get the rider. + CreatureObject *const riderObject = JavaLibrary::getCreatureThrow(env, riderId, "getMountId(): error in riderId arg"); + if (!riderObject) + return; + + //-- Ensure the rider is on a mount. + if (!riderObject->getState(States::RidingMount)) + { + LOG(LOCAL_LOG_CHANNEL, ("JavaLibrary::dismountCreature(): rider id=[%s] is not riding a mount.", riderObject->getNetworkId().getValueString().c_str())); + return; + } + + //-- Get the mount. + CreatureObject *const mountObject = riderObject->getMountedCreature(); + if (!mountObject) + { + LOG(LOCAL_LOG_CHANNEL, ("JavaLibrary::dismountCreature(): server id=[%d],rider id=[%s] has RidingMount state but CreatureObject::getMountedCreature() returns NULL, skipping dismount.", GameServer::getInstance().getProcessId(), riderObject->getNetworkId().getValueString().c_str())); + return; + } + + //-- Detach the rider from the mount. + IGNORE_RETURN(mountObject->detachRider(riderObject->getNetworkId())); +} + +// ---------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsMountNamespace::getMountId(JNIEnv *env, jobject self, jlong riderId) +{ + UNREF(env); + UNREF(self); + + //-- Ignore calls if mounts are disabled. + if (!ConfigServerGame::getMountsEnabled()) + return 0; + + //-- Get the rider object. + bool const throwIfNotOnServer = false; + CreatureObject const *const riderObject = JavaLibrary::getCreatureThrow(env, riderId, "getMountId(): error in riderId arg", throwIfNotOnServer); + if (!riderObject) + return 0; + + CreatureObject const *const mountedCreature = riderObject->getMountedCreature(); + NetworkId const mountNetworkId = (mountedCreature ? mountedCreature->getNetworkId() : NetworkId::cms_invalid); + + return mountNetworkId.getValue(); +} + +// ---------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsMountNamespace::getRiderId(JNIEnv *env, jobject self, jlong mountId) +{ + UNREF(env); + UNREF(self); + + //-- Ignore calls if mounts are disabled. + if (!ConfigServerGame::getMountsEnabled()) + return 0; + + //-- Get the rider object. + bool const throwIfNotOnServer = false; + CreatureObject const *const mountObject = JavaLibrary::getCreatureThrow(env, mountId, "getRiderId(): error in mountId arg", throwIfNotOnServer); + if (!mountObject) + return 0; + + CreatureObject const *const riderObject = mountObject->getPrimaryMountingRider(); + NetworkId const riderNetworkId = (riderObject ? riderObject->getNetworkId() : NetworkId::cms_invalid); + + return riderNetworkId.getValue(); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsMountNamespace::couldPetBeMadeMountable(JNIEnv *env, jobject self, jlong petId) +{ + UNREF(env); + UNREF(self); + UNREF(petId); + + //-- Ignore calls if mounts are disabled. + if (!ConfigServerGame::getMountsEnabled()) + { + LOG(LOCAL_LOG_CHANNEL, ("JavaLibrary::couldPetBeMadeMountable(): ignoring call, [GameServer] mountsEnabled is false.")); + return static_cast(MountValidScaleRangeTable::MS_speciesUnmountable); + } + + //-- Get CreatureObject for pet. + CreatureObject const *const petObject = JavaLibrary::getCreatureThrow(env, petId, "couldPetBeMadeMountable(): error in petId arg"); + if (!petObject) + return static_cast(MountValidScaleRangeTable::MS_speciesUnmountable); + + //-- Check if creature can be converted to a mount. + return static_cast(petObject->getMountabilityStatus()); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsMountNamespace::couldObjectTemplateBeMadeMountable(JNIEnv *env, jobject self, jstring objectTemplateName, jfloat objectScale) +{ + UNREF(env); + UNREF(self); + + //-- Ignore calls if mounts are disabled. + if (!ConfigServerGame::getMountsEnabled()) + { + LOG(LOCAL_LOG_CHANNEL, ("JavaLibrary::couldObjectTemplateBeMadeMountable(): ignoring call, [GameServer] mountsEnabled is false.")); + return static_cast(MountValidScaleRangeTable::MS_speciesUnmountable); + } + + //-- Convert objectTemplateName from jstring to something else. + JavaStringParam objectTemplateNameParam(objectTemplateName); + std::string objectTemplateNameNarrow; + IGNORE_RETURN(JavaLibrary::convert(objectTemplateNameParam, objectTemplateNameNarrow)); + + //-- Get the appearance name. + //... first grab the server object template name. + ObjectTemplate const *const objectTemplate = ObjectTemplateList::fetch(objectTemplateNameNarrow); + if (!objectTemplate) + { + LOG(LOCAL_LOG_CHANNEL, ("JavaLibrary::couldObjectTemplateBeMadeMountable(): object template [%s] could not be fetched.", objectTemplateNameNarrow.c_str())); + return static_cast(MountValidScaleRangeTable::MS_speciesUnmountable); + } + + //... grab the shared object template name from it. + ServerObjectTemplate const *const serverObjectTemplate = dynamic_cast(objectTemplate); + if (!serverObjectTemplate) + { + LOG(LOCAL_LOG_CHANNEL, ("JavaLibrary::couldObjectTemplateBeMadeMountable(): object template [%s] is not a ServerObjectTemplate.", objectTemplateNameNarrow.c_str())); + objectTemplate->releaseReference(); + return static_cast(MountValidScaleRangeTable::MS_speciesUnmountable); + } + + std::string const &sharedObjectTemplateName = serverObjectTemplate->getSharedTemplate(); + + //... get the shared object template. + ObjectTemplate const *const sharedObjectTemplateBase = ObjectTemplateList::fetch(sharedObjectTemplateName); + + if (!sharedObjectTemplateBase) + { + LOG(LOCAL_LOG_CHANNEL, ("JavaLibrary::couldObjectTemplateBeMadeMountable(): could not load shared object template [%s].", sharedObjectTemplateName.c_str())); + objectTemplate->releaseReference(); + return static_cast(MountValidScaleRangeTable::MS_speciesUnmountable); + } + + SharedObjectTemplate const *const sharedObjectTemplate = sharedObjectTemplateBase->asSharedObjectTemplate(); + if (!sharedObjectTemplate) + { + LOG(LOCAL_LOG_CHANNEL, ("JavaLibrary::couldObjectTemplateBeMadeMountable(): shared object template [%s] is not derived from class SharedObjectTemplate.", sharedObjectTemplateName.c_str())); + objectTemplate->releaseReference(); + sharedObjectTemplateBase->releaseReference(); + return static_cast(MountValidScaleRangeTable::MS_speciesUnmountable); + } + + //... get the appearance name. + TemporaryCrcString appearanceTemplateName(sharedObjectTemplate->getAppearanceFilename().c_str(), true); + + //-- Check if creature can be converted to a mount. + int const saddleCapacity = 1; + MountValidScaleRangeTable::MountabilityStatus const msResult = MountValidScaleRangeTable::doesCreatureSupportScaleAndSaddleCapacity(appearanceTemplateName, static_cast(objectScale), saddleCapacity); + + //-- Release resources. + objectTemplate->releaseReference(); + sharedObjectTemplateBase->releaseReference(); + + //-- Return result. + return static_cast(msResult); +} + +// ---------------------------------------------------------------------- + +void JNICALL JNICALL ScriptMethodsMountNamespace::makeContainerStateInconsistentTestOnly(JNIEnv *env, jobject self, jlong containedObjectId) +{ + //-- Get the ServerObject from the object id. + if (!containedObjectId) + { + LOG("script-bug", ("makeContainerStateInconsistentTestOnly(): containedObjectId is NULL")); + return; + } + + NetworkId networkId(containedObjectId); + if (networkId == NetworkId::cms_invalid) + { + LOG("script-bug", ("makeContainerStateInconsistentTestOnly(): containedObjectId is invalid")); + return; + } + + Object *const containedObject = NetworkIdManager::getObjectById(networkId); + if (!containedObject) + { + LOG("script-bug", ("makeContainerStateInconsistentTestOnly(): containedObjectId [%s] is not on this server", networkId.getValueString().c_str())); + return; + } + + if (!containedObject->isAuthoritative()) + { + LOG("script-bug", ("makeContainerStateInconsistentTestOnly(): containedObjectId [%s] is not authoritative on this server", networkId.getValueString().c_str())); + return; + } + + //-- Get the container. + Object* containerObject = ContainerInterface::getContainedByObject(*containedObject); + if (!containerObject) + { + LOG("script-bug", ("makeContainerStateInconsistentTestOnly(): containedObjectId [%s] is not contained by anything", networkId.getValueString().c_str())); + return; + } + + Container* container = ContainerInterface::getContainer(*containerObject); + if (!container) + { + LOG("script-bug", ("makeContainerStateInconsistentTestOnly(): containerObject [%s] returned a NULL container", containerObject->getNetworkId().getValueString().c_str())); + return; + } + + //-- Break the containment relationship. + container->internalItemRemoved(*containedObject); + LOG("script-bug", ("makeContainerStateInconsistentTestOnly(): broke containment relationship for containedObjectId [%s], container [%s] now has invalid information", networkId.getValueString().c_str(), containerObject->getNetworkId().getValueString().c_str())); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsMountNamespace::doesMountHaveRoom(JNIEnv * env, jobject self, jlong mountId) +{ + //-- Ignore calls if mounts are disabled. + if (!ConfigServerGame::getMountsEnabled()) + { + return JNI_FALSE; + } + + //-- Get the rider object. + bool const throwIfNotOnServer = false; + CreatureObject const * const mountObject = JavaLibrary::getCreatureThrow(env, mountId, "getRiderId(): error in mountId arg", throwIfNotOnServer); + + if (mountObject == 0) + { + return JNI_FALSE; + } + + return static_cast(mountObject->isMountableAndHasRoomForAnother()); +} + +// ====================================================================== diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsNewbieTutorial.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsNewbieTutorial.cpp new file mode 100644 index 00000000..7e54e09a --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsNewbieTutorial.cpp @@ -0,0 +1,516 @@ +// ====================================================================== +// +// ScriptMethodsNewbieTutorial.cpp +// asommers +// +// copyright 2002, sony online entertainment +// +// ====================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "serverGame/ConfigServerGame.h" +#include "serverGame/GameServer.h" +#include "serverGame/NewbieTutorial.h" +#include "serverGame/ServerObject.h" +#include "serverGame/ServerUniverse.h" +#include "sharedNetworkMessages/MessageQueueGenericValueType.h" +#include "sharedNetworkMessages/NewbieTutorialEnableHudElement.h" +#include "sharedNetworkMessages/NewbieTutorialEnableInterfaceElement.h" +#include "sharedNetworkMessages/NewbieTutorialHighlightUIElement.h" +#include "sharedNetworkMessages/NewbieTutorialSetToolbarElement.h" +#include "sharedNetworkMessages/NewbieTutorialRequest.h" +#include "sharedObject/Controller.h" +#include "sharedUtility/StartingLocationData.h" +#include "sharedUtility/StartingLocationManager.h" + +#include + +using namespace JNIWrappersNamespace; + + +// ====================================================================== + +namespace ScriptMethodsNewbieTutorialNamespace +{ + void sendMessageToPlayer (Object & player, MessageQueue::Data * msg, int messageType) + { + Controller * const controller = player.getController (); + + if (controller) + { + controller->appendMessage( + messageType, + 0.0f, + msg, + GameControllerMessageFlags::SEND | + GameControllerMessageFlags::RELIABLE | + GameControllerMessageFlags::DEST_AUTH_CLIENT + ); + } + else + { + WARNING (true, ("newbieTutorialSendStartingLocationsToPlayer: bad controller")); + delete & msg; + } + } + + bool install(); + + jboolean JNICALL newbieTutorialRequest (JNIEnv* env, jobject self, jlong player, jstring request); + jboolean JNICALL newbieTutorialEnableHudElement (JNIEnv* env, jobject self, jlong player, jstring name, jboolean enable, jfloat blinkTime); + jboolean JNICALL newbieTutorialEnableInterfaceElement (JNIEnv* env, jobject self, jlong player, jstring name, jboolean enable); + jboolean JNICALL newbieTutorialSetToolbarElement (JNIEnv* env, jobject self, jlong player, jint slot, jstring commandName); + jboolean JNICALL newbieTutorialSetToolbarElementObject (JNIEnv* env, jobject self, jlong player, jint slot, jlong object); + jboolean JNICALL newbieTutorialHighlightUIElement (JNIEnv* env, jobject self, jlong player, jstring widgetPath, jfloat time); + void JNICALL newbieTutorialSendStartingLocationsToPlayer (JNIEnv* env, jobject self, jlong player, jobjectArray locations); + void JNICALL newbieTutorialSendStartingLocationSelectionResult (JNIEnv* env, jobject self, jlong player, jstring name, jboolean result); + jobjectArray JNICALL getStartingLocations(JNIEnv* env, jobject self); + jboolean JNICALL isStartingLocationAvailable(JNIEnv* env, jobject self, jstring name); + jobject JNICALL getStartingLocationInfo(JNIEnv* env, jobject self, jstring name); + jboolean JNICALL isInTutorialArea(JNIEnv* env, jobject self, jlong object); +} + +using namespace ScriptMethodsNewbieTutorialNamespace; + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsNewbieTutorialNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsNewbieTutorialNamespace::c)} + JF("_newbieTutorialRequest", "(JLjava/lang/String;)Z", newbieTutorialRequest), + JF("_newbieTutorialEnableHudElement", "(JLjava/lang/String;ZF)Z", newbieTutorialEnableHudElement), + JF("_newbieTutorialEnableInterfaceElement", "(JLjava/lang/String;Z)Z", newbieTutorialEnableInterfaceElement), + JF("_newbieTutorialSetToolbarElement", "(JILjava/lang/String;)Z", newbieTutorialSetToolbarElement), + JF("_newbieTutorialSetToolbarElement", "(JIJ)Z", newbieTutorialSetToolbarElementObject), + JF("_newbieTutorialHighlightUIElement", "(JLjava/lang/String;F)Z", newbieTutorialHighlightUIElement), + JF("_newbieTutorialSendStartingLocationsToPlayer", "(J[Ljava/lang/String;)V", newbieTutorialSendStartingLocationsToPlayer), + JF("_newbieTutorialSendStartingLocationSelectionResult", "(JLjava/lang/String;Z)V", newbieTutorialSendStartingLocationSelectionResult), + JF("getStartingLocations", "()[Ljava/lang/String;", getStartingLocations), + JF("isStartingLocationAvailable", "(Ljava/lang/String;)Z", isStartingLocationAvailable), + JF("getStartingLocationInfo", "(Ljava/lang/String;)Lscript/location;", getStartingLocationInfo), + JF("_isInTutorialArea", "(J)Z", isInTutorialArea), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +//---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsNewbieTutorialNamespace::newbieTutorialRequest (JNIEnv* /*env*/, jobject /*self*/, jlong jobject_player, jstring jstring_request) +{ + //-- get the player object + ServerObject* player = 0; + if (!JavaLibrary::getObject (jobject_player, player)) + { + DEBUG_REPORT_LOG_PRINT (true, ("newbieTutorialRequest (): DB could not find player object")); + return JNI_FALSE; + } + + //-- get the client associated with the player + Client* const client = player->getClient (); + if (!client) + { + DEBUG_REPORT_LOG_PRINT (true, ("newbieTutorialRequest (): PB could get the player's client object")); + return JNI_FALSE; + } + + //-- get the request string + JavaStringParam javaStringParam_request (jstring_request); + std::string request; + if (!JavaLibrary::convert (javaStringParam_request, request)) + { + DEBUG_WARNING (true, ("newbieTutorialRequest (): DB failed to convert parameter 2 (request) to string")); + return JNI_FALSE; + } + + //-- send the message to the client + NewbieTutorialRequest const msg(request); + client->send(msg, true); + + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsNewbieTutorialNamespace::newbieTutorialEnableHudElement (JNIEnv* env, jobject self, jlong jobject_player, jstring jstring_name, jboolean jboolean_enable, jfloat jfloat_blinkTime) +{ + //-- get the player object + ServerObject* player = 0; + if (!JavaLibrary::getObject (jobject_player, player)) + { + DEBUG_REPORT_LOG_PRINT (true, ("newbieTutorialEnableHudElement (): DB could not find player object")); + return JNI_FALSE; + } + + //-- get the client associated with the player + Client* const client = player->getClient (); + if (!client) + { + DEBUG_REPORT_LOG_PRINT (true, ("newbieTutorialEnableHudElement (): PB could get the player's client object")); + return JNI_FALSE; + } + + //-- get the request string + JavaStringParam javaStringParam_name (jstring_name); + std::string name; + if (!JavaLibrary::convert (javaStringParam_name, name)) + { + DEBUG_WARNING (true, ("newbieTutorialEnableHudElement (): DB failed to convert parameter 2 (name) to string")); + return JNI_FALSE; + } + + //-- send the message to the client + NewbieTutorialEnableHudElement const msg(name, jboolean_enable == JNI_TRUE, jfloat_blinkTime); + client->send(msg, true); + + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsNewbieTutorialNamespace::newbieTutorialEnableInterfaceElement (JNIEnv* env, jobject self, jlong jobject_player, jstring jstring_name, jboolean jboolean_enable) +{ + //-- get the player object + ServerObject* player = 0; + if (!JavaLibrary::getObject (jobject_player, player)) + { + DEBUG_REPORT_LOG_PRINT (true, ("newbieTutorialEnableInterfaceElement (): DB could not find player object")); + return JNI_FALSE; + } + + //-- get the client associated with the player + Client* const client = player->getClient (); + if (!client) + { + DEBUG_REPORT_LOG_PRINT (true, ("newbieTutorialEnableInterfaceElement (): PB could get the player's client object")); + return JNI_FALSE; + } + + //-- get the request string + JavaStringParam javaStringParam_name (jstring_name); + std::string name; + if (!JavaLibrary::convert (javaStringParam_name, name)) + { + DEBUG_WARNING (true, ("newbieTutorialEnableInterfaceElement (): DB failed to convert parameter 2 (name) to string")); + return JNI_FALSE; + } + + //-- send the message to the client + NewbieTutorialEnableInterfaceElement const msg(name, jboolean_enable == JNI_TRUE); + client->send(msg, true); + + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsNewbieTutorialNamespace::newbieTutorialSetToolbarElement (JNIEnv* env, jobject self, jlong jobject_player, jint slot, jstring jstring_commandName) +{ + //-- get the player object + ServerObject* player = 0; + if (!JavaLibrary::getObject (jobject_player, player)) + { + DEBUG_REPORT_LOG_PRINT (true, ("newbieTutorialSetToolbarElement (): DB could not find player object")); + return JNI_FALSE; + } + + //-- get the client associated with the player + Client* const client = player->getClient (); + if (!client) + { + DEBUG_REPORT_LOG_PRINT (true, ("newbieTutorialSetToolbarElement (): PB could get the player's client object")); + return JNI_FALSE; + } + + //-- get the command name string + JavaStringParam javaStringParam_commandName (jstring_commandName); + std::string commandName; + if (!JavaLibrary::convert (javaStringParam_commandName, commandName)) + { + DEBUG_WARNING (true, ("newbieTutorialSetToolbarElement (): DB failed to convert parameter 3 (commandName) to string")); + return JNI_FALSE; + } + + //-- send the message to the client + NewbieTutorialSetToolbarElement const msg(slot, commandName); + client->send(msg, true); + + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsNewbieTutorialNamespace::newbieTutorialSetToolbarElementObject (JNIEnv* env, jobject self, jlong jobject_player, jint slot, jlong object) +{ + //-- get the player object + ServerObject* player = 0; + if (!JavaLibrary::getObject (jobject_player, player)) + { + DEBUG_REPORT_LOG_PRINT (true, ("newbieTutorialSetToolbarElement (): DB could not find player object")); + return JNI_FALSE; + } + + //-- get the client associated with the player + Client* const client = player->getClient (); + if (!client) + { + DEBUG_REPORT_LOG_PRINT (true, ("newbieTutorialSetToolbarElement (): PB could get the player's client object")); + return JNI_FALSE; + } + + //-- send the message to the client + NewbieTutorialSetToolbarElement const msg(slot, object); + client->send(msg, true); + + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsNewbieTutorialNamespace::newbieTutorialHighlightUIElement (JNIEnv* env, jobject self, jlong jobject_player, jstring jstring_widgetPath, jfloat time) +{ + //-- get the player object + ServerObject* player = 0; + if (!JavaLibrary::getObject (jobject_player, player)) + { + DEBUG_REPORT_LOG_PRINT (true, ("newbieTutorialSetToolbarElement (): DB could not find player object")); + return JNI_FALSE; + } + + //-- get the client associated with the player + Client* const client = player->getClient (); + if (!client) + { + DEBUG_REPORT_LOG_PRINT (true, ("newbieTutorialSetToolbarElement (): PB could get the player's client object")); + return JNI_FALSE; + } + + //-- get the widget path string + JavaStringParam javaStringParam_widgetPath (jstring_widgetPath); + std::string widgetPath; + if (!JavaLibrary::convert (javaStringParam_widgetPath, widgetPath)) + { + DEBUG_WARNING (true, ("newbieTutorialSetToolbarElement (): DB failed to convert parameter 3 (widgetPath) to string")); + return JNI_FALSE; + } + + //-- send the message to the client + NewbieTutorialHighlightUIElement const msg(widgetPath, time); + client->send(msg, true); + + return JNI_TRUE; +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsNewbieTutorialNamespace::newbieTutorialSendStartingLocationSelectionResult (JNIEnv* env, jobject self, jlong jobject_player, jstring jstring_name, jboolean result) +{ + UNREF (self); + + //-- get the player object + ServerObject* player = 0; + if (!JavaLibrary::getObject (jobject_player, player)) + { + DEBUG_REPORT_LOG_PRINT (true, ("newbieTutorialSendStartingLocationSelectionResult (): DB could not find player object")); + return; + } + + std::string name; + if (!JavaLibrary::convert(JavaStringParam (jstring_name), name)) + { + DEBUG_REPORT_LOG_PRINT (true, ("newbieTutorialSendStartingLocationSelectionResult (): DB bad string")); + return; + } + + typedef std::pair Payload; + typedef MessageQueueGenericValueType MessageType; + MessageType * const message = new MessageType (Payload (name, result)); + sendMessageToPlayer (*player, message, CM_startingLocationSelectionResult); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsNewbieTutorialNamespace::newbieTutorialSendStartingLocationsToPlayer (JNIEnv* env, jobject self, jlong jobject_player, jobjectArray locations) +{ + UNREF (self); + + //-- get the player object + ServerObject* player = 0; + if (!JavaLibrary::getObject (jobject_player, player)) + { + DEBUG_REPORT_LOG_PRINT (true, ("newbieTutorialSendStartingLocationsToPlayer (): DB could not find player object")); + return; + } + + StartingLocationManager::StartingLocationVector ldv; + + if (locations) + { + std::string name; + + const jsize count = env->GetArrayLength (locations); + for (jsize i = 0; i < count; ++i) + { + const LocalRefPtr loc = getObjectArrayElement (LocalObjectArrayRefParam(locations), i); + const jstring jstr = static_cast(loc->getValue()); + + name.clear (); + + if (JavaLibrary::convert(JavaStringParam (jstr), name)) + { + const StartingLocationData * const data = StartingLocationManager::findLocationByName (name); + if (data) + ldv.push_back (*data); + else + WARNING (true, ("newbieTutorialSendStartingLocationsToPlayer: request for bogus location [%s] index [%d/", name.c_str (), i)); + } + } + } + else + { + //-- copy vector + ldv = StartingLocationManager::getLocations (); + } + + //-- Sort the locations by population + typedef std::multimap PopulationSort; + PopulationSort populations; + + for (StartingLocationManager::StartingLocationVector::const_iterator it = ldv.begin (); it != ldv.end (); ++it) + { + const StartingLocationData & data = *it; + int population = ServerUniverse::getInstance().getPopulationAtLocation(data.planet, static_cast(data.x), static_cast(data.z)); + DEBUG_REPORT_LOG(true,("Starting locations: %s (%i,%i): population %i\n",data.planet.c_str(),static_cast(data.x), static_cast(data.z),population)); + populations.insert(std::pair(population,&data)); + } + + //-- Build the list for the client in order. Mark them unavailable when we've reached the minimum and the population is too high. + typedef std::pair LocationStatus; + typedef stdvector::fwd LocationStatusVector; + LocationStatusVector clientLocations; + clientLocations.reserve (ldv.size ()); + + int locationCount=0; + bool available=true; + for (PopulationSort::iterator i=populations.begin(); i!=populations.end(); ++i) + { + if (available && (locationCount++ >= ConfigServerGame::getMinNewbieTravelLocations()) && (i->first > ConfigServerGame::getMaxPopulationForNewbieTravel())) + available=false; + clientLocations.push_back (LocationStatus (*i->second, available)); + } + + //--Send the list to the client + typedef MessageQueueGenericValueType MessageType; + MessageType * const message = new MessageType (clientLocations); + sendMessageToPlayer (*player, message, CM_startingLocations); +} + +//---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsNewbieTutorialNamespace::getStartingLocations (JNIEnv* env, jobject self) +{ + UNREF (env); + UNREF (self); + + const StartingLocationManager::StartingLocationVector & ldv = StartingLocationManager::getLocations (); + LocalObjectArrayRefPtr valueArray = createNewObjectArray(ldv.size (), JavaLibrary::getClsString()); + size_t i = 0; + for (StartingLocationManager::StartingLocationVector::const_iterator it = ldv.begin (); it != ldv.end (); ++it, ++i) + { + const StartingLocationData & data = *it; + JavaString jval(data.name); + setObjectArrayElement(*valueArray, i, jval); + } + + return valueArray->getReturnValue(); +} + +//---------------------------------------------------------------------- + +jobject JNICALL ScriptMethodsNewbieTutorialNamespace::getStartingLocationInfo (JNIEnv* env, jobject self, jstring jName) +{ + UNREF (self); + + if (!jName) + { + WARNING (true, ("getStartingLocationInfo null name")); + return JNI_FALSE; + } + + std::string name; + if (!JavaLibrary::convert(JavaStringParam (jName), name)) + { + DEBUG_REPORT_LOG_PRINT (true, ("getStartingLocationInfo (): DB bad namestring")); + return JNI_FALSE; + } + + const StartingLocationData * const data = StartingLocationManager::findLocationByName (name); + if (!data) + { + WARNING (true, ("getStartingLocationInfo: request for bogus location [%s]", name.c_str ())); + return JNI_FALSE; + } + + const NetworkId cellId (data->cellId); + + Vector loc; + loc.x = data->x; + loc.y = data->y; + loc.z = data->z; + + LocalRefPtr jLocation; + if (ScriptConversion::convert (loc, data->planet, cellId, jLocation)) + return jLocation->getReturnValue(); + + return 0; +} + +//---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsNewbieTutorialNamespace::isStartingLocationAvailable (JNIEnv* env, jobject self, jstring jstring_name) +{ + std::string name; + if (!JavaLibrary::convert(JavaStringParam (jstring_name), name)) + { + DEBUG_REPORT_LOG_PRINT (true, ("isStartingLocationAvailable (): DB bad string")); + return JNI_FALSE; + } + + const StartingLocationData * const data = StartingLocationManager::findLocationByName (name); + if (!data) + { + WARNING (true, ("isStartingLocationAvailable: request for bogus location [%s]", name.c_str ())); + return JNI_FALSE; + } + + // check if the scene is supposed to be running + if (!GameServer::getInstance().isPlanetEnabledForCluster(data->planet)) + return JNI_FALSE; + + // check if the destination is too full + int const population = ServerUniverse::getInstance().getPopulationAtLocation(data->planet, static_cast(data->x), static_cast(data->z)); + if (population > ConfigServerGame::getMaxPopulationForNewbieTravel()) + return JNI_FALSE; + + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsNewbieTutorialNamespace::isInTutorialArea(JNIEnv *env, jobject self, jlong object) +{ + const ServerObject *serverObject = 0; + if (!JavaLibrary::getObject(object, serverObject)) + return false; + + return NewbieTutorial::isInTutorialArea(serverObject); +} + +// ====================================================================== + diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsNotification.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsNotification.cpp new file mode 100644 index 00000000..8c8cff43 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsNotification.cpp @@ -0,0 +1,109 @@ +// ====================================================================== +// +// ScriptMethodsNotification.cpp +// Copyright 2003, Sony Online Entertainment, Inc. +// All rights reserved. +// +// ====================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "serverGame/CreatureObject.h" +#include "sharedRandom/Random.h" +#include "sharedNetworkMessages/ClientNotificationBoxMessage.h" + +#include "UnicodeUtils.h" + +using namespace JNIWrappersNamespace; + + +// ====================================================================== + +namespace ScriptMethodsNotificationNamespace +{ + bool install(); + + jint JNICALL addNotification(JNIEnv *env, jobject self, jlong player, jstring contents, jboolean useNotificationIcon, jint iconStyle, jfloat timeout, jint channel, jstring sound); + void JNICALL cancelNotification(JNIEnv *env, jobject self, jlong player, jint notification); + void JNICALL cancelAllNotifications(JNIEnv *env, jobject self, jlong player); +} + +using namespace ScriptMethodsNotificationNamespace; + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsNotificationNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsNotificationNamespace::c)} + JF("_addNotification", "(JLjava/lang/String;ZIFILjava/lang/String;)I", addNotification), + JF("_cancelNotification", "(JI)V", cancelNotification), + JF("_cancelAllNotifications", "(J)V", cancelAllNotifications), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +// ====================================================================== + +jint JNICALL ScriptMethodsNotificationNamespace::addNotification(JNIEnv *env, jobject self, jlong player, jstring contents, jboolean useNotificationIcon, jint iconStyle, jfloat timeout, jint channel, jstring sound) +{ + CreatureObject const * playerObject = NULL; + if (!JavaLibrary::getObject(player, playerObject)) + return 0; + + JavaStringParam localContents(contents); + Unicode::String localContentsString; + JavaLibrary::convert(localContents, localContentsString); + if (localContentsString.empty()) + return 0; + + JavaStringParam localSoundContents(sound); + std::string localSoundContentsString; + JavaLibrary::convert(localSoundContents, localSoundContentsString); + + int sequenceId = static_cast(Random::random()); + ClientNotificationBoxMessage cnbm(sequenceId, playerObject->getNetworkId(), localContentsString, useNotificationIcon, iconStyle, timeout, channel, localSoundContentsString); + + if(playerObject->getClient()) + { + playerObject->getClient()->send(cnbm, true); + return sequenceId; + } + return 0; +} + +void JNICALL ScriptMethodsNotificationNamespace::cancelNotification(JNIEnv *env, jobject self, jlong player, jint notification) +{ + CreatureObject const * playerObject = NULL; + if (!JavaLibrary::getObject(player, playerObject)) + return; + ClientNotificationBoxMessage cnbm(notification, playerObject->getNetworkId(), Unicode::emptyString, FALSE, 0, 0.0f, ClientNotificationBoxMessage::NC_SPECIAL_CANCEL, std::string("")); + + if(playerObject->getClient()) + { + playerObject->getClient()->send(cnbm, true); + return; + } + return; +} + +void JNICALL ScriptMethodsNotificationNamespace::cancelAllNotifications(JNIEnv *env, jobject self, jlong player) +{ + CreatureObject const * playerObject = NULL; + if (!JavaLibrary::getObject(player, playerObject)) + return; + ClientNotificationBoxMessage cnbm(0, playerObject->getNetworkId(), Unicode::emptyString, FALSE, 0, 0.0f, ClientNotificationBoxMessage::NC_SPECIAL_CANCEL_ALL, std::string("")); + + if(playerObject->getClient()) + { + playerObject->getClient()->send(cnbm, true); + return; + } + return; +} + diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsNpc.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsNpc.cpp new file mode 100644 index 00000000..a617593b --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsNpc.cpp @@ -0,0 +1,676 @@ +//======================================================================== +// +// ScriptMethodsNpc.cpp - implements script methods dealing with Npcs. +// +// copyright 2001 Sony Online Entertainment +// +//======================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "serverGame/ConfigServerGame.h" +#include "serverGame/CreatureObject.h" +#include "serverGame/GameServer.h" +#include "serverGame/NameManager.h" +#include "serverGame/ServerCreatureObjectTemplate.h" +#include "sharedGame/OutOfBand.h" +#include "sharedGame/OutOfBandPackager.h" +#include "sharedGame/ProsePackage.h" +#include "sharedFoundation/Crc.h" +#include "sharedObject/ObjectTemplateList.h" +#include "UnicodeUtils.h" + +using namespace JNIWrappersNamespace; + + +//======================================================================== +// NPC conversation utility functions +//======================================================================== + +namespace ScriptMethodsNpcNamespace +{ + ProsePackage getProseFromOob (const Unicode::String & oob) + { + ProsePackage localPp; + const OutOfBandBase * const base = OutOfBandPackager::unpackOne (oob, OutOfBandPackager::OT_prosePackage); + if (base) + { + const OutOfBand * const oobpp = safe_cast *>(base); + const ProsePackage * const pp = oobpp->getObject (); + + localPp = *pp; + + delete pp; + delete base; + } + + return localPp; + } + + char const * const cms_conversationAppearanceOverride = "convo.appearance"; + + bool install(); + void setNpcConversationResponses(JNIEnv *env, TangibleObject * player, jobjectArray responses); + + jboolean JNICALL _npcStartConversation(JNIEnv *env, jobject self, jlong player, jlong npc, jstring convoName, jobject greeting, jstring greetingOob, jobjectArray responses, uint32 appearanceOverrideSharedTemplateCrc); + jboolean JNICALL npcStartConversation(JNIEnv *env, jobject self, jlong player, jlong npc, jstring convoName, jobject greeting, jstring greetingOob, jobjectArray responses); + jboolean JNICALL npcStartConversationAppearanceOverride(JNIEnv *env, jobject self, jlong player, jlong npc, jstring convoName, jobject greeting, jstring greetingOob, jobjectArray responses, jstring appearanceOverrideSharedTemplate); + jboolean JNICALL npcEndConversation(JNIEnv *env, jobject self, jlong player); + jboolean JNICALL npcEndConversationWithMessage(JNIEnv *env, jobject self, jlong player, jobject response, jstring responeOob); + jboolean JNICALL npcSpeak(JNIEnv *env, jobject self, jlong player, jobject text, jstring oob); + jboolean JNICALL npcSetConversationResponses(JNIEnv *env, jobject self, jlong player, jobjectArray responses); + jboolean JNICALL npcAddConversationResponse(JNIEnv *env, jobject self, jlong player, jobject response, jstring responeOob); + jboolean JNICALL npcRemoveConversationResponse(JNIEnv *env, jobject self, jlong player, jobject response); + jboolean JNICALL isInNpcConversation(JNIEnv *env, jobject self, jlong creature); + jlongArray JNICALL getNpcConversants(JNIEnv *env, jobject self, jlong creature); + jstring JNICALL generateRandomNameByTemplate(JNIEnv *env, jobject self, jstring templateName); + jstring JNICALL generateRandomNameByTable(JNIEnv *env, jobject self, jstring directory, jstring table); + jboolean JNICALL isNameReserved(JNIEnv *env, jobject self, jstring name); + jboolean JNICALL isNameReservedIgnoreRules(JNIEnv *env, jobject self, jstring name, jobjectArray ignoreRules); + jboolean JNICALL setNpcDifficulty(JNIEnv *env, jobject self, jlong npc, jlong difficulty); +} + +using namespace ScriptMethodsNpcNamespace; + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsNpcNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsNpcNamespace::c)} + JF("__npcStartConversation", "(JJLjava/lang/String;Lscript/string_id;Ljava/lang/String;[Ljava/lang/Object;)Z", npcStartConversation), + JF("__npcStartConversationWithOverrideAppearance", "(JJLjava/lang/String;Lscript/string_id;Ljava/lang/String;[Ljava/lang/Object;Ljava/lang/String;)Z", npcStartConversationAppearanceOverride), + JF("_npcEndConversation", "(J)Z", npcEndConversation), + JF("_npcEndConversationWithMessage", "(JLscript/string_id;Ljava/lang/String;)Z", npcEndConversationWithMessage), + JF("__npcSpeak", "(JLscript/string_id;Ljava/lang/String;)Z", npcSpeak), + JF("__npcSetConversationResponses", "(J[Ljava/lang/Object;)Z", npcSetConversationResponses), + JF("__npcAddConversationResponse", "(JLscript/string_id;Ljava/lang/String;)Z", npcAddConversationResponse), + JF("_npcRemoveConversationResponse", "(JLscript/string_id;)Z", npcRemoveConversationResponse), + JF("_isInNpcConversation", "(J)Z", isInNpcConversation ), + JF("_getNpcConversants", "(J)[J", getNpcConversants), + JF("generateRandomName", "(Ljava/lang/String;)Ljava/lang/String;", generateRandomNameByTemplate), + JF("generateRandomName", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", generateRandomNameByTable), + JF("isNameReserved", "(Ljava/lang/String;)Z", isNameReserved), + JF("isNameReserved", "(Ljava/lang/String;[Ljava/lang/String;)Z", isNameReservedIgnoreRules), + JF("_setNpcDifficulty", "(JJ)Z", setNpcDifficulty), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +//---------------------------------------------------------------------- + +/** + * Takes a Java string_id array and converts it into npc conversation reponses + * available to a player. + * + * @param env Java environment + * @param player the player + * @param reponses array of string_ids +*/ +void ScriptMethodsNpcNamespace::setNpcConversationResponses(JNIEnv *env, TangibleObject * player, jobjectArray responses) +{ + StringId stringId; + Unicode::String oob; + + player->clearNpcConversation(); + + if (responses == 0) + return; + + const jsize count = env->GetArrayLength(responses); + for (jsize i = 0; i < count; ++i) + { + LocalRefPtr response = getObjectArrayElement(LocalObjectArrayRefParam(responses), i); + if (response != LocalRef::cms_nullPtr) + { + if (ScriptConversion::convert(*response, stringId)) + { + // add the response to the player's conversation + player->addNpcConversationResponse(stringId, ProsePackage ()); + } + else if (isInstanceOf(*response, JavaLibrary::getClsString())) + { + oob.clear(); + jstring jstr = static_cast(response->getValue()); + if (JavaLibrary::convert(JavaStringParam (jstr), oob)) + { + const ProsePackage & pp = getProseFromOob (oob); + if (pp.isValid ()) + player->addNpcConversationResponse (StringId (), pp); + else + WARNING (true, ("ScriptMethodsNpc setNpcConversationResponses error getting prose from oob index %i", i)); + } + else + WARNING (true, ("ScriptMethodsNpc setNpcConversationResponses could not convert jstring to Unicode::String")); + } + else + { + WARNING (true, ("ScriptMethodsNpc setNpcConversationResponses error in setNpcConversationResponses index %d", i)); + } + } + else + { + DEBUG_WARNING(true, ("NPC Conversation setNpcConversationResponses response #%d (base-0) missing!", i)); + } + } +} + + +//======================================================================== +// class JavaLibrary JNI NPC callback methods +//======================================================================== + +//---------------------------------------------------------------------- + +/** + * Starts a conversation between an npc and a player. + * + * @param env Java environment + * @param self class calling this function + * @param player player in conversation + * @param npc npc in conversation + * @param convoName name of the conversation; passed to the trigger OnNpcConversationResponse + * @param greeting initial text npc will say to the player + * @param responses initial responses available to the player + * + * @return JNI_TRUE on success, JNI_FALSE on fail + */ +jboolean JNICALL ScriptMethodsNpcNamespace::_npcStartConversation(JNIEnv *env, jobject self, jlong player, jlong npc, jstring convoName, jobject greeting, jstring greetingOob, jobjectArray responses, uint32 appearanceOverrideTemplateCrc) +{ + UNREF(self); + + JavaStringParam localConvoName(convoName); + std::string convoNameStr; + if (!JavaLibrary::convert (localConvoName, convoNameStr)) + return JNI_FALSE; + + TangibleObject * playerObject = NULL; + if (!JavaLibrary::getObject(player, playerObject)) + return JNI_FALSE; + + if (playerObject->isInNpcConversation()) + return JNI_FALSE; + + TangibleObject * npcObject = NULL; + if (!JavaLibrary::getObject(npc, npcObject)) + return JNI_FALSE; + + if (!playerObject->startNpcConversation(*npcObject, convoNameStr, NpcConversationData::CS_NPC, appearanceOverrideTemplateCrc)) + return JNI_FALSE; + + // send the greeting + StringId greetingStringId; + if (greeting) + ScriptConversion::convert(greeting, greetingStringId); + + Unicode::String oob; + + if (greetingOob) + { + JavaStringParam localGreetingOob(greetingOob); + if (!JavaLibrary::convert (localGreetingOob, oob)) + { + WARNING (true, ("ScriptMethodsNpc unable to convert greetingOob")); + return JNI_FALSE; + } + } + + playerObject->sendNpcConversationMessage(greetingStringId, ProsePackage (), oob); + + // send the responses to the player + setNpcConversationResponses(env, playerObject, responses); + playerObject->sendNpcConversationResponses(); + + return JNI_TRUE; +} // JavaLibrary::NpcStartConversation + +//---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsNpcNamespace::npcStartConversation(JNIEnv *env, jobject self, jlong player, jlong npc, jstring convoName, jobject greeting, jstring greetingOob, jobjectArray responses) +{ + TangibleObject * speakerObject = NULL; + if (!JavaLibrary::getObject(npc, speakerObject) || !speakerObject) + return JNI_FALSE; + + std::string conversationAppearanceOverride; + speakerObject->getObjVars().getItem(cms_conversationAppearanceOverride, conversationAppearanceOverride); + + uint32 crc = Crc::crcNull; + ObjectTemplate const * const ot = ObjectTemplateList::fetch(conversationAppearanceOverride); + ServerObjectTemplate const * const sot = ot ? ot->asServerObjectTemplate() : NULL; + if(sot) + { + std::string const & sharedTemplateName = sot->getSharedTemplate(); + crc = Crc::calculate(sharedTemplateName.c_str()); + } + + return _npcStartConversation(env, self, player, npc, convoName, greeting, greetingOob, responses, crc); +} + +//---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsNpcNamespace::npcStartConversationAppearanceOverride(JNIEnv *env, jobject self, jlong player, jlong npc, jstring convoName, jobject greeting, jstring greetingOob, jobjectArray responses, jstring appearanceOverrideSharedTemplateName) +{ + JavaStringParam localAppearanceOverrideSharedTemplateName(appearanceOverrideSharedTemplateName); + std::string appearanceOverrideSharedTemplateNameStr; + if (!JavaLibrary::convert (localAppearanceOverrideSharedTemplateName, appearanceOverrideSharedTemplateNameStr)) + return JNI_FALSE; + + ObjectTemplate const * const ot = ObjectTemplateList::fetch(appearanceOverrideSharedTemplateNameStr); + ServerObjectTemplate const * const sot = ot ? ot->asServerObjectTemplate() : NULL; + if(!sot) + { + return JNI_FALSE; + WARNING (true, ("npcStartConversationAppearanceOverride: appearanceOverride string is not a server template name")); + } + std::string const & sharedTemplateName = sot->getSharedTemplate(); + uint32 const crc = Crc::calculate(sharedTemplateName.c_str()); + + return _npcStartConversation(env, self, player, npc, convoName, greeting, greetingOob, responses, crc); +} + +//---------------------------------------------------------------------- + +/** + * Ends a player's current conversation. + * + * @param env Java environment + * @param self class calling this function + * @param player player in conversation + * + * @return JNI_TRUE on success, JNI_FALSE on fail +*/ +jboolean JNICALL ScriptMethodsNpcNamespace::npcEndConversation(JNIEnv *env, jobject self, jlong player) +{ + UNREF(self); + + TangibleObject * playerObject = NULL; + if (!JavaLibrary::getObject(player, playerObject)) + return JNI_FALSE; + + if (playerObject->isInNpcConversation()) + { + playerObject->endNpcConversation(); + } + + return JNI_TRUE; +} // JavaLibrary::npcEndConversation + +//---------------------------------------------------------------------- + +/** + * Has the NPC a player is in conversation say something to the player. + * + * @param env Java environment + * @param self class calling this function + * @param player player in conversation + * @param text the message the npc will say to the player + * + * @return JNI_TRUE on success, JNI_FALSE on fail +*/ +jboolean JNICALL ScriptMethodsNpcNamespace::npcSpeak(JNIEnv *env, jobject self, jlong player, jobject paramTextId, jstring paramOob) +{ + UNREF(self); + + TangibleObject * playerObject = NULL; + if (!JavaLibrary::getObject(player, playerObject)) + return JNI_FALSE; + + if (!playerObject->isInNpcConversation()) + return JNI_FALSE; + + StringId textStringId; + Unicode::String oob; + + if (paramTextId) + { + if (!ScriptConversion::convert(paramTextId, textStringId)) + { + WARNING (true, ("ScriptMethodsNpc Unable to convert string id")); + return JNI_FALSE; + } + } + + if (paramOob) + { + if (!JavaLibrary::convert (JavaStringParam (paramOob), oob)) + { + WARNING (true, ("ScriptMethodsNpc unable to convert oob")); + return JNI_FALSE; + } + } + + playerObject->sendNpcConversationMessage(textStringId, ProsePackage (), oob); + return JNI_TRUE; +} // JavaLibrary::npcSpeak + +//---------------------------------------------------------------------- + +/** + * Sets the available responses for a player to select in a conversation with + * an NPC. + * + * @param env Java environment + * @param self class calling this function + * @param player player in conversation + * @param responses responses available to the player + * + * @return JNI_TRUE on success, JNI_FALSE on fail + */ +jboolean JNICALL ScriptMethodsNpcNamespace::npcSetConversationResponses(JNIEnv *env, jobject self, jlong player, jobjectArray responses) +{ + UNREF(self); + + TangibleObject * playerObject = NULL; + if (!JavaLibrary::getObject(player, playerObject)) + return JNI_FALSE; + + if (!playerObject->isInNpcConversation()) + return JNI_FALSE; + + setNpcConversationResponses(env, playerObject, responses); + + return JNI_TRUE; +} // JavaLibrary::npcSetConversationResponses + +//---------------------------------------------------------------------- + +/** + * Adds a response to the available responses for a player to select in a + * conversation with an NPC. + * + * @param env Java environment + * @param self class calling this function + * @param player player in conversation + * @param response response to add + * + * @return JNI_TRUE on success, JNI_FALSE on fail + */ +jboolean JNICALL ScriptMethodsNpcNamespace::npcAddConversationResponse(JNIEnv *env, jobject self, jlong player, jobject responseId, jstring responseOob) +{ + UNREF(self); + + TangibleObject * playerObject = NULL; + if (!JavaLibrary::getObject(player, playerObject)) + return JNI_FALSE; + + if (!playerObject->isInNpcConversation()) + return JNI_FALSE; + + StringId stringId; + ProsePackage pp; + + if (responseId) + { + if (!ScriptConversion::convert(responseId, stringId)) + return JNI_FALSE; + } + + if (responseOob) + { + Unicode::String oob; + if (!JavaLibrary::convert (JavaStringParam (responseOob), oob)) + return JNI_FALSE; + + pp = getProseFromOob (oob); + if (!pp.isValid ()) + { + WARNING (true, ("ScriptMethodsNpc error getting prose from oob")); + return JNI_FALSE; + } + } + + if (stringId.isInvalid () && !pp.isValid ()) + { + WARNING (true, ("No stringid or pp")); + return JNI_FALSE; + } + + if (!playerObject->addNpcConversationResponse(stringId, pp)) + return JNI_FALSE; + + return JNI_TRUE; +} // JavaLibrary::npcAddConversationResponse + +//---------------------------------------------------------------------- + +/** + * Removes a response from the available responses for a player to select in a + * conversation with an NPC. + * + * @param env Java environment + * @param self class calling this function + * @param player player in conversation + * @param response response to remove + * + * @return JNI_TRUE on success, JNI_FALSE on fail + */ +jboolean JNICALL ScriptMethodsNpcNamespace::npcRemoveConversationResponse(JNIEnv *env, jobject self, jlong player, jobject response) +{ + UNREF(self); + + TangibleObject * playerObject = NULL; + if (!JavaLibrary::getObject(player, playerObject)) + return JNI_FALSE; + + if (!playerObject->isInNpcConversation()) + return JNI_FALSE; + + StringId localResponse; + if (!ScriptConversion::convert(response, localResponse)) + return JNI_FALSE; + + if (!playerObject->removeNpcConversationResponse(localResponse, ProsePackage ())) + return JNI_FALSE; + + return JNI_TRUE; +} // JavaLibrary::npcRemoveConversationResponse + +//---------------------------------------------------------------------- + +/** + * Determines if a creature is in an NPC conversation or not. The creature may + * be a player or NPC. + * + * @param env Java environment + * @param self class calling this function + * @param creature creature being asked about + * + * @return JNI_TRUE if creature is in an NPC conversation, JNI_FALSE if not + */ +jboolean JNICALL ScriptMethodsNpcNamespace::isInNpcConversation(JNIEnv *env, jobject self, jlong creature) +{ + UNREF(self); + + TangibleObject * tangibleObject = NULL; + if (!JavaLibrary::getObject(creature, tangibleObject)) + return JNI_FALSE; + + if (tangibleObject->isInNpcConversation()) + return JNI_TRUE; + return JNI_FALSE; +} // JavaLibrary::isInNpcConversation + +//---------------------------------------------------------------------- + +/** + * Returns the ids of any creatures a creature is in an NPC conversation with. + * + * @param env Java environment + * @param self class calling this function + * @param creature creature being asked about + * + * @return an array of obj_ids the creature is in conversation with, or null on error +*/ +jlongArray JNICALL ScriptMethodsNpcNamespace::getNpcConversants(JNIEnv *env, jobject self, jlong creature) +{ + UNREF(self); + + TangibleObject * tangibleObject = NULL; + if (!JavaLibrary::getObject(creature, tangibleObject)) + return 0; + + const std::vector & conversants = tangibleObject->getConversations(); + int count = conversants.size(); + + // create an array of obj_ids and fill them in + LocalLongArrayRefPtr objIds = createNewLongArray(count); + if (objIds == LocalLongArrayRef::cms_nullPtr) + return 0; + + jlong jlongTmp; + for (int i = 0; i < count; ++i) + { + jlongTmp = (conversants[i]).getValue(); + setLongArrayRegion(*objIds, i, 1, &jlongTmp); + } + return objIds->getReturnValue(); +} // JavaLibrary::getNpcConversants + +//---------------------------------------------------------------------- + +/** + * Generates a random name for an object. + * + * @param env Java environment + * @param self class calling this function + * @param template the name of the template to generate the name for + * @return The random name, or blank if one could not be generated + */ +jstring JNICALL ScriptMethodsNpcNamespace::generateRandomNameByTemplate(JNIEnv *env, jobject self, jstring i_templateName) +{ + UNREF(self); + + std::string templateName; + if (!JavaLibrary::convert(JavaStringParam(i_templateName), templateName)) + return JavaString("").getReturnValue(); + + Unicode::String randomName; + + const ObjectTemplate * const objectTemplate = ObjectTemplateList::fetch(templateName); + if (objectTemplate) + { + const ServerCreatureObjectTemplate * const creatureTemplate = dynamic_cast(objectTemplate); + if (creatureTemplate) + { + // generate a name + randomName = NameManager::getInstance().generateRandomName(ConfigServerGame::getCharacterNameGeneratorDirectory(),creatureTemplate->getNameGeneratorType()); + } + objectTemplate->releaseReference(); + } + + return JavaString(randomName).getReturnValue(); +} // JavaLibrary::speakString + +// ---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsNpcNamespace::generateRandomNameByTable(JNIEnv *env, jobject self, jstring directory, jstring table) +{ + std::string myDirectory; + if (!JavaLibrary::convert(JavaStringParam(directory), myDirectory)) + return JavaString("").getReturnValue(); + + std::string myTable; + if (!JavaLibrary::convert(JavaStringParam(table), myTable)) + return JavaString("").getReturnValue(); + + Unicode::String randomName = NameManager::getInstance().generateRandomName(myDirectory, myTable); + return JavaString(randomName).getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsNpcNamespace::isNameReserved(JNIEnv *env, jobject self, jstring name) +{ + Unicode::String myName; + if (!JavaLibrary::convert(JavaStringParam(name), myName)) + return false; + + return NameManager::getInstance().isNameReserved(myName); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsNpcNamespace::isNameReservedIgnoreRules(JNIEnv *env, jobject self, jstring name, jobjectArray ignoreRules) +{ + Unicode::String myName; + if (!JavaLibrary::convert(JavaStringParam(name), myName)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::isNameReservedIgnoreRules passed invalid java string for the name")); + return true; + } + + std::vector rulesToIgnore; + if(!ScriptConversion::convert(ignoreRules, rulesToIgnore)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::isNameReservedIgnoreRules passed invalid java string array")); + return true; + } + + std::string dummyReturn; + return NameManager::getInstance().isNameReserved(myName, dummyReturn, rulesToIgnore); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsNpcNamespace::npcEndConversationWithMessage(JNIEnv * /*env*/, jobject /*self*/, jlong player, jobject response, jstring responseOob) +{ + TangibleObject * playerObject = NULL; + if(!JavaLibrary::getObject(player, playerObject)) + return JNI_FALSE; + + if(!playerObject->isInNpcConversation()) + return JNI_FALSE; + + StringId responseStringId; + bool responseIsValid = false; + if(response) + { + responseIsValid = static_cast(ScriptConversion::convert(response, responseStringId)); + } + + bool oobIsValid = false; + Unicode::String oob; + if(responseOob) + { + oobIsValid = static_cast(JavaLibrary::convert(JavaStringParam(responseOob), oob)); + } + + if(responseIsValid || oobIsValid) + { + playerObject->endNpcConversation(responseStringId, oob); + } + else + { + playerObject->endNpcConversation(); + } + + return JNI_TRUE; +} + +//---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsNpcNamespace::setNpcDifficulty(JNIEnv *env, jobject self, jlong npc, jlong difficulty) +{ + TangibleObject * npcObject = NULL; + if (!JavaLibrary::getObject(npc, npcObject)) + return JNI_FALSE; + + CreatureObject *creature = npcObject->asCreatureObject(); + + if (!creature) + return JNI_FALSE; + + if (difficulty < 0 || difficulty > 2) + return JNI_FALSE; + + creature->setDifficulty(static_cast (difficulty)); + + return JNI_TRUE; +} diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsObjectCreate.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsObjectCreate.cpp new file mode 100644 index 00000000..ea707e31 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsObjectCreate.cpp @@ -0,0 +1,2272 @@ +//======================================================================== +// +// ScriptMethodsObjectCreate.cpp - implements script methods dealing with object +// creation/destruction. +// +// copyright 2001 Sony Online Entertainment +// +//======================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "serverGame/CellObject.h" +#include "serverGame/ConfigServerGame.h" +#include "serverGame/ContainerInterface.h" +#include "serverGame/CreatureObject.h" +#include "serverGame/DraftSchematicObject.h" +#include "serverGame/FactoryObject.h" +#include "serverGame/GameServer.h" +#include "serverGame/IntangibleObject.h" +#include "serverGame/ManufactureSchematicObject.h" +#include "serverGame/MessageToQueue.h" +#include "serverGame/PlayerCreatureController.h" +#include "serverGame/PlayerObject.h" +#include "serverGame/ServerObject.h" +#include "serverGame/ServerUniverse.h" +#include "serverGame/ServerWorld.h" +#include "serverNetworkMessages/FlagObjectForDeleteMessage.h" +#include "serverPathfinding/CityPathGraphManager.h" +#include "serverScript/GameScriptObject.h" +#include "serverScript/ScriptParameters.h" +#include "sharedFoundation/Clock.h" +#include "sharedFoundation/ConstCharCrcString.h" +#include "sharedFoundation/Crc.h" +#include "sharedFoundation/CrcLowerString.h" +#include "sharedLog/Log.h" +#include "sharedObject/CellProperty.h" +#include "sharedObject/Container.h" +#include "sharedObject/NetworkIdManager.h" +#include "sharedObject/ObjectTemplateList.h" +#include "sharedObject/SlotId.h" +#include "sharedObject/SlotIdManager.h" +#include "sharedObject/SlottedContainer.h" +#include "sharedObject/SlottedContainmentProperty.h" +#include "sharedObject/VolumeContainer.h" +#include "sharedTerrain/TerrainModificationHelper.h" +#include "sharedUtility/DataTable.h" +#include "sharedUtility/DataTableManager.h" + +using namespace JNIWrappersNamespace; + + +//======================================================================== +// constants +//======================================================================== + +static const uint32 THEATER_DATATABLE_TAG = Crc::calculate("THEATER"); +static const std::string THEATER_TEMPLATE("object/intangible/theater/base_theater.iff"); +static const std::string THEATER_FLATTEN_LAYER("terrain/poi_small.lay"); + + +// ====================================================================== +// ScriptMethodsObjectCreateNamespace +// ====================================================================== + +namespace ScriptMethodsObjectCreateNamespace +{ + bool install(); + jlong createTheater(const stdvector::fwd & crcs, const stdvector::fwd & positions, const stdvector::fwd & headings, const std::vector & scripts, const Vector & center, const std::string & script, const NetworkId & creator, const std::string & name, int locationType); + + jlong JNICALL createNewObjectAt(JNIEnv *env, jobject self, jstring source, jlong target); + jlong JNICALL createNewObjectInWorld(JNIEnv *env, jobject self, jlong source, jobject location); + jlong JNICALL createNewObjectInWorldString(JNIEnv *env, jobject self, jobject source, jobject location); + jlong JNICALL createNewObjectInContainer(JNIEnv *env, jobject self, jlong source, jlong container, jstring slot); + jlong JNICALL createNewObjectInContainerString(JNIEnv *env, jobject self, jobject source, jlong container, jstring slot); + jlong JNICALL createNewObjectInContainerOverloaded(JNIEnv *env, jobject self, jlong source, jlong container); + jlong JNICALL createNewObjectInContainerOverloadedString(JNIEnv *env, jobject self, jobject source, jlong container); + jlong JNICALL createNewObjectInInventoryOverloaded(JNIEnv *env, jobject self, jstring sourceName, jlong target); + jlong JNICALL createNewObjectCrc(JNIEnv *env, jobject self, int sourceCrc, jobject location); + jlong JNICALL createNewObjectInContainerCrc(JNIEnv *env, jobject self, int sourceCrc, jlong container, jstring slot); + jlong JNICALL createNewObjectInContainerOverloadedCrc(JNIEnv *env, jobject self, int sourceCrc, jlong container); + jlong JNICALL createNewObjectInInventoryOverloadedCrc(JNIEnv *env, jobject self, int sourceCrc, jlong target); + jlong JNICALL createNewObjectAtCrc(JNIEnv *env, jobject self, int sourceCrc, jlong target); + jlong JNICALL createNewObjectSimulator(JNIEnv *env, jobject self, jstring source, jobject location); + jboolean JNICALL destroyObjectSimulator(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL destroyObject(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL destroyObjectHyperspace(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL persistObject(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL isObjectPersisted(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL reloadPathNodes(JNIEnv *env, jobject self, jlongArray target); + jstring JNICALL getObjectTemplateName(JNIEnv *env, jobject self, jint crc); + jint JNICALL getObjectTemplateCrc(JNIEnv *env, jobject self, jstring name); + jlong JNICALL createNewObjectTransform(JNIEnv *env, jobject self, jstring templateName, jobject transform, jlong cell); + jlong JNICALL createNewObjectTransformCrc(JNIEnv *env, jobject self, jint templateCrc, jobject transform, jlong cell); + jlong JNICALL createTheaterDatatableOnly(JNIEnv *env, jobject self, jstring datatable, jlong caller, jstring name, jint locationType); + jlong JNICALL createTheaterDatatable(JNIEnv *env, jobject self, jstring datatable, jobject center, jstring script, jlong caller, jstring name, jint locationType); + jboolean JNICALL createRemoteTheaterDatatableOnly(JNIEnv *env, jobject self, jstring datatable, jlong caller, jstring name, jint locationType); + jboolean JNICALL createRemoteTheaterDatatable(JNIEnv *env, jobject self, jstring datatable, jobject center, jstring script, jlong caller, jstring name, jint locationType); + jlong JNICALL createTheaterCrc(JNIEnv *env, jobject self, jintArray crcs, jobjectArray positions, jobject center, jstring script, jlong caller); + jlong JNICALL createTheaterString(JNIEnv *env, jobject self, jobjectArray templates, jobjectArray positions, jobject center, jstring script, jlong caller); + jboolean JNICALL assignTheaterToPlayer(JNIEnv *env, jobject self, jlong player, jstring datatable, jlong caller, jstring name, jint locationType); + jboolean JNICALL assignTheaterToPlayerLocation(JNIEnv *env, jobject self, jlong player, jstring datatable, jobject basePosition, jstring script, jlong caller, jstring name, jint locationType); + jboolean JNICALL unassignTheaterFromPlayer(JNIEnv *env, jobject self, jlong player); + jboolean JNICALL hasTheaterAssigned(JNIEnv *env, jobject self, jlong player); + jstring JNICALL getTheaterName(JNIEnv *env, jobject self, jlong theater); + jlong JNICALL findTheater(JNIEnv *env, jobject self, jstring name); + jlong JNICALL createSchematicString(JNIEnv *env, jobject self, jstring draftSchematic, jlong container); + jlong JNICALL createSchematicCrc(JNIEnv *env, jobject self, jint draftSchematicCrc, jlong container); + jlong JNICALL createNewObjectTransformHyperspace(JNIEnv *env, jobject self, jstring templateName, jobject transform, jlong cell); + jlong JNICALL createNewObjectTransformCrcHyperspace(JNIEnv *env, jobject self, jint templateCrc, jobject transform, jlong cell); + jlong JNICALL createNewObjectTransformInternal(JNIEnv *env, jobject self, jstring templateName, jobject transform, jlong cell, bool hyperspace = false); + jlong JNICALL createNewObjectTransformCrcInternal(JNIEnv *env, jobject self, jint templateCrc, jobject transform, jlong cell, bool hyperspace = false); + jboolean JNICALL updateNetworkTriggerVolume(JNIEnv *env, jobject self, jlong target, jfloat radius); +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsObjectCreateNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsObjectCreateNamespace::c)} + JF("_createObject", "(Ljava/lang/String;Lscript/location;)J", createNewObjectInWorldString), + JF("_createObject", "(JLscript/location;)J", createNewObjectInWorld), + JF("_createObject", "(Ljava/lang/String;JLjava/lang/String;)J", createNewObjectInContainerString), + JF("_createObject", "(JJLjava/lang/String;)J", createNewObjectInContainer), + JF("_createObjectOverloaded", "(Ljava/lang/String;J)J", createNewObjectInContainerOverloadedString), + JF("_createObjectOverloaded", "(JJ)J", createNewObjectInContainerOverloaded), + JF("_createObjectInInventoryAllowOverload", "(Ljava/lang/String;J)J", createNewObjectInInventoryOverloaded), + JF("_createObjectAt","(Ljava/lang/String;J)J", createNewObjectAt), + JF("_createObject", "(ILscript/location;)J", createNewObjectCrc), + JF("_createObject", "(IJLjava/lang/String;)J", createNewObjectInContainerCrc), + JF("_createObjectOverloaded", "(IJ)J", createNewObjectInContainerOverloadedCrc), + JF("_createObjectInInventoryAllowOverload", "(IJ)J", createNewObjectInInventoryOverloadedCrc), + JF("_createObjectAt","(IJ)J", createNewObjectAtCrc), + JF("_createObjectSimulator", "(Ljava/lang/String;Lscript/location;)J", createNewObjectSimulator), + JF("_destroyObjectSimulator", "(J)Z", destroyObjectSimulator), + JF("__destroyObject", "(J)Z", destroyObject), + JF("__destroyObjectHyperspace", "(J)Z", destroyObjectHyperspace), + JF("_persistObject", "(J)Z", persistObject), + JF("_isObjectPersisted", "(J)Z", isObjectPersisted), + JF("_reloadPathNodes", "([J)Z", reloadPathNodes), + JF("getObjectTemplateName", "(I)Ljava/lang/String;", getObjectTemplateName), + JF("getObjectTemplateCrc", "(Ljava/lang/String;)I", getObjectTemplateCrc), + JF("_createObject", "(Ljava/lang/String;Lscript/transform;J)J", createNewObjectTransform), + JF("_createObject", "(ILscript/transform;J)J", createNewObjectTransformCrc), + JF("_createTheater", "(Ljava/lang/String;JLjava/lang/String;I)J", createTheaterDatatableOnly), + JF("_createTheater", "(Ljava/lang/String;Lscript/location;Ljava/lang/String;JLjava/lang/String;I)J", createTheaterDatatable), + JF("_createRemoteTheater", "(Ljava/lang/String;JLjava/lang/String;I)Z", createRemoteTheaterDatatableOnly), + JF("_createRemoteTheater", "(Ljava/lang/String;Lscript/location;Ljava/lang/String;JLjava/lang/String;I)Z", createRemoteTheaterDatatable), + JF("_createTheater", "([I[Lscript/location;Lscript/location;Ljava/lang/String;J)J", createTheaterCrc), + JF("_createTheater", "([Ljava/lang/String;[Lscript/location;Lscript/location;Ljava/lang/String;J)J", createTheaterString), + JF("_assignTheaterToPlayer", "(JLjava/lang/String;JLjava/lang/String;I)Z", assignTheaterToPlayer), + JF("_assignTheaterToPlayer", "(JLjava/lang/String;Lscript/location;Ljava/lang/String;JLjava/lang/String;I)Z", assignTheaterToPlayerLocation), + JF("_unassignTheaterFromPlayer", "(J)Z", unassignTheaterFromPlayer), + JF("_hasTheaterAssigned", "(J)Z", hasTheaterAssigned), + JF("_getTheaterName", "(J)Ljava/lang/String;", getTheaterName), + JF("_findTheater", "(Ljava/lang/String;)J", findTheater), + JF("_createSchematic", "(Ljava/lang/String;J)J", createSchematicString), + JF("_createSchematic", "(IJ)J", createSchematicCrc), + JF("_createObjectHyperspace", "(Ljava/lang/String;Lscript/transform;J)J", createNewObjectTransformHyperspace), + JF("_createObjectHyperspace", "(ILscript/transform;J)J", createNewObjectTransformCrcHyperspace), + JF("_updateNetworkTriggerVolume", "(JF)Z", updateNetworkTriggerVolume), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +//======================================================================== +// utility functions +//======================================================================== + +/** + * Creates a group of objects centered at a given position. + * + * @param crcs template crcs of the objects to create + * @param positions where to create the objects, relative to the theater center + * @param headings the orientation of the objects + * @param scripts list of scripts that will be attached to the created objects + * @param center the location of the master theater object - may or may + * not the the actual center of the theater + * @param script optional script to be attached to the master theater object; + * the trigger OnTheaterCreated will be called when all the + * theater objects have been created + * @param creator the object that is creating the theater + * @param name the theater's name + * @param locationType how to create the theater + * + * @return the obj_id of the theater object + */ +jlong ScriptMethodsObjectCreateNamespace::createTheater(const std::vector & crcs, + const std::vector & positions, const std::vector & headings, + const std::vector & scripts, const Vector & center, + const std::string & script, const NetworkId & creator, const std::string & name, + int locationType) +{ + if (crcs.empty()) + { + WARNING(true, ("JavaLibrary::createTheater crc list empty")); + return 0; + } + if (crcs.size() != positions.size()) + { + WARNING(true, ("JavaLibrary::createTheater positions length does not " + "match crcs")); + return 0; + } + if (!headings.empty() && crcs.size() != headings.size()) + { + WARNING(true, ("JavaLibrary::createTheater headings length does not " + "match crcs")); + return 0; + } + if (!scripts.empty() && crcs.size() != scripts.size()) + { + WARNING(true, ("JavaLibrary::createTheater scripts length does not " + "match crcs")); + return 0; + } + if (!name.empty()) + { + // make sure the theater doesn't already exist + const NetworkId & oldTheater = ServerUniverse::getInstance().findTheaterId(name); + if (oldTheater != NetworkId::cms_invalid) + { + WARNING(true, ("JavaLibrary::createTheater asked to create theater " + "with name %s which is already assigned to theater %s", + name.c_str(), oldTheater.getValueString().c_str())); + return 0; + } + } + + // Find out the area the theater will take up and use getGoodLocation + // to try and find somewhere where we can place the theater. Our search + // area is the size of the theater * 3. + float minx = FLT_MAX; + float maxx = -FLT_MIN; + float minz = FLT_MAX; + float maxz = -FLT_MIN; + size_t count = positions.size(); + for (size_t i = 0; i < count; ++i) + { + if (positions[i].x < minx) + minx = positions[i].x; + else if (positions[i].x > maxx) + maxx = positions[i].x; + if (positions[i].z < minz) + minz = positions[i].z; + else if (positions[i].z > maxz) + maxz = positions[i].z; + } + float dx = maxx - minx; + float dz = maxz - minz; + float centerX = minx + dx / 2.0f + center.x; + float centerZ = minz + dz / 2.0f + center.z; + + TerrainGenerator::Layer * layer = NULL; + if (locationType == IntangibleObject::TLT_flatten) + { + layer = TerrainModificationHelper::importLayer(THEATER_FLATTEN_LAYER.c_str()); + if (layer == NULL) + { + WARNING (true, ("Layer %s not found for theater, using getGoodLocation " + "instead", THEATER_FLATTEN_LAYER.c_str())); + locationType = IntangibleObject::TLT_getGoodLocation; + } + } + + Vector goodLoc(centerX, 0, centerZ); + if (locationType == IntangibleObject::TLT_getGoodLocation) + { + goodLoc = ServerWorld::getGoodLocation(dx, dz, Vector(minx - dx + center.x, + 0, minz - dz + center.z), Vector(maxx + dx + center.x, 0, maxz + dz + center.z), + false, false); + } + if (goodLoc.x == 0 && goodLoc.z == 0) + { + WARNING(true, ("JavaLibrary::createTheater could not find good location " + "of size %f %f around point %f %f", dx, dz, centerX, centerZ)); + return 0; + } + DEBUG_LOG("Theater", ("JavaLibrary::createTheater found goodloc at %f %f", + goodLoc.x, goodLoc.z)); + + // create an object at the center of the theater that will be used to represent + // the entire theater + Transform tr; + tr.setPosition_p(goodLoc.x + center.x - centerX, 0, goodLoc.z + center.z - centerZ); + IntangibleObject * theater = safe_cast(ServerWorld::createNewObject(THEATER_TEMPLATE, tr, 0, false)); + NOT_NULL(theater); + theater->setTheater(); + if (layer != NULL) + { + theater->setLayer(layer); + } + + // this is freaking ugly, but a jint is defined as a long in Windows and an + // int in Linux, so we use our int32 definition + theater->setObjects(*reinterpret_cast *>(&crcs), + positions, headings, scripts); + theater->setTheaterCreator(creator); + theater->setTheaterName(name); + theater->addToWorld(); + theater->scheduleForAlter(); + + if (!script.empty()) + { + NOT_NULL(theater->getScriptObject()); + theater->getScriptObject()->attachScript(script, true); + } + + return (theater->getNetworkId()).getValue(); +} // JavaLibrary::createTheater + + +//======================================================================== +// class JavaLibrary JNI object creation callback methods +//======================================================================== + +/** + * Creates a new object. + * + * @param env Java environment + * @param self class calling this function + * @param source the template id or the object id to create the object with + * @param location where to put the object + * + * @return the new object, or null on error + */ +jlong JNICALL ScriptMethodsObjectCreateNamespace::createNewObjectInWorld(JNIEnv *env, jobject self, jlong source, jobject location) +{ + if (source == 0) + return 0; + if (location == 0) + return 0; + + // determine what source is and create the object + std::string localName; + + ServerObject* object = NULL; + if (!JavaLibrary::getObject(source, object)) + return 0; + localName = object->getTemplateName(); + + ConstCharCrcString crcName(ObjectTemplateList::lookUp(localName.c_str())); + if (crcName.getCrc() == 0) + { + WARNING(true, ("[designer bug] JavaLibrary::createNewObject called with " + "unknown template %s", localName.c_str())); + fprintf(stderr, "WARNING: Could not create object from template %s\n", + localName.c_str()); + JavaLibrary::printJavaStack(); + return 0; + } + return createNewObjectCrc(env, self, crcName.getCrc(), location); +} // JavaLibrary::createNewObject + +/** + * Creates a new object. + * + * @param env Java environment + * @param self class calling this function + * @param source the template id or the object id to create the object with + * @param location where to put the object + * + * @return the new object, or null on error + */ +jlong JNICALL ScriptMethodsObjectCreateNamespace::createNewObjectInWorldString(JNIEnv *env, jobject self, jobject source, jobject location) +{ + if (source == 0) + return 0; + if (location == 0) + return 0; + + // determine what source is and create the object + std::string localName; + if (env->IsInstanceOf(source, JavaLibrary::getClsString()) == JNI_TRUE) + { + JavaStringParam localSource(static_cast(source)); + JavaLibrary::convert(localSource, localName); + } + else + return 0; + + ConstCharCrcString crcName(ObjectTemplateList::lookUp(localName.c_str())); + if (crcName.getCrc() == 0) + { + WARNING(true, ("[designer bug] JavaLibrary::createNewObject called with " + "unknown template %s", localName.c_str())); + fprintf(stderr, "WARNING: Could not create object from template %s\n", + localName.c_str()); + JavaLibrary::printJavaStack(); + return 0; + } + + jlong result = createNewObjectCrc(env, self, crcName.getCrc(), location); + + if (result == 0) + { + fprintf(stderr, "WARNING: Could not create object from crc(%d) string(%s)\n", static_cast(crcName.getCrc()), (!crcName.isEmpty() ? crcName.getString() : "No String")); + JavaLibrary::printJavaStack(); + } + + return result; +} // JavaLibrary::createNewObject + +//-------------------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsObjectCreateNamespace::createNewObjectAt(JNIEnv *env, jobject self, jstring source, jlong target) +{ + if (source == 0) + return 0; + if (target == 0) + return 0; + + // get the template name into an std::string + JavaStringParam localSource(source); + std::string templateName; + JavaLibrary::convert(localSource, templateName); + + ConstCharCrcString crcName(ObjectTemplateList::lookUp(templateName.c_str())); + if (crcName.getCrc() == 0) + { + WARNING(true, ("[designer bug] JavaLibrary::createNewObjectAt called with " + "unknown template %s", templateName.c_str())); + fprintf(stderr, "WARNING: Could not create object from template %s\n", + templateName.c_str()); + JavaLibrary::printJavaStack(); + return 0; + } + return createNewObjectAtCrc(env, self, crcName.getCrc(), target); +} + +//-------------------------------------------------------------------------------- + +/** + * Creates a new object and puts it in another object's container slot. + * + * @param env Java environment + * @param self class calling this function + * @param source the template id or the object id to create the object with + * @param container the object we want to put our new object into + * @param slot the container slot we want to put the object in + * + * @return the new object, or null on error + */ +jlong JNICALL ScriptMethodsObjectCreateNamespace::createNewObjectInContainer(JNIEnv *env, jobject self, jlong source, jlong container, jstring slot) +{ + if (source == 0) + return 0; + if (container == 0) + return 0; + + // determine what source is and create the object + std::string templateName; + + const ServerObject* object = NULL; + if (!JavaLibrary::getObject(source, object)) + return 0; + templateName = object->getTemplateName(); + + ConstCharCrcString crcName(ObjectTemplateList::lookUp(templateName.c_str())); + if (crcName.getCrc() == 0) + { + WARNING(true, ("[designer bug] JavaLibrary::createNewObjectInContainer " + "called with unknown template %s", templateName.c_str())); + fprintf(stderr, "WARNING: Could not create object from template %s\n", + templateName.c_str()); + JavaLibrary::printJavaStack(); + return 0; + } + + jlong const result = createNewObjectInContainerCrc(env, self, crcName.getCrc(), container, slot); + + if (result == 0) + { + fprintf(stderr, "WARNING: Could not create object from crc(%d) string(%s)\n", static_cast(crcName.getCrc()), (!crcName.isEmpty() ? crcName.getString() : "No String")); + JavaLibrary::printJavaStack(); + } + + return result; +} + +//-------------------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsObjectCreateNamespace::createNewObjectInContainerString(JNIEnv *env, jobject self, jobject source, jlong container, jstring slot) +{ + if (source == 0) + return 0; + if (container == 0) + return 0; + + // determine what source is and create the object + std::string templateName; + if (env->IsInstanceOf(source, JavaLibrary::getClsString()) == JNI_TRUE) + { + JavaStringParam localSource(static_cast(source)); + JavaLibrary::convert(localSource, templateName); + } + else + return 0; + + ConstCharCrcString crcName(ObjectTemplateList::lookUp(templateName.c_str())); + if (crcName.getCrc() == 0) + { + WARNING(true, ("[designer bug] JavaLibrary::createNewObjectInContainer " + "called with unknown template %s", templateName.c_str())); + fprintf(stderr, "WARNING: Could not create object from template %s\n", + templateName.c_str()); + JavaLibrary::printJavaStack(); + return 0; + } + + jlong const result = createNewObjectInContainerCrc(env, self, crcName.getCrc(), container, slot); + + if (result == 0) + { + fprintf(stderr, "WARNING: Could not create object from crc(%d) string(%s)\n", static_cast(crcName.getCrc()), (!crcName.isEmpty() ? crcName.getString() : "No String")); + JavaLibrary::printJavaStack(); + } + + return result; +} + +//-------------------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsObjectCreateNamespace::createNewObjectInContainerOverloaded(JNIEnv *env, jobject self, jlong source, jlong container) +{ + if (source == 0) + return 0; + if (container == 0) + return 0; + + // determine what source is and create the object + std::string templateName; + const ServerObject* object = NULL; + if (!JavaLibrary::getObject(source, object)) + return 0; + templateName = object->getTemplateName(); + + ConstCharCrcString crcName(ObjectTemplateList::lookUp(templateName.c_str())); + if (crcName.getCrc() == 0) + { + WARNING(true, ("[designer bug] JavaLibrary::createNewObjectInContainerOverloaded " + "called with unknown template %s", templateName.c_str())); + fprintf(stderr, "WARNING: Could not create object from template %s\n", + templateName.c_str()); + JavaLibrary::printJavaStack(); + return 0; + } + return createNewObjectInContainerOverloadedCrc(env, self, crcName.getCrc(), + container); +} + +//-------------------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsObjectCreateNamespace::createNewObjectInContainerOverloadedString(JNIEnv *env, jobject self, jobject source, jlong container) +{ + if (source == 0) + return 0; + if (container == 0) + return 0; + + // determine what source is and create the object + std::string templateName; + if (env->IsInstanceOf(source, JavaLibrary::getClsString()) == JNI_TRUE) + { + JavaStringParam localSource(static_cast(source)); + JavaLibrary::convert(localSource, templateName); + } + else + return 0; + + ConstCharCrcString crcName(ObjectTemplateList::lookUp(templateName.c_str())); + if (crcName.getCrc() == 0) + { + WARNING(true, ("[designer bug] JavaLibrary::createNewObjectInContainerOverloaded " + "called with unknown template %s", templateName.c_str())); + fprintf(stderr, "WARNING: Could not create object from template %s\n", + templateName.c_str()); + JavaLibrary::printJavaStack(); + return 0; + } + return createNewObjectInContainerOverloadedCrc(env, self, crcName.getCrc(), + container); +} + +//-------------------------------------------------------------------------------- + +/** + * Creates a new object in a creature's inventory, not failing if full. + * + * @param env Java environment + * @param self class calling this function + * @param sourceName the template name used to create the object + * @param target the creature to create the object in + * + * @return the obj_id of the created object, or null on error + */ +jlong JNICALL ScriptMethodsObjectCreateNamespace::createNewObjectInInventoryOverloaded(JNIEnv *env, jobject self, jstring sourceName, jlong target) +{ + if (sourceName == 0 || target == 0) + return 0; + + JavaStringParam jsourceName(sourceName); + std::string objectTemplate; + if (!JavaLibrary::convert(jsourceName, objectTemplate)) + return 0; + + return createNewObjectInInventoryOverloadedCrc(env, self, Crc::calculate( + objectTemplate.c_str()), target); +} // JavaLibrary::createNewObjectInInventoryOverloaded + +//-------------------------------------------------------------------------------- + +/** + * Creates a new object. + * + * @param env Java environment + * @param self class calling this function + * @param sourceCrc the template crc to create the object with + * @param location where to put the object + * + * @return the new object, or null on error + */ +jlong JNICALL ScriptMethodsObjectCreateNamespace::createNewObjectCrc(JNIEnv *env, jobject self, int sourceCrc, jobject location) +{ + UNREF(self); + + if (sourceCrc == 0) + return 0; + if (location == 0) + return 0; + + // @todo: check to see if the location area matches our scene id + Vector newPos; + NetworkId cellId; + if (!ScriptConversion::convert(location, newPos, cellId)) + return 0; + + CellObject * cell = 0; + if (cellId.isValid()) + { + ServerObject * const so = safe_cast(NetworkIdManager::getObjectById(cellId)); + if (so) + cell = so->asCellObject(); + if (!cell) + return 0; + } + + jlong result = 0; + + Transform tr; + tr.setPosition_p(newPos); + ServerObject *newObject = ServerWorld::createNewObject(sourceCrc, tr, cell, false); + if (newObject != NULL) + { + // get the networkId to return + NetworkId netId = newObject->getNetworkId(); + if (netId == NetworkId::cms_invalid) + { + WARNING(true, ("JavaLibrary::createNewObject created object %s, but " + "could not get Java obj_id for it!", newObject->getNetworkId().getValueString().c_str())); + newObject->permanentlyDestroy(DeleteReasons::SetupFailed); + } + else + { + if (!cell) + newObject->addToWorld(); + + result = netId.getValue(); + } + } + else + { + fprintf(stderr, "WARNING: Could not create object from crc %d\n", sourceCrc); + JavaLibrary::printJavaStack(); + } + return result; +} // JavaLibrary::createNewObjectCrc + +//-------------------------------------------------------------------------------- + +/** + * Creates a new object and puts it in another object's container slot. + * + * @param env Java environment + * @param self class calling this function + * @param sourceCrc the template crc to create the object with + * @param container the object we want to put our new object into + * @param slot the container slot we want to put the object in + * + * @return the new object, or null on error + */ +jlong JNICALL ScriptMethodsObjectCreateNamespace::createNewObjectInContainerCrc(JNIEnv *env, jobject self, int sourceCrc, jlong container, jstring slot) +{ + UNREF(self); + + JavaStringParam localSlot(slot); + + if (sourceCrc == 0) + return 0; + if (container == 0) + return 0; + + // make sure the container exists + ServerObject * containerOwner = NULL; + if (!JavaLibrary::getObject(container, containerOwner)) + return 0; + if (ContainerInterface::getContainer(*containerOwner) == NULL) + return 0; + + //Create the object + ServerObject* target = 0; + + SlottedContainer * const slottedContainer = ContainerInterface::getSlottedContainer(*containerOwner); + if (slottedContainer) + { + std::string slotName; + if (!JavaLibrary::convert(localSlot, slotName)) + { + delete target; + return 0; + } + if (slotName == "") + { + target = ServerWorld::createNewObject(sourceCrc, *containerOwner, false); + } + else + { + const SlotId slotId = SlotIdManager::findSlotId(CrcLowerString(slotName.c_str())); + target = ServerWorld::createNewObject(sourceCrc, *containerOwner, slotId, false); + } + } + else + { + target = ServerWorld::createNewObject(sourceCrc, *containerOwner, false); + } + + if (!target) + { + fprintf(stderr, "WARNING: Could not create object from crc %d\n", sourceCrc); + JavaLibrary::printJavaStack(); + return 0; + } + + //Create its java id + NetworkId netId = target->getNetworkId(); + if (netId == NetworkId::cms_invalid) + { + delete target; + return 0; + } + + return netId.getValue(); +} // JavaLibrary::createNewObjectInContainerCrc + +//-------------------------------------------------------------------------------- + +/** + * + */ +jlong JNICALL ScriptMethodsObjectCreateNamespace::createNewObjectInContainerOverloadedCrc(JNIEnv *env, jobject self, int sourceCrc, jlong container) +{ + UNREF(self); + + if (sourceCrc == 0) + return 0; + if (container == 0) + return 0; + + // make sure the container exists + ServerObject * containerOwner = NULL; + if (!JavaLibrary::getObject(container, containerOwner)) + return 0; + if (ContainerInterface::getVolumeContainer(*containerOwner) == NULL) + { + DEBUG_WARNING(true, ("createObjectin an overloaded container only works on volume containers")); + return 0; + } + + ServerObject* target = ServerWorld::createNewObject(sourceCrc, *containerOwner, false, true); + if (!target) + { + fprintf(stderr, "WARNING: Could not create object from crc %d\n", sourceCrc); + JavaLibrary::printJavaStack(); + return 0; + } + + //Create its java id + NetworkId netId = target->getNetworkId(); + if (netId == NetworkId::cms_invalid) + { + delete target; + return 0; + } + + return netId.getValue(); +} // JavaLibrary::createNewObjectInContainerOverloadedCrc + +//-------------------------------------------------------------------------------- + +/** + * Creates a new object in a creature's inventory, not failing if full. + * + * @param env Java environment + * @param self class calling this function + * @param sourceCrc the template crc used to create the object + * @param target the creature to create the object in + * + * @return the obj_id of the created object, or null on error + */ +jlong JNICALL ScriptMethodsObjectCreateNamespace::createNewObjectInInventoryOverloadedCrc( + JNIEnv *env, jobject self, int sourceCrc, jlong target) +{ + if (sourceCrc == 0 || target == 0) + return 0; + + CreatureObject * targetObject = NULL; + if (!JavaLibrary::getObject(target, targetObject)) + return 0; + + ServerObject * inventory = targetObject->getInventory(); + if (inventory == NULL) + return 0; + + VolumeContainer * volContainer = ContainerInterface::getVolumeContainer(*inventory); + if (volContainer == NULL) + return 0; + + int oldCapacity = volContainer->debugDoNotUseSetCapacity(-1); + + ServerObject * newObject = ServerWorld::createNewObject(sourceCrc, *inventory, false, true); + + volContainer->debugDoNotUseSetCapacity(oldCapacity); + volContainer->recalculateVolume(); + + if (newObject == NULL) + return 0; + + return (newObject->getNetworkId()).getValue(); +} // JavaLibrary::createNewObjectInInventoryOverloadedCrc + +//-------------------------------------------------------------------------------- + +/** + * Creates a new object at exactly the location specified by target + * @param env Java environment + * @param self class calling this function + * @param sourceCrc the template crc of the new object to create + * @param target an object whose location and container/cell will be used to create the object. + * @return the obj_id of the created object, or null on error + */ +jlong JNICALL ScriptMethodsObjectCreateNamespace::createNewObjectAtCrc(JNIEnv *env, jobject self, int sourceCrc, jlong target) +{ + UNREF(self); + + if (sourceCrc == 0) + return 0; + if (target == 0) + return 0; + + ServerObject *sourceObject = NULL; + if (!JavaLibrary::getObject(target, sourceObject)) + return 0; + + if (!sourceObject->isInWorld()) + return 0; + + ServerObject *cell = 0; + CellProperty * const cellProperty = sourceObject->getParentCell(); + if (cellProperty && cellProperty != CellProperty::getWorldCellProperty()) + cell = safe_cast(&cellProperty->getOwner()); + + Transform tr; + tr.setPosition_p(sourceObject->getPosition_p()); + ServerObject *newObject = ServerWorld::createNewObject(sourceCrc, tr, cell, false); + if (newObject == NULL) + { + fprintf(stderr, "WARNING: Could not create object from crc %d\n", sourceCrc); + JavaLibrary::printJavaStack(); + return 0; + } + + // create an objId to return + NetworkId netId = newObject->getNetworkId(); + if (netId == NetworkId::cms_invalid) + { + delete newObject; + return 0; + } + + if (!cell) + newObject->addToWorld(); + + return netId.getValue(); +} // JavaLibrary::createNewObjectAtCrc + +//-------------------------------------------------------------------------------- + + +/** + + * Creates a new object, and gives it a playerObject, so it can be used to simulate players + * + * @param env Java environment + * @param self class calling this function + * @param source the template id or the object id to create the object with + * @param location where to put the object + * + * @return the new object, or null on error + */ +jlong JNICALL ScriptMethodsObjectCreateNamespace::createNewObjectSimulator(JNIEnv *env, jobject self, jstring source, jobject location) +{ + if (source == 0) + return 0; + if (location == 0) + return 0; + + // determine what source is and create the object + std::string localName; + if (env->IsInstanceOf(source, JavaLibrary::getClsString()) == JNI_TRUE) + { + JavaStringParam localSource(static_cast(source)); + JavaLibrary::convert(localSource, localName); + } + else + return 0; + + ConstCharCrcString crcName(ObjectTemplateList::lookUp(localName.c_str())); + if (crcName.getCrc() == 0) + { + WARNING(true, ("[designer bug] JavaLibrary::createNewObject called with unknown template %s", localName.c_str())); + fprintf(stderr, "WARNING: Could not create object from template %s\n", localName.c_str()); + JavaLibrary::printJavaStack(); + return 0; + } + + int sourceCrc = crcName.getCrc(); + UNREF(self); + + // @todo: check to see if the location area matches our scene id + Vector newPos; + NetworkId cellId; + if (!ScriptConversion::convert(location, newPos, cellId)) + return 0; + + CellObject * cell = 0; + if (cellId.isValid()) + { + ServerObject * const so = safe_cast(NetworkIdManager::getObjectById(cellId)); + if (so) + cell = so->asCellObject(); + if (!cell) + return 0; + } + + jlong result = 0; + + Transform tr; + tr.setPosition_p(newPos); + ServerObject *newObject = ServerWorld::createNewObject(sourceCrc, tr, cell, false); + if (newObject != NULL) + { + // add on the player object + CreatureObject * creature = dynamic_cast(newObject); + ServerWorld::createNewObject (ConfigServerGame::getPlayerObjectTemplate (), *creature, false); + creature->setPlayerControlled (true); + creature->setAuthoritative (true); + + // create a networkId to return + NetworkId netId = newObject->getNetworkId(); + if (netId == NetworkId::cms_invalid) + { + WARNING(true, ("JavaLibrary::createNewObjectSimulator created object %s, but could not get Java obj_id for it!", newObject->getNetworkId().getValueString().c_str())); + creature->setPlayerControlled (false); + newObject->permanentlyDestroy(DeleteReasons::SetupFailed); + } + else + { + if (!cell) + newObject->addToWorld(); + + result = netId.getValue(); + } + } + else + { + fprintf(stderr, "WARNING: Could not create object from crc %d\n", sourceCrc); + JavaLibrary::printJavaStack(); + } + return result; + +} // JavaLibrary::createNewObjectSimulator + +/** + * Destroys a simulator object. Should only be used for simulator objects + * + * @param env Java environment + * @param self class calling this function + * @param target the object to destroy + * + * @return true on success, false on error + */ +jboolean JNICALL ScriptMethodsObjectCreateNamespace::destroyObjectSimulator(JNIEnv *env, jobject self, jlong target) +{ + CreatureObject *playerObject = NULL; + // get the object + if (!JavaLibrary::getObject(target, playerObject)) + { + WARNING(true, ("JavaLibrary::destroyObjectSimulator : bad player object")); + return JNI_FALSE; + } + + // verify that it is a simulator object - it is playerControlled with no client + if (playerObject->getClient() || !playerObject->isPlayerControlled()) + { + WARNING(true, ("JavaLibrary::destroyObjectSimulator : the object you are trying to destroy (%s) is not a simulator object", playerObject->getNetworkId().getValueString().c_str())); + return JNI_FALSE; + } + + playerObject->setPlayerControlled(false); + + return destroyObject(env, self, target); + +} // JavaLibrary::destroyObjectSimulator + +/** + * Destroys an object. + * + * @param env Java environment + * @param self class calling this function + * @param target the object to destroy + * + * @return true on success, false on error + */ +jboolean JNICALL ScriptMethodsObjectCreateNamespace::destroyObject(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + NOT_NULL(env); + + const NetworkId targetId(target); + if (targetId == NetworkId::cms_invalid) + return JNI_FALSE; + + ServerObject* object = NULL; + bool retval = JavaLibrary::getObject(target, object); + + if (!retval || !object) // || object->isPersisted()) will be done in permanently destroy + { + // flag the object deleted in the database + FlagObjectForDeleteMessage const dm(targetId, DeleteReasons::Script,false,false,false); + GameServer::getInstance().sendToDatabaseServer(dm); + } + // remove the object from the game + if (object) + { + // check if the object is in a FactoryObject crate + Object * container = ContainerInterface::getContainedByObject(*object); + if (container != NULL && dynamic_cast(container) != NULL) + { + // destroy an object in the factory; if it is the last object, + // the factory will destroy itself + FactoryObject * factory = safe_cast(container); + factory->deleteContents(1); + return JNI_TRUE; + } + else + return object->permanentlyDestroy(DeleteReasons::Script); + } + + MessageToQueue::getInstance().sendMessageToC(targetId, "C++DestroySelf", "", 0, false); + return JNI_TRUE; +} // JavaLibrary::destroyObject + +//-------------------------------------------------------------------------------- + +/** + * Destroys an object by hyperspacing it away + * + * @param env Java environment + * @param self class calling this function + * @param target the object to destroy + * + * @return true on success, false on error + */ +jboolean JNICALL ScriptMethodsObjectCreateNamespace::destroyObjectHyperspace(JNIEnv *env, jobject self, jlong target) +{ + const NetworkId targetId(target); + if (targetId == NetworkId::cms_invalid) + return JNI_FALSE; + + ServerObject * object = NULL; + bool retval = JavaLibrary::getObject(target, object); + if(retval && object) + { + object->setHyperspaceOnDestroy(true); + return destroyObject(env, self, target); + } + else + return JNI_FALSE; +} // JavaLibrary::destroyObjectHyperspace + +//-------------------------------------------------------------------------------- + +/** + * Persists an object to the database. + * + * @param env Java environment + * @param self class calling this function + * @param target the object to persist + * + * @return true on success, false on error + */ +jboolean JNICALL ScriptMethodsObjectCreateNamespace::persistObject(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + NOT_NULL(env); + + ServerObject* object = NULL; + if (!JavaLibrary::getObject(target, object)) + return JNI_FALSE; + object->persist(); + return JNI_TRUE; +} // JavaLibrary::persistObject + +/** + * Checks if an object has been persisted to the database. + * + * @param env Java environment + * @param self class calling this function + * @param target the object to check + * + * @return JNI_TRUE if the object is persisted, JNI_FALSE if not + */ +jboolean JNICALL ScriptMethodsObjectCreateNamespace::isObjectPersisted(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + NOT_NULL(env); + + ServerObject* object = NULL; + if (!JavaLibrary::getObject(target, object)) + return JNI_FALSE; + + if (object->isPersisted()) + return JNI_TRUE; + return JNI_FALSE; +} // JavaLibrary::isObjectPersisted + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsObjectCreateNamespace::reloadPathNodes(JNIEnv *env, jobject self, jlongArray target) +{ + UNREF(self); + NOT_NULL(env); + + std::vector targetIds; + if (!ScriptConversion::convert(target, targetIds)) + return JNI_FALSE; + + std::vector objectList; + + int targetCount = targetIds.size(); + for(int i = 0; i < targetCount; i++) + { + ServerObject * serverObject = ServerWorld::findObjectByNetworkId(targetIds[i]); + + if(serverObject) objectList.push_back(serverObject); + } + + CityPathGraphManager::reloadPathNodes(objectList); + + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsObjectCreateNamespace::getObjectTemplateName(JNIEnv *env, jobject self, jint crc) +{ + JavaString str(ObjectTemplateList::lookUp(crc).getString()); + return str.getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsObjectCreateNamespace::getObjectTemplateCrc(JNIEnv *env, jobject self, jstring name) +{ + JavaStringParam localName(name); + std::string templateName; + JavaLibrary::convert(localName, templateName); + return ObjectTemplateList::lookUp(templateName.c_str()).getCrc(); +} + +// ---------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsObjectCreateNamespace::createNewObjectTransform(JNIEnv *env, jobject self, jstring templateName, jobject transform, jlong cell) +{ + return createNewObjectTransformInternal(env, self, templateName, transform, cell, false); +} + +// ---------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsObjectCreateNamespace::createNewObjectTransformHyperspace(JNIEnv *env, jobject self, jstring templateName, jobject transform, jlong cell) +{ + return createNewObjectTransformInternal(env, self, templateName, transform, cell, true); +} + +// ---------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsObjectCreateNamespace::createNewObjectTransformInternal(JNIEnv *env, jobject self, jstring templateName, jobject transform, jlong cell, bool const hyperspace) +{ + std::string localName; + JavaStringParam localSource(templateName); + if (!JavaLibrary::convert(localSource, localName)) + JavaLibrary::throwInternalScriptError("JavaLibrary::createNewObjectTransform - bad template name"); + else + { + ConstCharCrcString crcName(ObjectTemplateList::lookUp(localName.c_str())); + if (crcName.getCrc() == 0) + { + char buf[256]; + snprintf(buf, sizeof(buf), "JavaLibrary::createNewObjectTransform - unknown template %s", localName.c_str()); + JavaLibrary::throwInternalScriptError(buf); + } + else + return createNewObjectTransformCrcInternal(env, self, crcName.getCrc(), transform, cell, hyperspace); + } + return 0; +} + +// ---------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsObjectCreateNamespace::createNewObjectTransformCrc(JNIEnv *env, jobject self, jint templateCrc, jobject transform, jlong cell) +{ + return createNewObjectTransformCrcInternal(env, self, templateCrc, transform, cell, false); +} + +// ---------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsObjectCreateNamespace::createNewObjectTransformCrcHyperspace(JNIEnv *env, jobject self, jint templateCrc, jobject transform, jlong cell) +{ + return createNewObjectTransformCrcInternal(env, self, templateCrc, transform, cell, true); +} + +// ---------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsObjectCreateNamespace::createNewObjectTransformCrcInternal(JNIEnv *env, jobject self, jint templateCrc, jobject transform, jlong jcell, bool const hyperspace) +{ + NetworkId const cellId(jcell); + CellObject *cell = 0; + + if (cellId.isValid()) + { + Object * const o = NetworkIdManager::getObjectById(cellId); + if (o) + { + ServerObject * so = o->asServerObject(); + if (so) + cell = so->asCellObject(); + } + if (!cell) + return 0; + } + + Transform newTransform; + if (!ScriptConversion::convert(transform, newTransform)) + { + char buf[256]; + snprintf(buf, sizeof(buf), "JavaLibrary::createNewObjectTransform - bad transform (template crc %08x)", templateCrc); + JavaLibrary::throwInternalScriptError(buf); + } + else + { + ServerObject *newObject = ServerWorld::createNewObject(templateCrc, newTransform, cell, false, hyperspace); + if (!newObject) + { + char buf[256]; + snprintf(buf, sizeof(buf), "JavaLibrary::createNewObjectTransform - ServerWorld::createNewObject failed (template crc %08x, cell %s)", templateCrc, cell ? cell->getNetworkId().getValueString().c_str() : "0"); + JavaLibrary::throwInternalScriptError(buf); + } + else + { + // create an objId to return + NetworkId netId = newObject->getNetworkId(); + if (netId == NetworkId::cms_invalid) + { + char buf[256]; + snprintf(buf, sizeof(buf), "JavaLibrary::createNewObjectTransform - object %s created but could not get java obj_id for it", newObject->getNetworkId().getValueString().c_str()); + JavaLibrary::throwInternalScriptError(buf); + newObject->permanentlyDestroy(DeleteReasons::SetupFailed); + } + else + { + if (!cell) + newObject->addToWorld(); + return netId.getValue(); + } + } + } + return 0; +} + +// ---------------------------------------------------------------------- + +/** + * Creates a group of objects centered at a given position. The first entry in + * the datatable will define the base position of the theater and an optional + * script to be attached to the master theater object. + * + * @param env Java environment + * @param self class calling this function + * @param datatable file name of the datatable to read the objects from + * @param caller who's creating the theater + * @param name the name of the theater + * @param locationType how to create the theater + * + * @return the id of the master theater object, or null on error (bad datatable name or position) + */ +jlong JNICALL ScriptMethodsObjectCreateNamespace::createTheaterDatatableOnly(JNIEnv *env, jobject self, jstring datatable, jlong caller, jstring name, jint locationType) +{ +int i; + + if (datatable == 0) + return 0; + + // convert the Java data to C + JavaStringParam jdatatable(datatable); + std::string datatableName; + if (!JavaLibrary::convert(jdatatable, datatableName)) + return 0; + + NetworkId callerId(caller); + + std::string theaterName; + if (name != 0) + { + JavaStringParam jname(name); + if (!JavaLibrary::convert(jname, theaterName)) + return 0; + } + + // read the object data from the datatable + DataTable * dt = DataTableManager::getTable(datatableName, true); + if (dt == NULL) + { + WARNING(true, ("JavaLibrary::createTheaterDatatable could not open " + "datatable %s", datatableName.c_str())); + return 0; + } + int rows = dt->getNumRows(); + if (rows <= 0) + { + WARNING(true, ("JavaLibrary::createTheaterDatatable datatable %s has no " + "rows", datatableName.c_str())); + return 0; + } + // the 1st row is master object data so there needs to be at least 2 rows + if (rows == 1) + { + WARNING(true, ("JavaLibrary::createTheaterDatatable datatable %s has no " + "object rows", datatableName.c_str())); + return 0; + } + + int templateColumn = dt->findColumnNumber("template"); + int xColumn = dt->findColumnNumber("x"); + int yColumn = dt->findColumnNumber("y"); + int zColumn = dt->findColumnNumber("z"); + int headingColumn = dt->findColumnNumber("heading"); + int scriptColumn = dt->findColumnNumber("script"); + + Vector theaterCenter; + std::vector objectCrcs; + std::vector objectPositions(rows - 1); + std::vector objectHeadings(rows - 1); + std::vector objectScripts(rows - 1); + std::vector tempPos; + + dt->getIntColumn(templateColumn, objectCrcs); + objectCrcs.erase(objectCrcs.begin()); + + dt->getFloatColumn(xColumn, tempPos); + theaterCenter.x = tempPos[0]; + for (i = 1; i < rows; ++i) + objectPositions[i-1].x = tempPos[i]; + dt->getFloatColumn(yColumn, tempPos); + theaterCenter.y = tempPos[0]; + for (i = 1; i < rows; ++i) + objectPositions[i-1].y = tempPos[i]; + dt->getFloatColumn(zColumn, tempPos); + theaterCenter.z = tempPos[0]; + for (i = 1; i < rows; ++i) + objectPositions[i-1].z = tempPos[i]; + dt->getFloatColumn(headingColumn, tempPos); + for (i = 1; i < rows; ++i) + objectHeadings[i-1] = tempPos[i]; + + std::string theaterScript; + std::vector scripts; + dt->getStringColumn(scriptColumn, scripts); + theaterScript = scripts[0]; + for (i = 1; i < rows; ++i) + { + objectScripts[i-1] = scripts[i]; + } + + // start the creation process + return createTheater(objectCrcs, objectPositions, objectHeadings, objectScripts, theaterCenter, theaterScript, callerId, theaterName, locationType); +} // JavaLibrary::createTheaterDatatableOnly + +/** + * Creates a group of objects centered at a given position. + * + * @param env Java environment + * @param self class calling this function + * @param datatable file name of the datatable to read the objects from + * @param basePosition the base position of the theater; all objects will be + * placed relative to here + * @param script optional script to be attached to the master theater object; + * the trigger OnTheaterCreated will be called when all the + * theater objects have been created + * @param caller who's creating the theater + * @param name the name of the theater + * @param locationType how to create the theater + * + * @return the id of the master theater object, or null on error (bad datatable name or position) + */ +jlong JNICALL ScriptMethodsObjectCreateNamespace::createTheaterDatatable(JNIEnv *env, jobject self, jstring datatable, jobject basePosition, jstring script, jlong caller, jstring name, jint locationType) +{ +int i; + + if (datatable == 0 || basePosition == 0) + return 0; + + // convert the Java data to C + JavaStringParam jdatatable(datatable); + std::string datatableName; + Vector theaterCenter; + std::string theaterScript; + if (!JavaLibrary::convert(jdatatable, datatableName)) + return 0; + if (!ScriptConversion::convertWorld(basePosition, theaterCenter)) + return 0; + if (script != 0) + { + JavaStringParam jscript(script); + if (!JavaLibrary::convert(jscript, theaterScript)) + return 0; + } + + NetworkId callerId(caller); + + std::string theaterName; + if (name != 0) + { + JavaStringParam jname(name); + if (!JavaLibrary::convert(jname, theaterName)) + return 0; + } + + // read the object data from the datatable + DataTable * dt = DataTableManager::getTable(datatableName, true); + if (dt == NULL) + { + WARNING(true, ("JavaLibrary::createTheaterDatatable could not open " + "datatable %s", datatableName.c_str())); + return 0; + } + int rows = dt->getNumRows(); + if (rows <= 0) + { + WARNING(true, ("JavaLibrary::createTheaterDatatable datatable %s has no " + "rows", datatableName.c_str())); + return 0; + } + + int templateColumn = dt->findColumnNumber("template"); + int xColumn = dt->findColumnNumber("x"); + int yColumn = dt->findColumnNumber("y"); + int zColumn = dt->findColumnNumber("z"); + int headingColumn = dt->findColumnNumber("heading"); + int scriptColumn = dt->findColumnNumber("script"); + + std::vector objectCrcs; + std::vector objectPositions(rows); + std::vector objectHeadings; + std::vector objectScripts(rows); + std::vector tempPos; + + dt->getIntColumn(templateColumn, objectCrcs); + dt->getFloatColumn(headingColumn, objectHeadings); + dt->getFloatColumn(xColumn, tempPos); + for (i = 0; i < rows; ++i) + objectPositions[i].x = tempPos[i]; + dt->getFloatColumn(yColumn, tempPos); + for (i = 0; i < rows; ++i) + objectPositions[i].y = tempPos[i]; + dt->getFloatColumn(zColumn, tempPos); + for (i = 0; i < rows; ++i) + { + objectPositions[i].z = tempPos[i]; + objectScripts[i] = dt->getStringValue(scriptColumn, i); + } + + // start the creation process + return createTheater(objectCrcs, objectPositions, objectHeadings, objectScripts, theaterCenter, theaterScript, callerId, theaterName, locationType); +} // JavaLibrary::createTheaterDatatable + +// ---------------------------------------------------------------------- + +/** + * Creates a group of objects centered at a given position. The first entry in + * the datatable will define the base position of the theater and an optional + * script to be attached to the master theater object. The difference between + * this command and createTheater is that this will work if the theater is created + * on a different server than the one the command is called from, although the caller + * and the theater must still be on the same planet. + * + * @param env Java environment + * @param self class calling this function + * @param datatable file name of the datatable to read the objects from + * @param caller who's creating the theater + * @param name the name of the theater + * @param locationType how to create the theater + * + * @return true on success, or false on error (bad datatable name) + */ +jboolean JNICALL ScriptMethodsObjectCreateNamespace::createRemoteTheaterDatatableOnly(JNIEnv *env, jobject self, jstring datatable, jlong caller, jstring name, jint locationType) +{ + if (datatable == 0) + return JNI_FALSE; + + // convert the Java data to C + JavaStringParam jdatatable(datatable); + std::string datatableName; + if (!JavaLibrary::convert(jdatatable, datatableName)) + return JNI_FALSE; + + NetworkId callerId(caller); + + std::string theaterName; + if (name != 0) + { + JavaStringParam jname(name); + if (!JavaLibrary::convert(jname, theaterName)) + return JNI_FALSE; + if (!theaterName.empty()) + { + // make sure the theater doesn't exist + const NetworkId & oldTheater = ServerUniverse::getInstance().findTheaterId(theaterName); + if (oldTheater != NetworkId::cms_invalid) + { + WARNING(true, ("JavaLibrary::createRemoteTheaterDatatableOnly " + "asked to create theater with name %s which is already " + "assigned to theater %s", theaterName.c_str(), + oldTheater.getValueString().c_str())); + return JNI_FALSE; + } + } + } + + // read the object data from the datatable + DataTable * dt = DataTableManager::getTable(datatableName, true); + if (dt == NULL) + { + WARNING(true, ("JavaLibrary::createRemoteTheaterDatatable could not open " + "datatable %s", datatableName.c_str())); + return JNI_FALSE; + } + int rows = dt->getNumRows(); + if (rows <= 0) + { + WARNING(true, ("JavaLibrary::createRemoteTheaterDatatable datatable %s " + "has no rows", datatableName.c_str())); + return JNI_FALSE; + } + // the 1st row is master object data so there needs to be at least 2 rows + if (rows == 1) + { + WARNING(true, ("JavaLibrary::createRemoteTheaterDatatable datatable %s " + "has no object rows", datatableName.c_str())); + return JNI_FALSE; + } + + if (static_cast(dt->getIntValue("template", 0)) != Crc::normalizeAndCalculate("THEATER")) + { + WARNING(true, ("JavaLibrary::createRemoteTheaterDatatable datatable %s " + "first entry not THEATER", datatableName.c_str())); + return JNI_FALSE; + } + + Vector location; + location.x = dt->getFloatValue("x", 0); + location.y = dt->getFloatValue("y", 0); + location.z = dt->getFloatValue("z", 0); + + // + // create a "theater spawner" at the destination, and send it a message + // telling it what theater to spawn + // + + // create the packed dictionary we are going to send to the theater spawner + ScriptParams params; + params.addParam(datatableName.c_str(), "datatable"); + params.addParam(callerId, "caller"); + params.addParam(theaterName.c_str(), "name"); + params.addParam(locationType, "locationType"); + ScriptDictionaryPtr dictionary; + GameScriptObject::makeScriptDictionary(params, dictionary); + if (dictionary.get() == NULL) + { + WARNING(true, ("JavaLibrary::createRemoteTheaterDatatable could not " + "create dictionary for theater datatable %s", datatableName.c_str())); + return JNI_FALSE; + } + + // create the spawner + Transform tr; + tr.setPosition_p(location); + ServerObject * spawner = ServerWorld::createNewObject("object/tangible/spawning/remote_theater_spawner.iff", tr, 0, false); + if (spawner == NULL) + { + WARNING(true, ("JavaLibrary::createRemoteTheaterDatatable unable to " + "create remote theater spawner for datatable %s", datatableName.c_str())); + return JNI_FALSE; + } + spawner->addToWorld(); + + // tell the spawner what to create + dictionary->serialize(); + MessageToQueue::getInstance().sendMessageToJava(spawner->getNetworkId(), + "handleCreateRemoteTheater", dictionary->getSerializedData(), 1, false); + return JNI_TRUE; +} // JavaLibrary::createRemoteTheaterDatatableOnly + +// ---------------------------------------------------------------------- + +/** + * Creates a group of objects centered at a given position. The difference between this command and createTheater + * is that this will work if the theater is created on a different server than the one the command is called from, + * although the caller and the theater must still be on the same planet. + * + * @param env Java environment + * @param self class calling this function + * @param datatable file name of the datatable to read the objects from + * @param basePosition the base position of the theater; all objects will be placed relative to here + * @param script optional script to be attached to the master theater object; the trigger OnTheaterCreated + * will be called when all the theater objects have been created + * @param caller who's creating the theater + * @param name the name of the theater + * @param locationType how to create the theater + * + * @return true on success, or false on error (bad datatable name) + */ +jboolean JNICALL ScriptMethodsObjectCreateNamespace::createRemoteTheaterDatatable(JNIEnv *env, jobject self, jstring datatable, jobject basePosition, jstring script, jlong caller, jstring name, jint locationType) +{ + if (datatable == 0 || basePosition == 0) + return JNI_FALSE; + + // convert the Java data to C + JavaStringParam jdatatable(datatable); + std::string datatableName; + Vector theaterCenter; + std::string theaterScript; + if (!JavaLibrary::convert(jdatatable, datatableName)) + return JNI_FALSE; + if (!ScriptConversion::convertWorld(basePosition, theaterCenter)) + return JNI_FALSE; + if (script != 0) + { + JavaStringParam jscript(script); + if (!JavaLibrary::convert(jscript, theaterScript)) + return JNI_FALSE; + } + + NetworkId callerId(caller); + + std::string theaterName; + if (name != 0) + { + JavaStringParam jname(name); + if (!JavaLibrary::convert(jname, theaterName)) + return JNI_FALSE; + if (!theaterName.empty()) + { + // make sure the theater doesn't exist + const NetworkId & oldTheater = ServerUniverse::getInstance().findTheaterId(theaterName); + if (oldTheater != NetworkId::cms_invalid) + { + WARNING(true, ("JavaLibrary::createRemoteTheaterDatatable asked " + "to create theater with name %s which is already assigned " + "to theater %s", theaterName.c_str(), + oldTheater.getValueString().c_str())); + return JNI_FALSE; + } + } + } + + // read the object data from the datatable + DataTable * dt = DataTableManager::getTable(datatableName, true); + if (dt == NULL) + { + WARNING(true, ("JavaLibrary::createRemoteTheaterDatatable could not open " + "datatable %s", datatableName.c_str())); + return JNI_FALSE; + } + int rows = dt->getNumRows(); + if (rows <= 0) + { + WARNING(true, ("JavaLibrary::createRemoteTheaterDatatable datatable %s has no " + "rows", datatableName.c_str())); + return JNI_FALSE; + } + + // + // create a "theater spawner" at the destination, and send it a message + // telling it what theater to spawn + // + + // create the packed dictionary we are going to send to the theater spawner + ScriptParams params; + params.addParam(datatableName.c_str(), "datatable"); + params.addParam(theaterCenter.x, "x"); + params.addParam(theaterCenter.z, "z"); + params.addParam(theaterScript.c_str(), "script"); + params.addParam(callerId, "caller"); + params.addParam(theaterName.c_str(), "name"); + params.addParam(locationType, "locationType"); + ScriptDictionaryPtr dictionary; + GameScriptObject::makeScriptDictionary(params, dictionary); + if (dictionary.get() == NULL) + { + WARNING(true, ("JavaLibrary::createRemoteTheaterDatatable could not " + "create dictionary for theater datatable %s", datatableName.c_str())); + return JNI_FALSE; + } + LOG("theater", ("createRemoteTheaterDatatable will create theater at %f, %f\n", + theaterCenter.x, theaterCenter.z)); + + // create the spawner + Transform tr; + tr.setPosition_p(theaterCenter); + ServerObject * spawner = ServerWorld::createNewObject("object/tangible/spawning/remote_theater_spawner.iff", tr, 0, false); + if (spawner == NULL) + { + WARNING(true, ("JavaLibrary::createRemoteTheaterDatatable unable to " + "create remote theater spawner for datatable %s", datatableName.c_str())); + return JNI_FALSE; + } + spawner->addToWorld(); + + // tell the spawner what to create + dictionary->serialize(); + MessageToQueue::getInstance().sendMessageToJava(spawner->getNetworkId(), + "handleCreateRemoteTheater", dictionary->getSerializedData(), 1, false); + return JNI_TRUE; +} // JavaLibrary::createRemoteTheaterDatatable + +// ---------------------------------------------------------------------- + +/** + * Creates a group of objects centered at a given position. + * + * @param env Java environment + * @param self class calling this function + * @param crcs template crcs of the objects to create + * @param positions where to create the objects, relative to the theater center + * @param basePosition the base position of the theater; all objects will be + * placed relative to here + * @param script optional script to be attached to the master theater object; + * the trigger OnTheaterCreated will be called when all the + * theater objects have been created + * @param caller who's creating the theater + * + * @return the id of the master theater object, or null on error + */ +jlong JNICALL ScriptMethodsObjectCreateNamespace::createTheaterCrc(JNIEnv *env, jobject self, jintArray crcs, jobjectArray positions, jobject basePosition, jstring script, jlong caller) +{ + if (crcs == 0 || positions == 0 || basePosition == 0) + return 0; + + // make sure the arrays are good + jsize crcCount = env->GetArrayLength(crcs); + jsize posCount = env->GetArrayLength(positions); + if (crcCount != posCount) + { + WARNING(true, ("JavaLibrary::createTheaterCrc crc and position arrays do " + "not match")); + return 0; + } + if (crcCount == 0 || posCount == 0) + { + WARNING(true, ("JavaLibrary::createTheaterCrc 0-length crc or position " + "arrays")); + return 0; + } + + // convert Java data to C + std::vector objectCrcs(crcCount); + std::vector objectPositions; + Vector theaterCenter; + std::string theaterScript; + env->GetIntArrayRegion(crcs, 0, crcCount, &objectCrcs[0]); + if (!ScriptConversion::convertWorld(positions, objectPositions)) + return 0; + if (!ScriptConversion::convertWorld(basePosition, theaterCenter)) + return 0; + if (script != 0) + { + JavaStringParam jscript(script); + if (!JavaLibrary::convert(jscript, theaterScript)) + return 0; + } + + NetworkId callerId(caller); + + // start the creation process + std::vector const emptyFloatVector; + std::vector const emptyStringVector; + std::string const emptyString; + return createTheater(objectCrcs, objectPositions, emptyFloatVector, emptyStringVector, theaterCenter, theaterScript, callerId, emptyString, IntangibleObject::TLT_getGoodLocation); +} // JavaLibrary::createTheaterCrc + +// ---------------------------------------------------------------------- + +/** + * Creates a group of objects centered at a given position. + * + * @param env Java environment + * @param self class calling this function + * @param templates template names of the objects to create + * @param positions where to create the objects, relative to the theater center + * @param basePosition the base position of the theater; all objects will be + * placed relative to here + * @param script optional script to be attached to the master theater object; + * the trigger OnTheaterCreated will be called when all the + * theater objects have been created + * @param caller who's creating the theater + * + * @return the id of the master theater object, or null on error + */ +jlong JNICALL ScriptMethodsObjectCreateNamespace::createTheaterString(JNIEnv *env, jobject self, jobjectArray templates, jobjectArray positions, jobject basePosition, jstring script, jlong caller) +{ + if (templates == 0 || positions == 0 || basePosition == 0) + return 0; + + // make sure the arrays are good + jsize templatesCount = env->GetArrayLength(templates); + jsize posCount = env->GetArrayLength(positions); + if (templatesCount != posCount) + { + WARNING(true, ("JavaLibrary::createTheaterString template and position " + "arrays do not match")); + return 0; + } + if (templatesCount == 0 || posCount == 0) + { + WARNING(true, ("JavaLibrary::createTheaterString 0-length tempalte or " + "position arrays")); + return 0; + } + + // convert Java data to C + std::vector objectTemplates; + std::vector objectCrcs(templatesCount); + std::vector objectPositions; + Vector theaterCenter; + std::string theaterScript; + if (!ScriptConversion::convert(templates, objectTemplates)) + return 0; + if (!ScriptConversion::convertWorld(positions, objectPositions)) + return 0; + if (!ScriptConversion::convertWorld(basePosition, theaterCenter)) + return 0; + if (script != 0) + { + JavaStringParam jscript(script); + if (!JavaLibrary::convert(jscript, theaterScript)) + return 0; + } + + NetworkId callerId(caller); + + // convert the template names to crcs + for (jsize i = 0; i < templatesCount; ++i) + objectCrcs[i] = Crc::calculate(objectTemplates[i].c_str()); + + // start the creation process + std::vector const emptyFloatVector; + std::vector const emptyStringVector; + std::string const emptyString; + return createTheater(objectCrcs, objectPositions, emptyFloatVector, emptyStringVector, theaterCenter, theaterScript, callerId, emptyString, IntangibleObject::TLT_getGoodLocation); +} // JavaLibrary::createTheaterString + +// ---------------------------------------------------------------------- + +/** + * Causes a theater to be created when a player gets near its location. We only allow one theater to + * be assigned to a player at a time. + * + * @param env Java environment + * @param self class calling this function + * @param playerId the player who will cause the theater to be created + * @param datatable the datatable to read the theater data from; the 1st entry in the + * datatable defines its location, see createTheater(datatable) above + * @param caller who's creating the theater + * @param name the name of the theater + * @param locationType how to create the theater + * + * @return true on success, false on error + */ +jboolean JNICALL ScriptMethodsObjectCreateNamespace::assignTheaterToPlayer(JNIEnv *env, jobject self, jlong playerId, jstring datatable, jlong caller, jstring name, jint locationType) +{ + if (playerId == 0 || datatable == 0) + return JNI_FALSE; + + JavaStringParam jdatatable(datatable); + + CreatureObject * playerCreature = NULL; + if (!JavaLibrary::getObject(playerId, playerCreature)) + return JNI_FALSE; + + PlayerObject * const player = PlayerCreatureController::getPlayerObject( + playerCreature); + if (player == NULL) + return JNI_FALSE; + + if (player->hasTheater()) + return JNI_FALSE; + + std::string datatableName; + if (!JavaLibrary::convert(jdatatable, datatableName)) + return JNI_FALSE; + + NetworkId callerId(caller); + + std::string theaterName; + if (name != 0) + { + JavaStringParam jname(name); + if (!JavaLibrary::convert(jname, theaterName)) + return JNI_FALSE; + if (!theaterName.empty()) + { + // make sure the theater doesn't exist + const NetworkId & oldTheater = ServerUniverse::getInstance().findTheaterId(theaterName); + if (oldTheater != NetworkId::cms_invalid) + { + WARNING(true, ("JavaLibrary::assignTheaterToPlayer asked to create " + "theater with name %s which is already assigned to theater %s", + theaterName.c_str(), oldTheater.getValueString().c_str())); + return JNI_FALSE; + } + } + } + + // read the object data from the datatable + DataTable * dt = DataTableManager::getTable(datatableName, true); + if (dt == NULL) + { + WARNING(true, ("JavaLibrary::assignTheaterToPlayer could not open " + "datatable %s", datatableName.c_str())); + return JNI_FALSE; + } + int rows = dt->getNumRows(); + if (rows <= 0) + { + WARNING(true, ("JavaLibrary::assignTheaterToPlayer datatable %s has no " + "rows", datatableName.c_str())); + return JNI_FALSE; + } + + int templateColumn = dt->findColumnNumber("template"); + int xColumn = dt->findColumnNumber("x"); + int yColumn = dt->findColumnNumber("y"); + int zColumn = dt->findColumnNumber("z"); + int sceneColumn = dt->findColumnNumber("scene"); + int scriptColumn = dt->findColumnNumber("script"); + + if (static_cast(dt->getIntValue(templateColumn, 0)) == THEATER_DATATABLE_TAG) + return JNI_FALSE; + + Vector position; + std::string scene; + std::string script; + + position.x = dt->getFloatValue(xColumn, 0); + position.y = dt->getFloatValue(yColumn, 0); + position.z = dt->getFloatValue(zColumn, 0); + scene = dt->getStringValue(sceneColumn, 0); + script = dt->getStringValue(scriptColumn, 0); + + return player->setTheater(datatableName, position, scene, script, callerId, + theaterName, static_cast(locationType)); +} // JavaLibrary::assignTheaterToPlayer + +// ---------------------------------------------------------------------- + +/** + * Causes a theater to be created when a player gets near its location. + * + * @param env Java environment + * @param self class calling this function + * @param playerId the player who will cause the theater to be created + * @param datatable the datatable to read the theater data from + * @param basePosition the base position of the theater; all objects will be placed relative to here + * @param script optional script to be attached to the master theater object; the trigger OnTheaterCreated + * will be called when all the theater objects have been created + * @param caller who's creating the theater + * @param name the name of the theater + * @param locationType how to create the theater + * + * @return true on success, false on error + */ +jboolean JNICALL ScriptMethodsObjectCreateNamespace::assignTheaterToPlayerLocation(JNIEnv *env, jobject self, jlong playerId, jstring datatable, jobject basePosition, jstring script, jlong caller, jstring name, jint locationType) +{ + if (playerId == 0 || datatable == 0 || basePosition == 0) + return JNI_FALSE; + + JavaStringParam jdatatable(datatable); + JavaStringParam jscript(script); + + CreatureObject * playerCreature = NULL; + if (!JavaLibrary::getObject(playerId, playerCreature)) + return JNI_FALSE; + + PlayerObject * const player = PlayerCreatureController::getPlayerObject( + playerCreature); + if (player == NULL) + return JNI_FALSE; + + std::string datatableName; + if (!JavaLibrary::convert(jdatatable, datatableName)) + return JNI_FALSE; + + Vector position; + std::string scene; + if (!ScriptConversion::convertWorld(basePosition, position, scene)) + return JNI_FALSE; + + std::string scriptName; + if (script != 0) + { + if (!JavaLibrary::convert(jscript, scriptName)) + return JNI_FALSE; + } + + NetworkId callerId(caller); + + std::string theaterName; + if (name != 0) + { + JavaStringParam jname(name); + if (!JavaLibrary::convert(jname, theaterName)) + return JNI_FALSE; + if (!theaterName.empty()) + { + // make sure the theater doesn't exist + const NetworkId & oldTheater = ServerUniverse::getInstance().findTheaterId(theaterName); + if (oldTheater != NetworkId::cms_invalid) + { + WARNING(true, ("JavaLibrary::assignTheaterToPlayerLocation asked " + "to create theater with name %s which is already assigned " + "to theater %s", theaterName.c_str(), + oldTheater.getValueString().c_str())); + return JNI_FALSE; + } + } + } + + return player->setTheater(datatableName, position, scene, scriptName, + callerId, theaterName, static_cast(locationType)); +} // JavaLibrary::assignTheaterToPlayerLocation + +// ---------------------------------------------------------------------- + +/** + * Causes any theater assigned to a player to be unassigned. + * + * @param env Java environment + * @param self class calling this function + * @param playerId the player to remove the theater from + * + * @return true on success, false on error + */ +jboolean JNICALL ScriptMethodsObjectCreateNamespace::unassignTheaterFromPlayer(JNIEnv *env, jobject self, jlong playerId) +{ + if (playerId == 0) + return JNI_FALSE; + + CreatureObject * playerCreature = NULL; + if (!JavaLibrary::getObject(playerId, playerCreature)) + return JNI_FALSE; + + PlayerObject * const player = PlayerCreatureController::getPlayerObject( + playerCreature); + if (player == NULL) + return JNI_FALSE; + + player->clearTheater(); + return JNI_TRUE; +} // JavaLibrary::unassignTheaterFromPlayer + +// ---------------------------------------------------------------------- + +/** + * Checks if a player has a theater assigned to him. + * + * @param env Java environment + * @param self class calling this function + * @param playerId the player to check + * + * @return true if the player is assigned a theater, false if not + */ +jboolean JNICALL ScriptMethodsObjectCreateNamespace::hasTheaterAssigned(JNIEnv *env, jobject self, jlong playerId) +{ + if (playerId == 0) + return JNI_FALSE; + + const CreatureObject * playerCreature = NULL; + if (!JavaLibrary::getObject(playerId, playerCreature)) + return JNI_FALSE; + + const PlayerObject * player = PlayerCreatureController::getPlayerObject( + playerCreature); + if (player == NULL) + return JNI_FALSE; + + return player->hasTheater(); +} // JavaLibrary::hasTheaterAssigned + +// ---------------------------------------------------------------------- + +/** + * Returns the name of a theater. + * + * @param theater the theater id + * + * @return the theater's name, or null if it doesn't have one + */ +jstring JNICALL ScriptMethodsObjectCreateNamespace::getTheaterName(JNIEnv *env, jobject self, jlong theater) +{ + if (theater == 0) + return 0; + + const NetworkId theaterId(theater); + if (theaterId == NetworkId::cms_invalid) + return 0; + + const std::string & theaterName = ServerUniverse::getInstance().findTheaterName(theaterId); + if (theaterName.empty()) + return 0; + + return JavaString(theaterName).getReturnValue(); +} // JavaLibrary::getTheaterName + +// ---------------------------------------------------------------------- + +/** + * Finds a theater with a given name. + * + * @param name the theater name to look for + * + * @return the theater's id, or null if the theater doesn't exist + */ +jlong JNICALL ScriptMethodsObjectCreateNamespace::findTheater(JNIEnv *env, jobject self, jstring name) +{ + if (name == 0) + return 0; + + JavaStringParam jname(name); + std::string theaterName; + if (!JavaLibrary::convert(jname, theaterName)) + return 0; + + const NetworkId & theater = ServerUniverse::getInstance().findTheaterId(theaterName); + if (theater == NetworkId::cms_invalid) + return 0; + + return (theater).getValue(); +} // JavaLibrary::findTheater + +// ---------------------------------------------------------------------- + +/** + * Creates a manufacturing schematic from a draft schematic template. + * + * @param env Java environment + * @param self class calling this function + * @param draftSchematic the draft schematic template to create the manufacturing schematic from + * @param container the container to put the manufacturing schematic in + * + * @return the id of the manufacturing schematic, or null on error + */ +jlong JNICALL ScriptMethodsObjectCreateNamespace::createSchematicString(JNIEnv *env, jobject self, jstring draftSchematic, jlong container) +{ + if (draftSchematic == 0 || container == 0) + return 0; + + JavaStringParam jdraftSchematic(draftSchematic); + std::string schematicName; + if (!JavaLibrary::convert(jdraftSchematic, schematicName)) + return 0; + + return createSchematicCrc(env, self, Crc::calculate(schematicName.c_str()), + container); +} // JavaLibrary::createSchematicString + +// ---------------------------------------------------------------------- + +/** + * Creates a manufacturing schematic from a draft schematic template. + * + * @param env Java environment + * @param self class calling this function + * @param draftSchematicCrc the draft schematic template crc value to create the manufacturing schematic from + * @param container the container to put the manufacturing schematic in + * + * @return the id of the manufacturing schematic, or null on error + */ +jlong JNICALL ScriptMethodsObjectCreateNamespace::createSchematicCrc(JNIEnv *env, jobject self, jint draftSchematicCrc, jlong container) +{ + if (draftSchematicCrc == 0 || container == 0) + return 0; + + ServerObject * containerObject = NULL; + if (!JavaLibrary::getObject(container, containerObject)) + return 0; + + const DraftSchematicObject * const draftSchematic = DraftSchematicObject::getSchematic( + draftSchematicCrc); + if (draftSchematic == NULL) + return 0; + + ManufactureSchematicObject * manfSchematic = ServerWorld::createNewManufacturingSchematic( + *draftSchematic, *containerObject, false); + if (manfSchematic == NULL) + return 0; + + return (manfSchematic->getNetworkId()).getValue(); +} // JavaLibrary::createSchematicCrc + +// ---------------------------------------------------------------------- +/** +* Updates the Far Network Trigger volume for a given object. This causes the client to be notified about it earlier, causing it to load sooner. +* +* @param env Java environment +* @param self class calling this function +* @param target Target whose trigger volume will be changed +* @param radius Radius of the new trigger volume. +* +* @return true or false whether it completed properly or not. +*/ + +jboolean JNICALL ScriptMethodsObjectCreateNamespace::updateNetworkTriggerVolume(JNIEnv *env, jobject self, jlong target, jfloat radius) +{ + ServerObject * object = NULL; + if (!JavaLibrary::getObject(target, object)) + return JNI_FALSE; + + if(object->getNetworkTriggerVolume() && object->isNetworkUpdateFarTriggerVolume(*object->getNetworkTriggerVolume())) + object->destroyFarNetworkUpdateVolume(); + + object->createFarNetworkUpdateVolume(radius); + + return JNI_TRUE; +} +// ====================================================================== + diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsObjectInfo.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsObjectInfo.cpp new file mode 100644 index 00000000..8075cb7c --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsObjectInfo.cpp @@ -0,0 +1,6747 @@ +//======================================================================== +// +// ScriptMethodsObjInfo.cpp - implements script methods dealing with general +// object info. +// +// copyright 2001 Sony Online Entertainment +// +//======================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "UnicodeUtils.h" +#include "serverGame/AiCreatureController.h" +#include "serverGame/BuildingObject.h" +#include "serverGame/ContainerInterface.h" +#include "serverGame/CreatureController.h" +#include "serverGame/CreatureObject.h" +#include "serverGame/DraftSchematicObject.h" +#include "serverGame/FactoryObject.h" +#include "serverGame/GameServer.h" +#include "serverGame/GroupObject.h" +#include "serverGame/IntangibleObject.h" +#include "serverGame/NameManager.h" +#include "serverGame/ManufactureSchematicObject.h" +#include "serverGame/NamedObjectManager.h" +#include "serverGame/ObjectTracker.h" +#include "serverGame/ObserveTracker.h" +#include "serverGame/PlayerCreatureController.h" +#include "serverGame/PlayerObject.h" +#include "serverGame/ServerMessageForwarding.h" +#include "serverGame/ServerObjectTemplate.h" +#include "serverGame/ServerWorld.h" +#include "serverGame/ShipObject.h" +#include "sharedNetworkMessages/MessageQueueGenericValueType.h" +#include "serverNetworkMessages/SynchronizeScriptVarDeltasMessage.h" +#include "serverScript/GameScriptObject.h" +#include "sharedCollision/CollisionProperty.h" +#include "sharedDebug/Profiler.h" +#include "sharedFoundation/ConfigFile.h" +#include "sharedFoundation/ConstCharCrcString.h" +#include "sharedFoundation/CrcLowerString.h" +#include "sharedFoundation/GameControllerMessage.h" +#include "sharedFoundation/NetworkIdArchive.h" +#include "sharedGame/GameObjectTypes.h" +#include "sharedLog/Log.h" +#include "sharedMath/PackedArgb.h" +#include "sharedMath/PaletteArgb.h" +#include "sharedNetworkMessages/GenericValueTypeMessage.h" +#include "sharedNetworkMessages/MessageQueueShowFlyText.h" +#include "sharedNetworkMessages/MessageQueueShowCombatText.h" +#include "sharedObject/BasicRangedIntCustomizationVariable.h" +#include "sharedObject/CellProperty.h" +#include "sharedObject/CustomizationData.h" +#include "sharedObject/CustomizationDataProperty.h" +#include "sharedObject/NetworkIdManager.h" +#include "sharedObject/ObjectTemplate.h" +#include "sharedObject/ObjectTemplateList.h" +#include "sharedObject/PaletteColorCustomizationVariable.h" +#include "sharedObject/RangedIntCustomizationVariable.h" +#include "sharedObject/SlottedContainer.h" +#include "sharedObject/SlottedContainmentProperty.h" +#include "sharedObject/VolumeContainer.h" + +using namespace JNIWrappersNamespace; + + +// ====================================================================== +// ScriptMethodsObjectInfoNamespace +// ====================================================================== + +namespace ScriptMethodsObjectInfoNamespace +{ + bool install(); + void getGoodItemsFromContainer(const Container & container, stdvector::fwd & goodItems); + jobjectArray getNamesFromCrcs(JNIEnv *env, const stdvector::fwd & templateCrcs); + LocalRefPtr createCustomVar(const jlong &objId, const std::string &variablePathName, CustomizationVariable &variable); + LocalRefPtr createRangedIntCustomVar(const jlong &objId, const std::string &variablePathName, RangedIntCustomizationVariable &rangedIntVariable); + LocalRefPtr createPalcolorCustomVar(const jlong &objId, const std::string &variablePathName, PaletteColorCustomizationVariable &variable); + LocalRefPtr createColor(int r, int g, int b, int a); + CustomizationData * fetchCustomizationDataFromObjId(jlong objId); + + jboolean JNICALL setNameFromString (JNIEnv *env, jobject self, jlong target, jstring name); + jboolean JNICALL setNameFromStringId (JNIEnv *env, jobject self, jlong target, jobject nameId); + jstring JNICALL getName (JNIEnv *env, jobject self, jlong target); + jstring JNICALL getPlayerName (JNIEnv *env, jobject self, jlong player); + jstring JNICALL getPlayerFullName (JNIEnv *env, jobject self, jlong player); + jstring JNICALL getAssignedName (JNIEnv *env, jobject self, jlong target); + void JNICALL setCreatureName (JNIEnv *env, jobject self, jlong creature, jstring creatureName); + jstring JNICALL getCreatureName (JNIEnv *env, jobject self, jlong creature); + jobject JNICALL getNameStringId (JNIEnv *env, jobject self, jlong target); + jobject JNICALL getNameFromTemplate (JNIEnv *env, jobject self, jstring templateName); + jobject JNICALL getNameFromTemplateCrc (JNIEnv *env, jobject self, jint templateCrc); + jobjectArray JNICALL getNamesFromTemplates (JNIEnv *env, jobject self, jobjectArray templateNames); + jobjectArray JNICALL getNamesFromTemplateCrcs(JNIEnv *env,jobject self, jintArray templateCrcs); + jobjectArray JNICALL getCtsDestinationClusters(JNIEnv *env, jobject self); + jstring JNICALL getCurrentSceneName (JNIEnv *env, jobject self); + jstring JNICALL getClusterName (JNIEnv *env, jobject self); + void JNICALL setDescriptionStringId (JNIEnv *env, jobject self, jlong target, jobject descriptionId); + jobject JNICALL getDescriptionStringId (JNIEnv *env, jobject self, jlong target); + jboolean JNICALL internalIsAuthoritative(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL hasProxyOrAuthObject(JNIEnv *env, jobject self, jlong target); + jint JNICALL getGender(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL isSameGender(JNIEnv *env, jobject self, jlong target1, jlong target2); + jboolean JNICALL isRace(JNIEnv *env, jobject self, jlong target, jint species, jint race); + jboolean JNICALL isSpecies(JNIEnv *env, jobject self, jlong target, jint race); + jboolean JNICALL isNiche(JNIEnv *env, jobject self, jlong target, jint niche); + jboolean JNICALL isNicheMask(JNIEnv *env, jobject self, jobject target, jint niche, jint mask); + jint JNICALL getNiche(JNIEnv *env, jobject self, jlong target); + jint JNICALL getSpecies(JNIEnv *env, jobject self, jlong target); + jint JNICALL getRace(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL isMob(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL isTangible(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL isPlayer(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL isAwayFromKeyBoard(JNIEnv *env, jobject self, jlong player); + jint JNICALL getObjType(JNIEnv *env, jobject self, jlong target); + jstring JNICALL getTemplateId(JNIEnv *env, jobject self, jlong target); + jstring JNICALL getSharedObjectTemplateName(JNIEnv *env, jobject self, jlong target); + jlong JNICALL getLookAtTarget(JNIEnv *env, jobject self, jlong object); + jboolean JNICALL setLookAtTarget(JNIEnv *env, jobject self, jlong object, jlong target); + jlong JNICALL getIntendedTarget(JNIEnv *env, jobject self, jlong object); + jint JNICALL getPosture(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL setPosture(JNIEnv *env, jobject self, jlong target, jint posture); + jboolean JNICALL setPostureClientImmediate(JNIEnv *env, jobject self, jlong target, jint posture); + jint JNICALL getLocomotion(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL setLocomotion(JNIEnv *env, jobject self, jlong target, jint posture); + jint JNICALL getState(JNIEnv *env, jobject self, jlong target, jint whichState); + jboolean JNICALL setState(JNIEnv *env, jobject self, jlong target, jint whichState, jboolean value); + jlong JNICALL getOwner(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL setOwner(JNIEnv *env, jobject self, jlong target, jlong owner); + jboolean JNICALL isIncapacitated(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL isDead(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL isNpcCreature(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL isDisabled(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL setCraftedId(JNIEnv *env, jobject self, jlong target, jlong id); + jboolean JNICALL isCrafted(JNIEnv *env, jobject self, jlong target); + jlong JNICALL getCrafter(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL setCrafter(JNIEnv *env, jobject self, jlong target, jlong crafter); + jfloat JNICALL getScale(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL setScale(JNIEnv *env, jobject self, jlong target, jfloat scale); + jfloat JNICALL getDefaultScaleFromObjectTemplate(JNIEnv *env, jobject self, jstring serverObjectTemplateName); + jboolean JNICALL kill(JNIEnv *env, jobject self, jlong target); + jobject JNICALL killPlayer(JNIEnv *env, jobject self, jobject player, jobject killer); + jboolean JNICALL resurrect(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL removeAllAttributeAndSkillmodMods(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL setInvulnerable(JNIEnv *env, jobject self, jlong target, jboolean invulnerable); + jboolean JNICALL isInvulnerable(JNIEnv *env, jobject self, jlong target); + jfloat JNICALL getDistance(JNIEnv *env, jobject self, jlong target1, jlong target2); + jfloat JNICALL getLocationDistance(JNIEnv *env, jobject self, jobject loc1, jobject loc2); + jboolean JNICALL isLocationInConicalFrustum(JNIEnv *env, jobject self, jobject jTestLoc, jobject jStartLoc, jobject jEndLoc, jfloat startRadius, jfloat endRadius, jboolean use2d); + jboolean JNICALL isLocationInCone(JNIEnv *env, jobject self, jobject jTestLoc, jobject jStartLoc, jobject jDirectionLoc, jfloat range, jfloat halfAngle, jboolean use2d); + jfloat JNICALL getComplexity(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL setComplexity(JNIEnv *env, jobject self, jlong target, jfloat complexity); + jboolean JNICALL isGod(JNIEnv *env, jobject self, jlong target); + jint JNICALL getGodLevel(JNIEnv *env, jobject self, jlong target); + jint JNICALL getCount(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL setCount(JNIEnv *env, jobject self, jlong target, jint value); + jboolean JNICALL incrementCount(JNIEnv *env, jobject self, jlong target, jint delta); + jint JNICALL getCondition(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL hasCondition(JNIEnv *env, jobject self, jlong target, jint condition); + jboolean JNICALL setCondition(JNIEnv *env, jobject self, jlong target, jint condition); + jboolean JNICALL clearCondition(JNIEnv *env, jobject self, jlong target, jint condition); + void JNICALL sendScriptVarsToProxies(JNIEnv * env, jobject self, jlong obj, jbyteArray buffer); + jstring JNICALL getAppearance(JNIEnv * env, jobject self, jlong target); + jboolean JNICALL isInsured(JNIEnv * env, jobject self, jlong target); + jboolean JNICALL isAutoInsured(JNIEnv * env, jobject self, jlong target); + jboolean JNICALL isUninsurable(JNIEnv * env, jobject self, jlong target); + jlongArray JNICALL getInventoryAndEquipment(JNIEnv * env, jobject self, jlong player); + jboolean JNICALL setCheaterLevel(JNIEnv * env, jobject self, jlong player, jint level); + jint JNICALL getCheaterLevel(JNIEnv * env, jobject self, jlong player); + jboolean JNICALL setHouseId(JNIEnv * env, jobject self, jlong player, jlong houseId); + jlong JNICALL getHouseId(JNIEnv * env, jobject self, jlong player); + jstring JNICALL getDraftSchematic(JNIEnv * env, jobject self, jlong manfSchematic); + jint JNICALL getDraftSchematicCrc(JNIEnv * env, jobject self, jlong manfSchematic); + jint JNICALL getSourceDraftSchematic(JNIEnv * env, jobject self, jlong object); + jint JNICALL getPlayerBirthDate(JNIEnv * env, jobject self, jlong playerId); + jint JNICALL getCurrentBirthDate(JNIEnv * env, jobject self); + jint JNICALL getPlayerPlayedTime(JNIEnv * env, jobject self, jlong playerId); + jint JNICALL getBuildingCityId(JNIEnv *env, jobject self, jlong building); + void JNICALL setBuildingCityId(JNIEnv *env, jobject self, jlong building, jint cityId); + jobject JNICALL getProductNameFromSchematic(JNIEnv *env, jobject self, jstring draftSchematic); + jobject JNICALL getProductNameFromSchematicCrc(JNIEnv *env, jobject self, jint draftSchematic); + jstring JNICALL getTemplateCreatedFromSchematic(JNIEnv *env, jobject self, jstring draftSchematic); + jstring JNICALL getTemplateCreatedFromSchematicCrc(JNIEnv *env, jobject self, jint draftSchematicCrc); + jint JNICALL getTemplateCrcCreatedFromSchematic(JNIEnv *env, jobject self, jstring draftSchematic); + jint JNICALL getTemplateCrcCreatedFromSchematicCrc(JNIEnv *env, jobject self, jint draftSchematicCrc); + void JNICALL registerNamedObject(JNIEnv *env, jobject self, jstring name, jlong namedObject); + jlong JNICALL getNamedObject(JNIEnv *env, jobject self, jstring name); + void JNICALL findObjectAnywhere(JNIEnv *env, jobject self, jlong target, jlong objectToNotify); + void JNICALL findObjectAnywhereByTemplate(JNIEnv *env, jobject self, jstring templateName, jlong objectToNotify); + void JNICALL findPlayerAnywhereByPartialName(JNIEnv *env, jobject self, jstring targetName, jlong objectToNotify); + void JNICALL findWardenAnywhere(JNIEnv *env, jobject self, jlong objectToNotify); + void JNICALL findCreatureAnywhere(JNIEnv *env, jobject self, jstring creatureName, jlong objectToNotify); + void JNICALL requestPreloadCompleteTrigger(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL canTrade(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL isNoTradeShared(JNIEnv *env, jobject self, jlong target); + jlong JNICALL getLastSpawnedTheater(JNIEnv *env, jobject self, jlong player); + jboolean JNICALL setBioLink(JNIEnv *env, jobject self, jlong target, jlong link); + jboolean JNICALL clearBioLink(JNIEnv *env, jobject self, jlong target); + jlong JNICALL getBioLink(JNIEnv *env, jobject self, jlong target); + float JNICALL getObjectCollisionRadius(JNIEnv * env, jobject self, jlong obj); + jint JNICALL getGameObjectType(JNIEnv *env, jobject self, jlong obj); + jint JNICALL getGameObjectTypeFromTemplate(JNIEnv *env, jobject self, jstring templateName); + jint JNICALL getGameObjectTypeFromTemplateCrc(JNIEnv *env, jobject self, jint templateCrc); + jstring JNICALL getGameObjectTypeName(JNIEnv *env, jobject self, jint type); + jint JNICALL getGameObjectTypeFromName(JNIEnv *env, jobject self, jstring typeName); + jint JNICALL getVolume(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL isFacing(JNIEnv *env, jobject self, jlong mob, jobject target); + jboolean JNICALL exists(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL isInWorld(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL isInWorldCell(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL areFacingEachOther(JNIEnv *env, jobject self, jlong mob1, jlong mob2); + void JNICALL watch(JNIEnv * env, jobject self, jlong target); + void JNICALL stopWatching(JNIEnv * env, jobject self, jlong target); + jobjectArray JNICALL getAllCustomVars(JNIEnv *env, jclass selfClass, jlong target); + jobject JNICALL getCustomVarByName(JNIEnv *env, jclass selfClass, jlong target, jstring varPathName); + jint JNICALL getRangedIntCustomVarValue(JNIEnv *env, jclass selfClass, jlong target, jstring varPathName); + void JNICALL setRangedIntCustomVarValue(JNIEnv *env, jclass selfClass, jlong target, jstring varPathName, jint newValue); + jobject JNICALL getPalcolorCustomVarSelectedColor(JNIEnv *env, jclass selfClass, jlong target, jstring varPathName); + void JNICALL setPalcolorCustomVarClosestColor(JNIEnv *env, jclass selfClass, jlong target, jstring varPathName, jint r, jint g, jint b, jint a); + jobjectArray JNICALL getPalcolorCustomVarColors(JNIEnv *env, jclass selfClass, jlong target, jstring varPathName); + jlong JNICALL getGroupObject(JNIEnv *env, jobject self, jlong obj); + jstring JNICALL getGroupName(JNIEnv *env, jobject self, jlong obj); + jlongArray JNICALL getGroupMemberIds(JNIEnv *env, jobject self, jlong obj); + jobjectArray JNICALL getGroupMemberNames(JNIEnv *env, jobject self, jlong obj); + jlong JNICALL getGroupLeaderId(JNIEnv *env, jobject self, jlong group); + jint JNICALL getGroupSize(JNIEnv *env, jobject self, jlong group); + jint JNICALL getPCGroupSize(JNIEnv *env, jobject self, jlong group); + jlong JNICALL getGroupMasterLooterId(JNIEnv *env, jobject self, jlong group); + jint JNICALL getGroupLootRule(JNIEnv *env, jobject self, jlong group); + jboolean JNICALL setGroupLootRule(JNIEnv *env, jobject self, jlong target, jint value); + void JNICALL openLotteryWindow(JNIEnv *env, jobject self, jlong playerToSendTo, jlong container); + jint JNICALL getPerformanceType(JNIEnv *env, jobject self, jlong target); + void JNICALL setPerformanceType(JNIEnv *env, jobject self, jlong target, jint performanceType); + jint JNICALL getPerformanceStartTime(JNIEnv *env, jobject self, jlong target); + void JNICALL setPerformanceStartTime(JNIEnv *env, jobject self, jlong target, jint performanceStartTime); + jlong JNICALL getPerformanceListenTarget(JNIEnv *env, jobject self, jlong actor); + void JNICALL setPerformanceListenTarget(JNIEnv *env, jobject self, jlong actor, jlong target); + jlong JNICALL getPerformanceWatchTarget(JNIEnv *env, jobject self, jlong actor); + void JNICALL setPerformanceWatchTarget(JNIEnv *env, jobject self, jlong actor, jlong target); + jint JNICALL getInstrumentVisualId(JNIEnv *env, jobject self, jlong who); + jint JNICALL getInstrumentAudioId(JNIEnv *env, jobject self, jlong who); + void JNICALL sendMusicFlourish(JNIEnv *env, jobject self, jlong performer, jint flourishIndex); + void JNICALL showFlyText (JNIEnv *env, jobject self, jlong emitterId, jobject outputTextId, jfloat scale, jint r, jint g, jint b); + void JNICALL showFlyTextPrivate (JNIEnv *env, jobject self, jlong emitterId, jlong receiverId, jobject outputTextId, jfloat scale, jint r, jint g, jint b, jboolean showInChatBox); + void JNICALL showCombatText (JNIEnv *env, jobject self, jlong defenderId, jlong attackerId, jobject outputTextId, jfloat scale, jint r, jint g, jint b); + void JNICALL showCombatTextPrivate (JNIEnv *env, jobject self, jlong defenderId, jlong attackerId, jlong emitterId, jobject outputTextId, jfloat scale, jint r, jint g, jint b); + void JNICALL showFlyTextProse (JNIEnv *env, jobject self, jlong emitterId, jstring outputTextOOB, jfloat scale, jint r, jint g, jint b); + void JNICALL showFlyTextPrivateProseWithFlags (JNIEnv *env, jobject self, jlong emitterId, jlong receiverId, jstring outputTextOOB, jfloat scale, jint r, jint g, jint b, jint flags); + void JNICALL showFlyTextPrivateProse (JNIEnv *env, jobject self, jlong emitterId, jlong receiverId, jstring outputTextOOB, jfloat scale, jint r, jint g, jint b, jboolean showInChatBox); + void JNICALL showCombatTextProse (JNIEnv *env, jobject self, jlong defenderId, jlong attackerId, jstring outputTextOOB, jfloat scale, jint r, jint g, jint b); + void JNICALL showCombatTextPrivateProse (JNIEnv *env, jobject self, jlong defenderId, jlong attackerId, jlong emitterId, jstring outputTextOOB, jfloat scale, jint r, jint g, jint b); + jlong JNICALL getMaster (JNIEnv *env, jobject self, jlong target); + void JNICALL setMaster (JNIEnv *env, jobject self, jlong target, jlong master); + jint JNICALL getNumAI(JNIEnv *env, jobject self); + jint JNICALL getNumCreatures(JNIEnv *env, jobject self); + jint JNICALL getNumPlayers(JNIEnv *env, jobject self); + jint JNICALL getNumRunTimeRules(JNIEnv *env, jobject self); + jint JNICALL getNumDynamicAI(JNIEnv *env, jobject self); + jint JNICALL getNumStaticAI(JNIEnv *env, jobject self); + jint JNICALL getNumCombatAI(JNIEnv *env, jobject self); + jint JNICALL getNumHibernatingAI(JNIEnv *env, jobject self); + jint JNICALL getGroupLevel (JNIEnv *env, jobject self, jlong target); + jint JNICALL getLevel(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL setLevel(JNIEnv *env, jobject self, jlong target, jint forcedLevel); + jboolean JNICALL recalculateLevel(JNIEnv *env, jobject self, jlong target); + void JNICALL sendDirtyObjectMenuNotification (JNIEnv *env, jobject self, jlong jTarget); + void JNICALL sendDirtyAttributesNotification (JNIEnv *env, jobject self, jlong jTarget); + void JNICALL activateQuest(JNIEnv * env, jobject self, jlong target, jint questId); + void JNICALL completeQuest(JNIEnv * env, jobject self, jlong target, jint questId); + void JNICALL clearCompletedQuest(JNIEnv * env, jobject self, jlong target, jint questId); + void JNICALL deactivateQuest(JNIEnv * env, jobject self, jlong target, jint questId); + jboolean JNICALL isQuestActive(JNIEnv * env, jobject self, jlong target, jint questId); + jboolean JNICALL isQuestComplete(JNIEnv * env, jobject self, jlong target, jint questId); + jbyteArray JNICALL getByteStreamFromAutoVariable(JNIEnv * env, jobject self, jlong target, jstring variableName); + void JNICALL setAutoVariableFromByteStream(JNIEnv * env, jobject self, jlong target, jstring variableName, jbyteArray data); + jstring JNICALL getStaticItemName(JNIEnv * env, jobject self, jlong target); + jint JNICALL getStaticItemVersion(JNIEnv * env, jobject self, jlong target); + void JNICALL setStaticItemName(JNIEnv * env, jobject self, jlong target, jstring staticItemName); + void JNICALL setStaticItemVersion(JNIEnv * env, jobject self, jlong target, jint staticItemVersion); + jint JNICALL getConversionId(JNIEnv * env, jobject self, jlong target); + void JNICALL setConversionId(JNIEnv * env, jobject self, jlong target, jint conversionId); + jboolean JNICALL canEquipWearable(JNIEnv * env, jobject self, jlong player, jlong target); + void JNICALL openCustomizationWindow(JNIEnv *env, jobject self, jlong player, jlong object, jstring customVarName1, jint minVar1, jint maxVar1, jstring customVarName2, jint minVar2, jint maxVar2, jstring customVarName3, jint minVar3, jint maxVar3, jstring customVarName4, jint minVar4, jint maxVar4); + jint JNICALL getHologramType(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL setHologramType(JNIEnv *env, jobject self, jlong target, jint type); + jboolean JNICALL setVisibleOnMapAndRadar(JNIEnv *env, jobject self, jlong target, jboolean visible); + jboolean JNICALL getVisibleOnMapAndRadar(JNIEnv *env, jobject self, jlong target); + jlong JNICALL getBeastmasterPet(JNIEnv *env, jobject self, jlong object); + jboolean JNICALL setBeastmasterPet(JNIEnv *env, jobject self, jlong object, jlong target); + jboolean JNICALL isPlayerBackpackHidden(JNIEnv *env, jobject self, jlong player); + jboolean JNICALL isPlayerHelmetHidden(JNIEnv *env, jobject self, jlong player); + jfloat JNICALL getDefaultScaleFromSharedObjectTemplate(JNIEnv *env, jobject self, jstring sharedObjectTemplateName); + jboolean JNICALL setOverrideMapColor(JNIEnv * env, jobject self, jlong object, jint r, jint g, jint b); + jboolean JNICALL clearOverrideMapColor(JNIEnv * env, jobject self, jlong object); + jobject JNICALL getOverrideMapColor(JNIEnv * env, jobject self, jlong object); + jboolean JNICALL setForceShowHam(JNIEnv * env, jobject self, jlong object, jboolean show); + jboolean JNICALL isContainedByPlayerAppearanceInventory(JNIEnv *env, jobject self, jlong player, jlong item); + jlongArray JNICALL getAllItemsFromAppearanceInventory(JNIEnv *env, jobject self, jlong player); + jboolean JNICALL isAPlayerAppearanceInventoryContainer(JNIEnv *env, jobject self, jlong container); + jlongArray JNICALL getAllWornItems(JNIEnv *env, jobject self, jlong player, jboolean ignoreAppearanceItems); + jlong JNICALL getAppearanceInventory(JNIEnv *env, jobject self, jlong player); + jboolean JNICALL setDecoyOrigin(JNIEnv *env, jobject self, jlong creature, jlong origin); + jlong JNICALL getDecoyOrigin(JNIEnv *env, jobject self, jlong creature); + jboolean JNICALL openRatingWindow(JNIEnv * env, jobject self, jlong player, jstring title, jstring description); + void JNICALL openExamineWindow(JNIEnv * env, jobject self, jlong player, jlong item); +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsObjectInfoNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsObjectInfoNamespace::c)} + JF("_setName", "(JLjava/lang/String;)Z", setNameFromString), + JF("_setName", "(JLscript/string_id;)Z", setNameFromStringId), + JF("_getName", "(J)Ljava/lang/String;", getName), + JF("_getPlayerName", "(J)Ljava/lang/String;", getPlayerName), + JF("_getPlayerFullName", "(J)Ljava/lang/String;", getPlayerFullName), + JF("_getAssignedName", "(J)Ljava/lang/String;", getAssignedName), + JF("_setCreatureName", "(JLjava/lang/String;)V", setCreatureName), + JF("_getCreatureName", "(J)Ljava/lang/String;", getCreatureName), + JF("_getNameStringId", "(J)Lscript/string_id;", getNameStringId), + JF("getNameFromTemplate", "(Ljava/lang/String;)Lscript/string_id;", getNameFromTemplate), + JF("getNameFromTemplate", "(I)Lscript/string_id;", getNameFromTemplateCrc), + JF("getNamesFromTemplates", "([Ljava/lang/String;)[Lscript/string_id;", getNamesFromTemplates), + JF("getNamesFromTemplates", "([I)[Lscript/string_id;", getNamesFromTemplateCrcs), + JF("_setDescriptionStringId", "(JLscript/string_id;)V", setDescriptionStringId), + JF("_getDescriptionStringId", "(J)Lscript/string_id;", getDescriptionStringId), + JF("__internalIsAuthoritative", "(J)Z", internalIsAuthoritative), + JF("_hasProxyOrAuthObject", "(J)Z", hasProxyOrAuthObject), + JF("_getGender", "(J)I", getGender), + JF("_isSameGender", "(JJ)Z", isSameGender), + JF("_isRace", "(JII)Z", isRace), + JF("_isSpecies", "(JI)Z", isSpecies), + JF("_isNiche", "(JI)Z", isNiche), + JF("_getRace", "(J)I", getRace), + JF("_getNiche", "(J)I", getNiche), + JF("_getSpecies", "(J)I", getSpecies), + JF("_isMob", "(J)Z", isMob), + JF("_isTangible", "(J)Z", isTangible), + JF("_isPlayer", "(J)Z", isPlayer), + JF("_isAwayFromKeyBoard", "(J)Z", isAwayFromKeyBoard), + JF("_getObjType", "(J)I", getObjType), + JF("_getLookAtTarget", "(J)J", getLookAtTarget), + JF("_setLookAtTarget", "(JJ)Z", setLookAtTarget), + JF("_getIntendedTarget", "(J)J", getIntendedTarget), + JF("_getPosture", "(J)I", getPosture), + JF("_setPosture", "(JI)Z", setPosture), + JF("_setPostureClientImmediate", "(JI)Z", setPostureClientImmediate), + JF("_getLocomotion", "(J)I", getLocomotion), + JF("_setLocomotion", "(JI)Z", setLocomotion), + JF("_getState", "(JI)I", getState), + JF("_setState", "(JIZ)Z", setState), + JF("_getOwner", "(J)J", getOwner), + JF("_setOwner", "(JJ)Z", setOwner), + JF("_isIncapacitated", "(J)Z", isIncapacitated), + JF("_isDead", "(J)Z", isDead), + JF("_isNpcCreature", "(J)Z", isNpcCreature), + JF("_isDisabled", "(J)Z", isDisabled), + JF("_setCraftedId", "(JJ)Z", setCraftedId), + JF("_isCrafted", "(J)Z", isCrafted), + JF("_getCrafter", "(J)J", getCrafter), + JF("_setCrafter", "(JJ)Z", setCrafter), + JF("_getScale", "(J)F", getScale), + JF("_setScale", "(JF)Z", setScale), + JF("getDefaultScaleFromObjectTemplate", "(Ljava/lang/String;)F", getDefaultScaleFromObjectTemplate), + JF("_getTemplateName", "(J)Ljava/lang/String;", getTemplateId), + JF("_getSharedObjectTemplateName", "(J)Ljava/lang/String;", getSharedObjectTemplateName), + JF("_kill", "(J)Z", kill), + JF("_resurrect", "(J)Z", resurrect), + JF("_removeAllAttributeAndSkillmodMods", "(J)Z", removeAllAttributeAndSkillmodMods), + JF("_getDistance", "(JJ)F",getDistance), + JF("_getDistance", "(Lscript/location;Lscript/location;)F", getLocationDistance), + JF("_isLocationWithinConicalFrustum", "(Lscript/location;Lscript/location;Lscript/location;FFZ)Z", isLocationInConicalFrustum), + JF("_isLocationInCone", "(Lscript/location;Lscript/location;Lscript/location;FFZ)Z", isLocationInCone), + JF("_setInvulnerable", "(JZ)Z", setInvulnerable), + JF("_isInvulnerable", "(J)Z", isInvulnerable), + JF("_getComplexity", "(J)F", getComplexity), + JF("_setComplexity", "(JF)Z", setComplexity), + JF("_isGod", "(J)Z", isGod), + JF("_getGodLevel", "(J)I", getGodLevel), + JF("_getCount", "(J)I", getCount), + JF("_setCount", "(JI)Z", setCount), + JF("_incrementCount", "(JI)Z", incrementCount), + JF("_getCondition", "(J)I", getCondition), + JF("_hasCondition", "(JI)Z", hasCondition), + JF("_setCondition", "(JI)Z", setCondition), + JF("_clearCondition", "(JI)Z", clearCondition), + JF("_getAppearance", "(J)Ljava/lang/String;", getAppearance), + JF("_isInsured", "(J)Z", isInsured), + JF("_isAutoInsured", "(J)Z", isAutoInsured), + JF("_isUninsurable", "(J)Z", isUninsurable), + JF("_getInventoryAndEquipment", "(J)[J", getInventoryAndEquipment), + JF("_setCheaterLevel", "(JI)Z", setCheaterLevel), + JF("_getCheaterLevel", "(J)I", getCheaterLevel), + JF("_setHouseId", "(JJ)Z", setHouseId), + JF("_getHouseId", "(J)J", getHouseId), + JF("_getDraftSchematic", "(J)Ljava/lang/String;", getDraftSchematic), + JF("_getDraftSchematicCrc", "(J)I", getDraftSchematicCrc), + JF("_getSourceDraftSchematic", "(J)I", getSourceDraftSchematic), + JF("_getPlayerBirthDate", "(J)I", getPlayerBirthDate), + JF("getCurrentBirthDate", "()I", getCurrentBirthDate), + JF("_getPlayerPlayedTime", "(J)I", getPlayerPlayedTime), + JF("_getBuildingCityId", "(J)I", getBuildingCityId), + JF("_setBuildingCityId", "(JI)V", setBuildingCityId), + JF("getProductNameFromSchematic", "(Ljava/lang/String;)Lscript/string_id;", getProductNameFromSchematic), + JF("getProductNameFromSchematic", "(I)Lscript/string_id;", getProductNameFromSchematicCrc), + JF("getTemplateCreatedFromSchematic", "(Ljava/lang/String;)Ljava/lang/String;", getTemplateCreatedFromSchematic), + JF("getTemplateCreatedFromSchematic", "(I)Ljava/lang/String;", getTemplateCreatedFromSchematicCrc), + JF("getTemplateCrcCreatedFromSchematic", "(Ljava/lang/String;)I", getTemplateCrcCreatedFromSchematic), + JF("getTemplateCrcCreatedFromSchematic", "(I)I", getTemplateCrcCreatedFromSchematicCrc), + JF("_registerNamedObject", "(Ljava/lang/String;J)V", registerNamedObject), + JF("_getNamedObject", "(Ljava/lang/String;)J", getNamedObject), + JF("_findObjectAnywhere", "(JJ)V", findObjectAnywhere), + JF("_findObjectAnywhereByTemplate", "(Ljava/lang/String;J)V", findObjectAnywhereByTemplate), + JF("_findPlayerAnywhereByPartialName", "(Ljava/lang/String;J)V", findPlayerAnywhereByPartialName), + JF("_findWardenAnywhere", "(J)V", findWardenAnywhere), + JF("_findCreatureAnywhere", "(Ljava/lang/String;J)V", findCreatureAnywhere), + JF("_requestPreloadCompleteTrigger", "(J)V", requestPreloadCompleteTrigger), + JF("_canTrade", "(J)Z", canTrade), + JF("_isNoTradeShared", "(J)Z", isNoTradeShared), + JF("_getLastSpawnedTheater", "(J)J", getLastSpawnedTheater), + JF("_setBioLink", "(JJ)Z", setBioLink), + JF("_clearBioLink", "(J)Z", clearBioLink), + JF("_getBioLink", "(J)J", getBioLink), + JF("_getObjectCollisionRadius", "(J)F", getObjectCollisionRadius), + JF("_getGameObjectType", "(J)I", getGameObjectType), + JF("getGameObjectTypeFromTemplate", "(Ljava/lang/String;)I", getGameObjectTypeFromTemplate), + JF("getGameObjectTypeFromTemplate", "(I)I", getGameObjectTypeFromTemplateCrc), + JF("getGameObjectTypeName", "(I)Ljava/lang/String;", getGameObjectTypeName), + JF("getGameObjectTypeFromName", "(Ljava/lang/String;)I", getGameObjectTypeFromName), + JF("_getVolume", "(J)I",getVolume), + JF("_isFacing", "(JLscript/location;)Z", isFacing), + JF("_exists", "(J)Z", exists), + JF("_isInWorld", "(J)Z",isInWorld), + JF("_isInWorldCell", "(J)Z", isInWorldCell), + JF("_areFacingEachOther", "(JJ)Z",areFacingEachOther), + JF("_watch", "(J)V", watch), + JF("_stopWatching", "(J)V", stopWatching), + JF("_getAllCustomVars", "(J)[Lscript/custom_var;", getAllCustomVars), + JF("_getCustomVarByName", "(JLjava/lang/String;)Lscript/custom_var;", getCustomVarByName), + JF("_getRangedIntCustomVarValue", "(JLjava/lang/String;)I", getRangedIntCustomVarValue), + JF("_setRangedIntCustomVarValue", "(JLjava/lang/String;I)V", setRangedIntCustomVarValue), + JF("_getPalcolorCustomVarSelectedColor","(JLjava/lang/String;)Lscript/color;", getPalcolorCustomVarSelectedColor), + JF("_setPalcolorCustomVarClosestColor", "(JLjava/lang/String;IIII)V", setPalcolorCustomVarClosestColor), + JF("_getPalcolorCustomVarColors", "(JLjava/lang/String;)[Lscript/color;", getPalcolorCustomVarColors), + JF("_getGroupObject", "(J)J", getGroupObject), + JF("_getGroupName", "(J)Ljava/lang/String;", getGroupName), + JF("_getGroupMemberIds", "(J)[J", getGroupMemberIds), + JF("_getGroupMemberNames", "(J)[Ljava/lang/String;", getGroupMemberNames), + JF("_getGroupLeaderId", "(J)J", getGroupLeaderId), + JF("_getGroupSize", "(J)I", getGroupSize), + JF("_getPCGroupSize", "(J)I", getPCGroupSize), + JF("_getGroupMasterLooterId", "(J)J", getGroupMasterLooterId), + JF("_getGroupLootRule", "(J)I", getGroupLootRule), + JF("_setGroupLootRule", "(JI)Z", setGroupLootRule), + JF("_openLotteryWindow", "(JJ)V", openLotteryWindow), + JF("_getPerformanceType", "(J)I", getPerformanceType), + JF("_setPerformanceType", "(JI)V", setPerformanceType), + JF("_getPerformanceStartTime", "(J)I", getPerformanceStartTime), + JF("_setPerformanceStartTime", "(JI)V", setPerformanceStartTime), + JF("_getPerformanceListenTarget", "(J)J", getPerformanceListenTarget), + JF("_setPerformanceListenTarget", "(JJ)V", setPerformanceListenTarget), + JF("_getPerformanceWatchTarget", "(J)J", getPerformanceWatchTarget), + JF("_setPerformanceWatchTarget", "(JJ)V", setPerformanceWatchTarget), + JF("_getInstrumentVisualId", "(J)I", getInstrumentVisualId), + JF("_getInstrumentAudioId", "(J)I", getInstrumentAudioId), + JF("_sendMusicFlourish", "(JI)V", sendMusicFlourish), + JF("_showFlyText", "(JLscript/string_id;FIII)V", showFlyText), + JF("_showFlyTextPrivate", "(JJLscript/string_id;FIIIZ)V", showFlyTextPrivate), + JF("_showFlyTextProse", "(JLjava/lang/String;FIII)V", showFlyTextProse), + JF("_showFlyTextPrivateProse", "(JJLjava/lang/String;FIIIZ)V", showFlyTextPrivateProse), + JF("_showCombatText", "(JJLscript/string_id;FIII)V", showCombatText), + JF("_showCombatTextPrivate", "(JJJLscript/string_id;FIII)V", showCombatTextPrivate), + JF("_showCombatTextProse", "(JJLjava/lang/String;FIII)V", showCombatTextProse), + JF("_showCombatTextPrivateProse", "(JJJLjava/lang/String;FIII)V", showCombatTextPrivateProse), + JF("_showFlyTextPrivateProseWithFlags", "(JJLjava/lang/String;FIIII)V", showFlyTextPrivateProseWithFlags), + JF("_getMaster", "(J)J", getMaster), + JF("_setMaster", "(JJ)V", setMaster), + JF("getNumAI", "()I", getNumAI), + JF("getNumCreatures", "()I", getNumCreatures), + JF("getNumPlayers", "()I", getNumPlayers), + JF("getNumRunTimeRules", "()I", getNumRunTimeRules), + JF("getNumDynamicAI", "()I", getNumDynamicAI), + JF("getNumStaticAI", "()I", getNumStaticAI), + JF("getNumCombatAI", "()I", getNumCombatAI), + JF("getNumHibernatingAI", "()I", getNumHibernatingAI), + JF("_getGroupObjectLevel", "(J)I", getGroupLevel), + JF("_getLevel", "(J)I", getLevel), + JF("_setLevel", "(JI)Z", setLevel), + JF("_recalculateLevel", "(J)Z", recalculateLevel), + JF("_sendDirtyObjectMenuNotification", "(J)V", sendDirtyObjectMenuNotification), + JF("_sendDirtyAttributesNotification", "(J)V", sendDirtyAttributesNotification), + JF("_activateQuest", "(JI)V", activateQuest), + JF("_completeQuest", "(JI)V", completeQuest), + JF("_clearCompletedQuest", "(JI)V", clearCompletedQuest), + JF("_deactivateQuest", "(JI)V", deactivateQuest), + JF("_isQuestActive", "(JI)Z", isQuestActive), + JF("_isQuestComplete", "(JI)Z", isQuestComplete), + JF("_getByteStreamFromAutoVariable", "(JLjava/lang/String;)[B", getByteStreamFromAutoVariable), + JF("_setAutoVariableFromByteStream", "(JLjava/lang/String;[B)V", setAutoVariableFromByteStream), + JF("_getStaticItemName", "(J)Ljava/lang/String;", getStaticItemName), + JF("_getStaticItemVersion", "(J)I", getStaticItemVersion), + JF("_setStaticItemName", "(JLjava/lang/String;)V", setStaticItemName), + JF("_setStaticItemVersion", "(JI)V", setStaticItemVersion), + JF("_getConversionId", "(J)I", getConversionId), + JF("_setConversionId", "(JI)V", setConversionId), + JF("getCtsDestinationClusters", "()[Ljava/lang/String;", getCtsDestinationClusters), + JF("getCurrentSceneName", "()Ljava/lang/String;", getCurrentSceneName), + JF("getClusterName", "()Ljava/lang/String;", getClusterName), + JF("_sendScriptVarsToProxies", "(J[B)V", sendScriptVarsToProxies), + JF("_canEquipWearable", "(JJ)Z", canEquipWearable), + JF("_openCustomizationWindow", "(JJLjava/lang/String;IILjava/lang/String;IILjava/lang/String;IILjava/lang/String;II)V", openCustomizationWindow), + JF("_getHologramType", "(J)I", getHologramType), + JF("_setHologramType", "(JI)Z", setHologramType), + JF("_setVisibleOnMapAndRadar", "(JZ)Z", setVisibleOnMapAndRadar), + JF("_getVisibleOnMapAndRadar", "(J)Z", getVisibleOnMapAndRadar), + JF("_getBeastmasterPet", "(J)J", getBeastmasterPet), + JF("_setBeastmasterPet", "(JJ)Z", setBeastmasterPet), + JF("_isPlayerBackpackHidden", "(J)Z", isPlayerBackpackHidden), + JF("_isPlayerHelmetHidden", "(J)Z", isPlayerHelmetHidden), + JF("getDefaultScaleFromSharedObjectTemplate", "(Ljava/lang/String;)F", getDefaultScaleFromSharedObjectTemplate), + JF("_setOverrideMapColor", "(JIII)Z", setOverrideMapColor), + JF("_clearOverrideMapColor", "(J)Z", clearOverrideMapColor), + JF("_getOverrideMapColor", "(J)Lscript/color;", getOverrideMapColor), + JF("_setForceShowHam", "(JZ)Z", setForceShowHam), + JF("_isContainedByPlayerAppearanceInventory", "(JJ)Z", isContainedByPlayerAppearanceInventory), + JF("_getAllItemsFromAppearanceInventory", "(J)[J", getAllItemsFromAppearanceInventory), + JF("_isAPlayerAppearanceInventoryContainer", "(J)Z", isAPlayerAppearanceInventoryContainer), + JF("_getAllWornItems", "(JZ)[J", getAllWornItems), + JF("_getAppearanceInventory", "(J)J", getAppearanceInventory), + JF("_setDecoyOrigin", "(JJ)Z", setDecoyOrigin), + JF("_getDecoyOrigin", "(J)J", getDecoyOrigin), + JF("_openRatingWindow", "(JLjava/lang/String;Ljava/lang/String;)Z", openRatingWindow), + JF("_openExamineWindow", "(JJ)V", openExamineWindow), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +//======================================================================== +// class JavaLibrary internal methods +//======================================================================== + +/** + * Goes through all the items in a container and finds the "good" ones. A good + * item must be a visible TangibleObject, and not a special item such as hair. + * If a good item is a container itself, we will recursively go through its + * contents. + * + * @param container the container to look through + * @param goodItems list that will be filled with the good items + */ +void ScriptMethodsObjectInfoNamespace::getGoodItemsFromContainer(const Container & container, + std::vector & goodItems) +{ + const ServerObject * owner = safe_cast( + ContainerInterface::getFirstParentInWorld(container.getOwner())); + const ServerObject * ownerInventory = NULL; + const ServerObject * ownerDatapad = NULL; + const ServerObject * ownerAppearanceInventory = NULL; + const ServerObject * ownerHangar = NULL; + + if (owner != NULL) + { + const CreatureObject * creature = owner->asCreatureObject(); + if (creature != NULL) + { + ownerInventory = creature->getInventory(); + ownerDatapad = creature->getDatapad(); + ownerAppearanceInventory = creature->getAppearanceInventory(); + ownerHangar = creature->getHangar(); + } + } + + for (ContainerConstIterator i(container.begin()); i != container.end(); ++i) + { + const CachedNetworkId & itemId = *i; + const ServerObject * item = safe_cast( + itemId.getObject()); + if (item != NULL && item->asTangibleObject() != NULL && + item->asTangibleObject()->isVisible()) + { + // + // test for special items + // + + // no player inventory + if (ownerInventory != NULL && ownerInventory->getNetworkId() == + item->getNetworkId()) + { + continue; + } + + // no player datapad + if (ownerDatapad != NULL && ownerDatapad->getNetworkId() == + item->getNetworkId()) + { + continue; + } + + // no player appearance inventories! + if(ownerAppearanceInventory && ownerAppearanceInventory->getNetworkId() == item->getNetworkId()) + continue; + + // TCG Ship hangar + if(ownerHangar && ownerHangar->getNetworkId() == item->getNetworkId()) + continue; + + // no creatures (pets/droids) + if (item->asCreatureObject() != NULL) + continue; + + // no hair + const ServerObjectTemplate * itemTemplate = safe_cast< + const ServerObjectTemplate *>(item->getObjectTemplate()); + NOT_NULL(itemTemplate); + if (strstr(itemTemplate->getName(), "tangible/hair") != NULL) + continue; + + // no Trandoshan feet + + + + goodItems.push_back(itemId); + + // see if the item is a container and go through its contents + const Container * itemContainer = ContainerInterface::getContainer(*item); + if (itemContainer != NULL) + getGoodItemsFromContainer(*itemContainer, goodItems); + } + } +} // JavaLibrary::getGoodItemsFromContainer + +/** + * Returns the default names of objects that would be created by given templates. + * + * @param env Java environment + * @param self class calling this function + * @param jtemplateCrcs the template crcs + * + * @return the names, or null on error + */ +jobjectArray ScriptMethodsObjectInfoNamespace::getNamesFromCrcs(JNIEnv *env, + const std::vector & templateCrcs) +{ + int count = templateCrcs.size(); + LocalObjectArrayRefPtr names = createNewObjectArray(count, JavaLibrary::getClsStringId()); + if (names == LocalObjectArrayRef::cms_nullPtr) + return 0; + + for (int i = 0; i < count; ++i) + { + if (templateCrcs[i] == 0) + continue; + + // get the server template + const ObjectTemplate * ot = ObjectTemplateList::fetch(templateCrcs[i]); + if (ot == NULL) + { + WARNING(true, ("JavaLibrary::getNamesFromTemplateCrcs: Could not " + "find object template for crc %d", templateCrcs[i])); + continue; + } + + // get the shared template + const ServerObjectTemplate * serverOt = ot->asServerObjectTemplate(); + if (serverOt != NULL) + { + const std::string sharedTemplateName(serverOt->getSharedTemplate()); + serverOt->releaseReference(); + serverOt = NULL; + ot = ObjectTemplateList::fetch(sharedTemplateName); + if (ot == NULL) + { + WARNING(true, ("JavaLibrary::getNamesFromTemplateCrcs: Could not " + "find shared object template %s", sharedTemplateName.c_str())); + continue; + } + } + + const SharedObjectTemplate * sharedOt = ot->asSharedObjectTemplate(); + if (sharedOt == NULL) + { + WARNING(true, ("JavaLibrary::getNamesFromTemplateCrcs: template %s " + "is not a shared template", ot->getName())); + ot->releaseReference(); + continue; + } + ot = NULL; + + const StringId objectName(sharedOt->getObjectName()); + sharedOt->releaseReference(); + sharedOt = NULL; + + LocalRefPtr jobjectName; + if (ScriptConversion::convert(objectName, jobjectName)) + { + setObjectArrayElement(*names, i, *jobjectName); + } + else + { + WARNING(true, ("JavaLibrary::getNamesFromTemplateCrcs: could not " + "convert stringId %s to Java", + objectName.getCanonicalRepresentation().c_str())); + } + + } + return names->getReturnValue(); +} // JavaLibrary::getNamesFromTemplateCrcs + + +//======================================================================== +// class JavaLibrary JNI object name callback methods +//======================================================================== + +/** + * Sets an object's name from a string. + * + * @param env Java environment + * @param self class calling this function + * @param target id of object to change name + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::setNameFromString(JNIEnv *env, jobject self, jlong target, jstring name) +{ + UNREF(self); + + JavaStringParam localName(name); + + ServerObject* object = NULL; + if (!JavaLibrary::getObject(target, object)) + return JNI_FALSE; + + std::string nameString; + JavaLibrary::convert(localName, nameString); + object->setObjectName(Unicode::utf8ToWide(nameString)); + + return JNI_TRUE; +} // JavaLibrary::setNameFromString + +/** + * Sets an object's name from a stringId. + * + * @param env Java environment + * @param self class calling this function + * @param target id of object to change name + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::setNameFromStringId(JNIEnv *env, jobject, jlong target, jobject nameId) +{ + ServerObject * object = 0; + if(!JavaLibrary::getObject(target, object)) + return JNI_FALSE; + + JavaStringPtr tempString = getStringField(LocalRefParam(nameId), JavaLibrary::getFidStringIdTable()); + std::string table; + if(! JavaLibrary::convert(*tempString, table)) + return JNI_FALSE; + + std::string asciiId; + JavaStringPtr tempAsciiIdString = getStringField(LocalRefParam(nameId), JavaLibrary::getFidStringIdAsciiId()); + if(! JavaLibrary::convert(*tempAsciiIdString, asciiId)) + return JNI_FALSE; + + StringId stringId(table, asciiId); + object->setObjectNameStringId(stringId); + + return JNI_TRUE; +} // JavaLibrary::setNameFromStringId + +/** +* Sets an object's description from a stringId. +* +* @param env Java environment +* @param self class calling this function +* @param target id of object to change name +* @param descriptionId string id of the new description +* +* @return true on success, false on fail +*/ +void JNICALL ScriptMethodsObjectInfoNamespace::setDescriptionStringId(JNIEnv * env, jobject self, jlong target, jobject descriptionId) +{ + ServerObject * object = 0; + if(! JavaLibrary::getObject(target, object)) + return; + + JavaStringPtr tempString = getStringField(LocalRefParam(descriptionId), JavaLibrary::getFidStringIdTable()); + std::string table; + if(! JavaLibrary::convert(*tempString, table)) + return; + + std::string asciiId; + JavaStringPtr tempAsciiIdString = getStringField(LocalRefParam(descriptionId), JavaLibrary::getFidStringIdAsciiId()); + if(! JavaLibrary::convert(*tempAsciiIdString, asciiId)) + return; + + StringId stringId(table, asciiId); + object->setDescriptionStringId(stringId); +} + +/** +* Returns an object's description. +* +* @param env Java environment +* @param self class calling this function +* @param target id of object whose name to get +* +* @return the description, or null on error +*/ +jobject JNICALL ScriptMethodsObjectInfoNamespace::getDescriptionStringId(JNIEnv * env, jobject self, jlong target) +{ + ServerObject * object = 0; + if (!JavaLibrary::getObject(target, object)) + return 0; + + StringId const & descriptionId = object->getDescriptionStringId(); + + LocalRefPtr result; + if (ScriptConversion::convert(descriptionId, result)) + return result->getReturnValue(); + + return 0; +} + +/** + * Returns an object's name. + * + * @param env Java environment + * @param self class calling this function + * @param target id of object whose name to get + * + * @return the name, or null on error + */ +jstring JNICALL ScriptMethodsObjectInfoNamespace::getName(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + ServerObject* object = NULL; + if (!JavaLibrary::getObject(target, object)) + return 0; + + const Unicode::String & name = object->getObjectName(); + return JavaString(name).getReturnValue(); +} // JavaLibrary::getName + +/** + * Returns a player's base name. The base name is the player's first name, + * all lowercase. + * + * @param env Java environment + * @param self class calling this function + * @param player id of the player to get + * + * @return the name, or null on error + */ +jstring JNICALL ScriptMethodsObjectInfoNamespace::getPlayerName(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + const NetworkId id(target); + if (id == NetworkId::cms_invalid) + return 0; + + const std::string & name = NameManager::getInstance().getPlayerName(id); + if (name.empty()) + return 0; + return JavaString(name).getReturnValue(); +} // JavaLibrary::getName + +jstring JNICALL ScriptMethodsObjectInfoNamespace::getPlayerFullName(JNIEnv *env, jobject, jlong target) +{ + NetworkId const id(target); + if (id == NetworkId::cms_invalid) + return 0; + + std::string const &name = NameManager::getInstance().getPlayerFullName(id); + if (name.empty()) + return 0; + return JavaString(name).getReturnValue(); +} + +/** + * Returns an object's name. + * + * @param env Java environment + * @param self class calling this function + * @param target id of object whose name to get + * + * @return the name, or null on error + */ +jstring JNICALL ScriptMethodsObjectInfoNamespace::getAssignedName(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + ServerObject* object = NULL; + if (!JavaLibrary::getObject(target, object)) + return 0; + + const Unicode::String & name = object->getAssignedObjectName(); + return JavaString(name).getReturnValue(); +} // JavaLibrary::getName + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectInfoNamespace::setCreatureName(JNIEnv * /*env*/, jobject /*self*/, jlong creature, jstring creatureName) +{ + NetworkId const networkId(creature); + CreatureObject * const creatureObject = CreatureObject::getCreatureObject(networkId); + + if (creatureObject == NULL) + { + WARNING(true, ("ERROR: ScriptMethodsObjectInfo::setCreatureName() Unable to resolve the object(%s) to a CreatureObject.", networkId.getValueString().c_str())); + return; + } + + AICreatureController * const aiCreatureController = AICreatureController::asAiCreatureController(creatureObject->getController()); + + if (aiCreatureController == NULL) + { + WARNING(true, ("ERROR: ScriptMethodsObjectInfo::setCreatureName() Unable to resolve the object's(%s) controller to an AiCreatureController.", creatureObject->getDebugInformation().c_str())); + return; + } + + std::string nameString; + JavaLibrary::convert(JavaStringParam(creatureName), nameString); + aiCreatureController->setCreatureName(nameString); +} + +// ---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsObjectInfoNamespace::getCreatureName(JNIEnv * /*env*/, jobject /*self*/, jlong creature) +{ + NetworkId const networkId(creature); + CreatureObject * const creatureObject = CreatureObject::getCreatureObject(networkId); + + if (creatureObject == NULL) + { + return 0; + } + + AICreatureController * const aiCreatureController = AICreatureController::asAiCreatureController(creatureObject->getController()); + + if (aiCreatureController == NULL) + { + return 0; + } + + PersistentCrcString const & creatureName = aiCreatureController->getCreatureName(); + + if (creatureName.isEmpty()) + { + WARNING(true, ("ScriptMethodsObjectInfo::getCreatureName() Somehow this AI(%s) is and calling this function but it was not created using the proper create.scriptlib::initializeCreature().", creatureObject->getDebugInformation().c_str())); + + return 0; + } + + return JavaString(creatureName.getString()).getReturnValue(); +} + +/** + * Returns an object's name. + * + * @param env Java environment + * @param self class calling this function + * @param target id of object whose name to get + * + * @return the name, or null on error + */ +jobject JNICALL ScriptMethodsObjectInfoNamespace::getNameStringId(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + ServerObject* object = NULL; + if (!JavaLibrary::getObject(target, object)) + return 0; + + const StringId & nameId = object->getObjectNameStringId(); + + LocalRefPtr result; + if (ScriptConversion::convert(nameId, result)) + return result->getReturnValue(); + return 0; +} // JavaLibrary::getName + +/** + * Returns the default name of an object that would be created by a given template. + * + * @param env Java environment + * @param self class calling this function + * @param jtemplateName the template name + * + * @return the name, or null if the template doesn't exist + */ +jobject JNICALL ScriptMethodsObjectInfoNamespace::getNameFromTemplate(JNIEnv *env, jobject self, + jstring jtemplateName) +{ + JavaStringParam templateNameParam(jtemplateName); + + std::string templateName; + if (!JavaLibrary::convert(templateNameParam, templateName)) + return 0; + + jint templateCrc = Crc::calculate(templateName.c_str()); + + return getNameFromTemplateCrc(env, self, templateCrc); +} // JavaLibrary::getNameFromTemplate + +/** + * Returns the default name of an object that would be created by a given template. + * + * @param env Java environment + * @param self class calling this function + * @param templateCrc the template crc + * + * @return the name, or null if the template doesn't exist + */ +jobject JNICALL ScriptMethodsObjectInfoNamespace::getNameFromTemplateCrc(JNIEnv *env, jobject self, + jint templateCrc) +{ + const ObjectTemplate * ot = ObjectTemplateList::fetch(templateCrc); + if (ot == NULL) + return 0; + + // the name is stored in the shared template, so if this is a server template, + // get the shared one from it + const SharedObjectTemplate * sharedOt = NULL; + const ServerObjectTemplate * serverOt = dynamic_cast( + ot); + if (serverOt != NULL) + { + const std::string sharedTemplateName(serverOt->getSharedTemplate()); + serverOt->releaseReference(); + serverOt = NULL; + ot = ObjectTemplateList::fetch(sharedTemplateName); + if (ot == NULL) + return 0; + } + + sharedOt = dynamic_cast(ot); + if (sharedOt == NULL) + { + ot->releaseReference(); + return 0; + } + ot = NULL; + + const StringId objectName(sharedOt->getObjectName()); + sharedOt->releaseReference(); + sharedOt = NULL; + + LocalRefPtr jobjectName; + if (!ScriptConversion::convert(objectName, jobjectName)) + return 0; + return jobjectName->getReturnValue(); +} // JavaLibrary::getNameFromTemplate + +/** + * Returns the default names of objects that would be created by given templates. + * + * @param env Java environment + * @param self class calling this function + * @param jtemplateNames the template names + * + * @return the names, or null on error + */ +jobjectArray JNICALL ScriptMethodsObjectInfoNamespace::getNamesFromTemplates(JNIEnv *env, jobject self, + jobjectArray jtemplateNames) +{ + if (jtemplateNames == 0) + return 0; + + // convert the Java template names to C + std::vector templateNames; + if (!ScriptConversion::convert(jtemplateNames, templateNames)) + return 0; + + // convert the C template strings to crcs + std::vector templateCrcs; + templateCrcs.resize(templateNames.size()); + int j = 0; + for (std::vector::const_iterator i = templateNames.begin(); + i != templateNames.end(); ++i) + { + templateCrcs[j++] = Crc::calculate((*i).c_str()); + } + + return getNamesFromCrcs(env, templateCrcs); +} // JavaLibrary::getNamesFromTemplates + +/** + * Returns the default names of objects that would be created by given templates. + * + * @param env Java environment + * @param self class calling this function + * @param jtemplateCrcs the template crcs + * + * @return the names, or null on error + */ +jobjectArray JNICALL ScriptMethodsObjectInfoNamespace::getNamesFromTemplateCrcs(JNIEnv *env, jobject self, + jintArray jtemplateCrcs) +{ + if (jtemplateCrcs == 0) + return 0; + + jsize length = env->GetArrayLength(jtemplateCrcs); + std::vector templateCrcs; + templateCrcs.resize(length); + if (length > 0) + env->GetIntArrayRegion(jtemplateCrcs, 0, length, &templateCrcs[0]); + + return getNamesFromCrcs(env, templateCrcs); +} // JavaLibrary::getNamesFromTemplates + + +//======================================================================== +// class JavaLibrary JNI object info callback methods +//======================================================================== + +/** + * Checks if C thinks an object is authoritative. We usually use the flag on + * obj_id, but we've noticed cases where they are getting out of synch for some + * unknown reason. This function will reset the obj_id flag to the appropriate + * value. + * + * @param env Java environment + * @param self class calling this function + * @param id id of the object to test + * + * @return true if the object is authoritative, false if not + */ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::internalIsAuthoritative(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + const ServerObject * object = NULL; + if (!JavaLibrary::getObject(target, object)) + return JNI_FALSE; + + jboolean authoritative = static_cast(object->isAuthoritative() ? + JNI_TRUE : JNI_FALSE); + const uint32 pid = GameServer::getInstance().getProcessId(); + + LocalRefPtr targetRefPtr = JavaLibrary::getObjId(target); + + if (targetRefPtr != LocalRef::cms_nullPtr) + { + callVoidMethod(*targetRefPtr, JavaLibrary::getMidObjIdSetAuthoritative(), authoritative, pid); + } + else + { + WARNING(true, ("ScriptMethodsObjectInfo::internalIsAuthoritative() network id could not be resolved to an object id")); + } + + return authoritative; +} // JavaLibrary::internalIsAuthoritative + +/** +* Checks to see if the object has a proxy object or an authoritative object on another game server +* @param id id of the object to test +* @return true or false +*/ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::hasProxyOrAuthObject(JNIEnv *env, jobject self, jlong target) +{ + PROFILER_AUTO_BLOCK_DEFINE("JNI::hasProxyOrAuthObject"); + + UNREF(self); + + const ServerObject * object = NULL; + + // if I'm not authoritative, then I must have an authoritative object on another game server + // if I'm authoritative, then see if I'm proxied on any other game server + return (JavaLibrary::getObject(target, object) && (!object->isAuthoritative() || !object->getExposedProxyList().empty())); +} // JavaLibrary::hasProxyOrAuthObject + +/** + * Returns the gender of a creature + * + * @param env Java environment + * @param self class calling this function + * @param target creature we want to check + * + * @return the gender, or -1 on error + */ +jint JNICALL ScriptMethodsObjectInfoNamespace::getGender(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + const CreatureObject *creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return -1; + + return creature->getGender(); +} // JavaLibrary::getGender + +/** + * Tests if two creatures are the same gender. + * + * @param env Java environment + * @param self class calling this function + * @param target1 1st creature + * @param target2 2nd creature + * + * @return true if they are the same gender, false if not or error + */ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::isSameGender(JNIEnv *env, jobject self, jlong target1, jlong target2) +{ + UNREF(self); + + const CreatureObject *creature1 = 0; + if (!JavaLibrary::getObject(target1, creature1)) + return JNI_FALSE; + const CreatureObject *creature2 = 0; + if (!JavaLibrary::getObject(target2, creature2)) + return JNI_FALSE; + + return static_cast(creature1->getGender() == creature2->getGender() ? + JNI_TRUE : JNI_FALSE); +} // JavaLibrary::isSameGender + +/** + * Tests if a creature is a given species. + * + * @param env Java environment + * @param self class calling this function + * @param target creature we want to check + * @param race race we want to check against + * + * @return true if the creature is the race, false if not or error + */ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::isSpecies(JNIEnv *env, jobject self, jlong target, jint race) +{ + UNREF(self); + + const CreatureObject *creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + return static_cast(creature->getSpecies() == race ? JNI_TRUE : JNI_FALSE); +} // JavaLibrary::isRace + +/** + * Tests if a creature is a given race. + * + * @param env Java environment + * @param self class calling this function + * @param target creature we want to check + * @param race race we want to check against + * + * @return true if the creature is the race, false if not or error + */ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::isRace(JNIEnv *env, jobject self, jlong target, jint species, jint race) +{ + UNREF(self); + + const CreatureObject *creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + return static_cast(creature->getSpecies() == species && creature->getRace() == race ? JNI_TRUE : JNI_FALSE); +} // JavaLibrary::isRace + +/** + * Tests if a creature is a given niche. + * + * @param env Java environment + * @param self class calling this function + * @param target creature we want to check + * @param race race we want to check against + * + * @return true if the creature is the race, false if not or error + */ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::isNiche(JNIEnv *env, jobject self, jlong target, jint niche) +{ + UNREF(self); + + const CreatureObject *creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + return static_cast(creature->getNiche() == niche ? JNI_TRUE : JNI_FALSE); +} // JavaLibrary::isRace + +/** + * Tests if a creature is a given niche using a mask. + * + * @param env Java environment + * @param self class calling this function + * @param target creature we want to check + * @param race race we want to check against + * + * @return true if the creature is the race, false if not or error + */ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::isNicheMask(JNIEnv *env, jobject self, jobject target, jint niche, jint mask) +{ + UNREF(self); + + const CreatureObject *creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + return static_cast((creature->getNiche() & mask) == (niche & mask) ? JNI_TRUE : JNI_FALSE); +} // JavaLibrary::isRace + +/** + * Returns the speciesof a creature. + * + * @param env Java environment + * @param self class calling this function + * @param target creature we want to check + * + * @return the race, or -1 on error + */ +jint JNICALL ScriptMethodsObjectInfoNamespace::getSpecies(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + const CreatureObject *creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return -1; + + return creature->getSpecies(); +} // JavaLibrary::getRace + + +/** + * Returns the race of a creature. + * + * @param env Java environment + * @param self class calling this function + * @param target creature we want to check + * + * @return the race, or -1 on error + */ +jint JNICALL ScriptMethodsObjectInfoNamespace::getRace(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + const CreatureObject *creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return -1; + + return creature->getRace(); +} // JavaLibrary::getRace + +/** + * Returns the niche of a creature. + * + * @param env Java environment + * @param self class calling this function + * @param target creature we want to check + * + * @return the race, or -1 on error + */ +jint JNICALL ScriptMethodsObjectInfoNamespace::getNiche(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + const CreatureObject *creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return -1; + + return creature->getNiche(); +} // JavaLibrary::getRace + +/** + * Returns if an object is a mobile/creature. + * + * @param env Java environment + * @param self class calling this function + * @param target object we want to check + * + * @return true if it is, false if not or error + */ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::isMob(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + const CreatureObject *creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + return JNI_TRUE; +} // JavaLibrary::isMob + +/** + * Returns if an object is a tangible. + * + * @param env Java environment + * @param self class calling this function + * @param target object we want to check + * + * @return true if it is, false if not or error + */ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::isTangible(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + const TangibleObject *tangible = 0; + if (!JavaLibrary::getObject(target, tangible)) + return JNI_FALSE; + return JNI_TRUE; +} // JavaLibrary::isTangible + +/** + * Returns if an object is a player. + * + * @param env Java environment + * @param self class calling this function + * @param target object we want to check + * + * @return true if it is, false if not or error + */ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::isPlayer(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + // adding back in old functionality for isplayer - causing issues when players aren't fully loaded yet in npe + // NEEDS TO BE ADDRESSED WITH NAME MANAGER + const ServerObject *player = 0; + if (JavaLibrary::getObject(target, player) && player->isPlayerControlled()) + return JNI_TRUE; + + // Use the name manager so that we can identify players that are not on this server + if (NameManager::getInstance().isPlayer(NetworkId(target))) + return JNI_TRUE; + + return JNI_FALSE; +} // JavaLibrary::isPlayer + +/** + * Returns if the player is AFK + * + * @param env Java environment + * @param self class calling this function + * @param target player we want to check + * + * @return true if the player is currently AFK, false if not + */ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::isAwayFromKeyBoard(JNIEnv *env, jobject self, jlong player) +{ + UNREF(self); + + CreatureObject * playerCreature = NULL; + if (!JavaLibrary::getObject(player, playerCreature)) + return JNI_FALSE; + + PlayerObject * const playerObj = PlayerCreatureController::getPlayerObject(playerCreature); + if (playerObj != NULL && playerObj->isAwayFromKeyBoard()) + { + return JNI_TRUE; + } + return JNI_FALSE; + +} // JavaLibrary::isAwayFromKeyBoard + +/** + * Returns the type of an object. + * + * @param env Java environment + * @param self class calling this function + * @param target object we want to check + * + * @return the object type, or -1 on error + */ +jint JNICALL ScriptMethodsObjectInfoNamespace::getObjType(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + const Object *object = NULL; + if (!JavaLibrary::getObject(target, object)) + return -1; + + return object->getObjectType(); +} // JavaLibrary::getObjType + +/** + * Returns the template id of an object. + * + * @param env Java environment + * @param self class calling this function + * @param target object we want to check + * + * @return the template type, or null on error + */ +jstring JNICALL ScriptMethodsObjectInfoNamespace::getTemplateId(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + const Object *object = NULL; + if (!JavaLibrary::getObject(target, object)) + return 0; + + return JavaString(object->getObjectTemplateName()).getReturnValue(); +} // JavaLibrary::getTemplateId + +/** + * Returns the shared template id of an object. + * + * @param env Java environment + * @param self class calling this function + * @param target object we want to check + * + * @return the template type, or null on error +*/ + +jstring JNICALL ScriptMethodsObjectInfoNamespace::getSharedObjectTemplateName(JNIEnv * /*env*/, jobject /*self*/, jlong target) +{ + Object const * object = NULL; + if (!JavaLibrary::getObject(target, object)) + return 0; + + ObjectTemplate const * const objectTemplate = object->getObjectTemplate(); + if (!objectTemplate) + return 0; + + ServerObjectTemplate const * const serverObjectTemplate = objectTemplate->asServerObjectTemplate(); + if (!serverObjectTemplate) + return 0; + + std::string sharedObjectTemplateName = serverObjectTemplate->getSharedTemplate(); + + char const * const debug = sharedObjectTemplateName.c_str(); + + return JavaString(debug).getReturnValue(); +} // JavaLibrary::getSharedObjectTemplateName + +/** + * Returns a creature's lookat target. + * + * @param env Java environment + * @param self class calling this function + * @param object creature we want to check + * + * @return the lookat target, 0 if error + */ + +jlong JNICALL ScriptMethodsObjectInfoNamespace::getLookAtTarget (JNIEnv* /*env*/, jobject /*self*/, jlong object) +{ + //-- make sure we have a creature object + const CreatureObject* creatureObject = 0; + const ShipObject* shipObject = 0; + if (!JavaLibrary::getObject (object, creatureObject)) + { + if (!JavaLibrary::getObject (object, shipObject)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("getLookAtTarget (): jobject object is not a creature object")); + return 0; + } + } + + //-- if our network id is invalid, we have no lookat target + NetworkId networkId; + if(creatureObject) + networkId = creatureObject->getLookAtTarget (); + else if(shipObject) + networkId = shipObject->getPilotLookAtTarget (); + if (networkId == NetworkId::cms_invalid) + return 0; + + //-- return the network id + return networkId.getValue(); +} + +/** + * Sets the creature's lookat target + * + * @param env Java environment + * @param self class calling this function + * @param object object we want to set the target of + * @param target new target for the object + * + * @return JNI_TRUE on success, JNI_FALSE on fail + */ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::setLookAtTarget (JNIEnv* /*env*/, jobject /*self*/, jlong object, jlong target) +{ + //-- make sure we have a creature object + CreatureObject* creatureObject = 0; + ShipObject* shipObject = 0; + + if (!JavaLibrary::getObject(object, creatureObject)) + { + if (!JavaLibrary::getObject(object, shipObject)) + { + WARNING(true, ("ScriptMethodsObjectInfo::setLookAtTarget() Object could not be resolved to a CreatureObject or ShipObject")); + return JNI_FALSE; + } + } + + NetworkId const networkId(target); + + //-- set our lookat target + if(creatureObject) + creatureObject->setLookAtTarget (networkId); + else if(shipObject) + shipObject->setPilotLookAtTarget (networkId); + + return JNI_TRUE; +} + + +/** +* Returns a creature's beastmaster pet. +* +* @param env Java environment +* @param self class calling this function +* @param object player we want to get pet id of +* +* @return the pet id, 0 if error +*/ + +jlong JNICALL ScriptMethodsObjectInfoNamespace::getBeastmasterPet (JNIEnv* /*env*/, jobject /*self*/, jlong object) +{ + //-- make sure we have a creature object + const CreatureObject* creatureObject = 0; + if (!JavaLibrary::getObject (object, creatureObject)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("getBeastmasterPet (): jobject object is not a creature object")); + return 0; + } + + PlayerObject const *po = PlayerCreatureController::getPlayerObject(creatureObject); + if(!po) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("getBeastmasterPet (): jobject object does not have a player object")); + return 0; + } + + NetworkId networkId = po->getPetId(); + if (networkId == NetworkId::cms_invalid) + return 0; + + //-- return the network id + return networkId.getValue(); +} + +/** +* Sets the creature's beastmaster pet +* +* @param env Java environment +* @param self class calling this function +* @param object object we want to set the pet of +* @param pet new pet id +* +* @return JNI_TRUE on success, JNI_FALSE on fail +*/ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::setBeastmasterPet (JNIEnv* /*env*/, jobject /*self*/, jlong object, jlong pet) +{ + //-- make sure we have a creature object + CreatureObject* creatureObject = 0; + + if (!JavaLibrary::getObject(object, creatureObject)) + { + WARNING(true, ("ScriptMethodsObjectInfo::setBeastmasterPet() Object could not be resolved to a CreatureObject")); + return JNI_FALSE; + } + + PlayerObject *po = PlayerCreatureController::getPlayerObject(creatureObject); + + if(!po) + { + WARNING(true, ("ScriptMethodsObjectInfo::setBeastmasterPet() Object has no player object")); + return JNI_FALSE; + } + NetworkId const networkId(pet); + + po->setPetId(networkId); + + // set the bool for being a beast on the CreatureObject. This lets the client + // handle it slightly differently. + if(networkId.isValid()) + { + CreatureObject *petObject = 0; + if (!JavaLibrary::getObject(pet, petObject)) + { + WARNING(true, ("ScriptMethodsObjectInfo::setBeastmasterPet() Pet object could not be resolved to a CreatureObject")); + return JNI_FALSE; + } + petObject->setIsBeast(true); + + } + + return JNI_TRUE; +} + + +/** +* Returns a creature's intended target. +* +* @param env Java environment +* @param self class calling this function +* @param object creature we want to check +* +* @return the intended target, 0 if error +*/ + +jlong JNICALL ScriptMethodsObjectInfoNamespace::getIntendedTarget (JNIEnv* /*env*/, jobject /*self*/, jlong object) +{ + NetworkId const objectId(object); + CreatureObject const * creatureObject = 0; + if (!JavaLibrary::getObject (object, creatureObject)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsObjectInfo::getIntendedTarget() The specified object(%s) is not a creatureObject", objectId.getValueString().c_str())); + return 0; + } + + //-- if our network id is invalid, we have no intended target + NetworkId networkId; + if(creatureObject) + networkId = creatureObject->getIntendedTarget(); + if (networkId == NetworkId::cms_invalid) + return 0; + + //-- return the network id + return networkId.getValue(); +} + +/** + * Returns a creature's posture. + * + * @param env Java environment + * @param self class calling this function + * @param target creature we want to check + * + * @return the posture, 0 if error/target not creature + */ +jint JNICALL ScriptMethodsObjectInfoNamespace::getPosture(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + const CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return -1; + + return creature->getPosture(); +} // JavaLibrary::getPosture + +/** + * Sets a creature's posture. + * + * @param env Java environment + * @param self class calling this function + * @param target creature we want to change + * @param posture the new posture + * + * @return JNI_TRUE on success, JNI_FALSE on fail/target not creature + */ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::setPosture(JNIEnv *env, jobject self, jlong target, jint posture) +{ + UNREF(self); + + if (posture < 0 || posture >= Postures::NumberOfPostures) + return JNI_FALSE; + + CreatureObject * creature = 0; + if (! JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + // take care of special postures + if (posture == Postures::Dead) + creature->makeDead(NetworkId::cms_invalid, NetworkId::cms_invalid); + else if (posture == Postures::Incapacitated) + creature->setIncapacitated(true, NetworkId::cms_invalid); + else + { + if (creature->isIncapacitated()) + creature->setIncapacitated(false, NetworkId::cms_invalid); + creature->setPosture(static_cast(posture)); + } + return JNI_TRUE; +} // JavaLibrary::setPosture + +/** + * Sets a creature's posture, taking effect immediately on all observing clients. + * + * @param env Java environment + * @param self class calling this function + * @param target creature we want to change + * @param posture the new posture + * + * @return JNI_TRUE on success, JNI_FALSE on fail/target not creature + */ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::setPostureClientImmediate(JNIEnv *env, jobject self, jlong target, jint posture) +{ + UNREF(self); + + if (posture < 0 || posture >= Postures::NumberOfPostures) + return JNI_FALSE; + + CreatureObject * creature = 0; + if (! JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + // take care of special postures + if (posture == Postures::Dead) + creature->makeDead(NetworkId::cms_invalid, NetworkId::cms_invalid); + else if (posture == Postures::Incapacitated) + creature->setIncapacitated(true, NetworkId::cms_invalid); + else + { + if (creature->isIncapacitated()) + creature->setIncapacitated(false, NetworkId::cms_invalid); + creature->setPosture(static_cast(posture)); + } + + //-- Whatever posture was resolved, set that posture in immediate mode on the client. + creature->setPosture(creature->getPosture(), true); + + return JNI_TRUE; +} // JavaLibrary::setPosture + +/** + * Returns a creature's locomotion. + * + * @param env Java environment + * @param self class calling this function + * @param target creature we want to check + * + * @return the posture, 0 if error/target not creature + */ +jint JNICALL ScriptMethodsObjectInfoNamespace::getLocomotion(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + const CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return -1; + + return creature->getLocomotion(); +} // JavaLibrary::getLocomotion + +/** + * Sets a creature's locomotion. + * + * @param env Java environment + * @param self class calling this function + * @param target creature we want to change + * @param posture the new posture + * + * @return JNI_TRUE on success, JNI_FALSE on fail/target not creature + */ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::setLocomotion(JNIEnv *env, jobject, jlong target, jint posture) +{ + if (posture < 0 || posture >= Locomotions::NumberOfLocomotions) + return JNI_FALSE; + + CreatureObject * creature = 0; + if(!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + creature->setLocomotion(static_cast(posture)); + return JNI_TRUE; +} // JavaLibrary::setLocomotion + +/** + * Returns a whether state is set on a creature. + * + * @param env Java environment + * @param self class calling this function + * @param target creature we want to check + * @param whichState state we wish to check + * + * @return 0 if not set, 1 if set, -1 on error/target not creature + */ +jint JNICALL ScriptMethodsObjectInfoNamespace::getState(JNIEnv *env, jobject self, jlong target, jint whichState) +{ + UNREF(self); + + if (whichState < 0 || whichState >= States::NumberOfStates) + return -1; + + const CreatureObject *creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return -1; + + return creature->getState(static_cast(whichState)) ? 1 : 0; +} // JavaLibrary::getState + +/** + * Sets or clears a state on a creature. NOTE: Do not call this function with state + * "Combat". Use the setInCombat()/removeFromCombat() functions instead. + * + * @param env Java environment + * @param self class calling this function + * @param target creature we want to change + * @param whichState the state identifier to deal with + * @param value the new value for the state (set/clear) + * + * @return JNI_TRUE on success, JNI_FALSE on fail/target not creature + */ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::setState(JNIEnv *env, jobject self, jlong target, jint whichState, jboolean value) +{ + UNREF(self); + + if (whichState < 0 || whichState >= States::NumberOfStates) + return JNI_FALSE; + + CreatureObject * creature = 0; + if (! JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + if (whichState == States::Combat) + { + WARNING_STRICT_FATAL(true, ("WARNING: Calling JavaLibrary::setState with " + "state=Combat on object %s", creature->getNetworkId().getValueString().c_str())); + return JNI_FALSE; + } + + creature->setState(static_cast(whichState), value); + + return JNI_TRUE; +} // JavaLibrary::setState + +/** + * Returns the owner of a tangible object + * + * @param env Java environment + * @param self class calling this function + * @param target object whose owner we want + * + * @return id of owner + */ +jlong JNICALL ScriptMethodsObjectInfoNamespace::getOwner(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + const TangibleObject *tobj = 0; + if (!JavaLibrary::getObject(target, tobj)) + return (NetworkId::cms_invalid).getValue(); + return (tobj->getOwnerId()).getValue(); +} // JavaLibrary::getOwner + +/** + * Sets the owner of a tangible object + * + * @param env Java environment + * @param self class calling this function + * @param target object we want to set the owner of + * @param owner new owner for the object + * + * @return JNI_TRUE on success, JNI_FALSE on fail/target not tangible + */ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::setOwner(JNIEnv *env, jobject, jlong target, jlong owner) +{ + ServerObject *tobj = 0; + if (! JavaLibrary::getObject(target, tobj)) + return JNI_FALSE; + + tobj->setOwnerId(NetworkId(owner)); + return JNI_TRUE; +} // JavaLibrary::setOwner + +/** + * Returns if a creature is incapacitated. + * + * @param env Java environment + * @param self class calling this function + * @param target creature we want to know about + * + * @return JNI_TRUE if the creature is incapaciated, JNI_FALSE if not or error + */ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::isIncapacitated(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + const CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + if (creature->isIncapacitated()) + return JNI_TRUE; + return JNI_FALSE; +} // JavaLibrary::isIncapacitated + +/** + * Returns if a creature is incapacitated. + * + * @param env Java environment + * @param self class calling this function + * @param target creature we want to know about + * + * @return JNI_TRUE if the creature is incapaciated, JNI_FALSE if not or error + */ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::isDead(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + const CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + if (creature->isDead()) + return JNI_TRUE; + return JNI_FALSE; +} // JavaLibrary::isIncapacitated + +/** + * Returns if a creature is an npc (i.e. not a player). + * + * @param env Java environment + * @param self class calling this function + * @param target creature we want to know about + * + * @return JNI_TRUE if the creature is an npc, JNI_FALSE if not or error + */ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::isNpcCreature(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + const CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + if (creature->isPlayerControlled()) + return JNI_FALSE; + return JNI_TRUE; +} + + +/** + * Returns if an object is disabled. + * + * @param env Java environment + * @param self class calling this function + * @param target object we want to know about + * + * @return JNI_TRUE if the object is disabled, JNI_FALSE if not + */ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::isDisabled(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + const TangibleObject * object = 0; + if (!JavaLibrary::getObject(target, object)) + return JNI_FALSE; + + // make sure the object isn't a creature or is a vehicle + if (object->asCreatureObject () != NULL && + !GameObjectTypes::isTypeOf (object->getGameObjectType (), SharedObjectTemplate::GOT_vehicle)) + return JNI_FALSE; + + if (object->isDisabled()) + return JNI_TRUE; + return JNI_FALSE; +} // JavaLibrary::isDisabled + +// ---------------------------------------------------------------- + +/** + * Sets the source id an object will be marked as crafted with. If the id is 0, + * the object will be considered not crafted. + * + * @param env Java environment + * @param self class calling this function + * @param target object we want to set as (not)crafted + * @param id the id that will be used as the crafted id + * + * @return JNI_TRUE in success, JNI_FALSE if the target is invalid + */ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::setCraftedId(JNIEnv *env, jobject self, jlong target, jlong id) +{ + TangibleObject * object = 0; + if (!JavaLibrary::getObject(target, object)) + return JNI_FALSE; + + NetworkId craftedId(id); + + object->setCraftedId(craftedId); + return JNI_TRUE; +} // JavaLibrary::setCraftedId + +// ---------------------------------------------------------------- + +/** + * Returns if an object is crafted. + * + * @param env Java environment + * @param self class calling this function + * @param target object we want to know about + * + * @return JNI_TRUE if the object is crafted, JNI_FALSE if not + */ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::isCrafted(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + const TangibleObject * object = 0; + if (!JavaLibrary::getObject(target, object)) + return JNI_FALSE; + + // make sure the object isn't a creature + if (dynamic_cast(object) != NULL) + return JNI_FALSE; + + if (object->isCrafted()) + return JNI_TRUE; + return JNI_FALSE; +} // JavaLibrary::isCrafted + +// ---------------------------------------------------------------- + +/** + * Returns the id of the player who crafted an object. + * + * @param env Java environment + * @param self class calling this function + * @param target object we want to know about + * + * @return the crafter id, or null on error or if the item was not crafted + */ +jlong JNICALL ScriptMethodsObjectInfoNamespace::getCrafter(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + const TangibleObject * object = 0; + if (!JavaLibrary::getObject(target, object)) + return 0; + + const NetworkId crafterId(object->getCreatorId()); + if (crafterId == NetworkId::cms_invalid) + return 0; + + return crafterId.getValue(); +} // JavaLibrary::getCrafter + +// ---------------------------------------------------------------- + +/** + * Changes the id of the player who crafted an object. + * + * @param env Java environment + * @param self class calling this function + * @param target object we want to know about + * @param crafter the id of the crafter + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::setCrafter(JNIEnv *env, jobject self, jlong target, jlong crafter) +{ + UNREF(self); + + TangibleObject * object = 0; + if (!JavaLibrary::getObject(target, object)) + return JNI_FALSE; + + const NetworkId crafterId(crafter); + if (crafterId == NetworkId::cms_invalid) + return JNI_FALSE; + + object->setCreatorId(crafterId); + return JNI_TRUE; +} // JavaLibrary::setCrafter + +// ---------------------------------------------------------------- + +/** + * Returns the scale of a creature. + * + * @param env Java environment + * @param self class calling this function + * @param target creature we want to know about + * + * @return the scale, or -1 on error + */ +jfloat JNICALL ScriptMethodsObjectInfoNamespace::getScale(JNIEnv *env, jobject self, jlong target) +{ + const CreatureObject * creature = NULL; + if (!JavaLibrary::getObject(target, creature)) + return -1.0f; + + return creature->getScaleFactor(); +} // JavaLibrary::getScale + +/** + * Sets the scale of a creature. + * + * @param env Java environment + * @param self class calling this function + * @param target creature we want to set + * @param scale the creature's new scale + * + * @return JNI_TRUE on success, JNI_FALSE on error + */ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::setScale(JNIEnv *env, jobject self, jlong target, jfloat scale) +{ + if (scale <= 0) + return JNI_FALSE; + + CreatureObject * creature = NULL; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + creature->setScaleFactor(scale); + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsObjectInfoNamespace::getDefaultScaleFromObjectTemplate(JNIEnv *env, jobject self, jstring serverObjectTemplateName) +{ + UNREF(env); + UNREF(self); + + //-- Retrieve the server object template name. + JavaStringParam serverObjectTemplateNameParam(serverObjectTemplateName); + std::string serverObjectTemplateNameNarrow; + if (!JavaLibrary::convert(serverObjectTemplateNameParam, serverObjectTemplateNameNarrow)) + { + char const *const errorMessage = "getDefaultScaleFromObjectTemplate(): error handling serverObjectTemplateName arg."; + LOG("ScriptMethodsObjectInfo", (errorMessage)); + JavaLibrary::throwInternalScriptError(errorMessage); + return static_cast(0.0f); + } + + //-- Open the server object template. + ObjectTemplate const *const baseServerObjectTemplate = ObjectTemplateList::fetch(serverObjectTemplateNameNarrow); + if (!baseServerObjectTemplate) + { + char buffer[512]; + snprintf(buffer, sizeof(buffer) - 1, "getDefaultScaleFromObjectTemplate(): failed to open object template [%s].", serverObjectTemplateNameNarrow.c_str()); + buffer[sizeof(buffer) - 1] = '\0'; + + LOG("ScriptMethodsObjectInfo", (buffer)); + JavaLibrary::throwInternalScriptError(buffer); + return static_cast(0.0f); + } + + //-- Convert base object template to server object template. + ServerObjectTemplate const *const serverObjectTemplate = dynamic_cast(baseServerObjectTemplate); + if (!serverObjectTemplate) + { + char buffer[512]; + snprintf(buffer, sizeof(buffer) - 1, "getDefaultScaleFromObjectTemplate(): object template [%s] is not derived from ServerObjectTemplate.", serverObjectTemplateNameNarrow.c_str()); + buffer[sizeof(buffer) - 1] = '\0'; + + LOG("ScriptMethodsObjectInfo", (buffer)); + JavaLibrary::throwInternalScriptError(buffer); + + baseServerObjectTemplate->releaseReference(); + return static_cast(0.0f); + } + + //-- Open the shared object template. + std::string const &sharedObjectTemplateName = serverObjectTemplate->getSharedTemplate(); + ObjectTemplate const *const baseSharedObjectTemplate = ObjectTemplateList::fetch(sharedObjectTemplateName); + if (!baseSharedObjectTemplate) + { + char buffer[512]; + snprintf(buffer, sizeof(buffer) - 1, "getDefaultScaleFromObjectTemplate(): failed to open shared object template [%s].", sharedObjectTemplateName.c_str()); + buffer[sizeof(buffer) - 1] = '\0'; + + LOG("ScriptMethodsObjectInfo", (buffer)); + JavaLibrary::throwInternalScriptError(buffer); + + baseServerObjectTemplate->releaseReference(); + return static_cast(0.0f); + } + + //-- Convert to a shared object template. + SharedObjectTemplate const *const sharedObjectTemplate = baseSharedObjectTemplate->asSharedObjectTemplate(); + if (!sharedObjectTemplate) + { + char buffer[512]; + snprintf(buffer, sizeof(buffer) - 1, "getDefaultScaleFromObjectTemplate(): object template [%s] is not derived from SharedObjectTemplate.", sharedObjectTemplateName.c_str()); + buffer[sizeof(buffer) - 1] = '\0'; + + LOG("ScriptMethodsObjectInfo", (buffer)); + JavaLibrary::throwInternalScriptError(buffer); + + baseSharedObjectTemplate->releaseReference(); + baseServerObjectTemplate->releaseReference(); + return static_cast(0.0f); + } + + //-- Get scale. + jfloat const returnScale = static_cast(sharedObjectTemplate->getScale()); + + baseSharedObjectTemplate->releaseReference(); + baseServerObjectTemplate->releaseReference(); + + return returnScale; +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsObjectInfoNamespace::getVolume(JNIEnv *env, jobject self, jlong target) +{ + ServerObject *obj; + if (!JavaLibrary::getObject(target,obj)) + return 0; + else + return obj->getVolume(); +} + +jboolean JNICALL ScriptMethodsObjectInfoNamespace::isFacing(JNIEnv *env, jobject self, jlong mob, jobject target) +{ + Object * object = 0; + if (!JavaLibrary::getObject(mob, object)) + return JNI_FALSE; + Vector v; + if (!ScriptConversion::convertWorld(target, v)) + { + return JNI_FALSE; + } + + Vector positionInObjectSpace = object->rotateTranslate_w2o (v); + real theta = positionInObjectSpace.theta (); + + if (abs(theta) <= PI_OVER_4) + return JNI_TRUE; + else + return JNI_FALSE; +} + +/** + * Returns the distance between two objects. Note that this is the distance + * between the bounding-sphere edges, not the centers. + * + * @param env Java environment + * @param self class calling this function + * @param target1 one of the objects + * @param target2 the other object + * + * @return the distance, or -1 on error + */ +jfloat JNICALL ScriptMethodsObjectInfoNamespace::getDistance(JNIEnv *env, jobject self, jlong target1, jlong target2) +{ + ServerObject const * object1 = 0; + if (!JavaLibrary::getObject(target1, object1)) + return -1.0f; + ServerObject const * object2 = 0; + if (!JavaLibrary::getObject(target2, object2)) + return -1.0f; + + jfloat distance = object1->getDistanceBetweenCollisionSpheres_w(*object2); + return distance; +} // JavaLibrary::getDistance + +/** + * Returns the distance between two locations. The locations should be in + * different cells. + * + * @param env Java environment + * @param self class calling this function + * @param loc1 the 1st location + * @param loc2 the 2st location + * + * @return the distance between the points, or -1 on error + */ +jfloat JNICALL ScriptMethodsObjectInfoNamespace::getLocationDistance(JNIEnv *env, jobject self, jobject loc1, jobject loc2) +{ + if (loc1 == 0 || loc2 == 0) + return -1.0f; + + // get the location data + Vector targetLoc1; + std::string targetSceneId1; + NetworkId targetCell1; + if (!ScriptConversion::convert(loc1, targetLoc1, targetSceneId1, targetCell1)) + return -1.0f; + + Vector targetLoc2; + std::string targetSceneId2; + NetworkId targetCell2; + if (!ScriptConversion::convert(loc2, targetLoc2, targetSceneId2, targetCell2)) + return -1.0f; + + // make sure we're on the same planet + if (targetSceneId1 != targetSceneId2) + return -1.0f; + + // translate local coordinates to world coordinates + Object * cell1 = NetworkIdManager::getObjectById(targetCell1); + if (cell1 == NULL) + return -1; + const Vector & worldLoc1 = cell1->rotateTranslate_o2w(targetLoc1); + Object * cell2 = NetworkIdManager::getObjectById(targetCell2); + if (cell2 == NULL) + return -1; + const Vector & worldLoc2 = cell2->rotateTranslate_o2w(targetLoc2); + + float dx = worldLoc1.x - worldLoc2.x; + float dy = worldLoc1.y - worldLoc2.y; + float dz = worldLoc1.z - worldLoc2.z; + + return sqrt(dx * dx + dy * dy + dz * dz); +} // JavaLibrary::getLocationDistance + +/** +* Returns true if a point is within a conical frustum. +* +* @param env Java environment +* @param self class calling this function +* @param jTestLoc the location to be tested +* @param jStartLoc the center of one end of the conical frustum +* @param jEndLoc the center of the second end of the conical frustum +* @param startRadius the radius at the first point +* @param endRadius the radius at the second point +* +* @return true if the point is within the conical frustum +*/ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::isLocationInConicalFrustum(JNIEnv *env, jobject self, jobject jTestLoc, jobject jStartLoc, jobject jEndLoc, jfloat startRadius, jfloat endRadius, jboolean use2d) +{ + if (jTestLoc == 0 || jStartLoc == 0 || jEndLoc == 0) + return false; + + // get the location data + Vector testLoc; + std::string testSceneId; + NetworkId testCellId; + if (!ScriptConversion::convert(jTestLoc, testLoc, testSceneId, testCellId)) + return false; + + Vector startLoc; + std::string startSceneId; + NetworkId startCellId; + if (!ScriptConversion::convert(jStartLoc, startLoc, startSceneId, startCellId)) + return false; + + Vector endLoc; + std::string endSceneId; + NetworkId endCellId; + if (!ScriptConversion::convert(jEndLoc, endLoc, endSceneId, endCellId)) + return false; + + // make sure we're all on the same planet + if (testSceneId != startSceneId || testSceneId != endSceneId) + return false; + + // translate local coordinates to world coordinates if they are in cells + Object * testCell = NetworkIdManager::getObjectById(testCellId); + Vector testWorldLoc = (testCell != NULL) ? testCell->rotateTranslate_o2w(testLoc) : testLoc; + + Object * startCell = NetworkIdManager::getObjectById(startCellId); + Vector startWorldLoc = (startCell != NULL) ? startCell->rotateTranslate_o2w(startLoc) : startLoc; + + Object * endCell = NetworkIdManager::getObjectById(endCellId); + Vector endWorldLoc = (endCell != NULL) ? endCell->rotateTranslate_o2w(endLoc) : endLoc; + + if(use2d) + { + testWorldLoc.y = 0.0f; + startWorldLoc.y = 0.0f; + endWorldLoc.y = 0.0f; + } + + float t; + Vector const closestPointOnAxis = testWorldLoc.findClosestPointOnLine(startWorldLoc, endWorldLoc, &t); + + if(t < 0.0f || t > 1.0f) + return false; + + float const distanceFromAxisSquared = testWorldLoc.magnitudeBetweenSquared(closestPointOnAxis); + float const frustumRadius = (endRadius - startRadius) * t + startRadius; + + return (frustumRadius*frustumRadius) > distanceFromAxisSquared; + +} // JavaLibrary::isLocationInConicalFrustum + +/** +* Returns true if a point is within a cone +* +* @param env Java environment +* @param self class calling this function +* @param jTestLoc the location to be tested +* @param jStartLoc the center of one end of the conical frustum +* @param jDirectionLoc a point in the direction of the cone +* @param range the range of the cone +* @param halfAngle the half angle of the cone in degrees +* +* @return true if the point is within the cone +*/ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::isLocationInCone(JNIEnv *env, jobject self, jobject jTestLoc, jobject jStartLoc, jobject jDirectionLoc, jfloat range, jfloat halfAngle, jboolean use2d) +{ + if (jTestLoc == 0 || jStartLoc == 0 || jDirectionLoc == 0) + return false; + + // get the location data + Vector testLoc; + std::string testSceneId; + NetworkId testCellId; + if (!ScriptConversion::convert(jTestLoc, testLoc, testSceneId, testCellId)) + return false; + + Vector startLoc; + std::string startSceneId; + NetworkId startCellId; + if (!ScriptConversion::convert(jStartLoc, startLoc, startSceneId, startCellId)) + return false; + + Vector endLoc; + std::string endSceneId; + NetworkId endCellId; + if (!ScriptConversion::convert(jDirectionLoc, endLoc, endSceneId, endCellId)) + return false; + + // make sure we're all on the same planet + if (testSceneId != startSceneId || testSceneId != endSceneId) + return false; + + // translate local coordinates to world coordinates if they are in cells + Object * testCell = NetworkIdManager::getObjectById(testCellId); + Vector const& testWorldLoc = (testCell != NULL) ? testCell->rotateTranslate_o2w(testLoc) : testLoc; + + Object * startCell = NetworkIdManager::getObjectById(startCellId); + Vector const & startWorldLoc = (startCell != NULL) ? startCell->rotateTranslate_o2w(startLoc) : startLoc; + + Object * endCell = NetworkIdManager::getObjectById(endCellId); + Vector const & endWorldLoc = (endCell != NULL) ? endCell->rotateTranslate_o2w(endLoc) : endLoc; + + Vector testPointConeSpace = testWorldLoc - startWorldLoc; + if(use2d) + { + testPointConeSpace.y = 0.0f; + } + + float const distanceSquared = testPointConeSpace.magnitudeSquared(); + + if(distanceSquared > sqr(range)) + return false; + + Vector coneAxisVector = endWorldLoc - startWorldLoc; + + if(use2d) + { + coneAxisVector.y = 0.0f; + } + + if(!coneAxisVector.normalize()) + return false; + + //If the vector is too small to normalize then the test location + //must be within some small epsilon of the start location so allow + //it to pass + if(!testPointConeSpace.normalize()) + return true; + + float const cosAngle = cos(convertDegreesToRadians(halfAngle)); + const float dotProduct = coneAxisVector.dot(testPointConeSpace); + const bool withinCone = (dotProduct >= cosAngle); + + return withinCone; + +} // JavaLibrary::isLocationInCone + +jboolean JNICALL ScriptMethodsObjectInfoNamespace::areFacingEachOther(JNIEnv *env, jobject self, jlong mob1, jlong mob2) +{ + Object * object1 = 0; + if (!JavaLibrary::getObject(mob1, object1)) + return JNI_FALSE; + Object * object2 = 0; + if (!JavaLibrary::getObject(mob2, object2)) + return JNI_FALSE; + + Vector positionInObjectSpace = object1->rotateTranslate_w2o (object2->getPosition_w()); + real theta = positionInObjectSpace.theta (); + + if (abs(theta) > PI_OVER_4) + return JNI_FALSE; + else + { + // object1 is facing object2, so see if object2 is facing object1 + Vector positionInObjectSpace2 = object2->rotateTranslate_w2o (object1->getPosition_w()); + real theta2 = positionInObjectSpace2.theta (); + + if (abs(theta2) > PI_OVER_4) + return JNI_FALSE; + else + return JNI_TRUE; + } +} + +jboolean JNICALL ScriptMethodsObjectInfoNamespace::exists(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + Object * object = 0; + if (!JavaLibrary::getObject(target, object)) + return JNI_FALSE; + else + return JNI_TRUE; +} + +jboolean JNICALL ScriptMethodsObjectInfoNamespace::isInWorld(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + ServerObject * object = 0; + if (!JavaLibrary::getObject(target, object)) + return JNI_FALSE; + else + { + if (object->isInWorld()) + return JNI_TRUE; + else + return JNI_FALSE; + } +} + +jboolean JNICALL ScriptMethodsObjectInfoNamespace::isInWorldCell(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + NOT_NULL(env); + + ServerObject* object = NULL; + if (!JavaLibrary::getObject(target, object)) + return JNI_FALSE; + + return (object->isInWorldCell()); +} + +//----------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectInfoNamespace::watch(JNIEnv * env, jobject self, jlong target) +{ + UNREF(env); + UNREF(self); + UNREF(target); + WARNING_STRICT_FATAL(true, ("This function has been depricated. Do not use\n")); +} + +//----------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectInfoNamespace::stopWatching(JNIEnv * env, jobject self, jlong target) +{ + UNREF(env); + UNREF(self); + UNREF(target); + WARNING_STRICT_FATAL(true, ("This function has been depricated. Do not use\n")); + +} + +//----------------------------------------------------------------------- + +void JavaLibrary::onStopWatching(ServerObject & observer, ServerObject & subject) +{ + DEBUG_FATAL(true, ("DO NOT CALL WATCHING/STOP WATCHING! REQUIRES NON-EXISTENT MESSAGE INTERFACE!")); + static const std::string dictEntry("subject"); + + LocalRefPtr params = createNewObject(ms_clsDictionary, ms_midDictionary); + LocalRefPtr s = JavaLibrary::getObjId(subject); + JavaString paramName(dictEntry.c_str()); + callObjectMethod(*params, ms_midDictionaryPut, paramName.getValue(), s->getValue()); + + GameScriptObject * scripts = observer.getScriptObject(); + if(scripts) + { + //depricated +// scripts->addMessage("OnStopWatching", params, 0); + } +} + +//----------------------------------------------------------------------- + +void JavaLibrary::onWatching(ServerObject & observer, ServerObject & subject) +{ + DEBUG_FATAL(true, ("DO NOT CALL WATCHING/STOP WATCHING! REQUIRES NON-EXISTENT MESSAGE INTERFACE!")); + static const std::string dictEntry("subject"); + + LocalRefPtr params = createNewObject(ms_clsDictionary, ms_midDictionary); + LocalRefPtr s = JavaLibrary::getObjId(subject); + JavaString paramName(dictEntry.c_str()); + callObjectMethod(*params, ms_midDictionaryPut, paramName.getValue(), s->getValue()); + + GameScriptObject * scripts = observer.getScriptObject(); + if(scripts) + { + // depricated +// scripts->addMessage("OnWatching", params, 0); + } +} + +//----------------------------------------------------------------------- +// private local namespace used for CustomizationData support + +namespace +{ + typedef std::vector StringVector; + typedef std::vector CustomizationVariableVector; + + // custom_var TypeId definitions + const jint CVT_UNKNOWN = static_cast(0); + const jint CVT_CONST_STRING = static_cast(1); + const jint CVT_RANGED_INT = static_cast(2); + const jint CVT_PALCOLOR = static_cast(3); + + struct CustomizationVariableIteratorData + { + StringVector m_variableNames; + CustomizationVariableVector m_customizationVariables; + }; + + // NOTE: this is inappropriate if we will allow multithreaded Java script execution + CustomizationVariableIteratorData s_customizationVariableIteratorData; + + //----------------------------------------------------------------------- + + bool DebugDumpCustomVar(JNIEnv *env, LocalRefPtr customVar) + { + NOT_NULL(env); + NOT_NULL(customVar.get()); + NOT_NULL(customVar->getValue()); + + //-- get class for custom_var + const jclass customVarClass = env->FindClass("custom_var"); + + DEBUG_REPORT_LOG(!customVarClass, ("FindClass() failed for custom_var.\n")); + if (!customVarClass) + return false; + + //-- invoke "String getVarName()" method + const jmethodID getVarNameMid = env->GetMethodID(customVarClass, "getVarName", "()Ljava/lang/String;"); + + DEBUG_REPORT_LOG(!getVarNameMid , ("GetMethodId() failed for getVarName().\n")); + if (!getVarNameMid) + { + env->DeleteLocalRef(customVarClass); + return false; + } + + std::string nativeCustomVarName; + + JavaStringPtr javaCustomVarName = callStringMethod(*customVar, getVarNameMid); + JavaLibrary::convert(*javaCustomVarName, nativeCustomVarName); + + //-- invoke "int getTypeId()" method + const jmethodID getTypeIdMid = env->GetMethodID(customVarClass, "getTypeId", "()I"); + + DEBUG_REPORT_LOG(!getTypeIdMid, ("GetMethodId() failed for getTypeId().\n")); + if (!getTypeIdMid) + { + env->DeleteLocalRef(customVarClass); + return false; + } + + const int nativeCustomVarTypeId = callIntMethod(*customVar, getTypeIdMid); + + //-- cleanup + env->DeleteLocalRef(customVarClass); + + //-- print results + REPORT_LOG(true, ("<*> (context); + + //-- add CustomizationVariable to the container + iteratorData->m_variableNames.push_back(fullVariablePathName); + iteratorData->m_customizationVariables.push_back(customizationVariable); + } + + // ---------------------------------------------------------------------- + + void BasicRangedIntCustomizationVariableCollector(const std::string &fullVariablePathName, CustomizationVariable *customizationVariable, void *context) + { + //-- validate arguments + if (!customizationVariable || !context) + { + DEBUG_FATAL(true, ("programmer error: callback made with NULL arguments.\n")); + return; + } + + //-- check if this is a basic ranged int + BasicRangedIntCustomizationVariable *const variable = dynamic_cast(customizationVariable); + if (!variable) + return; + + //-- convert context to customization variable collection + CustomizationVariableIteratorData *const iteratorData = reinterpret_cast(context); + + //-- add CustomizationVariable to the container + iteratorData->m_variableNames.push_back(fullVariablePathName); + iteratorData->m_customizationVariables.push_back(customizationVariable); + } + + // ---------------------------------------------------------------------- + + void PalcolorCustomizationVariableCollector(const std::string &fullVariablePathName, CustomizationVariable *customizationVariable, void *context) + { + //-- validate arguments + if (!customizationVariable || !context) + { + DEBUG_FATAL(true, ("programmer error: callback made with NULL arguments.\n")); + return; + } + + //-- check if this is a PaletteColorCustomizationVariable + PaletteColorCustomizationVariable *const variable = dynamic_cast(customizationVariable); + if (!variable) + return; + + //-- convert context to customization variable collection + CustomizationVariableIteratorData *const iteratorData = reinterpret_cast(context); + + //-- add CustomizationVariable to the container + iteratorData->m_variableNames.push_back(fullVariablePathName); + iteratorData->m_customizationVariables.push_back(customizationVariable); + } +} + +// ---------------------------------------------------------------------- +/** + * Create a Java custom_var given a CustomizationVariable instance + * and its name. + * + * The Java custom_var instance will provide information regarding the + * given CustomizationVariable instance, and will allow access to modify + * the CustomizationVariable if applicable. + * + * @param objId the Java obj_id for the Object influenced by + * the newly-created customization variable. + * @param variablePathName the full pathname for the variable to create. + * @param variable the variable for which we will construct a + * Java custom_var. + * + * @return the Java-accessible custom_var instance, the script-side counterpart to + * the given C++-side CustomizationVariable. Will return NULL if + * a Java exception or other error occurs. + */ +LocalRefPtr ScriptMethodsObjectInfoNamespace::createCustomVar(const jlong &objId, const std::string &variablePathName, CustomizationVariable &variable) +{ + PROFILER_AUTO_BLOCK_DEFINE("JNI::createCustomVar"); + //-- handle variables of type BasicRangedIntCustomVariable + BasicRangedIntCustomizationVariable *const briVariable = dynamic_cast(&variable); + if (briVariable) + return createRangedIntCustomVar(objId, variablePathName, *briVariable); + + //-- handle variables of type PaletteColorCustomizationVariable + PaletteColorCustomizationVariable *const pcVariable = dynamic_cast(&variable); + if (pcVariable) + return createPalcolorCustomVar(objId, variablePathName, *pcVariable); + + //-- create Java string for custom_var name arg + JavaString customVarName(variablePathName.c_str()); + if (customVarName.getValue() == 0) + { + // exception thrown. + return LocalRef::cms_nullPtr; + } + + //-- construct a basic custom_var + return createNewObject(JavaLibrary::getClsCustomVar(), JavaLibrary::getMidCustomVarObjIdStringInt(), objId, customVarName.getValue(), CVT_UNKNOWN); +} + +/** + * Create a Java ranged_int_custom_var given a RangedIntCustomizationVariable + * instance and its name. + * + * The Java custom_var instance will provide information regarding the + * given CustomizationVariable instance, and will allow access to modify + * the CustomizationVariable if applicable. + * + * @param objId the Java obj_id for the Object influenced by + * the newly-created customization variable. + * @param variablePathName the full pathname for the variable to create. + * @param variable the variable for which we will construct a + * Java custom_var. + * + * @return the Java-accessible ranged_int_custom_var instance, the script-side counterpart to + * the given C++-side CustomizationVariable. Will return NULL if + * a Java exception or other error occurs. + */ +LocalRefPtr ScriptMethodsObjectInfoNamespace::createRangedIntCustomVar(const jlong &objId, const std::string &variablePathName, RangedIntCustomizationVariable &rangedIntVariable) +{ + PROFILER_AUTO_BLOCK_DEFINE("JNI::createRangedIntCustomVar"); + //-- create Java string for custom_var name arg + JavaString customVarName(variablePathName.c_str()); + if (customVarName.getValue() == 0) + { + // exception thrown. + return LocalRef::cms_nullPtr; + } + + //-- get the variable range + int minRangeInclusive = 0; + int maxRangeExclusive = 0; + + rangedIntVariable.getRange(minRangeInclusive, maxRangeExclusive); + + //-- create the variable + return createNewObject(JavaLibrary::getClsRangedIntCustomVar(), JavaLibrary::getMidRangedIntCustomVar(), objId, customVarName.getValue(), CVT_RANGED_INT, static_cast(minRangeInclusive), static_cast(maxRangeExclusive)); +} + +/** + * Create a Java palcolor_custom_var given a PaletteColorCustomizationVariable + * instance and its name. + * + * The Java custom_var instance will provide information regarding the + * given CustomizationVariable instance, and will allow access to modify + * the CustomizationVariable if applicable. + * + * @param objId the Java obj_id for the Object influenced by + * the newly-created customization variable. + * @param variablePathName the full pathname for the variable to create. + * @param variable the variable for which we will construct a + * Java custom_var. + * + * @return the Java-accessible palcolor_custom_var instance, the script-side counterpart to + * the given C++-side CustomizationVariable. Will return NULL if + * a Java exception or other error occurs. + */ +LocalRefPtr ScriptMethodsObjectInfoNamespace::createPalcolorCustomVar(const jlong &objId, const std::string &variablePathName, PaletteColorCustomizationVariable &variable) +{ + PROFILER_AUTO_BLOCK_DEFINE("JNI::createPalcolorCustomVar"); + //-- create Java string for custom_var name arg + JavaString customVarName(variablePathName.c_str()); + if (customVarName.getValue() == 0) + { + // exception thrown. + return LocalRef::cms_nullPtr; + } + + //-- get the variable range + int minRangeInclusive = 0; + int maxRangeExclusive = 0; + + variable.getRange(minRangeInclusive, maxRangeExclusive); + + //-- create the variable + return createNewObject(JavaLibrary::getClsPalcolorCustomVar(), JavaLibrary::getMidPalcolorCustomVar(), objId, customVarName.getValue(), CVT_PALCOLOR, static_cast(minRangeInclusive), static_cast(maxRangeExclusive)); +} + +// ---------------------------------------------------------------------- + +LocalRefPtr ScriptMethodsObjectInfoNamespace::createColor(int r, int g, int b, int a) +{ + return createNewObject(JavaLibrary::getClsColor(), JavaLibrary::getMidColor(), static_cast(r), static_cast(g), static_cast(b), static_cast(a)); +} + +// ---------------------------------------------------------------------- +/** + * Fetch the CustomizationData instance associated with the Object + * specified by the given obj_id. + * + * This function may return NULL if the specified object doesn't have + * customization data or if some other error occurs. + * + * The caller must call CustomizationData::release() on the non-NULL return + * value when the reference no longer is needed. Failure to do so will cause + * a memory leak. + * + * @param objId the Java obj_id representing the Object for which the + * CustomizationData instance should be retrieved. + * + * @return the CustomizationData instance associated with the specified + * Object. May return NULL if the Object doesn't have customization + * data or if an error occurs. + */ +CustomizationData *ScriptMethodsObjectInfoNamespace::fetchCustomizationDataFromObjId(jlong objId) +{ + PROFILER_AUTO_BLOCK_DEFINE("JNI::fetchCustomizationDataFromObjId"); + if (!objId) + return NULL; + + //-- Get the target TangibleObject. + TangibleObject *object = 0; + if (!JavaLibrary::getObject(objId, object)) + { + // this Object doesn't exist or isn't derived from TangibleObject + return NULL; + } + + //-- Fetch the CustomizationData. + CustomizationDataProperty *const cdProperty = safe_cast(object->getProperty(CustomizationDataProperty::getClassPropertyId())); + if (!cdProperty) + { + // this Object doesn't expose any customization data + return NULL; + } + + CustomizationData *const customizationData = cdProperty->fetchCustomizationData(); + if (!customizationData) + { + // this shouldn't happen + DEBUG_WARNING(true, ("CustomizationDataProperty returned NULL CustomizationData on fetch().\n")); + return NULL; + } + + //-- return the CustomizationData instance. + return customizationData; +} + +//----------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsObjectInfoNamespace::getAllCustomVars(JNIEnv * env, jclass /* selfClass */, jlong target) +{ + PROFILER_AUTO_BLOCK_DEFINE("JNI::getAllCustomVars"); + //-- get the CustomizationData instance for the target object. + CustomizationData *const customizationData = fetchCustomizationDataFromObjId(target); + if (!customizationData) + return NULL; + + //-- collect all local CustomizationVariable instances. + // NOTE: if we allow multithreaded access to this code from script, we cannot use this static + // iterator data structure. + s_customizationVariableIteratorData.m_customizationVariables.clear(); + s_customizationVariableIteratorData.m_variableNames.clear(); + + customizationData->iterateOverVariables(CustomizationVariableCollector, &s_customizationVariableIteratorData, false); + DEBUG_FATAL(s_customizationVariableIteratorData.m_variableNames.size() != s_customizationVariableIteratorData.m_customizationVariables.size(), ("mismatched return data sizes: %u/%u", s_customizationVariableIteratorData.m_variableNames.size(), s_customizationVariableIteratorData.m_customizationVariables.size())); + + //-- create a Java custom_var for each CustomizationVariable instance. + LocalObjectArrayRefPtr customVarArray; + + if (!s_customizationVariableIteratorData.m_variableNames.empty()) + { + // create the Java return array + const int variableCount = static_cast(s_customizationVariableIteratorData.m_variableNames.size()); + customVarArray = createNewObjectArray(variableCount, JavaLibrary::getClsCustomVar()); + if (customVarArray != LocalObjectArrayRef::cms_nullPtr) + { + // convert each C++ CustomizationVariable into a Java custom_var + for (int i = 0; i < variableCount; ++i) + { + CustomizationVariable *const variable = s_customizationVariableIteratorData.m_customizationVariables[static_cast(i)]; + NOT_NULL(variable); + + LocalRefPtr customVar = createCustomVar(target, s_customizationVariableIteratorData.m_variableNames[static_cast(i)], *variable); + if (customVar == LocalRef::cms_nullPtr) + { + // ran into problem, bail. + customVarArray = LocalObjectArrayRef::cms_nullPtr; + break; + } + + // set new customVar into return array + setObjectArrayElement(*customVarArray, i, *customVar); + if (env->ExceptionCheck()) + { + // ran into a problem, bail. + customVarArray = LocalObjectArrayRef::cms_nullPtr; + break; + } + } + } + } + + //-- release local CustomizationData reference + customizationData->release(); + + //-- return result + if (customVarArray.get() != NULL) + return customVarArray->getReturnValue(); + return 0; +} + +// ---------------------------------------------------------------------- + +jobject JNICALL ScriptMethodsObjectInfoNamespace::getCustomVarByName(JNIEnv * /* env */, jclass /* selfClass */, jlong target, jstring varPathName) +{ + JavaStringParam localVarPathName(varPathName); + + //-- get the CustomizationData instance for the target object. + CustomizationData *const customizationData = fetchCustomizationDataFromObjId(target); + if (!customizationData) + return NULL; + + //-- get the CustomizationVariable for the specified variable name + std::string nativeVarPathName; + JavaLibrary::convert(localVarPathName, nativeVarPathName); + + CustomizationVariable *const variable = customizationData->findVariable(nativeVarPathName); + if (!variable) + return NULL; + + //-- create a Java custom_var based on this CustomizationVariable + LocalRefPtr newCustomVar = createCustomVar(target, nativeVarPathName, *variable); + + //-- release local references + customizationData->release(); + + return newCustomVar->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsObjectInfoNamespace::getRangedIntCustomVarValue(JNIEnv * /* env */, jclass /* selfClass */, jlong target, jstring varPathName) +{ + JavaStringParam localVarPathName(varPathName); + + //-- get the CustomizationData instance for the target object. + CustomizationData *const customizationData = fetchCustomizationDataFromObjId(target); + if (!customizationData) + return 0; + + //-- get the CustomizationVariable for the specified variable name + std::string nativeVarPathName; + JavaLibrary::convert(localVarPathName, nativeVarPathName); + + const RangedIntCustomizationVariable *const variable = dynamic_cast(customizationData->findConstVariable(nativeVarPathName)); + if (!variable) + { + DEBUG_WARNING(true, ("getRangedIntCustomVarValue() tried to access var [%s] as ranged int, but doesn't exist or not right type.\n", nativeVarPathName.c_str())); + return 0; + } + + //-- retrieve the variable value + const jint returnValue = static_cast(variable->getValue()); + + //-- release local references + customizationData->release(); + + //-- return value + return returnValue; +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectInfoNamespace::setRangedIntCustomVarValue(JNIEnv * /* env */, jclass /* selfClass */, jlong target, jstring varPathName, jint newValue) +{ + JavaStringParam localVarPathName(varPathName); + + //-- get the CustomizationData instance for the target object. + CustomizationData *const customizationData = fetchCustomizationDataFromObjId(target); + if (!customizationData) + return; + + //-- get the CustomizationVariable for the specified variable name + std::string nativeVarPathName; + JavaLibrary::convert(localVarPathName, nativeVarPathName); + + RangedIntCustomizationVariable *const variable = dynamic_cast(customizationData->findVariable(nativeVarPathName)); + if (!variable) + { + DEBUG_WARNING(true, ("setRangedIntCustomVarValue() tried to access var [%s] as ranged int, but not right type.\n", nativeVarPathName.c_str())); + return; + } + + //-- set the variable value + variable->setValue(static_cast(newValue)); + + //-- release local references + customizationData->release(); +} + +// ---------------------------------------------------------------------- + +jobject JNICALL ScriptMethodsObjectInfoNamespace::getPalcolorCustomVarSelectedColor(JNIEnv * /* env */, jclass /* selfClass */, jlong target, jstring varPathName) +{ + JavaStringParam localVarPathName(varPathName); + + //-- get the CustomizationData instance for the target object. + CustomizationData *const customizationData = fetchCustomizationDataFromObjId(target); + if (!customizationData) + return 0; + + //-- get the CustomizationVariable for the specified variable name + std::string nativeVarPathName; + JavaLibrary::convert(localVarPathName, nativeVarPathName); + + const PaletteColorCustomizationVariable *const variable = dynamic_cast(customizationData->findConstVariable(nativeVarPathName)); + if (!variable) + { + DEBUG_WARNING(true, ("getPalcolorCustomVarSelectedColor() tried to access var [%s] as palette color var, but doesn't exist or is not the right type.\n", nativeVarPathName.c_str())); + return 0; + } + + //-- get the PackedArgb value for the color + const int paletteIndex = variable->getValue(); + + const PaletteArgb *const palette = variable->fetchPalette(); + bool error = false; + const PackedArgb color = palette->getEntry(paletteIndex, error); + palette->release(); + + //-- release local references + customizationData->release(); + + if (error) + return NULL; + + //-- return value + return createColor(color.getR(), color.getG(), color.getB(), color.getA())->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectInfoNamespace::setPalcolorCustomVarClosestColor(JNIEnv * /* env */, jclass /* selfClass */, jlong target, jstring varPathName, jint r, jint g, jint b, jint a) +{ + JavaStringParam localVarPathName(varPathName); + + CustomizationData *const customizationData = fetchCustomizationDataFromObjId(target); + if (!customizationData) + { + DEBUG_WARNING(true, ("setPalcolorCustomVarClosestColor(): object doesn't have any customization variables.\n")); + return; + } + + //-- get the CustomizationVariable for the specified variable name + std::string nativeVarPathName; + JavaLibrary::convert(localVarPathName, nativeVarPathName); + + PaletteColorCustomizationVariable *const variable = dynamic_cast(customizationData->findVariable(nativeVarPathName)); + if (!variable) + { + DEBUG_WARNING(true, ("setPalcolorCustomVarClosestColor() tried to access var [%s] as palette color var, but doesn't exist or is not the right type.\n", nativeVarPathName.c_str())); + return; + } + + //-- set variable to the palette entry closest to the given color + variable->setClosestColor(PackedArgb(static_cast(a), static_cast(r), static_cast(g), static_cast(b))); +} + +// ---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsObjectInfoNamespace::getPalcolorCustomVarColors(JNIEnv * env, jclass /* selfClass */, jlong target, jstring varPathName) +{ + JavaStringParam localVarPathName(varPathName); + + //-- get the CustomizationData instance for the target object. + CustomizationData *const customizationData = fetchCustomizationDataFromObjId(target); + if (!customizationData) + return 0; + + //-- get the CustomizationVariable for the specified variable name + std::string nativeVarPathName; + JavaLibrary::convert(localVarPathName, nativeVarPathName); + + const PaletteColorCustomizationVariable *const variable = dynamic_cast(customizationData->findConstVariable(nativeVarPathName)); + if (!variable) + { + DEBUG_WARNING(true, ("getPalcolorCustomVarColors() tried to access var [%s] as palette color var, but doesn't exist or is not the right type.\n", nativeVarPathName.c_str())); + return 0; + } + + //-- get the PackedArgb value for the color + const PaletteArgb *const palette = variable->fetchPalette(); + + //-- create the array of colors + LocalObjectArrayRefPtr colorArray; + const int colorCount = palette->getEntryCount(); + + if (colorCount > 0) + { + // create the Java return array + colorArray = createNewObjectArray(colorCount, JavaLibrary::getClsColor()); + if (colorArray != LocalObjectArrayRef::cms_nullPtr) + { + // convert each palette entry color into a Java color instance + for (int i = 0; i < colorCount; ++i) + { + bool error = false; + const PackedArgb color = palette->getEntry(i, error); + + if (error) + { + colorArray = LocalObjectArrayRef::cms_nullPtr; + break; + } + + LocalRefPtr javaColor = createColor(color.getR(), color.getG(), color.getB(), color.getA()); + + if (javaColor == LocalRef::cms_nullPtr) + { + // ran into problem, bail. + colorArray = LocalObjectArrayRef::cms_nullPtr; + break; + } + + // set new color into return array + setObjectArrayElement(*colorArray, i, *javaColor); + if (env->ExceptionCheck()) + { + // ran into a problem, bail. + colorArray = LocalObjectArrayRef::cms_nullPtr; + break; + } + } + } + } + + //-- release local references + palette->release(); + customizationData->release(); + + //-- return result + if (colorArray.get() != NULL) + return colorArray->getReturnValue(); + return 0; +} + +//----------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsObjectInfoNamespace::getCtsDestinationClusters(JNIEnv * /*env*/, jobject /*self*/) +{ + static std::set * s_ctsDestinationClusters = NULL; + if (!s_ctsDestinationClusters) + { + s_ctsDestinationClusters = new std::set; + + bool thisClusterAllowedToUploadCharacterData = false; + + { + int index = 0; + char const * result = 0; + do + { + result = ConfigFile::getKeyString("TransferServer", "serverAllowedToUploadCharacterData", index++, 0); + if ((result != 0) && (GameServer::getInstance().getClusterName() == std::string(result))) + thisClusterAllowedToUploadCharacterData = true; + } + while (result && !thisClusterAllowedToUploadCharacterData); + } + + if (thisClusterAllowedToUploadCharacterData) + { + int index = 0; + char const * result = 0; + do + { + result = ConfigFile::getKeyString("TransferServer", "serverAllowedToDownloadCharacterData", index++, 0); + if ((result != 0) && (GameServer::getInstance().getClusterName() != std::string(result))) + s_ctsDestinationClusters->insert(std::string(result)); + } + while (result); + } + } + + if (!s_ctsDestinationClusters || s_ctsDestinationClusters->empty()) + return 0; + + LocalObjectArrayRefPtr valueArray = createNewObjectArray(s_ctsDestinationClusters->size(), JavaLibrary::getClsString()); + + int i = 0; + for (std::set::const_iterator iter = s_ctsDestinationClusters->begin(); iter != s_ctsDestinationClusters->end(); ++iter) + { + JavaString jval(*iter); + setObjectArrayElement(*valueArray, i++, jval); + } + + return valueArray->getReturnValue(); +} + +//----------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsObjectInfoNamespace::getCurrentSceneName(JNIEnv * env, jobject self) +{ + return JavaString(ServerWorld::getSceneId().c_str()).getReturnValue(); +} + +//----------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsObjectInfoNamespace::getClusterName(JNIEnv * env, jobject self) +{ + return JavaString(GameServer::getInstance().getClusterName().c_str()).getReturnValue(); +} + +//----------------------------------------------------------------------- + +void JavaLibrary::setScriptVar(const ServerObject &object, const std::string & name, int value) +{ + LocalRefPtr obj_id = getObjId(object); + if (obj_id == LocalRef::cms_nullPtr) + return; + + JavaString jname(name); + callVoidMethod(*obj_id, ms_midObjIdSetScriptVarInt, jname.getValue(), value); +} + +//----------------------------------------------------------------------- + +void JavaLibrary::setScriptVar(const ServerObject &object, const std::string & name, float value) +{ + LocalRefPtr obj_id = getObjId(object); + if (obj_id == LocalRef::cms_nullPtr) + return; + + JavaString jname(name); + callVoidMethod(*obj_id, ms_midObjIdSetScriptVarFloat, jname.getValue(), value); +} + +//----------------------------------------------------------------------- + +void JavaLibrary::setScriptVar(const ServerObject &object, const std::string & name, const std::string & value) +{ + LocalRefPtr obj_id = getObjId(object); + if (obj_id == LocalRef::cms_nullPtr) + return; + + JavaString jname(name); + JavaString jvalue(value); + callVoidMethod(*obj_id, ms_midObjIdSetScriptVarString, jname.getValue(), jvalue.getValue()); +} + +//----------------------------------------------------------------------- + +void JavaLibrary::clearScriptVars(const ServerObject & source) +{ + LocalRefPtr obj_id = getObjId(source); + if (obj_id == LocalRef::cms_nullPtr) + return; + callVoidMethod(*obj_id, ms_midObjIdClearScriptVars); +} + +//----------------------------------------------------------------------- + +void JavaLibrary::packScriptVars(const ServerObject & source, std::vector & data) +{ + LocalByteArrayRefPtr jdata = callStaticByteArrayMethod( + ms_clsObjId, ms_midObjIdPackScriptVars, (source.getNetworkId()).getValue()); + ScriptConversion::convert(*jdata, data); + + WARNING(data.size() > 60000, ("JavaLibrary::packScriptVars: Packing " + "scriptvars for object %s, packed data size = %d", + source.getNetworkId().getValueString().c_str(), + static_cast(data.size()))); +} + +//----------------------------------------------------------------------- + +void JavaLibrary::packAllDeltaScriptVars() +{ + callStaticVoidMethod(ms_clsObjId, ms_midObjIdPackAllDeltaScriptVars); +} + +//----------------------------------------------------------------------- + +void JavaLibrary::unpackDeltaScriptVars(const ServerObject & target, const std::vector & data) +{ + LocalByteArrayRefPtr jdata; + ScriptConversion::convert(data, jdata); + callStaticVoidMethod(ms_clsObjId, ms_midObjIdUnpackDeltaScriptVars, (target.getNetworkId()).getValue(), jdata->getValue()); +} + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsObjectInfoNamespace::canEquipWearable(JNIEnv * env, jobject self, jlong player, jlong wearable) +{ + NetworkId const & wearableId = NetworkId(wearable); + CreatureObject * const creatureObject = JavaLibrary::getCreatureThrow(env, player, "canEquipWearable(): player did not resolve to a CreatureObject", false); + if (!creatureObject) + return JNI_FALSE; + + Object * const wearableObj = NetworkIdManager::getObjectById(wearableId); + if(!wearableObj) + { + DEBUG_WARNING(true, ("canEquipWearable got a bad object id %s", wearableId.getValueString().c_str())); + return JNI_FALSE; + } + return (creatureObject->isAppearanceEquippable(wearableObj->asServerObject()->getSharedTemplateName())) ? JNI_TRUE : JNI_FALSE; +} + +//----------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectInfoNamespace::sendScriptVarsToProxies(JNIEnv * env, jobject self, jlong obj, jbyteArray buffer) +{ + PROFILER_AUTO_BLOCK_DEFINE("JNI::sendScriptVarsToProxies"); + + ServerObject * object = 0; + if (obj != 0 && buffer != 0) + { + if (JavaLibrary::getObject(obj, object)) + { + ProxyList const &proxyList = object->getExposedProxyList(); + if (!proxyList.empty()) + { + std::vector data; + if (ScriptConversion::convert(buffer, data)) + { + if(data.size() > 0) + { + WARNING(data.size() > 60000, ("JavaLibrary::sendScriptVarsToProxies: " + "Packing scriptvars for object %s, packed data size = %d", + object->getNetworkId().getValueString().c_str(), + static_cast(data.size()))); + + uint32 const myProcessId = GameServer::getInstance().getProcessId(); + uint32 const authProcessId = object->getAuthServerProcessId(); + ProxyList syncServers(proxyList); + if (myProcessId != authProcessId) + { + syncServers.erase(myProcessId); + syncServers.insert(authProcessId); + } + + ServerMessageForwarding::begin(std::vector(syncServers.begin(), syncServers.end())); + + SynchronizeScriptVarDeltasMessage const deltasMessage(object->getNetworkId(), data); + ServerMessageForwarding::send(deltasMessage); + + ServerMessageForwarding::end(); + } + } + } + } + } +} + +//----------------------------------------------------------------------- + +void JavaLibrary::unpackScriptVars(const ServerObject & target, const std::vector & buffer) +{ + LocalByteArrayRefPtr jbuffer; + ScriptConversion::convert(buffer, jbuffer); + callStaticVoidMethod(ms_clsObjId, ms_midObjIdUnpackScriptVars, (target.getNetworkId()).getValue(), jbuffer->getValue()); +} + +//-------------------------------------------------------------------- + +/** + * Kills a creature and returns true if it was killed or already dead + * + * @param env Java environment + * @param self class calling this function + * @param target creature we want to know about + * + * @return JNI_TRUE if the creature is incapaciated, JNI_FALSE if not or error + */ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::kill(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + if (creature->makeDead(NetworkId::cms_invalid, NetworkId::cms_invalid)) + return JNI_TRUE; + return JNI_FALSE; +} + +//---------------------------------------------------------------------- + +/** + * Kills a player. + * + * @param env Java environment + * @param self class calling this function + * @param player the player + * @param killer who killed the player (may be null) + * + * @return the corpse id of the player, or null on error + */ +jobject JNICALL ScriptMethodsObjectInfoNamespace::killPlayer(JNIEnv *env, jobject self, jobject player, jobject killer) +{ + static const std::string corpseTemplateName("object/tangible/container/corpse/player_corpse.iff"); + + CreatureObject * playerObject = NULL; + if (!JavaLibrary::getObject(player, playerObject)) + return 0; + + NetworkId killerId; + if (killer != 0) + killerId = JavaLibrary::getNetworkId(killer); + + // make a corpse object for the player + ServerObject *cell = 0; + CellProperty * const cellProperty = playerObject->getParentCell(); + if (cellProperty && cellProperty != CellProperty::getWorldCellProperty()) + cell = safe_cast(&cellProperty->getOwner()); + + Transform tr; + tr.setPosition_p(playerObject->getPosition_p()); + ServerObject * corpse = ServerWorld::createNewObject(corpseTemplateName, tr, cell, true); + if (corpse == NULL) + return 0; + + if (playerObject->makeDead(killerId, corpse->getNetworkId())) + { + if (!cell) + corpse->addToWorld(); + LocalRefPtr corpseId = JavaLibrary::getObjId(*corpse); + return corpseId->getReturnValue(); + } + else + { + corpse->permanentlyDestroy(DeleteReasons::SetupFailed); + return 0; + } +} // JavaLibrary::killPlayer + +//---------------------------------------------------------------------- + +/** + * Resurrects a creature and returns true if it is resurrected or not already dead + * + * @param env Java environment + * @param self class calling this function + * @param target creature we want to know about + * + * @return JNI_TRUE if the creature is incapaciated, JNI_FALSE if not or error + */ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::resurrect(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + if (creature->makeNotDead()) + return JNI_TRUE; + return JNI_FALSE; +} // JavaLibrary::resurrect + +//---------------------------------------------------------------------- + +/** +* Removes all the attribute and skill mod modifiers from a creature. +* Does NOT remove buffs, only the effects so be sure to manually remove +* any buffs for which you need the icons to go away. +* +* @param env Java environment +* @param self class calling this function +* @param target creature we want to remove all mods from +* +* @return JNI_TRUE if the creature is incapaciated, JNI_FALSE if not or error +*/ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::removeAllAttributeAndSkillmodMods(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + creature->removeAllAttributeAndSkillmodMods(); + return JNI_TRUE; +} // JavaLibrary::removeAllAttributeAndSkillmodMods + +//---------------------------------------------------------------------- + + +/** + * Sets the invulnerable flag on an object. + * + * @param env Java environment + * @param self class calling this function + * @param target object we want to set + * @param invulnerable the new invulnerable state of the object + * + * @return JNI_TRUE on success, JNI_FALSE on error + */ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::setInvulnerable(JNIEnv *env, jobject self, jlong target, jboolean invulnerable) +{ + UNREF(self); + + TangibleObject * object = NULL; + if (!JavaLibrary::getObject(target, object)) + return JNI_FALSE; + + object->setInvulnerable(invulnerable); + return JNI_TRUE; +} // JavaLibrary::setInvulnerable + +//---------------------------------------------------------------------- + +/** + * Returns the invulnerable flag of an object. + * + * @param env Java environment + * @param self class calling this function + * @param target object we want to get + * + * @return the invulnerable flag on success, JNI_FALSE on error + */ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::isInvulnerable(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + TangibleObject * object = NULL; + if (!JavaLibrary::getObject(target, object)) + return JNI_FALSE; + + return object->isInvulnerable(); +} // JavaLibrary::isInvulnerable + +//---------------------------------------------------------------------- + +/** + * Returns the complexity of an object. + * + * @param env Java environment + * @param self class calling this function + * @param target object we want to get + * + * @return the complexity, or -1 on error + */ +jfloat JNICALL ScriptMethodsObjectInfoNamespace::getComplexity(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + const ServerObject * object = NULL; + if (!JavaLibrary::getObject(target, object)) + return -1; + + return object->getComplexity(); +} // JavaLibrary::getComplexity + +//---------------------------------------------------------------------- + +/** + * Sets the complexity of an object. + * + * @param env Java environment + * @param self class calling this function + * @param target object we want to set + * @param complexity complexity of the object + * + * @return true on success, false on error + */ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::setComplexity(JNIEnv *env, jobject self, jlong target, jfloat complexity) +{ + UNREF(self); + + ServerObject * object = NULL; + if (!JavaLibrary::getObject(target, object)) + return JNI_FALSE; + + object->setComplexity(complexity); + return JNI_TRUE; +} + +//---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsObjectInfoNamespace::getGameObjectType(JNIEnv *env, jobject self, jlong obj) +{ + UNREF (self); + + ServerObject * object = NULL; + if (!JavaLibrary::getObject(obj, object)) + return JNI_FALSE; + + return object->getGameObjectType (); +} + +//---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsObjectInfoNamespace::getGameObjectTypeFromTemplate(JNIEnv *env, jobject self, jstring templateName) +{ + std::string templateString; + if (!JavaLibrary::convert(JavaStringParam(templateName), templateString)) + return 0; + + return getGameObjectTypeFromTemplateCrc(env, self, Crc::calculate(templateString.c_str())); +} + +//---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsObjectInfoNamespace::getGameObjectTypeFromTemplateCrc(JNIEnv *env, jobject self, jint templateCrc) +{ + const ObjectTemplate * objectTemplate = ObjectTemplateList::fetch(templateCrc); + if (objectTemplate == NULL) + return 0; + + const std::string & sharedTemplateName = safe_cast(objectTemplate)->getSharedTemplate(); + const ObjectTemplate * sharedTemplate = ObjectTemplateList::fetch(sharedTemplateName); + objectTemplate->releaseReference(); + if (sharedTemplate == NULL) + return 0; + + jint got = safe_cast(sharedTemplate)->getGameObjectType(); + sharedTemplate->releaseReference(); + return got; +} + +//---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsObjectInfoNamespace::getGameObjectTypeName(JNIEnv *env, jobject self, jint type) +{ + UNREF (self); + + return JavaString(GameObjectTypes::getCanonicalName (type)).getReturnValue(); +} + +//---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsObjectInfoNamespace::getGameObjectTypeFromName(JNIEnv *, jobject , jstring typeName) +{ + std::string typeNameString; + if (!JavaLibrary::convert(JavaStringParam(typeName), typeNameString)) + return 0; + return GameObjectTypes::getGameObjectType(typeNameString); +} + +//---------------------------------------------------------------------- + +/** + * Returns if an object is an object being controlled by a god-mode client. + * + * @param env Java environment + * @param self class calling this function + * @param target the object to test + * + * @return true if the object is god-mode controlled, false if not + */ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::isGod(JNIEnv *env, jobject self, jlong target) +{ + UNREF (self); + + const ServerObject * object = NULL; + if (!JavaLibrary::getObject(target, object)) + return JNI_FALSE; + + if (object->getClient() == NULL) + return JNI_FALSE; + + return object->getClient()->isGod(); +} // JavaLibrary::isGod + +//---------------------------------------------------------------------- + +/** + * Returns the god-level of a player. + * + * @param env Java environment + * @param self class calling this function + * @param target the object to test + * + * @return the god level + */ +jint JNICALL ScriptMethodsObjectInfoNamespace::getGodLevel(JNIEnv *env, jobject self, jlong target) +{ + UNREF (self); + + const ServerObject * object = NULL; + if (!JavaLibrary::getObject(target, object)) + return 0; + + if (object->getClient() == NULL) + return 0; + + if (object->getClient()->isGod()) + return object->getClient()->getGodLevel(); + return 0; +} // JavaLibrary::getGodLevel + +//---------------------------------------------------------------------- + +/** + * Returns an object's counter. + * + * @param env Java environment + * @param self class calling this function + * @param target the object + * + * @return the counter value + */ +jint JNICALL ScriptMethodsObjectInfoNamespace::getCount(JNIEnv *env, jobject self, jlong target) +{ + // both Tangible and Intangible have counters, so we have to test for both + // cases + + const TangibleObject * tangibleObject = NULL; + if (JavaLibrary::getObject(target, tangibleObject)) + { + return tangibleObject->getCount(); + } + + const IntangibleObject * intangibleObject = NULL; + if (JavaLibrary::getObject(target, intangibleObject)) + { + return intangibleObject->getCount(); + } + + return 0; +} // JavaLibrary::getCount + +//---------------------------------------------------------------------- + +/** + * Sets an object's counter. + * + * @param env Java environment + * @param self class calling this function + * @param target the object + * @param value the counter value + * + * @return true if the counter was set, false if there was an error + */ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::setCount(JNIEnv *env, jobject self, jlong target, jint value) +{ + // both Tangible and Intangible have counters, so we have to test for both + // cases + + TangibleObject * tangibleObject = NULL; + if (JavaLibrary::getObject(target, tangibleObject)) + { + tangibleObject->setCount(value); + return JNI_TRUE; + } + + IntangibleObject * intangibleObject = NULL; + if (JavaLibrary::getObject(target, intangibleObject)) + { + intangibleObject->setCount(value); + return JNI_TRUE; + } + + return JNI_FALSE; +} // JavaLibrary::setCount + +//---------------------------------------------------------------------- + +/** + * Increments (or decrements, if passed a negative value) an object's counter. + * + * @param env Java environment + * @param self class calling this function + * @param target the object + * @param delta number to add to the current count + * + * @return true on success, false if there was an error + */ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::incrementCount(JNIEnv *env, jobject self, jlong target, jint delta) +{ + // both Tangible and Intangible have counters, so we have to test for both + // cases + + TangibleObject * tangibleObject = NULL; + if (JavaLibrary::getObject(target, tangibleObject)) + { + tangibleObject->incrementCount(delta); + return JNI_TRUE; + } + + IntangibleObject * intangibleObject = NULL; + if (JavaLibrary::getObject(target, intangibleObject)) + { + intangibleObject->incrementCount(delta); + return JNI_TRUE; + } + + return JNI_FALSE; +} // JavaLibrary::incrementCount + +//---------------------------------------------------------------------- + +/** + * Returns an object's condition flags. + * + * @param env Java environment + * @param self class calling this function + * @param target the object + * + * @return the object's condition flags + */ +jint JNICALL ScriptMethodsObjectInfoNamespace::getCondition(JNIEnv *env, jobject self, jlong target) +{ + const TangibleObject * object = NULL; + if (!JavaLibrary::getObject(target, object)) + return 0; + + return object->getCondition(); +} // JavaLibrary::getCondition + +//---------------------------------------------------------------------- + +/** + * Tests if an object has a condition flag set. + * + * @param env Java environment + * @param self class calling this function + * @param target the object + * @param condition the condition flag to test + * + * @return true if the condition flag is set, false if not + */ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::hasCondition(JNIEnv *env, jobject self, jlong target, jint condition) +{ + const TangibleObject * object = NULL; + if (!JavaLibrary::getObject(target, object)) + return JNI_FALSE; + + return object->hasCondition(condition); +} // JavaLibrary::hasCondition + +//---------------------------------------------------------------------- + +/** + * Sets a condition flag on an object. + * + * @param env Java environment + * @param self class calling this function + * @param target the object + * @param condition the condition flag + * + * @return true on success, false if there was an error + */ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::setCondition(JNIEnv *env, jobject self, jlong target, jint condition) +{ + TangibleObject * object = NULL; + if (!JavaLibrary::getObject(target, object)) + return JNI_FALSE; + + object->setCondition(condition); + return JNI_TRUE; +} // JavaLibrary::setCondition + +//---------------------------------------------------------------------- + +/** + * Clears a condition flag on an object. + * + * @param env Java environment + * @param self class calling this function + * @param target the object + * @param condition the condition flag + * + * @return true on success, false if there was an error + */ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::clearCondition(JNIEnv *env, jobject self, jlong target, jint condition) +{ + TangibleObject * object = NULL; + if (!JavaLibrary::getObject(target, object)) + return JNI_FALSE; + + object->clearCondition(condition); + return JNI_TRUE; +} // JavaLibrary::clearCondition + +//---------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsObjectInfoNamespace::getGroupObject(JNIEnv *env, jobject self, jlong obj) +{ + UNREF(self); + + CreatureObject *creature = 0; + if (!JavaLibrary::getObject(obj, creature)) + return 0; + + GroupObject *group = creature->getGroup(); + NetworkId networkId = group ? group->getNetworkId() : NetworkId::cms_invalid; + return networkId.getValue(); +} + +//---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsObjectInfoNamespace::getGroupName(JNIEnv *env, jobject self, jlong obj) +{ + UNREF(self); + + GroupObject *group = 0; + if (!JavaLibrary::getObject(obj, group)) + return 0; + + return JavaString(group->getGroupName().c_str()).getReturnValue(); +} + +//---------------------------------------------------------------------- + +jlongArray JNICALL ScriptMethodsObjectInfoNamespace::getGroupMemberIds(JNIEnv *env, jobject self, jlong obj) +{ + UNREF(self); + + GroupObject *group = 0; + if (!JavaLibrary::getObject(obj, group)) + return 0; + + GroupObject::GroupMemberVector const &members = group->getGroupMembers(); + LocalLongArrayRefPtr items = createNewLongArray(members.size()); + if (items == LocalLongArrayRef::cms_nullPtr) + return 0; + + int index = 0; + jlong jlongTmp; + for (GroupObject::GroupMemberVector::const_iterator i = members.begin(); i != members.end(); ++i) + { + jlongTmp = ((*i).first).getValue(); + setLongArrayRegion(*items, index, 1, &jlongTmp); + ++index; + } + + return items->getReturnValue(); +} + +//---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsObjectInfoNamespace::getGroupMemberNames(JNIEnv *env, jobject self, jlong obj) +{ + UNREF(self); + + GroupObject *group = 0; + if (!JavaLibrary::getObject(obj, group)) + return 0; + + GroupObject::GroupMemberVector const &members = group->getGroupMembers(); + // create the string array to return + LocalObjectArrayRefPtr strings = createNewObjectArray(members.size(), JavaLibrary::getClsString()); + if (strings == LocalObjectArrayRef::cms_nullPtr) + return 0; + + int index = 0; + for (GroupObject::GroupMemberVector::const_iterator i = members.begin(); i != members.end(); ++i) + { + JavaString jval((*i).second.c_str()); + setObjectArrayElement(*strings, index, jval); + ++index; + } + + return strings->getReturnValue(); +} + +//---------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsObjectInfoNamespace::getGroupLeaderId(JNIEnv *env, jobject self, jlong group) +{ + UNREF(self); + + GroupObject *groupObj = 0; + if (!JavaLibrary::getObject(group, groupObj)) + return 0; + + return (groupObj->getGroupLeaderId()).getValue(); +} + +//---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsObjectInfoNamespace::getGroupSize(JNIEnv *env, jobject self, jlong group) +{ + UNREF(self); + + GroupObject *groupObj = 0; + if (!JavaLibrary::getObject(group, groupObj)) + return 0; + + return static_cast(groupObj->getGroupMembers().size()); +} + +//---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsObjectInfoNamespace::getPCGroupSize(JNIEnv *env, jobject self, jlong group) +{ + UNREF(self); + + GroupObject *groupObj = 0; + if (!JavaLibrary::getObject(group, groupObj)) + return 0; + + return static_cast(groupObj->getPCMemberCount()); +} + +//---------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsObjectInfoNamespace::getGroupMasterLooterId(JNIEnv *env, jobject /*self*/, jlong group) +{ + GroupObject * groupObject = 0; + if (!JavaLibrary::getObject(group, groupObject)) + { + return 0; + } + + return (groupObject->getLootMasterId()).getValue(); +} + +//---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsObjectInfoNamespace::getGroupLootRule(JNIEnv *env, jobject /*self*/, jlong group) +{ + GroupObject * groupObject = 0; + if (!JavaLibrary::getObject(group, groupObject)) + { + return 0; + } + + return static_cast(groupObject->getLootRule()); +} + +//---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsObjectInfoNamespace::setGroupLootRule(JNIEnv *env, jobject /*self*/, jlong group, jint value) +{ + GroupObject * groupObject = 0; + if (!JavaLibrary::getObject(group, groupObject)) + { + return JNI_FALSE; + } + + groupObject->setLootRule(value); + return JNI_TRUE; +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectInfoNamespace::openLotteryWindow(JNIEnv *env, jobject /*self*/, jlong playerToSendTo, jlong containerToObserve) +{ + ServerObject * container = 0; + if (!JavaLibrary::getObject(containerToObserve, container)) + { + DEBUG_REPORT_LOG(true, ("openLotteryWindow: container == 0.\n")); + return; + } + + CreatureObject * player = 0; + if (!JavaLibrary::getObject(playerToSendTo, player)) + { + DEBUG_REPORT_LOG(true, ("openLotteryWindow: player == 0.\n")); + return; + } + + if (ContainerInterface::getContainer(*container) == 0) + { + DEBUG_REPORT_LOG(true, ("commandFuncOpenLotteryContainer: ContainerInterface::getContainer == 0.\n")); + return; + } + + Client *client = player->getClient(); + if (client != 0) + { + int const sequence = -1; + std::string const slotName; + client->observeContainer(*container, sequence, slotName); + } + else + { + DEBUG_REPORT_LOG(true, ("commandFuncOpenLotteryContainer: unable to get client\n")); + } + + Controller * const controller = player->getController(); + + if (controller != 0) + { + typedef MessageQueueGenericValueType Message; + Message * const message = new Message(container->getNetworkId()); + + controller->appendMessage( + CM_groupOpenLotteryWindowOnClient, + 0.0f, + message, + GameControllerMessageFlags::SEND | + GameControllerMessageFlags::RELIABLE | + GameControllerMessageFlags::DEST_AUTH_CLIENT); + } +} + +//---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsObjectInfoNamespace::getPerformanceType(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + CreatureObject *creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return 0; + return creature->getPerformanceType(); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectInfoNamespace::setPerformanceType(JNIEnv *env, jobject self, jlong target, jint performanceType) +{ + UNREF(self); + + CreatureObject *creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return; + creature->setPerformanceType(performanceType); +} + +//---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsObjectInfoNamespace::getPerformanceStartTime(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + CreatureObject *creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return 0; + return creature->getPerformanceStartTime(); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectInfoNamespace::setPerformanceStartTime(JNIEnv *env, jobject self, jlong target, jint performanceStartTime) +{ + UNREF(self); + + CreatureObject *creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return; + creature->setPerformanceStartTime(performanceStartTime); +} + +//---------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsObjectInfoNamespace::getPerformanceListenTarget(JNIEnv *env, jobject self, jlong actor) +{ + UNREF(self); + + CreatureObject *actorCreature = 0; + if (!JavaLibrary::getObject(actor, actorCreature)) + return 0; + return (actorCreature->getPerformanceListenTarget()).getValue(); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectInfoNamespace::setPerformanceListenTarget(JNIEnv *env, jobject self, jlong actor, jlong target) +{ + UNREF(self); + + CreatureObject *actorCreature = 0; + if (!JavaLibrary::getObject(actor, actorCreature)) + return; + CreatureObject *targetCreature = 0; + JavaLibrary::getObject(target, targetCreature); + actorCreature->setPerformanceListenTarget(targetCreature ? targetCreature->getNetworkId() : NetworkId::cms_invalid); +} + +//---------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsObjectInfoNamespace::getPerformanceWatchTarget(JNIEnv *env, jobject self, jlong actor) +{ + UNREF(self); + + CreatureObject *actorCreature = 0; + if (!JavaLibrary::getObject(actor, actorCreature)) + return 0; + return (actorCreature->getPerformanceWatchTarget()).getValue(); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectInfoNamespace::setPerformanceWatchTarget(JNIEnv *env, jobject self, jlong actor, jlong target) +{ + UNREF(self); + + CreatureObject *actorCreature = 0; + if (!JavaLibrary::getObject(actor, actorCreature)) + return; + CreatureObject *targetCreature = 0; + JavaLibrary::getObject(target, targetCreature); + actorCreature->setPerformanceWatchTarget(targetCreature ? targetCreature->getNetworkId() : NetworkId::cms_invalid); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsObjectInfoNamespace::getInstrumentVisualId(JNIEnv *env, jobject self, jlong who) +{ + UNREF(self); + + CreatureObject *creature = 0; + if (!JavaLibrary::getObject(who, creature)) + return 0; + return creature->getInstrumentVisualId(); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsObjectInfoNamespace::getInstrumentAudioId(JNIEnv *env, jobject self, jlong who) +{ + UNREF(self); + + CreatureObject *creature = 0; + if (!JavaLibrary::getObject(who, creature)) + return 0; + return creature->getInstrumentAudioId(); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectInfoNamespace::sendMusicFlourish(JNIEnv *env, jobject self, jlong performer, jint flourishIndex) +{ + CreatureObject *creature = 0; + if (JavaLibrary::getObject(performer, creature)) + creature->sendMusicFlourish(flourishIndex); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectInfoNamespace::showFlyText(JNIEnv *env, jobject self, jlong emitterId, jobject outputTextId, jfloat scale, jint r, jint g, jint b) +{ + //-- Get the TangibleObject for the emitter. + TangibleObject *emitterObject = 0; + if (!JavaLibrary::getObject(emitterId, emitterObject) || !emitterObject) + { + DEBUG_WARNING(true, ("showFlyText: emitterId parameter is not a TangibleObject, cannot show fly text.")); + return; + } + + //-- Get the StringId from Java. + StringId gameOutputTextId; + if (!ScriptConversion::convert(outputTextId, gameOutputTextId)) + { + DEBUG_WARNING(true, ("showFlyText: failed to retrieve string_id outputTextId from Java.")); + return; + } + + //-- Request the object to render the text. + emitterObject->showFlyText(gameOutputTextId, scale, r, g, b); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectInfoNamespace::showFlyTextPrivate(JNIEnv *env, jobject self, jlong emitterId, jlong recipientId, jobject outputTextId, jfloat scale, jint r, jint g, jint b, jboolean showInChatBox) +{ + //-- Get the Object for the recipient. + ServerObject *recipientObject = 0; + if (!JavaLibrary::getObject(recipientId, recipientObject) || !recipientObject) + { + DEBUG_WARNING(true, ("showFlyTextPrivate: recipientObject parameter is not a ServerObject, cannot show fly text.")); + return; + } + + //-- Ensure recipient is player-controlled. + if (!recipientObject->isPlayerControlled()) + return; + + //-- Get the TangibleObject for the emitter. + TangibleObject *emitterObject = 0; + if (!JavaLibrary::getObject(emitterId, emitterObject) || !emitterObject) + { + DEBUG_WARNING(true, ("showFlyTextPrivate: emitterId parameter is not a TangibleObject, cannot show fly text.")); + return; + } + + //-- Get the StringId from Java. + StringId gameOutputTextId; + if (!ScriptConversion::convert(outputTextId, gameOutputTextId)) + { + DEBUG_WARNING(true, ("showFlyTextPrivate: failed to retrieve string_id outputTextId from Java.")); + return; + } + + //-- Request the recipient's client to have the emitter object render the text. + Controller *const controller = recipientObject->getController(); + if (!controller) + { + DEBUG_WARNING(true, ("showFlyTextPrivate: object [%s] has no controller.", recipientObject->getNetworkId().getValueString().c_str())); + return; + } + + int textFlags = MessageQueueShowFlyText::F_private; + + if (showInChatBox) + textFlags |= MessageQueueShowFlyText::F_showInChatBox; + + MessageQueueShowFlyText * const msg = new MessageQueueShowFlyText (emitterObject->getNetworkId(), gameOutputTextId, scale, r, g, b, textFlags); + + //-- Send the showFlyText message only to the authoratative recipient client. + controller->appendMessage(static_cast(CM_showFlyText), 0.0f, msg, GameControllerMessageFlags::SEND | GameControllerMessageFlags::RELIABLE | GameControllerMessageFlags::DEST_AUTH_CLIENT); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectInfoNamespace::showCombatText(JNIEnv *env, jobject self, jlong defenderId, jlong attackerId, jobject outputTextId, jfloat scale, jint r, jint g, jint b) +{ + //-- Get the TangibleObject for the emitter. + TangibleObject *defenderObject = 0; + if (!JavaLibrary::getObject(defenderId, defenderObject) || !defenderObject) + { + DEBUG_WARNING(true, ("showCombatText: defenderId parameter is not a TangibleObject, cannot show combat text.")); + return; + } + + TangibleObject *attackerObject = 0; + if (!JavaLibrary::getObject(attackerId, attackerObject) || !attackerObject) + { + DEBUG_WARNING(true, ("showCombatText: attackerId parameter is not a TangibleObject, cannot show combat text.")); + return; + } + + //-- Get the StringId from Java. + StringId gameOutputTextId; + if (!ScriptConversion::convert(outputTextId, gameOutputTextId)) + { + DEBUG_WARNING(true, ("showCombatText: failed to retrieve string_id outputTextId from Java.")); + return; + } + + //-- Request the object to render the text. + defenderObject->showCombatText(*attackerObject, gameOutputTextId, scale, r, g, b); +} + +void JNICALL ScriptMethodsObjectInfoNamespace::showCombatTextPrivate(JNIEnv *env, jobject self, jlong defenderId, jlong attackerId, jlong clientObjectId, jobject outputTextId, jfloat scale, jint r, jint g, jint b) +{ + //-- Get the Object for the recipient. + ServerObject *clientObject = 0; + if (!JavaLibrary::getObject(clientObjectId, clientObject) || !clientObject) + { + DEBUG_WARNING(true, ("showCombatTextPrivate: clientObject parameter is not a ServerObject, cannot show fly text.")); + return; + } + + //-- Ensure recipient is player-controlled. + if (!clientObject->isPlayerControlled()) + return; + + //-- Get the TangibleObject for the emitter. + TangibleObject *defenderObject = 0; + if (!JavaLibrary::getObject(defenderId, defenderObject) || !defenderObject) + { + DEBUG_WARNING(true, ("showCombatTextPrivate: defenderId parameter is not a TangibleObject, cannot show combat text.")); + return; + } + + TangibleObject *attackerObject = 0; + if (!JavaLibrary::getObject(attackerId, attackerObject) || !attackerObject) + { + DEBUG_WARNING(true, ("showCombatText: attackerId parameter is not a TangibleObject, cannot show combat text.")); + return; + } + + + //-- Get the StringId from Java. + StringId gameOutputTextId; + if (!ScriptConversion::convert(outputTextId, gameOutputTextId)) + { + DEBUG_WARNING(true, ("showCombatTextPrivate: failed to retrieve string_id outputTextId from Java.")); + return; + } + + //-- Request the recipient's client to have the emitter object render the text. + Controller *const controller = clientObject->getController(); + if (!controller) + { + DEBUG_WARNING(true, ("showCombatTextPrivate: object [%s] has no controller.", clientObject->getNetworkId().getValueString().c_str())); + return; + } + + int textFlags = MessageQueueShowFlyText::F_private; + + MessageQueueShowCombatText * const msg = new MessageQueueShowCombatText (defenderObject->getNetworkId(), attackerObject->getNetworkId(), gameOutputTextId, scale, r, g, b, textFlags); + + //-- Send the showCombatText message only to the authoratative recipient client. + controller->appendMessage(static_cast(CM_showCombatText), 0.0f, msg, GameControllerMessageFlags::SEND | GameControllerMessageFlags::RELIABLE | GameControllerMessageFlags::DEST_AUTH_CLIENT); +} + +// ---------------------------------------------------------------------- +// ---------------------------------------------------------------------- +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectInfoNamespace::showFlyTextProse (JNIEnv *env, jobject self, jlong emitterId, jstring jStringOutputTextOOB, jfloat scale, jint r, jint g, jint b) +{ + //-- Get the TangibleObject for the emitter. + TangibleObject *emitterObject = 0; + if (!JavaLibrary::getObject(emitterId, emitterObject) || !emitterObject) + { + DEBUG_WARNING(true, ("showFlyTextProse: emitterId parameter is not a TangibleObject, cannot show fly text.")); + return; + } + + JavaStringParam joutputTextOOB(jStringOutputTextOOB); + Unicode::String outputTextOOB; + if (!JavaLibrary::convert(joutputTextOOB, outputTextOOB)) + { + DEBUG_WARNING(true, ("showFlyTextProse: could not convert outputTextProse to a string.")); + return; + } + + //-- Request the object to render the text. + emitterObject->showFlyText(outputTextOOB, scale, r, g, b); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectInfoNamespace::showFlyTextPrivateProse (JNIEnv *env, jobject self, jlong emitterId, jlong recipientId, jstring jStringOutputTextOOB, jfloat scale, jint r, jint g, jint b, jboolean showInChatBox) +{ + //-- Get the Object for the recipient. + ServerObject *recipientObject = 0; + if (!JavaLibrary::getObject(recipientId, recipientObject) || !recipientObject) + { + DEBUG_WARNING(true, ("showFlyTextPrivateProse: recipientObject parameter is not a ServerObject, cannot show fly text.")); + return; + } + + //-- Ensure recipient is player-controlled. + if (!recipientObject->isPlayerControlled()) + return; + + //-- Get the TangibleObject for the emitter. + TangibleObject *emitterObject = 0; + if (!JavaLibrary::getObject(emitterId, emitterObject) || !emitterObject) + { + DEBUG_WARNING(true, ("showFlyTextPrivateProse: emitterId parameter is not a TangibleObject, cannot show fly text.")); + return; + } + + JavaStringParam joutputTextOOB(jStringOutputTextOOB); + Unicode::String outputTextOOB; + if (!JavaLibrary::convert(joutputTextOOB, outputTextOOB)) + { + DEBUG_WARNING(true, ("showFlyTextPrivateProse: could not convert outputTextProse to a string.")); + return; + } + + //-- Request the recipient's client to have the emitter object render the text. + Controller *const controller = recipientObject->getController(); + if (!controller) + { + DEBUG_WARNING(true, ("showFlyTextPrivateProse: object [%s] has no controller.", recipientObject->getNetworkId().getValueString().c_str())); + return; + } + + int textFlags = MessageQueueShowFlyText::F_private; + + if (showInChatBox) + textFlags |= MessageQueueShowFlyText::F_showInChatBox; + + MessageQueueShowFlyText * const msg = new MessageQueueShowFlyText (emitterObject->getNetworkId(), outputTextOOB, scale, r, g, b, textFlags); + + //-- Send the showFlyText message only to the authoratative recipient client. + controller->appendMessage(static_cast(CM_showFlyText), 0.0f, msg, GameControllerMessageFlags::SEND | GameControllerMessageFlags::RELIABLE | GameControllerMessageFlags::DEST_AUTH_CLIENT); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectInfoNamespace::showFlyTextPrivateProseWithFlags (JNIEnv *env, jobject self, jlong emitterId, jlong recipientId, jstring jStringOutputTextOOB, jfloat scale, jint r, jint g, jint b, jint flags) +{ + //-- Get the Object for the recipient. + ServerObject *recipientObject = 0; + if (!JavaLibrary::getObject(recipientId, recipientObject) || !recipientObject) + { + DEBUG_WARNING(true, ("showFlyTextPrivateProse: recipientObject parameter is not a ServerObject, cannot show fly text.")); + return; + } + + //-- Ensure recipient is player-controlled. + if (!recipientObject->isPlayerControlled()) + return; + + //-- Get the TangibleObject for the emitter. + TangibleObject *emitterObject = 0; + if (!JavaLibrary::getObject(emitterId, emitterObject) || !emitterObject) + { + DEBUG_WARNING(true, ("showFlyTextPrivateProse: emitterId parameter is not a TangibleObject, cannot show fly text.")); + return; + } + + JavaStringParam joutputTextOOB(jStringOutputTextOOB); + Unicode::String outputTextOOB; + if (!JavaLibrary::convert(joutputTextOOB, outputTextOOB)) + { + DEBUG_WARNING(true, ("showFlyTextPrivateProse: could not convert outputTextProse to a string.")); + return; + } + + //-- Request the recipient's client to have the emitter object render the text. + Controller *const controller = recipientObject->getController(); + if (!controller) + { + DEBUG_WARNING(true, ("showFlyTextPrivateProse: object [%s] has no controller.", recipientObject->getNetworkId().getValueString().c_str())); + return; + } + + int textFlags = MessageQueueShowFlyText::F_private | flags; + + MessageQueueShowFlyText * const msg = new MessageQueueShowFlyText (emitterObject->getNetworkId(), outputTextOOB, scale, r, g, b, textFlags); + + //-- Send the showFlyText message only to the authoratative recipient client. + controller->appendMessage(static_cast(CM_showFlyText), 0.0f, msg, GameControllerMessageFlags::SEND | GameControllerMessageFlags::RELIABLE | GameControllerMessageFlags::DEST_AUTH_CLIENT); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectInfoNamespace::showCombatTextProse (JNIEnv *env, jobject self, jlong defenderId, jlong attackerId, jstring jStringOutputTextOOB, jfloat scale, jint r, jint g, jint b) +{ + //-- Get the TangibleObject for the emitter. + TangibleObject *defenderObject = 0; + if (!JavaLibrary::getObject(defenderId, defenderObject) || !defenderObject) + { + DEBUG_WARNING(true, ("showCombatTextProse: defenderId parameter is not a TangibleObject, cannot show combat text.")); + return; + } + + TangibleObject *attackerObject = 0; + if (!JavaLibrary::getObject(attackerId, attackerObject) || !attackerObject) + { + DEBUG_WARNING(true, ("showCombatTextProse: attackerId parameter is not a TangibleObject, cannot show combat text.")); + return; + } + + JavaStringParam joutputTextOOB(jStringOutputTextOOB); + Unicode::String outputTextOOB; + if (!JavaLibrary::convert(joutputTextOOB, outputTextOOB)) + { + DEBUG_WARNING(true, ("showCombatTextProse: could not convert outputTextProse to a string.")); + return; + } + + //-- Request the object to render the text. + defenderObject->showCombatText(*attackerObject, outputTextOOB, scale, r, g, b); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectInfoNamespace::showCombatTextPrivateProse (JNIEnv *env, jobject self, jlong defenderId, jlong attackerId, jlong clientObjectId, jstring jStringOutputTextOOB, jfloat scale, jint r, jint g, jint b) +{ + //-- Get the Object for the recipient. + ServerObject *clientObject = 0; + if (!JavaLibrary::getObject(clientObjectId, clientObject) || !clientObject) + { + DEBUG_WARNING(true, ("showCombatTextPrivateProse: clientObject parameter is not a ServerObject, cannot show fly text.")); + return; + } + + //-- Ensure recipient is player-controlled. + if (!clientObject->isPlayerControlled()) + return; + + //-- Get the TangibleObject for the emitter. + TangibleObject *defenderObject = 0; + if (!JavaLibrary::getObject(defenderId, defenderObject) || !defenderObject) + { + DEBUG_WARNING(true, ("showCombatTextPrivateProse: defenderId parameter is not a TangibleObject, cannot show combat text.")); + return; + } + + TangibleObject *attackerObject = 0; + if (!JavaLibrary::getObject(attackerId, attackerObject) || !attackerObject) + { + DEBUG_WARNING(true, ("showCombatTextPrivateProse: attackerId parameter is not a TangibleObject, cannot show combat text.")); + return; + } + + JavaStringParam joutputTextOOB(jStringOutputTextOOB); + Unicode::String outputTextOOB; + if (!JavaLibrary::convert(joutputTextOOB, outputTextOOB)) + { + DEBUG_WARNING(true, ("showCombatTextPrivateProse: could not convert outputTextProse to a string.")); + return; + } + + //-- Request the recipient's client to have the emitter object render the text. + Controller *const controller = clientObject->getController(); + if (!controller) + { + DEBUG_WARNING(true, ("showCombatTextPrivateProse: object [%s] has no controller.", clientObject->getNetworkId().getValueString().c_str())); + return; + } + + int textFlags = MessageQueueShowFlyText::F_private; + + MessageQueueShowCombatText * const msg = new MessageQueueShowCombatText (defenderObject->getNetworkId(), attackerObject->getNetworkId(), outputTextOOB, scale, r, g, b, textFlags); + + //-- Send the showCombatText message only to the authoratative recipient client. + controller->appendMessage(static_cast(CM_showCombatText), 0.0f, msg, GameControllerMessageFlags::SEND | GameControllerMessageFlags::RELIABLE | GameControllerMessageFlags::DEST_AUTH_CLIENT); +} + +// ---------------------------------------------------------------------- +// ---------------------------------------------------------------------- +// ---------------------------------------------------------------------- +// ---------------------------------------------------------------------- + + +jlong JNICALL ScriptMethodsObjectInfoNamespace::getMaster(JNIEnv *env, jobject self, jlong target) +{ + CreatureObject const *creature = 0; + if (!JavaLibrary::getObject(target, creature)) + { + ServerObject const *obj = 0; + if (JavaLibrary::getObject(target, obj)) + { + char errbuf[1024]; + snprintf(errbuf, sizeof(errbuf), "JavaLibrary::getMasterId called with non-creature target %s (%s)", obj->getNetworkId().getValueString().c_str(), obj->getObjectTemplateName()); + errbuf[sizeof(errbuf)-1] = '\0'; + JavaLibrary::throwInternalScriptError(errbuf); + } + else + JavaLibrary::throwInternalScriptError("JavaLibrary::getMasterId called with target which could not be resolved"); + return 0; + } + return (creature->getMasterId()).getValue(); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectInfoNamespace::setMaster(JNIEnv *env, jobject self, jlong target, jlong master) +{ + CreatureObject *creature = 0; + if (!JavaLibrary::getObject(target, creature)) + JavaLibrary::throwInternalScriptError("JavaLibrary::setMasterId called with bad target"); + else + creature->setMasterId(NetworkId(master)); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsObjectInfoNamespace::getNumAI(JNIEnv *env, jobject self) +{ + return ObjectTracker::getNumAI(); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsObjectInfoNamespace::getNumCreatures(JNIEnv *env, jobject self) +{ + return ObjectTracker::getNumCreatures(); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsObjectInfoNamespace::getNumPlayers(JNIEnv *env, jobject self) +{ + return ObjectTracker::getNumPlayers(); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsObjectInfoNamespace::getNumRunTimeRules(JNIEnv *env, jobject self) +{ + return ObjectTracker::getNumRunTimeRules(); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsObjectInfoNamespace::getNumDynamicAI(JNIEnv *env, jobject self) +{ + return ObjectTracker::getNumDynamicAI(); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsObjectInfoNamespace::getNumStaticAI(JNIEnv *env, jobject self) +{ + return ObjectTracker::getNumStaticAI(); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsObjectInfoNamespace::getNumCombatAI(JNIEnv *env, jobject self) +{ + return ObjectTracker::getNumCombatAI(); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsObjectInfoNamespace::getNumHibernatingAI(JNIEnv *env, jobject self) +{ + return ObjectTracker::getNumHibernatingAI(); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsObjectInfoNamespace::getGroupLevel(JNIEnv *, jobject, jlong target) +{ + if (!target) + { + DEBUG_WARNING (true, ("JavaLibrary::getGroupLevel null target ")); + return 0; + } + + NetworkId targetId(target); + if (targetId == NetworkId::cms_invalid) + { + DEBUG_WARNING (true, ("JavaLibrary::getGroupLevel invalid target ")); + return 0; + } + + const GroupObject * const group = dynamic_cast(ServerWorld::findObjectByNetworkId (targetId)); + if (!group) + { + DEBUG_WARNING (true, ("JavaLibrary::getGroupLevel target is not a group")); + return 0; + } + + return group->getGroupLevel (); +} + +//----------------------------------------------------------------------- + +jint JNICALL ScriptMethodsObjectInfoNamespace::getLevel(JNIEnv *env, jobject self, jlong target) +{ + jint result = 0; + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return result; + + result = creature->getLevel(); + return result; + } + +jboolean JNICALL ScriptMethodsObjectInfoNamespace::setLevel(JNIEnv *env, jobject self, jlong target, jint forcedLevel) +{ + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return false; + + creature->setLevel(forcedLevel); + return true; + } + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsObjectInfoNamespace::recalculateLevel(JNIEnv *env, jobject self, jlong target) + { + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return false; + + creature->recalculateLevel(); + return true; +} + + +//----------------------------------------------------------------------- + +jint JNICALL ScriptMethodsObjectInfoNamespace::getHologramType(JNIEnv *env, jobject self, jlong target) +{ + jint result = -1; + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return result; + + result = creature->getHologramType(); + return result; +} + +jboolean JNICALL ScriptMethodsObjectInfoNamespace::setHologramType(JNIEnv *env, jobject self, jlong target, jint type) +{ + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return false; + + creature->setHologramType(type); + return true; +} + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsObjectInfoNamespace::setVisibleOnMapAndRadar(JNIEnv *env, jobject self, jlong target, jboolean visible) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return false; + + creature->setVisibleOnMapAndRadar(visible); + return true; +} + +jboolean JNICALL ScriptMethodsObjectInfoNamespace::getVisibleOnMapAndRadar(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return true; // true is the default value - return true on failure case + + return creature->getVisibleOnMapAndRadar(); +} + +//---------------------------------------------------------------------- + +/** + * Returns the appearance file name of an object. + * + * @param env Java environment + * @param self class calling this function + * @param target the object + * + * @return the appearance name, or null on error + */ +jstring JNICALL ScriptMethodsObjectInfoNamespace::getAppearance(JNIEnv * env, jobject self, jlong target) +{ + UNREF(self); + + const ServerObject * object = NULL; + if (!JavaLibrary::getObject(target, object)) + return 0; + + const SharedObjectTemplate * sharedTemplate = object->getSharedTemplate(); + if (sharedTemplate == NULL) + return 0; + + JavaString appearance(sharedTemplate->getAppearanceFilename()); + return appearance.getReturnValue(); +} // JavaLibrary::getAppearance + +// ---------------------------------------------------------------------- + +/** + * Returns if an object is insured. + * + * @param env Java environment + * @param self class calling this function + * @param target the object + * + * @return true if the object is insured, false if not + */ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::isInsured(JNIEnv * env, jobject self, jlong target) +{ + UNREF(self); + + const TangibleObject * object = NULL; + if (!JavaLibrary::getObject(target, object)) + return JNI_FALSE; + + return object->isInsured(); +} // JavaLibrary::isInsured + +// ---------------------------------------------------------------------- + +/** + * Returns if an object is auto-insured. + * + * @param env Java environment + * @param self class calling this function + * @param target the object + * + * @return true if the object is auto-insured, false if not + */ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::isAutoInsured(JNIEnv * env, jobject self, jlong target) +{ + UNREF(self); + + const TangibleObject * object = NULL; + if (!JavaLibrary::getObject(target, object)) + return JNI_FALSE; + + return object->isInsured() && object->isUninsurable(); +} // JavaLibrary::isAutoInsured + +// ---------------------------------------------------------------------- + +/** + * Returns if an object is uninsurable. + * + * @param env Java environment + * @param self class calling this function + * @param target the object + * + * @return true if the object is uninsurable, false if not + */ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::isUninsurable(JNIEnv * env, jobject self, jlong target) +{ + UNREF(self); + + const TangibleObject * object = NULL; + if (!JavaLibrary::getObject(target, object)) + return JNI_FALSE; + + return object->isUninsurable(); +} // JavaLibrary::isUninsurable + +// ---------------------------------------------------------------------- + +/** + * Returns all the objects that are in a player's (or creature's) inventory and + * equipment. Special items, such as hair and Trandoshan feet, will not be + * returned. Items that are not visible to the player will also not be returned. + * + * @param env Java environment + * @param self class calling this function + * @param player the player to get objects from + * + * @return an array of objects, or null on error + */ +jlongArray JNICALL ScriptMethodsObjectInfoNamespace::getInventoryAndEquipment(JNIEnv * env, jobject self, jlong player) +{ + UNREF(self); + + const CreatureObject * playerCreature = NULL; + if (!JavaLibrary::getObject(player, playerCreature)) + return 0; + + std::vector objectIds; + + // go through the player's inventory + const ServerObject * inventoryObject = playerCreature->getInventory(); + if (inventoryObject != NULL) + { + const VolumeContainer * inventoryContainer = + ContainerInterface::getVolumeContainer(*inventoryObject); + if (inventoryContainer != NULL) + { + getGoodItemsFromContainer(*inventoryContainer, objectIds); + } + else + { + DEBUG_WARNING(true, ("JavaLibrary::getInventoryAndEquipment creature %s " + "inventory object %s has no volume container", + playerCreature->getNetworkId().getValueString().c_str(), + inventoryObject->getNetworkId().getValueString().c_str())); + } + } + else + { + DEBUG_WARNING(true, ("JavaLibrary::getInventoryAndEquipment creature %s has " + "no inventory object", + playerCreature->getNetworkId().getValueString().c_str())); + } + + // go through the player's equipment + SlottedContainer const * const equipmentContainer = ContainerInterface::getSlottedContainer(*playerCreature); + if (equipmentContainer != NULL) + getGoodItemsFromContainer(*equipmentContainer, objectIds); + else + { + DEBUG_WARNING(true, ("JavaLibrary::getInventoryAndEquipment creature %s has " + "no slotted container", + playerCreature->getNetworkId().getValueString().c_str())); + } + + if (!objectIds.empty()) + { + LocalLongArrayRefPtr returnedIds; + if (ScriptConversion::convert(objectIds, returnedIds)) + return returnedIds->getReturnValue(); + } + return 0; +} // JavaLibrary::getInventoryAndEquipment + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsObjectInfoNamespace::setCheaterLevel(JNIEnv * env, jobject self, jlong player, jint level) +{ + UNREF(self); + + CreatureObject * playerCreature = NULL; + if (!JavaLibrary::getObject(player, playerCreature)) + return JNI_FALSE; + + PlayerObject * const playerObj = PlayerCreatureController::getPlayerObject(playerCreature); + if (playerObj != NULL && playerObj->isAuthoritative()) + { + playerObj->setCheaterLevel(static_cast(level)); + return JNI_TRUE; + } + return JNI_FALSE; + +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsObjectInfoNamespace::getCheaterLevel(JNIEnv * env, jobject self, jlong player) +{ + UNREF(self); + + const CreatureObject * playerCreature = NULL; + if (!JavaLibrary::getObject(player, playerCreature)) + return 0; + + PlayerObject const * const playerObj = PlayerCreatureController::getPlayerObject(playerCreature); + if (playerObj != NULL) + { + return static_cast(playerObj->getCheaterLevel()); + } + + return 0; +} + +// ---------------------------------------------------------------------- + +/** + * Sets the house that a player owns. + * + * @param env Java environment + * @param self class calling this function + * @param player the player + * @param houseId the house + * + * @return true on success, false on error + */ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::setHouseId(JNIEnv * env, jobject self, jlong player, jlong houseId) +{ + UNREF(self); + + CreatureObject * playerCreature = NULL; + if (!JavaLibrary::getObject(player, playerCreature)) + return JNI_FALSE; + + CachedNetworkId house(houseId); + + playerCreature->setHouse(house); + return JNI_TRUE; +} // JavaLibrary::setHouseId + +// ---------------------------------------------------------------------- + +/** + * Sets the house that a player owns. + * + * @param env Java environment + * @param self class calling this function + * @param player the player + * + * @return the house id, or null on error + */ +jlong JNICALL ScriptMethodsObjectInfoNamespace::getHouseId(JNIEnv * env, jobject self, jlong player) +{ + UNREF(self); + + const CreatureObject * playerCreature = NULL; + if (!JavaLibrary::getObject(player, playerCreature)) + return 0; + + return (playerCreature->getHouse()).getValue(); +} // JavaLibrary::getHouseId + +// ---------------------------------------------------------------------- + +/** + * Returns the draft schematic template name used to create a manufacture + * schematic or factory crate. + * + * @param env Java environment + * @param self class calling this function + * @param object the manf schematic or factory id + * + * @return the draft schematic name, or null on error + */ +jstring JNICALL ScriptMethodsObjectInfoNamespace::getDraftSchematic(JNIEnv * env, jobject self, jlong object) +{ + UNREF(self); + + const ManufactureObjectInterface * craftable = NULL; + + const FactoryObject * factoryObject = NULL; + const ManufactureSchematicObject * manfSchematicObject = NULL; + if (JavaLibrary::getObject(object, manfSchematicObject)) + { + craftable = manfSchematicObject; + } + else if (JavaLibrary::getObject(object, factoryObject)) + { + craftable = factoryObject; + } + else + return 0; + + const ConstCharCrcString draftSchematic(ObjectTemplateList::lookUp( + craftable->getDraftSchematic())); + if (draftSchematic.getString() == NULL) + return 0; + + return JavaString(draftSchematic.getString()).getReturnValue(); +} // JavaLibrary::getDraftSchematic + +// ---------------------------------------------------------------------- + +/** + * Returns the draft schematic template name crc used to create a manufacture + * schematic or factory crate. + * + * @param env Java environment + * @param self class calling this function + * @param object the manf schematic or factory id + * + * @return the draft schematic name crc, or null on error + */ +jint JNICALL ScriptMethodsObjectInfoNamespace::getDraftSchematicCrc(JNIEnv * env, jobject self, jlong object) +{ + UNREF(self); + + const ManufactureObjectInterface * craftable = NULL; + + const FactoryObject * factoryObject = NULL; + const ManufactureSchematicObject * manfSchematicObject = NULL; + if (JavaLibrary::getObject(object, manfSchematicObject)) + { + craftable = manfSchematicObject; + } + else if (JavaLibrary::getObject(object, factoryObject)) + { + craftable = factoryObject; + } + else + return 0; + + const ConstCharCrcString draftSchematic(ObjectTemplateList::lookUp( + craftable->getDraftSchematic())); + if (draftSchematic.getString() == NULL) + return 0; + + return draftSchematic.getCrc(); +} // JavaLibrary::getDraftSchematicCrc + +// ---------------------------------------------------------------------- + +/** + * Returns the draft schematic template name crc used to create an object. + * + * @param env Java environment + * @param self class calling this function + * @param target the object we want the source schematic of + * + * @return the draft schematic name crc, or 0 on error or if the object wasn't crafted + */ +jint JNICALL ScriptMethodsObjectInfoNamespace::getSourceDraftSchematic(JNIEnv * env, jobject self, jlong target) +{ + UNREF(self); + + const TangibleObject * object = NULL; + if (!JavaLibrary::getObject(target, object)) + return 0; + + return static_cast(object->getSourceDraftSchematic()); +} // JavaLibrary::getSourceDraftSchematic + +// ---------------------------------------------------------------------- + +/** + * Returns the "birth" date of a player character. + * + * @param env Java environment + * @param self class calling this function + * @param playerId the id of the player we want + * + * @return returns the birth date, in days since Jan 1st, 2001 (Jan 1st, 2001 = 0); + * returns -1 on error + */ +jint JNICALL ScriptMethodsObjectInfoNamespace::getPlayerBirthDate(JNIEnv * env, jobject self, jlong playerId) +{ + UNREF(self); + + const CreatureObject * playerCreature = NULL; + if (!JavaLibrary::getObject(playerId, playerCreature)) + return -1; + + const PlayerObject * player = PlayerCreatureController::getPlayerObject( + playerCreature); + if (player == NULL) + return -1; + + return player->getBornDate(); +} // JavaLibrary::getPlayerBirthDate + +// ---------------------------------------------------------------------- + +/** + * Returns the "birth" date that a player being created now would get. + * + * @param env Java environment + * @param self class calling this function + * + * @return returns the birth date, in days since Jan 1st, 2001 (Jan 1st, 2001 = 0) + */ +jint JNICALL ScriptMethodsObjectInfoNamespace::getCurrentBirthDate(JNIEnv * env, jobject self) +{ + UNREF(self); + + return PlayerObject::getCurrentBornDate(); +} // JavaLibrary::getCurrentBirthDate + +// ---------------------------------------------------------------------- + +/** + * Returns the amount of time a player has been online. + * + * @param env Java environment + * @param self class calling this function + * @param playerId the id of the player we want + * + * @return + */ +jint JNICALL ScriptMethodsObjectInfoNamespace::getPlayerPlayedTime(JNIEnv * env, jobject self, jlong playerId) +{ + UNREF(self); + + const CreatureObject * playerCreature = NULL; + if (!JavaLibrary::getObject(playerId, playerCreature)) + return -1; + + const PlayerObject * player = PlayerCreatureController::getPlayerObject( + playerCreature); + if (player == NULL) + return -1; + + return player->getPlayedTime(); +} // JavaLibrary::getPlayerPlayedTime + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsObjectInfoNamespace::getBuildingCityId(JNIEnv *env, jobject self, jlong building) +{ + UNREF(self); + BuildingObject *buildingObj = 0; + if (JavaLibrary::getObject(building, buildingObj)) + return buildingObj->getCityId(); + return 0; +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectInfoNamespace::setBuildingCityId(JNIEnv *env, jobject self, jlong building, jint cityId) +{ + UNREF(self); + BuildingObject *buildingObj = 0; + if (JavaLibrary::getObject(building, buildingObj)) + buildingObj->setCityId(cityId); +} + +// ---------------------------------------------------------------------- + +/** + * Returns the default name that would be given an object created by a given + * draft schematic. + * + * @param env Java environment + * @param self class calling this function + * @param jschematicName the schematic name + * + * @return the object name, or null if the schematic doesn't exist + */ +jobject JNICALL ScriptMethodsObjectInfoNamespace::getProductNameFromSchematic(JNIEnv *env, jobject self, + jstring jschematicName) +{ + JavaStringParam schematicNameParam(jschematicName); + + std::string schematicName; + if (!JavaLibrary::convert(schematicNameParam, schematicName)) + return 0; + + const DraftSchematicObject * schematic = DraftSchematicObject::getSchematic( + schematicName); + if (schematic == NULL) + return 0; + + const ServerObjectTemplate * serverOt = schematic->getCraftedObjectTemplate(); + if (serverOt == NULL) + return 0; + + const std::string sharedTemplateName(serverOt->getSharedTemplate()); + const ObjectTemplate * ot = ObjectTemplateList::fetch(sharedTemplateName); + if (ot == NULL) + return 0; + + const SharedObjectTemplate * sharedOt = dynamic_cast( + ot); + if (sharedOt == NULL) + { + ot->releaseReference(); + return 0; + } + ot = NULL; + + const StringId objectName(sharedOt->getObjectName()); + sharedOt->releaseReference(); + sharedOt = NULL; + + LocalRefPtr jobjectName; + if (!ScriptConversion::convert(objectName, jobjectName)) + return 0; + return jobjectName->getReturnValue(); +} // JavaLibrary::getProductNameFromSchematic + +// ---------------------------------------------------------------------- + +/** + * Returns the default name that would be given an object created by a given + * draft schematic. + * + * @param env Java environment + * @param self class calling this function + * @param schematicCrc the schematic name crc + * + * @return the object name, or null if the schematic doesn't exist + */ +jobject JNICALL ScriptMethodsObjectInfoNamespace::getProductNameFromSchematicCrc(JNIEnv *env, jobject self, + jint schematicCrc) +{ + const DraftSchematicObject * schematic = DraftSchematicObject::getSchematic( + schematicCrc); + if (schematic == NULL) + return 0; + + const ServerObjectTemplate * serverOt = schematic->getCraftedObjectTemplate(); + if (serverOt == NULL) + return 0; + + const std::string sharedTemplateName(serverOt->getSharedTemplate()); + const ObjectTemplate * ot = ObjectTemplateList::fetch(sharedTemplateName); + if (ot == NULL) + return 0; + + const SharedObjectTemplate * sharedOt = dynamic_cast( + ot); + if (sharedOt == NULL) + { + ot->releaseReference(); + return 0; + } + ot = NULL; + + const StringId objectName(sharedOt->getObjectName()); + sharedOt->releaseReference(); + sharedOt = NULL; + + LocalRefPtr jobjectName; + if (!ScriptConversion::convert(objectName, jobjectName)) + return 0; + return jobjectName->getReturnValue(); +} // JavaLibrary::getProductNameFromSchematicCrc + +// ---------------------------------------------------------------------- + +/** + * Gets the template of the item a draft schematic creates. + * + * @param env Java environment + * @param self class calling this function + * @param draftSchematic the draft schematic's template + * + * @return the template for the item the schematic creates, or null on error + */ +jstring JNICALL ScriptMethodsObjectInfoNamespace::getTemplateCreatedFromSchematic(JNIEnv *env, jobject self, + jstring draftSchematic) +{ + if (draftSchematic == 0) + return 0; + + JavaStringParam jdraftSchematic(draftSchematic); + std::string schematicName; + if (!JavaLibrary::convert(jdraftSchematic, schematicName)) + return 0; + + return getTemplateCreatedFromSchematicCrc(env, self, Crc::calculate( + schematicName.c_str())); +} // JavaLibrary::getTemplateCreatedFromSchematic + +// ---------------------------------------------------------------------- + +/** + * Gets the template of the item a draft schematic creates. + * + * @param env Java environment + * @param self class calling this function + * @param draftSchematicCrc the draft schematic's template crc + * + * @return the template for the item the schematic creates, or null on error + */ +jstring JNICALL ScriptMethodsObjectInfoNamespace::getTemplateCreatedFromSchematicCrc(JNIEnv *env, jobject self, + jint draftSchematicCrc) +{ + UNREF(self); + + if (draftSchematicCrc == 0) + return 0; + + const DraftSchematicObject * schematic = DraftSchematicObject::getSchematic( + draftSchematicCrc); + if (schematic == NULL) + return 0; + + const ServerObjectTemplate * serverOt = schematic->getCraftedObjectTemplate(); + if (serverOt == NULL) + return 0; + + JavaString templateName(serverOt->getName()); + return templateName.getReturnValue(); +} // JavaLibrary::getTemplateCreatedFromSchematicCrc + +// ---------------------------------------------------------------------- + +/** + * Gets the template of the item a draft schematic creates. + * + * @param env Java environment + * @param self class calling this function + * @param draftSchematic the draft schematic's template + * + * @return the template crc for the item the schematic creates, or 0 on error + */ +jint JNICALL ScriptMethodsObjectInfoNamespace::getTemplateCrcCreatedFromSchematic(JNIEnv *env, jobject self, + jstring draftSchematic) +{ + if (draftSchematic == 0) + return 0; + + JavaStringParam jdraftSchematic(draftSchematic); + std::string schematicName; + if (!JavaLibrary::convert(jdraftSchematic, schematicName)) + return 0; + + return getTemplateCrcCreatedFromSchematicCrc(env, self, Crc::calculate( + schematicName.c_str())); +} // JavaLibrary::getTemplateCrcCreatedFromSchematic + +// ---------------------------------------------------------------------- + +/** + * Gets the template of the item a draft schematic creates. + * + * @param env Java environment + * @param self class calling this function + * @param draftSchematicCrc the draft schematic's template crc + * + * @return the template crc for the item the schematic creates, or 0 on error + */ +jint JNICALL ScriptMethodsObjectInfoNamespace::getTemplateCrcCreatedFromSchematicCrc(JNIEnv *env, jobject self, + jint draftSchematicCrc) +{ + UNREF(self); + + if (draftSchematicCrc == 0) + return 0; + + const DraftSchematicObject * schematic = DraftSchematicObject::getSchematic( + draftSchematicCrc); + if (schematic == NULL) + return 0; + + const ServerObjectTemplate * serverOt = schematic->getCraftedObjectTemplate(); + if (serverOt == NULL) + return 0; + + return Crc::calculate(serverOt->getName()); +} // JavaLibrary::getTemplateCrcCreatedFromSchematicCrc + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectInfoNamespace::findObjectAnywhere(JNIEnv *env, jobject self, jlong target, jlong objectToNotify) +{ + NetworkId targetId(target); + NetworkId notifyId(objectToNotify); + + if (targetId == NetworkId::cms_invalid || notifyId == NetworkId::cms_invalid) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("findObjectAnywhere received a bad object in its parameters")); + else + { + GenericValueTypeMessage > > locateObject( + "LocateObject", + std::make_pair( + GameServer::getInstance().getProcessId(), + std::make_pair(targetId, notifyId))); + GameServer::getInstance().sendToCentralServer(locateObject); + } +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectInfoNamespace::findObjectAnywhereByTemplate(JNIEnv *env, jobject self, jstring templateName, jlong objectToNotify) +{ + NetworkId notifyId(objectToNotify); + + if (notifyId == NetworkId::cms_invalid) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::findObjectAnywhereByTemplate received a bad notify object in its parameters")); + else + { + JavaStringParam jspTemplateName(templateName); + std::string templateNameString; + if (!JavaLibrary::convert(jspTemplateName, templateNameString)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::findObjectAnywhereByTemplate given bad template name string")); + } + else + { + if (!templateNameString.empty()) + { + GenericValueTypeMessage > > locatePlayer( + "LocateObjectByTemplateName", + std::make_pair( + GameServer::getInstance().getProcessId(), + std::make_pair(CrcLowerString::calculateCrc(templateNameString.c_str()), notifyId))); + GameServer::getInstance().sendToCentralServer(locatePlayer); + } + } + } +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectInfoNamespace::findPlayerAnywhereByPartialName(JNIEnv *env, jobject self, jstring targetName, jlong objectToNotify) +{ + NetworkId notifyId(objectToNotify); + + if (notifyId == NetworkId::cms_invalid) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::findPlayerAnywhereByPartialName received a bad notify object in its parameters")); + else + { + JavaStringParam playerName(targetName); + std::string playerNameString; + if (!JavaLibrary::convert(playerName, playerNameString)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::findPlayerAnywhereByPartialName given bad player name string")); + } + else + { + if (!playerNameString.empty()) + { + GenericValueTypeMessage > > locatePlayer( + "LocatePlayerByPartialName", + std::make_pair( + GameServer::getInstance().getProcessId(), + std::make_pair(playerNameString, notifyId))); + GameServer::getInstance().sendToCentralServer(locatePlayer); + } + } + } +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectInfoNamespace::findWardenAnywhere(JNIEnv *env, jobject self, jlong objectToNotify) +{ + NetworkId notifyId(objectToNotify); + + if (notifyId == NetworkId::cms_invalid) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::findWardenAnywhere received a bad notify object in its parameters")); + else + { + GenericValueTypeMessage > locateWarden( + "LocateWarden", + std::make_pair(GameServer::getInstance().getProcessId(), notifyId)); + GameServer::getInstance().sendToCentralServer(locateWarden); + } +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectInfoNamespace::findCreatureAnywhere(JNIEnv *env, jobject self, jstring creatureName, jlong objectToNotify) +{ + NetworkId notifyId(objectToNotify); + + if (notifyId == NetworkId::cms_invalid) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::findCreatureAnywhere received a bad notify object in its parameters")); + else + { + JavaStringParam jspCreatureName(creatureName); + std::string creatureNameString; + if (!JavaLibrary::convert(jspCreatureName, creatureNameString)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::findCreatureAnywhere given bad creature name string")); + } + else + { + if (!creatureNameString.empty()) + { + GenericValueTypeMessage > > locatePlayer( + "LocateCreatureByCreatureName", + std::make_pair( + GameServer::getInstance().getProcessId(), + std::make_pair(creatureNameString, notifyId))); + GameServer::getInstance().sendToCentralServer(locatePlayer); + } + } + } +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectInfoNamespace::sendDirtyObjectMenuNotification(JNIEnv *env, jobject self, jlong jTarget) +{ + UNREF (env); + UNREF (self); + ServerObject *target = 0; + if (JavaLibrary::getObject(jTarget, target) && target) + target->sendDirtyObjectMenuNotification (); + else + DEBUG_WARNING(true, ("[designer bug] sendDirtyObjectMenuNotification script hook was passed an invalid target reference")); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectInfoNamespace::sendDirtyAttributesNotification(JNIEnv *env, jobject self, jlong jTarget) +{ + UNREF (env); + UNREF (self); + ServerObject *target = 0; + if (JavaLibrary::getObject(jTarget, target) && target) + target->sendDirtyAttributesNotification (); + else + DEBUG_WARNING(true, ("[designer bug] sendDirtyAttributesNotification script hook was passed an invalid target reference")); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectInfoNamespace::registerNamedObject(JNIEnv *env, jobject self, jstring name, jlong namedObject) +{ + JavaStringParam localName(name); + std::string objectNameString; + if (!JavaLibrary::convert(localName, objectNameString)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::registerNamedObject: bad name string")); + else + { + NetworkId netId(namedObject); + NamedObjectManager::registerNamedObjectId(objectNameString, netId); + } +} + +// ---------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsObjectInfoNamespace::getNamedObject(JNIEnv *env, jobject self, jstring name) +{ + JavaStringParam localName(name); + std::string objectNameString; + if (!JavaLibrary::convert(localName, objectNameString)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::getNamedObject: bad name string")); + else + { + NetworkId const &namedObjectId = NamedObjectManager::getNamedObjectId(objectNameString); + if (namedObjectId != NetworkId::cms_invalid) + return namedObjectId.getValue(); + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::getNamedObject: no such object named '%s'", objectNameString.c_str())); + } + return 0; +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectInfoNamespace::requestPreloadCompleteTrigger(JNIEnv *env, jobject self, jlong target) +{ + ServerObject *targetObject = 0; + if (!JavaLibrary::getObject(target, targetObject)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::requestPreloadCompleteTrigger: bad target object")); + else + ServerWorld::requestPreloadCompleteTrigger(*targetObject); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectInfoNamespace::activateQuest(JNIEnv * env, jobject self, jlong target, jint questId) +{ + CreatureObject * playerCreature = NULL; + if (JavaLibrary::getObject(target, playerCreature)) + { + PlayerObject * player = PlayerCreatureController::getPlayerObject(playerCreature); + if(player) + { + player->activateQuest(questId); + } + } + +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectInfoNamespace::deactivateQuest(JNIEnv * env, jobject self, jlong target, jint questId) +{ + CreatureObject * playerCreature = NULL; + if (JavaLibrary::getObject(target, playerCreature)) + { + PlayerObject * player = PlayerCreatureController::getPlayerObject(playerCreature); + if(player) + { + player->deactivateQuest(questId); + } + } + +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectInfoNamespace::completeQuest(JNIEnv * env, jobject self, jlong target, jint questId) +{ + CreatureObject * playerCreature = NULL; + if (JavaLibrary::getObject(target, playerCreature)) + { + PlayerObject * player = PlayerCreatureController::getPlayerObject(playerCreature); + if(player) + { + player->completeQuest(questId); + } + } + +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsObjectInfoNamespace::isQuestComplete(JNIEnv * env, jobject self, jlong target, jint questId) +{ + jboolean result = false; + const CreatureObject * playerCreature = NULL; + if (JavaLibrary::getObject(target, playerCreature)) + { + const PlayerObject * player = PlayerCreatureController::getPlayerObject(playerCreature); + if(player) + { + result = player->isQuestComplete(questId); + } + } + return result; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsObjectInfoNamespace::isQuestActive(JNIEnv * env, jobject self, jlong target, jint questId) +{ + jboolean result = false; + const CreatureObject * playerCreature = NULL; + if (JavaLibrary::getObject(target, playerCreature)) + { + const PlayerObject * player = PlayerCreatureController::getPlayerObject(playerCreature); + if(player) + { + result = player->isQuestActive(questId); + } + } + return result; +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectInfoNamespace::clearCompletedQuest(JNIEnv * env, jobject self, jlong target, jint questId) +{ + if(questId >= 0) + { + CreatureObject * playerCreature = NULL; + if (JavaLibrary::getObject(target, playerCreature)) + { + PlayerObject * player = PlayerCreatureController::getPlayerObject(playerCreature); + if(player) + { + player->clearCompletedQuest(questId); + } + } + } +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsObjectInfoNamespace::canTrade(JNIEnv *env, jobject self, jlong target) +{ + const ServerObject * object = NULL; + if (!JavaLibrary::getObject(target, object)) + return JNI_FALSE; + + return static_cast(object->canTrade() ? JNI_TRUE : JNI_FALSE); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsObjectInfoNamespace::isNoTradeShared(JNIEnv *env, jobject self, jlong target) +{ + const ServerObject * object = NULL; + if (!JavaLibrary::getObject(target, object)) + return JNI_FALSE; + + return static_cast(object->markedNoTradeShared(true) ? JNI_TRUE : JNI_FALSE); +} + +// ---------------------------------------------------------------------- + +/** + * Returns the id of the last theater spawned for a player. Note that we do not + * keep track of any theaters spawned except for the last one. + * + * @param env Java environment + * @param self class calling this function + * @param player the player to check + * + * @return the theater id, or null on error + */ +jlong JNICALL ScriptMethodsObjectInfoNamespace::getLastSpawnedTheater(JNIEnv *env, jobject self, jlong player) +{ + const CreatureObject * creature = NULL; + if (!JavaLibrary::getObject(player, creature)) + return 0; + + const PlayerObject * playerObject = PlayerCreatureController::getPlayerObject(creature); + if (playerObject == NULL) + return 0; + + return (playerObject->getTheater()).getValue(); +} // JavaLibrary::getLastSpawnedTheater + +// ---------------------------------------------------------------------- + +jbyteArray JNICALL ScriptMethodsObjectInfoNamespace::getByteStreamFromAutoVariable(JNIEnv * env, jobject self, jlong target, jstring variableName) +{ + ServerObject * object = 0; + if(JavaLibrary::getObject(target, object)) + { + JavaStringParam localName(variableName); + std::string nameString; + JavaLibrary::convert(localName, nameString); + Archive::ByteStream bs; + object->getByteStreamFromAutoVariable(nameString, bs); + LocalByteArrayRefPtr localInstance; + std::vector source; + + size_t i; + + const unsigned char * const p = bs.getBuffer(); + if(p) + { + for(i = 0; i < bs.getSize(); ++i) + { + source.push_back(static_cast(*(p + i))); + } + if(ScriptConversion::convert(source, localInstance)) + { + return localInstance->getReturnValue(); + } + } + } + return 0; +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectInfoNamespace::setAutoVariableFromByteStream(JNIEnv * env, jobject self, jlong target, jstring variableName, jbyteArray data) +{ + std::vector cdata; + if(ScriptConversion::convert(data, cdata)) + { + Archive::ByteStream bs(reinterpret_cast(&cdata[0]), cdata.size()); + ServerObject * object = 0; + if(JavaLibrary::getObject(target, object)) + { + JavaStringParam localName(variableName); + + std::string nameString; + JavaLibrary::convert(localName, nameString); + + object->setAutoVariableFromByteStream(nameString, bs); + } + } +} + +// ---------------------------------------------------------------------- + +/** + * Sets a bio-link on an object. If the object is equippable, only the player that + * the object is linked to will be able to equip it. If the object is used as a + * component during crafting, the crafted object will also be linked to the player. + * + * @param env Java environment + * @param self class calling this function + * @param target the item to be bio-linked + * @param link the id of the player to link the item to + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::setBioLink(JNIEnv *env, jobject self, jlong target, jlong link) +{ + TangibleObject * object = NULL; + if (!JavaLibrary::getObject(target, object)) + return JNI_FALSE; + + NetworkId bioLink(link); + if (bioLink != NetworkId::cms_invalid) + object->setBioLink(bioLink); + else + object->setPendingBioLink(); + return JNI_TRUE; +} // JavaLibrary::setBioLink + +// ---------------------------------------------------------------------- + +/** + * Removes a bio-link from an object. + * + * @param env Java environment + * @param self class calling this function + * @param target the item to remove the link from + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsObjectInfoNamespace::clearBioLink(JNIEnv *env, jobject self, jlong target) +{ + TangibleObject * object = NULL; + if (!JavaLibrary::getObject(target, object)) + return JNI_FALSE; + + object->clearBioLink(); + return JNI_TRUE; +} // JavaLibrary::clearBioLink + +// ---------------------------------------------------------------------- + +/** + * Returns the bio-link attached to an object. + * + * @param env Java environment + * @param self class calling this function + * @param target the item to get the link from + * + * @return the bio-link id, null if the item isn't linked + */ +jlong JNICALL ScriptMethodsObjectInfoNamespace::getBioLink(JNIEnv *env, jobject self, jlong target) +{ + const TangibleObject * object = NULL; + if (!JavaLibrary::getObject(target, object)) + return 0; + + NetworkId link(object->getBioLink()); + if (link == NetworkId::cms_invalid) + return 0; + return link.getValue(); +} // JavaLibrary::getBioLink + +//---------------------------------------------------------------------- + +float JNICALL ScriptMethodsObjectInfoNamespace::getObjectCollisionRadius(JNIEnv * env, jobject self, jlong jobject_obj) +{ + const Object * object = NULL; + if (!JavaLibrary::getObject(jobject_obj, object)) + return 0.0f; + + Sphere const & sphere = object->getCollisionSphereExtent_o(); + + return sphere.getRadius(); +} + +// ---------------------------------------------------------------------- + +/** + * Returns the static item name (if any) of the object + * + * @param env Java environment + * @param self class calling this function + * @param target id of the object + * + * @return the name, or null on error + */ +jstring JNICALL ScriptMethodsObjectInfoNamespace::getStaticItemName(JNIEnv * /*env*/, jobject /*self*/, jlong target) +{ + const ServerObject * o = NULL; + if (!JavaLibrary::getObject(target, o)) + return 0; + + const std::string & name = o->getStaticItemName(); + if (name.empty()) + return 0; + return JavaString(name).getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsObjectInfoNamespace::getStaticItemVersion(JNIEnv *env, jobject /*self*/, jlong target) +{ + const ServerObject * o = NULL; + if (!JavaLibrary::getObject(target, o)) + return 0; + + return o->getStaticItemVersion(); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectInfoNamespace::setStaticItemName(JNIEnv * /*env*/, jobject /*self*/, jlong target, jstring staticItemName) +{ + NetworkId const networkId(target); + ServerObject * const o = ServerObject::getServerObject(networkId); + + if (o == NULL) + { + WARNING(true, ("ERROR: ScriptMethodsObjectInfo::setStaticItemName() Unable to resolve the object(%s).", networkId.getValueString().c_str())); + return; + } + + std::string nameString; + JavaLibrary::convert(JavaStringParam(staticItemName), nameString); + o->setStaticItemName(nameString); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectInfoNamespace::setStaticItemVersion(JNIEnv * /*env*/, jobject /*self*/, jlong target, jint staticItemVersion) +{ + NetworkId const networkId(target); + ServerObject * const o = ServerObject::getServerObject(networkId); + + if (o == NULL) + { + WARNING(true, ("ERROR: ScriptMethodsObjectInfo::setStaticItemVersion() Unable to resolve the object(%s).", networkId.getValueString().c_str())); + return; + } + + o->setStaticItemVersion(staticItemVersion); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsObjectInfoNamespace::getConversionId(JNIEnv * /*env*/, jobject /*self*/, jlong target) +{ + const ServerObject * o = NULL; + if (!JavaLibrary::getObject(target, o)) + return 0; + + return o->getConversionId(); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectInfoNamespace::setConversionId(JNIEnv * /*env*/, jobject /*self*/, jlong target, jint conversionId) +{ + NetworkId const networkId(target); + ServerObject * const o = ServerObject::getServerObject(networkId); + + if (o == NULL) + { + WARNING(true, ("ERROR: ScriptMethodsObjectInfo::setConversionId() Unable to resolve the object(%s).", networkId.getValueString().c_str())); + return; + } + + o->setConversionId(conversionId); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectInfoNamespace::openCustomizationWindow(JNIEnv *env, jobject self, jlong player, jlong object, jstring customVarName1, jint minVar1, jint maxVar1, jstring customVarName2, jint minVar2, jint maxVar2, jstring customVarName3, jint minVar3, jint maxVar3, jstring customVarName4, jint minVar4, jint maxVar4) +{ + CreatureObject * playerObject = NULL; + if (!JavaLibrary::getObject(player, playerObject)) + return; + std::string customVarName1String; + JavaLibrary::convert(JavaStringParam(customVarName1), customVarName1String); + std::string customVarName2String; + JavaLibrary::convert(JavaStringParam(customVarName2), customVarName2String); + std::string customVarName3String; + JavaLibrary::convert(JavaStringParam(customVarName3), customVarName3String); + std::string customVarName4String; + JavaLibrary::convert(JavaStringParam(customVarName4), customVarName4String); + + std::string value; + value.append(customVarName1String); + char tmp[512]; + sprintf(tmp, " %d %d ", minVar1, maxVar1); + value.append(tmp); + if(!customVarName2String.empty()) + { + value.append(" "); + value.append(customVarName2String); + char tmp[512]; + sprintf(tmp, " %d %d ", minVar2, maxVar2); + value.append(tmp); + } + if(!customVarName3String.empty()) + { + value.append(" "); + value.append(customVarName3String); + char tmp[512]; + sprintf(tmp, " %d %d ", minVar3, maxVar3); + value.append(tmp); + } + if(!customVarName4String.empty()) + { + value.append(" "); + value.append(customVarName4String); + char tmp[512]; + sprintf(tmp, " %d %d ", minVar4, maxVar4); + value.append(tmp); + } + + NetworkId const objectId(object); + + if (playerObject->isPlayerControlled() && playerObject->getController() != NULL) + { + playerObject->getController()->appendMessage( + static_cast(CM_openCustomizationWindow), + 0, + new MessageQueueGenericValueType >(std::make_pair(objectId, value)), + GameControllerMessageFlags::SEND | + GameControllerMessageFlags::RELIABLE | + GameControllerMessageFlags::DEST_AUTH_CLIENT); + } + return; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsObjectInfoNamespace::isPlayerBackpackHidden(JNIEnv *env, jobject self, jlong player) +{ + UNREF(self); + + const CreatureObject *playerObj = 0; + if (JavaLibrary::getObject(player, playerObj) && playerObj->isPlayerControlled()) + { + const PlayerObject * playerObject = PlayerCreatureController::getPlayerObject(playerObj); + if(playerObject) + { + if(playerObject->getShowBackpack()) + return JNI_FALSE; + else + return JNI_TRUE; + } + } + + return JNI_FALSE; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsObjectInfoNamespace::isPlayerHelmetHidden(JNIEnv *env, jobject self, jlong player) +{ + UNREF(self); + + const CreatureObject *playerObj = 0; + if (JavaLibrary::getObject(player, playerObj) && playerObj->isPlayerControlled()) + { + const PlayerObject * playerObject = PlayerCreatureController::getPlayerObject(playerObj); + if(playerObject) + { + if(playerObject->getShowHelmet()) + return JNI_FALSE; + else + return JNI_TRUE; + } + } + + return JNI_FALSE; +} + +// ---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsObjectInfoNamespace::getDefaultScaleFromSharedObjectTemplate(JNIEnv *env, jobject self, jstring sharedObjectTemplateName) +{ + UNREF(env); + UNREF(self); + + //-- Retrieve the server object template name. + JavaStringParam sharedObjectTemplateNameParam(sharedObjectTemplateName); + std::string sharedObjectTemplateNameNarrow; + + JavaLibrary::convert(sharedObjectTemplateNameParam, sharedObjectTemplateNameNarrow); + + //-- Open the shared object template. + ObjectTemplate const *const baseSharedObjectTemplate = ObjectTemplateList::fetch(sharedObjectTemplateNameNarrow); + if (!baseSharedObjectTemplate) + { + char buffer[512]; + snprintf(buffer, sizeof(buffer) - 1, "getDefaultScaleFromSharedObjectTemplate(): failed to open shared object template [%s].", sharedObjectTemplateNameNarrow.c_str()); + buffer[sizeof(buffer) - 1] = '\0'; + + LOG("ScriptMethodsObjectInfo", (buffer)); + JavaLibrary::throwInternalScriptError(buffer); + + return static_cast(0.0f); + } + + //-- Convert to a shared object template. + SharedObjectTemplate const *const sharedObjectTemplate = baseSharedObjectTemplate->asSharedObjectTemplate(); + if (!sharedObjectTemplate) + { + char buffer[512]; + snprintf(buffer, sizeof(buffer) - 1, "getDefaultScaleFromSharedObjectTemplate(): object template [%s] is not derived from SharedObjectTemplate.", sharedObjectTemplateNameNarrow.c_str()); + buffer[sizeof(buffer) - 1] = '\0'; + + LOG("ScriptMethodsObjectInfo", (buffer)); + JavaLibrary::throwInternalScriptError(buffer); + + baseSharedObjectTemplate->releaseReference(); + return static_cast(0.0f); + } + + //-- Get scale. + jfloat const returnScale = static_cast(sharedObjectTemplate->getScale()); + + baseSharedObjectTemplate->releaseReference(); + + return returnScale; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsObjectInfoNamespace::setOverrideMapColor(JNIEnv * env, jobject self, jlong object, jint r, jint g, jint b) +{ + TangibleObject * tangible = NULL; + if (!JavaLibrary::getObject(object, tangible)) + return JNI_FALSE; + + if(!tangible->setOverrideMapColor(static_cast(r), static_cast(g), static_cast(b))) + { + return JNI_FALSE; + } + + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsObjectInfoNamespace::clearOverrideMapColor(JNIEnv * env, jobject self, jlong object) +{ + TangibleObject * tangible = NULL; + if (!JavaLibrary::getObject(object, tangible)) + return JNI_FALSE; + + if(!tangible->clearOverrideMapColor()) + { + return JNI_FALSE; + } + + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +jobject JNICALL ScriptMethodsObjectInfoNamespace::getOverrideMapColor(JNIEnv * env, jobject self, jlong object) +{ + TangibleObject * tangible = NULL; + if (!JavaLibrary::getObject(object, tangible)) + return NULL; + + uint8 r, g, b; + if(!tangible->getOverrideMapColor(r,g,b)) + { + return NULL; + } + + return createColor(r, g, b, 255)->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsObjectInfoNamespace::setForceShowHam(JNIEnv * env, jobject self, jlong object, jboolean show) +{ + CreatureObject * creature = NULL; + if (!JavaLibrary::getObject(object, creature)) + return JNI_FALSE; + + if(!creature->setForceShowHam(show)) + { + return JNI_FALSE; + } + + return JNI_TRUE; +} + +jboolean JNICALL ScriptMethodsObjectInfoNamespace::isContainedByPlayerAppearanceInventory(JNIEnv *env, jobject self, jlong player, jlong item) +{ + UNREF(self); + ServerObject *itemObj = NULL; + CreatureObject *playerObj = NULL; + + if(!JavaLibrary::getObject(item, itemObj)) + { + WARNING(true, ("isContainedByPlayerAppearanceInventory: Failed to get item object")); + } + if(!JavaLibrary::getObject(player, playerObj)) + { + WARNING(true, ("isContainedByPlayerAppearanceInventory: Failed to get player object")); + } + + if(!itemObj || !playerObj || !playerObj->isPlayerControlled()) + return JNI_FALSE; + + Object const * containedBy = ContainerInterface::getContainedByObject(*itemObj); + if(!containedBy) + return JNI_FALSE; + + ServerObject const * playerAppearInv = playerObj->getAppearanceInventory(); + + if(playerAppearInv && playerAppearInv == containedBy) + return JNI_TRUE; + + return JNI_FALSE; +} + +jlongArray JNICALL ScriptMethodsObjectInfoNamespace::getAllItemsFromAppearanceInventory(JNIEnv * env, jobject self, jlong player) +{ + UNREF(self); + + const CreatureObject * playerCreature = NULL; + if (!JavaLibrary::getObject(player, playerCreature)) + return 0; + + std::vector objectIds; + + // go through the player's appearance inventory + const ServerObject * appearanceInventoryObject = playerCreature->getAppearanceInventory(); + if (appearanceInventoryObject != NULL) + { + const SlottedContainer * appearanceInvContainer = + ContainerInterface::getSlottedContainer(*appearanceInventoryObject); + if (appearanceInvContainer != NULL) + { + getGoodItemsFromContainer(*appearanceInvContainer, objectIds); + } + else + { + DEBUG_WARNING(true, ("JavaLibrary::getAllItemsFromAppearanceInventory creature %s " + "appearance inventory object %s has no slotted container", + playerCreature->getNetworkId().getValueString().c_str(), + appearanceInventoryObject->getNetworkId().getValueString().c_str())); + } + } + else + { + DEBUG_WARNING(true, ("JavaLibrary::getAllItemsFromAppearanceInventory creature %s has " + "no appearance inventory object", + playerCreature->getNetworkId().getValueString().c_str())); + } + + if (!objectIds.empty()) + { + LocalLongArrayRefPtr returnedIds; + if (ScriptConversion::convert(objectIds, returnedIds)) + return returnedIds->getReturnValue(); + } + + return 0; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsObjectInfoNamespace::isAPlayerAppearanceInventoryContainer(JNIEnv *env, jobject self, jlong container) +{ + UNREF(self); + + const ServerObject * containerObj = NULL; + if (!JavaLibrary::getObject(container, containerObj)) + return JNI_FALSE; + + const CreatureObject * creatureParent = dynamic_cast(ContainerInterface::getContainedByObject(*containerObj)); + if(creatureParent && creatureParent->isPlayerControlled() && creatureParent->getAppearanceInventory() == containerObj) + return JNI_TRUE; + + return JNI_FALSE; +} + +// ---------------------------------------------------------------------- + +jlongArray JNICALL ScriptMethodsObjectInfoNamespace::getAllWornItems(JNIEnv *env, jobject self, jlong player, jboolean ignoreAppearanceItems) +{ + UNREF(self); + + const CreatureObject * playerCreature = NULL; + if (!JavaLibrary::getObject(player, playerCreature)) + return 0; + + std::vector objectIds; + std::map wornObjects; + + if(!ignoreAppearanceItems && playerCreature->getAppearanceInventory() ) + { + const SlottedContainer * appearanceInventory = ContainerInterface::getSlottedContainer(*playerCreature->getAppearanceInventory()); + + if(!appearanceInventory) + { + DEBUG_WARNING(true, ("JavaLibrary: getAllWornItems - Tried to get all the worn items(INCLUDING appearance items) from player [%s], but this player has no appearance inventory container.", + playerCreature->getNetworkId().getValueString().c_str())); + + return NULL; + } + + for (ContainerConstIterator i(appearanceInventory->begin()); i != appearanceInventory->end(); ++i) + { + const CachedNetworkId & itemId = *i; + const ServerObject * item = safe_cast( + itemId.getObject()); + if (item != NULL && item->asTangibleObject() != NULL && + item->asTangibleObject()->isVisible()) + { + + const SlottedContainmentProperty * slottedContainment = ContainerInterface::getSlottedContainmentProperty(*item); // Get the slot property of our item. + + if(slottedContainment && slottedContainment->getCurrentArrangement() >= 0) + { + SlottedContainmentProperty::SlotArrangement const slots = slottedContainment->getSlotArrangement(slottedContainment->getCurrentArrangement()); // Get the old arrangement + for(unsigned int j = 0; j < slots.size(); ++j) + wornObjects.insert(std::make_pair(slots[j], item)); + } + } + } + } + + const SlottedContainer * inventory = ContainerInterface::getSlottedContainer(*playerCreature); + + if(!inventory) + { + DEBUG_WARNING(true, ("JavaLibrary: getAllWornItems - Tried to get all the worn items from player [%s], but this player has no creature slot container.", + playerCreature->getNetworkId().getValueString().c_str())); + + return NULL; + } + + for (ContainerConstIterator i(inventory->begin()); i != inventory->end(); ++i) + { + const CachedNetworkId & itemId = *i; + const ServerObject * item = safe_cast( + itemId.getObject()); + if (item != NULL && item->asTangibleObject() != NULL && + item->asTangibleObject()->isVisible()) + { + const SlottedContainmentProperty * slottedContainment = ContainerInterface::getSlottedContainmentProperty(*item); // Get the slot property of our item. + + if(slottedContainment && slottedContainment->getCurrentArrangement() >= 0) + { + SlottedContainmentProperty::SlotArrangement const slots = slottedContainment->getSlotArrangement(slottedContainment->getCurrentArrangement()); // Get the old arrangement + bool slotOccupied = false; + for(unsigned int j = 0; j < slots.size(); ++j) + { + if(wornObjects.find(slots[j]) != wornObjects.end()) + { + slotOccupied = true; + break; + } + + } + + if(!slotOccupied) + { + for(unsigned int j = 0; j < slots.size(); ++j) + wornObjects.insert(std::make_pair(slots[j], item)); + } + } + } + } + + std::map::iterator mapIter = wornObjects.begin(); + + for(; mapIter != wornObjects.end(); ++mapIter) + objectIds.push_back((*mapIter).second->getNetworkId()); + + if (!objectIds.empty()) + { + LocalLongArrayRefPtr returnedIds; + if (ScriptConversion::convert(objectIds, returnedIds)) + return returnedIds->getReturnValue(); + } + + return NULL; + +} + +// ---------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsObjectInfoNamespace::getAppearanceInventory(JNIEnv *env, jobject self, jlong player) +{ + UNREF(env); + UNREF(self); + + const CreatureObject * playerCreature = NULL; + if (!JavaLibrary::getObject(player, playerCreature)) + return 0; + + NetworkId appearInv = NetworkId::cms_invalid; + if(playerCreature->getAppearanceInventory()) + appearInv = playerCreature->getAppearanceInventory()->getNetworkId(); + + return appearInv == NetworkId::cms_invalid ? 0 : appearInv.getValue(); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsObjectInfoNamespace::setDecoyOrigin(JNIEnv *env, jobject self, jlong creature, jlong origin) +{ + UNREF(env); + UNREF(self); + + CreatureObject * decoyCreature = NULL; + if (!JavaLibrary::getObject(creature, decoyCreature)) + return JNI_FALSE; + + const CreatureObject * originCreature = NULL; + if (!JavaLibrary::getObject(origin, originCreature)) + return JNI_FALSE; + + if(decoyCreature && originCreature) + { + decoyCreature->setDecoyOrigin(originCreature->getNetworkId()); + return JNI_TRUE; + } + + return JNI_FALSE; + +} + +// ---------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsObjectInfoNamespace::getDecoyOrigin(JNIEnv *env, jobject self, jlong creature) +{ + UNREF(env); + UNREF(self); + + CreatureObject * decoyCreature = NULL; + if (!JavaLibrary::getObject(creature, decoyCreature)) + return JNI_FALSE; + + if(decoyCreature) + return decoyCreature->getDecoyOrigin().getValue(); + + return 0; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsObjectInfoNamespace::openRatingWindow(JNIEnv * env, jobject self, jlong player, jstring title, jstring description) +{ + UNREF(env); + UNREF(self); + + CreatureObject * playerCreature = NULL; + if (!JavaLibrary::getObject(player, playerCreature)) + { + DEBUG_WARNING(true, ("OpenRatingWindow: Failed to get valid creature object with OID %d", player)); + return JNI_FALSE; + } + + JavaStringParam localTitle(title); + std::string narrowTitle; + + if(!JavaLibrary::convert(localTitle, narrowTitle)) + { + DEBUG_WARNING(true, ("OpenRatingWindow: Failed to convert title string.")); + return JNI_FALSE; + } + + JavaStringParam localDesc(description); + std::string narrowDesc; + + if(!JavaLibrary::convert(localDesc, narrowDesc)) + { + DEBUG_WARNING(true, ("OpenRatingWindow: Failed to convert description string.")); + return JNI_FALSE; + } + + if (playerCreature->isPlayerControlled() && playerCreature->getController() != NULL) + { + playerCreature->getController()->appendMessage( + static_cast(CM_openRatingWindow), + 0, + new MessageQueueGenericValueType >(std::make_pair(narrowTitle, narrowDesc)), + GameControllerMessageFlags::SEND | + GameControllerMessageFlags::RELIABLE | + GameControllerMessageFlags::DEST_AUTH_CLIENT); + + return JNI_TRUE; + } + + return JNI_FALSE; +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectInfoNamespace::openExamineWindow(JNIEnv * env, jobject self, jlong player, jlong item) +{ + UNREF(env); + UNREF(self); + + CreatureObject const * playerCreature = NULL; + if (!JavaLibrary::getObject(player, playerCreature) || !playerCreature || !playerCreature->getClient()) + { + return; + } + + ServerObject const * itemObject = NULL; + if (!JavaLibrary::getObject(item, itemObject) || !itemObject) + { + return; + } + + if (!ObserveTracker::isObserving(*(playerCreature->getClient()), *itemObject)) + { + return; + } + + GenericValueTypeMessage const openExamineWindowMsg("OpenExamineWindow", itemObject->getNetworkId()); + playerCreature->getClient()->send(openExamineWindowMsg, true); +} + +// ====================================================================== diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsObjectMove.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsObjectMove.cpp new file mode 100644 index 00000000..d345c4f0 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsObjectMove.cpp @@ -0,0 +1,1781 @@ +//======================================================================== +// +// ScriptMethodsObjectMove.cpp - implements script methods dealing with object +// movement. +// +// copyright 2001 Sony Online Entertainment +// +//======================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "serverGame/AiCreatureController.h" +#include "serverGame/CellObject.h" +#include "serverGame/ConfigServerGame.h" +#include "serverGame/ContainerInterface.h" +#include "serverGame/CreatureObject.h" +#include "serverGame/GameServer.h" +#include "serverGame/NewbieTutorial.h" +#include "serverGame/PlayerCreatureController.h" +#include "serverGame/PlayerObject.h" +#include "serverGame/PositionUpdateTracker.h" +#include "serverGame/ServerCreatureObjectTemplate.h" +#include "serverGame/ServerUniverse.h" +#include "serverGame/ServerWorld.h" +#include "serverGame/ShipObject.h" +#include "serverGame/TangibleController.h" +#include "serverScript/ScriptParameters.h" +#include "serverUtility/LocationData.h" +#include "sharedCollision/CollisionProperty.h" +#include "sharedCollision/Footprint.h" +#include "sharedLog/Log.h" +#include "sharedMath/Quaternion.h" +#include "sharedMath/Vector.h" +#include "sharedObject/CachedNetworkId.h" +#include "sharedObject/CellProperty.h" +#include "sharedObject/NetworkIdManager.h" + +using namespace JNIWrappersNamespace; + + +// ====================================================================== +// ScriptMethodsObjectMoveNamespace +// ====================================================================== + +namespace ScriptMethodsObjectMoveNamespace +{ + bool install(); + bool testInvalidObjectMove(const ServerObject * object); + + jboolean JNICALL setLocationFromPos(JNIEnv *env, jobject self, jlong objectId, jobject to); + jboolean JNICALL setLocationFromObj(JNIEnv *env, jobject self, jlong objectId, jlong toId); + jobject JNICALL getLocation(JNIEnv *env, jobject self, jlong objectId); + jobject JNICALL getWorldLocation(JNIEnv *env, jobject self, jlong objectId); + jobject JNICALL getHeading(JNIEnv *env, jobject self, jlong objectId); + jobject JNICALL getTransform_o2w(JNIEnv *env, jobject self, jlong objectId); + jobject JNICALL getTransform_o2p(JNIEnv *env, jobject self, jlong objectId); + jlong JNICALL getAttachedTo(JNIEnv *env, jobject self, jlong objectId); + void JNICALL setTransform_o2p(JNIEnv *env, jobject self, jlong objectId, jobject transform); + jboolean JNICALL faceToObj(JNIEnv *env, jobject self, jlong mob, jlong target); + jboolean JNICALL faceToPos(JNIEnv *env, jobject self, jlong mob, jobject target); + jboolean JNICALL faceToBehavior(JNIEnv *env, jobject self, jlong mob, jlong target); + jint JNICALL elevatorMove(JNIEnv * env, jobject self, jlong mob, jint nFloors); + void JNICALL setClientUsesAnimationLocomotion(JNIEnv *env, jobject self, jlong target, jboolean enabled); + jfloat JNICALL getMovementSpeed(JNIEnv *env, jobject self, jlong object); + jfloat JNICALL getWalkSpeed(JNIEnv *env, jobject self, jlong object); + jfloat JNICALL getRunSpeed(JNIEnv *env, jobject self, jlong object); + void JNICALL setBaseWalkSpeed(JNIEnv *env, jobject self, jlong object, jfloat speed); + jfloat JNICALL getBaseWalkSpeed(JNIEnv *env, jobject self, jlong object); + void JNICALL setBaseRunSpeed(JNIEnv *env, jobject self, jlong object, jfloat speed); + jfloat JNICALL getBaseRunSpeed(JNIEnv *env, jobject self, jlong object); + void JNICALL setMovementWalk(JNIEnv *env, jobject self, jlong object); + void JNICALL setMovementRun(JNIEnv *env, jobject self, jlong object); + void JNICALL hideFromClient(JNIEnv *env, jobject self, jlong object, jboolean hide); + jboolean JNICALL stopFloating(JNIEnv *env, jobject self, jlong objectId); + jboolean JNICALL setFloatingTime(JNIEnv *env, jobject self, jlong objectId, jint seconds ); + jfloat JNICALL getYaw(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL setYaw(JNIEnv *env, jobject self, jlong target, jfloat scale); + void JNICALL modifyYaw(JNIEnv *env, jobject self, jlong target, jfloat degrees); + void JNICALL modifyPitch(JNIEnv *env, jobject self, jlong target, jfloat degrees); + void JNICALL modifyRoll(JNIEnv *env, jobject self, jlong target, jfloat degrees); + jfloatArray JNICALL getQuaternion(JNIEnv *env, jobject self, jlong target); + void JNICALL setQuaternion(JNIEnv *env, jobject self, jlong target, jfloat qw, jfloat qx, jfloat qy, jfloat qz); + jint JNICALL getFurnitureRotationDegree(JNIEnv *env, jobject self, jlong player); + void JNICALL saveDecorationLayout(JNIEnv *env, jobject self, jlong player, jlong pob, jint saveSlotNumber, jstring description); + void JNICALL restoreDecorationLayout(JNIEnv *env, jobject self, jlong player, jlong pob, jint saveSlotNumber); + jboolean JNICALL setSlopeModAngle(JNIEnv *env, jobject self, jlong mob, jfloat value); + jfloat JNICALL getSlopeModAngle(JNIEnv *env, jobject self, jlong mob); + jfloat JNICALL getTemplateSlopeModAngle(JNIEnv *env, jobject self, jlong mob); + jboolean JNICALL setSlopeModPercent(JNIEnv *env, jobject self, jlong mob, jfloat value); + jfloat JNICALL getSlopeModPercent(JNIEnv *env, jobject self, jlong mob); + jfloat JNICALL getTemplateSlopeModPercent(JNIEnv *env, jobject self, jlong mob); + jboolean JNICALL setWaterModPercent(JNIEnv *env, jobject self, jlong mob, jfloat value); + jfloat JNICALL getWaterModPercent(JNIEnv *env, jobject self, jlong mob); + jfloat JNICALL getTemplateWaterModPercent(JNIEnv *env, jobject self, jlong mob); + jboolean JNICALL setMovementPercent(JNIEnv *env, jobject self, jlong mob, jfloat value); + jfloat JNICALL getMovementPercent(JNIEnv *env, jobject self, jlong mob); + jboolean JNICALL setAccelPercent(JNIEnv *env, jobject self, jlong mob, jfloat value); + jfloat JNICALL getAccelPercent(JNIEnv *env, jobject self, jlong mob); + jboolean JNICALL monitorCreatureMovement(JNIEnv *env, jobject self, jlong mob, jlong target, jfloat skittishness, jfloat curve); + jboolean JNICALL ignoreCreatureMovement(JNIEnv *env, jobject self, jlong mob, jlong target); + jobject JNICALL getApproachSpeed(JNIEnv *env, jobject self, jlong i_mob, jobject i_mobDelta, jlong i_target, jobject i_targetDelta, jfloat i_time); + jfloat JNICALL getTargetBearing(JNIEnv *env, jobject self, jlong i_mob, jlong i_target); + void JNICALL warpPlayerCellId(JNIEnv *env, jobject self, jlong player, jstring scene, jfloat x_w, jfloat y_w, jfloat z_w, jlong cell, jfloat x_p, jfloat y_p, jfloat z_p, jstring callback, jboolean forceLoadScreen); + void JNICALL warpPlayerCellName(JNIEnv *env, jobject self, jlong player, jstring scene, jfloat x_w, jfloat y_w, jfloat z_w, jlong building, jstring cell, jfloat x_p, jfloat y_p, jfloat z_p, jstring callback, jboolean forceLoadScreen); + void JNICALL disconnectPlayer(JNIEnv *env, jobject self, jlong player); + jboolean JNICALL isPlayerConnected(JNIEnv *env, jobject self, jlong player); + jobject JNICALL getConnectedPlayerLocation(JNIEnv * env, jobject self, jlong player); + jboolean JNICALL isPlayerActive(JNIEnv *env, jobject self, jlong player); + void JNICALL addLocationTarget(JNIEnv * env, jobject self, jlong target, jstring name, jobject location, jfloat radius, jboolean is3d); + void JNICALL removeLocationTarget(JNIEnv * env, jobject self, jlong target, jstring name); + void JNICALL sendPlayerToTutorial(JNIEnv * env, jobject self, jlong player); + void JNICALL addPassiveReveal(JNIEnv * env, jobject self, jlong object, jlong target, jint range); + void JNICALL removePassiveReveal(JNIEnv * env, jobject self, jlong object, jlong target); + void JNICALL clearPassiveRevealList(JNIEnv * env, jobject self, jlong object); + jint JNICALL getPassiveRevealRange(JNIEnv * env, jobject self, jlong object, jlong target); + jobject JNICALL getPassiveRevealList(JNIEnv * env, jobject self, jlong object); + void JNICALL requestSendPositionUpdate(JNIEnv * env, jobject self, jlong object); +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsObjectMoveNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsObjectMoveNamespace::c)} + JF("_setLocation", "(JLscript/location;)Z", setLocationFromPos), + JF("_setLocation", "(JJ)Z", setLocationFromObj), + JF("_getLocation", "(J)Lscript/location;", getLocation), + JF("_getWorldLocation", "(J)Lscript/location;", getWorldLocation), + JF("_getHeading", "(J)Lscript/location;", getHeading), + JF("_getTransform_o2w", "(J)Lscript/transform;", getTransform_o2w), + JF("_getTransform_o2p", "(J)Lscript/transform;", getTransform_o2p), + JF("_getAttachedTo", "(J)J", getAttachedTo), + JF("_setTransform_o2p", "(JLscript/transform;)V", setTransform_o2p), + JF("_faceTo", "(JJ)Z", faceToObj), + JF("_faceTo", "(JLscript/location;)Z", faceToPos), + JF("_faceToBehavior", "(JJ)Z", faceToBehavior), + JF("_elevatorMove", "(JI)I", elevatorMove), + JF("_getMovementSpeed", "(J)F", getMovementSpeed), + JF("_getWalkSpeed", "(J)F", getWalkSpeed), + JF("_getRunSpeed", "(J)F", getRunSpeed), + JF("_setClientUsesAnimationLocomotion", "(JZ)V", setClientUsesAnimationLocomotion), + JF("_setBaseWalkSpeed", "(JF)V", setBaseWalkSpeed), + JF("_getBaseWalkSpeed", "(J)F", getBaseWalkSpeed), + JF("_setBaseRunSpeed", "(JF)V", setBaseRunSpeed), + JF("_getBaseRunSpeed", "(J)F", getBaseRunSpeed), + JF("_setMovementWalk", "(J)V", setMovementWalk), + JF("_setMovementRun", "(J)V", setMovementRun), + JF("_hideFromClient", "(JZ)V", hideFromClient), + JF("_stopFloating", "(J)Z", stopFloating), + JF("_setFloatingTime", "(JI)Z", setFloatingTime), + JF("_getYaw", "(J)F", getYaw), + JF("_setYaw", "(JF)Z", setYaw), + JF("_modifyYaw", "(JF)V", modifyYaw), + JF("_modifyPitch", "(JF)V", modifyPitch), + JF("_modifyRoll", "(JF)V", modifyRoll), + JF("_getQuaternion", "(J)[F", getQuaternion), + JF("_setQuaternion", "(JFFFF)V", setQuaternion), + JF("_getFurnitureRotationDegree", "(J)I", getFurnitureRotationDegree), + JF("_saveDecorationLayout", "(JJILjava/lang/String;)V", saveDecorationLayout), + JF("_restoreDecorationLayout", "(JJI)V", restoreDecorationLayout), + JF("_setSlopeModAngle", "(JF)Z", setSlopeModAngle), + JF("_getSlopeModAngle", "(J)F",getSlopeModAngle), + JF("_getTemplateSlopeModAngle", "(J)F",getTemplateSlopeModAngle), + JF("_setSlopeModPercent", "(JF)Z", setSlopeModPercent), + JF("_getSlopeModPercent", "(J)F",getSlopeModPercent), + JF("_getTemplateSlopeModPercent", "(J)F",getTemplateSlopeModPercent), + JF("_setWaterModPercent", "(JF)Z", setWaterModPercent), + JF("_getWaterModPercent", "(J)F",getWaterModPercent), + JF("_getTemplateWaterModPercent", "(J)F",getTemplateWaterModPercent), + JF("_setMovementPercent", "(JF)Z", setMovementPercent), + JF("_getMovementPercent", "(J)F",getMovementPercent), + JF("_setAccelPercent", "(JF)Z", setAccelPercent), + JF("_getAccelPercent", "(J)F",getAccelPercent), + JF("__addLocationTarget", "(JLjava/lang/String;Lscript/location;FZ)V", addLocationTarget), + JF("__removeLocationTarget", "(JLjava/lang/String;)V", removeLocationTarget), + JF("_monitorCreatureMovement", "(JJFF)Z", monitorCreatureMovement), + JF("_ignoreCreatureMovement", "(JJ)Z", ignoreCreatureMovement), + JF("_getApproachSpeed", "(JLscript/location;JLscript/location;F)Lscript/location;", getApproachSpeed), + JF("_getTargetBearing", "(JJ)F", getTargetBearing), + JF("_warpPlayer", "(JLjava/lang/String;FFFJFFFLjava/lang/String;Z)V", warpPlayerCellId), + JF("_warpPlayer", "(JLjava/lang/String;FFFJLjava/lang/String;FFFLjava/lang/String;Z)V", warpPlayerCellName), + JF("_disconnectPlayer", "(J)V", disconnectPlayer), + JF("_isPlayerConnected", "(J)Z", isPlayerConnected), + JF("_getConnectedPlayerLocation", "(J)Lscript/dictionary;", getConnectedPlayerLocation), + JF("_isPlayerActive", "(J)Z", isPlayerActive), + JF("_sendPlayerToTutorial", "(J)V", sendPlayerToTutorial), + JF("_addPassiveReveal", "(JJI)V", addPassiveReveal), + JF("_removePassiveReveal", "(JJ)V", removePassiveReveal), + JF("_clearPassiveRevealList", "(J)V", clearPassiveRevealList), + JF("_getPassiveRevealRange", "(JJ)I", getPassiveRevealRange), + JF("_getPassiveRevealList", "(J)Lscript/dictionary;", getPassiveRevealList), + JF("_requestSendPositionUpdate", "(J)V", requestSendPositionUpdate), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +//======================================================================== +// helper functions +//======================================================================== + +/** + * Tests if an object can be moved. Throws a Java error if the object can't be + * moved. + * + * @param object the object to test + * + * @return true if the object can be moved, false if not + */ +bool ScriptMethodsObjectMoveNamespace::testInvalidObjectMove(const ServerObject * object) +{ + if (object->getCacheVersion() > 0 || object->getCellProperty() != NULL) + { + char buffer[1024]; + sprintf(buffer, "A script is trying to move object %s, which is a cached " + "or cell object", object->getNetworkId().getValueString().c_str()); + WARNING(true, (buffer)); + JavaLibrary::throwInternalScriptError(buffer); + return false; + } + return true; +} // testInvalidObjectMove + + +//======================================================================== +// class JavaLibrary JNI object location callback methods +//======================================================================== + +/** + * Sets an object's location in the world based on a world coordinate. + * + * @param env Java environment + * @param self class calling this function + * @param objectId object to move + * @param to where to move the object + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsObjectMoveNamespace::setLocationFromPos(JNIEnv *env, jobject self, jlong objectId, jobject to) +{ + UNREF(self); + + ServerObject * object = 0; + if (!JavaLibrary::getObject(objectId, object)) + return JNI_FALSE; + + if (!testInvalidObjectMove(object)) + return JNI_FALSE; + + Vector newPosition_p; + std::string sceneId; + NetworkId cell; + ScriptConversion::convert(to, newPosition_p, sceneId, cell); + + if (object->getSceneId() != sceneId) + { + // @todo: can we move the object to a different scene? + // no, we can't without having a world location specified + } + + if (cell == NetworkId::cms_invalid) + object->teleportObject(newPosition_p, NetworkId::cms_invalid, "", Vector(), ""); + else + { + CellObject *destCell = dynamic_cast(NetworkIdManager::getObjectById(cell)); + if (!destCell) + { + JavaLibrary::throwInternalScriptError("JavaLibrary::setLocationFromPos tried to teleport to a non-cell or unloaded cell"); + return JNI_FALSE; + } + Object *topmost = ContainerInterface::getTopmostContainer(*destCell); + object->teleportObject(topmost->getPosition_w(), cell, "", newPosition_p, ""); + } + + // fix any scene ids that may be incorrect - this was causing an issue with pack houses + object->setSceneIdOnThisAndContents(object->getSceneId()); + + return JNI_TRUE; +} // JavaLibrary::setLocationFromPos + +/** + * Sets an object's location in the world based on another object's position. + * + * @param env Java environment + * @param self class calling this function + * @param objectId object to move + * @param toId object to move our object to + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsObjectMoveNamespace::setLocationFromObj(JNIEnv *env, jobject self, jlong objectId, jlong toId) +{ + UNREF(self); + + ServerObject * object = 0; + ServerObject * toObject = 0; + if (!JavaLibrary::getObject(objectId, object) || !JavaLibrary::getObject(toId, toObject)) + return JNI_FALSE; + + if (!testInvalidObjectMove(object)) + return JNI_FALSE; + + Object *toCell = ContainerInterface::getContainedByObject(*toObject); + Object *topmost = ContainerInterface::getTopmostContainer(*toObject); + object->teleportObject(topmost->getPosition_w(), toCell ? toCell->getNetworkId() : NetworkId::cms_invalid, "", toObject->getPosition_p(), ""); + + // fix any scene ids that may be incorrect - this was causing an issue with pack houses + object->setSceneIdOnThisAndContents(object->getSceneId()); + + return JNI_TRUE; +} // JavaLibrary::setLocationFromObj + +/** + * Returns an object's location. + * + * @param env Java environment + * @param self class calling this function + * @param objectId object to get + * + * @return the object's location, or null on error + */ +jobject JNICALL ScriptMethodsObjectMoveNamespace::getLocation(JNIEnv *env, jobject self, jlong objectId) +{ + UNREF(self); + + ServerObject * object = 0; + if (!JavaLibrary::getObject(objectId, object)) + return 0; + + //-- Retrieve the object's cell. This is not necessarily the object's immediate container Object. + // (e.g. for mounts, the immediate Container is the mount). + NOT_NULL(object); + CellProperty const *const cellProperty = object->getParentCell(); + Object const *const cell = (cellProperty != NULL) ? &(cellProperty->getOwner()) : NULL; + + // Remember, just because we're not in a cell doesn't mean we're not contained by something else, + // particularly in the case of a rider mounted where the mount is in the world cell. + Vector const positionRelativeToCellOrWorld = (cell != NULL) ? object->getPosition_c() : + object->getPosition_w(); + NetworkId const &networkIdForCellOrWorld = (cell != NULL) ? cell->getNetworkId() : + NetworkId::cms_invalid; + + LocalRefPtr location; + if (!ScriptConversion::convert(positionRelativeToCellOrWorld, object->getSceneId(), + networkIdForCellOrWorld, location)) + { + return 0; + } + return location->getReturnValue(); +} // JavaLibrary::getLocation + +/** + * Returns an object's world location. + * + * @param env Java environment + * @param self class calling this function + * @param objectId object to get + * + * @return the object's world location, or null on error + */ +jobject JNICALL ScriptMethodsObjectMoveNamespace::getWorldLocation(JNIEnv *env, jobject self, jlong objectId) +{ + UNREF(self); + + ServerObject * object = 0; + if (!JavaLibrary::getObject(objectId, object)) + return 0; + + LocalRefPtr location; + if (!ScriptConversion::convert(object->getPosition_w(), object->getSceneId(), NetworkId::cms_invalid, location)) + { + return 0; + } + return location->getReturnValue(); +} // JavaLibrary::getWorldLocation + +/** + * Returns an object's heading. + * + * @param env Java environment + * @param self class calling this function + * @param objectId object to get + * + * @return the object's location, or null on error + */ +jobject JNICALL ScriptMethodsObjectMoveNamespace::getHeading(JNIEnv *env, jobject self, jlong objectId) +{ + UNREF(self); + + ServerObject * object = 0; + if (!JavaLibrary::getObject(objectId, object)) + return 0; + + const Object * cell = ContainerInterface::getContainedByObject(*object); + + LocalRefPtr location; + if (!ScriptConversion::convert(object->getObjectFrameK_p(), object->getSceneId(), + cell ? cell->getNetworkId() : NetworkId::cms_invalid, location)) + { + return 0; + } + + return location->getReturnValue(); +} // JavaLibrary::getLocation + +//======================================================================== + +jboolean JNICALL ScriptMethodsObjectMoveNamespace::stopFloating(JNIEnv *env, jobject self, jlong objectId) +{ + UNREF(self); + + ServerObject * object = 0; + if (!JavaLibrary::getObject(objectId, object)) return JNI_FALSE; + + CollisionProperty * collision = object->getCollisionProperty(); + if(!collision) return JNI_FALSE; + + Footprint * foot = collision->getFootprint(); + if(!foot) return JNI_FALSE; + + foot->stopFloating(); + + return JNI_TRUE; +} + +//======================================================================== + +jboolean JNICALL ScriptMethodsObjectMoveNamespace::setFloatingTime(JNIEnv *env, jobject self, jlong objectId, jint seconds ) +{ + UNREF(self); + + ServerObject * object = 0; + if (!JavaLibrary::getObject(objectId, object)) return JNI_FALSE; + + CollisionProperty * collision = object->getCollisionProperty(); + if(!collision) return JNI_FALSE; + + Footprint * foot = collision->getFootprint(); + if(!foot) return JNI_FALSE; + + foot->setFloatingTime(static_cast(seconds)); + + return JNI_TRUE; +} + +//======================================================================== +// class JavaLibrary JNI object movement callback methods +//======================================================================== + +/** + * Moves an object to face another object. + * + * @param env Java environment + * @param self class calling this function + * @param mob object to move + * @param target object to face our object to + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsObjectMoveNamespace::faceToObj(JNIEnv *env, jobject self, jlong mob, jlong target) +{ + UNREF(self); + + ServerObject * object = 0; + Object * targetObject = 0; + if (!JavaLibrary::getObject(mob, object) || !JavaLibrary::getObject(target, targetObject)) + return JNI_FALSE; + + if (!testInvalidObjectMove(object)) + return JNI_FALSE; + + object->lookAt_p(object->rotateTranslate_w2p(targetObject->getPosition_w ())); + return JNI_TRUE; +} + +/** + * Moves an object to face a position. + * + * @param env Java environment + * @param self class calling this function + * @param mob object to move + * @param target location to face our object to + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsObjectMoveNamespace::faceToPos(JNIEnv *env, jobject self, jlong mob, jobject target) +{ + UNREF(self); + + ServerObject * object = 0; + if (!JavaLibrary::getObject(mob, object)) + return JNI_FALSE; + + if (!testInvalidObjectMove(object)) + return JNI_FALSE; + + Vector location; + NetworkId cellId; + + if (ScriptConversion::convert(target,location,cellId)) + { + object->lookAt_p(location); + + return JNI_TRUE; + } + return JNI_FALSE; +} + +// ---------------------------------------------------------------------- +/** + * Puts an AI into the faceTo behavior - they'll stand in place and keep + * turning to face the target until you tell them to do something else + * + * @param env Java environment + * @param self class calling this function + * @param mob object to move + * @param target object to face our object to + * + * @return true on success, false on fail + */ + +jboolean JNICALL ScriptMethodsObjectMoveNamespace::faceToBehavior(JNIEnv *env, jobject self, jlong mob, jlong target) +{ + UNREF(self); + + ServerObject * object = 0; + Object * targetObject = 0; + if (!JavaLibrary::getObject(mob, object) || !JavaLibrary::getObject(target, targetObject)) + return JNI_FALSE; + + if (!testInvalidObjectMove(object)) + return JNI_FALSE; + + AICreatureController * controller = 0; + if (JavaLibrary::getObjectController(mob, object, controller)) + { + controller->faceTo(NetworkId(target)); + return JNI_TRUE; + } + else + { + return JNI_FALSE; + } +} + +// ---------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsObjectMoveNamespace::getYaw(JNIEnv *env, jobject self, jlong target) +{ + const ServerObject * object = NULL; + if (!JavaLibrary::getObject(target, object)) + return -1.0f; + + return convertRadiansToDegrees (object->getObjectFrameK_p ().theta ()); +} + +// ---------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsObjectMoveNamespace::setYaw(JNIEnv *env, jobject self, jlong target, jfloat yaw) +{ + PROFILER_AUTO_BLOCK_DEFINE("JavaLibrary::setYaw"); + ServerObject * object = NULL; + { + PROFILER_AUTO_BLOCK_DEFINE("JavaLibrary::setYaw::getObject"); + if (!JavaLibrary::getObject(target, object)) + { + return JNI_FALSE; + } + } + + { + PROFILER_AUTO_BLOCK_DEFINE("JavaLibrary::setYaw::testInvalidObjectMove"); + if (!testInvalidObjectMove(object)) + { + return JNI_FALSE; + } + } + + float radians = convertDegreesToRadians(yaw) - object->getObjectFrameK_p().theta(); + if (object->getClient()) + { + Transform t(object->getTransform_o2p()); + if (radians != 0.0f) + { + t.yaw_l(radians); + t.reorthonormalize(); + ServerController *controller = safe_cast(object->getController()); + ServerObject *destContainer = safe_cast(ContainerInterface::getContainedByObject(*object)); + controller->teleport(t, destContainer); + } + } + else + { + PROFILER_AUTO_BLOCK_DEFINE("JavaLibrary::setYaw::objectYaw"); + object->yaw_o(radians); + } + return JNI_TRUE; +} + +// ---------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectMoveNamespace::modifyYaw(JNIEnv *env, jobject self, jlong target, jfloat degrees) +{ + PROFILER_AUTO_BLOCK_DEFINE("JavaLibrary::modifyYaw"); + ServerObject * object = NULL; + { + PROFILER_AUTO_BLOCK_DEFINE("JavaLibrary::modifyYaw::getObject"); + if (!JavaLibrary::getObject(target, object)) + { + return; + } + } + + { + PROFILER_AUTO_BLOCK_DEFINE("JavaLibrary::modifyYaw::testInvalidObjectMove"); + if (!testInvalidObjectMove(object)) + { + return; + } + } + + float const radians = convertDegreesToRadians(degrees); + if (object->getClient()) + { + Transform t(object->getTransform_o2p()); + if (radians != 0.0f) + { + t.yaw_l(radians); + t.reorthonormalize(); + ServerController *controller = safe_cast(object->getController()); + ServerObject *destContainer = safe_cast(ContainerInterface::getContainedByObject(*object)); + controller->teleport(t, destContainer); + } + } + else + { + PROFILER_AUTO_BLOCK_DEFINE("JavaLibrary::modifyYaw::objectYaw"); + object->yaw_o(radians); + } +} + +// ---------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectMoveNamespace::modifyPitch(JNIEnv *env, jobject self, jlong target, jfloat degrees) +{ + PROFILER_AUTO_BLOCK_DEFINE("JavaLibrary::modifyPitch"); + ServerObject * object = NULL; + { + PROFILER_AUTO_BLOCK_DEFINE("JavaLibrary::modifyPitch::getObject"); + if (!JavaLibrary::getObject(target, object)) + { + return; + } + } + + { + PROFILER_AUTO_BLOCK_DEFINE("JavaLibrary::modifyPitch::testInvalidObjectMove"); + if (!testInvalidObjectMove(object)) + { + return; + } + } + + float const radians = convertDegreesToRadians(degrees); + if (object->getClient()) + { + Transform t(object->getTransform_o2p()); + if (radians != 0.0f) + { + t.pitch_l(radians); + t.reorthonormalize(); + ServerController *controller = safe_cast(object->getController()); + ServerObject *destContainer = safe_cast(ContainerInterface::getContainedByObject(*object)); + controller->teleport(t, destContainer); + } + } + else + { + PROFILER_AUTO_BLOCK_DEFINE("JavaLibrary::modifyPitch::objectPitch"); + object->pitch_o(radians); + } +} + +// ---------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectMoveNamespace::modifyRoll(JNIEnv *env, jobject self, jlong target, jfloat degrees) +{ + PROFILER_AUTO_BLOCK_DEFINE("JavaLibrary::modifyRoll"); + ServerObject * object = NULL; + { + PROFILER_AUTO_BLOCK_DEFINE("JavaLibrary::modifyRoll::getObject"); + if (!JavaLibrary::getObject(target, object)) + { + return; + } + } + + { + PROFILER_AUTO_BLOCK_DEFINE("JavaLibrary::modifyRoll::testInvalidObjectMove"); + if (!testInvalidObjectMove(object)) + { + return; + } + } + + float const radians = convertDegreesToRadians(degrees); + if (object->getClient()) + { + Transform t(object->getTransform_o2p()); + if (radians != 0.0f) + { + t.roll_l(radians); + t.reorthonormalize(); + ServerController *controller = safe_cast(object->getController()); + ServerObject *destContainer = safe_cast(ContainerInterface::getContainedByObject(*object)); + controller->teleport(t, destContainer); + } + } + else + { + PROFILER_AUTO_BLOCK_DEFINE("JavaLibrary::modifyRoll::objectRoll"); + object->roll_o(radians); + } +} + +// ---------------------------------------------------------------- + +jfloatArray JNICALL ScriptMethodsObjectMoveNamespace::getQuaternion(JNIEnv *env, jobject self, jlong target) +{ + PROFILER_AUTO_BLOCK_DEFINE("JavaLibrary::getQuaternion"); + ServerObject * object = NULL; + { + PROFILER_AUTO_BLOCK_DEFINE("JavaLibrary::getQuaternion::getObject"); + if (!JavaLibrary::getObject(target, object)) + { + return 0; + } + } + + Quaternion const q(object->getTransform_o2p()); + + LocalFloatArrayRefPtr valueArray = createNewFloatArray(static_cast(4)); + if (valueArray == LocalFloatArrayRef::cms_nullPtr) + { + return 0; + } + + jfloat value = static_cast(q.w); + setFloatArrayRegion(*valueArray, 0, 1, &value); + + value = static_cast(q.x); + setFloatArrayRegion(*valueArray, 1, 1, &value); + + value = static_cast(q.y); + setFloatArrayRegion(*valueArray, 2, 1, &value); + + value = static_cast(q.z); + setFloatArrayRegion(*valueArray, 3, 1, &value); + + return valueArray->getReturnValue(); +} + +// ---------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectMoveNamespace::setQuaternion(JNIEnv *env, jobject self, jlong target, jfloat qw, jfloat qx, jfloat qy, jfloat qz) +{ + PROFILER_AUTO_BLOCK_DEFINE("JavaLibrary::setQuaternion"); + ServerObject * object = NULL; + { + PROFILER_AUTO_BLOCK_DEFINE("JavaLibrary::setQuaternion::getObject"); + if (!JavaLibrary::getObject(target, object)) + { + return; + } + } + + Quaternion const q(static_cast(qw), static_cast(qx), static_cast(qy), static_cast(qz)); + Transform t; + q.getTransform(&t); + t.setPosition_p(object->getTransform_o2p().getPosition_p()); + + if (object->getClient()) + { + t.reorthonormalize(); + ServerController *controller = safe_cast(object->getController()); + ServerObject *destContainer = safe_cast(ContainerInterface::getContainedByObject(*object)); + controller->teleport(t, destContainer); + } + else + { + PROFILER_AUTO_BLOCK_DEFINE("JavaLibrary::setQuaternion::objectSetQuaternion"); + object->setTransform_o2p(t); + } +} + +// ---------------------------------------------------------------- + +jint JNICALL ScriptMethodsObjectMoveNamespace::getFurnitureRotationDegree(JNIEnv *env, jobject self, jlong player) +{ + PROFILER_AUTO_BLOCK_DEFINE("JavaLibrary::getFurnitureRotationDegree"); + ServerObject * object = NULL; + { + PROFILER_AUTO_BLOCK_DEFINE("JavaLibrary::getFurnitureRotationDegree::getObject"); + if (!JavaLibrary::getObject(player, object)) + { + return 90; + } + } + + if (object->getClient()) + return abs(object->getClient()->getFurnitureRotationDegree()); + + return 90; +} + +// ---------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectMoveNamespace::saveDecorationLayout(JNIEnv *env, jobject self, jlong player, jlong pob, jint saveSlotNumber, jstring description) +{ + CreatureObject * playerObject = NULL; + if (!JavaLibrary::getObject(player, playerObject) || !playerObject) + return; + + ServerObject const * pobObject = NULL; + if (!JavaLibrary::getObject(pob, pobObject) || !pobObject) + return; + + JavaStringParam localDescription(description); + std::string descriptionStr; + if (!JavaLibrary::convert(localDescription, descriptionStr)) + return; + + playerObject->saveDecorationLayout(*pobObject, saveSlotNumber, descriptionStr); +} + +// ---------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectMoveNamespace::restoreDecorationLayout(JNIEnv *env, jobject self, jlong player, jlong pob, jint saveSlotNumber) +{ + CreatureObject * playerObject = NULL; + if (!JavaLibrary::getObject(player, playerObject) || !playerObject) + return; + + ServerObject const * pobObject = NULL; + if (!JavaLibrary::getObject(pob, pobObject) || !pobObject) + return; + + playerObject->restoreDecorationLayout(*pobObject, saveSlotNumber); +} + +// ---------------------------------------------------------------- + +/** + * Sets the slope aversion for an object. This may cause a repath to take place. The aversion is calculated by adding the + * height delta times the aversion value to the actual distance. So a 5 meter edge with a 1 meter slope difference would + * be pathed as 6 meters with a 1 aversion factor. + * + * @param env Java environment + * @param self class calling this function + * @param objectId object to change the slope aversion + * @param value the aversion value. 0 is no aversion. + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsObjectMoveNamespace::setSlopeModAngle(JNIEnv *env, jobject self, jlong objectId, jfloat value) +{ + UNREF(self); + + CreatureObject * object = 0; + CreatureController * controller = 0; + if (!JavaLibrary::getObjectController(objectId, object, controller)) + return JNI_FALSE; + + return controller->setSlopeModAngle(value * PI / 180); +} + +/** + * Sets the slope aversion for an object. This may cause a repath to take place. The aversion is calculated by adding the + * height delta times the aversion value to the actual distance. So a 5 meter edge with a 1 meter slope difference would + * be pathed as 6 meters with a 1 aversion factor. + * + * @param env Java environment + * @param self class calling this function + * @param objectId object to change the slope aversion + * @param value the aversion value. 0 is no aversion. + * + * @return true on success, false on fail + */ +jfloat JNICALL ScriptMethodsObjectMoveNamespace::getSlopeModAngle(JNIEnv *env, jobject self, jlong objectId) +{ + UNREF(self); + + CreatureObject * object = 0; + if (!JavaLibrary::getObject(objectId, object)) + return 0.0f; + + return object->getSlopeModAngle() * 180 / PI; +} + +/** + * Sets the slope aversion for an object. This may cause a repath to take place. The aversion is calculated by adding the + * height delta times the aversion value to the actual distance. So a 5 meter edge with a 1 meter slope difference would + * be pathed as 6 meters with a 1 aversion factor. + * + * @param env Java environment + * @param self class calling this function + * @param objectId object to change the slope aversion + * @param value the aversion value. 0 is no aversion. + * + * @return true on success, false on fail + */ +jfloat JNICALL ScriptMethodsObjectMoveNamespace::getTemplateSlopeModAngle(JNIEnv *env, jobject self, jlong objectId) +{ + UNREF(self); + + CreatureObject * object = 0; + if (!JavaLibrary::getObject(objectId, object)) + return 0.0f; + + const SharedCreatureObjectTemplate * sharedTemplate = safe_cast(object->getSharedTemplate()); + + return sharedTemplate->getSlopeModAngle() * 180 / PI; +} + +/** + * Sets the slope aversion for an object. This may cause a repath to take place. The aversion is calculated by adding the + * height delta times the aversion value to the actual distance. So a 5 meter edge with a 1 meter slope difference would + * be pathed as 6 meters with a 1 aversion factor. + * + * @param env Java environment + * @param self class calling this function + * @param objectId object to change the slope aversion + * @param value the aversion value. 0 is no aversion. + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsObjectMoveNamespace::setWaterModPercent(JNIEnv *env, jobject self, jlong objectId, jfloat value) +{ + UNREF(self); + + CreatureObject * object = 0; + CreatureController * controller = 0; + if (!JavaLibrary::getObjectController(objectId, object, controller)) + return JNI_FALSE; + + return controller->setWaterModPercent(value); +} + +/** + * Sets the slope aversion for an object. This may cause a repath to take place. The aversion is calculated by adding the + * height delta times the aversion value to the actual distance. So a 5 meter edge with a 1 meter slope difference would + * be pathed as 6 meters with a 1 aversion factor. + * + * @param env Java environment + * @param self class calling this function + * @param objectId object to change the slope aversion + * @param value the aversion value. 0 is no aversion. + * + * @return true on success, false on fail + */ +jfloat JNICALL ScriptMethodsObjectMoveNamespace::getWaterModPercent(JNIEnv *env, jobject self, jlong objectId) +{ + UNREF(self); + + CreatureObject * object = 0; + if (!JavaLibrary::getObject(objectId, object)) + return 0.0f; + + return object->getWaterModPercent(); +} + +/** + * Sets the slope aversion for an object. This may cause a repath to take place. The aversion is calculated by adding the + * height delta times the aversion value to the actual distance. So a 5 meter edge with a 1 meter slope difference would + * be pathed as 6 meters with a 1 aversion factor. + * + * @param env Java environment + * @param self class calling this function + * @param objectId object to change the slope aversion + * @param value the aversion value. 0 is no aversion. + * + * @return true on success, false on fail + */ +jfloat JNICALL ScriptMethodsObjectMoveNamespace::getTemplateWaterModPercent(JNIEnv *env, jobject self, jlong objectId) +{ + UNREF(self); + + CreatureObject * object = 0; + if (!JavaLibrary::getObject(objectId, object)) + return 0.0f; + + const SharedCreatureObjectTemplate * sharedTemplate = safe_cast(object->getSharedTemplate()); + + return sharedTemplate->getWaterModPercent(); +} + +/** + * Sets the slope aversion for an object. This may cause a repath to take place. The aversion is calculated by adding the + * height delta times the aversion value to the actual distance. So a 5 meter edge with a 1 meter slope difference would + * be pathed as 6 meters with a 1 aversion factor. + * + * @param env Java environment + * @param self class calling this function + * @param objectId object to change the slope aversion + * @param value the aversion value. 0 is no aversion. + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsObjectMoveNamespace::setSlopeModPercent(JNIEnv *env, jobject self, jlong objectId, jfloat value) +{ + UNREF(self); + + CreatureObject * object = 0; + CreatureController * controller = 0; + if (!JavaLibrary::getObjectController(objectId, object, controller)) + return JNI_FALSE; + + return controller->setSlopeModPercent(value); +} + +/** + * Sets the slope aversion for an object. This may cause a repath to take place. The aversion is calculated by adding the + * height delta times the aversion value to the actual distance. So a 5 meter edge with a 1 meter slope difference would + * be pathed as 6 meters with a 1 aversion factor. + * + * @param env Java environment + * @param self class calling this function + * @param objectId object to change the slope aversion + * @param value the aversion value. 0 is no aversion. + * + * @return true on success, false on fail + */ +jfloat JNICALL ScriptMethodsObjectMoveNamespace::getSlopeModPercent(JNIEnv *env, jobject self, jlong objectId) +{ + UNREF(self); + + CreatureObject * object = 0; + if (!JavaLibrary::getObject(objectId, object)) + return 0.0f; + + return object->getSlopeModPercent(); +} + +/** + * Sets the slope aversion for an object. This may cause a repath to take place. The aversion is calculated by adding the + * height delta times the aversion value to the actual distance. So a 5 meter edge with a 1 meter slope difference would + * be pathed as 6 meters with a 1 aversion factor. + * + * @param env Java environment + * @param self class calling this function + * @param objectId object to change the slope aversion + * @param value the aversion value. 0 is no aversion. + * + * @return true on success, false on fail + */ +jfloat JNICALL ScriptMethodsObjectMoveNamespace::getTemplateSlopeModPercent(JNIEnv *env, jobject self, jlong objectId) +{ + UNREF(self); + + CreatureObject * object = 0; + if (!JavaLibrary::getObject(objectId, object)) + return 0.0f; + + const SharedCreatureObjectTemplate * sharedTemplate = safe_cast(object->getSharedTemplate()); + + return sharedTemplate->getSlopeModPercent(); +} + +jboolean JNICALL ScriptMethodsObjectMoveNamespace::setMovementPercent(JNIEnv *, jobject, jlong objectId, jfloat value) +{ + TangibleObject *tangibleTarget = 0; + if (JavaLibrary::getObject(objectId, tangibleTarget)) + { + if (tangibleTarget->asShipObject()) + return tangibleTarget->asShipObject()->setMovementPercent(value); + else if (tangibleTarget->asCreatureObject()) + return tangibleTarget->asCreatureObject()->setMovementPercent(value); + } + return static_cast(JNI_FALSE); +} + +jfloat JNICALL ScriptMethodsObjectMoveNamespace::getMovementPercent(JNIEnv *, jobject, jlong objectId) +{ + TangibleObject *tangibleTarget = 0; + if (JavaLibrary::getObject(objectId, tangibleTarget)) + { + if (tangibleTarget->asShipObject()) + return tangibleTarget->asShipObject()->getMovementPercent(); + else if (tangibleTarget->asCreatureObject()) + return tangibleTarget->asCreatureObject()->getMovementPercent(); + } + return 0.f; +} + +jboolean JNICALL ScriptMethodsObjectMoveNamespace::setAccelPercent(JNIEnv *env, jobject self, jlong objectId, jfloat value) +{ + UNREF(self); + + CreatureObject * object = 0; + CreatureController * controller = 0; + if (!JavaLibrary::getObjectController(objectId, object, controller)) + return JNI_FALSE; + + return controller->setAccelPercent(value); +} + +jfloat JNICALL ScriptMethodsObjectMoveNamespace::getAccelPercent(JNIEnv *env, jobject self, jlong objectId) +{ + UNREF(self); + + CreatureObject * object = 0; + if (!JavaLibrary::getObject(objectId, object)) + return 0.0f; + + return object->getAccelPercent(); +} + +//----------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectMoveNamespace::addLocationTarget(JNIEnv * env, jobject self, jlong target, jstring name, jobject location, jfloat radius, jboolean is3d) +{ + JavaStringParam localName(name); + + if(! self) + return; + if(!name) + return; + if(!location) + return; + + Vector pos; + if (ScriptConversion::convertWorld(location, pos)) + { + LocationData d; + // @todo : check scene id! + std::string s; + JavaStringPtr scene = getStringField(LocalRefParam(location), JavaLibrary::getFidLocationArea()); + if(JavaLibrary::convert(*scene, s)) + { + d.scene = s; + + // 3d location targets are denoted by y coordinates > 50k, with 100k added to them + // location targets with y coordinates less than 50k have their y coordinates ignored during comparisons. + if (is3d) + pos.y += 100000.0f; + d.location.setCenter(pos); + d.location.setRadius(radius); + Unicode::String n; + if(JavaLibrary::convert(localName, n)) + { + TangibleObject * t = 0; + d.name = n; + if(JavaLibrary::getObject(target, t)) + { + if(t) + { + if (testInvalidObjectMove(t)) + t->addLocationTarget(d); + } + } + } + } + } +} + +//----------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectMoveNamespace::removeLocationTarget(JNIEnv * env, jobject self, jlong target, jstring name) +{ + JavaStringParam localName(name); + + if(! self) + return; + if(! name) + return; + + Unicode::String n; + if(JavaLibrary::convert(localName, n)) + { + TangibleObject * t = 0; + if(JavaLibrary::getObject(target, t)) + { + if(t) + { + if (testInvalidObjectMove(t)) + t->removeLocationTarget(n); + } + } + } +} + +//----------------------------------------------------------------------- + +jint JNICALL ScriptMethodsObjectMoveNamespace::elevatorMove(JNIEnv *env, jobject self, jlong mob, jint nFloors ) +{ + UNREF(env); + UNREF(self); + + CreatureObject * creature = 0; + ServerController * controller = 0; + + if (JavaLibrary::getObjectController(mob, creature, controller)) + { + int movedFloors = controller->elevatorMove(static_cast(nFloors)); + + return static_cast(movedFloors); + } + + return 0; +} + + +jboolean JNICALL ScriptMethodsObjectMoveNamespace::monitorCreatureMovement(JNIEnv *env, jobject self, jlong mob, jlong target, jfloat skittishness, jfloat curve) +{ + UNREF(env); + UNREF(self); + + CreatureObject * creature = 0; + if (JavaLibrary::getObject(mob, creature)) + { + CachedNetworkId targetId(target); + if (!targetId) + return false; + return creature->monitorCreatureMovement(targetId, skittishness, curve); + } + return false; +} + +jboolean JNICALL ScriptMethodsObjectMoveNamespace::ignoreCreatureMovement(JNIEnv *env, jobject self, jlong mob, jlong target) +{ + UNREF(env); + UNREF(self); + + CreatureObject * creature = 0; + if (JavaLibrary::getObject(mob, creature)) + { + CachedNetworkId targetId(target); + if (targetId == NetworkId::cms_invalid) + return false; + return creature->ignoreCreatureMovement(targetId); + } + return false; +} + +jobject JNICALL ScriptMethodsObjectMoveNamespace::getApproachSpeed(JNIEnv *env, jobject self, jlong i_mob, jobject i_mobDelta, jlong i_target, jobject i_targetDelta, jfloat i_time) +{ + UNREF(env); + UNREF(self); + + Vector resultVector(Vector::zero); + + CreatureObject * mob = 0; + Vector mobDelta; + NetworkId mobCell; + CreatureObject * target = 0; + Vector targetDelta; + NetworkId targetCell; + if (i_time > 0 && JavaLibrary::getObject(i_mob, mob) && ScriptConversion::convert(i_mobDelta, mobDelta, mobCell) && + JavaLibrary::getObject(i_target, target) && ScriptConversion::convert(i_targetDelta, targetDelta, targetCell)) + { + Vector mobPosition = mob->getPosition_w(); + Vector targetPosition = target->getPosition_w(); + float originalDistance = (targetPosition - targetDelta).magnitudeBetween(mobPosition - mobDelta); + float currentDistance = targetPosition.magnitudeBetween(mobPosition); + float approachVelocity = (originalDistance - currentDistance) / i_time; + float tangentVelocity = sqrt(((mobDelta - targetDelta)/i_time).magnitudeSquared() - approachVelocity * approachVelocity); + resultVector.x = approachVelocity; + resultVector.y = tangentVelocity; + resultVector.z = currentDistance; + } + + LocalRefPtr result; + if (!ScriptConversion::convert(resultVector, NetworkId::cms_invalid, result)) + return 0; + return result->getReturnValue(); +} + +jfloat JNICALL ScriptMethodsObjectMoveNamespace::getTargetBearing(JNIEnv *env, jobject self, jlong i_mob, jlong i_target) +{ + UNREF(env); + UNREF(self); + + ServerObject * mob = 0; + ServerObject * target = 0; + float result=0; + if (JavaLibrary::getObject(i_mob, mob) && JavaLibrary::getObject(i_target, target)) + { + Vector localPosition = mob->rotateTranslate_w2o(target->getPosition_w()); + result = float(atan2(localPosition.x, localPosition.z)) * 180 / PI; + } + return result; +} + +void JNICALL ScriptMethodsObjectMoveNamespace::warpPlayerCellId(JNIEnv *env, jobject self, jlong player, jstring scene, jfloat x_w, jfloat y_w, jfloat z_w, jlong cell, jfloat x_p, jfloat y_p, jfloat z_p, jstring callback, jboolean forceLoadScreen) +{ + ServerObject *playerObject = 0; + if (!JavaLibrary::getObject(player, playerObject)) + return; + + JavaStringParam localScene(scene); + std::string sceneName; + if (!JavaLibrary::convert(localScene, sceneName)) + return; + + std::string callbackName; + + if (callback) + { + JavaStringParam localCallback(callback); + if (!JavaLibrary::convert(localCallback, callbackName)) + return; + } + + NetworkId cellId(cell); + GameServer::getInstance().requestSceneWarp( + CachedNetworkId(*playerObject), + sceneName, + Vector(x_w, y_w, z_w), + cellId, + Vector(x_p, y_p, z_p), + callbackName.c_str(), + forceLoadScreen); +} + +void JNICALL ScriptMethodsObjectMoveNamespace::warpPlayerCellName(JNIEnv *env, jobject self, jlong player, jstring scene, jfloat x_w, jfloat y_w, jfloat z_w, jlong building, jstring cell, jfloat x_p, jfloat y_p, jfloat z_p, jstring callback, jboolean forceLoadScreen) +{ + ServerObject *playerObject = 0; + if (!JavaLibrary::getObject(player, playerObject)) + return; + + JavaStringParam localScene(scene); + std::string sceneName; + if (!JavaLibrary::convert(localScene, sceneName)) + return; + + JavaStringParam localCell(cell); + std::string cellName; + if (!JavaLibrary::convert(localCell, cellName)) + return; + + NetworkId buildingId(building); + if (buildingId == NetworkId::cms_invalid) + return; + + std::string callbackName; + if (callback) + { + JavaStringParam localCallback(callback); + if (!JavaLibrary::convert(localCallback, callbackName)) + return; + } + + GameServer::getInstance().requestSceneWarp( + CachedNetworkId(*playerObject), + sceneName, + Vector(x_w, y_w, z_w), + buildingId, + cellName, + Vector(x_p, y_p, z_p), + callbackName.c_str(), + forceLoadScreen); +} + +void JNICALL ScriptMethodsObjectMoveNamespace::disconnectPlayer(JNIEnv *env, jobject self, jlong player) +{ + CreatureObject * playerCreature = 0; + if (JavaLibrary::getObject(player, playerCreature)) + playerCreature->disconnect(); +} + +jboolean JNICALL ScriptMethodsObjectMoveNamespace::isPlayerConnected(JNIEnv *env, jobject self, jlong player) +{ + CreatureObject const * playerCreature = 0; + if (JavaLibrary::getObject(player, playerCreature) && playerCreature) + { + PlayerObject const * const playerPlayer = PlayerCreatureController::getPlayerObject(playerCreature); + if (playerPlayer && (playerPlayer->getSessionStartPlayTime() != 0)) + { + return JNI_TRUE; + } + else + { + return JNI_FALSE; + } + } + + // player may be on a different game server, check the cluster wide LFG data + if (ServerUniverse::getConnectedCharacterLfgData().count(NetworkId(static_cast(player))) > 0) + return JNI_TRUE; + + return JNI_FALSE; +} + +jobject JNICALL ScriptMethodsObjectMoveNamespace::getConnectedPlayerLocation(JNIEnv * env, jobject self, jlong player) +{ + std::map const & connectedCharacterLfgData = ServerUniverse::getConnectedCharacterLfgData(); + std::map::const_iterator const iterFind = connectedCharacterLfgData.find(NetworkId(static_cast(player))); + if (iterFind == connectedCharacterLfgData.end()) + return NULL; + + LocalRefPtr dictionary = createNewObject(JavaLibrary::getClsDictionary(), JavaLibrary::getMidDictionary()); + if (dictionary == LocalRef::cms_nullPtr) + return NULL; + + callObjectMethod(*dictionary, JavaLibrary::getMidDictionaryPut(), JavaString("planet").getValue(), JavaString(iterFind->second.locationPlanet).getValue()); + + if (!iterFind->second.locationRegion.empty()) + callObjectMethod(*dictionary, JavaLibrary::getMidDictionaryPut(), JavaString("region").getValue(), JavaString(iterFind->second.locationRegion).getValue()); + + if (!iterFind->second.locationPlayerCity.empty()) + callObjectMethod(*dictionary, JavaLibrary::getMidDictionaryPut(), JavaString("playerCity").getValue(), JavaString(iterFind->second.locationPlayerCity).getValue()); + + if (env->ExceptionCheck()) + { + env->ExceptionDescribe(); + return 0; + } + + return dictionary->getReturnValue(); +} + +jboolean JNICALL ScriptMethodsObjectMoveNamespace::isPlayerActive(JNIEnv *env, jobject self, jlong player) +{ + CreatureObject const * playerCreature = 0; + if (JavaLibrary::getObject(player, playerCreature) && playerCreature) + { + PlayerObject const * const playerPlayer = PlayerCreatureController::getPlayerObject(playerCreature); + if (playerPlayer && (playerPlayer->getSessionLastActiveTime() != 0)) + { + return JNI_TRUE; + } + else + { + return JNI_FALSE; + } + } + + // player may be on a different game server, check the cluster wide LFG data + std::map const & connectedCharacterLfgData = ServerUniverse::getConnectedCharacterLfgData(); + std::map::const_iterator iter = connectedCharacterLfgData.find(NetworkId(static_cast(player))); + if ((iter != connectedCharacterLfgData.end()) && iter->second.active) + return JNI_TRUE; + + return JNI_FALSE; +} + +// ---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsObjectMoveNamespace::getMovementSpeed(JNIEnv * /*env*/, jobject /*self*/, jlong object) +{ + NetworkId const networkId(object); + CreatureController * const creatureController = CreatureController::getCreatureController(networkId); + + return (creatureController != NULL) ? creatureController->getCurrentVelocity().magnitude() : 0.0f; +} + +// ---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsObjectMoveNamespace::getWalkSpeed(JNIEnv * /*env*/, jobject /*self*/, jlong object) +{ + NetworkId const networkId(object); + CreatureObject * const creatureObject = CreatureObject::getCreatureObject(networkId); + + return (creatureObject != NULL) ? creatureObject->getWalkSpeed() : 0.0f; +} + +// ---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsObjectMoveNamespace::getRunSpeed(JNIEnv * /*env*/, jobject /*self*/, jlong object) +{ + NetworkId const networkId(object); + CreatureObject * const creatureObject = CreatureObject::getCreatureObject(networkId); + + return (creatureObject != NULL) ? creatureObject->getRunSpeed() : 0.0f; +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectMoveNamespace::setBaseWalkSpeed(JNIEnv * /*env*/, jobject /*self*/, jlong object, jfloat speed) +{ + NetworkId const networkId(object); + CreatureObject * const creatureObject = CreatureObject::getCreatureObject(networkId); + + if (creatureObject == NULL) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsObjectMove::setBaseWalkSpeed() Unable to resolve the object(%s) to a CreatureObject.", networkId.getValueString().c_str())); + return; + } + + LOGC(ConfigServerGame::isAiLoggingEnabled(), "debug_ai", ("ScriptMethodsObjectMove::setBaseWalkSpeed() object(%s) speed(%.2f)", networkId.getValueString().c_str(), speed)); + + creatureObject->setBaseWalkSpeed(speed); +} + +// ---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsObjectMoveNamespace::getBaseWalkSpeed(JNIEnv * /*env*/, jobject /*self*/, jlong object) +{ + NetworkId const networkId(object); + CreatureObject * const creatureObject = CreatureObject::getCreatureObject(networkId); + + return (creatureObject != NULL) ? creatureObject->getBaseWalkSpeed() : 0.0f; +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectMoveNamespace::setBaseRunSpeed(JNIEnv * /*env*/, jobject /*self*/, jlong object, jfloat speed) +{ + NetworkId const networkId(object); + CreatureObject * const creatureObject = CreatureObject::getCreatureObject(networkId); + + if (creatureObject == NULL) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsObjectMove::setBaseRunSpeed() Unable to resolve the object(%s) to a CreatureObject.", networkId.getValueString().c_str())); + return; + } + + LOGC(ConfigServerGame::isAiLoggingEnabled(), "debug_ai", ("ScriptMethodsObjectMove::setBaseRunSpeed() object(%s) speed(%.2f)", networkId.getValueString().c_str(), speed)); + + creatureObject->setBaseRunSpeed(speed); +} + +// ---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsObjectMoveNamespace::getBaseRunSpeed(JNIEnv * /*env*/, jobject /*self*/, jlong object) +{ + NetworkId const networkId(object); + CreatureObject * const creatureObject = CreatureObject::getCreatureObject(networkId); + + return (creatureObject != NULL) ? creatureObject->getBaseRunSpeed() : 0.0f; +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectMoveNamespace::setMovementWalk(JNIEnv * /*env*/, jobject /*self*/, jlong object) +{ + NetworkId const networkId(object); + CreatureObject * const creatureObject = CreatureObject::getCreatureObject(networkId); + + if (creatureObject == NULL) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsObjectMove::setMovementWalk() Unable to resolve the object(%s) to a CreatureObject.", networkId.getValueString().c_str())); + return; + } + + AICreatureController * const aiCreatureController = AICreatureController::asAiCreatureController(creatureObject->getController()); + + if (aiCreatureController == NULL) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsObjectMove::setMovementWalk() Unable to resolve the object's(%s) controller to an AiCreatureController.", creatureObject->getDebugInformation().c_str())); + return; + } + + LOGC(ConfigServerGame::isAiLoggingEnabled(), "debug_ai", ("ScriptMethodsObjectMove::setMovementWalk() object(%s)", networkId.getValueString().c_str())); + + aiCreatureController->setMovementWalk(); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectMoveNamespace::setMovementRun(JNIEnv * /*env*/, jobject /*self*/, jlong object) +{ + NetworkId const networkId(object); + CreatureObject * const creatureObject = CreatureObject::getCreatureObject(networkId); + + if (creatureObject == NULL) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsObjectMove::setMovementRun() Unable to resolve the object(%s) to a CreatureObject.", networkId.getValueString().c_str())); + return; + } + + AICreatureController * const aiCreatureController = AICreatureController::asAiCreatureController(creatureObject->getController()); + + if (aiCreatureController == NULL) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsObjectMove::setMovementRun() Unable to resolve the object's(%s) controller to an AiCreatureController.", creatureObject->getDebugInformation().c_str())); + return; + } + + LOGC(ConfigServerGame::isAiLoggingEnabled(), "debug_ai", ("ScriptMethodsObjectMove::setMovementRun() object(%s)", networkId.getValueString().c_str())); + + aiCreatureController->setMovementRun(); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectMoveNamespace::hideFromClient(JNIEnv *env, jobject self, jlong target, jboolean hide) +{ + TangibleObject * tangibleObject = 0; + if (JavaLibrary::getObject(target, tangibleObject)) + tangibleObject->setHidden(hide); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectMoveNamespace::setClientUsesAnimationLocomotion(JNIEnv *env, jobject self, jlong target, jboolean enabled) +{ + CreatureObject * creature = 0; + if (JavaLibrary::getObject(target, creature)) + { + if (creature->isAuthoritative()) + { + creature->setClientUsesAnimationLocomotion(enabled); + return; + } + } +} + +// ---------------------------------------------------------------------- + +jobject JNICALL ScriptMethodsObjectMoveNamespace::getTransform_o2w(JNIEnv *env, jobject self, jlong objectId) +{ + ServerObject *object = 0; + if (!JavaLibrary::getObject(objectId, object)) + { + JavaLibrary::throwInternalScriptError("JavaLibrary::getTransform_o2w could not resolve object"); + return 0; + } + + LocalRefPtr transform; + if (ScriptConversion::convert(object->getTransform_o2w(), transform)) + return transform->getReturnValue(); + return 0; +} + +// ---------------------------------------------------------------------- + +jobject JNICALL ScriptMethodsObjectMoveNamespace::getTransform_o2p(JNIEnv *env, jobject self, jlong objectId) +{ + ServerObject *object = 0; + if (!JavaLibrary::getObject(objectId, object)) + JavaLibrary::throwInternalScriptError("JavaLibrary::getTransform_o2p could not resolve object"); + else + { + LocalRefPtr transform; + if (ScriptConversion::convert(object->getTransform_o2p(), transform)) + return transform->getReturnValue(); + } + return 0; +} + +// ---------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsObjectMoveNamespace::getAttachedTo(JNIEnv *env, jobject self, jlong objectId) +{ + ServerObject *object = 0; + if (!JavaLibrary::getObject(objectId, object)) + JavaLibrary::throwInternalScriptError("JavaLibrary::getAttachedTo could not resolve object"); + else + { + Object *attachedTo = object->getAttachedTo(); + if (attachedTo) + return (attachedTo->getNetworkId()).getValue(); + } + return 0; +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectMoveNamespace::setTransform_o2p(JNIEnv *env, jobject self, jlong objectId, jobject transform) +{ + ServerObject *object = 0; + if (!JavaLibrary::getObject(objectId, object)) + JavaLibrary::throwInternalScriptError("JavaLibrary::setTransform_o2p could not resolve object"); + else if (testInvalidObjectMove(object)) + { + Transform newTransform; + ScriptConversion::convert(transform, newTransform); + safe_cast(object->getController())->teleport(newTransform, safe_cast(object->getAttachedTo())); + } +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectMoveNamespace::sendPlayerToTutorial(JNIEnv *env, jobject self, jlong player) +{ + CreatureObject *playerObject = 0; + if (!JavaLibrary::getObject(player, playerObject)) + return; + + NewbieTutorial::setupCharacterForTutorial(playerObject); + GameServer::getInstance().requestSceneWarp(CachedNetworkId(*playerObject), NewbieTutorial::getSceneId(), NewbieTutorial::getTutorialLocation(), NetworkId::cms_invalid, Vector(0,0,0)); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectMoveNamespace::addPassiveReveal(JNIEnv * env, jobject self, jlong object, jlong target, jint range) +{ + TangibleObject * toObject = 0; + if (!JavaLibrary::getObject(object, toObject)) + return; + + TangibleObject * toTarget = 0; + if (!JavaLibrary::getObject(target, toTarget)) + return; + + toObject->addPassiveReveal(*toTarget, range); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectMoveNamespace::removePassiveReveal(JNIEnv * env, jobject self, jlong object, jlong target) +{ + TangibleObject * toObject = 0; + if (!JavaLibrary::getObject(object, toObject)) + return; + + toObject->removePassiveReveal(NetworkId(static_cast(target))); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectMoveNamespace::clearPassiveRevealList(JNIEnv * env, jobject self, jlong object) +{ + TangibleObject * toObject = 0; + if (!JavaLibrary::getObject(object, toObject)) + return; + + toObject->removeAllPassiveReveal(); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsObjectMoveNamespace::getPassiveRevealRange(JNIEnv * env, jobject self, jlong object, jlong target) +{ + TangibleObject * toObject = 0; + if (!JavaLibrary::getObject(object, toObject)) + return -1; + + return toObject->getPassiveRevealRange(NetworkId(static_cast(target))); +} + +// ---------------------------------------------------------------------- + +jobject JNICALL ScriptMethodsObjectMoveNamespace::getPassiveRevealList(JNIEnv * env, jobject self, jlong object) +{ + TangibleObject * toObject = 0; + if (!JavaLibrary::getObject(object, toObject)) + return 0; + + std::map const & passiveReveal = toObject->getPassiveReveal(); + if (passiveReveal.empty()) + return 0; + + // params (see below) will be responsible for destructing these + std::vector * id = new std::vector; + std::vector * range = new std::vector; + + for (std::map::const_iterator iter = passiveReveal.begin(); iter != passiveReveal.end(); ++iter) + { + id->push_back(iter->first); + range->push_back(iter->second); + } + + ScriptParams params; + params.addParam(*id, "id", true); + params.addParam(*range, "range", true); + + JavaDictionaryPtr dictionary; + JavaLibrary::instance()->convert(params, dictionary); + return dictionary->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsObjectMoveNamespace::requestSendPositionUpdate(JNIEnv * env, jobject self, jlong object) +{ + ServerObject * soObject = 0; + if (!JavaLibrary::getObject(object, soObject)) + return; + + PositionUpdateTracker::positionChanged(*soObject); +} + +// ====================================================================== diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsPermissions.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsPermissions.cpp new file mode 100644 index 00000000..732a9f6d --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsPermissions.cpp @@ -0,0 +1,446 @@ +// ====================================================================== +// +// ScriptMethodsPermissions.cpp - implements script methods dealing with +// cell and building permissions +// +// Copyright 2002 Sony Online Entertainment +// +// ====================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" +#include "serverGame/BuildingObject.h" +#include "serverGame/CellObject.h" +#include "serverGame/ContainerInterface.h" +#include "serverGame/CreatureObject.h" + +using namespace JNIWrappersNamespace; + + +// ====================================================================== +// ScriptMethodsPermissionsNamespace +// ====================================================================== + +namespace ScriptMethodsPermissionsNamespace +{ + bool install(); + + jobjectArray JNICALL permissionsGetBanned(JNIEnv *env, jobject self, jlong target); + jobjectArray JNICALL permissionsGetAllowed(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL permissionsIsPublic(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL permissionsIsAllowed(JNIEnv *env, jobject self, jlong target, jlong who); + void JNICALL permissionsAddAllowed(JNIEnv *env, jobject self, jlong target, jstring name); + void JNICALL permissionsRemoveAllAllowed(JNIEnv *env, jobject self, jlong target); + void JNICALL permissionsRemoveAllowed(JNIEnv *env, jobject self, jlong target, jstring name); + void JNICALL permissionsAddBanned(JNIEnv *env, jobject self, jlong target, jstring name); + void JNICALL permissionsRemoveBanned(JNIEnv *env, jobject self, jlong target, jstring name); + void JNICALL permissionsRemoveAllBanned(JNIEnv *env, jobject self, jlong target); + void JNICALL permissionsMakePublic(JNIEnv *env, jobject self, jlong target); + void JNICALL permissionsMakePrivate(JNIEnv *env, jobject self, jlong target); + void JNICALL expelFromBuilding(JNIEnv *env, jobject self, jlong target); +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsPermissionsNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsPermissionsNamespace::c)} + JF("_permissionsGetBanned", "(J)[Ljava/lang/String;", permissionsGetBanned), + JF("_permissionsGetAllowed", "(J)[Ljava/lang/String;", permissionsGetAllowed), + JF("_permissionsIsPublic", "(J)Z", permissionsIsPublic), + JF("_permissionsIsAllowed", "(JJ)Z", permissionsIsAllowed), + JF("_permissionsAddAllowed", "(JLjava/lang/String;)V", permissionsAddAllowed), + JF("_permissionsRemoveAllowed", "(JLjava/lang/String;)V", permissionsRemoveAllowed), + JF("_permissionsRemoveAllAllowed", "(J)V", permissionsRemoveAllAllowed), + JF("_permissionsAddBanned", "(JLjava/lang/String;)V", permissionsAddBanned), + JF("_permissionsRemoveBanned", "(JLjava/lang/String;)V", permissionsRemoveBanned), + JF("_permissionsRemoveAllBanned", "(J)V", permissionsRemoveAllBanned), + JF("_permissionsMakePublic", "(J)V", permissionsMakePublic), + JF("_permissionsMakePrivate", "(J)V", permissionsMakePrivate), + JF("_expelFromBuilding", "(J)V", expelFromBuilding), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +// ====================================================================== +// class JavaLibrary JNI command table methods +// ====================================================================== + +/** + * Get the banned list for a cell or building + * + * @param env Java Environment + * @param self class calling this function + * @param target the cell or building to get permissions for + * + * @return the banned list + */ +jobjectArray JNICALL ScriptMethodsPermissionsNamespace::permissionsGetBanned(JNIEnv *env, jobject self, jlong target) +{ + ServerObject *serverObj = 0; + if (!JavaLibrary::getObject(target, serverObj)) + return NULL; + + LocalObjectArrayRefPtr strArray; + BuildingObject *buildingObj = dynamic_cast(serverObj); + if (buildingObj) + if (ScriptConversion::convert(buildingObj->getBanned(), strArray)) + return strArray->getReturnValue(); + CellObject *cellObj = dynamic_cast(serverObj); + if (cellObj) + if (ScriptConversion::convert(cellObj->getBanned(), strArray)) + return strArray->getReturnValue(); + return NULL; +} + +// ---------------------------------------------------------------------- + +/** + * Get the allowed list for a cell or building + * + * @param env Java Environment + * @param self class calling this function + * @param target the cell or building to get permissions for + * + * @return the allowed list + */ +jobjectArray JNICALL ScriptMethodsPermissionsNamespace::permissionsGetAllowed(JNIEnv *env, jobject self, jlong target) +{ + ServerObject *serverObj = 0; + if (!JavaLibrary::getObject(target, serverObj)) + return NULL; + + LocalObjectArrayRefPtr strArray; + BuildingObject *buildingObj = dynamic_cast(serverObj); + if (buildingObj) + if (ScriptConversion::convert(buildingObj->getAllowed(), strArray)) + return strArray->getReturnValue(); + CellObject *cellObj = dynamic_cast(serverObj); + if (cellObj) + if (ScriptConversion::convert(cellObj->getAllowed(), strArray)) + return strArray->getReturnValue(); + return NULL; +} + +// ---------------------------------------------------------------------- + +/** + * Get whether a cell or building is public + * + * @param env Java Environment + * @param self class calling this function + * @param target the cell or building to get permissions for + * + * @return true if public, false if not found or private + */ +jboolean JNICALL ScriptMethodsPermissionsNamespace::permissionsIsPublic(JNIEnv *env, jobject self, jlong target) +{ + ServerObject *serverObj = 0; + if (!JavaLibrary::getObject(target, serverObj)) + return JNI_FALSE; + + bool isPublic = false; + BuildingObject *buildingObj = dynamic_cast(serverObj); + if (buildingObj) + isPublic = buildingObj->getIsPublic(); + else + { + CellObject *cellObj = dynamic_cast(serverObj); + if (cellObj) + isPublic = cellObj->getIsPublic(); + } + + if (isPublic) + return JNI_TRUE; + return JNI_FALSE; +} + +// ---------------------------------------------------------------------- + +/** + * check if someone is allowed in a cell/building + * + * @param env Java Environment + * @param self class calling this function + * @param target the cell or building to test permissions on + * @param who the person to test permissions for + */ +jboolean JNICALL ScriptMethodsPermissionsNamespace::permissionsIsAllowed(JNIEnv *env, jobject self, jlong target, jlong who) +{ + CreatureObject *person = 0; + if (JavaLibrary::getObject(who, person)) + { + NetworkId buildingId(target); + if(buildingId == NetworkId::cms_invalid) + { + // target "building" is the world cell - permissions are always allowed + + return JNI_TRUE; + } + + ServerObject *serverObj = 0; + if (JavaLibrary::getObject(target, serverObj)) + { + BuildingObject *buildingObj = dynamic_cast(serverObj); + if (buildingObj) + { + if (buildingObj->isAllowed(*person)) + return JNI_TRUE; + } + else + { + CellObject *cellObj = dynamic_cast(serverObj); + if (cellObj && cellObj->isAllowed(*person)) + return JNI_TRUE; + } + } + } + return JNI_FALSE; +} + +// ---------------------------------------------------------------------- + +/** + * add someone to a cell or building's allowed list + * + * @param env Java Environment + * @param self class calling this function + * @param target the cell or building to set permissions for + * @param name name or id string to add to allowed list + */ +void JNICALL ScriptMethodsPermissionsNamespace::permissionsAddAllowed(JNIEnv *env, jobject self, jlong target, jstring name) +{ + JavaStringParam localName(name); + std::string strName; + if (!JavaLibrary::convert(localName, strName)) + return; + + ServerObject *serverObj = 0; + if (JavaLibrary::getObject(target, serverObj)) + { + BuildingObject *buildingObj = dynamic_cast(serverObj); + if (buildingObj) + buildingObj->addAllowed(strName); + else + { + CellObject *cellObj = dynamic_cast(serverObj); + if (cellObj) + cellObj->addAllowed(strName); + } + } +} + +// ---------------------------------------------------------------------- + +/** + * remove someone from a cell or building's allowed list + * + * @param env Java Environment + * @param self class calling this function + * @param target the cell or building to set permissions for + * @param name name or id string to remove from allowed list + */ +void JNICALL ScriptMethodsPermissionsNamespace::permissionsRemoveAllowed(JNIEnv *env, jobject self, jlong target, jstring name) +{ + JavaStringParam localName(name); + std::string strName; + if (!JavaLibrary::convert(localName, strName)) + return; + + ServerObject *serverObj = 0; + if (JavaLibrary::getObject(target, serverObj)) + { + BuildingObject *buildingObj = dynamic_cast(serverObj); + if (buildingObj) + buildingObj->removeAllowed(strName); + else + { + CellObject *cellObj = dynamic_cast(serverObj); + if (cellObj) + cellObj->removeAllowed(strName); + } + } +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsPermissionsNamespace::permissionsRemoveAllAllowed(JNIEnv *env, jobject self, jlong target) +{ + ServerObject *serverObj = 0; + if (JavaLibrary::getObject(target, serverObj)) + { + BuildingObject *buildingObj = dynamic_cast(serverObj); + if (buildingObj) + buildingObj->removeAllAllowed(); + else + { + CellObject *cellObj = dynamic_cast(serverObj); + if (cellObj) + cellObj->removeAllAllowed(); + } + } +} + +// ---------------------------------------------------------------------- + +/** + * add someone to a cell or building's banned list + * + * @param env Java Environment + * @param self class calling this function + * @param target the cell or building to set permissions for + * @param name name or id string to add to banned list + */ +void JNICALL ScriptMethodsPermissionsNamespace::permissionsAddBanned(JNIEnv *env, jobject self, jlong target, jstring name) +{ + JavaStringParam localName(name); + std::string strName; + if (!JavaLibrary::convert(localName, strName)) + return; + + ServerObject *serverObj = 0; + if (JavaLibrary::getObject(target, serverObj)) + { + BuildingObject *buildingObj = dynamic_cast(serverObj); + if (buildingObj) + buildingObj->addBanned(strName); + else + { + CellObject *cellObj = dynamic_cast(serverObj); + if (cellObj) + cellObj->addBanned(strName); + } + } +} + +// ---------------------------------------------------------------------- + +/** + * remove someone from a cell or building's banned list + * + * @param env Java Environment + * @param self class calling this function + * @param target the cell or building to set permissions for + * @param name name or id string to remove from banned list + */ +void JNICALL ScriptMethodsPermissionsNamespace::permissionsRemoveBanned(JNIEnv *env, jobject self, jlong target, jstring name) +{ + JavaStringParam localName(name); + std::string strName; + if (!JavaLibrary::convert(localName, strName)) + return; + + ServerObject *serverObj = 0; + if (JavaLibrary::getObject(target, serverObj)) + { + BuildingObject *buildingObj = dynamic_cast(serverObj); + if (buildingObj) + buildingObj->removeBanned(strName); + else + { + CellObject *cellObj = dynamic_cast(serverObj); + if (cellObj) + cellObj->removeBanned(strName); + } + } +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsPermissionsNamespace::permissionsRemoveAllBanned(JNIEnv *env, jobject self, jlong target) +{ + ServerObject *serverObj = 0; + if (JavaLibrary::getObject(target, serverObj)) + { + BuildingObject *buildingObj = dynamic_cast(serverObj); + if (buildingObj) + buildingObj->removeAllBanned(); + else + { + CellObject *cellObj = dynamic_cast(serverObj); + if (cellObj) + cellObj->removeAllBanned(); + } + } +} + +// ---------------------------------------------------------------------- + +/** + * make a cell or building public + * + * @param env Java Environment + * @param self class calling this function + * @param target the cell or building to set permissions for + */ +void JNICALL ScriptMethodsPermissionsNamespace::permissionsMakePublic(JNIEnv *env, jobject self, jlong target) +{ + ServerObject *serverObj = 0; + if (JavaLibrary::getObject(target, serverObj)) + { + BuildingObject *buildingObj = dynamic_cast(serverObj); + if (buildingObj) + buildingObj->setIsPublic(true); + else + { + CellObject *cellObj = dynamic_cast(serverObj); + if (cellObj) + cellObj->setIsPublic(true); + } + } +} + +// ---------------------------------------------------------------------- + +/** + * make a cell or building private + * + * @param env Java Environment + * @param self class calling this function + * @param target the cell or building to set permissions for + */ +void JNICALL ScriptMethodsPermissionsNamespace::permissionsMakePrivate(JNIEnv *env, jobject self, jlong target) +{ + ServerObject *serverObj = 0; + if (JavaLibrary::getObject(target, serverObj)) + { + BuildingObject *buildingObj = dynamic_cast(serverObj); + if (buildingObj) + buildingObj->setIsPublic(false); + else + { + CellObject *cellObj = dynamic_cast(serverObj); + if (cellObj) + cellObj->setIsPublic(false); + } + } +} + +// ---------------------------------------------------------------------- + +/** + * expel an object from a building + * + * @param env Java Environment + * @param self class calling this function + * @param target the object to expel + */ +void JNICALL ScriptMethodsPermissionsNamespace::expelFromBuilding(JNIEnv *env, jobject self, jlong target) +{ + ServerObject *serverObj = 0; + if (JavaLibrary::getObject(target, serverObj)) + { + BuildingObject *buildingObj = dynamic_cast(ContainerInterface::getTopmostContainer(*serverObj)); + if (buildingObj) + buildingObj->expelObject(*serverObj); + } +} + +// ====================================================================== + diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsPilot.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsPilot.cpp new file mode 100644 index 00000000..5d216dc2 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsPilot.cpp @@ -0,0 +1,1671 @@ +// ====================================================================== +// +// ScriptMethodsPilot.cpp +// Copyright 2003, Sony Online Entertainment, Inc. +// All rights reserved. +// +// ====================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "serverGame/AiShipAttackTargetList.h" +#include "serverGame/AiShipController.h" +#include "serverGame/ConfigServerGame.h" +#include "serverGame/ServerWorld.h" +#include "serverGame/ShipObject.h" +#include "serverGame/SpaceDockingManager.h" +#include "serverGame/SpacePath.h" +#include "serverGame/SpacePathManager.h" +#include "serverGame/SpaceSquad.h" +#include "serverGame/SpaceSquadManager.h" +#include "sharedFoundation/NetworkId.h" +#include "sharedLog/Log.h" +#include "sharedMath/Transform.h" +#include "sharedObject/Appearance.h" +#include "sharedTerrain/TerrainObject.h" + +using namespace JNIWrappersNamespace; + + +// ====================================================================== + +namespace ScriptMethodsPilotNamespace +{ + bool verifyShipsEnabled() + { + if (!ConfigServerGame::getShipsEnabled()) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("Ship support is not enabled. Make sure [GameServer] shipsEnabled=1 is in your config file.")); + return false; + } + + return true; + } + + bool install(); + + jint JNICALL spaceUnitGetBehavior(JNIEnv * env, jobject self, jlong unit); + void JNICALL spaceUnitIdle(JNIEnv * env, jobject self, jlong unit); + void JNICALL spaceUnitTrack(JNIEnv * env, jobject self, jlong unit, jlong target); + void JNICALL spaceUnitMoveTo(JNIEnv * env, jobject self, jlong unit, jobjectArray path); + void JNICALL spaceUnitAddPatrolPath(JNIEnv * env, jobject self, jlong unit, jobjectArray path); + void JNICALL spaceUnitClearPatrolPath(JNIEnv * env, jobject self, jlong unit); + void JNICALL spaceUnitFollow(JNIEnv * env, jobject self, jlong unit, jlong followedUnit, jobject direction_o, jfloat distance); + void JNICALL spaceUnitAddDamageTaken(JNIEnv * env, jobject self, jlong unit, jlong targetUnit, jfloat damage); + void JNICALL spaceUnitSetAttackOrders(JNIEnv * env, jobject self, jlong unit, jint attackOrders); + void JNICALL spaceUnitSetPilotType(JNIEnv * env, jobject self, jlong unit, jstring pilotType); + jstring JNICALL spaceUnitGetPilotType(JNIEnv * env, jobject self, jlong unit); + jlong JNICALL spaceUnitGetPrimaryAttackTarget(JNIEnv * env, jobject self, jlong unit); + jlongArray JNICALL spaceUnitGetAttackTargetList(JNIEnv * env, jobject self, jlong unit); + jlongArray JNICALL spaceUnitGetWhoIsTargetingMe(JNIEnv * env, jobject self, jlong unit); + jboolean JNICALL spaceUnitIsAttacking(JNIEnv * env, jobject self, jlong unit); + void JNICALL spaceUnitRemoveAttackTarget(JNIEnv * env, jobject self, jlong unit, jlong targetUnit); + void JNICALL spaceUnitSetLeashDistance(JNIEnv * env, jobject self, jlong unit, jfloat distance); + void JNICALL spaceUnitSetSquadId(JNIEnv * env, jobject self, jlong unit, jint squadId); + jint JNICALL spaceUnitGetSquadId(JNIEnv * env, jobject self, jlong unit); + void JNICALL spaceUnitDock(JNIEnv * env, jobject self, jlong unit, jlong dockTarget, jfloat timeAtDock); + void JNICALL spaceUnitUnDock(JNIEnv * env, jobject self, jlong unit); + jboolean JNICALL spaceUnitIsDocked(JNIEnv * env, jobject self, jlong unit); + jboolean JNICALL spaceUnitIsDocking(JNIEnv * env, jobject self, jlong unit); + void JNICALL spaceUnitSetAutoAggroImmuneTime(JNIEnv * env, jobject self, jlong unit, jfloat time); + jboolean JNICALL spaceUnitIsAutoAggroImmune(JNIEnv * env, jobject self, jlong unit); + void JNICALL spaceUnitSetDamageAggroImmune(JNIEnv * env, jobject self, jlong unit, jboolean enabled); + jobject JNICALL spaceUnitGetDockTransform(JNIEnv * env, jobject self, jlong dockTarget, jlong dockingUnit); + void JNICALL spaceUnitAddExclusiveAggro(JNIEnv * env, jobject self, jlong unit, jlong pilot); + void JNICALL spaceUnitRemoveExclusiveAggro(JNIEnv * env, jobject self, jlong unit, jlong pilot); + jint JNICALL spaceSquadCreateSquadId(JNIEnv * env, jobject self); + jint JNICALL spaceSquadRemoveUnit(JNIEnv * env, jobject self, jlong unit); + jint JNICALL spaceSquadCombine(JNIEnv * env, jobject self, jint squadId1, jint squadId2); + jint JNICALL spaceSquadGetSize(JNIEnv * env, jobject self, jint squadId); + jlongArray JNICALL spaceSquadGetUnitList(JNIEnv * env, jobject self, jint squadId); + void JNICALL spaceSquadSetFormation(JNIEnv * env, jobject self, jint squadId, jint formation); + void JNICALL spaceSquadSetFormationSpacing(JNIEnv * env, jobject self, jint squadId, jfloat scale); + jint JNICALL spaceSquadGetFormation(JNIEnv * env, jobject self, jint squadId); + void JNICALL spaceSquadSetLeader(JNIEnv * env, jobject self, jint squadId, jlong unit); + jlong JNICALL spaceSquadGetLeader(JNIEnv * env, jobject self, jint squadId); + void JNICALL spaceSquadIdle(JNIEnv * env, jobject self, jint squadId); + void JNICALL spaceSquadTrack(JNIEnv * env, jobject self, jint squadId, jlong target); + void JNICALL spaceSquadMoveTo(JNIEnv * env, jobject self, jint squadId, jobjectArray path); + void JNICALL spaceSquadAddPatrolPath(JNIEnv * env, jobject self, jint squadId, jobjectArray path); + void JNICALL spaceSquadClearPatrolPath(JNIEnv * env, jobject self, jint squadId); + void JNICALL spaceSquadFollow(JNIEnv * env, jobject self, jint squadId, jlong followedUnit, jobject direction_o, jfloat distance); + void JNICALL spaceSquadSetGuardTarget(JNIEnv * env, jobject self, jint squad, jint targetSquad); + jint JNICALL spaceSquadGetGuardTarget(JNIEnv * env, jobject self, jint squad); + void JNICALL spaceSquadRemoveGuardTarget(JNIEnv * env, jobject self, jint squad); + jboolean JNICALL spaceSquadIsSquadIdValid(JNIEnv *env, jobject self, jint squadId); + void JNICALL setShipAggroDistance(JNIEnv *env, jobject self, jlong shipId, jfloat aggroDistance); +} + +using namespace ScriptMethodsPilotNamespace; + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsPilotNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsPilotNamespace::c)} + JF("__spaceUnitGetBehavior", "(J)I", spaceUnitGetBehavior), + JF("__spaceUnitIdle", "(J)V", spaceUnitIdle), + JF("__spaceUnitTrack", "(JJ)V", spaceUnitTrack), + JF("__spaceUnitMoveTo", "(J[Lscript/transform;)V", spaceUnitMoveTo), + JF("__spaceUnitAddPatrolPath", "(J[Lscript/transform;)V", spaceUnitAddPatrolPath), + JF("__spaceUnitClearPatrolPath", "(J)V", spaceUnitClearPatrolPath), + JF("__spaceUnitFollow", "(JJLscript/vector;F)V", spaceUnitFollow), + JF("__spaceUnitAddDamageTaken", "(JJF)V", spaceUnitAddDamageTaken), + JF("__spaceUnitSetAttackOrders", "(JI)V", spaceUnitSetAttackOrders), + JF("__spaceUnitSetPilotType", "(JLjava/lang/String;)V", spaceUnitSetPilotType), + JF("__spaceUnitGetPilotType", "(J)Ljava/lang/String;", spaceUnitGetPilotType), + JF("__spaceUnitGetPrimaryAttackTarget", "(J)J", spaceUnitGetPrimaryAttackTarget), + JF("__spaceUnitGetAttackTargetList", "(J)[J", spaceUnitGetAttackTargetList), + JF("__spaceUnitGetWhoIsTargetingMe", "(J)[J", spaceUnitGetWhoIsTargetingMe), + JF("__spaceUnitIsAttacking", "(J)Z", spaceUnitIsAttacking), + JF("__spaceUnitRemoveAttackTarget", "(JJ)V", spaceUnitRemoveAttackTarget), + JF("__spaceUnitSetLeashDistance", "(JF)V", spaceUnitSetLeashDistance), + JF("__spaceUnitSetSquadId", "(JI)V", spaceUnitSetSquadId), + JF("__spaceUnitGetSquadId", "(J)I", spaceUnitGetSquadId), + JF("__spaceUnitDock", "(JJF)V", spaceUnitDock), + JF("__spaceUnitUnDock", "(J)V", spaceUnitUnDock), + JF("__spaceUnitIsDocked", "(J)Z", spaceUnitIsDocked), + JF("__spaceUnitIsDocking", "(J)Z", spaceUnitIsDocking), + JF("__spaceUnitSetAutoAggroImmuneTime", "(JF)V", spaceUnitSetAutoAggroImmuneTime), + JF("__spaceUnitIsAutoAggroImmune", "(J)Z", spaceUnitIsAutoAggroImmune), + JF("__spaceUnitSetDamageAggroImmune", "(JZ)V", spaceUnitSetDamageAggroImmune), + JF("__spaceUnitGetDockTransform", "(JJ)Lscript/transform;", spaceUnitGetDockTransform), + JF("__spaceUnitAddExclusiveAggro", "(JJ)V", spaceUnitAddExclusiveAggro), + JF("__spaceUnitRemoveExclusiveAggro", "(JJ)V", spaceUnitRemoveExclusiveAggro), + JF("_spaceSquadCreateSquadId", "()I", spaceSquadCreateSquadId), + JF("__spaceSquadRemoveUnit", "(J)I", spaceSquadRemoveUnit), + JF("_spaceSquadCombine", "(II)I", spaceSquadCombine), + JF("_spaceSquadGetSize", "(I)I", spaceSquadGetSize), + JF("__spaceSquadGetUnitList", "(I)[J", spaceSquadGetUnitList), + JF("_spaceSquadSetFormation", "(II)V", spaceSquadSetFormation), + JF("_spaceSquadSetFormationSpacing", "(IF)V", spaceSquadSetFormationSpacing), + JF("_spaceSquadGetFormation", "(I)I", spaceSquadGetFormation), + JF("__spaceSquadSetLeader", "(IJ)V", spaceSquadSetLeader), + JF("__spaceSquadGetLeader", "(I)J", spaceSquadGetLeader), + JF("_spaceSquadIdle", "(I)V", spaceSquadIdle), + JF("__spaceSquadTrack", "(IJ)V", spaceSquadTrack), + JF("_spaceSquadMoveTo", "(I[Lscript/transform;)V", spaceSquadMoveTo), + JF("_spaceSquadAddPatrolPath", "(I[Lscript/transform;)V", spaceSquadAddPatrolPath), + JF("_spaceSquadClearPatrolPath", "(I)V", spaceSquadClearPatrolPath), + JF("__spaceSquadFollow", "(IJLscript/vector;F)V", spaceSquadFollow), + JF("_spaceSquadSetGuardTarget", "(II)V", spaceSquadSetGuardTarget), + JF("_spaceSquadGetGuardTarget", "(I)I", spaceSquadGetGuardTarget), + JF("_spaceSquadRemoveGuardTarget", "(I)V", spaceSquadRemoveGuardTarget), + JF("_spaceSquadIsSquadIdValid", "(I)Z", spaceSquadIsSquadIdValid), + JF("_setShipAggroDistance", "(JF)V", setShipAggroDistance), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsPilotNamespace::spaceUnitGetBehavior(JNIEnv * env, jobject /*self*/, jlong jobject_unit) +{ + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceUnitGetBehavior()")); + + if (!verifyShipsEnabled()) + return JNI_FALSE; + + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, jobject_unit, "ScriptMethodsPilot::spaceUnitGetBehavior() unit did not resolve to a ShipObject"); + if (!shipObject) + return JNI_FALSE; + + AiShipController * const aiShipController = (shipObject->getController()->asShipController() != NULL) ? shipObject->getController()->asShipController()->asAiShipController() : NULL; + if (!aiShipController) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceUnitGetBehavior() called on unit(%s) without AiShipController", shipObject->getNetworkId().getValueString().c_str())); + return JNI_FALSE; + } + + return aiShipController->getBehaviorType(); +} + +// ---------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsPilotNamespace::spaceUnitGetPrimaryAttackTarget(JNIEnv * env, jobject /*self*/, jlong jobject_unit) +{ + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceUnitGetPrimaryAttackTarget()")); + + if (!verifyShipsEnabled()) + return JNI_FALSE; + + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, jobject_unit, "ScriptMethodsPilot::spaceUnitGetPrimaryAttackTarget() unit did not resolve to a ShipObject"); + if (!shipObject) + return JNI_FALSE; + + AiShipController * const aiShipController = (shipObject->getController()->asShipController() != NULL) ? shipObject->getController()->asShipController()->asAiShipController() : NULL; + if (!aiShipController) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceUnitGetPrimaryAttackTarget() called on unit(%s) without AiShipController", shipObject->getNetworkId().getValueString().c_str())); + return JNI_FALSE; + } + + return (aiShipController->getPrimaryAttackTarget()).getValue(); +} + +// ---------------------------------------------------------------------- + +jlongArray JNICALL ScriptMethodsPilotNamespace::spaceUnitGetAttackTargetList(JNIEnv * env, jobject /*self*/, jlong jobject_unit) +{ + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceUnitGetAttackTargetList()")); + + if (!verifyShipsEnabled()) + return JNI_FALSE; + + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, jobject_unit, "ScriptMethodsPilot::spaceUnitGetAttackTargetList() unit did not resolve to a ShipObject"); + if (!shipObject) + return JNI_FALSE; + + AiShipController * const aiShipController = (shipObject->getController()->asShipController() != NULL) ? shipObject->getController()->asShipController()->asAiShipController() : NULL; + if (!aiShipController) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceUnitGetAttackTargetList() called on unit(%s) without AiShipController", shipObject->getNetworkId().getValueString().c_str())); + return JNI_FALSE; + } + + AiShipAttackTargetList::SortedTargetList targetList; + aiShipController->getAttackTargetList().getSortedTargetList(targetList); + + LocalLongArrayRefPtr attackTargetList = createNewLongArray(static_cast(targetList.size())); + AiShipAttackTargetList::SortedTargetList::const_iterator iterTargetList = targetList.begin(); + int index = 0; + + jlong jlongTmp; + for (; iterTargetList != targetList.end(); ++iterTargetList) + { + jlongTmp = ((iterTargetList->first).getValue()); + setLongArrayRegion(*attackTargetList, index, 1, &jlongTmp); + ++index; + } + + return attackTargetList->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jlongArray JNICALL ScriptMethodsPilotNamespace::spaceUnitGetWhoIsTargetingMe(JNIEnv * env, jobject /*self*/, jlong jobject_unit) +{ + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceUnitGetWhoIsTargetingMe()")); + + if (!verifyShipsEnabled()) + return JNI_FALSE; + + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, jobject_unit, "ScriptMethodsPilot::spaceUnitGetWhoIsTargetingMe() unit did not resolve to a ShipObject"); + if (!shipObject) + return JNI_FALSE; + + ShipController * const shipController = shipObject->getController()->asShipController(); + if (!shipController) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceUnitGetWhoIsTargetingMe() called on unit(%s) without ShipController", shipObject->getNetworkId().getValueString().c_str())); + return JNI_FALSE; + } + + ShipController::CachedNetworkIdList const & aiTargetingMeList = shipController->getAiTargetingMeList(); + +#ifdef _DEBUG + if (ConfigServerGame::isSpaceAiLoggingEnabled()) + { + ShipController::CachedNetworkIdList::const_iterator iterAiTargetingMeList = aiTargetingMeList.begin(); + int index = 0; + + for (; iterAiTargetingMeList != aiTargetingMeList.end(); ++iterAiTargetingMeList) + { + LOG("debug_ai", ("ScriptMethodsPilot::spaceUnitGetWhoIsTargetingMe() [%d] unit(%s)", ++index, iterAiTargetingMeList->getValueString().c_str())); + } + } +#endif // _DEBUG + + LocalLongArrayRefPtr attackTargetList = createNewLongArray(static_cast(aiTargetingMeList.size())); + ShipController::CachedNetworkIdList::const_iterator iterAiTargetingMeList = aiTargetingMeList.begin(); + int index = 0; + + jlong jlongTmp; + for (; iterAiTargetingMeList != aiTargetingMeList.end(); ++iterAiTargetingMeList) + { + jlongTmp = (*iterAiTargetingMeList).getValue(); + setLongArrayRegion(*attackTargetList, index, 1, &jlongTmp); + ++index; + } + + return attackTargetList->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsPilotNamespace::spaceUnitIsAttacking(JNIEnv * env, jobject /*self*/, jlong jobject_unit) +{ + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceUnitIsAttacking()")); + + if (!verifyShipsEnabled()) + return JNI_FALSE; + + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, jobject_unit, "ScriptMethodsPilot::spaceUnitIsAttacking() unit did not resolve to a ShipObject"); + if (!shipObject) + return JNI_FALSE; + + AiShipController * const aiShipController = (shipObject->getController()->asShipController() != NULL) ? shipObject->getController()->asShipController()->asAiShipController() : NULL; + if (!aiShipController) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceUnitIsAttacking() called on unit(%s) without AiShipController", shipObject->getNetworkId().getValueString().c_str())); + return JNI_FALSE; + } + + return aiShipController->isAttacking(); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsPilotNamespace::spaceUnitIdle(JNIEnv * env, jobject /*self*/, jlong jobject_unit) +{ + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceUnitIdle()")); + + if (!verifyShipsEnabled()) + return; + + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, jobject_unit, "ScriptMethodsPilot::spaceUnitIdle() unit did not resolve to a ShipObject"); + if (!shipObject) + return; + + AiShipController * const aiShipController = (shipObject->getController()->asShipController() != NULL) ? shipObject->getController()->asShipController()->asAiShipController() : NULL; + if (!aiShipController) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceUnitIdle() called on unit(%s) without AiShipController", shipObject->getNetworkId().getValueString().c_str())); + return; + } + + aiShipController->idle(); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsPilotNamespace::spaceUnitTrack(JNIEnv * env, jobject /*self*/, jlong jobject_unit, jlong jobject_target) +{ + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceUnitTrack()")); + + if (!verifyShipsEnabled()) + return; + + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, jobject_unit, "ScriptMethodsPilot::spaceUnitTrack() unit did not resolve to a ShipObject"); + if (!shipObject) + return; + + AiShipController * const aiShipController = (shipObject->getController()->asShipController() != NULL) ? shipObject->getController()->asShipController()->asAiShipController() : NULL; + if (!aiShipController) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceUnitTrack() called on unit(%s) without AiShipController", shipObject->getNetworkId().getValueString().c_str())); + return; + } + + Object * target = NULL; + if (!JavaLibrary::getObject(jobject_target, target)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceUnitTrack() The target did not resolve to an Object")); + return; + } + + aiShipController->track(*target); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsPilotNamespace::spaceUnitMoveTo(JNIEnv * env, jobject /*self*/, jlong jobject_unit, jobjectArray jobjectArray_path) +{ + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceUnitMoveTo()")); + + if (!verifyShipsEnabled()) + return; + + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, jobject_unit, "ScriptMethodsPilot::spaceUnitMoveTo() unit did not resolve to a ShipObject"); + if (!shipObject) + return; + + AiShipController * const aiShipController = (shipObject->getController()->asShipController() != NULL) ? shipObject->getController()->asShipController()->asAiShipController() : NULL; + if (!aiShipController) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceUnitMoveTo() called on unit(%s) without AiShipController", shipObject->getNetworkId().getValueString().c_str())); + return; + } + + //-- Convert the path + + AiShipController::TransformList convertedPath; + + if (!ScriptConversion::convert(jobjectArray_path, convertedPath)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceUnitMoveTo() unit(%s) scene(%s) Failed to convert the path to a vector of transforms.", shipObject->getDebugInformation().c_str(), ServerWorld::getSceneId().c_str())); + return; + } + + if (convertedPath.empty()) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceUnitMoveTo() unit(%s) scene(%s) Specifying an empty path transform list. Are you sure you wanted to do that?", shipObject->getDebugInformation().c_str(), ServerWorld::getSceneId().c_str())); + return; + } + + SpacePath * const path = SpacePathManager::fetch(NULL, aiShipController->getOwner(), aiShipController->getShipRadius()); + AiShipController::TransformList::const_iterator iterTransformList = convertedPath.begin(); + + for (; iterTransformList != convertedPath.end(); ++iterTransformList) + { + path->addTransform(*iterTransformList); + } + + aiShipController->moveTo(path); + SpacePathManager::release(path, aiShipController->getOwner()); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsPilotNamespace::spaceUnitAddPatrolPath(JNIEnv * env, jobject /*self*/, jlong jobject_unit, jobjectArray jobjectArray_path) +{ + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceUnitAddPatrolPath()")); + + if (!verifyShipsEnabled()) + return; + + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, jobject_unit, "ScriptMethodsPilot::spaceUnitAddPatrolPath() unit did not resolve to a ShipObject"); + if (!shipObject) + return; + + AiShipController * const aiShipController = (shipObject->getController()->asShipController() != NULL) ? shipObject->getController()->asShipController()->asAiShipController() : NULL; + if (!aiShipController) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceUnitAddPatrolPath() called on unit(%s) without AiShipController", shipObject->getNetworkId().getValueString().c_str())); + return; + } + + //-- Convert the path + + AiShipController::TransformList convertedPath; + + if (!ScriptConversion::convert(jobjectArray_path, convertedPath)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceUnitAddPatrolPath() unit(%s) scene(%s) Failed to convert the path to a vector of transforms.", shipObject->getDebugInformation().c_str(), ServerWorld::getSceneId().c_str())); + return; + } + + if (convertedPath.empty()) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceUnitAddPatrolPath() unit(%s) scene(%s) Specifying an empty path transform list. Are you sure you wanted to do that?", shipObject->getDebugInformation().c_str(), ServerWorld::getSceneId().c_str())); + return; + } + + SpacePath * const path = SpacePathManager::fetch(aiShipController->getPath(), aiShipController->getOwner(), aiShipController->getShipRadius()); + AiShipController::TransformList::const_iterator iterTransformList = convertedPath.begin(); + + for (; iterTransformList != convertedPath.end(); ++iterTransformList) + { + path->addTransform(*iterTransformList); + } + + aiShipController->addPatrolPath(path); + SpacePathManager::release(path, aiShipController->getOwner()); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsPilotNamespace::spaceUnitClearPatrolPath(JNIEnv * env, jobject /*self*/, jlong jobject_unit) +{ + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceUnitClearPatrolPath()")); + + if (!verifyShipsEnabled()) + return; + + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, jobject_unit, "ScriptMethodsPilot::spaceUnitClearPatrolPath() unit did not resolve to a ShipObject"); + if (!shipObject) + return; + + AiShipController * const aiShipController = (shipObject->getController()->asShipController() != NULL) ? shipObject->getController()->asShipController()->asAiShipController() : NULL; + if (!aiShipController) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceUnitClearPatrolPath() called on unit(%s) without AiShipController", shipObject->getNetworkId().getValueString().c_str())); + return; + } + + aiShipController->clearPatrolPath(); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsPilotNamespace::spaceUnitFollow(JNIEnv * env, jobject /*self*/, jlong jobject_unit, jlong jobject_followedUnit, jobject jobject_direction_o, jfloat jfloat_distance) +{ + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceUnitFollow()")); + + if (!verifyShipsEnabled()) + return; + + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, jobject_unit, "ScriptMethodsPilot::spaceUnitFollow() unit did not resolve to a ShipObject"); + if (!shipObject) + return; + + AiShipController * const aiShipController = (shipObject->getController()->asShipController() != NULL) ? shipObject->getController()->asShipController()->asAiShipController() : NULL; + if (!aiShipController) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceUnitFollow() called on unit(%s) without AiShipController", shipObject->getNetworkId().getValueString().c_str())); + return; + } + + Object * followedUnit = NULL; + if (!JavaLibrary::getObject(jobject_followedUnit, followedUnit)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceUnitFollow() followedUnit did not resolve to an Object")); + return; + } + + Vector direction_o; + if (!ScriptConversion::convert(jobject_direction_o, direction_o)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceUnitFollow() direction did not resolve to a Vector")); + return; + } + + NetworkId const followedUnitId(jobject_followedUnit); + if (followedUnitId == NetworkId::cms_invalid) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceUnitFollow() DB failed to convert parameter 2 (followedUnit) to NetworkId")); + return; + } + + aiShipController->follow(followedUnitId, direction_o, jfloat_distance); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsPilotNamespace::spaceUnitAddDamageTaken(JNIEnv * env, jobject /*self*/, jlong jobject_unit, jlong jobject_targetUnit, jfloat jfloat_damage) +{ + if (!verifyShipsEnabled()) + { + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceUnitAddDamageTaken() ERROR: Ships are disabled.")); + return; + } + + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, jobject_unit, "ScriptMethodsPilot::spaceUnitAddDamageTaken() unit did not resolve to a ShipObject"); + if (!shipObject) + { + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceUnitAddDamageTaken() ERROR: Unable to resolve the attacking unit to a ShipObject.")); + return; + } + + ShipObject * const targetShipObject = JavaLibrary::getShipThrow(env, jobject_targetUnit, "ScriptMethodsPilot::spaceUnitAddDamageTaken() targetUnit did not resolve to a ShipObject"); + if (!targetShipObject) + { + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceUnitAddDamageTaken() ERROR: Unable to resolve target_unit to a ShipObject.")); + return; + } + + if (shipObject->getNetworkId() == targetShipObject->getNetworkId()) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceUnitAddDamageTaken() unit(%s) is attempting to attack itself", shipObject->getNetworkId().getValueString().c_str())); + return; + } + + { + float const chassisHitPointsCurrent = targetShipObject->getCurrentChassisHitPoints(); + float const chassisHitPointsMaximum = targetShipObject->getMaximumChassisHitPoints(); + float const currentChassisPercent = (chassisHitPointsMaximum > 0.0f) ? (chassisHitPointsCurrent / chassisHitPointsMaximum) * 100.0f : -1.0f; + + float const frontArmorCurrent = targetShipObject->getComponentHitpointsCurrent(ShipChassisSlotType::SCST_armor_0); + float const frontArmorMaximum = targetShipObject->getComponentHitpointsMaximum(ShipChassisSlotType::SCST_armor_0); + float const frontArmorPercent = (frontArmorMaximum > 0.0f) ? (frontArmorCurrent / frontArmorMaximum) * 100.0f : -1.0f; + + float const backArmorCurrent = targetShipObject->getComponentHitpointsCurrent(ShipChassisSlotType::SCST_armor_1); + float const backArmorMaximum = targetShipObject->getComponentHitpointsMaximum(ShipChassisSlotType::SCST_armor_1); + float const backArmorPercent = (backArmorMaximum > 0.0f) ? (backArmorCurrent / backArmorMaximum) * 100.0f : -1.0f; + + float const frontShieldCurrent = targetShipObject->getShieldHitpointsFrontCurrent(); + float const frontShieldMaximum = targetShipObject->getShieldHitpointsFrontMaximum(); + float const frontShieldPercent = (frontShieldMaximum > 0.0f) ? (frontShieldCurrent / frontShieldMaximum) * 100.0f : -1.0f; + + float const backShieldCurrent = targetShipObject->getShieldHitpointsFrontCurrent(); + float const backShieldMaximum = targetShipObject->getShieldHitpointsBackMaximum(); + float const backShieldPercent = (backShieldMaximum > 0.0f) ? (backShieldCurrent / backShieldMaximum) * 100.0f : -1.0f; + + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceUnitAddDamageTaken() target(%s) dmg(%.2f) ch(%.0f) af(%.0f) ab(%.0f) sf(%.0f) sb(%.0f)", targetShipObject->getNetworkId().getValueString().c_str(), jfloat_damage, currentChassisPercent, frontArmorPercent, backArmorPercent, frontShieldPercent, backShieldPercent)); + } + + ShipController * const shipController = shipObject->getController()->asShipController(); + AiShipController * const aiShipController = (shipController != NULL) ? shipController->asAiShipController() : NULL; + bool const verifyAttacker = true; + + if (aiShipController != NULL) + { + // This adds damage to an AI unit + + bool const notifySquad = true; + bool const checkPlayerAttacker = true; + + if (!aiShipController->addDamageTaken(targetShipObject->getNetworkId(), jfloat_damage, verifyAttacker, notifySquad, checkPlayerAttacker)) + { + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceUnitAddDamageTaken() targetUnit(%s) is not attackable", targetShipObject->getNetworkId().getValueString().c_str())); + } + } + else if (shipController != NULL) + { + // This adds damage to a player unit + + if (!shipController->addDamageTaken(targetShipObject->getNetworkId(), jfloat_damage, verifyAttacker)) + { + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceUnitAddDamageTaken() targetUnit(%s) is not attackable", targetShipObject->getNetworkId().getValueString().c_str())); + } + } + else + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceUnitAddDamageTaken() unit(%s) Why does this ship not have a ShipController?", shipObject->getNetworkId().getValueString().c_str())); + } +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsPilotNamespace::spaceUnitSetAttackOrders(JNIEnv * env, jobject /*self*/, jlong jobject_unit, jint jint_attackOrders) +{ + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceUnitSetAttackOrder()")); + + if (!verifyShipsEnabled()) + return; + + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, jobject_unit, "ScriptMethodsPilot::spaceUnitSetAttackOrder() unit did not resolve to a ShipObject"); + if (!shipObject) + return; + + AiShipController * const aiShipController = (shipObject->getController()->asShipController() != NULL) ? shipObject->getController()->asShipController()->asAiShipController() : NULL; + if (!aiShipController) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceUnitSetAttackOrder() called on unit(%s) without AiShipController", shipObject->getNetworkId().getValueString().c_str())); + return; + } + + if ( (jint_attackOrders < 0) + || (jint_attackOrders >= static_cast(AiShipController::AO_count))) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceUnitSetAttackOrder() called on unit(%s) with out of range attack orders %d valid range [0...%d]", shipObject->getNetworkId().getValueString().c_str(), jint_attackOrders, static_cast(AiShipController::AO_count) - 1)); + return; + } + + aiShipController->setAttackOrders(static_cast(jint_attackOrders)); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsPilotNamespace::spaceUnitSetPilotType(JNIEnv * env, jobject /*self*/, jlong jobject_unit, jstring jstring_pilotType) +{ + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceUnitSetPilotType()")); + + if (!verifyShipsEnabled()) + return; + + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, jobject_unit, "ScriptMethodsPilot::spaceUnitSetPilotType() unit did not resolve to a ShipObject"); + if (!shipObject) + return; + + AiShipController * const aiShipController = (shipObject->getController()->asShipController() != NULL) ? shipObject->getController()->asShipController()->asAiShipController() : NULL; + if (!aiShipController) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceUnitSetPilotType() called on unit(%s) without AiShipController", shipObject->getNetworkId().getValueString().c_str())); + return; + } + + JavaStringParam javaStringParam_pilotType (jstring_pilotType); + std::string pilotType; + if (!JavaLibrary::convert (javaStringParam_pilotType, pilotType)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceUnitSetPilotType() DB failed to convert parameter 2 (pilotType) to string")); + return; + } + + if (pilotType.empty()) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::spaceUnitSetPilotType empty pilotType for ship [%s]", + shipObject ? shipObject->getDebugInformation().c_str() : "NONE")); + return; + } + + aiShipController->setPilotType(pilotType); +} + +// ---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsPilotNamespace::spaceUnitGetPilotType(JNIEnv * env, jobject /*self*/, jlong jobject_unit) +{ + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceUnitGetPilotType()")); + + if (!verifyShipsEnabled()) + return NULL; + + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, jobject_unit, "ScriptMethodsPilot::spaceUnitGetPilotType() unit did not resolve to a ShipObject"); + if (!shipObject) + return NULL; + + AiShipController * const aiShipController = (shipObject->getController()->asShipController() != NULL) ? shipObject->getController()->asShipController()->asAiShipController() : NULL; + if (!aiShipController) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceUnitGetPilotType() called on unit(%s) without AiShipController", shipObject->getNetworkId().getValueString().c_str())); + return JNI_FALSE; + } + + return JavaString(aiShipController->getPilotType()).getReturnValue(); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsPilotNamespace::spaceUnitRemoveAttackTarget(JNIEnv * env, jobject /*self*/, jlong jobject_unit, jlong jobject_targetUnit) +{ + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceUnitRemoveAttackTarget()")); + + if (!verifyShipsEnabled()) + return; + + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, jobject_unit, "ScriptMethodsPilot::spaceUnitRemoveAttackTarget() unit did not resolve to a ShipObject"); + if (!shipObject) + return; + + AiShipController * const aiShipController = (shipObject->getController()->asShipController() != NULL) ? shipObject->getController()->asShipController()->asAiShipController() : NULL; + if (!aiShipController) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceUnitRemoveAttackTarget() called on unit(%s) without AiShipController", shipObject->getNetworkId().getValueString().c_str())); + return; + } + + NetworkId const targetUnit(jobject_targetUnit); + if (targetUnit == NetworkId::cms_invalid) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceUnitRemoveAttackTarget() DB failed to convert parameter 2 (targetUnit) to NetworkId")); + return; + } + + if (targetUnit == shipObject->getNetworkId()) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceUnitRemoveAttackTarget() unit(%s) is attempting to remove itself from its target list", shipObject->getNetworkId().getValueString().c_str())); + return; + } + + if (!aiShipController->removeAttackTarget(targetUnit)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceUnitRemoveAttackTarget() The targetUnit(%s) is not in the units(%s) target list", targetUnit.getValueString().c_str(), shipObject->getNetworkId().getValueString().c_str())); + } +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsPilotNamespace::spaceUnitSetLeashDistance(JNIEnv * env, jobject /*self*/, jlong jobject_unit, jfloat jfloat_radius) +{ + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceUnitSetLeashDistance()")); + + if (!verifyShipsEnabled()) + return; + + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, jobject_unit, "ScriptMethodsPilot::spaceUnitSetLeashDistance() unit did not resolve to a ShipObject"); + if (!shipObject) + return; + + AiShipController * const aiShipController = (shipObject->getController()->asShipController() != NULL) ? shipObject->getController()->asShipController()->asAiShipController() : NULL; + if (!aiShipController) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceUnitSetLeashDistance() called on unit(%s) without AiShipController", shipObject->getNetworkId().getValueString().c_str())); + return; + } + + aiShipController->setLeashRadius(jfloat_radius); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsPilotNamespace::spaceUnitSetSquadId(JNIEnv * /*env*/, jobject /*self*/, jlong jobject_unit, jint jint_squadId) +{ + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceUnitSetSquadId()")); + + if (!verifyShipsEnabled()) + return; + + NetworkId unit(jobject_unit); + + if (!SpaceSquadManager::setSquadId(unit, jint_squadId)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceUnitSetSquadId() called on unit(%s) without AiShipController", unit.getValueString().c_str())); + } +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsPilotNamespace::spaceUnitGetSquadId(JNIEnv * env, jobject /*self*/, jlong jobject_unit) +{ + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceUnitGetSquadId()")); + + if (!verifyShipsEnabled()) + return JNI_FALSE; + + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, jobject_unit, "ScriptMethodsPilot::spaceUnitGetSquadId() unit did not resolve to a ShipObject"); + if (!shipObject) + return JNI_FALSE; + + AiShipController * const aiShipController = (shipObject->getController()->asShipController() != NULL) ? shipObject->getController()->asShipController()->asAiShipController() : NULL; + if (!aiShipController) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceUnitGetSquadId() called on unit(%s) without AiShipController", shipObject->getNetworkId().getValueString().c_str())); + return JNI_FALSE; + } + + return aiShipController->getSquad().getId(); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsPilotNamespace::spaceSquadMoveTo(JNIEnv * /*env*/, jobject /*self*/, jint jint_squadId, jobjectArray jobjectArray_path) +{ + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceSquadMoveTo()")); + + if (!verifyShipsEnabled()) + return; + + //-- Convert the path + + AiShipController::TransformList convertedPath; + + if (!ScriptConversion::convert(jobjectArray_path, convertedPath)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceSquadMoveTo() squadId(%d) scene(%s) Failed to convert the path to a vector of transforms.", jint_squadId, ServerWorld::getSceneId().c_str())); + return; + } + + if (convertedPath.empty()) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceSquadMoveTo() squadId(%d) scene(%s) Specifying an empty path transform list. Are you sure you wanted to do that?", jint_squadId, ServerWorld::getSceneId().c_str())); + return; + } + + SpaceSquad * const squad = SpaceSquadManager::getSquad(jint_squadId); + + if (!squad) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceSquadMoveTo() Unable to resolve squadId(%d) to a SpaceSquad", jint_squadId)); + return; + } + + float const largestShipRadius = squad->getLargestShipRadius(); + SpacePath * const path = SpacePathManager::fetch(NULL, squad, largestShipRadius); + AiShipController::TransformList::const_iterator iterTransformList = convertedPath.begin(); + + for (; iterTransformList != convertedPath.end(); ++iterTransformList) + { + path->addTransform(*iterTransformList); + } + + squad->moveTo(path); + SpacePathManager::release(path, squad); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsPilotNamespace::spaceSquadAddPatrolPath(JNIEnv * /*env*/, jobject /*self*/, jint jint_squadId, jobjectArray jobjectArray_path) +{ + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceSquadAddPatrolPath()")); + + if (!verifyShipsEnabled()) + return; + + SpaceSquad * const squad = SpaceSquadManager::getSquad(jint_squadId); + + if (!squad) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceSquadAddPatrolPath() Unable to resolve squadId(%d) to a SpaceSquad", jint_squadId)); + return; + } + + //-- Convert the path + + AiShipController::TransformList convertedPath; + + if (!ScriptConversion::convert(jobjectArray_path, convertedPath)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceSquadAddPatrolPath() squadId(%d) scene(%s) Failed to convert the path to a vector of transforms.", jint_squadId, ServerWorld::getSceneId().c_str())); + return; + } + + if (convertedPath.empty()) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceSquadAddPatrolPath() squadId(%d) scene(%s) Specifying an empty path transform list. Are you sure you wanted to do that?", jint_squadId, ServerWorld::getSceneId().c_str())); + return; + } + + //-- Add the transforms to the path + + float const largestShipRadius = squad->getLargestShipRadius(); + SpacePath * const path = SpacePathManager::fetch(squad->getPath(), squad, largestShipRadius); + AiShipController::TransformList::const_iterator iterTransformList = convertedPath.begin(); + + for (; iterTransformList != convertedPath.end(); ++iterTransformList) + { + path->addTransform(*iterTransformList); + } + + //-- Patrol + + squad->addPatrolPath(path); + SpacePathManager::release(path, squad); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsPilotNamespace::spaceSquadCreateSquadId(JNIEnv * /*env*/, jobject /*self*/) +{ + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceSquadCreateSquadId()")); + + if (!verifyShipsEnabled()) + return JNI_FALSE; + + return SpaceSquadManager::createSquadId(); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsPilotNamespace::spaceSquadRemoveUnit(JNIEnv * env, jobject /*self*/, jlong jobject_unit) +{ + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceSquadRemoveUnit()")); + + if (!verifyShipsEnabled()) + return JNI_FALSE; + + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, jobject_unit, "ScriptMethodsPilot::spaceSquadRemoveUnit() unit did not resolve to a ShipObject"); + if (!shipObject) + return JNI_FALSE; + + AiShipController * const aiShipController = (shipObject->getController()->asShipController() != NULL) ? shipObject->getController()->asShipController()->asAiShipController() : NULL; + if (!aiShipController) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceSquadRemoveUnit() called on unit(%s) without AiShipController", shipObject->getNetworkId().getValueString().c_str())); + return JNI_FALSE; + } + + SpaceSquad * const squad = SpaceSquadManager::createSquad(); + + IGNORE_RETURN(SpaceSquadManager::setSquadId(shipObject->getNetworkId(), squad->getId())); + + return squad->getId(); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsPilotNamespace::spaceSquadCombine(JNIEnv * /*env*/, jobject /*self*/, jint jint_squadId1, jint jint_squadId2) +{ + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceSquadCombine()")); + + if (!verifyShipsEnabled()) + return JNI_FALSE; + + SpaceSquad * const squad1 = SpaceSquadManager::getSquad(jint_squadId1); + + if (!squad1) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceSquadCombine() Unable to resolve squadId1(%d) to a SpaceSquad", jint_squadId1)); + return JNI_FALSE; + } + + SpaceSquad * const squad2 = SpaceSquadManager::getSquad(jint_squadId2); + + if (!squad2) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceSquadCombine() Unable to resolve squadId2(%d) to a SpaceSquad", jint_squadId2)); + return JNI_FALSE; + } + + squad1->combineWith(*squad2); + + return squad1->getId(); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsPilotNamespace::spaceSquadGetSize(JNIEnv * /*env*/, jobject /*self*/, jint jint_squadId) +{ + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceSquadGetSize()")); + + if (!verifyShipsEnabled()) + return JNI_FALSE; + + SpaceSquad * const squad = SpaceSquadManager::getSquad(jint_squadId); + + if (!squad) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceSquadGetSize() Unable to resolve squadId(%d) to a SpaceSquad", jint_squadId)); + return JNI_FALSE; + } + + return squad->getUnitCount(); +} + +// ---------------------------------------------------------------------- + +jlongArray JNICALL ScriptMethodsPilotNamespace::spaceSquadGetUnitList(JNIEnv * env, jobject /*self*/, jint jint_squadId) +{ + UNREF(env); + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceSquadGetUnitList()")); + + if (!verifyShipsEnabled()) + return JNI_FALSE; + + SpaceSquad * const squad = SpaceSquadManager::getSquad(jint_squadId); + + if (!squad) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceSquadGetUnitList() Unable to resolve squadId(%d) to a SpaceSquad", jint_squadId)); + return JNI_FALSE; + } + + SpaceSquad::UnitList unitList; + + squad->getUnitList(unitList); + + LocalLongArrayRefPtr resultUnitList = createNewLongArray(static_cast(unitList.size())); + + SpaceSquad::UnitList::const_iterator iterUnitList = unitList.begin(); + int index = 0; + + jlong jlongTmp; + for (; iterUnitList != unitList.end(); ++iterUnitList) + { + jlongTmp = (*iterUnitList).getValue(); + setLongArrayRegion(*resultUnitList, index, 1, &jlongTmp); + ++index; + } + + return resultUnitList->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsPilotNamespace::spaceSquadSetFormation(JNIEnv * /*env*/, jobject /*self*/, jint jint_squadId, jint jint_formation) +{ + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceSquadSetFormation()")); + + if (!verifyShipsEnabled()) + return; + + if ( (jint_formation <= static_cast(Formation::S_invalid)) + || (jint_formation >= static_cast(Formation::S_count))) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceSquadSetFormation() Invalid formation(%d) specified", jint_formation)); + return; + } + + SpaceSquad * const squad = SpaceSquadManager::getSquad(jint_squadId); + + if (!squad) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceSquadSetFormation() Unable to resolve squadId(%d) to a SpaceSquad", jint_squadId)); + return; + } + + squad->getFormation().setShape(static_cast(jint_formation)); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsPilotNamespace::spaceSquadSetFormationSpacing(JNIEnv * /*env*/, jobject /*self*/, jint jint_squadId, jfloat jfloat_scale) +{ + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceSquadSetFormationSpacing()")); + + if (!verifyShipsEnabled()) + return; + + if (jfloat_scale < 1.0f) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceSquadSetFormationSpacing() Invalid scale specified(%.2f) specified. Valid range is [1.0f...n]", jfloat_scale)); + return; + } + + SpaceSquad * const squad = SpaceSquadManager::getSquad(jint_squadId); + + if (!squad) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceSquadSetFormationSpacing() Unable to resolve squadId(%d) to a SpaceSquad", jint_squadId)); + return; + } + + squad->getFormation().setSpacing(jfloat_scale); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsPilotNamespace::spaceSquadGetFormation(JNIEnv * /*env*/, jobject /*self*/, jint jint_squadId) +{ + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceSquadGetFormation()")); + + if (!verifyShipsEnabled()) + return JNI_FALSE; + + SpaceSquad * const squad = SpaceSquadManager::getSquad(jint_squadId); + + if (!squad) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceSquadGetFormation() Unable to resolve squadId(%d) to a SpaceSquad", jint_squadId)); + return JNI_FALSE; + } + + return static_cast(squad->getFormation().getShape()); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsPilotNamespace::spaceSquadIdle(JNIEnv * /*env*/, jobject /*self*/, jint jint_squadId) +{ + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceSquadIdle()")); + + if (!verifyShipsEnabled()) + return; + + SpaceSquad * const squad = SpaceSquadManager::getSquad(jint_squadId); + + if (!squad) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceSquadIdle() Unable to resolve squadId(%d) to a SpaceSquad", jint_squadId)); + return; + } + + squad->idle(); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsPilotNamespace::spaceSquadTrack(JNIEnv * /*env*/, jobject /*self*/, jint jint_squadId, jlong jobject_target) +{ + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceSquadTrack()")); + + if (!verifyShipsEnabled()) + return; + + SpaceSquad * const squad = SpaceSquadManager::getSquad(jint_squadId); + + if (!squad) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceSquadTrack() Unable to resolve squadId(%d) to a SpaceSquad", jint_squadId)); + return; + } + + Object * target = NULL; + if (!JavaLibrary::getObject(jobject_target, target)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceSquadTrack() The target did not resolve to an Object")); + return; + } + + squad->track(*target); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsPilotNamespace::spaceSquadSetLeader(JNIEnv * env, jobject /*self*/, jint jint_squadId, jlong jobject_unit) +{ + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceSquadSetLeader()")); + + if (!verifyShipsEnabled()) + return; + + ShipObject * const leaderShipObject = JavaLibrary::getShipThrow(env, jobject_unit, "ScriptMethodsPilot::spaceSquadSetLeader() unit did not resolve to a ShipObject"); + if (!leaderShipObject) + return; + + AiShipController * const aiShipController = (leaderShipObject->getController()->asShipController() != NULL) ? leaderShipObject->getController()->asShipController()->asAiShipController() : NULL; + if (!aiShipController) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceSquadSetLeader() called on unit(%s) without AiShipController", leaderShipObject->getNetworkId().getValueString().c_str())); + return; + } + + SpaceSquad * const squad = SpaceSquadManager::getSquad(jint_squadId); + + if (!squad) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceSquadSetLeader() Unable to resolve squadId(%d) to a SpaceSquad", jint_squadId)); + return; + } + + bool const rebuildFormation = true; + + if (!squad->setLeader(leaderShipObject->getNetworkId(), rebuildFormation)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceSquadSetLeader() The specified leader(%s) is not a member of the squad(%i).", leaderShipObject->getNetworkId().getValueString().c_str(), jint_squadId)); + } +} + +// ---------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsPilotNamespace::spaceSquadGetLeader(JNIEnv * /*env*/, jobject /*self*/, jint jint_squadId) +{ + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceSquadGetLeader()")); + + if (!verifyShipsEnabled()) + return JNI_FALSE; + + SpaceSquad * const squad = SpaceSquadManager::getSquad(jint_squadId); + + if (!squad) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceSquadGetLeader() Unable to resolve squadId(%d) to a SpaceSquad", jint_squadId)); + return JNI_FALSE; + } + + return (squad->getLeader()).getValue(); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsPilotNamespace::spaceSquadClearPatrolPath(JNIEnv * /*env*/, jobject /*self*/, jint jint_squadId) +{ + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceSquadClearPatrolPath()")); + + if (!verifyShipsEnabled()) + return; + + SpaceSquad * const squad = SpaceSquadManager::getSquad(jint_squadId); + + if (!squad) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceSquadClearPatrolPath() Unable to resolve squadId(%d) to a SpaceSquad", jint_squadId)); + return; + } + + squad->clearPatrolPath(); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsPilotNamespace::spaceSquadFollow(JNIEnv * /*env*/, jobject /*self*/, jint jint_squadId, jlong jobject_followedUnit, jobject jobject_direction_o, jfloat jfloat_distance) +{ + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceSquadFollow()")); + + if (!verifyShipsEnabled()) + return; + + SpaceSquad * const squad = SpaceSquadManager::getSquad(jint_squadId); + + if (!squad) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceSquadFollow() Unable to resolve squadId(%d) to a SpaceSquad", jint_squadId)); + return; + } + + Object * followedUnit = NULL; + if (!JavaLibrary::getObject(jobject_followedUnit, followedUnit)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceSquadFollow() followedUnit did not resolve to an Object")); + return; + } + + Vector direction_o; + if (!ScriptConversion::convert(jobject_direction_o, direction_o)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceSquadFollow() direction did not resolve to a Vector")); + return; + } + + NetworkId const followedUnitId(jobject_followedUnit); + if (followedUnitId == NetworkId::cms_invalid) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceSquadFollow() DB failed to convert parameter 2 (followedUnit) to NetworkId")); + return; + } + + squad->follow(followedUnitId, direction_o, jfloat_distance); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsPilotNamespace::spaceUnitDock(JNIEnv * env, jobject /*self*/, jlong jobject_unit, jlong jobject_dockTarget, jfloat jfloat_timeAtDock) +{ + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceUnitDock()")); + + if (!verifyShipsEnabled()) + return; + + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, jobject_unit, "ScriptMethodsPilot::spaceUnitDock() The unit did not resolve to a ShipObject"); + if (!shipObject) + return; + + ShipController * const shipController = shipObject->getController()->asShipController(); + if (!shipController) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceUnitDock() called on unit(%s) without ShipController", shipObject->getNetworkId().getValueString().c_str())); + return; + } + + ShipObject * const targetShipObject = JavaLibrary::getShipThrow(env, jobject_dockTarget, "ScriptMethodsPilot::spaceUnitDock() The dockTarget did not resolve to a ShipObject"); + if (!targetShipObject) + return; + + ShipController * const targetShipController = targetShipObject->getController()->asShipController(); + if (!targetShipController) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceUnitDock() called on target(%s) without ShipController", targetShipObject->getNetworkId().getValueString().c_str())); + return; + } + + shipController->dock(*targetShipObject, jfloat_timeAtDock); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsPilotNamespace::spaceUnitUnDock(JNIEnv * env, jobject /*self*/, jlong jobject_unit) +{ + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceUnitUnDock()")); + + if (!verifyShipsEnabled()) + return; + + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, jobject_unit, "ScriptMethodsPilot::spaceUnitUnDock() unit did not resolve to a ShipObject"); + if (!shipObject) + return; + + ShipController * const shipController = shipObject->getController()->asShipController(); + if (!shipController) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceUnitUnDock() called on unit(%s) without a ShipController", shipObject->getNetworkId().getValueString().c_str())); + return; + } + + shipController->unDock(); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsPilotNamespace::spaceUnitIsDocked(JNIEnv * env, jobject /*self*/, jlong jobject_unit) +{ + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceUnitDock()")); + + if (!verifyShipsEnabled()) + return JNI_FALSE; + + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, jobject_unit, "ScriptMethodsPilot::spaceUnitDock() unit did not resolve to a ShipObject"); + if (!shipObject) + return JNI_FALSE; + + ShipController * const shipController = shipObject->getController()->asShipController(); + if (!shipController) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceUnitIsDocked() called on unit(%s) without ShipController", shipObject->getNetworkId().getValueString().c_str())); + return JNI_FALSE; + } + + return shipController->isDocked(); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsPilotNamespace::spaceUnitIsDocking(JNIEnv * env, jobject /*self*/, jlong jobject_unit) +{ + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceUnitIsDocking()")); + + if (!verifyShipsEnabled()) + return JNI_FALSE; + + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, jobject_unit, "ScriptMethodsPilot::spaceUnitIsDocking() unit did not resolve to a ShipObject"); + if (!shipObject) + return JNI_FALSE; + + ShipController * const shipController = shipObject->getController()->asShipController(); + if (!shipController) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceUnitIsDocking() called on unit(%s) without ShipController", shipObject->getNetworkId().getValueString().c_str())); + return JNI_FALSE; + } + + return shipController->isDocking(); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsPilotNamespace::spaceSquadSetGuardTarget(JNIEnv * /*env*/, jobject /*self*/, jint jint_squadId, jint jint_targetSquadId) +{ + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceSquadSetGuardTarget()")); + + if (!verifyShipsEnabled()) + return; + + SpaceSquad * const squad = SpaceSquadManager::getSquad(jint_squadId); + + if (!squad) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceSquadSetGuardTarget() Unable to resolve squadId(%d) to a SpaceSquad", jint_squadId)); + return; + } + + if (!squad->setGuardTarget(jint_targetSquadId)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceSquadSetGuardTarget() Unable to resolve targetSquadId(%d) to a SpaceSquad", jint_targetSquadId)); + } +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsPilotNamespace::spaceSquadGetGuardTarget(JNIEnv * /*env*/, jobject /*self*/, jint jint_squadId) +{ + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceSquadGetGuardTarget()")); + + if (!verifyShipsEnabled()) + return JNI_FALSE; + + SpaceSquad * const squad = SpaceSquadManager::getSquad(jint_squadId); + + if (!squad) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceSquadGetGuardTarget() Unable to resolve squadId(%d) to a SpaceSquad", jint_squadId)); + return JNI_FALSE; + } + + if (squad->getGuardTarget() == NULL) + { + return 0; + } + + return squad->getGuardTarget()->getId(); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsPilotNamespace::spaceSquadRemoveGuardTarget(JNIEnv * /*env*/, jobject /*self*/, jint jint_squadId) +{ + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceSquadRemoveGuardTarget()")); + + if (!verifyShipsEnabled()) + return; + + SpaceSquad * const squad = SpaceSquadManager::getSquad(jint_squadId); + + if (!squad) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceSquadRemoveGuardTarget() Unable to resolve squadId(%d) to a SpaceSquad", jint_squadId)); + return; + } + + squad->removeGuardTarget(); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsPilotNamespace::spaceSquadIsSquadIdValid(JNIEnv * env, jobject /*self*/, jint squadId) +{ + if (SpaceSquadManager::getSquad(squadId)) + return static_cast(JNI_TRUE); + return static_cast(JNI_FALSE); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsPilotNamespace::setShipAggroDistance(JNIEnv * env, jobject /*self*/, jlong jobject_unit, jfloat jfloat_aggroRadius) +{ + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, jobject_unit, "ScriptMethodsPilot::setShipAggroDistance(): jobject_unit did not resolve to a ShipObject", false); + if (!shipObject) + return; + + AiShipController * const aiShipController = (shipObject->getController()->asShipController() != NULL) ? shipObject->getController()->asShipController()->asAiShipController() : NULL; + if (!aiShipController) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::setShipAggroDistance(): unit(%s) does not have an AiShipController",shipObject->getNetworkId().getValueString().c_str())); + return; + } + + TerrainObject const * const terrain = TerrainObject::getInstance(); + + if (!terrain) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::setShipAggroDistance(): unit(%s) Unable to get the terrain object to determine the map side length.",shipObject->getNetworkId().getValueString().c_str())); + return; + } + + if (jfloat_aggroRadius > terrain->getMapWidthInMeters()) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::setShipAggroDistance(): unit(%s) aggroRadius(%f) > mapSideLength(%f).",shipObject->getNetworkId().getValueString().c_str(), jfloat_aggroRadius, terrain->getMapWidthInMeters())); + return; + } + + if (jfloat_aggroRadius <= 1.0f) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::setShipAggroDistance(): unit(%s) aggroRadius(%f) <= 1.",shipObject->getNetworkId().getValueString().c_str(), jfloat_aggroRadius)); + return; + } + + aiShipController->setAggroRadius(jfloat_aggroRadius); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsPilotNamespace::spaceUnitSetAutoAggroImmuneTime(JNIEnv * env, jobject /*self*/, jlong jobject_unit, jfloat jfloat_time) +{ + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceUnitSetAutoAggroImmuneTime() time(%.2f)", jfloat_time)); + + if (!verifyShipsEnabled()) + return; + + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, jobject_unit, "ScriptMethodsPilot::spaceUnitSetAutoAggroImmuneTime() unit did not resolve to a ShipObject"); + if (!shipObject) + return; + + if ( (jfloat_time < 0.0f) + && !WithinEpsilonInclusive(-1.0f, jfloat_time, 0.00001f)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceUnitSetAutoAggroImmuneTime(): unit(%s) The time(%f) must be >= 0.0f", shipObject->getNetworkId().getValueString().c_str(), jfloat_time)); + return; + } + + shipObject->setAutoAggroImmuneTime(jfloat_time); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsPilotNamespace::spaceUnitIsAutoAggroImmune(JNIEnv * env, jobject /*self*/, jlong jobject_unit) +{ + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceUnitIsAutoAggroImmune()")); + + if (!verifyShipsEnabled()) + return JNI_FALSE; + + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, jobject_unit, "ScriptMethodsPilot::spaceUnitIsAutoAggroImmune() unit did not resolve to a ShipObject"); + if (!shipObject) + return JNI_FALSE; + + return shipObject->isAutoAggroImmune(); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsPilotNamespace::spaceUnitSetDamageAggroImmune(JNIEnv * env, jobject /*self*/, jlong jobject_unit, jboolean jboolean_enabled) +{ + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceUnitSetDamageAggroImmune() enabled(%s)", jboolean_enabled ? "yes" : "no")); + + if (!verifyShipsEnabled()) + return; + + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, jobject_unit, "ScriptMethodsPilot::spaceUnitSetDamageAggroImmune() unit did not resolve to a ShipObject"); + if (!shipObject) + return; + + shipObject->setDamageAggroImmune(jboolean_enabled); +} + +// ---------------------------------------------------------------------- + +jobject JNICALL ScriptMethodsPilotNamespace::spaceUnitGetDockTransform(JNIEnv * /*env*/, jobject /*self*/, jlong jobject_dockTarget, jlong jobject_dockingUnit) +{ + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceUnitGetDockTransform()")); + + if (!verifyShipsEnabled()) + return 0; + + Object * dockTarget = NULL; + if (!JavaLibrary::getObject(jobject_dockTarget, dockTarget)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceUnitGetDockTransform() dockTarget did not resolve to an Object")); + return 0; + } + + Object * dockingUnit = NULL; + if (!JavaLibrary::getObject(jobject_dockingUnit, dockingUnit)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceUnitGetDockTransform() dockingUnit did not resolve to an Object")); + return 0; + } + + Transform dockHardPoint; + SpaceDockingManager::HardPointList approachHardPointList; + SpaceDockingManager::HardPointList exitHardPointList; + + SpaceDockingManager::fetchDockingProcedure(*dockingUnit, *dockTarget, dockHardPoint, approachHardPointList, exitHardPointList); + SpaceDockingManager::releaseDockingProcedure(dockingUnit->getNetworkId(), dockTarget->getNetworkId()); + + LocalRefPtr transform; + if (ScriptConversion::convert(dockHardPoint, transform)) + return transform->getReturnValue(); + return 0; +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsPilotNamespace::spaceUnitAddExclusiveAggro(JNIEnv * env, jobject /*self*/, jlong jobject_unit, jlong jobject_pilot) +{ + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceUnitAddExclusiveAggro()")); + + if (!verifyShipsEnabled()) + return; + + ShipObject * const unitShipObject = JavaLibrary::getShipThrow(env, jobject_unit, "ScriptMethodsPilot::spaceUnitAddExclusiveAggro() unit did not resolve to a ShipObject"); + + if (!unitShipObject) + { + return; + } + + AiShipController * const unitAiShipController = (unitShipObject->getController()->asShipController() != NULL) ? unitShipObject->getController()->asShipController()->asAiShipController() : NULL; + if (!unitAiShipController) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceUnitAddExclusiveAggro() called on unit(%s) without AiShipController", unitShipObject->getDebugInformation().c_str())); + return; + } + + Object * pilotObject = NULL; + if (!JavaLibrary::getObject(jobject_pilot, pilotObject)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceUnitAddExclusiveAggro() pilot did not resolve to an Object")); + return; + } + + ServerObject * const pilotServerObject = pilotObject->asServerObject(); + + if ( !pilotServerObject + || !pilotServerObject->isPlayerControlled()) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceUnitAddExclusiveAggro() pilot(%s) did not resolve to player-controlled ServerObject", pilotObject->getDebugInformation().c_str())); + return; + } + + unitAiShipController->addExclusiveAggro(pilotObject->getNetworkId()); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsPilotNamespace::spaceUnitRemoveExclusiveAggro(JNIEnv * env, jobject /*self*/, jlong jobject_unit, jlong jobject_pilot) +{ + LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("ScriptMethodsPilot::spaceUnitRemoveExclusiveAggro()")); + + if (!verifyShipsEnabled()) + return; + + ShipObject * const unitShipObject = JavaLibrary::getShipThrow(env, jobject_unit, "ScriptMethodsPilot::spaceUnitRemoveExclusiveAggro() unit did not resolve to a ShipObject"); + + if (!unitShipObject) + { + return; + } + + AiShipController * const unitAiShipController = (unitShipObject->getController()->asShipController() != NULL) ? unitShipObject->getController()->asShipController()->asAiShipController() : NULL; + if (!unitAiShipController) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceUnitRemoveExclusiveAggro() called on unit(%s) without AiShipController", unitShipObject->getDebugInformation().c_str())); + return; + } + + Object * pilotObject = NULL; + if (!JavaLibrary::getObject(jobject_pilot, pilotObject)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceUnitRemoveExclusiveAggro() pilot did not resolve to an Object")); + return; + } + + ServerObject * const pilotServerObject = pilotObject->asServerObject(); + + if ( !pilotServerObject + || !pilotServerObject->isPlayerControlled()) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsPilot::spaceUnitRemoveExclusiveAggro() pilot(%s) did not resolve to player-controlled ServerObject", pilotObject->getDebugInformation().c_str())); + return; + } + + unitAiShipController->removeExclusiveAggro(pilotObject->getNetworkId()); +} + +// ====================================================================== diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsPlanet.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsPlanet.cpp new file mode 100644 index 00000000..9f708a22 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsPlanet.cpp @@ -0,0 +1,551 @@ +// ====================================================================== +// +// ScriptMethodsPlanet.cpp +// asommers +// +// copyright 2002, sony online entertainment +// +// ====================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "UnicodeUtils.h" +#include "serverGame/ConfigServerGame.h" +#include "serverGame/GameServer.h" +#include "serverGame/PlanetObject.h" +#include "serverGame/ServerUniverse.h" +#include "serverGame/ServerWorld.h" +#include "sharedGame/SharedBuildoutAreaManager.h" +#include "sharedGame/TravelManager.h" +#include "sharedGame/TravelPoint.h" +#include "sharedMath/Vector.h" +#include "sharedNetworkMessages/EnterTicketPurchaseModeMessage.h" +#include "sharedNetworkMessages/GenericValueTypeMessage.h" + +using namespace JNIWrappersNamespace; + + +// ====================================================================== +// ScriptMethodsPlanetNamespace +// ====================================================================== + +namespace ScriptMethodsPlanetNamespace +{ + bool install(); + + jboolean JNICALL addPlanetTravelPoint (JNIEnv* env, jobject self, jstring planetName, jstring travelPointName, jobject location, jint cost, jboolean interplanetary, jint type); + jboolean JNICALL removePlanetTravelPoint (JNIEnv* env, jobject self, jstring planetName, jstring travelPointName); + jobjectArray JNICALL getPlanetTravelPoints (JNIEnv* env, jobject self, jstring planetName); + jstring JNICALL getPlanetTravelPointGcwContestedRegion (JNIEnv* env, jobject self, jstring planetName, jstring travelPointName); + jobject JNICALL getPlanetTravelPointLocation (JNIEnv* env, jobject self, jstring planetName, jstring travelPointName); + jint JNICALL getPlanetTravelPointCost (JNIEnv* env, jobject self, jstring planetName, jstring travelPointName); + jboolean JNICALL getPlanetTravelPointInterplanetary (JNIEnv* env, jobject self, jstring planetName, jstring travelPointName); + jint JNICALL getPlanetTravelCost (JNIEnv* env, jobject self, jstring sourcePlanetName, jstring destinationPlanetName); + jboolean JNICALL enterClientTicketPurchaseMode (JNIEnv* env, jobject self, jlong player, jstring startingPlanetName, jstring startingTravelPointName, jboolean instantTravel); + jboolean JNICALL isAreaTooFullForTravel (JNIEnv* env, jobject self, jstring planetName_j, jint x, jint z); + jstring JNICALL getBuildoutAreaName( JNIEnv *env, jobject self, jfloat x, jfloat z, jstring scene ); + jfloatArray JNICALL getBuildoutAreaSizeAndCenter(JNIEnv *env, jobject self, jfloat x, jfloat z, jstring scene, jboolean ignoreInternal, jboolean allowComposite); + void JNICALL requestSameServer(JNIEnv *env, jobject self, jlong object1, jlong object2); +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsPlanetNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsPlanetNamespace::c)} + JF("addPlanetTravelPoint", "(Ljava/lang/String;Ljava/lang/String;Lscript/location;IZI)Z", addPlanetTravelPoint), + JF("removePlanetTravelPoint", "(Ljava/lang/String;Ljava/lang/String;)Z", removePlanetTravelPoint), + JF("getPlanetTravelPoints", "(Ljava/lang/String;)[Ljava/lang/String;", getPlanetTravelPoints), + JF("getPlanetTravelPointGcwContestedRegion", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", getPlanetTravelPointGcwContestedRegion), + JF("getPlanetTravelPointLocation", "(Ljava/lang/String;Ljava/lang/String;)Lscript/location;", getPlanetTravelPointLocation), + JF("getPlanetTravelPointCost", "(Ljava/lang/String;Ljava/lang/String;)I", getPlanetTravelPointCost), + JF("getPlanetTravelPointInterplanetary", "(Ljava/lang/String;Ljava/lang/String;)Z", getPlanetTravelPointInterplanetary), + JF("getPlanetTravelCost", "(Ljava/lang/String;Ljava/lang/String;)I", getPlanetTravelCost), + JF("_enterClientTicketPurchaseMode", "(JLjava/lang/String;Ljava/lang/String;Z)Z", enterClientTicketPurchaseMode), + JF("isAreaTooFullForTravel", "(Ljava/lang/String;II)Z", isAreaTooFullForTravel), + JF("getBuildoutAreaName", "(FFLjava/lang/String;)Ljava/lang/String;", getBuildoutAreaName), + JF("getBuildoutAreaSizeAndCenter", "(FFLjava/lang/String;ZZ)[F", getBuildoutAreaSizeAndCenter), + JF("_requestSameServer", "(JJ)V", requestSameServer), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +// ====================================================================== + +jboolean JNICALL ScriptMethodsPlanetNamespace::addPlanetTravelPoint (JNIEnv* const /*env*/, jobject /*self*/, jstring jstring_planetName, jstring jstring_travelPointName, jobject jobject_location, jint cost, jboolean jboolean_interplanetary, jint type) +{ + //-- get the planet object + JavaStringParam javaStringParam_planetName (jstring_planetName); + std::string planetName; + if (!JavaLibrary::convert (javaStringParam_planetName, planetName)) + { + DEBUG_WARNING (true, ("addPlanetTravelPoint (): DB failed to convert parameter 1 (planetName) to string")); + return JNI_FALSE; + } + + PlanetObject* const planetObject = ServerUniverse::getInstance ().getPlanetByName (planetName); + if (!planetObject) + { + DEBUG_WARNING (true, ("addPlanetTravelPoint (): DB planet %s does not exist", planetName.c_str ())); + return JNI_FALSE; + } + + //-- get the name of the travel point + JavaStringParam javaStringParam_travelPointName (jstring_travelPointName); + std::string travelPointName; + if (!JavaLibrary::convert (javaStringParam_travelPointName, travelPointName)) + { + DEBUG_WARNING (true, ("addPlanetTravelPoint (): DB failed to convert parameter 2 (travelPointName) to string")); + return JNI_FALSE; + } + + //-- get (and verify) location + std::string sceneId; + Vector position_w; + if (!ScriptConversion::convertWorld (jobject_location, position_w, sceneId)) + { + DEBUG_WARNING (true, ("addPlanetTravelPoint (): DB failed to convert parameter 3 (location) to sceneId, and position_w")); + return JNI_FALSE; + } + + //-- make sure the planet name matches the location name +// if (sceneId != planetName) +// { +// DEBUG_WARNING (true, ("addPlanetTravelPoint (): DB planet %s does not match scene id %s in travel point location %s", planetName.c_str (), sceneId.c_str (), travelPointName.c_str ())); +// return FALSE; +// } + + //-- add to the planet + planetObject->addTravelPoint (travelPointName, position_w, cost, jboolean_interplanetary == JNI_TRUE, static_cast(type)); + + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsPlanetNamespace::removePlanetTravelPoint (JNIEnv* const /*env*/, jobject /*self*/, jstring jstring_planetName, jstring jstring_travelPointName) +{ + //-- get the planet object + JavaStringParam javaStringParam_planetName (jstring_planetName); + std::string planetName; + if (!JavaLibrary::convert (javaStringParam_planetName, planetName)) + { + DEBUG_WARNING (true, ("removePlanetTravelPoint (): DB failed to convert parameter 1 (planetName) to string")); + return JNI_FALSE; + } + + PlanetObject* const planetObject = ServerUniverse::getInstance ().getPlanetByName (planetName); + if (!planetObject) + { + DEBUG_WARNING (true, ("removePlanetTravelPoint (): DB planet %s does not exist", planetName.c_str ())); + return JNI_FALSE; + } + + //-- get the name of the travel point + JavaStringParam javaStringParam_travelPointName (jstring_travelPointName); + std::string travelPointName; + if (!JavaLibrary::convert (javaStringParam_travelPointName, travelPointName)) + { + DEBUG_WARNING (true, ("removePlanetTravelPoint (): DB failed to convert parameter 2 (travelPointName) to string")); + return JNI_FALSE; + } + + //-- remove from the planet + planetObject->removeTravelPoint (travelPointName); + + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsPlanetNamespace::getPlanetTravelPoints (JNIEnv* env, jobject /*self*/, jstring jstring_planetName) +{ + //-- get the planet object + JavaStringParam javaStringParam_planetName (jstring_planetName); + std::string planetName; + if (!JavaLibrary::convert (javaStringParam_planetName, planetName)) + { + DEBUG_WARNING (true, ("getPlanetTravelPoints (): DB failed to convert parameter 1 (planetName) to string")); + return JNI_FALSE; + } + + PlanetObject* const planetObject = ServerUniverse::getInstance ().getPlanetByName (planetName); + if (!planetObject) + { + DEBUG_WARNING (true, ("getPlanetTravelPoints (): DB planet %s does not exist", planetName.c_str ())); + return JNI_FALSE; + } + + //-- create list of travel points + std::vector travelPointNameList; + planetObject->getTravelPointNameList (travelPointNameList); + + //-- convert to a string array + LocalObjectArrayRefPtr jobjectArray_travelPointNameList = createNewObjectArray(travelPointNameList.size (), JavaLibrary::getClsString()); + + uint i; + for (i = 0; i < travelPointNameList.size (); ++i) + { + JavaString jstring_travelPointName (Unicode::narrowToWide (travelPointNameList [i])); + setObjectArrayElement (*jobjectArray_travelPointNameList, i, jstring_travelPointName); + } + + return jobjectArray_travelPointNameList->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsPlanetNamespace::getPlanetTravelPointGcwContestedRegion (JNIEnv* env, jobject self, jstring jstring_planetName, jstring jstring_travelPointName) +{ + //-- get the planet object + JavaStringParam javaStringParam_planetName (jstring_planetName); + std::string planetName; + if (!JavaLibrary::convert (javaStringParam_planetName, planetName)) + { + DEBUG_WARNING (true, ("getPlanetTravelPointGcwContestedRegion (): DB failed to convert parameter 1 (planetName) to string")); + return 0; + } + + PlanetObject* const planetObject = ServerUniverse::getInstance ().getPlanetByName (planetName); + if (!planetObject) + { + DEBUG_WARNING (true, ("getPlanetTravelPointGcwContestedRegion (): DB planet %s does not exist", planetName.c_str ())); + return 0; + } + + //-- get the name of the travel point + JavaStringParam javaStringParam_travelPointName (jstring_travelPointName); + std::string travelPointName; + if (!JavaLibrary::convert (javaStringParam_travelPointName, travelPointName)) + { + DEBUG_WARNING (true, ("getPlanetTravelPointGcwContestedRegion (): DB failed to convert parameter 2 (travelPointName) to string")); + return 0; + } + + const TravelPoint* const travelPoint = planetObject->getTravelPoint (travelPointName); + if (!travelPoint) + { + DEBUG_WARNING (true, ("getPlanetTravelPointGcwContestedRegion (): DB travel point %s does not exist on planet %s", travelPointName.c_str (), planetName.c_str ())); + return 0; + } + + if (travelPoint->getGcwContestedRegion().empty()) + { + return 0; + } + + return JavaString(travelPoint->getGcwContestedRegion().c_str()).getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jobject JNICALL ScriptMethodsPlanetNamespace::getPlanetTravelPointLocation (JNIEnv* const /*env*/, jobject /*self*/, jstring jstring_planetName, jstring jstring_travelPointName) +{ + //-- get the planet object + JavaStringParam javaStringParam_planetName (jstring_planetName); + std::string planetName; + if (!JavaLibrary::convert (javaStringParam_planetName, planetName)) + { + DEBUG_WARNING (true, ("getPlanetTravelPointLocation (): DB failed to convert parameter 1 (planetName) to string")); + return 0; + } + + PlanetObject* const planetObject = ServerUniverse::getInstance ().getPlanetByName (planetName); + if (!planetObject) + { + DEBUG_WARNING (true, ("getPlanetTravelPointLocation (): DB planet %s does not exist", planetName.c_str ())); + return 0; + } + + //-- get the name of the travel point + JavaStringParam javaStringParam_travelPointName (jstring_travelPointName); + std::string travelPointName; + if (!JavaLibrary::convert (javaStringParam_travelPointName, travelPointName)) + { + DEBUG_WARNING (true, ("getPlanetTravelPointLocation (): DB failed to convert parameter 2 (travelPointName) to string")); + return 0; + } + + const TravelPoint* const travelPoint = planetObject->getTravelPoint (travelPointName); + if (!travelPoint) + { + DEBUG_WARNING (true, ("getPlanetTravelPointLocation (): DB travel point %s does not exist on planet %s", travelPointName.c_str (), planetName.c_str ())); + return 0; + } + + //-- transform into location + const Vector& position_w = travelPoint->getPosition_w (); + + LocalRefPtr location; + if (!ScriptConversion::convert (position_w, NetworkId (), location)) + { + DEBUG_WARNING (true, ("getPlanetTravelPointLocation (): PB could not convert travel point %s to location (scene %s, position <%1.2f, %1.2f, %1.2f>)", travelPointName.c_str (), planetName.c_str (), position_w.x, position_w.y, position_w.z)); + return 0; + } + + return location->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsPlanetNamespace::getPlanetTravelPointCost (JNIEnv* const /*env*/, jobject /*self*/, jstring jstring_planetName, jstring jstring_travelPointName) +{ + //-- get the planet object + JavaStringParam javaStringParam_planetName (jstring_planetName); + std::string planetName; + if (!JavaLibrary::convert (javaStringParam_planetName, planetName)) + { + DEBUG_WARNING (true, ("getPlanetTravelPointCost (): DB failed to convert parameter 1 (planetName) to string")); + return 0; + } + + PlanetObject* const planetObject = ServerUniverse::getInstance ().getPlanetByName (planetName); + if (!planetObject) + { + DEBUG_WARNING (true, ("getPlanetTravelPointCost (): DB planet %s does not exist", planetName.c_str ())); + return 0; + } + + //-- get the name of the travel point + JavaStringParam javaStringParam_travelPointName (jstring_travelPointName); + std::string travelPointName; + if (!JavaLibrary::convert (javaStringParam_travelPointName, travelPointName)) + { + DEBUG_WARNING (true, ("getPlanetTravelPointCost (): DB failed to convert parameter 2 (travelPointName) to string")); + return 0; + } + + const TravelPoint* const travelPoint = planetObject->getTravelPoint (travelPointName); + if (!travelPoint) + { + DEBUG_WARNING (true, ("getPlanetTravelPointCost (): DB travel point %s does not exist on planet %s", travelPointName.c_str (), planetName.c_str ())); + return 0; + } + + return travelPoint->getCost (); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsPlanetNamespace::getPlanetTravelPointInterplanetary (JNIEnv* const /*env*/, jobject /*self*/, jstring jstring_planetName, jstring jstring_travelPointName) +{ + //-- get the planet object + JavaStringParam javaStringParam_planetName (jstring_planetName); + std::string planetName; + if (!JavaLibrary::convert (javaStringParam_planetName, planetName)) + { + DEBUG_WARNING (true, ("getPlanetTravelPointInterplanetary (): DB failed to convert parameter 1 (planetName) to string")); + return 0; + } + + PlanetObject* const planetObject = ServerUniverse::getInstance ().getPlanetByName (planetName); + if (!planetObject) + { + DEBUG_WARNING (true, ("getPlanetTravelPointInterplanetary (): DB planet %s does not exist", planetName.c_str ())); + return 0; + } + + //-- get the name of the travel point + JavaStringParam javaStringParam_travelPointName (jstring_travelPointName); + std::string travelPointName; + if (!JavaLibrary::convert (javaStringParam_travelPointName, travelPointName)) + { + DEBUG_WARNING (true, ("getPlanetTravelPointInterplanetary (): DB failed to convert parameter 2 (travelPointName) to string")); + return 0; + } + + const TravelPoint* const travelPoint = planetObject->getTravelPoint (travelPointName); + if (!travelPoint) + { + DEBUG_WARNING (true, ("getPlanetTravelPointInterplanetary (): DB travel point %s does not exist on planet %s", travelPointName.c_str (), planetName.c_str ())); + return 0; + } + + return travelPoint->getInterplanetary (); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsPlanetNamespace::getPlanetTravelCost (JNIEnv* const /*env*/, jobject /*self*/, jstring jstring_planetName1, jstring jstring_planetName2) +{ + //-- get planet 1 name + JavaStringParam javaStringParam_planetName1 (jstring_planetName1); + std::string planetName1; + if (!JavaLibrary::convert (javaStringParam_planetName1, planetName1)) + { + DEBUG_WARNING (true, ("getPlanetTravelCost (): DB failed to convert parameter 1 (planetName1) to string")); + return 0; + } + + //-- get planet 2 name + JavaStringParam javaStringParam_planetName2 (jstring_planetName2); + std::string planetName2; + if (!JavaLibrary::convert (javaStringParam_planetName2, planetName2)) + { + DEBUG_WARNING (true, ("getPlanetTravelCost (): DB failed to convert parameter 2 (planetName2) to string")); + return 0; + } + + //-- find and return the cost + int cost; + if (!TravelManager::getPlanetSingleHopCost (planetName1, planetName2, cost)) + { + DEBUG_WARNING (true, ("getPlanetTravelCost (): DB could not get the cost between planet %s and planet %s", planetName1.c_str (), planetName2.c_str ())); + return 0; + } + + return cost; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsPlanetNamespace::enterClientTicketPurchaseMode (JNIEnv* /*env*/, jobject /*self*/, jlong jobject_player, jstring jstring_planetName, jstring jstring_travelPointName, jboolean instantTravel) +{ + //-- get the player object + ServerObject* player = 0; + if (!JavaLibrary::getObject (jobject_player, player)) + { + DEBUG_WARNING (true, ("enterClientTicketPurchaseMode (): DB could not find player object")); + return JNI_FALSE; + } + + //-- get the client associated with the player + Client* const client = player->getClient (); + if (!client) + { + DEBUG_WARNING (true, ("enterClientTicketPurchaseMode (): PB could get the player's client object")); + return JNI_FALSE; + } + + //-- make sure we have a valid planet name + JavaStringParam javaStringParam_planetName (jstring_planetName); + std::string planetName; + if (!JavaLibrary::convert (javaStringParam_planetName, planetName)) + { + DEBUG_WARNING (true, ("enterClientTicketPurchaseMode (): DB failed to convert parameter 2 (planetName) to string")); + return JNI_FALSE; + } + + //-- make sure we have a valid travel point name + JavaStringParam javaStringParam_travelPointName (jstring_travelPointName); + std::string travelPointName; + if (!JavaLibrary::convert (javaStringParam_travelPointName, travelPointName)) + { + DEBUG_WARNING (true, ("enterClientTicketPurchaseMode (): DB failed to convert parameter 3 (travelPointName) to string")); + return JNI_FALSE; + } + + //-- send the message to the client + EnterTicketPurchaseModeMessage const msg(planetName, travelPointName, instantTravel == JNI_TRUE); + client->send(msg, true); + + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsPlanetNamespace::isAreaTooFullForTravel (JNIEnv* const /*env*/, jobject /*self*/, jstring planetName_j, jint x, jint z) +{ + std::string planetName; + JavaStringParam planetName_jsp (planetName_j); + if (!JavaLibrary::convert (planetName_jsp, planetName)) + { + WARNING(true,("isAreaTooFullForTravel could not convert the planet name to string")); + return JNI_TRUE; // invalid locations are always too full + } + int const population = ServerUniverse::getInstance().getPopulationAtLocation(planetName, x, z); + if (population > ConfigServerGame::getMaxPopulationForNewbieTravel()) + return JNI_TRUE; + else + return JNI_FALSE; +} + +// ---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsPlanetNamespace::getBuildoutAreaName( JNIEnv *const /*env*/, jobject /*self*/, const jfloat x, const jfloat z, const jstring sceneId_j ) +{ + std::string sceneId; + JavaStringParam sceneId_jsp (sceneId_j); + if (!JavaLibrary::convert (sceneId_jsp, sceneId)) + { + WARNING(true,("getBuildoutAreaName could not convert the scene id to string")); + return 0; + } + + const BuildoutArea * const area = SharedBuildoutAreaManager::findBuildoutAreaAtPosition(sceneId.c_str(), x, z, false ); + + return area ? JavaString( area->areaName ).getReturnValue() : 0; +} + +// ---------------------------------------------------------------------- + +jfloatArray JNICALL ScriptMethodsPlanetNamespace::getBuildoutAreaSizeAndCenter(JNIEnv *const /*env*/, jobject /*self*/, const jfloat x, const jfloat z, const jstring sceneId_j, const jboolean ignoreInternal, const jboolean allowComposite) +{ + std::string sceneId; + JavaStringParam sceneId_jsp (sceneId_j); + if (!JavaLibrary::convert (sceneId_jsp, sceneId)) + { + WARNING(true,("getBuildoutAreaSizeAndCenter could not convert the scene id to string")); + return 0; + } + + const BuildoutArea * const area = SharedBuildoutAreaManager::findBuildoutAreaAtPosition(sceneId.c_str(), x, z, (ignoreInternal == JNI_TRUE)); + if (!area) + return 0; + + LocalFloatArrayRefPtr valueArray = createNewFloatArray(static_cast(4)); + if (valueArray == LocalFloatArrayRef::cms_nullPtr) + { + return 0; + } + + Vector2d areaSize = area->getSize(allowComposite == JNI_TRUE); + + jfloat value = static_cast(areaSize.x); + setFloatArrayRegion(*valueArray, 0, 1, &value); + + value = static_cast(areaSize.y); + setFloatArrayRegion(*valueArray, 1, 1, &value); + + value = static_cast(area->getXCenterPoint(allowComposite == JNI_TRUE)); + setFloatArrayRegion(*valueArray, 2, 1, &value); + + value = static_cast(area->getZCenterPoint(allowComposite == JNI_TRUE)); + setFloatArrayRegion(*valueArray, 3, 1, &value); + + return valueArray->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsPlanetNamespace::requestSameServer(JNIEnv *env, jobject self, jlong object1, jlong object2) +{ + ServerObject const * serverObject1 = 0; + if (!JavaLibrary::getObject(object1, serverObject1)) + { + WARNING(true, ("requestSameServer - could not find object %s", NetworkId(object1).getValueString().c_str())); + return; + } + + ServerObject const * serverObject2 = 0; + if (!JavaLibrary::getObject(object2, serverObject2)) + { + WARNING(true, ("requestSameServer - could not find object %s", NetworkId(object2).getValueString().c_str())); + return; + } + + GenericValueTypeMessage > const rssMessage( + "RequestSameServer", + std::make_pair(serverObject1->getNetworkId(), serverObject2->getNetworkId())); + + GameServer::getInstance().sendToPlanetServer(rssMessage); +} + +// ====================================================================== diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsPlayerAccount.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsPlayerAccount.cpp new file mode 100644 index 00000000..3830b681 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsPlayerAccount.cpp @@ -0,0 +1,977 @@ +// ====================================================================== +// +// ScriptMethodsPlayerAccount.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "serverGame/Chat.h" +#include "serverGame/ConfigServerGame.h" +#include "serverGame/ContainerInterface.h" +#include "serverGame/CreatureObject.h" +#include "serverGame/GameServer.h" +#include "serverGame/MessageToQueue.h" +#include "serverGame/NameManager.h" +#include "serverGame/PlayerCreationManagerServer.h" +#include "serverGame/PlayerCreatureController.h" +#include "serverGame/PlayerObject.h" +#include "serverGame/ServerCreatureObjectTemplate.h" +#include "serverNetworkMessages/CentralGameServerMessages.h" +#include "serverNetworkMessages/RenameCharacterMessage.h" +#include "serverScript/ScriptParameters.h" +#include "sharedFoundation/ConstCharCrcLowerString.h" +#include "sharedLog/Log.h" +#include "sharedNetworkMessages/GenericValueTypeMessage.h" +#include "sharedNetworkMessages/NameErrors.h" +#include "serverNetworkMessages/TransferRequestMoveValidation.h" +#include "serverNetworkMessages/VerifyAndLockName.h" +#include "serverScript/GameScriptObject.h" +#include "sharedObject/ObjectTemplateList.h" +#include "sharedObject/SlotId.h" +#include "sharedObject/SlotIdManager.h" +#include "sharedObject/SlottedContainer.h" +#include "sharedUtility/DataTableManager.h" +#include "sharedUtility/DataTable.h" +#include "serverUtility/FreeCtsDataTable.h" +#include "UnicodeUtils.h" + +#include + +using namespace JNIWrappersNamespace; + + +// ====================================================================== +// ScriptMethodsPlayerAccountNamespace +// ====================================================================== + +namespace ScriptMethodsPlayerAccountNamespace +{ + bool install(); + + jlong JNICALL getPlayerObject(JNIEnv *env, jobject self, jlong creature); + jboolean JNICALL isIgnoring(JNIEnv *env, jobject self, jlong player, jstring who); + jboolean JNICALL adjustLotCount(JNIEnv *env, jobject self, jlong player, jint adjustment); + jint JNICALL getAccountNumLots(JNIEnv *env, jobject self, jlong player); + jint JNICALL getGameFeatureBits(JNIEnv *env, jobject self, jlong player); + jint JNICALL getSubscriptionFeatureBits(JNIEnv *env, jobject self, jlong player); + jboolean JNICALL isUsingAdminLogin(JNIEnv *env, jobject self, jlong player); + jboolean JNICALL isWarden(JNIEnv *env, jobject self, jlong player); + jobject JNICALL getAccountTimeData(JNIEnv * env, jobject self, jlong target); + jint JNICALL getPlayerLastLoginTime(JNIEnv *env, jobject self, jlong player); + jboolean JNICALL isFreeTrialAccount(JNIEnv *env, jobject self, jlong player); + jboolean JNICALL setCompletedTutorial(JNIEnv *env, jobject self, jlong player, jboolean value); + void JNICALL logActivity(JNIEnv *env, jobject self, jlong player, jint activityType); + jboolean JNICALL isAccountQualifiedForHousePackup(JNIEnv *env, jobject self, jlong target); + jobject JNICALL getCharacterCtsHistory(JNIEnv * env, jobject self, jlong player); + jobjectArray JNICALL getCharacterRetroactiveCtsObjvars(JNIEnv * env, jobject self, jlong player); + jobjectArray JNICALL qualifyForFreeCts(JNIEnv *env, jobject self, jlong player); + void JNICALL validateFreeCts(JNIEnv *env, jobject self, jlong player, jstring destinationGalaxy, jstring destinationCharacterName); + void JNICALL performFreeCts(JNIEnv *env, jobject self, jlong player, jstring destinationGalaxy, jstring destinationCharacterName); + void JNICALL validateCts(JNIEnv *env, jobject self, jlong player, jstring destinationGalaxy, jstring destinationCharacterName); + void JNICALL performCts(JNIEnv *env, jobject self, jlong player, jstring destinationGalaxy, jstring destinationCharacterName); + void JNICALL validateRenameCharacter(JNIEnv *env, jobject self, jlong player, jstring newName); + void JNICALL renameCharacterReleaseNameReservation(JNIEnv *env, jobject self, jlong player); + void JNICALL renameCharacter(JNIEnv *env, jobject self, jlong player, jstring newName); + jint JNICALL getPlayerStationId(JNIEnv *env, jobject self, jlong player); +} + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsPlayerAccountNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsPlayerAccountNamespace::c)} + JF("_getPlayerObject", "(J)J", getPlayerObject), + JF("_isIgnoring", "(JLjava/lang/String;)Z", isIgnoring), + JF("_adjustLotCount", "(JI)Z", adjustLotCount), + JF("_getAccountNumLots", "(J)I", getAccountNumLots), + JF("_getGameFeatureBits", "(J)I", getGameFeatureBits), + JF("_getSubscriptionFeatureBits", "(J)I", getSubscriptionFeatureBits), + JF("_isUsingAdminLogin", "(J)Z", isUsingAdminLogin), + JF("_isWarden", "(J)Z", isWarden), + JF("_getAccountTimeData", "(J)Lscript/dictionary;", getAccountTimeData), + JF("_getPlayerLastLoginTime", "(J)I", getPlayerLastLoginTime), + JF("_isFreeTrialAccount", "(J)Z", isFreeTrialAccount), + JF("_setCompletedTutorial", "(JZ)Z", setCompletedTutorial), + JF("__logActivity", "(JI)V", logActivity), + JF("_isAccountQualifiedForHousePackup", "(J)Z", isAccountQualifiedForHousePackup), + JF("_getCharacterCtsHistory", "(J)Lscript/dictionary;", getCharacterCtsHistory), + JF("_getCharacterRetroactiveCtsObjvars", "(J)[Lscript/dictionary;", getCharacterRetroactiveCtsObjvars), + JF("_qualifyForFreeCts", "(J)[Ljava/lang/String;", qualifyForFreeCts), + JF("_validateFreeCts", "(JLjava/lang/String;Ljava/lang/String;)V", validateFreeCts), + JF("_performFreeCts", "(JLjava/lang/String;Ljava/lang/String;)V", performFreeCts), + JF("_validateCts", "(JLjava/lang/String;Ljava/lang/String;)V", validateCts), + JF("_performCts", "(JLjava/lang/String;Ljava/lang/String;)V", performCts), + JF("_validateRenameCharacter", "(JLjava/lang/String;)V", validateRenameCharacter), + JF("_renameCharacterReleaseNameReservation", "(J)V", renameCharacterReleaseNameReservation), + JF("_renameCharacter", "(JLjava/lang/String;)V", renameCharacter), + JF("_getPlayerStationId", "(J)I", getPlayerStationId), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +// ====================================================================== +// Methods for dealing with PlayerObjects and (Station) account data + +jlong JNICALL ScriptMethodsPlayerAccountNamespace::getPlayerObject(JNIEnv *env, jobject self, jlong creature) +{ + UNREF(self); + NOT_NULL(env); + + jlong objId = 0; + + ServerObject * creatureServerObject = NULL; + if (JavaLibrary::getObject(creature,creatureServerObject)) + { + SlotId slot = SlotIdManager::findSlotId(ConstCharCrcLowerString("ghost")); + if (slot != SlotId::invalid) + { + SlottedContainer const * const slots = ContainerInterface::getSlottedContainer(*creatureServerObject); + if (slots) + { + Container::ContainerErrorCode tmp = Container::CEC_Success; + CachedNetworkId playerObjectId = slots->getObjectInSlot(slot, tmp); + objId = playerObjectId.getValue(); + } + } + } + return objId; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsPlayerAccountNamespace::isIgnoring(JNIEnv *env, jobject self, jlong player, jstring who) +{ + PlayerObject *playerObject = 0; + if (!JavaLibrary::getObject(player, playerObject)) + { + DEBUG_WARNING(true, ("JavaLibrary::isIgnoring: bad player object")); + return JNI_FALSE; + } + std::string whoStr; + if (!JavaLibrary::convert(JavaStringParam(who), whoStr)) + { + DEBUG_WARNING(true, ("JavaLibrary::isIgnoring: bad who string")); + return JNI_FALSE; + } + + if (playerObject->isIgnoring(whoStr)) + return JNI_TRUE; + return JNI_FALSE; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsPlayerAccountNamespace::adjustLotCount(JNIEnv *env, jobject self, jlong player, jint adjustment) +{ + PlayerObject *playerObject = 0; + if (!JavaLibrary::getObject(player, playerObject)) + { + DEBUG_WARNING(true, ("JavaLibrary::adjustLotCount: bad player object")); + return JNI_FALSE; + } + + return playerObject->adjustLotCount(adjustment); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsPlayerAccountNamespace::getAccountNumLots(JNIEnv *env, jobject self, jlong player) +{ + PlayerObject *playerObject = 0; + if (!JavaLibrary::getObject(player, playerObject)) + { + DEBUG_WARNING(true, ("JavaLibrary::getAccountNumLots: bad player object")); + return 0; + } + + return playerObject->getAccountNumLots(); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsPlayerAccountNamespace::getGameFeatureBits(JNIEnv *env, jobject self, jlong player) +{ + CreatureObject *playerObject = 0; + if (!JavaLibrary::getObject(player, playerObject)) + { + DEBUG_WARNING(true, ("JavaLibrary::getGameFeatureBits: bad player object")); + return 0; + } + + if (!playerObject->getClient()) + { + DEBUG_WARNING(true, ("JavaLibrary::getGameFeatureBits: player object had no client")); + return 0; + } + + return playerObject->getClient()->getGameFeatures(); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsPlayerAccountNamespace::getSubscriptionFeatureBits(JNIEnv *env, jobject self, jlong player) +{ + CreatureObject *playerObject = 0; + if (!JavaLibrary::getObject(player, playerObject)) + { + DEBUG_WARNING(true, ("JavaLibrary::GetSubscriptionFeatureBits: bad player object")); + return 0; + } + + if (!playerObject->getClient()) + { + DEBUG_WARNING(true, ("JavaLibrary::GetSubscriptionFeatureBits: player object had no client")); + return 0; + } + + return playerObject->getClient()->getSubscriptionFeatures(); +} + +// ---------------------------------------------------------------------- + +/** + * Returns info on how long a player has been playing the game. + * + * @param env Java environment + * @param self class calling this function + * @param target the id of the player + * + * @return a dictionary with the player's account time info: + * "total_subscription_time" the total amount of time since the player first subscribed + * "total_entitled_time" the total amount of time the player has been billed + * "last_login_time" the amount of time passed since the player last logged in + * "entitled_login_time" the amount of billing time since the player last logged in + */ +jobject JNICALL ScriptMethodsPlayerAccountNamespace::getAccountTimeData(JNIEnv * env, jobject self, jlong target) +{ + const CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return 0; + + const PlayerObject * player = PlayerCreatureController::getPlayerObject( + creature); + if (player == NULL) + return 0; + + const Client * client = creature->getClient(); + if (client == NULL) + return 0; + + // get the values that came from Platform + int total_time = static_cast(client->getEntitlementTotalTime()); + int entitled_time = static_cast(client->getEntitlementEntitledTime()); + int login_time = static_cast(client->getEntitlementTotalTimeSinceLastLogin()); + int entitled_login_time = static_cast(client->getEntitlementEntitledTimeSinceLastLogin()); + + // override with any global configuration specified values + int temp = ConfigServerGame::getMinEntitledTime(); + + if ((temp >= 0) && (temp > entitled_time)) + entitled_time = temp; + + // override with any manually created test values on the creature + if (creature->getObjVars().getItem("_testVeteran.total_time", temp)) + total_time = temp; + + if (creature->getObjVars().getItem("_testVeteran.entitled_time", temp)) + entitled_time = temp; + + if (creature->getObjVars().getItem("_testVeteran.login_time", temp)) + login_time = temp; + + if (creature->getObjVars().getItem("_testVeteran.entitled_login_time", temp)) + entitled_login_time = temp; + + // don't return any information if all the values are 0 because it + // indicates that Platform does not have the information available + // at this time; we'll try again the next time the player logs in. + if ((total_time == 0) && (entitled_time == 0) && (login_time == 0) && (entitled_login_time == 0)) + return 0; + + LocalRefPtr dictionary = createNewObject(JavaLibrary::getClsDictionary(), JavaLibrary::getMidDictionary()); + if (dictionary != LocalRef::cms_nullPtr) + { + callObjectMethod(*dictionary, JavaLibrary::getMidDictionaryPutInt(), JavaString("total_subscription_time").getValue(), total_time); + callObjectMethod(*dictionary, JavaLibrary::getMidDictionaryPutInt(), JavaString("total_entitled_time").getValue(), entitled_time); + callObjectMethod(*dictionary, JavaLibrary::getMidDictionaryPutInt(), JavaString("last_login_time").getValue(), login_time); + callObjectMethod(*dictionary, JavaLibrary::getMidDictionaryPutInt(), JavaString("entitled_login_time").getValue(), entitled_login_time); + if (env->ExceptionCheck()) + { + env->ExceptionDescribe(); + return 0; + } + } + return dictionary->getReturnValue(); +} // JavaLibrary::getAccountTimeData + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsPlayerAccountNamespace::getPlayerLastLoginTime(JNIEnv *env, jobject self, jlong player) +{ + NetworkId playerId(player); + return NameManager::getInstance().getPlayerLastLoginTime(playerId); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsPlayerAccountNamespace::isUsingAdminLogin(JNIEnv *env, jobject self, jlong player) +{ + CreatureObject *playerObject = 0; + if (!JavaLibrary::getObject(player, playerObject)) + { + DEBUG_WARNING(true, ("JavaLibrary::isUsingAdminLogin: bad player object")); + return false; + } + + if (!playerObject->getClient()) + { + DEBUG_WARNING(true, ("JavaLibrary::isUsingAdminLogin: player object had no client")); + return false; + } + + return playerObject->getClient()->isUsingAdminLogin(); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsPlayerAccountNamespace::isWarden(JNIEnv *env, jobject self, jlong player) +{ + CreatureObject *creatureObject = 0; + if (!JavaLibrary::getObject(player, creatureObject)) + { + DEBUG_WARNING(true, ("JavaLibrary::isWarden: bad creature object")); + return false; + } + + PlayerObject *playerObject = PlayerCreatureController::getPlayerObject(creatureObject); + if (!playerObject) + { + DEBUG_WARNING(true, ("JavaLibrary::isWarden: creature object had no player object")); + return false; + } + + return playerObject->isWarden(); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsPlayerAccountNamespace::isFreeTrialAccount(JNIEnv *env, jobject self, jlong player) +{ + CreatureObject *playerObject = 0; + if (!JavaLibrary::getObject(player, playerObject)) + { + DEBUG_WARNING(true, ("JavaLibrary::isFreeTrialAccount: bad player object")); + return false; + } + + if (!playerObject->getClient()) + { + DEBUG_WARNING(true, ("JavaLibrary::isFreeTrialAccount: player object had no client")); + return false; + } + + return playerObject->getClient()->isFreeTrialAccount(); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsPlayerAccountNamespace::setCompletedTutorial(JNIEnv *env, jobject self, jlong player, jboolean value) +{ + CreatureObject *playerObject = 0; + if (!JavaLibrary::getObject(player, playerObject)) + { + DEBUG_WARNING(true, ("JavaLibrary::setCompletedTutorial: bad player object")); + return false; + } + + if (!playerObject->getClient()) + { + DEBUG_WARNING(true, ("JavaLibrary::setCompletedTutorial: player object had no client")); + return false; + } + + if (playerObject->getClient()->isFreeTrialAccount()) + { + DEBUG_WARNING(true, ("JavaLibrary::setCompletedTutorial: client is from a free trial and CANNOT have completed tutorial bit set")); + return false; + } + + const unsigned int stationId = playerObject->getClient()->getStationId(); + + LOG("CustomerService", ("Setting tutorial bit to %s for stationId %i\n", (value) ? "true" : "false", stationId)); + GenericValueTypeMessage< std::pair > const updateTutorial("LoginToggleCompletedTutorial", std::pair(stationId, value)); + GameServer::getInstance().sendToCentralServer(updateTutorial); + return true; +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsPlayerAccountNamespace::logActivity(JNIEnv *env, jobject self, jlong player, jint activityType) +{ + UNREF(self); + + CreatureObject * creatureObject = 0; + if (!JavaLibrary::getObject(player, creatureObject)) + return; + + PlayerObject * playerObject = PlayerCreatureController::getPlayerObject(creatureObject); + if (playerObject) + playerObject->addSessionActivity(static_cast(activityType)); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsPlayerAccountNamespace::isAccountQualifiedForHousePackup(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + NOT_NULL(env); + + static std::hash_set accountsQualifiedForHousePackup; + if (accountsQualifiedForHousePackup.empty()) + { + DataTable * table = DataTableManager::getTable(ConfigServerGame::getHousePackupAccountListDataTableName(), true); + if (table) + { + int const columnId = table->findColumnNumber("stationId"); + if (columnId >= 0) + { + int const numRows = table->getNumRows(); + for (int i = 0; i < numRows; ++i) + { + IGNORE_RETURN(accountsQualifiedForHousePackup.insert(static_cast(table->getIntValue(columnId, i)))); + } + } + + DataTableManager::close(ConfigServerGame::getHousePackupAccountListDataTableName()); + } + } + + return (accountsQualifiedForHousePackup.count(static_cast(NameManager::getInstance().getPlayerStationId(NetworkId(static_cast(target))))) >= 1); +} + +/** +* Gets the CTS history of the specified character +* +* @returns a dictionary that contains the following data in paralled arrays +* with the oldest CTS transaction first and the newest CTS transaction last +* +* @returns null if the character doesn't have any CTS history +* +* string[] character_name full name of the source character +* string[] cluster_name name of the source cluster +* int[] transfer_time calendar time of the transfer +*/ +jobject JNICALL ScriptMethodsPlayerAccountNamespace::getCharacterCtsHistory(JNIEnv * env, jobject self, jlong player) +{ + CreatureObject const * playerObject = NULL; + if (!JavaLibrary::getObject(player, playerObject)) + { + DEBUG_WARNING(true, ("JavaLibrary::getCharacterCtsHistory: bad player object")); + return 0; + } + + if (!playerObject->getObjVars().hasItem("ctsHistory")) + return 0; + + // we need to return the CTS history ordered by transfer time + std::multimap > orderedCtsHistory; + + DynamicVariableList::NestedList const ctsTransactions(playerObject->getObjVars(), "ctsHistory"); + for (DynamicVariableList::NestedList::const_iterator i = ctsTransactions.begin(); i != ctsTransactions.end(); ++i) + { + Unicode::String ctsTransactionDetail; + if (i.getValue(ctsTransactionDetail)) + { + Unicode::UnicodeStringVector tokens; + if (Unicode::tokenize(ctsTransactionDetail, tokens, NULL, NULL) && (tokens.size() >= 4)) + { + Unicode::String * characterName = new Unicode::String(); + for (size_t i = 3, j = tokens.size(); i < j; ++i) + { + if (!characterName->empty()) + *characterName += Unicode::narrowToWide(" "); + + *characterName += tokens[i]; + } + + IGNORE_RETURN(orderedCtsHistory.insert(std::make_pair(atoi(Unicode::wideToNarrow(tokens[0]).c_str()), std::make_pair(characterName, new Unicode::String(tokens[1]))))); + } + } + } + + if (orderedCtsHistory.empty()) + return 0; + + std::vector * sourceCharacterName = new std::vector; + std::vector * sourceClusterName = new std::vector; + std::vector * transferTime = new std::vector; + + for (std::multimap >::const_iterator iter = orderedCtsHistory.begin(); iter != orderedCtsHistory.end(); ++iter) + { + transferTime->push_back(iter->first); + sourceCharacterName->push_back(iter->second.first); + sourceClusterName->push_back(iter->second.second); + } + + ScriptParams params; + params.addParam(*sourceCharacterName, "character_name", true); + params.addParam(*sourceClusterName, "cluster_name", true); + params.addParam(*transferTime, "transfer_time", true); + + JavaDictionaryPtr dictionary; + JavaLibrary::instance()->convert(params, dictionary); + return dictionary->getReturnValue(); +} // JavaLibrary::requestJedi + +/** +* Gets the retroactive CTS objvars history of the specified character +* +* @returns an array of dictionaries each of which contains the retroactive CTS objvars +* for the particular CTS source character that this character at one time transferred from +* with the oldest CTS transaction first and the newest CTS transaction last +* +* @returns null if the character doesn't have any retroactive CTS objvars history +*/ +jobjectArray JNICALL ScriptMethodsPlayerAccountNamespace::getCharacterRetroactiveCtsObjvars(JNIEnv * env, jobject self, jlong player) +{ + std::vector > const *> const & characterRetroactiveCtsObjvars = GameServer::getRetroactiveCtsHistoryObjvars(NetworkId(static_cast(player))); + if (characterRetroactiveCtsObjvars.empty()) + return NULL; + + LocalObjectArrayRefPtr results = createNewObjectArray(characterRetroactiveCtsObjvars.size(), JavaLibrary::getClsDictionary()); + for (size_t i = 0, size = characterRetroactiveCtsObjvars.size(); i < size; ++i) + { + bool addedAnything = false; + ScriptParams params; + + if (characterRetroactiveCtsObjvars[i] && !characterRetroactiveCtsObjvars[i]->empty()) + { + for (std::vector >::const_iterator iterObjvar = characterRetroactiveCtsObjvars[i]->begin(); iterObjvar != characterRetroactiveCtsObjvars[i]->end(); ++iterObjvar) + { + // can only handle INT (type 0) and INT_ARRAY (type 1) objvar type at this time + if (iterObjvar->second.getType() == DynamicVariable::INT) + { + int iValue; + iterObjvar->second.get(iValue); + params.addParam(iValue, iterObjvar->first); + addedAnything = true; + } + else if (iterObjvar->second.getType() == DynamicVariable::INT_ARRAY) + { + // iaValue will be owned and deleted by params + std::vector * iaValue = new std::vector(); + iterObjvar->second.get(*iaValue); + params.addParam(*iaValue, iterObjvar->first, true); + addedAnything = true; + } + } + } + + if (!addedAnything) + { + setObjectArrayElement(*results, i, *JavaDictionary::cms_nullPtr); + } + else + { + JavaDictionaryPtr dictionary; + JavaLibrary::instance()->convert(params, dictionary); + setObjectArrayElement(*results, i, *dictionary); + } + } + + return results->getReturnValue(); +} + +/** +* Checks to see if the specified character qualifies for free CTS +* +* @returns an array of strings containing the galaxies to which this character can transfer for free +*/ +jobjectArray JNICALL ScriptMethodsPlayerAccountNamespace::qualifyForFreeCts(JNIEnv * /*env*/, jobject /*self*/, jlong player) +{ + time_t const characterCreateTime = static_cast(NameManager::getInstance().getPlayerCreateTime(NetworkId(player))); + FreeCtsDataTable::FreeCtsInfo const * freeCtsInfo = FreeCtsDataTable::getFreeCtsInfoForCharacter(characterCreateTime, GameServer::getInstance().getClusterName(), false); + + // see if we can/should bypass the free CTS time restriction + if (!freeCtsInfo && ConfigServerGame::getAllowIgnoreFreeCtsTimeRestriction()) + { + CreatureObject const * playerObject = NULL; + if (JavaLibrary::getObject(player, playerObject) && playerObject && playerObject->getClient() && playerObject->getClient()->isGod()) + { + freeCtsInfo = FreeCtsDataTable::getFreeCtsInfoForCharacter(characterCreateTime, GameServer::getInstance().getClusterName(), true); + if (freeCtsInfo) + { + Chat::sendSystemMessage(*playerObject, Unicode::narrowToWide("Bypassing free CTS time restriction for GOD MODE!!!"), Unicode::emptyString); + } + } + } + + if (!freeCtsInfo || freeCtsInfo->targetCluster.empty()) + return NULL; + + LocalObjectArrayRefPtr valueArray = createNewObjectArray(freeCtsInfo->targetCluster.size(), JavaLibrary::getClsString()); + + int i = 0; + for (std::map::const_iterator iter = freeCtsInfo->targetCluster.begin(); iter != freeCtsInfo->targetCluster.end(); ++iter) + { + JavaString jval(iter->second); + setObjectArrayElement(*valueArray, i++, jval); + } + + return valueArray->getReturnValue(); +} + +/** +* Validate the free CTS information and messageTo back to the object to indicate status of the validation +*/ +void JNICALL ScriptMethodsPlayerAccountNamespace::validateFreeCts(JNIEnv * /*env*/, jobject /*self*/, jlong player, jstring destinationGalaxy, jstring destinationCharacterName) +{ + CreatureObject const * creatureObject = NULL; + if (!JavaLibrary::getObject(player, creatureObject) || !creatureObject) + { + DEBUG_WARNING(true, ("JavaLibrary::validateFreeCts: bad CreatureObject")); + return; + } + + PlayerObject const * const playerObject = PlayerCreatureController::getPlayerObject(creatureObject); + if (!playerObject) + { + DEBUG_WARNING(true, ("JavaLibrary::validateFreeCts: bad PlayerObject")); + return; + } + + std::string destinationGalaxyString; + JavaStringParam temp1(destinationGalaxy); + if (!JavaLibrary::convert(temp1, destinationGalaxyString)) + { + DEBUG_WARNING(true, ("JavaLibrary::validateFreeCts: bad destinationGalaxy")); + return; + } + + std::string destinationCharacterNameString; + JavaStringParam temp2(destinationCharacterName); + if (!JavaLibrary::convert(temp2, destinationCharacterNameString)) + { + DEBUG_WARNING(true, ("JavaLibrary::validateFreeCts: bad destinationCharacterName")); + return; + } + + TransferRequestMoveValidation const trmv(TransferRequestMoveValidation::TRS_ingame_freects_command_validate, GameServer::getInstance().getProcessId(), playerObject->getStationId(), playerObject->getStationId(), GameServer::getInstance().getClusterName(), destinationGalaxyString, Unicode::wideToNarrow(creatureObject->getAssignedObjectName()), creatureObject->getNetworkId(), creatureObject->getTemplateCrc(), destinationCharacterNameString, std::string("en")); + GameServer::getInstance().sendToCentralServer(trmv); +} + +/** +* Validate the free CTS information and initiate the transfer process if the validation passes, or +* messageTo back to the object to indicate status of the validation if the validation fails +*/ +void JNICALL ScriptMethodsPlayerAccountNamespace::performFreeCts(JNIEnv * /*env*/, jobject /*self*/, jlong player, jstring destinationGalaxy, jstring destinationCharacterName) +{ + CreatureObject const * creatureObject = NULL; + if (!JavaLibrary::getObject(player, creatureObject) || !creatureObject) + { + DEBUG_WARNING(true, ("JavaLibrary::performFreeCts: bad CreatureObject")); + return; + } + + PlayerObject const * const playerObject = PlayerCreatureController::getPlayerObject(creatureObject); + if (!playerObject) + { + DEBUG_WARNING(true, ("JavaLibrary::performFreeCts: bad PlayerObject")); + return; + } + + std::string destinationGalaxyString; + JavaStringParam temp1(destinationGalaxy); + if (!JavaLibrary::convert(temp1, destinationGalaxyString)) + { + DEBUG_WARNING(true, ("JavaLibrary::performFreeCts: bad destinationGalaxy")); + return; + } + + std::string destinationCharacterNameString; + JavaStringParam temp2(destinationCharacterName); + if (!JavaLibrary::convert(temp2, destinationCharacterNameString)) + { + DEBUG_WARNING(true, ("JavaLibrary::performFreeCts: bad destinationCharacterName")); + return; + } + + TransferRequestMoveValidation const trmv(TransferRequestMoveValidation::TRS_ingame_freects_command_transfer, GameServer::getInstance().getProcessId(), playerObject->getStationId(), playerObject->getStationId(), GameServer::getInstance().getClusterName(), destinationGalaxyString, Unicode::wideToNarrow(creatureObject->getAssignedObjectName()), creatureObject->getNetworkId(), creatureObject->getTemplateCrc(), destinationCharacterNameString, std::string("en")); + GameServer::getInstance().sendToCentralServer(trmv); +} + +/** +* Validate the CTS information and messageTo back to the object to indicate status of the validation +*/ +void JNICALL ScriptMethodsPlayerAccountNamespace::validateCts(JNIEnv * /*env*/, jobject /*self*/, jlong player, jstring destinationGalaxy, jstring destinationCharacterName) +{ + CreatureObject const * creatureObject = NULL; + if (!JavaLibrary::getObject(player, creatureObject) || !creatureObject) + { + DEBUG_WARNING(true, ("JavaLibrary::validateCts: bad CreatureObject")); + return; + } + + PlayerObject const * const playerObject = PlayerCreatureController::getPlayerObject(creatureObject); + if (!playerObject) + { + DEBUG_WARNING(true, ("JavaLibrary::validateCts: bad PlayerObject")); + return; + } + + std::string destinationGalaxyString; + JavaStringParam temp1(destinationGalaxy); + if (!JavaLibrary::convert(temp1, destinationGalaxyString)) + { + DEBUG_WARNING(true, ("JavaLibrary::validateCts: bad destinationGalaxy")); + return; + } + + std::string destinationCharacterNameString; + JavaStringParam temp2(destinationCharacterName); + if (!JavaLibrary::convert(temp2, destinationCharacterNameString)) + { + DEBUG_WARNING(true, ("JavaLibrary::validateCts: bad destinationCharacterName")); + return; + } + + TransferRequestMoveValidation const trmv(TransferRequestMoveValidation::TRS_ingame_cts_command_validate, GameServer::getInstance().getProcessId(), playerObject->getStationId(), playerObject->getStationId(), GameServer::getInstance().getClusterName(), destinationGalaxyString, Unicode::wideToNarrow(creatureObject->getAssignedObjectName()), creatureObject->getNetworkId(), creatureObject->getTemplateCrc(), destinationCharacterNameString, std::string("en")); + GameServer::getInstance().sendToCentralServer(trmv); +} + +/** +* Validate the CTS information and initiate the transfer process if the validation passes, or +* messageTo back to the object to indicate status of the validation if the validation fails +*/ +void JNICALL ScriptMethodsPlayerAccountNamespace::performCts(JNIEnv * /*env*/, jobject /*self*/, jlong player, jstring destinationGalaxy, jstring destinationCharacterName) +{ + CreatureObject const * creatureObject = NULL; + if (!JavaLibrary::getObject(player, creatureObject) || !creatureObject) + { + DEBUG_WARNING(true, ("JavaLibrary::performCts: bad CreatureObject")); + return; + } + + PlayerObject const * const playerObject = PlayerCreatureController::getPlayerObject(creatureObject); + if (!playerObject) + { + DEBUG_WARNING(true, ("JavaLibrary::performCts: bad PlayerObject")); + return; + } + + std::string destinationGalaxyString; + JavaStringParam temp1(destinationGalaxy); + if (!JavaLibrary::convert(temp1, destinationGalaxyString)) + { + DEBUG_WARNING(true, ("JavaLibrary::performCts: bad destinationGalaxy")); + return; + } + + std::string destinationCharacterNameString; + JavaStringParam temp2(destinationCharacterName); + if (!JavaLibrary::convert(temp2, destinationCharacterNameString)) + { + DEBUG_WARNING(true, ("JavaLibrary::performCts: bad destinationCharacterName")); + return; + } + + TransferRequestMoveValidation const trmv(TransferRequestMoveValidation::TRS_ingame_cts_command_transfer, GameServer::getInstance().getProcessId(), playerObject->getStationId(), playerObject->getStationId(), GameServer::getInstance().getClusterName(), destinationGalaxyString, Unicode::wideToNarrow(creatureObject->getAssignedObjectName()), creatureObject->getNetworkId(), creatureObject->getTemplateCrc(), destinationCharacterNameString, std::string("en")); + GameServer::getInstance().sendToCentralServer(trmv); +} + +/** + * Validate the new character name for the rename operation and messageTo back to the object to indicate status of the validation + */ +void JNICALL ScriptMethodsPlayerAccountNamespace::validateRenameCharacter(JNIEnv *env, jobject self, jlong player, jstring newName) +{ + CreatureObject const * creatureObject = NULL; + if (!JavaLibrary::getObject(player, creatureObject) || !creatureObject) + { + DEBUG_WARNING(true, ("JavaLibrary::validateRenameCharacter: bad CreatureObject")); + return; + } + + PlayerObject const * const playerObject = PlayerCreatureController::getPlayerObject(creatureObject); + if (!playerObject) + { + DEBUG_WARNING(true, ("JavaLibrary::validateRenameCharacter: bad PlayerObject")); + return; + } + + Unicode::String newNameString; + JavaStringParam temp(newName); + if (!JavaLibrary::convert(temp, newNameString)) + { + DEBUG_WARNING(true, ("JavaLibrary::validateRenameCharacter: bad newName")); + return; + } + + // if this is a last name change only, to validate that the last name is valid, + // generate a random unique first name, and validate that with the new last name + bool lastNameChangeOnly = false; + static Unicode::String const delimiters(Unicode::narrowToWide(" ")); + Unicode::UnicodeStringVector newNameTokens; + if (!Unicode::tokenize(newNameString, newNameTokens, &delimiters, NULL)) + newNameTokens.clear(); + + size_t const newNameTokensCount = newNameTokens.size(); + + if ((newNameTokensCount == 1) || (newNameTokensCount == 2)) + { + if (Unicode::caseInsensitiveCompare(creatureObject->getAssignedObjectFirstName(), newNameTokens[0])) + { + lastNameChangeOnly = true; + + // no last name specified, so validation passes + if (newNameTokensCount == 1) + { + MessageToQueue::getInstance().sendMessageToJava(creatureObject->getNetworkId(), "renameCharacterNameValidationSuccess", std::vector(), 0, false); + return; + } + else + { + const ObjectTemplate * const objectTemplate = ObjectTemplateList::fetch(creatureObject->getObjectTemplateName()); + if (objectTemplate) + { + const ServerCreatureObjectTemplate * const creatureTemplate = dynamic_cast(objectTemplate); + if (creatureTemplate) + { + Unicode::String const uniqueRandomName = NameManager::getInstance().generateUniqueRandomName(ConfigServerGame::getCharacterNameGeneratorDirectory(), creatureTemplate->getNameGeneratorType()); + Unicode::UnicodeStringVector uniqueRandomNameTokens; + if (!Unicode::tokenize(uniqueRandomName, uniqueRandomNameTokens, &delimiters, NULL)) + uniqueRandomNameTokens.clear(); + + newNameString = ((uniqueRandomNameTokens.size() >= 1) ? uniqueRandomNameTokens[0] : delimiters) + delimiters + newNameTokens[1]; + } + } + } + } + } + else + { + ScriptParams params; + params.addParam("@ui:name_declined_racially_inappropriate", "reason"); + ScriptDictionaryPtr dictionary; + GameScriptObject::makeScriptDictionary(params, dictionary); + if (dictionary.get() != NULL) + { + dictionary->serialize(); + MessageToQueue::getInstance().sendMessageToJava(creatureObject->getNetworkId(), "renameCharacterNameValidationFail", dictionary->getSerializedData(), 0, false); + } + + return; + } + + VerifyAndLockNameRequest const verifyRequest(playerObject->getStationId(), creatureObject->getNetworkId(), creatureObject->getObjectTemplateName(), newNameString, 0xFFFFFFFF); + StringId const verifyResult = GameServer::getInstance().handleVerifyAndLockNameRequest(verifyRequest, false, !lastNameChangeOnly); + if (verifyResult != NameErrors::nameApproved) + { + std::string const errorText(std::string("@") + verifyResult.getCanonicalRepresentation()); + ScriptParams params; + params.addParam(errorText.c_str(), "reason"); + ScriptDictionaryPtr dictionary; + GameScriptObject::makeScriptDictionary(params, dictionary); + if (dictionary.get() != NULL) + { + dictionary->serialize(); + MessageToQueue::getInstance().sendMessageToJava(creatureObject->getNetworkId(), "renameCharacterNameValidationFail", dictionary->getSerializedData(), 0, false); + } + } + else if (lastNameChangeOnly) + { + // last name passes validation + MessageToQueue::getInstance().sendMessageToJava(creatureObject->getNetworkId(), "renameCharacterNameValidationSuccess", std::vector(), 0, false); + } + else + { + // nothing to do here, as it means the request has been forwarded + // to the DB server for additional verification, so when that + // verification is complete, we'll send the response from there + } +} + +/** +* Release the character name that had been reserved for renaming the specified character; the character +* name is reserved during the character rename process, even if the name doesn't end up being used, +* so we want to return the name back to the pool; just make sure you don't call this function during +* the character rename process, or before the character rename process has completed +*/ +void JNICALL ScriptMethodsPlayerAccountNamespace::renameCharacterReleaseNameReservation(JNIEnv *env, jobject self, jlong player) +{ + CreatureObject const * creatureObject = NULL; + if (!JavaLibrary::getObject(player, creatureObject) || !creatureObject) + { + DEBUG_WARNING(true, ("JavaLibrary::renameCharacterReleaseNameReservation: bad CreatureObject")); + return; + } + + PlayerObject const * const playerObject = PlayerCreatureController::getPlayerObject(creatureObject); + if (!playerObject) + { + DEBUG_WARNING(true, ("JavaLibrary::renameCharacterReleaseNameReservation: bad PlayerObject")); + return; + } + + ReleaseNameMessage const rnm(playerObject->getStationId(), creatureObject->getNetworkId()); + GameServer::getInstance().sendToDatabaseServer(rnm); +} + +/** +* submit request to rename character; the name is assumed to have already been validated with validateRenameCharacter() +*/ +void JNICALL ScriptMethodsPlayerAccountNamespace::renameCharacter(JNIEnv *env, jobject self, jlong player, jstring newName) +{ + CreatureObject const * creatureObject = NULL; + if (!JavaLibrary::getObject(player, creatureObject) || !creatureObject) + { + DEBUG_WARNING(true, ("JavaLibrary::renameCharacter: bad CreatureObject")); + return; + } + + PlayerObject const * const playerObject = PlayerCreatureController::getPlayerObject(creatureObject); + if (!playerObject) + { + DEBUG_WARNING(true, ("JavaLibrary::renameCharacter: bad PlayerObject")); + return; + } + + Unicode::String newNameString; + JavaStringParam temp(newName); + if (!JavaLibrary::convert(temp, newNameString)) + { + DEBUG_WARNING(true, ("JavaLibrary::renameCharacter: bad newName")); + return; + } + + PlayerCreationManagerServer::renamePlayer(static_cast(RenameCharacterMessageEx::RCMS_player_request), playerObject->getStationId(), creatureObject->getNetworkId(), newNameString, creatureObject->getAssignedObjectName(), NetworkId::cms_invalid); +} + +// ---------------------------------------------------------------------- + +/** +* Get the station id of the player. +* +* @param env Java environment +* @param self class calling this function +* @param player the id of the player +* +* @return the station id of the player +*/ + +jint JNICALL ScriptMethodsPlayerAccountNamespace::getPlayerStationId(JNIEnv *env, jobject self, jlong player) +{ + UNREF(self); + NOT_NULL(env); + + return NameManager::getInstance().getPlayerStationId(NetworkId(static_cast(player))); +} + +// ====================================================================== diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsPlayerQuest.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsPlayerQuest.cpp new file mode 100644 index 00000000..2e523419 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsPlayerQuest.cpp @@ -0,0 +1,815 @@ +// ScriptMethodsPlayerQuest.cpp +// Copyright 2009, Sony Online Entertainment Inc., all rights reserved. +// Author: Matt Boudreaux + +//----------------------------------------------------------------------- + +#include "serverScript/FirstServerScript.h" +#include "serverGame/ContainerInterface.h" +#include "serverGame/CreatureController.h" +#include "serverGame/CreatureObject.h" +#include "serverGame/PlayerQuestObject.h" +#include "serverGame/PlanetObject.h" +#include "serverGame/ServerObject.h" +#include "serverScript/JavaLibrary.h" + +#include "sharedGame/TextManager.h" + +#include "sharedNetworkMessages/MessageQueueGenericValueType.h" + +#include "UnicodeUtils.h" + +using namespace JNIWrappersNamespace; + + +// ====================================================================== +// ScriptMethodsPlayerQuest +// ====================================================================== + +namespace ScriptMethodsPlayerQuestNamespace +{ + bool install(); + + //jlong createPlayerQuestObjectInDatapad(JNIEnv * env, jobject self, jlong creature); + jlong createPlayerQuestObjectInInventory(JNIEnv * env, jobject self, jlong creature); + jboolean addPlayerQuestTask(JNIEnv * env, jobject self, jlong quest, jstring title, jstring desc, jint counter, jobject waypointLocation); + jobjectArray getPlayerQuestTasks(JNIEnv * env, jobject self, jlong quest); + jintArray getAllPlayerQuestTaskStatus(JNIEnv * env, jobject self, jlong quest); + jint getPlayerQuestTaskStatus(JNIEnv * env, jobject self, jlong quest, jint taskIndex); + void setPlayerQuestTaskStatus(JNIEnv * env, jobject self, jlong quest, jint taskIndex, jint status); + jboolean setPlayerQuestTitle(JNIEnv * env, jobject self, jlong quest, jstring title); + jboolean setPlayerQuestDescription(JNIEnv * env, jobject self, jlong quest, jstring desc); + void setPlayerQuestDifficulty(JNIEnv * env, jobject self, jlong quest, jint difficulty); + jint getPlayerQuestDifficulty(JNIEnv * env, jobject self, jlong quest); + jint getPlayerQuestTaskCounter(JNIEnv * env, jobject self, jlong quest, jint index); + void setPlayerQuestTaskCounter(JNIEnv * env, jobject self, jlong quest, jint index, jint value); + jobject getPlayerQuestWaypoint(JNIEnv * env, jobject self, jlong quest, jint index); + jboolean isPlayerQuestTaskComplete(JNIEnv * env, jobject self, jlong quest, jint index); + jboolean isPlayerQuestComplete(JNIEnv * env, jobject self, jlong quest); + jobject getPlayerQuestTitle(JNIEnv * env, jobject self, jlong quest); + jobject getPlayerQuestDescription(JNIEnv * env, jobject self, jlong quest); + jobject getPlayerQuestTaskTitle(JNIEnv * env, jobject self, jlong quest, jint index); + jobject getPlayerQuestTaskDescription(JNIEnv * env, jobject self, jlong quest, jint index); + //void setPlayerQuestWaypoint(JNIEnv * env, jobject self, jlong quest, jint index, jobject loc); + void setPlayerQuestRecipe(JNIEnv * env, jobject self, jlong quest, jboolean recipe); + jboolean isPlayerQuestRecipe(JNIEnv * env, jobject self, jlong quest); + void addPlayerQuestTaskRecipeData(JNIEnv * env, jobject self, jlong quest, jstring data); + void addPlayerQuestTaskRecipeDataWithIndex(JNIEnv * env, jobject self, jlong quest, jint index, jstring data); + void setPlayerQuestRewardData(JNIEnv * env, jobject self, jlong quest, jstring data); + void setPlayerQuestCreator(JNIEnv * env, jobject self, jlong quest, jlong creator); + jstring filterText(JNIEnv * env, jobject self, jstring text); + void openPlayerQuestRecipe(JNIEnv * env, jobject self, jlong player, jlong recipe); + void resetAllPlayerQuestData(JNIEnv * env, jobject self, jlong quest); +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsPlayerQuestNamespace::install() +{ + const JNINativeMethod NATIVES[] = { +#define JF(a,b,c) {a,b,(void*)(ScriptMethodsPlayerQuestNamespace::c)} + //JF("_createPlayerQuestObjectInDatapad", "(J)J", createPlayerQuestObjectInDatapad), + JF("_createPlayerQuestObjectInInventory", "(J)J", createPlayerQuestObjectInInventory), + JF("_addPlayerQuestTask", "(JLjava/lang/String;Ljava/lang/String;ILscript/location;)Z", addPlayerQuestTask), + JF("_getPlayerQuestTasks", "(J)[Ljava/lang/String;", getPlayerQuestTasks), + JF("_getAllPlayerQuestTaskStatus", "(J)[I", getAllPlayerQuestTaskStatus), + JF("_getPlayerQuestTaskStatus", "(JI)I", getPlayerQuestTaskStatus), + JF("_setPlayerQuestTaskStatus", "(JII)V", setPlayerQuestTaskStatus), + JF("_setPlayerQuestTitle", "(JLjava/lang/String;)Z", setPlayerQuestTitle), + JF("_setPlayerQuestDescription", "(JLjava/lang/String;)Z", setPlayerQuestDescription), + JF("_setPlayerQuestDifficulty", "(JI)V", setPlayerQuestDifficulty), + JF("_getPlayerQuestDifficulty", "(J)I", getPlayerQuestDifficulty), + JF("_getPlayerQuestTaskCounter", "(JI)I", getPlayerQuestTaskCounter), + JF("_setPlayerQuestTaskCounter", "(JII)V", setPlayerQuestTaskCounter), + JF("_getPlayerQuestWaypoint", "(JI)Ljava/lang/String;", getPlayerQuestWaypoint), + JF("_isPlayerQuestTaskComplete", "(JI)Z", isPlayerQuestTaskComplete), + JF("_isPlayerQuestComplete", "(J)Z", isPlayerQuestComplete), + //JF("_setPlayerQuestWaypoint", "(JILscript/location;)V", setPlayerQuestWaypoint) + JF("_getPlayerQuestTitle", "(J)Ljava/lang/String;", getPlayerQuestTitle), + JF("_getPlayerQuestDescription", "(J)Ljava/lang/String;", getPlayerQuestDescription), + JF("_getPlayerQuestTaskTitle", "(JI)Ljava/lang/String;", getPlayerQuestTaskTitle), + JF("_getPlayerQuestTaskDescription", "(JI)Ljava/lang/String;", getPlayerQuestTaskDescription), + JF("_setPlayerQuestRecipe", "(JZ)V", setPlayerQuestRecipe), + JF("_isPlayerQuestRecipe", "(J)Z", isPlayerQuestRecipe), + JF("_addPlayerQuestTaskRecipeData", "(JLjava/lang/String;)V", addPlayerQuestTaskRecipeData), + JF("_addPlayerQuestTaskRecipeDataWithIndex", "(JILjava/lang/String;)V", addPlayerQuestTaskRecipeDataWithIndex), + JF("_setPlayerQuestRewardData", "(JLjava/lang/String;)V", setPlayerQuestRewardData), + JF("_setPlayerQuestCreator", "(JJ)V", setPlayerQuestCreator), + JF("filterText", "(Ljava/lang/String;)Ljava/lang/String;", filterText), + JF("_openPlayerQuestRecipe", "(JJ)V", openPlayerQuestRecipe), + JF("_resetAllPlayerQuestData", "(J)V", resetAllPlayerQuestData), + }; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +//jlong ScriptMethodsPlayerQuestNamespace::createPlayerQuestObjectInDatapad(JNIEnv * env, jobject self, jlong creature) +//{ +// UNREF(env); +// UNREF(self); +// UNREF(creature); +// +// CreatureObject * creatureObj = 0; +// if(JavaLibrary::getObject(creature, creatureObj)) +// { +// PlayerQuestObject * questObject = PlayerQuestObject::createPlayerQuestObjectInCreatureDatapad(creatureObj); +// if(questObject) +// { +// return questObject->getNetworkId().getValue(); +// } +// } +// return 0; +//} + +jlong ScriptMethodsPlayerQuestNamespace::createPlayerQuestObjectInInventory(JNIEnv * env, jobject self, jlong creature) +{ + UNREF(env); + UNREF(self); + UNREF(creature); + + CreatureObject * creatureObj = 0; + if(JavaLibrary::getObject(creature, creatureObj)) + { + PlayerQuestObject * questObject = PlayerQuestObject::createPlayerQuestObjectInCreatureInventory(creatureObj); + if(questObject) + { + return questObject->getNetworkId().getValue(); + } + } + return 0; +} + +jboolean ScriptMethodsPlayerQuestNamespace::addPlayerQuestTask(JNIEnv * env, jobject self, jlong quest, jstring title, jstring desc, jint counter, jobject waypointLocation) +{ + UNREF(env); + UNREF(self); + + PlayerQuestObject * questObject; + if(!JavaLibrary::getObject(quest, questObject)) + { + WARNING(true, ("AddPlayerQuestTask: Could not get valid Player Quest Object from OID: %d", quest)); + return JNI_FALSE; + } + + Vector waypointVec; + std::string sceneId; + if (!ScriptConversion::convertWorld(waypointLocation, waypointVec, sceneId)) + { + // NULL or Invalid Location passed in. That's fine, just means no waypoint. + if(questObject) + { + std::string titleString; + if(!JavaLibrary::convert(JavaString(title), titleString)) + { + WARNING(true, ("AddPlayerQuestTask: Failed to localize title string.")); + return JNI_FALSE; + } + + std::string descString; + if(!JavaLibrary::convert(JavaString(desc), descString)) + { + WARNING(true, ("AddPlayerQuestTask: Failed to localize description string.")); + return JNI_FALSE; + } + + questObject->addNewTask(titleString, descString, counter, std::string()); + return JNI_TRUE; + } + return JNI_FALSE; + } + + std::string formatedWaypoint; + char buffer[256]; + memset(buffer, 0, 256); + sprintf(buffer, "%f %f %f %s", waypointVec.x, waypointVec.y, waypointVec.z, sceneId.c_str()); + formatedWaypoint = buffer; + + if(questObject) + { + std::string titleString; + if(!JavaLibrary::convert(JavaString(title), titleString)) + { + WARNING(true, ("AddPlayerQuestTask: Failed to localize title string.")); + return JNI_FALSE; + } + + std::string descString; + if(!JavaLibrary::convert(JavaString(desc), descString)) + { + WARNING(true, ("AddPlayerQuestTask: Failed to localize description string.")); + return JNI_FALSE; + } + + questObject->addNewTask(titleString, descString, counter, formatedWaypoint); + return JNI_TRUE; + } + + return JNI_FALSE; +} + +jobjectArray ScriptMethodsPlayerQuestNamespace::getPlayerQuestTasks(JNIEnv * env, jobject self, jlong quest) +{ + UNREF(env); + UNREF(self); + + PlayerQuestObject * questObject; + if(!JavaLibrary::getObject(quest, questObject)) + { + WARNING(true, ("getPlayerQuestTasks: Could not get valid Player Quest Object from OID: %d", quest)); + return 0; + } + std::vector taskVector; + questObject->getTasks(taskVector); + + LocalObjectArrayRefPtr valueArray = createNewObjectArray(taskVector.size(), JavaLibrary::getClsString()); + for (std::vector::size_type i = 0; i < taskVector.size(); ++i) + { + JavaString jval(Unicode::wideToNarrow(taskVector[i])); + setObjectArrayElement(*valueArray, i, jval); + } + + return valueArray->getReturnValue(); + +} + +jintArray ScriptMethodsPlayerQuestNamespace::getAllPlayerQuestTaskStatus(JNIEnv * env, jobject self, jlong quest) +{ + UNREF(env); + UNREF(self); + + PlayerQuestObject * questObject; + if(!JavaLibrary::getObject(quest, questObject)) + { + WARNING(true, ("getAllPlayerQuestTaskStatus: Could not get valid Player Quest Object from OID: %d", quest)); + return 0; + } + + std::vector taskStatus; + questObject->getTaskStatus(taskStatus); + + LocalIntArrayRefPtr idArray = createNewIntArray(taskStatus.size()); + if (idArray == LocalIntArrayRef::cms_nullPtr) + { + if (env->ExceptionCheck()) + env->ExceptionDescribe(); + return 0; + } + + std::vector::iterator iter = taskStatus.begin(); + int count = 0; + for (; iter != taskStatus.end(); ++iter) + { + jint jintTemp = (*iter); + setIntArrayRegion(*idArray, count, 1, &jintTemp); + ++count; + } + + return idArray->getReturnValue(); +} + +jint ScriptMethodsPlayerQuestNamespace::getPlayerQuestTaskStatus(JNIEnv * env, jobject self, jlong quest, jint taskIndex) +{ + UNREF(env); + UNREF(self); + + PlayerQuestObject * questObject; + if(!JavaLibrary::getObject(quest, questObject)) + { + WARNING(true, ("getPlayerQuestTaskStatus: Could not get valid Player Quest Object from OID: %d", quest)); + return 0; + } + + return questObject->getTaskStatus(taskIndex); +} + +void ScriptMethodsPlayerQuestNamespace::setPlayerQuestTaskStatus(JNIEnv * env, jobject self, jlong quest, jint taskIndex, jint status) +{ + UNREF(env); + UNREF(self); + + PlayerQuestObject * questObject; + if(!JavaLibrary::getObject(quest, questObject)) + { + WARNING(true, ("setPlayerQuestTaskStatus: Could not get valid Player Quest Object from OID: %d", quest)); + return; + } + + questObject->setTaskStatus(taskIndex, status); +} + +jboolean ScriptMethodsPlayerQuestNamespace::setPlayerQuestTitle(JNIEnv * env, jobject self, jlong quest, jstring title) +{ + UNREF(env); + UNREF(self); + + PlayerQuestObject * questObject; + if(!JavaLibrary::getObject(quest, questObject)) + { + WARNING(true, ("setPlayerQuestTitle: Could not get valid Player Quest Object from OID: %d", quest)); + return JNI_FALSE; + } + + if(questObject) + { + std::string titleString; + if(!JavaLibrary::convert(JavaString(title), titleString)) + { + WARNING(true, ("setPlayerQuestTitle: Failed to localize task string.")); + return JNI_FALSE; + } + + questObject->setQuestTitle(titleString); + return JNI_TRUE; + } + + return JNI_FALSE; +} + +jboolean ScriptMethodsPlayerQuestNamespace::setPlayerQuestDescription(JNIEnv * env, jobject self, jlong quest, jstring desc) +{ + UNREF(env); + UNREF(self); + + PlayerQuestObject * questObject; + if(!JavaLibrary::getObject(quest, questObject)) + { + WARNING(true, ("setPlayerQuestDescription: Could not get valid Player Quest Object from OID: %d", quest)); + return JNI_FALSE; + } + + if(questObject) + { + std::string descString; + if(!JavaLibrary::convert(JavaString(desc), descString)) + { + WARNING(true, ("setPlayerQuestDescription: Failed to localize task string.")); + return JNI_FALSE; + } + + questObject->setQuestDescription(descString); + return JNI_TRUE; + } + + return JNI_FALSE; +} + +void ScriptMethodsPlayerQuestNamespace::setPlayerQuestDifficulty(JNIEnv * env, jobject self, jlong quest, jint difficulty) +{ + UNREF(env); + UNREF(self); + + PlayerQuestObject * questObject; + if(!JavaLibrary::getObject(quest, questObject)) + { + WARNING(true, ("setPlayerQuestDifficulty: Could not get valid Player Quest Object from OID: %d", quest)); + return; + } + + if(questObject) + { + questObject->setQuestDifficulty(difficulty); + } + + return; +} + +jint ScriptMethodsPlayerQuestNamespace::getPlayerQuestDifficulty(JNIEnv * env, jobject self, jlong quest) +{ + UNREF(env); + UNREF(self); + + PlayerQuestObject * questObject; + if(!JavaLibrary::getObject(quest, questObject)) + { + WARNING(true, ("setPlayerQuestDifficulty: Could not get valid Player Quest Object from OID: %d", quest)); + return -1; + } + + if(questObject) + return questObject->getQuestDifficulty(); + + return -1; +} + +jint ScriptMethodsPlayerQuestNamespace::getPlayerQuestTaskCounter(JNIEnv * env, jobject self, jlong quest, jint index) +{ + UNREF(env); + UNREF(self); + + PlayerQuestObject * questObject; + if(!JavaLibrary::getObject(quest, questObject)) + { + WARNING(true, ("getPlayerQuestTaskCounter: Could not get valid Player Quest Object from OID: %d", quest)); + return -1; + } + + if(questObject) + { + if(index < 0 || index > questObject->getTotalTasks()) + { + WARNING(true, ("getPlayerQuestTaskCounter: index passed in was invalid. Index = %d Current number of Tasks = %d", index, questObject->getTotalTasks())); + return -1; + } + + return questObject->getTaskCounter(index); + } + + return -1; +} + +void ScriptMethodsPlayerQuestNamespace::setPlayerQuestTaskCounter(JNIEnv * env, jobject self, jlong quest, jint index, jint value) +{ + UNREF(env); + UNREF(self); + + PlayerQuestObject * questObject; + if(!JavaLibrary::getObject(quest, questObject)) + { + WARNING(true, ("setPlayerQuestTaskCounter: Could not get valid Player Quest Object from OID: %d", quest)); + return; + } + + if(questObject) + { + if(index < 0 || index > questObject->getTotalTasks()) + { + WARNING(true, ("setPlayerQuestTaskCounter: index passed in was invalid. Index = %d Current number of Tasks = %d", index, questObject->getTotalTasks())); + return; + } + + questObject->setTaskCounter(index, value); + } + + return; +} + +jobject ScriptMethodsPlayerQuestNamespace::getPlayerQuestWaypoint(JNIEnv * env, jobject self, jlong quest, jint index) +{ + UNREF(env); + UNREF(self); + + PlayerQuestObject * questObject; + if(!JavaLibrary::getObject(quest, questObject)) + { + WARNING(true, ("getPlayerQuestWaypoint: Could not get valid Player Quest Object from OID: %d", quest)); + return NULL; + } + + if(questObject) + { + JavaString jString(questObject->getWaypoint(index)); + return jString.getReturnValue(); + } + + return NULL; +} + + +jboolean ScriptMethodsPlayerQuestNamespace::isPlayerQuestTaskComplete(JNIEnv * env, jobject self, jlong quest, jint index) +{ + UNREF(env); + UNREF(self); + + PlayerQuestObject * questObject; + if(!JavaLibrary::getObject(quest, questObject)) + { + WARNING(true, ("isPlayerQuestTaskComplete: Could not get valid Player Quest Object from OID: %d", quest)); + return JNI_FALSE; + } + + if(questObject) + { + if(questObject->getTaskStatus(index) == 2) // Not a magic number, it's defined in the Base_class.java file + return JNI_TRUE; + } + + return JNI_FALSE; +} + +jboolean ScriptMethodsPlayerQuestNamespace::isPlayerQuestComplete(JNIEnv * env, jobject self, jlong quest) +{ + UNREF(env); + UNREF(self); + + PlayerQuestObject * questObject; + if(!JavaLibrary::getObject(quest, questObject)) + { + WARNING(true, ("isPlayerQuestComplete: Could not get valid Player Quest Object from OID: %d", quest)); + return JNI_FALSE; + } + + if(questObject) + { + if(questObject->isCompleted()) + return JNI_TRUE; + } + + return JNI_FALSE; +} + +jobject ScriptMethodsPlayerQuestNamespace::getPlayerQuestTitle(JNIEnv * env, jobject self, jlong quest) +{ + UNREF(env); + UNREF(self); + + PlayerQuestObject * questObject; + if(!JavaLibrary::getObject(quest, questObject)) + { + WARNING(true, ("getPlayerQuestTitle: Could not get valid Player Quest Object from OID: %d", quest)); + return NULL; + } + + if(questObject) + { + JavaString returnVal(questObject->getQuestTitle().c_str()); + return returnVal.getReturnValue(); + } + + return NULL; +} + +jobject ScriptMethodsPlayerQuestNamespace::getPlayerQuestDescription(JNIEnv * env, jobject self, jlong quest) +{ + UNREF(env); + UNREF(self); + + PlayerQuestObject * questObject; + if(!JavaLibrary::getObject(quest, questObject)) + { + WARNING(true, ("getPlayerQuestDescription: Could not get valid Player Quest Object from OID: %d", quest)); + return NULL; + } + + if(questObject) + { + JavaString returnVal(questObject->getQuestDescription().c_str()); + return returnVal.getReturnValue(); + } + + return NULL; +} + +jobject ScriptMethodsPlayerQuestNamespace::getPlayerQuestTaskTitle(JNIEnv * env, jobject self, jlong quest, jint index) +{ + UNREF(env); + UNREF(self); + + PlayerQuestObject * questObject; + if(!JavaLibrary::getObject(quest, questObject)) + { + WARNING(true, ("getPlayerQuestTaskTitle: Could not get valid Player Quest Object from OID: %d", quest)); + return NULL; + } + + if(questObject) + { + JavaString returnVal(questObject->getTaskTitle(index).c_str()); + return returnVal.getReturnValue(); + } + + return NULL; +} + +jobject ScriptMethodsPlayerQuestNamespace::getPlayerQuestTaskDescription(JNIEnv * env, jobject self, jlong quest, jint index) +{ + UNREF(env); + UNREF(self); + + PlayerQuestObject * questObject; + if(!JavaLibrary::getObject(quest, questObject)) + { + WARNING(true, ("getPlayerQuestTaskDescription: Could not get valid Player Quest Object from OID: %d", quest)); + return NULL; + } + + if(questObject) + { + JavaString returnVal(questObject->getTaskDescription(index).c_str()); + return returnVal.getReturnValue(); + } + + return NULL; +} + +void ScriptMethodsPlayerQuestNamespace::setPlayerQuestRecipe(JNIEnv * env, jobject self, jlong quest, jboolean recipe) +{ + UNREF(env); + UNREF(self); + + PlayerQuestObject * questObject; + if(!JavaLibrary::getObject(quest, questObject)) + { + WARNING(true, ("setPlayerQuestRecipe: Could not get valid Player Quest Object from OID: %d", quest)); + return; + } + + if(questObject) + { + questObject->setRecipe(recipe == JNI_TRUE ? true : false); + } + +} + +jboolean ScriptMethodsPlayerQuestNamespace::isPlayerQuestRecipe(JNIEnv * env, jobject self, jlong quest) +{ + UNREF(env); + UNREF(self); + + PlayerQuestObject * questObject; + if(!JavaLibrary::getObject(quest, questObject)) + { + WARNING(true, ("isPlayerQuestRecipe: Could not get valid Player Quest Object from OID: %d", quest)); + return JNI_FALSE; + } + + if(questObject) + { + return questObject->isRecipe() ? JNI_TRUE : JNI_FALSE; + } + + return JNI_FALSE; +} + +void ScriptMethodsPlayerQuestNamespace::addPlayerQuestTaskRecipeData(JNIEnv * env, jobject self, jlong quest, jstring data) +{ + UNREF(env); + UNREF(self); + + PlayerQuestObject * questObject; + if(!JavaLibrary::getObject(quest, questObject)) + { + WARNING(true, ("addPlayerQuestTaskRecipeData: Could not get valid Player Quest Object from OID: %d", quest)); + return; + } + + std::string dataString; + if(!JavaLibrary::convert(JavaString(data), dataString)) + { + WARNING(true, ("addPlayerQuestTaskRecipeData: Failed to localize data string.")); + return; + } + + if(questObject) + { + questObject->addRecipeTaskData(dataString); + } + + return; +} + +void ScriptMethodsPlayerQuestNamespace::addPlayerQuestTaskRecipeDataWithIndex(JNIEnv * env, jobject self, jlong quest, jint index, jstring data) +{ + UNREF(env); + UNREF(self); + + PlayerQuestObject * questObject; + if(!JavaLibrary::getObject(quest, questObject)) + { + WARNING(true, ("addPlayerQuestTaskRecipeDataWithIndex: Could not get valid Player Quest Object from OID: %d", quest)); + return; + } + + std::string dataString; + if(!JavaLibrary::convert(JavaString(data), dataString)) + { + WARNING(true, ("addPlayerQuestTaskRecipeDataWithIndex: Failed to localize data string.")); + return; + } + + if(questObject) + { + questObject->setRecipeTaskData(index, dataString); + } + + return; +} + +void ScriptMethodsPlayerQuestNamespace::setPlayerQuestRewardData(JNIEnv * env, jobject self, jlong quest, jstring data) +{ + UNREF(env); + UNREF(self); + + PlayerQuestObject * questObject; + if(!JavaLibrary::getObject(quest, questObject)) + { + WARNING(true, ("setPlayerQuestRewardData: Could not get valid Player Quest Object from OID: %d", quest)); + return; + } + + std::string dataString; + if(!JavaLibrary::convert(JavaString(data), dataString)) + { + WARNING(true, ("setPlayerQuestRewardData: Failed to localize data string.")); + return; + } + + if(questObject) + { + questObject->setRewards(dataString); + } + + return; +} + +void ScriptMethodsPlayerQuestNamespace::setPlayerQuestCreator(JNIEnv * env, jobject self, jlong quest, jlong creator) +{ + UNREF(env); + UNREF(self); + + PlayerQuestObject * questObject; + if(!JavaLibrary::getObject(quest, questObject)) + { + WARNING(true, ("setPlayerQuestCreator: Could not get valid Player Quest Object from OID: %d", quest)); + return; + } + + ServerObject * creatorObject; + if(!JavaLibrary::getObject(creator, creatorObject)) + { + WARNING(true, ("setPlayerQuestCreator: Could not get valid Player Object from OID: %d", creator)); + return; + } + + if(questObject && creatorObject) + { + questObject->setCreator(creatorObject->getNetworkId()); + } +} + +jstring ScriptMethodsPlayerQuestNamespace::filterText(JNIEnv * env, jobject self, jstring text) +{ + UNREF(env); + UNREF(self); + + std::string textString; + if(!JavaLibrary::convert(JavaString(text), textString)) + { + WARNING(true, ("filterText: Failed to convert string.")); + std::string empty = ""; + JavaString jval(empty); + return jval.getReturnValue(); + } + + Unicode::String filteredString = TextManager::filterText( Unicode::narrowToWide(textString) ); + + std::string narrowFilter = Unicode::wideToNarrow(filteredString); + + JavaString jval(narrowFilter); + + return jval.getReturnValue(); +} + +void ScriptMethodsPlayerQuestNamespace::openPlayerQuestRecipe(JNIEnv * env, jobject self, jlong player, jlong recipe) +{ + UNREF(env); + UNREF(self); + + CreatureObject * playerCreature = NULL; + if (!JavaLibrary::getObject(player, playerCreature)) + { + DEBUG_WARNING(true, ("openPlayerQuestRecipe: Failed to get valid creature object with OID %d", player)); + return; + } + + ServerObject * recipeObj = NULL; + if (!JavaLibrary::getObject(recipe, recipeObj)) + { + DEBUG_WARNING(true, ("openPlayerQuestRecipe: Failed to get valid recipe object with OID %d", player)); + return; + } + + if (playerCreature->isPlayerControlled() && playerCreature->getController() != NULL) + { + playerCreature->getController()->appendMessage( + static_cast(CM_openRecipe), + 0, + new MessageQueueGenericValueType< NetworkId >( recipeObj->getNetworkId() ), + GameControllerMessageFlags::SEND | + GameControllerMessageFlags::RELIABLE | + GameControllerMessageFlags::DEST_AUTH_CLIENT); + } + + return; +} + +void ScriptMethodsPlayerQuestNamespace::resetAllPlayerQuestData(JNIEnv * env, jobject self, jlong quest) +{ + UNREF(env); + UNREF(self); + + PlayerQuestObject * playerQuest = NULL; + if (!JavaLibrary::getObject(quest, playerQuest)) + { + DEBUG_WARNING(true, ("resetAllPlayerQuestData: Failed to get valid recipe object with OID %d", quest)); + return; + } + + if(playerQuest) + playerQuest->resetAllData(); + + return; +} diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsPvp.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsPvp.cpp new file mode 100644 index 00000000..b27444e7 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsPvp.cpp @@ -0,0 +1,2224 @@ +// ====================================================================== +// +// ScriptMethodsPvp.cpp - implements script methods dealing with Pvp +// +// Copyright 2002 Sony Online Entertainment +// +// ====================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "serverGame/BattlefieldMarkerObject.h" +#include "serverGame/CityInfo.h" +#include "serverGame/CityInterface.h" +#include "serverGame/ConfigServerGame.h" +#include "serverGame/CreatureObject.h" +#include "serverGame/GuildInterface.h" +#include "serverGame/PlanetObject.h" +#include "serverGame/PlayerCreatureController.h" +#include "serverGame/PlayerObject.h" +#include "serverGame/Pvp.h" +#include "serverGame/PvpFactions.h" +#include "serverGame/RegionPvp.h" +#include "serverGame/ServerUniverse.h" +#include "serverGame/ServerWorld.h" +#include "serverGame/TangibleObject.h" +#include "serverScript/ScriptParameters.h" +#include "sharedFoundation/CalendarTime.h" +#include "sharedFoundation/FormattedString.h" + +using namespace JNIWrappersNamespace; + + +// ====================================================================== +// ScriptMethodsPvpNamespace +// ====================================================================== + +namespace ScriptMethodsPvpNamespace +{ + bool install(); + + // ---------------------------------------------------------------------- + + const char * makeCopyOfString(const char * rhs) + { + char * lhs = NULL; + if (rhs) + { + lhs = new char[strlen(rhs) + 1]; + strcpy(lhs, rhs); + } + else + { + lhs = new char[1]; + lhs[0] = '\0'; + } + + return lhs; + } + + // ---------------------------------------------------------------------- + + void JNICALL pvpSetAttackableOverride(JNIEnv *env, jobject self, jlong dest, jboolean value); + jboolean JNICALL pvpCanAttack(JNIEnv *env, jobject self, jlong actor, jlong target); + jboolean JNICALL pvpCanHelp(JNIEnv *env, jobject self, jlong actor, jlong target); + void JNICALL pvpAttackPerformed(JNIEnv *env, jobject self, jlong actor, jlong target); + void JNICALL pvpHelpPerformed(JNIEnv *env, jobject self, jlong actor, jlong target); + void JNICALL pvpNeutralSetMercenaryFaction(JNIEnv *env, jobject self, jlong dest, jint factionId, jboolean declared); + jint JNICALL pvpNeutralGetMercenaryFaction(JNIEnv *env, jobject self, jlong who); + jboolean JNICALL pvpNeutralIsMercenaryDeclared(JNIEnv *env, jobject self, jlong who); + void JNICALL pvpSetAlignedFaction(JNIEnv *env, jobject self, jlong dest, jint factionId); + void JNICALL pvpMakeOnLeave(JNIEnv *env, jobject self, jlong dest); + void JNICALL pvpMakeCovert(JNIEnv *env, jobject self, jlong dest); + void JNICALL pvpMakeDeclared(JNIEnv *env, jobject self, jlong dest); + void JNICALL pvpMakeNeutral(JNIEnv *env, jobject self, jlong dest); + void JNICALL pvpPrepareToBeCovert(JNIEnv *env, jobject self, jlong dest); + void JNICALL pvpPrepareToBeDeclared(JNIEnv *env, jobject self, jlong dest); + void JNICALL pvpPrepareToBeNeutral(JNIEnv *env, jobject self, jlong dest); + void JNICALL pvpSetPersonalEnemyFlag(JNIEnv *env, jobject self, jlong dest, jlong enemy); + void JNICALL pvpSetPermanentPersonalEnemyFlag(JNIEnv *env, jobject self, jlong dest, jlong enemy); + void JNICALL pvpSetFactionEnemyFlag(JNIEnv *env, jobject self, jlong dest, jint factionId); + void JNICALL pvpSetGuildWarCoolDownPeriodEnemyFlag(JNIEnv *env, jobject self, jlong dest); + jint JNICALL pvpGetType(JNIEnv *env, jobject self, jlong who); + jint JNICALL pvpGetAlignedFaction(JNIEnv *env, jobject self, jlong who); + jobjectArray JNICALL pvpGetEnemyFlags(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL pvpIsEnemy(JNIEnv *env, jobject self, jlong actor, jlong target); + jboolean JNICALL pvpIsDueling(JNIEnv *env, jobject self, jlong actor, jlong target); + jboolean JNICALL pvpHasBattlefieldEnemyFlag(JNIEnv *env, jobject self, jlong target); + jlongArray JNICALL pvpGetEnemiesInRange(JNIEnv *env, jobject self, jlong actor, jlong location, jfloat range); + jlongArray JNICALL pvpGetEnemiesInCone(JNIEnv *env, jobject self, jlong actor, jlong coneCenterObjectId, jlong coneDirectionObjectId, jfloat range, jfloat angle); + jlongArray JNICALL pvpGetEnemiesInConeLocation(JNIEnv *env, jobject self, jlong actor, jlong coneCenterObjectId, jobject coneDirectionLocation, jfloat range, jfloat angle); + jlongArray JNICALL pvpGetTargetsInRange(JNIEnv *env, jobject self, jlong actor, jlong location, jfloat range); + jlongArray JNICALL pvpGetTargetsInCone(JNIEnv *env, jobject self, jlong actor, jlong coneCenterObjectId, jlong coneDirectionObjectId, jfloat range, jfloat angle); + jlongArray JNICALL pvpGetTargetsInConeLocation(JNIEnv *env, jobject self, jlong actor, jlong coneCenterObjectId, jobject coneDirectionLocation, jfloat range, jfloat angle); + jboolean JNICALL pvpAreFactionsOpposed(JNIEnv *env, jobject self, jint faction1, jint faction2); + jint JNICALL pvpBattlefieldGetFaction(JNIEnv *env, jobject self, jlong target, jobject region); + jboolean JNICALL pvpBattlefieldIsParticipant(JNIEnv *env, jobject self, jlong target, jobject region); + void JNICALL pvpBattlefieldSetParticipant(JNIEnv *env, jobject self, jlong target, jobject region, jint faction); + jlongArray JNICALL pvpBattlefieldGetParticipantsForFaction(JNIEnv *env, jobject self, jobject region, jint faction); + void JNICALL pvpBattlefieldClearParticipants(JNIEnv *env, jobject self, jobject region); + void JNICALL pvpRemoveAllTempEnemyFlags(JNIEnv *env, jobject self, jlong target); + jlong JNICALL getBattlefieldRegionMasterObject(JNIEnv *env, jobject self, jobject battlefieldRegion); + void JNICALL setBattlefieldMarkerRegionName(JNIEnv *env, jobject self, jlong marker, jstring regionName); + jboolean JNICALL pvpHasAnyTempEnemyFlags(JNIEnv *env, jobject self, jlong target); + jlongArray JNICALL pvpGetPersonalEnemyIds(JNIEnv *env, jobject self, jlong target); + void JNICALL pvpRemoveTempEnemyFlags(JNIEnv *env, jobject self, jlong target, jlong enemyId); + jboolean JNICALL pvpWouldAttackCauseAlignedEnemyFlag(JNIEnv *env, jobject self, jlong actor, jlong target); + jboolean JNICALL pvpWouldHelpCauseAlignedEnemyFlag(JNIEnv *env, jobject self, jlong actor, jlong target); + jboolean JNICALL pvpHasPersonalEnemyFlag(JNIEnv *env, jobject self, jlong actor, jlong target); + void JNICALL pvpRemovePersonalEnemyFlags(JNIEnv *env, jobject self, jlong target, jlong enemyId); + void JNICALL pvpModifyCurrentGcwPoints(JNIEnv *env, jobject self, jlong target, jint adjustment); + void JNICALL pvpModifyCurrentPvpKills(JNIEnv *env, jobject self, jlong target, jint adjustment); + jint JNICALL pvpGetCurrentGcwRank(JNIEnv *env, jobject self, jlong target); + jint JNICALL pvpGetMaxGcwImperialRank(JNIEnv *env, jobject self, jlong target); + jint JNICALL pvpGetMaxGcwRebelRank(JNIEnv *env, jobject self, jlong target); + jint JNICALL pvpGetCurrentGcwPoints(JNIEnv *env, jobject self, jlong target); + jint JNICALL pvpGetCurrentGcwRating(JNIEnv *env, jobject self, jlong target); + jint JNICALL pvpGetCurrentPvpKills(JNIEnv *env, jobject self, jlong target); + jlong JNICALL pvpGetLifetimeGcwPoints(JNIEnv *env, jobject self, jlong target); + jint JNICALL pvpGetMaxGcwImperialRating(JNIEnv *env, jobject self, jlong target); + jint JNICALL pvpGetMaxGcwRebelRating(JNIEnv *env, jobject self, jlong target); + jint JNICALL pvpGetLifetimePvpKills(JNIEnv *env, jobject self, jlong target); + jint JNICALL pvpGetNextGcwRatingCalcTime(JNIEnv *env, jobject self, jlong target); + void JNICALL ctsUseOnlySetGcwInfo(JNIEnv *env, jobject self, jlong target, jint currentGcwPoints, jint currentGcwRating, jint currentPvpKills, jlong lifetimeGcwPoints, jint maxGcwImperialRating, jint maxGcwRebelRating, jint lifetimePvpKills, jint nextGcwRatingCalcTime); + void JNICALL adjustGcwImperialScore(JNIEnv *env, jobject self, jstring source, jlong sourceOid, jstring gcwCategory, jint adjustment); + void JNICALL adjustGcwRebelScore(JNIEnv *env, jobject self, jstring source, jlong sourceOid, jstring gcwCategory, jint adjustment); + jint JNICALL getGcwImperialScorePercentile(JNIEnv *env, jobject self, jstring gcwCategory); + jint JNICALL getGcwGroupImperialScorePercentile(JNIEnv *env, jobject self, jstring gcwGroup); + jobject JNICALL getGcwFactionalPresenceTableDictionary(JNIEnv * env, jobject self); + jobject JNICALL getGcwContributionTrackingTableDictionary(JNIEnv * env, jobject self, jlong player); + jobjectArray JNICALL getGcwDefenderRegions(JNIEnv *env, jobject self); + jobjectArray JNICALL getGcwDefenderRegionsCitiesImperial(JNIEnv *env, jobject self); + jobjectArray JNICALL getGcwDefenderRegionsCitiesRebel(JNIEnv *env, jobject self); + jint JNICALL getGcwDefenderRegionsCitiesVersion(JNIEnv *env, jobject self); + jobjectArray JNICALL getGcwDefenderRegionsGuildsImperial(JNIEnv *env, jobject self); + jobjectArray JNICALL getGcwDefenderRegionsGuildsRebel(JNIEnv *env, jobject self); + jint JNICALL getGcwDefenderRegionsGuildsVersion(JNIEnv *env, jobject self); + jintArray JNICALL getGcwDefenderRegionCitiesImperial(JNIEnv *env, jobject self, jstring gcwCategory); + jintArray JNICALL getGcwDefenderRegionCitiesRebel(JNIEnv *env, jobject self, jstring gcwCategory); + jintArray JNICALL getGcwDefenderRegionGuildsImperial(JNIEnv *env, jobject self, jstring gcwCategory); + jintArray JNICALL getGcwDefenderRegionGuildsRebel(JNIEnv *env, jobject self, jstring gcwCategory); + jfloat JNICALL getGcwDefenderRegionImperialBonus(JNIEnv *env, jobject self, jstring gcwCategory); + jfloat JNICALL getGcwDefenderRegionRebelBonus(JNIEnv *env, jobject self, jstring gcwCategory); +} + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsPvpNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsPvpNamespace::c)} + JF("_pvpSetAttackableOverride", "(JZ)V", pvpSetAttackableOverride), + JF("_pvpCanAttack", "(JJ)Z", pvpCanAttack), + JF("_pvpCanHelp", "(JJ)Z", pvpCanHelp), + JF("_pvpAttackPerformed", "(JJ)V", pvpAttackPerformed), + JF("_pvpHelpPerformed", "(JJ)V", pvpHelpPerformed), + JF("_pvpNeutralSetMercenaryFaction", "(JIZ)V", pvpNeutralSetMercenaryFaction), + JF("_pvpNeutralGetMercenaryFaction", "(J)I", pvpNeutralGetMercenaryFaction), + JF("_pvpNeutralIsMercenaryDeclared", "(J)Z", pvpNeutralIsMercenaryDeclared), + JF("_pvpSetAlignedFaction", "(JI)V", pvpSetAlignedFaction), + JF("_pvpMakeOnLeave", "(J)V", pvpMakeOnLeave), + JF("_pvpMakeCovert", "(J)V", pvpMakeCovert), + JF("_pvpMakeDeclared", "(J)V", pvpMakeDeclared), + JF("_pvpMakeNeutral", "(J)V", pvpMakeNeutral), + JF("_pvpPrepareToBeCovert", "(J)V", pvpPrepareToBeCovert), + JF("_pvpPrepareToBeDeclared", "(J)V", pvpPrepareToBeDeclared), + JF("_pvpPrepareToBeNeutral", "(J)V", pvpPrepareToBeNeutral), + JF("_pvpSetPersonalEnemyFlag", "(JJ)V", pvpSetPersonalEnemyFlag), + JF("_pvpSetPermanentPersonalEnemyFlag", "(JJ)V", pvpSetPermanentPersonalEnemyFlag), + JF("_pvpSetFactionEnemyFlag", "(JI)V", pvpSetFactionEnemyFlag), + JF("_pvpSetGuildWarCoolDownPeriodEnemyFlag", "(J)V", pvpSetGuildWarCoolDownPeriodEnemyFlag), + JF("_pvpGetType", "(J)I", pvpGetType), + JF("_pvpGetAlignedFaction", "(J)I", pvpGetAlignedFaction), + JF("_pvpGetEnemyFlags", "(J)[Ljava/lang/String;", pvpGetEnemyFlags), + JF("_pvpIsEnemy", "(JJ)Z", pvpIsEnemy), + JF("_pvpIsDueling", "(JJ)Z", pvpIsDueling), + JF("_pvpHasBattlefieldEnemyFlag", "(J)Z", pvpHasBattlefieldEnemyFlag), + JF("_pvpGetEnemiesInRange", "(JJF)[J", pvpGetEnemiesInRange), + JF("_pvpGetEnemiesInCone", "(JJJFF)[J", pvpGetEnemiesInCone), + JF("_pvpGetEnemiesInCone", "(JJLscript/location;FF)[J", pvpGetEnemiesInConeLocation), + JF("_pvpGetTargetsInRange", "(JJF)[J", pvpGetTargetsInRange), + JF("_pvpGetTargetsInCone", "(JJJFF)[J", pvpGetTargetsInCone), + JF("_pvpGetTargetsInCone", "(JJLscript/location;FF)[J", pvpGetTargetsInConeLocation), + JF("pvpAreFactionsOpposed", "(II)Z", pvpAreFactionsOpposed), + JF("_pvpBattlefieldGetFaction", "(JLscript/region;)I", pvpBattlefieldGetFaction), + JF("_pvpBattlefieldIsParticipant", "(JLscript/region;)Z", pvpBattlefieldIsParticipant), + JF("_pvpBattlefieldSetParticipant", "(JLscript/region;I)V", pvpBattlefieldSetParticipant), + JF("_pvpBattlefieldGetParticipantsForFaction", "(Lscript/region;I)[J", pvpBattlefieldGetParticipantsForFaction), + JF("pvpBattlefieldClearParticipants", "(Lscript/region;)V", pvpBattlefieldClearParticipants), + JF("_pvpRemoveAllTempEnemyFlags", "(J)V", pvpRemoveAllTempEnemyFlags), + JF("_getBattlefieldRegionMasterObject", "(Lscript/region;)J", getBattlefieldRegionMasterObject), + JF("_setBattlefieldMarkerRegionName", "(JLjava/lang/String;)V", setBattlefieldMarkerRegionName), + JF("_pvpHasAnyTempEnemyFlags", "(J)Z", pvpHasAnyTempEnemyFlags), + JF("_pvpGetPersonalEnemyIds", "(J)[J", pvpGetPersonalEnemyIds), + JF("_pvpRemoveTempEnemyFlags", "(JJ)V", pvpRemoveTempEnemyFlags), + JF("_pvpWouldAttackCauseAlignedEnemyFlag", "(JJ)Z", pvpWouldAttackCauseAlignedEnemyFlag), + JF("_pvpWouldHelpCauseAlignedEnemyFlag", "(JJ)Z", pvpWouldHelpCauseAlignedEnemyFlag), + JF("_pvpHasPersonalEnemyFlag", "(JJ)Z", pvpHasPersonalEnemyFlag), + JF("_pvpRemovePersonalEnemyFlags", "(JJ)V", pvpRemovePersonalEnemyFlags), + JF("_pvpModifyCurrentGcwPoints", "(JI)V", pvpModifyCurrentGcwPoints), + JF("_pvpModifyCurrentPvpKills", "(JI)V", pvpModifyCurrentPvpKills), + JF("_pvpGetCurrentGcwRank", "(J)I", pvpGetCurrentGcwRank), + JF("_pvpGetMaxGcwImperialRank", "(J)I", pvpGetMaxGcwImperialRank), + JF("_pvpGetMaxGcwRebelRank", "(J)I", pvpGetMaxGcwRebelRank), + JF("_pvpGetCurrentGcwPoints", "(J)I", pvpGetCurrentGcwPoints), + JF("_pvpGetCurrentGcwRating", "(J)I", pvpGetCurrentGcwRating), + JF("_pvpGetCurrentPvpKills", "(J)I", pvpGetCurrentPvpKills), + JF("_pvpGetLifetimeGcwPoints", "(J)J", pvpGetLifetimeGcwPoints), + JF("_pvpGetMaxGcwImperialRating", "(J)I", pvpGetMaxGcwImperialRating), + JF("_pvpGetMaxGcwRebelRating", "(J)I", pvpGetMaxGcwRebelRating), + JF("_pvpGetLifetimePvpKills", "(J)I", pvpGetLifetimePvpKills), + JF("_pvpGetNextGcwRatingCalcTime", "(J)I", pvpGetNextGcwRatingCalcTime), + JF("_ctsUseOnlySetGcwInfo", "(JIIIJIIII)V", ctsUseOnlySetGcwInfo), + JF("_adjustGcwImperialScore", "(Ljava/lang/String;JLjava/lang/String;I)V", adjustGcwImperialScore), + JF("_adjustGcwRebelScore", "(Ljava/lang/String;JLjava/lang/String;I)V", adjustGcwRebelScore), + JF("getGcwImperialScorePercentile", "(Ljava/lang/String;)I", getGcwImperialScorePercentile), + JF("getGcwGroupImperialScorePercentile", "(Ljava/lang/String;)I", getGcwGroupImperialScorePercentile), + JF("getGcwFactionalPresenceTableDictionary", "()Lscript/dictionary;", getGcwFactionalPresenceTableDictionary), + JF("_getGcwContributionTrackingTableDictionary", "(J)Lscript/dictionary;", getGcwContributionTrackingTableDictionary), + JF("_getGcwDefenderRegions", "()[Ljava/lang/String;", getGcwDefenderRegions), + JF("_getGcwDefenderRegionsCitiesImperial", "()[Ljava/lang/String;", getGcwDefenderRegionsCitiesImperial), + JF("_getGcwDefenderRegionsCitiesRebel", "()[Ljava/lang/String;", getGcwDefenderRegionsCitiesRebel), + JF("getGcwDefenderRegionsCitiesVersion", "()I", getGcwDefenderRegionsCitiesVersion), + JF("_getGcwDefenderRegionsGuildsImperial", "()[Ljava/lang/String;", getGcwDefenderRegionsGuildsImperial), + JF("_getGcwDefenderRegionsGuildsRebel", "()[Ljava/lang/String;", getGcwDefenderRegionsGuildsRebel), + JF("getGcwDefenderRegionsGuildsVersion", "()I", getGcwDefenderRegionsGuildsVersion), + JF("getGcwDefenderRegionCitiesImperial", "(Ljava/lang/String;)[I", getGcwDefenderRegionCitiesImperial), + JF("getGcwDefenderRegionCitiesRebel", "(Ljava/lang/String;)[I", getGcwDefenderRegionCitiesRebel), + JF("getGcwDefenderRegionGuildsImperial", "(Ljava/lang/String;)[I", getGcwDefenderRegionGuildsImperial), + JF("getGcwDefenderRegionGuildsRebel", "(Ljava/lang/String;)[I", getGcwDefenderRegionGuildsRebel), + JF("getGcwDefenderRegionImperialBonus", "(Ljava/lang/String;)F", getGcwDefenderRegionImperialBonus), + JF("getGcwDefenderRegionRebelBonus", "(Ljava/lang/String;)F", getGcwDefenderRegionRebelBonus), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + +// ====================================================================== +// class JavaLibrary JNI command table methods +// ====================================================================== + +//------------------------------------------------------------------------------------------------ + +void JNICALL ScriptMethodsPvpNamespace::pvpSetAttackableOverride(JNIEnv *env, jobject self, jlong dest, jboolean value) +{ + TangibleObject *destObj = 0; + if (!JavaLibrary::getObject(dest, destObj)) + return; + if (destObj) + destObj->setAttackableOverride(value); +} + +/** + * Check whether an object is allowed to attack another. + * + * @param env Java Environment + * @param self class calling this function + * @param actor actor for the aggressive action + * @param target target for the aggressive action + * + * @return whether allowed + */ +jboolean JNICALL ScriptMethodsPvpNamespace::pvpCanAttack(JNIEnv *env, jobject self, jlong actor, jlong target) +{ + TangibleObject *actorObj = 0; + if (!JavaLibrary::getObject(actor, actorObj)) + return JNI_FALSE; + TangibleObject *targetObj = 0; + if (!JavaLibrary::getObject(target, targetObj)) + return JNI_FALSE; + + if (!actorObj || !targetObj) + return JNI_FALSE; + + if (Pvp::canAttack(*actorObj, *targetObj)) + return JNI_TRUE; + return JNI_FALSE; +} + +// ---------------------------------------------------------------------- + +/** + * Check whether an object is allowed to help another. + * + * @param env Java Environment + * @param self class calling this function + * @param actor actor for the helping action + * @param target target for the helping action + * + * @return whether allowed + */ +jboolean JNICALL ScriptMethodsPvpNamespace::pvpCanHelp(JNIEnv *env, jobject self, jlong actor, jlong target) +{ + TangibleObject *actorObj = 0; + if (!JavaLibrary::getObject(actor, actorObj)) + return JNI_FALSE; + TangibleObject *targetObj = 0; + if (!JavaLibrary::getObject(target, targetObj)) + return JNI_FALSE; + + if (!actorObj || !targetObj) + return JNI_FALSE; + + if (Pvp::canHelp(*actorObj, *targetObj)) + return JNI_TRUE; + return JNI_FALSE; +} + +// ---------------------------------------------------------------------- + +/** + * Handle an aggressive action having been done. + * + * @param env Java Environment + * @param self class calling this function + * @param actor actor for the aggressive action + * @param target target for the aggressive action + */ +void JNICALL ScriptMethodsPvpNamespace::pvpAttackPerformed(JNIEnv *env, jobject self, jlong actor, jlong target) +{ + TangibleObject *actorObj = 0, *targetObj = 0; + if (!JavaLibrary::getObject(actor, actorObj)) + return; + if (!JavaLibrary::getObject(target, targetObj)) + return; + + if (!actorObj || !targetObj) + return; + + if (ConfigServerGame::getDebugPvp() && !Pvp::canAttack(*actorObj, *targetObj)) + JavaLibrary::throwInternalScriptError("Tried to call pvpAttackPerformed when pvpCanAttack is false"); + else + Pvp::attackPerformed(*actorObj, *targetObj); +} + +// ---------------------------------------------------------------------- + +/** + * Handle a helping action having been done. + * + * @param env Java Environment + * @param self class calling this function + * @param actor actor for the helping action + * @param target target for the helping action + */ +void JNICALL ScriptMethodsPvpNamespace::pvpHelpPerformed(JNIEnv *env, jobject self, jlong actor, jlong target) +{ + TangibleObject *actorObj = 0, *targetObj = 0; + if (!JavaLibrary::getObject(actor, actorObj)) + return; + if (!JavaLibrary::getObject(target, targetObj)) + return; + + if (!actorObj || !targetObj) + return; + + if (ConfigServerGame::getDebugPvp() && !Pvp::canHelp(*actorObj, *targetObj)) + JavaLibrary::throwInternalScriptError("Tried to call pvpHelpPerformed when pvpCanHelp is false"); + else + Pvp::helpPerformed(*actorObj, *targetObj); +} + +// ---------------------------------------------------------------------- + +/** +* Set mercenary faction (Imperial or Rebel or 0) for a neutral player character +* +* @param env Java Environment +* @param self class calling this function +* @param dest object to set on +* @param factionId id for the faction +* @param declared declared (or covert) +*/ +void JNICALL ScriptMethodsPvpNamespace::pvpNeutralSetMercenaryFaction(JNIEnv *env, jobject self, jlong dest, jint factionId, jboolean declared) +{ + CreatureObject *destObj = 0; + if (!JavaLibrary::getObject(dest, destObj)) + return; + + // only applies to player character + if (!PlayerCreatureController::getPlayerObject(destObj)) + return; + + if (PvpData::isNeutralFactionId(static_cast(factionId))) + Pvp::setNeutralMercenaryFaction(*destObj, static_cast(factionId), PvpType_Neutral); + else if (PvpData::isImperialFactionId(static_cast(factionId)) || PvpData::isRebelFactionId(static_cast(factionId))) + Pvp::setNeutralMercenaryFaction(*destObj, static_cast(factionId), ((declared == JNI_FALSE) ? PvpType_Covert : PvpType_Declared)); +} + +// ---------------------------------------------------------------------- + +/** +* Get mercenary faction (Imperial or Rebel or 0) for a neutral player character +* +* @param env Java Environment +* @param self class calling this function +* @param who object to get mercenary faction from +* @return hash value for the faction +*/ +jint JNICALL ScriptMethodsPvpNamespace::pvpNeutralGetMercenaryFaction(JNIEnv *env, jobject self, jlong who) +{ + CreatureObject *obj = 0; + if (!JavaLibrary::getObject(who, obj)) + return 0; + + return static_cast(obj->getPvpMercenaryFaction()); +} + +// ---------------------------------------------------------------------- + +/** +* Get mercenary declared (vs covert) state for a neutral player character +* +* @param env Java Environment +* @param self class calling this function +* @param who object to get mercenary faction from +* @return boolean +*/ +jboolean JNICALL ScriptMethodsPvpNamespace::pvpNeutralIsMercenaryDeclared(JNIEnv *env, jobject self, jlong who) +{ + CreatureObject *obj = 0; + if (!JavaLibrary::getObject(who, obj)) + return JNI_FALSE; + + return ((obj->getPvpMercenaryType() == PvpType_Declared) ? JNI_TRUE : JNI_FALSE); +} + +// ---------------------------------------------------------------------- + +/** + * Set aligned faction for an object + * + * @param env Java Environment + * @param self class calling this function + * @param dest object to set on + * @param factionId id for the faction + */ +void JNICALL ScriptMethodsPvpNamespace::pvpSetAlignedFaction(JNIEnv *env, jobject self, jlong dest, jint factionId) +{ + TangibleObject *destObj = 0; + if (!JavaLibrary::getObject(dest, destObj)) + return; + if (destObj) + Pvp::setAlignedFaction(*destObj, static_cast(factionId)); +} + +// ---------------------------------------------------------------------- + +/** +* Set an object to on leave +* +* @param env Java Environment +* @param self class calling this function +* @param dest object to set on +*/ +void JNICALL ScriptMethodsPvpNamespace::pvpMakeOnLeave(JNIEnv *env, jobject self, jlong dest) +{ + TangibleObject *destObj = 0; + if (!JavaLibrary::getObject(dest, destObj)) + return; + if (destObj) + Pvp::makeOnLeave(*destObj); +} + +// ---------------------------------------------------------------------- + +/** + * Set an object to covert + * + * @param env Java Environment + * @param self class calling this function + * @param dest object to set on + */ +void JNICALL ScriptMethodsPvpNamespace::pvpMakeCovert(JNIEnv *env, jobject self, jlong dest) +{ + TangibleObject *destObj = 0; + if (!JavaLibrary::getObject(dest, destObj)) + return; + if (destObj) + Pvp::makeCovert(*destObj); +} + +// ---------------------------------------------------------------------- + +/** + * Set an object to declared + * + * @param env Java Environment + * @param self class calling this function + * @param dest object to set on + */ +void JNICALL ScriptMethodsPvpNamespace::pvpMakeDeclared(JNIEnv *env, jobject self, jlong dest) +{ + TangibleObject *destObj = 0; + if (!JavaLibrary::getObject(dest, destObj)) + return; + if (destObj) + Pvp::makeDeclared(*destObj); +} + +// ---------------------------------------------------------------------- + +/** + * Set an object to neutral + * + * @param env Java Environment + * @param self class calling this function + * @param dest object to set on + */ +void JNICALL ScriptMethodsPvpNamespace::pvpMakeNeutral(JNIEnv *env, jobject self, jlong dest) +{ + TangibleObject *destObj = 0; + if (!JavaLibrary::getObject(dest, destObj)) + return; + if (destObj) + Pvp::makeNeutral(*destObj); +} + +// ---------------------------------------------------------------------- + +/** + * Set a personal enemy flag on an object + * + * @param env Java Environment + * @param self class calling this function + * @param dest object to set on + * @param enemy enemy object + */ +void JNICALL ScriptMethodsPvpNamespace::pvpSetPersonalEnemyFlag(JNIEnv *env, jobject self, jlong dest, jlong enemy) +{ + TangibleObject *destObj = 0; + if (!JavaLibrary::getObject(dest, destObj)) + return; + TangibleObject *enemyObj = 0; + if (!JavaLibrary::getObject(enemy, enemyObj)) + return; + if (destObj && enemyObj) + Pvp::setPersonalEnemyFlag(*destObj, *enemyObj); +} + +// ---------------------------------------------------------------------- + +/** + * Set a permanent personal enemy flag on an object + * + * @param env Java Environment + * @param self class calling this function + * @param dest object to set on + * @param enemy enemy object + */ +void JNICALL ScriptMethodsPvpNamespace::pvpSetPermanentPersonalEnemyFlag(JNIEnv *env, jobject self, jlong dest, jlong enemy) +{ + TangibleObject *destObj = 0; + if (JavaLibrary::getObject(dest, destObj)) + { + NetworkId enemyId(enemy); + if (enemyId != NetworkId::cms_invalid) + Pvp::setPermanentPersonalEnemyFlag(*destObj, enemyId); + } +} + +// ---------------------------------------------------------------------- + +/** + * Set a faction enemy flag on an object + * + * @param env Java Environment + * @param self class calling this function + * @param dest object to set on + * @param factionId enemy faction + */ +void JNICALL ScriptMethodsPvpNamespace::pvpSetFactionEnemyFlag(JNIEnv *env, jobject self, jlong dest, jint factionId) +{ + TangibleObject *destObj = 0; + if (!JavaLibrary::getObject(dest, destObj)) + return; + if (destObj) + Pvp::setFactionEnemyFlag(*destObj, static_cast(factionId)); +} + +/** + * Set the "guild war cool down period" enemy flag on an object + * to prevent it from participating in any guild war related + * pvp for a period of time + * + * @param env Java Environment + * @param self class calling this function + * @param dest object to set on + */ +void JNICALL ScriptMethodsPvpNamespace::pvpSetGuildWarCoolDownPeriodEnemyFlag(JNIEnv *env, jobject self, jlong dest) +{ + CreatureObject *destObj = 0; + if (!JavaLibrary::getObject(dest, destObj)) + return; + if (destObj && destObj->getGuildWarEnabled() && (ConfigServerGame::getPvpGuildWarCoolDownPeriodTimeMs() > 0)) + Pvp::setFactionEnemyFlag(*destObj, PvpFactions::getGuildWarCoolDownPeriodFactionId(), ConfigServerGame::getPvpGuildWarCoolDownPeriodTimeMs()); +} + +// ---------------------------------------------------------------------- + +/** + * Get the pvp type for an object (0=neutral, 1=covert, 2=declared) + * + * @param env Java Environment + * @param self class calling this function + * @param who object to get pvp type from + * @return pvp type for the object + */ +jint JNICALL ScriptMethodsPvpNamespace::pvpGetType(JNIEnv *env, jobject self, jlong who) +{ + TangibleObject *obj = 0; + if (!JavaLibrary::getObject(who, obj)) + return 0; + return obj->getPvpType(); +} + +// ---------------------------------------------------------------------- + +/** + * Get the aligned faction for an object (hash string of the faction name) + * + * @param env Java Environment + * @param self class calling this function + * @param who object to get aligned faction from + * @return hash value for the faction + */ +jint JNICALL ScriptMethodsPvpNamespace::pvpGetAlignedFaction(JNIEnv *env, jobject self, jlong who) +{ + TangibleObject *obj = 0; + if (!JavaLibrary::getObject(who, obj)) + return 0; + return obj->getPvpFaction(); +} + +// ---------------------------------------------------------------------- + +/** + * Get the enemy flags on an object (string array, "enemyId enemyAlign expireTime") + * + * @param env Java Environment + * @param self class calling this function + * @param who object to get enemy flags from + * @return array of enemy flag specifiers + */ +jobjectArray JNICALL ScriptMethodsPvpNamespace::pvpGetEnemyFlags(JNIEnv *env, jobject self, jlong who) +{ + LocalObjectArrayRefPtr strArray; + TangibleObject *obj = 0; + if (JavaLibrary::getObject(who, obj)) + { + std::vector const &enemies = obj->getPvpEnemies().get(); + std::vector enemyStrings; + for (std::vector::const_iterator i = enemies.begin(); i != enemies.end(); ++i) + { + // faction id is stored in C++ as an unsigned crc, but in script/Java, + // there is no unsigned, so we must return the faction id as a signed + // crc, so script/Java can parse the string to arrive at the corresponding + // signed crc + char buffer[64]; + sprintf(buffer, "%s %d %d", + (*i).enemyId.getValueString().c_str(), + static_cast((*i).enemyFaction), + (*i).expireTime); + enemyStrings.push_back(std::string(buffer)); + } + if (ScriptConversion::convert(enemyStrings, strArray)) + return strArray->getReturnValue(); + } + return NULL; +} + +// ---------------------------------------------------------------------- + +/** + * Check whether the target is either an explicit or faction enemy of the actor + * + * @param env Java Environment + * @param self class calling this function + * @param actor person checking enemy status + * @param target target to check enemy status on + * @return true if enemy, false if not or on error + */ +jboolean JNICALL ScriptMethodsPvpNamespace::pvpIsEnemy(JNIEnv *env, jobject self, jlong actor, jlong target) +{ + TangibleObject *actorObj = 0; + TangibleObject *targetObj = 0; + if (JavaLibrary::getObject(actor, actorObj) && + JavaLibrary::getObject(target, targetObj) && + Pvp::isEnemy(*actorObj, *targetObj)) + { + return JNI_TRUE; + } + return JNI_FALSE; +} + +// ---------------------------------------------------------------------- + +/** + * Check whether the actor and target are currently dueling + * + * @param env Java Environment + * @param self class calling this function + * @param actor actor + * @param target target + * @return true if dueling, false if not or on error + */ +jboolean JNICALL ScriptMethodsPvpNamespace::pvpIsDueling(JNIEnv *env, jobject self, jlong actor, jlong target) +{ + TangibleObject *actorObj = 0; + TangibleObject *targetObj = 0; + if (JavaLibrary::getObject(actor, actorObj) && + JavaLibrary::getObject(target, targetObj) && + Pvp::hasDuelEnemyFlag(*actorObj, targetObj->getNetworkId()) && + Pvp::hasDuelEnemyFlag(*targetObj, actorObj->getNetworkId())) + { + return JNI_TRUE; + } + return JNI_FALSE; +} + +// ---------------------------------------------------------------------- + +/** + * Check whether the target has a battlefield enemy flag + * + * @param env Java Environment + * @param self class calling this function + * @param target target to look for a battlefield enemy flag on + * @return true if enemy, false if not or on error + */ +jboolean JNICALL ScriptMethodsPvpNamespace::pvpHasBattlefieldEnemyFlag(JNIEnv *env, jobject self, jlong target) +{ + // a battlefield enemy flag is an FEF toward the battlefield faction + TangibleObject *targetObj = 0; + if (!JavaLibrary::getObject(target, targetObj)) + return JNI_FALSE; + return Pvp::hasFactionEnemyFlag(*targetObj, PvpFactions::getBattlefieldFactionId()); +} + +// ---------------------------------------------------------------------- + +/** + * Get an array of enemy objects which are in range of a location. + * + * @param env Java Environment + * @param self class calling this function + * @param actor The actor for the enemy check + * @param from The center of the range + * @param range The distance to query. + * @return null if there is an error, or an array of enemy objects which are in range. + */ +jlongArray JNICALL ScriptMethodsPvpNamespace::pvpGetEnemiesInRange(JNIEnv *env, jobject self, jlong actor, jlong location, jfloat range) +{ + UNREF(self); + + TangibleObject *actorObject = 0; + if (!JavaLibrary::getObject(actor, actorObject) || !actorObject) + return 0; + + if (!location) + return 0; + Vector target; + if (!ScriptConversion::convertWorld(location, target)) + return 0; + + std::vector results; + ServerWorld::findObjectsInRange(target, range, results); + + std::vector filteredResults(results.size()); + for (std::vector::iterator i = results.begin(); i != results.end(); ++i) + { + TangibleObject *t = (*i)->asTangibleObject(); + if (t && Pvp::isEnemy(*actorObject, *t)) + filteredResults.push_back(t); + } + + LocalLongArrayRefPtr rv; + if (ScriptConversion::convert(filteredResults, rv)) + return rv->getReturnValue(); + return 0; +} + +// ---------------------------------------------------------------------- + +/** + * Get an array of enemy objects which are in a cone of a location. + * + * @param env Java Environment + * @param self class calling this function + * @param actor The actor for the enemy check + * @param coneCenterObject The object at the center (base, pointy part) of the cone. + * @param coneDirectionObject An object to orient the axis of the cone. The axis goes from + * the coneCenterObject position to this object's position. + * @param range The distance to query from the center of the cone. Note the cone + * extends along the cone axis this distance, and does not necessarily + * extend as far as the cone direction object's distance from the cone center. + * @param angle The cone angle, in degrees, that the cone sweeps out. The + * total cone angle is twice this angle; therefore, this angle + * represents the angle swept out to each side of the cone axis. + * @return null if there is an error, or an array of enemy objects which are in range. + */ +jlongArray JNICALL ScriptMethodsPvpNamespace::pvpGetEnemiesInCone(JNIEnv *env, jobject self, jlong actor, jlong coneCenterObjectId, jlong coneDirectionObjectId, jfloat range, jfloat angle) +{ + UNREF(self); + + if (!coneCenterObjectId || !coneDirectionObjectId) + return 0; + + TangibleObject *actorObject = 0; + Object *coneCenterObject = 0; + Object *coneDirectionObject = 0; + + if (!JavaLibrary::getObject(actor, actorObject) || !actorObject) + return 0; + if (!JavaLibrary::getObject(coneCenterObjectId, coneCenterObject) || !coneCenterObject) + return 0; + if (!JavaLibrary::getObject(coneDirectionObjectId, coneDirectionObject) || !coneDirectionObject) + return 0; + + std::vector results; + ServerWorld::findObjectsInCone(*coneCenterObject, *coneDirectionObject, range, convertDegreesToRadians(angle), results); + + std::vector filteredResults(results.size()); + for (std::vector::iterator i = results.begin(); i != results.end(); ++i) + { + TangibleObject *t = (*i)->asTangibleObject(); + if (t && Pvp::isEnemy(*actorObject, *t)) + filteredResults.push_back(t); + } + + LocalLongArrayRefPtr rv; + if (ScriptConversion::convert(filteredResults, rv)) + return rv->getReturnValue(); + return 0; +} + +// ---------------------------------------------------------------------- + +/** + * Get an array of enemy objects which are in a cone of a location. + * + * @param env Java Environment + * @param self class calling this function + * @param actor The actor for the enemy check + * @param coneCenterObjectId The object at the center (base, pointy part) of the cone. + * @param coneDirectionLocation The position to orient the axis of the cone. The axis goes from + * the coneCenterObject position to this position (scene value of the location ignored). + * @param range The distance to query from the center of the cone. Note the cone + * extends along the cone axis this distance, and does not necessarily + * extend as far as the cone direction object's distance from the cone center. + * @param angle The cone angle, in degrees, that the cone sweeps out. The + * total cone angle is twice this angle; therefore, this angle + * represents the angle swept out to each side of the cone axis. + * @return null if there is an error, or an array of enemy objects which are in range. + */ +jlongArray JNICALL ScriptMethodsPvpNamespace::pvpGetEnemiesInConeLocation(JNIEnv *env, jobject self, jlong actor, jlong coneCenterObjectId, jobject coneDirectionLocation, jfloat range, jfloat angle) +{ + UNREF(self); + + if (!coneCenterObjectId || !coneDirectionLocation) + return 0; + + TangibleObject *actorObject = 0; + Object *coneCenterObject = 0; + Location coneDirection; + + if (!JavaLibrary::getObject(actor, actorObject) || !actorObject) + return 0; + if (!JavaLibrary::getObject(coneCenterObjectId, coneCenterObject) || !coneCenterObject) + return 0; + if (!ScriptConversion::convert(LocalRefParam(coneDirectionLocation), coneDirection)) + return 0; + + std::vector results; + ServerWorld::findObjectsInCone(*coneCenterObject, coneDirection, range, convertDegreesToRadians(angle), results); + + std::vector filteredResults(results.size()); + for (std::vector::iterator i = results.begin(); i != results.end(); ++i) + { + TangibleObject *t = (*i)->asTangibleObject(); + if (t && Pvp::isEnemy(*actorObject, *t)) + filteredResults.push_back(t); + } + + LocalLongArrayRefPtr rv; + if (ScriptConversion::convert(filteredResults, rv)) + return rv->getReturnValue(); + return 0; +} + +// ---------------------------------------------------------------------- + +/** + * Get an array of attackable objects which are in range of a location. + * + * @param env Java Environment + * @param self class calling this function + * @param actor The actor for the canAttack check + * @param from The center of the range + * @param range The distance to query. + * @return null if there is an error, or an array of attackable objects which are in range. + */ +jlongArray JNICALL ScriptMethodsPvpNamespace::pvpGetTargetsInRange(JNIEnv *env, jobject self, jlong actor, jlong location, jfloat range) +{ + UNREF(self); + + TangibleObject *actorObject = 0; + if (!JavaLibrary::getObject(actor, actorObject) || !actorObject) + return 0; + + if (!location) + return 0; + + Vector target; + if (!ScriptConversion::convertWorld(location, target)) + return 0; + + std::vector results; + ServerWorld::findObjectsInRange(target, range, results); + + std::vector filteredResults(results.size()); + for (std::vector::iterator i = results.begin(); i != results.end(); ++i) + { + TangibleObject *t = (*i)->asTangibleObject(); + if (t && Pvp::canAttack(*actorObject, *t)) + filteredResults.push_back(t); + } + + LocalLongArrayRefPtr rv; + if (ScriptConversion::convert(filteredResults, rv)) + return rv->getReturnValue(); + return 0; +} + +// ---------------------------------------------------------------------- + +/** + * Get an array of attackable objects which are in a cone of a location. + * + * @param env Java Environment + * @param self class calling this function + * @param actor The actor for the canAttack check + * @param coneCenterObject The object at the center (base, pointy part) of the cone. + * @param coneDirectionObject An object to orient the axis of the cone. The axis goes from + * the coneCenterObject position to this object's position. + * @param range The distance to query from the center of the cone. Note the cone + * extends along the cone axis this distance, and does not necessarily + * extend as far as the cone direction object's distance from the cone center. + * @param angle The cone angle, in degrees, that the cone sweeps out. The + * total cone angle is twice this angle; therefore, this angle + * represents the angle swept out to each side of the cone axis. + * @return null if there is an error, or an array of attackable objects which are in range. + */ +jlongArray JNICALL ScriptMethodsPvpNamespace::pvpGetTargetsInCone(JNIEnv *env, jobject self, jlong actor, jlong coneCenterObjectId, jlong coneDirectionObjectId, jfloat range, jfloat angle) +{ + UNREF(self); + + if (!coneCenterObjectId || !coneDirectionObjectId) + return 0; + + TangibleObject *actorObject = 0; + Object *coneCenterObject = 0; + Object *coneDirectionObject = 0; + + if (!JavaLibrary::getObject(actor, actorObject) || !actorObject) + return 0; + if (!JavaLibrary::getObject(coneCenterObjectId, coneCenterObject) || !coneCenterObject) + return 0; + if (!JavaLibrary::getObject(coneDirectionObjectId, coneDirectionObject) || !coneDirectionObject) + return 0; + + std::vector results; + ServerWorld::findObjectsInCone(*coneCenterObject, *coneDirectionObject, range, convertDegreesToRadians(angle), results); + + std::vector filteredResults(results.size()); + for (std::vector::iterator i = results.begin(); i != results.end(); ++i) + { + TangibleObject *t = (*i)->asTangibleObject(); + if (t && Pvp::canAttack(*actorObject, *t)) + filteredResults.push_back(t); + } + + LocalLongArrayRefPtr rv; + if (ScriptConversion::convert(filteredResults, rv)) + return rv->getReturnValue(); + return 0; +} + +// ---------------------------------------------------------------------- + +/** + * Get an array of attackable objects which are in a cone of a location. + * + * @param env Java Environment + * @param self class calling this function + * @param actor The actor for the canAttack check + * @param coneCenterObject The object at the center (base, pointy part) of the cone. + * @param coneDirectionLocation The position to orient the axis of the cone. The axis goes from + * the coneCenterObject position to this position (scene value of the location ignored). + * @param range The distance to query from the center of the cone. Note the cone + * extends along the cone axis this distance, and does not necessarily + * extend as far as the cone direction object's distance from the cone center. + * @param angle The cone angle, in degrees, that the cone sweeps out. The + * total cone angle is twice this angle; therefore, this angle + * represents the angle swept out to each side of the cone axis. + * @return null if there is an error, or an array of attackable objects which are in range. + */ +jlongArray JNICALL ScriptMethodsPvpNamespace::pvpGetTargetsInConeLocation(JNIEnv *env, jobject self, jlong actor, jlong coneCenterObjectId, jobject coneDirectionLocation, jfloat range, jfloat angle) +{ + UNREF(self); + + if (!coneCenterObjectId || !coneDirectionLocation) + return 0; + + TangibleObject *actorObject = 0; + Object *coneCenterObject = 0; + Location coneDirection; + + if (!JavaLibrary::getObject(actor, actorObject) || !actorObject) + return 0; + if (!JavaLibrary::getObject(coneCenterObjectId, coneCenterObject) || !coneCenterObject) + return 0; + if (!ScriptConversion::convert(LocalRefParam(coneDirectionLocation), coneDirection)) + return 0; + + std::vector results; + ServerWorld::findObjectsInCone(*coneCenterObject, coneDirection, range, convertDegreesToRadians(angle), results); + + std::vector filteredResults(results.size()); + for (std::vector::iterator i = results.begin(); i != results.end(); ++i) + { + TangibleObject *t = (*i)->asTangibleObject(); + if (t && Pvp::canAttack(*actorObject, *t)) + filteredResults.push_back(t); + } + + LocalLongArrayRefPtr rv; + if (ScriptConversion::convert(filteredResults, rv)) + return rv->getReturnValue(); + return 0; +} + +// ---------------------------------------------------------------------- + +/** + * Check whether a faction has another faction as an opponent + * + * @param env Java Environment + * @param self class calling this function + * @param faction1 id for faction to check opponents of + * @param faction2 id for potential opponent + * @return whether factions are opposed + */ +jboolean JNICALL ScriptMethodsPvpNamespace::pvpAreFactionsOpposed(JNIEnv *env, jobject self, jint faction1, jint faction2) +{ + return Pvp::areFactionsOpposed(faction1, faction2); +} + +// ---------------------------------------------------------------------- + +/** + * Get a person's faction on a particular battlefield + * + * @param env Java Environment + * @param self class calling this function + * @param target the person to get the faction for + * @param region the battlefield region + * @return the faction id or 0 + */ +jint JNICALL ScriptMethodsPvpNamespace::pvpBattlefieldGetFaction(JNIEnv *env, jobject self, jlong target, jobject region) +{ + TangibleObject *targetObject = 0; + if (!JavaLibrary::getObject(target, targetObject)) + return 0; + + Region const *regionObject = 0; + if (!ScriptConversion::convert(region, regionObject)) + { + WARNING(true, ("JavaLibrary::pvpBattlefieldGetFaction object passed in is not a region")); + return 0; + } + + RegionPvp const *pvpRegion = regionObject->asRegionPvp(); + if (!pvpRegion) + { + WARNING(true, ("JavaLibrary::pvpBattlefieldGetFaction object passed in is not a pvp region")); + return 0; + } + + return Pvp::battlefieldGetFaction(*targetObject, *pvpRegion); +} + +// ---------------------------------------------------------------------- + +/** + * Check whether a person is a participant on a battlefield + * + * @param env Java Environment + * @param self class calling this function + * @param target the person to check + * @param region the battlefield region + * @return whether the person is involved in the battlefield + */ +jboolean JNICALL ScriptMethodsPvpNamespace::pvpBattlefieldIsParticipant(JNIEnv *env, jobject self, jlong target, jobject region) +{ + TangibleObject *targetObject = 0; + if (!JavaLibrary::getObject(target, targetObject)) + return JNI_FALSE; + + Region const *regionObject = 0; + if (!ScriptConversion::convert(region, regionObject)) + { + WARNING(true, ("JavaLibrary::pvpBattlefieldIsParticipant object passed in is not a region")); + return JNI_FALSE; + } + + RegionPvp const *pvpRegion = regionObject->asRegionPvp(); + if (!pvpRegion) + { + WARNING(true, ("JavaLibrary::pvpBattlefieldIsParticipant object passed in is not a pvp region")); + return JNI_FALSE; + } + + if (Pvp::battlefieldIsParticipant(*targetObject, *pvpRegion)) + return JNI_TRUE; + return JNI_FALSE; +} + +// ---------------------------------------------------------------------- + +/** + * Set the faction a person is fighting for on a battlefield + * + * @param env Java Environment + * @param self class calling this function + * @param target the person + * @param region the battlefield region + * @param faction the faction + */ +void JNICALL ScriptMethodsPvpNamespace::pvpBattlefieldSetParticipant(JNIEnv *env, jobject self, jlong target, jobject region, jint faction) +{ + TangibleObject *targetObject = 0; + if (!JavaLibrary::getObject(target, targetObject)) + return; + + Region const *regionObject = 0; + if (!ScriptConversion::convert(region, regionObject)) + { + WARNING(true, ("JavaLibrary::pvpBattlefieldSetParticipant object passed in is not a region")); + return; + } + + RegionPvp const *pvpRegion = regionObject->asRegionPvp(); + if (!pvpRegion) + { + WARNING(true, ("JavaLibrary::pvpBattlefieldSetParticipant object passed in is not a pvp region")); + return; + } + + Pvp::battlefieldSetParticipant(*targetObject, *pvpRegion, faction); +} + +// ---------------------------------------------------------------------- + +jlongArray JNICALL ScriptMethodsPvpNamespace::pvpBattlefieldGetParticipantsForFaction(JNIEnv *env, jobject self, jobject region, jint faction) +{ + Region const *regionObject = 0; + if (!ScriptConversion::convert(region, regionObject)) + { + WARNING(true, ("JavaLibrary::pvpBattlefieldGetParticipantsForFaction object passed in is not a region")); + return 0; + } + + RegionPvp const *pvpRegion = regionObject->asRegionPvp(); + if (!pvpRegion) + { + WARNING(true, ("JavaLibrary::pvpBattlefieldGetParticipantsForFaction object passed in is not a pvp region")); + return 0; + } + + BattlefieldMarkerObject const *marker = pvpRegion->getBattlefieldMarker(); + if (!marker) + { + WARNING(true, ("JavaLibrary::pvpBattlefieldGetParticipantsForFaction could not find battlefield marker for region")); + return 0; + } + + std::map const &participantMap = marker->getBattlefieldParticipants(); + + int count = 0; + + { + for (std::map::const_iterator i = participantMap.begin(); i != participantMap.end(); ++i) + if (faction == 0 || (*i).second == static_cast(faction)) + ++count; + } + + LocalLongArrayRefPtr items = createNewLongArray(count); + if (items == LocalLongArrayRef::cms_nullPtr) + return 0; + + int index = 0; + jlong jlongTmp; + { + for (std::map::const_iterator i = participantMap.begin(); i != participantMap.end(); ++i) + { + if (faction == 0 || (*i).second == static_cast(faction)) + { + jlongTmp = ((*i).first).getValue(); + setLongArrayRegion(*items, index, 1, &jlongTmp); + ++index; + } + } + } + + return items->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +/** + * Clear the participant info for a battlefield region. + * + * @param env Java Environment + * @param self class calling this function + * @param region the battlefield region + */ +void JNICALL ScriptMethodsPvpNamespace::pvpBattlefieldClearParticipants(JNIEnv *env, jobject self, jobject region) +{ + Region const *regionObject = 0; + if (!ScriptConversion::convert(region, regionObject)) + { + WARNING(true, ("JavaLibrary::pvpBattlefieldClearParticipants object passed in is not a region")); + return; + } + + RegionPvp const *pvpRegion = regionObject->asRegionPvp(); + if (!pvpRegion) + { + WARNING(true, ("JavaLibrary::pvpBattlefieldClearParticipants object passed in is not a pvp region")); + return; + } + + Pvp::battlefieldClearParticipants(*pvpRegion); +} + +// ---------------------------------------------------------------------- + +/** + * Remove all temp enemy flags from an object (generally used for death) + * + * @param env Java Environment + * @param self class calling this function + * @param target the object to strip temp enemy flags from + */ +void JNICALL ScriptMethodsPvpNamespace::pvpRemoveAllTempEnemyFlags(JNIEnv *env, jobject self, jlong target) +{ + TangibleObject *targetObject = 0; + if (JavaLibrary::getObject(target, targetObject)) + Pvp::removeAllTempEnemyFlags(*targetObject); +} + +// ---------------------------------------------------------------------- + +/** + * Returns the battlefield marker object associated with a battlefield region. + * + * @param env Java Environment + * @param self class calling this function + * @param region the battlefield region + * + * @return the marker object + */ +jlong JNICALL ScriptMethodsPvpNamespace::getBattlefieldRegionMasterObject(JNIEnv *env, jobject self, jobject battlefieldRegion) +{ + Region const *regionObject = 0; + if (!ScriptConversion::convert(battlefieldRegion, regionObject)) + { + WARNING(true, ("JavaLibrary::getBattlefieldRegionMasterObject object passed in is not a region")); + return 0; + } + + RegionPvp const *pvpRegion = regionObject->asRegionPvp(); + if (!pvpRegion) + { + WARNING(true, ("JavaLibrary::getBattlefieldRegionMasterObject object passed in is not a pvp region")); + return 0; + } + + BattlefieldMarkerObject const *markerObject = pvpRegion->getBattlefieldMarker(); + NetworkId marker = markerObject ? markerObject->getNetworkId() : NetworkId::cms_invalid; + return marker.getValue(); +} // JavaLibrary::getBattlefieldRegionMasterObject + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsPvpNamespace::setBattlefieldMarkerRegionName(JNIEnv *env, jobject self, jlong marker, jstring regionName) +{ + BattlefieldMarkerObject *markerObject = 0; + if (JavaLibrary::getObject(marker, markerObject)) + { + JavaStringParam localRegionName(regionName); + std::string regionNameString; + JavaLibrary::convert(localRegionName, regionNameString); + markerObject->setRegionName(regionNameString); + } +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsPvpNamespace::pvpHasAnyTempEnemyFlags(JNIEnv *env, jobject self, jlong target) +{ + TangibleObject *targetObject = 0; + if (JavaLibrary::getObject(target, targetObject)) + return static_cast(Pvp::hasAnyTimedEnemyFlag(*targetObject) ? JNI_TRUE : JNI_FALSE); + return JNI_FALSE; +} + +// ---------------------------------------------------------------------- + +jlongArray JNICALL ScriptMethodsPvpNamespace::pvpGetPersonalEnemyIds(JNIEnv *env, jobject self, jlong target) +{ + TangibleObject *targetObject = 0; + if (!JavaLibrary::getObject(target, targetObject)) + return 0; + + std::vector enemyIds; + Pvp::getPersonalEnemyIds(*targetObject, enemyIds); + + LocalLongArrayRefPtr items = createNewLongArray(enemyIds.size()); + if (items == LocalLongArrayRef::cms_nullPtr) + return 0; + + jlong jlongTmp; + for (unsigned int i = 0; i < enemyIds.size(); ++i) + { + jlongTmp = enemyIds[i].getValue(); + setLongArrayRegion(*items, i, 1, &jlongTmp); + } + + return items->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsPvpNamespace::pvpRemoveTempEnemyFlags(JNIEnv *env, jobject self, jlong target, jlong enemyId) +{ + TangibleObject *targetObject = 0; + if (!JavaLibrary::getObject(target, targetObject)) + return; + + NetworkId enemyNetworkId(enemyId); + Pvp::removeTempEnemyFlags(*targetObject, enemyNetworkId); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsPvpNamespace::pvpWouldAttackCauseAlignedEnemyFlag(JNIEnv *env, jobject self, jlong actor, jlong target) +{ + TangibleObject *actorObject = 0; + TangibleObject *targetObject = 0; + if (!JavaLibrary::getObject(actor, actorObject) || + !JavaLibrary::getObject(target, targetObject)) + { + return JNI_FALSE; + } + return Pvp::wouldAttackCauseAlignedEnemyFlag(*actorObject, *targetObject); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsPvpNamespace::pvpWouldHelpCauseAlignedEnemyFlag(JNIEnv *env, jobject self, jlong actor, jlong target) +{ + TangibleObject *actorObject = 0; + TangibleObject *targetObject = 0; + if (!JavaLibrary::getObject(actor, actorObject) || + !JavaLibrary::getObject(target, targetObject)) + { + return JNI_FALSE; + } + return Pvp::wouldHelpCauseAlignedEnemyFlag(*actorObject, *targetObject); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsPvpNamespace::pvpHasPersonalEnemyFlag(JNIEnv *env, jobject self, jlong actor, jlong target) +{ + TangibleObject *actorObj = 0; + if (!JavaLibrary::getObject(actor, actorObj)) + return JNI_FALSE; + + if (!actorObj) + return JNI_FALSE; + + NetworkId targetNetworkId(target); + if (Pvp::hasPersonalEnemyFlag(*actorObj, targetNetworkId)) + return JNI_TRUE; + + return JNI_FALSE; +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsPvpNamespace::pvpRemovePersonalEnemyFlags(JNIEnv *env, jobject self, jlong target, jlong enemyId) +{ + TangibleObject *targetObject = 0; + if (!JavaLibrary::getObject(target, targetObject)) + return; + + if (!targetObject) + return; + + NetworkId enemyNetworkId(enemyId); + Pvp::removePersonalEnemyFlags(*targetObject, enemyNetworkId); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsPvpNamespace::pvpPrepareToBeCovert(JNIEnv * env, jobject /*self*/, jlong dest) +{ + TangibleObject *destObj = 0; + if (!JavaLibrary::getObject(dest, destObj)) + { + return; + } + + if (destObj != 0) + { + Pvp::prepareToBeCovert(*destObj); + } +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsPvpNamespace::pvpPrepareToBeDeclared(JNIEnv * env, jobject /*self*/, jlong dest) +{ + TangibleObject *destObj = 0; + if (!JavaLibrary::getObject(dest, destObj)) + { + return; + } + + if (destObj != 0) + { + Pvp::prepareToBeDeclared(*destObj); + } +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsPvpNamespace::pvpPrepareToBeNeutral(JNIEnv * env, jobject /*self*/, jlong dest) +{ + TangibleObject *destObj = 0; + if (!JavaLibrary::getObject(dest, destObj)) + { + return; + } + + if (destObj != 0) + { + Pvp::prepareToBeNeutral(*destObj); + } +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsPvpNamespace::pvpModifyCurrentGcwPoints(JNIEnv *env, jobject self, jlong target, jint adjustment) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return; + + PlayerObject * const player = PlayerCreatureController::getPlayerObject(creature); + if (player) + { + // grant GCW Region Defender bonus + float bonus = 0.0f; + if ((adjustment > 0) && Pvp::getGcwDefenderRegionBonus(*creature, *player, bonus) && (bonus > 0.0f)) + adjustment += std::max(1, static_cast(static_cast(bonus) * static_cast(adjustment) / static_cast(100))); + + player->modifyCurrentGcwPoints(adjustment, true); + } +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsPvpNamespace::pvpModifyCurrentPvpKills(JNIEnv *env, jobject self, jlong target, jint adjustment) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return; + + PlayerObject * player = PlayerCreatureController::getPlayerObject(creature); + if (player) + player->modifyCurrentPvpKills(adjustment, true); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsPvpNamespace::pvpGetCurrentGcwRank(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return 0; + + PlayerObject * player = PlayerCreatureController::getPlayerObject(creature); + if (!player) + return 0; + + return player->getCurrentGcwRank(); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsPvpNamespace::pvpGetMaxGcwImperialRank(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return 0; + + PlayerObject * player = PlayerCreatureController::getPlayerObject(creature); + if (!player) + return 0; + + return player->getMaxGcwImperialRank(); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsPvpNamespace::pvpGetMaxGcwRebelRank(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return 0; + + PlayerObject * player = PlayerCreatureController::getPlayerObject(creature); + if (!player) + return 0; + + return player->getMaxGcwRebelRank(); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsPvpNamespace::pvpGetCurrentGcwPoints(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return 0; + + PlayerObject * player = PlayerCreatureController::getPlayerObject(creature); + if (!player) + return 0; + + return static_cast(player->getCurrentGcwPoints()); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsPvpNamespace::pvpGetCurrentGcwRating(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return -1; + + PlayerObject * player = PlayerCreatureController::getPlayerObject(creature); + if (!player) + return -1; + + return static_cast(player->getCurrentGcwRating()); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsPvpNamespace::pvpGetCurrentPvpKills(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return 0; + + PlayerObject * player = PlayerCreatureController::getPlayerObject(creature); + if (!player) + return 0; + + return static_cast(player->getCurrentPvpKills()); +} + +// ---------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsPvpNamespace::pvpGetLifetimeGcwPoints(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return 0; + + PlayerObject * player = PlayerCreatureController::getPlayerObject(creature); + if (!player) + return 0; + + return static_cast(player->getLifetimeGcwPoints()); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsPvpNamespace::pvpGetMaxGcwImperialRating(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return -1; + + PlayerObject * player = PlayerCreatureController::getPlayerObject(creature); + if (!player) + return -1; + + return static_cast(player->getMaxGcwImperialRating()); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsPvpNamespace::pvpGetMaxGcwRebelRating(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return -1; + + PlayerObject * player = PlayerCreatureController::getPlayerObject(creature); + if (!player) + return -1; + + return static_cast(player->getMaxGcwRebelRating()); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsPvpNamespace::pvpGetLifetimePvpKills(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return 0; + + PlayerObject * player = PlayerCreatureController::getPlayerObject(creature); + if (!player) + return 0; + + return static_cast(player->getLifetimePvpKills()); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsPvpNamespace::pvpGetNextGcwRatingCalcTime(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return 0; + + PlayerObject * player = PlayerCreatureController::getPlayerObject(creature); + if (!player) + return 0; + + return static_cast(player->getNextGcwRatingCalcTime()); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsPvpNamespace::ctsUseOnlySetGcwInfo(JNIEnv *env, jobject self, jlong target, jint currentGcwPoints, jint currentGcwRating, jint currentPvpKills, jlong lifetimeGcwPoints, jint maxGcwImperialRating, jint maxGcwRebelRating, jint lifetimePvpKills, jint nextGcwRatingCalcTime) +{ + UNREF(self); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return; + + PlayerObject * player = PlayerCreatureController::getPlayerObject(creature); + if (!player) + return; + + player->ctsUseOnlySetGcwInfo(static_cast(currentGcwPoints), static_cast(currentGcwRating), static_cast(currentPvpKills), static_cast(lifetimeGcwPoints), static_cast(maxGcwImperialRating), static_cast(maxGcwRebelRating), static_cast(lifetimePvpKills), static_cast(nextGcwRatingCalcTime)); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsPvpNamespace::adjustGcwImperialScore(JNIEnv *env, jobject self, jstring source, jlong sourceOid, jstring gcwCategory, jint adjustment) +{ + JavaStringParam localSource(source); + std::string sourceString; + JavaLibrary::convert(localSource, sourceString); + + JavaStringParam localGcwCategory(gcwCategory); + std::string gcwCategoryString; + JavaLibrary::convert(localGcwCategory, gcwCategoryString); + + CreatureObject * creature = 0; + JavaLibrary::getObject(sourceOid, creature); + + ServerUniverse::getInstance().adjustGcwImperialScore(sourceString, creature, gcwCategoryString, adjustment); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsPvpNamespace::adjustGcwRebelScore(JNIEnv *env, jobject self, jstring source, jlong sourceOid, jstring gcwCategory, jint adjustment) +{ + JavaStringParam localSource(source); + std::string sourceString; + JavaLibrary::convert(localSource, sourceString); + + JavaStringParam localGcwCategory(gcwCategory); + std::string gcwCategoryString; + JavaLibrary::convert(localGcwCategory, gcwCategoryString); + + CreatureObject * creature = 0; + JavaLibrary::getObject(sourceOid, creature); + + ServerUniverse::getInstance().adjustGcwRebelScore(sourceString, creature, gcwCategoryString, adjustment); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsPvpNamespace::getGcwImperialScorePercentile(JNIEnv *env, jobject self, jstring gcwCategory) +{ + JavaStringParam localGcwCategory(gcwCategory); + std::string gcwCategoryString; + JavaLibrary::convert(localGcwCategory, gcwCategoryString); + + return ServerUniverse::getInstance().getGcwImperialScorePercentile(gcwCategoryString); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsPvpNamespace::getGcwGroupImperialScorePercentile(JNIEnv *env, jobject self, jstring gcwGroup) +{ + JavaStringParam localGcwGroup(gcwGroup); + std::string gcwGroupString; + JavaLibrary::convert(localGcwGroup, gcwGroupString); + + return ServerUniverse::getInstance().getGcwGroupImperialScorePercentile(gcwGroupString); +} + +// ---------------------------------------------------------------------- + +jobject JNICALL ScriptMethodsPvpNamespace::getGcwFactionalPresenceTableDictionary(JNIEnv * env, jobject self) +{ + ScriptParams const * scriptParams = PlanetObject::getConnectedCharacterLfgDataFactionalPresenceTableDictionary(); + if (!scriptParams) + return 0; + + JavaDictionaryPtr dictionary; + JavaLibrary::instance()->convert(*scriptParams, dictionary); + return dictionary->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jobject JNICALL ScriptMethodsPvpNamespace::getGcwContributionTrackingTableDictionary(JNIEnv * env, jobject self, jlong player) +{ + UNREF(self); + + CreatureObject const * creatureObj = 0; + if (!JavaLibrary::getObject(player, creatureObj)) + return 0; + + PlayerObject const * const playerObj = PlayerCreatureController::getPlayerObject(creatureObj); + if (!playerObj) + return 0; + + DynamicVariableList::NestedList const gcwContribution(playerObj->getObjVars(), "gcwContributionTracking"); + int const size = gcwContribution.getCount(); + if (size <= 0) + return 0; + + std::vector * scriptParamsRegion = new std::vector; + std::vector * scriptParamsTime = new std::vector; + scriptParamsRegion->reserve(size); + scriptParamsTime->reserve(size); + + char buffer[128]; + int timeLastContributed = 0; + for (DynamicVariableList::NestedList::const_iterator i = gcwContribution.begin(); i != gcwContribution.end(); ++i) + { + if (Pvp::getGcwScoreCategory(i.getName()) && i.getValue(timeLastContributed)) + { + snprintf(buffer, sizeof(buffer)-1, "@gcw_regions:%s", i.getName().c_str()); + buffer[sizeof(buffer)-1] = '\0'; + + scriptParamsRegion->push_back(makeCopyOfString(buffer)); + scriptParamsTime->push_back(makeCopyOfString(CalendarTime::convertEpochToTimeStringLocal_YYYYMMDDHHMMSS(static_cast(timeLastContributed)).c_str())); + } + } + + // column header + static const char * s_scriptParamsColumnHeadersText[2] = + { + "GCW Region/Category", + "Time Of Last Contribution" + }; + static std::vector s_scriptParamsColumnHeaders(s_scriptParamsColumnHeadersText, s_scriptParamsColumnHeadersText + (sizeof(s_scriptParamsColumnHeadersText) / sizeof(const char *))); + + // column type + static const char * s_scriptParamsColumnTypeText[2] = + { + "text", + "text" + }; + static std::vector s_scriptParamsColumnType(s_scriptParamsColumnTypeText, s_scriptParamsColumnTypeText + (sizeof(s_scriptParamsColumnTypeText) / sizeof(const char *))); + + ScriptParams sp; + sp.addParam(s_scriptParamsColumnHeaders, "column", false); + sp.addParam(s_scriptParamsColumnType, "columnType", false); + sp.addParam(*scriptParamsRegion, "column0", true); + sp.addParam(*scriptParamsTime, "column1", true); + + JavaDictionaryPtr dictionary; + JavaLibrary::instance()->convert(sp, dictionary); + return dictionary->getReturnValue(); +} + +//----------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsPvpNamespace::getGcwDefenderRegions(JNIEnv * /*env*/, jobject /*self*/) +{ + // walk the list twice, this method shouldn't get called + // very often as the result is cached in script + std::map const & allGcwScoreCategory = Pvp::getAllGcwScoreCategory(); + std::map::const_iterator iter; + int count = 0; + for (iter = allGcwScoreCategory.begin(); iter != allGcwScoreCategory.end(); ++iter) + { + if (iter->second->gcwRegionDefender) + ++count; + } + + if (count <= 0) + return 0; + + LocalObjectArrayRefPtr valueArray = createNewObjectArray(count, JavaLibrary::getClsString()); + count = 0; + for (iter = allGcwScoreCategory.begin(); iter != allGcwScoreCategory.end(); ++iter) + { + if (iter->second->gcwRegionDefender) + { + JavaString jval(std::string("@gcw_regions:") + iter->second->categoryName); + setObjectArrayElement(*valueArray, count++, jval); + } + } + + return valueArray->getReturnValue(); +} + +//----------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsPvpNamespace::getGcwDefenderRegionsCitiesImperial(JNIEnv *env, jobject self) +{ + // walk the list twice, this method shouldn't get called + // very often as the result is cached in script + std::map const & allGcwScoreCategory = Pvp::getAllGcwScoreCategory(); + std::map::const_iterator iter; + int count = 0; + for (iter = allGcwScoreCategory.begin(); iter != allGcwScoreCategory.end(); ++iter) + { + if (iter->second->gcwRegionDefender) + ++count; + } + + if (count <= 0) + return 0; + + LocalObjectArrayRefPtr valueArray = createNewObjectArray(count, JavaLibrary::getClsString()); + std::map, uint32> const & gcwRegionDefenderCities = CityInterface::getGcwRegionDefenderCities(); + count = 0; + for (iter = allGcwScoreCategory.begin(); iter != allGcwScoreCategory.end(); ++iter) + { + if (iter->second->gcwRegionDefender) + { + std::string cities; + int numberOfCities = 0; + + for (std::map, uint32>::const_iterator iterCity = gcwRegionDefenderCities.lower_bound(std::make_pair(iter->first, 0)); ((iterCity != gcwRegionDefenderCities.end()) && (iterCity->first.first == iter->first)); ++iterCity) + { + if (PvpData::isImperialFactionId(iterCity->second)) + { + if (!cities.empty()) + cities += ", "; + + cities += CityInterface::getCityInfo(iterCity->first.second).getCityName(); + ++numberOfCities; + } + } + + if ((numberOfCities > 0) && !cities.empty()) + cities = std::string(FormattedString<32>().sprintf("%02d - ", numberOfCities)) + cities; + + JavaString jval(cities); + setObjectArrayElement(*valueArray, count++, jval); + } + } + + return valueArray->getReturnValue(); +} + +//----------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsPvpNamespace::getGcwDefenderRegionsCitiesRebel(JNIEnv *env, jobject self) +{ + // walk the list twice, this method shouldn't get called + // very often as the result is cached in script + std::map const & allGcwScoreCategory = Pvp::getAllGcwScoreCategory(); + std::map::const_iterator iter; + int count = 0; + for (iter = allGcwScoreCategory.begin(); iter != allGcwScoreCategory.end(); ++iter) + { + if (iter->second->gcwRegionDefender) + ++count; + } + + if (count <= 0) + return 0; + + LocalObjectArrayRefPtr valueArray = createNewObjectArray(count, JavaLibrary::getClsString()); + std::map, uint32> const & gcwRegionDefenderCities = CityInterface::getGcwRegionDefenderCities(); + count = 0; + for (iter = allGcwScoreCategory.begin(); iter != allGcwScoreCategory.end(); ++iter) + { + if (iter->second->gcwRegionDefender) + { + std::string cities; + int numberOfCities = 0; + + for (std::map, uint32>::const_iterator iterCity = gcwRegionDefenderCities.lower_bound(std::make_pair(iter->first, 0)); ((iterCity != gcwRegionDefenderCities.end()) && (iterCity->first.first == iter->first)); ++iterCity) + { + if (PvpData::isRebelFactionId(iterCity->second)) + { + if (!cities.empty()) + cities += ", "; + + cities += CityInterface::getCityInfo(iterCity->first.second).getCityName(); + ++numberOfCities; + } + } + + if ((numberOfCities > 0) && !cities.empty()) + cities = std::string(FormattedString<32>().sprintf("%02d - ", numberOfCities)) + cities; + + JavaString jval(cities); + setObjectArrayElement(*valueArray, count++, jval); + } + } + + return valueArray->getReturnValue(); +} + +//----------------------------------------------------------------------- + +jint JNICALL ScriptMethodsPvpNamespace::getGcwDefenderRegionsCitiesVersion(JNIEnv *env, jobject self) +{ + return CityInterface::getGcwRegionDefenderCitiesVersion(); +} + +//----------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsPvpNamespace::getGcwDefenderRegionsGuildsImperial(JNIEnv *env, jobject self) +{ + // walk the list twice, this method shouldn't get called + // very often as the result is cached in script + std::map const & allGcwScoreCategory = Pvp::getAllGcwScoreCategory(); + std::map::const_iterator iter; + int count = 0; + for (iter = allGcwScoreCategory.begin(); iter != allGcwScoreCategory.end(); ++iter) + { + if (iter->second->gcwRegionDefender) + ++count; + } + + if (count <= 0) + return 0; + + LocalObjectArrayRefPtr valueArray = createNewObjectArray(count, JavaLibrary::getClsString()); + std::map, uint32> const & gcwRegionDefenderGuilds = GuildInterface::getGcwRegionDefenderGuilds(); + count = 0; + for (iter = allGcwScoreCategory.begin(); iter != allGcwScoreCategory.end(); ++iter) + { + if (iter->second->gcwRegionDefender) + { + std::string guilds; + int numberOfGuilds = 0; + + for (std::map, uint32>::const_iterator iterGuild = gcwRegionDefenderGuilds.lower_bound(std::make_pair(iter->first, 0)); ((iterGuild != gcwRegionDefenderGuilds.end()) && (iterGuild->first.first == iter->first)); ++iterGuild) + { + if (PvpData::isImperialFactionId(iterGuild->second)) + { + if (!guilds.empty()) + guilds += ", "; + + guilds += GuildInterface::getGuildName(iterGuild->first.second); + guilds += " ("; + guilds += GuildInterface::getGuildAbbrev(iterGuild->first.second); + guilds += ")"; + ++numberOfGuilds; + } + } + + if ((numberOfGuilds > 0) && !guilds.empty()) + guilds = std::string(FormattedString<32>().sprintf("%02d - ", numberOfGuilds)) + guilds; + + JavaString jval(guilds); + setObjectArrayElement(*valueArray, count++, jval); + } + } + + return valueArray->getReturnValue(); +} + +//----------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsPvpNamespace::getGcwDefenderRegionsGuildsRebel(JNIEnv *env, jobject self) +{ + // walk the list twice, this method shouldn't get called + // very often as the result is cached in script + std::map const & allGcwScoreCategory = Pvp::getAllGcwScoreCategory(); + std::map::const_iterator iter; + int count = 0; + for (iter = allGcwScoreCategory.begin(); iter != allGcwScoreCategory.end(); ++iter) + { + if (iter->second->gcwRegionDefender) + ++count; + } + + if (count <= 0) + return 0; + + LocalObjectArrayRefPtr valueArray = createNewObjectArray(count, JavaLibrary::getClsString()); + std::map, uint32> const & gcwRegionDefenderGuilds = GuildInterface::getGcwRegionDefenderGuilds(); + count = 0; + for (iter = allGcwScoreCategory.begin(); iter != allGcwScoreCategory.end(); ++iter) + { + if (iter->second->gcwRegionDefender) + { + std::string guilds; + int numberOfGuilds = 0; + + for (std::map, uint32>::const_iterator iterGuild = gcwRegionDefenderGuilds.lower_bound(std::make_pair(iter->first, 0)); ((iterGuild != gcwRegionDefenderGuilds.end()) && (iterGuild->first.first == iter->first)); ++iterGuild) + { + if (PvpData::isRebelFactionId(iterGuild->second)) + { + if (!guilds.empty()) + guilds += ", "; + + guilds += GuildInterface::getGuildName(iterGuild->first.second); + guilds += " ("; + guilds += GuildInterface::getGuildAbbrev(iterGuild->first.second); + guilds += ")"; + ++numberOfGuilds; + } + } + + if ((numberOfGuilds > 0) && !guilds.empty()) + guilds = std::string(FormattedString<32>().sprintf("%02d - ", numberOfGuilds)) + guilds; + + JavaString jval(guilds); + setObjectArrayElement(*valueArray, count++, jval); + } + } + + return valueArray->getReturnValue(); +} + +//----------------------------------------------------------------------- + +jint JNICALL ScriptMethodsPvpNamespace::getGcwDefenderRegionsGuildsVersion(JNIEnv *env, jobject self) +{ + return GuildInterface::getGcwRegionDefenderGuildsVersion(); +} + +//----------------------------------------------------------------------- + +jintArray JNICALL ScriptMethodsPvpNamespace::getGcwDefenderRegionCitiesImperial(JNIEnv *env, jobject self, jstring gcwCategory) +{ + JavaStringParam localGcwCategory(gcwCategory); + std::string gcwCategoryString; + if (!JavaLibrary::convert(localGcwCategory, gcwCategoryString)) + return 0; + + std::vector cityIds; + std::map, uint32> const & gcwRegionDefenderCities = CityInterface::getGcwRegionDefenderCities(); + for (std::map, uint32>::const_iterator iterCity = gcwRegionDefenderCities.lower_bound(std::make_pair(gcwCategoryString, 0)); ((iterCity != gcwRegionDefenderCities.end()) && (iterCity->first.first == gcwCategoryString)); ++iterCity) + { + if (PvpData::isImperialFactionId(iterCity->second)) + cityIds.push_back(iterCity->first.second); + } + + if (cityIds.empty()) + return 0; + + LocalIntArrayRefPtr ret = createNewIntArray(cityIds.size()); + setIntArrayRegion(*ret, 0, cityIds.size(), reinterpret_cast(&cityIds[0])); + return ret->getReturnValue(); +} + +//----------------------------------------------------------------------- + +jintArray JNICALL ScriptMethodsPvpNamespace::getGcwDefenderRegionCitiesRebel(JNIEnv *env, jobject self, jstring gcwCategory) +{ + JavaStringParam localGcwCategory(gcwCategory); + std::string gcwCategoryString; + if (!JavaLibrary::convert(localGcwCategory, gcwCategoryString)) + return 0; + + std::vector cityIds; + std::map, uint32> const & gcwRegionDefenderCities = CityInterface::getGcwRegionDefenderCities(); + for (std::map, uint32>::const_iterator iterCity = gcwRegionDefenderCities.lower_bound(std::make_pair(gcwCategoryString, 0)); ((iterCity != gcwRegionDefenderCities.end()) && (iterCity->first.first == gcwCategoryString)); ++iterCity) + { + if (PvpData::isRebelFactionId(iterCity->second)) + cityIds.push_back(iterCity->first.second); + } + + if (cityIds.empty()) + return 0; + + LocalIntArrayRefPtr ret = createNewIntArray(cityIds.size()); + setIntArrayRegion(*ret, 0, cityIds.size(), reinterpret_cast(&cityIds[0])); + return ret->getReturnValue(); +} + +//----------------------------------------------------------------------- + +jintArray JNICALL ScriptMethodsPvpNamespace::getGcwDefenderRegionGuildsImperial(JNIEnv *env, jobject self, jstring gcwCategory) +{ + JavaStringParam localGcwCategory(gcwCategory); + std::string gcwCategoryString; + if (!JavaLibrary::convert(localGcwCategory, gcwCategoryString)) + return 0; + + std::vector guildIds; + std::map, uint32> const & gcwRegionDefenderGuilds = GuildInterface::getGcwRegionDefenderGuilds(); + for (std::map, uint32>::const_iterator iterGuild = gcwRegionDefenderGuilds.lower_bound(std::make_pair(gcwCategoryString, 0)); ((iterGuild != gcwRegionDefenderGuilds.end()) && (iterGuild->first.first == gcwCategoryString)); ++iterGuild) + { + if (PvpData::isImperialFactionId(iterGuild->second)) + guildIds.push_back(iterGuild->first.second); + } + + if (guildIds.empty()) + return 0; + + LocalIntArrayRefPtr ret = createNewIntArray(guildIds.size()); + setIntArrayRegion(*ret, 0, guildIds.size(), reinterpret_cast(&guildIds[0])); + return ret->getReturnValue(); +} + +//----------------------------------------------------------------------- + +jintArray JNICALL ScriptMethodsPvpNamespace::getGcwDefenderRegionGuildsRebel(JNIEnv *env, jobject self, jstring gcwCategory) +{ + JavaStringParam localGcwCategory(gcwCategory); + std::string gcwCategoryString; + if (!JavaLibrary::convert(localGcwCategory, gcwCategoryString)) + return 0; + + std::vector guildIds; + std::map, uint32> const & gcwRegionDefenderGuilds = GuildInterface::getGcwRegionDefenderGuilds(); + for (std::map, uint32>::const_iterator iterGuild = gcwRegionDefenderGuilds.lower_bound(std::make_pair(gcwCategoryString, 0)); ((iterGuild != gcwRegionDefenderGuilds.end()) && (iterGuild->first.first == gcwCategoryString)); ++iterGuild) + { + if (PvpData::isRebelFactionId(iterGuild->second)) + guildIds.push_back(iterGuild->first.second); + } + + if (guildIds.empty()) + return 0; + + LocalIntArrayRefPtr ret = createNewIntArray(guildIds.size()); + setIntArrayRegion(*ret, 0, guildIds.size(), reinterpret_cast(&guildIds[0])); + return ret->getReturnValue(); +} + +//----------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsPvpNamespace::getGcwDefenderRegionImperialBonus(JNIEnv *env, jobject self, jstring gcwCategory) +{ + JavaStringParam localGcwCategory(gcwCategory); + std::string gcwCategoryString; + if (!JavaLibrary::convert(localGcwCategory, gcwCategoryString)) + return 0.0f; + + return Pvp::getGcwDefenderRegionImperialBonus(gcwCategoryString); +} + +//----------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsPvpNamespace::getGcwDefenderRegionRebelBonus(JNIEnv *env, jobject self, jstring gcwCategory) +{ + JavaStringParam localGcwCategory(gcwCategory); + std::string gcwCategoryString; + if (!JavaLibrary::convert(localGcwCategory, gcwCategoryString)) + return 0.0f; + + return Pvp::getGcwDefenderRegionRebelBonus(gcwCategoryString); +} + +// ====================================================================== diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsQuest.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsQuest.cpp new file mode 100644 index 00000000..43d65ff7 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsQuest.cpp @@ -0,0 +1,731 @@ +// ====================================================================== +// +// ScriptMethodsQuest.cpp +// copyright (c) 2004 Sony Online Entertainment +// +// ====================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "serverGame/Chat.h" +#include "serverGame/CreatureObject.h" +#include "serverGame/PlayerCreatureController.h" +#include "serverGame/PlayerObject.h" +#include "serverGame/StaticLootItemManager.h" +#include "sharedGame/Quest.h" +#include "sharedGame/QuestManager.h" +#include "sharedGame/QuestTask.h" +#include "sharedGame/SharedStringIds.h" +#include "sharedNetworkMessages/MessageQueueGenericValueType.h" +#include "sharedNetworkMessages/MessageQueueQuestTaskCounterMessage.h" +#include "sharedNetworkMessages/MessageQueueQuestTaskLocationMessage.h" +#include "sharedNetworkMessages/MessageQueueQuestTaskTimerMessage.h" +#include "sharedObject/Controller.h" +#include "sharedNetworkMessages/MessageQueueCyberneticsOpen.h" + +#include "UnicodeUtils.h" + +using namespace JNIWrappersNamespace; + + +// ====================================================================== + +namespace ScriptMethodsQuestNamespace +{ + PlayerObject * getPlayerForCharacter(jlong playerCreatureId) + { + CreatureObject * playerCreature = NULL; + if (JavaLibrary::getObject(playerCreatureId, playerCreature)) + { + return PlayerCreatureController::getPlayerObject(playerCreature); + } + else + { + NetworkId id(playerCreatureId); + JAVA_THROW_SCRIPT_EXCEPTION(true, ("Requested player %s, who could not be found.", id.getValueString().c_str())); + return NULL; + } + } + + bool install(); + + jint JNICALL questGetQuestId(JNIEnv *env, jobject self, jstring questName); + jstring JNICALL questGetQuestName(JNIEnv *env, jobject self, jint questId); + jboolean JNICALL questIsQuestComplete(JNIEnv *env, jobject self, jint questId, jlong playerId); + jint JNICALL questCanActivateQuest(JNIEnv *env, jobject self, jint questId, jlong playerId); + jboolean JNICALL questIsQuestActive(JNIEnv *env, jobject self, jint questId, jlong playerId); + jint JNICALL questActivateQuest(JNIEnv *env, jobject self, jint questId, jlong playerId, jlong questGiver); + jint JNICALL questCompleteQuest(JNIEnv *env, jobject self, jint questId, jlong playerId); + void JNICALL questClearQuest(JNIEnv *env, jobject self, jint questId, jlong playerId); + jboolean JNICALL questIsTaskComplete(JNIEnv *env, jobject self, jint questId, jint taskId, jlong playerId); + jint JNICALL questCanActivateTask(JNIEnv *env, jobject self, jint questId, jint taskId, jlong playerId); + jboolean JNICALL questIsTaskActive(JNIEnv *env, jobject self, jint questId, jint taskId, jlong playerId); + jint JNICALL questActivateTask(JNIEnv *env, jobject self, jint questId, jint taskId, jlong playerId); + jint JNICALL questCompleteTask(JNIEnv *env, jobject self, jint questId, jint taskId, jlong playerId); + jint JNICALL questFailTask(JNIEnv *env, jobject self, jint questId, jint taskId, jlong playerId); + void JNICALL questClearQuestTask(JNIEnv *env, jobject self, jint questId, jint taskId, jlong playerId); + void JNICALL questSetDebugging(JNIEnv *env, jobject self, jboolean debugging); + jboolean JNICALL questGetDebugging(JNIEnv *env, jobject self); + void JNICALL questSetQuestTaskCounter(JNIEnv *env, jobject self, jlong playerId, jstring questName, jint taskId, jstring sourceName, jint counter, jint counterMax); + void JNICALL questSetQuestTaskLocation(JNIEnv *env, jobject self, jlong playerId, jstring questName, jint taskId, jobject taskLocation); + void JNICALL questSetQuestTaskTimer(JNIEnv *env, jobject self, jlong playerId, jstring questName, jint taskId, jstring sourceName, jint timerLength); + jintArray JNICALL questGetAllActiveQuestIds(JNIEnv *env, jobject self, jlong object); + jintArray JNICALL questGetAllCompletedQuestIds(JNIEnv *env, jobject self, jlong object); + bool JNICALL questIsQuestAbandonable(JNIEnv * env, jobject self, jint questCrc); + bool JNICALL questIsQuestForceAccept(JNIEnv * env, jobject self, jint questCrc); + bool JNICALL questDoesUseAcceptanceUI(JNIEnv * env, jobject self, jint questCrc); + void JNICALL requestActivateQuest(JNIEnv * env, jobject self, jint questCrc, jlong playerId, jlong questGiver); + void JNICALL requestCompleteQuest(JNIEnv * env, jobject self, jint questCrc, jlong playerId); + void JNICALL showCyberneticsPage(JNIEnv *env, jobject self, jlong playerId, jlong npcId, jint openType); + void JNICALL sendStaticItemDataToPlayer(JNIEnv *env, jobject self, jlong player, jobjectArray keys, jobjectArray values); + void JNICALL showLootBox(JNIEnv *env, jobject self, jlong player, jlongArray newObjects); +} + +using namespace ScriptMethodsQuestNamespace; + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsQuestNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsQuestNamespace::c)} + JF("questGetQuestId","(Ljava/lang/String;)I",questGetQuestId), + JF("questGetQuestName", "(I)Ljava/lang/String;",questGetQuestName), + JF("_questIsQuestComplete","(IJ)Z",questIsQuestComplete), + JF("_questCanActivateQuest","(IJ)I",questCanActivateQuest), + JF("_questIsQuestActive","(IJ)Z",questIsQuestActive), + JF("_questActivateQuest","(IJJ)I",questActivateQuest), + JF("_questCompleteQuest","(IJ)I",questCompleteQuest), + JF("_questClearQuest","(IJ)V",questClearQuest), + JF("_questIsTaskComplete","(IIJ)Z",questIsTaskComplete), + JF("_questCanActivateTask","(IIJ)I",questCanActivateTask), + JF("_questIsTaskActive","(IIJ)Z",questIsTaskActive), + JF("_questActivateTask","(IIJ)I",questActivateTask), + JF("_questCompleteTask","(IIJ)I",questCompleteTask), + JF("_questFailTask", "(IIJ)I", questFailTask), + JF("_questClearQuestTask","(IIJ)V",questClearQuestTask), + JF("questSetDebugging", "(Z)V", questSetDebugging), + JF("questGetDebugging", "()Z", questGetDebugging), + JF("_questSetQuestTaskCounter", "(JLjava/lang/String;ILjava/lang/String;II)V", questSetQuestTaskCounter), + JF("_questSetQuestTaskLocation", "(JLjava/lang/String;ILscript/location;)V", questSetQuestTaskLocation), + JF("_questSetQuestTaskTimer", "(JLjava/lang/String;ILjava/lang/String;I)V", questSetQuestTaskTimer), + JF("_questGetAllActiveQuestIds", "(J)[I", questGetAllActiveQuestIds), + JF("_questGetAllCompletedQuestIds", "(J)[I", questGetAllCompletedQuestIds), + JF("_questIsQuestAbandonable", "(I)Z", questIsQuestAbandonable), + JF("_questIsQuestForceAccept", "(I)Z", questIsQuestForceAccept), + JF("_questDoesUseAcceptanceUI", "(I)Z", questDoesUseAcceptanceUI), + JF("_requestActivateQuest", "(IJJ)V", requestActivateQuest), + JF("_requestCompleteQuest", "(IJ)V", requestCompleteQuest), + JF("_showCyberneticsPage", "(JJI)V", showCyberneticsPage), + JF("_sendStaticItemDataToPlayer", "(J[Ljava/lang/String;[Ljava/lang/String;)V", sendStaticItemDataToPlayer), + JF("_showLootBox", "(J[J)V", showLootBox), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +// ====================================================================== +// Quest functions + +jint JNICALL ScriptMethodsQuestNamespace::questGetQuestId(JNIEnv *, jobject, jstring questName) +{ + JavaStringParam jquestName(questName); + std::string questNameString; + if (!JavaLibrary::convert(jquestName, questNameString)) + return 0; + + Quest const * const quest = QuestManager::getQuest(questNameString); + return quest ? static_cast(quest->getId()) : 0; +} + +// --------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsQuestNamespace::questGetQuestName(JNIEnv *, jobject, jint questId) +{ + std::string const questName = QuestManager::getQuestName(static_cast(questId)); + return JavaString(questName).getReturnValue(); +} + +// --------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsQuestNamespace::questIsQuestComplete(JNIEnv *, jobject, jint questId, jlong playerId) +{ + PlayerObject const * const playerObject = getPlayerForCharacter(playerId); + if (playerObject) + return playerObject->questHasCompletedQuest(static_cast(questId)); + else + return JNI_FALSE; +} + +// --------------------------------------------------------------------- + +jint JNICALL ScriptMethodsQuestNamespace::questCanActivateQuest(JNIEnv *, jobject, jint questId, jlong playerId) +{ + PlayerObject const * const playerObject = getPlayerForCharacter(playerId); + if (playerObject) + { + PlayerObject::QuestResult result = playerObject->questCanActivateQuest(static_cast(questId)); + JAVA_THROW_SCRIPT_EXCEPTION(result==PlayerObject::QR_noSuchQuest,("Requested quest %i, which could not be found.", questId)); + return static_cast(result); + } + else + return static_cast(PlayerObject::QR_noSuchPlayer); +} + +// --------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsQuestNamespace::questIsQuestActive(JNIEnv *, jobject, jint questId, jlong playerId) +{ + PlayerObject const * const playerObject = getPlayerForCharacter(playerId); + if (playerObject) + return playerObject->questHasActiveQuest(static_cast(questId)); + else + return false; +} + +// --------------------------------------------------------------------- + +jint JNICALL ScriptMethodsQuestNamespace::questActivateQuest(JNIEnv *, jobject, jint questId, jlong playerId, jlong questGiver) +{ + PlayerObject * const playerObject = getPlayerForCharacter(playerId); + if (!playerObject) + return static_cast(PlayerObject::QR_noSuchPlayer); + + //send down the loot info + Quest const * const q = QuestManager::getQuest(questId); + if(q) + { + std::vector const & inclusiveStaticLootItems = q->getInclusiveStaticLootItemNames(); + for(std::vector::const_iterator it = inclusiveStaticLootItems.begin(); it != inclusiveStaticLootItems.end(); ++it) + { + StaticLootItemManager::sendDataToClient(NetworkId(playerId), *it); + } + + std::vector const & exclusiveStaticLootItems = q->getExclusiveStaticLootItemNames(); + for(std::vector::const_iterator it2 = exclusiveStaticLootItems.begin(); it2 != exclusiveStaticLootItems.end(); ++it2) + { + StaticLootItemManager::sendDataToClient(NetworkId(playerId), *it2); + } + } + + PlayerObject::QuestResult result = playerObject->questActivateQuest(static_cast(questId), NetworkId(questGiver)); + JAVA_THROW_SCRIPT_EXCEPTION(result==PlayerObject::QR_noSuchQuest,("Requested quest %i, which could not be found.", questId)); + return static_cast(result); +} + +// --------------------------------------------------------------------- + +jint JNICALL ScriptMethodsQuestNamespace::questCompleteQuest(JNIEnv *, jobject, jint questId, jlong playerId) +{ + PlayerObject * const playerObject = getPlayerForCharacter(playerId); + if (!playerObject) + return static_cast(PlayerObject::QR_noSuchPlayer); + + PlayerObject::QuestResult result = playerObject->questCompleteQuest(static_cast(questId)); + JAVA_THROW_SCRIPT_EXCEPTION(result==PlayerObject::QR_noSuchQuest,("Requested quest %i, which could not be found.", questId)); + return static_cast(result); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsQuestNamespace::questClearQuest(JNIEnv *, jobject, jint questId, jlong playerId) +{ + PlayerObject * const playerObject = getPlayerForCharacter(playerId); + if (playerObject) + playerObject->questClearQuest(static_cast(questId)); +} + +// ====================================================================== +// Task Functions + +jboolean JNICALL ScriptMethodsQuestNamespace::questIsTaskComplete(JNIEnv *, jobject, jint questId, jint taskId, jlong playerId) +{ + if(!QuestManager::isValidTaskId(taskId)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("TaskId %i, outside legal range.", taskId)); + return JNI_FALSE; + } + + PlayerObject const * const playerObject = getPlayerForCharacter(playerId); + if (playerObject) + return playerObject->questHasCompletedQuestTask(static_cast(questId), taskId); + else + return JNI_FALSE; +} + +// --------------------------------------------------------------------- + +jint JNICALL ScriptMethodsQuestNamespace::questCanActivateTask(JNIEnv *, jobject, jint questId, jint taskId, jlong playerId) +{ + PlayerObject const * const playerObject = getPlayerForCharacter(playerId); + if (playerObject) + { + if(!QuestManager::isValidTaskId(taskId)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("TaskId %i, outside legal range.", taskId)); + return PlayerObject::QR_noSuchTask; + } + + PlayerObject::QuestResult result = playerObject->questCanActivateQuestTask(static_cast(questId), taskId); + JAVA_THROW_SCRIPT_EXCEPTION(result==PlayerObject::QR_noSuchQuest,("Requested quest %i, which could not be found.", questId)); + JAVA_THROW_SCRIPT_EXCEPTION(result==PlayerObject::QR_noSuchTask,("Requested quest %i task %i, which could not be found.", questId, taskId)); + return static_cast(result); + } + else + return static_cast(PlayerObject::QR_noSuchPlayer); +} + +// --------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsQuestNamespace::questIsTaskActive(JNIEnv *, jobject, jint questId, jint taskId, jlong playerId) +{ + PlayerObject const * const playerObject = getPlayerForCharacter(playerId); + if(!QuestManager::isValidTaskId(taskId)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("TaskId %i, outside legal range.", taskId)); + return JNI_FALSE; + } + + if (playerObject) + return playerObject->questHasActiveQuestTask(static_cast(questId), taskId); + else + return JNI_FALSE; +} + +// --------------------------------------------------------------------- + +jint JNICALL ScriptMethodsQuestNamespace::questActivateTask(JNIEnv *, jobject, jint questId, jint taskId, jlong playerId) +{ + PlayerObject * const playerObject = getPlayerForCharacter(playerId); + if (!playerObject) + return static_cast(PlayerObject::QR_noSuchPlayer); + + if(!QuestManager::isValidTaskId(taskId)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("TaskId %i, outside legal range.", taskId)); + return PlayerObject::QR_noSuchTask; + } + + PlayerObject::QuestResult result = playerObject->questActivateQuestTask(static_cast(questId), taskId); + JAVA_THROW_SCRIPT_EXCEPTION(result==PlayerObject::QR_noSuchQuest,("Requested quest %i, which could not be found.", questId)); + JAVA_THROW_SCRIPT_EXCEPTION(result==PlayerObject::QR_noSuchTask,("Requested quest %i task %i, which could not be found.", questId, taskId)); + return static_cast(result); +} + +// --------------------------------------------------------------------- + +jint JNICALL ScriptMethodsQuestNamespace::questCompleteTask(JNIEnv *, jobject, jint questId, jint taskId, jlong playerId) +{ + PlayerObject * const playerObject = getPlayerForCharacter(playerId); + if (!playerObject) + return static_cast(PlayerObject::QR_noSuchPlayer); + + if(!QuestManager::isValidTaskId(taskId)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("TaskId %i, outside legal range.", taskId)); + return PlayerObject::QR_noSuchTask; + } + + PlayerObject::QuestResult result = playerObject->questCompleteQuestTask(static_cast(questId), taskId); + JAVA_THROW_SCRIPT_EXCEPTION(result==PlayerObject::QR_noSuchQuest,("Requested quest %i, which could not be found.", questId)); + JAVA_THROW_SCRIPT_EXCEPTION(result==PlayerObject::QR_noSuchTask,("Requested quest %i task %i, which could not be found.", questId, taskId)); + return static_cast(result); +} + +// --------------------------------------------------------------------- + +jint JNICALL ScriptMethodsQuestNamespace::questFailTask(JNIEnv *, jobject, jint questId, jint taskId, jlong playerId) +{ + PlayerObject * const playerObject = getPlayerForCharacter(playerId); + if (!playerObject) + return static_cast(PlayerObject::QR_noSuchPlayer); + + if(!QuestManager::isValidTaskId(taskId)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("TaskId %i, outside legal range.", taskId)); + return PlayerObject::QR_noSuchTask; + } + + PlayerObject::QuestResult result = playerObject->questFailQuestTask(static_cast(questId), taskId); + JAVA_THROW_SCRIPT_EXCEPTION(result==PlayerObject::QR_noSuchQuest,("Requested quest %i, which could not be found.", questId)); + JAVA_THROW_SCRIPT_EXCEPTION(result==PlayerObject::QR_noSuchTask,("Requested quest %i task %i, which could not be found.", questId, taskId)); + return static_cast(result); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsQuestNamespace::questClearQuestTask(JNIEnv *, jobject, jint questId, jint taskId, jlong playerId) +{ + if(!QuestManager::isValidTaskId(taskId)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("TaskId %i, outside legal range.", taskId)); + return; + } + + PlayerObject * const playerObject = getPlayerForCharacter(playerId); + if (playerObject) + IGNORE_RETURN(playerObject->questClearQuestTask(static_cast(questId), taskId)); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsQuestNamespace::questSetDebugging(JNIEnv *env, jobject self, jboolean debugging) +{ + QuestManager::setDebugging(debugging); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsQuestNamespace::questGetDebugging(JNIEnv *env, jobject self) +{ + return QuestManager::getDebugging(); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsQuestNamespace::questSetQuestTaskCounter(JNIEnv *env, jobject self, jlong playerId, jstring questName, jint taskId, jstring sourceName, jint counter, jint counterMax) +{ + if(!QuestManager::isValidTaskId(taskId)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("TaskId %i, outside legal range.", taskId)); + return; + } + + PlayerObject * const playerObject = getPlayerForCharacter(playerId); + CreatureObject * const creatureObject = playerObject ? playerObject->getCreatureObject() : NULL; + Controller * const controller = creatureObject ? creatureObject->getController() : NULL; + if(!controller) + return; + + JavaStringParam jquestNameName(questName); + std::string questNameString; + if (!JavaLibrary::convert(jquestNameName, questNameString)) + return; + + JavaStringParam jsourceNameName(sourceName); + std::string sourceNameString; + if (!JavaLibrary::convert(jsourceNameName, sourceNameString)) + return; + + MessageQueueQuestTaskCounterMessage * const msg = new MessageQueueQuestTaskCounterMessage(questNameString, taskId, Unicode::narrowToWide(sourceNameString), counter, counterMax); + controller->appendMessage(static_cast(CM_questTaskCounterData), 0.0f, msg, GameControllerMessageFlags::SEND | GameControllerMessageFlags::RELIABLE | GameControllerMessageFlags::DEST_AUTH_CLIENT); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsQuestNamespace::questSetQuestTaskLocation(JNIEnv *env, jobject self, jlong playerId, jstring questName, jint taskId, jobject taskLocation) +{ + if(!QuestManager::isValidTaskId(taskId)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("TaskId %i, outside legal range.", taskId)); + return; + } + + PlayerObject * const playerObject = getPlayerForCharacter(playerId); + CreatureObject * const creatureObject = playerObject ? playerObject->getCreatureObject() : NULL; + Controller * const controller = creatureObject ? creatureObject->getController() : NULL; + if(!controller) + return; + + JavaStringParam jquestNameName(questName); + std::string questNameString; + if (!JavaLibrary::convert(jquestNameName, questNameString)) + return; + + Location location; + if(!ScriptConversion::convert(LocalRefParam(taskLocation), location)) + return; + + MessageQueueQuestTaskLocationMessage * const msg = new MessageQueueQuestTaskLocationMessage(questNameString, taskId, location); + controller->appendMessage(static_cast(CM_questTaskLocationData), 0.0f, msg, GameControllerMessageFlags::SEND | GameControllerMessageFlags::RELIABLE | GameControllerMessageFlags::DEST_AUTH_CLIENT); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsQuestNamespace::questSetQuestTaskTimer(JNIEnv *env, jobject self, jlong playerId, jstring questName, jint taskId, jstring sourceName, jint finalPlayedTime) +{ + if(!QuestManager::isValidTaskId(taskId)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("TaskId %i, outside legal range.", taskId)); + return; + } + + PlayerObject * const playerObject = getPlayerForCharacter(playerId); + CreatureObject * const creatureObject = playerObject ? playerObject->getCreatureObject() : NULL; + Controller * const controller = creatureObject ? creatureObject->getController() : NULL; + if(!controller) + return; + + JavaStringParam jquestNameName(questName); + std::string questNameString; + if (!JavaLibrary::convert(jquestNameName, questNameString)) + return; + + JavaStringParam jsourceNameName(sourceName); + std::string sourceNameString; + if (!JavaLibrary::convert(jsourceNameName, sourceNameString)) + return; + + MessageQueueQuestTaskTimerMessage * const msg = new MessageQueueQuestTaskTimerMessage(questNameString, taskId, Unicode::narrowToWide(sourceNameString), finalPlayedTime); + controller->appendMessage(static_cast(CM_questTaskTimerData), 0.0f, msg, GameControllerMessageFlags::SEND | GameControllerMessageFlags::RELIABLE | GameControllerMessageFlags::DEST_AUTH_CLIENT); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsQuestNamespace::requestActivateQuest(JNIEnv * env, jobject self, jint questCrc, jlong playerId, jlong questGiver) +{ + PlayerObject * const playerObject = getPlayerForCharacter(playerId); + if (playerObject) + { + if(playerObject->questHasActiveQuest(static_cast(questCrc))) + { + return; + } + + CreatureObject * playerCreature = NULL; + if (JavaLibrary::getObject(playerId, playerCreature) && playerCreature) + { + Quest const * const q = QuestManager::getQuest(questCrc); + if(q) + { + std::vector const & inclusiveStaticLootItems = q->getInclusiveStaticLootItemNames(); + for(std::vector::const_iterator it = inclusiveStaticLootItems.begin(); it != inclusiveStaticLootItems.end(); ++it) + { + StaticLootItemManager::sendDataToClient(NetworkId(playerId), *it); + } + + std::vector const & exclusiveStaticLootItems = q->getExclusiveStaticLootItemNames(); + for(std::vector::const_iterator it2 = exclusiveStaticLootItems.begin(); it2 != exclusiveStaticLootItems.end(); ++it2) + { + StaticLootItemManager::sendDataToClient(NetworkId(playerId), *it2); + } + + if(QuestManager::isQuestForceAccepted(q->getName().getString())) + { + PlayerObject::QuestResult result = playerObject->questActivateQuest(static_cast(questCrc), NetworkId(questGiver)); + JAVA_THROW_SCRIPT_EXCEPTION(result==PlayerObject::QR_noSuchQuest,("Requested quest %i, which could not be found.", questCrc)); + MessageQueueGenericValueType * const msg = new MessageQueueGenericValueType(static_cast(questCrc)); + Controller * const controller = playerCreature->getController(); + if(controller) + { + controller->appendMessage(static_cast(CM_forceActivateQuest), 0.0f, msg, GameControllerMessageFlags::SEND | GameControllerMessageFlags::RELIABLE | GameControllerMessageFlags::DEST_AUTH_CLIENT); + } + } + //see if this quest needs to go through our acceptance/completion UI flow + else if(QuestManager::isQuestAcceptable(q->getName().getString())) + { + Controller * const controller = playerCreature->getController(); + if(controller) + { + if(QuestManager::getMaximumNumberOfQuestsPerPlayer() > -1) + { + if(playerObject->getNumberOfActiveQuests() >= QuestManager::getMaximumNumberOfQuestsPerPlayer()) + { + Chat::sendSystemMessage(*playerCreature, SharedStringIds::quest_journal_is_full, Unicode::emptyString); + return; + } + } + playerObject->setPendingRequestQuestInformation(questCrc, NetworkId(questGiver)); + MessageQueueGenericValueType * const msg = new MessageQueueGenericValueType(static_cast(questCrc)); + controller->appendMessage(static_cast(CM_requestActivateQuest), 0.0f, msg, GameControllerMessageFlags::SEND | GameControllerMessageFlags::RELIABLE | GameControllerMessageFlags::DEST_AUTH_CLIENT); + } + } + else + { + PlayerObject::QuestResult result = playerObject->questActivateQuest(static_cast(questCrc), NetworkId(questGiver)); + JAVA_THROW_SCRIPT_EXCEPTION(result==PlayerObject::QR_noSuchQuest,("Requested quest %i, which could not be found.", questCrc)); + } + } + } + } +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsQuestNamespace::requestCompleteQuest(JNIEnv * env, jobject self, jint questCrc, jlong playerId) +{ + PlayerObject * const playerObject = getPlayerForCharacter(playerId); + if (playerObject) + { + if(!playerObject->questHasActiveQuest(static_cast(questCrc))) + { + return; + } + + CreatureObject * playerCreature = NULL; + if (JavaLibrary::getObject(playerId, playerCreature) && playerCreature) + { + Quest const * const q = QuestManager::getQuest(questCrc); + if(q) + { + PlayerObject::QuestResult result = playerObject->questCompleteQuest(static_cast(questCrc)); + JAVA_THROW_SCRIPT_EXCEPTION(result==PlayerObject::QR_noSuchQuest,("Requested quest %i, which could not be found.", questCrc)); + } + } + } +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsQuestNamespace::showCyberneticsPage(JNIEnv *env, jobject self, jlong playerId, jlong npcId, jint openType) +{ + MessageQueueCyberneticsOpen::OpenType const type = static_cast(openType); + + CreatureObject * npc = NULL; + if (!JavaLibrary::getObject(npcId, npc)) + return; + + if(!npc) + return; + + CreatureObject * playerCreature = NULL; + if (JavaLibrary::getObject(playerId, playerCreature)) + { + Controller * const playerController = playerCreature->getController(); + if(playerController) + { + MessageQueueCyberneticsOpen * msg = new MessageQueueCyberneticsOpen(type, npc->getNetworkId()); + playerController->appendMessage(CM_cyberneticsOpen, 0.0f, msg, GameControllerMessageFlags::SEND | GameControllerMessageFlags::RELIABLE | GameControllerMessageFlags::DEST_AUTH_CLIENT); + } + } +} + +// ---------------------------------------------------------------------- + +jintArray JNICALL ScriptMethodsQuestNamespace::questGetAllActiveQuestIds(JNIEnv *env, jobject self, jlong playerId) +{ + PlayerObject const * const playerObject = getPlayerForCharacter(playerId); + if (!playerObject) + { + LocalIntArrayRefPtr results = createNewIntArray(0); + return results->getReturnValue(); + } + std::vector questIds = playerObject->questGetAllActiveQuestIds(); + LocalIntArrayRefPtr results = createNewIntArray(static_cast(questIds.size())); + setIntArrayRegion(*results, 0 , static_cast(questIds.size()), reinterpret_cast(&(questIds[0]))); + return results->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jintArray JNICALL ScriptMethodsQuestNamespace::questGetAllCompletedQuestIds(JNIEnv *env, jobject self, jlong playerId) +{ + PlayerObject const * const playerObject = getPlayerForCharacter(playerId); + if (!playerObject) + { + LocalIntArrayRefPtr results = createNewIntArray(0); + return results->getReturnValue(); + } + std::vector questIds = playerObject->questGetAllCompletedQuestIds(); + LocalIntArrayRefPtr results = createNewIntArray(static_cast(questIds.size())); + setIntArrayRegion(*results, 0 , static_cast(questIds.size()), reinterpret_cast(&(questIds[0]))); + return results->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +/** + * Given a dictionary representing the static item data for loot item, pack it all into a single vector and send to the client. + */ +void JNICALL ScriptMethodsQuestNamespace::sendStaticItemDataToPlayer(JNIEnv *env, jobject self, jlong playerId, jobjectArray keys, jobjectArray values) +{ + //turn the java objects into parallel vectors + std::vector keyStrings; + getStringArray(LocalObjectArrayRefParam(keys), keyStrings); + std::vector valueStrings; + getStringArray(LocalObjectArrayRefParam(values), valueStrings); + + //build a single dictionary to hold ALL the data. ALL keys, then ALL data. gcc can't handle it as a pair of vector, + // it caused an deep in archive where it blows out the template instanctiation depth + std::vector flattenedDictionary; + flattenedDictionary.reserve(keyStrings.size() * 2); + + //put everything in it + Unicode::String s; + for(std::vector::const_iterator i = keyStrings.begin(); i != keyStrings.end(); ++i) + { + s = **i; + flattenedDictionary.push_back(s); + } + for(std::vector::const_iterator i2 = valueStrings.begin(); i2 != valueStrings.end(); ++i2) + { + s = **i2; + flattenedDictionary.push_back(s); + } + + //send to player + CreatureObject * playerCreature = NULL; + if (JavaLibrary::getObject(playerId, playerCreature)) + { + Controller * const playerController = playerCreature->getController(); + if(playerController) + { + MessageQueueGenericValueType > * const msg = new MessageQueueGenericValueType >(flattenedDictionary); + playerController->appendMessage(static_cast(CM_staticLootItemData), 0.0f, msg, GameControllerMessageFlags::SEND | GameControllerMessageFlags::RELIABLE | GameControllerMessageFlags::DEST_AUTH_CLIENT); + } + } +} + +// ---------------------------------------------------------------------- + +/** + * Given a player and a list of networkids, tell the client to show a UI listing these objects as newly earned + */ +void JNICALL ScriptMethodsQuestNamespace::showLootBox(JNIEnv *env, jobject self, jlong playerId, jlongArray newObjects) +{ + std::vector objectIds; + if (!ScriptConversion::convert(newObjects, objectIds)) + return; + + //send to player + CreatureObject * playerCreature = NULL; + if (JavaLibrary::getObject(playerId, playerCreature)) + { + Controller * const playerController = playerCreature->getController(); + if(playerController) + { + MessageQueueGenericValueType > * const msg = new MessageQueueGenericValueType >(objectIds); + playerController->appendMessage(static_cast(CM_showLootBox), 0.0f, msg, GameControllerMessageFlags::SEND | GameControllerMessageFlags::RELIABLE | GameControllerMessageFlags::DEST_AUTH_CLIENT); + } + } +} + +// ---------------------------------------------------------------------- + +bool JNICALL ScriptMethodsQuestNamespace::questIsQuestAbandonable(JNIEnv * , jobject , jint questCrc) +{ + Quest const * const q = QuestManager::getQuest(questCrc); + if(!q) + return JNI_FALSE; + + return(QuestManager::isQuestAbandonable(q->getName().getString())) ? JNI_TRUE : JNI_FALSE; +} + +// ---------------------------------------------------------------------- + +bool JNICALL ScriptMethodsQuestNamespace::questIsQuestForceAccept(JNIEnv * , jobject , jint questCrc) +{ + Quest const * const q = QuestManager::getQuest(questCrc); + if(!q) + return JNI_FALSE; + + return(QuestManager::isQuestForceAccepted(q->getName().getString())) ? JNI_TRUE : JNI_FALSE; +} + +// ---------------------------------------------------------------------- + +bool JNICALL ScriptMethodsQuestNamespace::questDoesUseAcceptanceUI(JNIEnv * , jobject , jint questCrc) +{ + Quest const * const q = QuestManager::getQuest(questCrc); + if(!q) + return JNI_FALSE; + + return(QuestManager::isQuestAcceptable(q->getName().getString())) ? JNI_TRUE : JNI_FALSE; +} + +// ====================================================================== diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsRegion.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsRegion.cpp new file mode 100644 index 00000000..9a393578 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsRegion.cpp @@ -0,0 +1,1168 @@ +//----------------------------------------------------------------------- +// ScriptMethodsRegion.cpp +// Copyright 2002, Sony Online Entertainment Inc., all rights reserved. +//----------------------------------------------------------------------- + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "sharedDebug/Profiler.h" +#include "serverGame/PlanetObject.h" +#include "serverGame/Region.h" +#include "serverGame/RegionMaster.h" +#include "serverGame/ServerObject.h" +#include "serverGame/ServerUniverse.h" +#include "serverGame/UniverseObject.h" +#include "sharedMath/MxCifQuadTreeBounds.h" +#include "sharedRandom/Random.h" +#include + +using namespace JNIWrappersNamespace; + + +// ====================================================================== +// ScriptMethodsRegionNamespace +// ====================================================================== + +namespace ScriptMethodsRegionNamespace +{ + bool install(); + LocalObjectArrayRefPtr _getRegionsAtPoint(jobject location); + + void JNICALL createRectRegion(JNIEnv *env, jobject self, jobject lowerLeftLocation, jobject upperRightLocation, jstring name, jint pvp, jint buildable, jint municipal, jint geography, jint minDifficulty, jint maxDifficulty, jint spawnable, jint mission, jboolean visible, jboolean notify); + void JNICALL createCircleRegion(JNIEnv *env, jobject self, jobject center, jfloat radius, jstring name, jint pvp, jint buildable, jint municipal, jint geography, jint minDifficulty, jint maxDifficulty, jint spawnable, jint mission, jboolean visible, jboolean notify); + jlong JNICALL createCircleRegionWithSpawn(JNIEnv *env, jobject self, jobject center, jfloat radius, jstring name, jint pvp, jint buildable, jint municipal, jint geography, jint minDifficulty, jint maxDifficulty, jint spawnable, jint mission, jboolean visible, jboolean notify, jstring spawnTable, jint duration); + jobject JNICALL getRegion(JNIEnv *env, jobject self, jstring planet, jstring region); + jobjectArray JNICALL getRegionsAtPoint(JNIEnv *env, jobject self, jobject location); + jobjectArray JNICALL getRegions(JNIEnv *env, jobject self, jstring planet); + jobjectArray JNICALL getRegionsWithPvP(JNIEnv *env, jobject self, jstring planet, jint value); + jobjectArray JNICALL getRegionsWithBuildable(JNIEnv *env, jobject self, jstring planet, jint value); + jobjectArray JNICALL getRegionsWithMunicipal(JNIEnv *env, jobject self, jstring planet, jint value); + jobjectArray JNICALL getRegionsWithGeographical(JNIEnv *env, jobject self, jstring planet, jint value); + jobjectArray JNICALL getRegionsWithDifficulty(JNIEnv *env, jobject self, jstring planet, jint value); + jobjectArray JNICALL getRegionsWithSpawnable(JNIEnv *env, jobject self, jstring planet, jint value); + jobjectArray JNICALL getRegionsWithMission(JNIEnv *env, jobject self, jstring planet, jint value); + jobjectArray JNICALL getRegionsWithPvPAtPoint(JNIEnv *env, jobject self, jobject location, jint value); + jobjectArray JNICALL getRegionsWithBuildableAtPoint(JNIEnv *env, jobject self, jobject location, jint value); + jobjectArray JNICALL getRegionsWithMunicipalAtPoint(JNIEnv *env, jobject self, jobject location, jint value); + jobjectArray JNICALL getRegionsWithGeographicalAtPoint(JNIEnv *env, jobject self, jobject location, jint value); + jobjectArray JNICALL getRegionsWithDifficultyAtPoint(JNIEnv *env, jobject self, jobject location, jint value); + jobjectArray JNICALL getRegionsWithSpawnableAtPoint(JNIEnv *env, jobject self, jobject location, jint value); + jobjectArray JNICALL getRegionsWithMissionAtPoint(JNIEnv *env, jobject self, jobject location, jint value); + jobject JNICALL getSmallestRegionAtPoint(JNIEnv *env, jobject self, jobject location); + jobject JNICALL getSmallestVisibleRegionAtPoint(JNIEnv *env, jobject self, jobject location); + jboolean JNICALL wipeRegionsFromPlanet(JNIEnv *env, jobject self, jstring planet); + jboolean JNICALL deleteRegion(JNIEnv *env, jobject self, jobject region); + jobject JNICALL findPointInRegion(JNIEnv *env, jobject self, jobject region); + jobjectArray JNICALL getRegionExtent(JNIEnv *env, jobject self, jobject region); + jboolean JNICALL isNotifyRegion(JNIEnv *env, jobject self, jobject region); +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsRegionNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsRegionNamespace::c)} + JF("createRectRegion", "(Lscript/location;Lscript/location;Ljava/lang/String;IIIIIIIIZZ)V",createRectRegion), + JF("createCircleRegion", "(Lscript/location;FLjava/lang/String;IIIIIIIIZZ)V", createCircleRegion), + JF("_createCircleRegionWithSpawn","(Lscript/location;FLjava/lang/String;IIIIIIIIZZLjava/lang/String;I)J", createCircleRegionWithSpawn), + JF("getRegion", "(Ljava/lang/String;Ljava/lang/String;)Lscript/region;", getRegion), + JF("getRegionsAtPoint", "(Lscript/location;)[Lscript/region;", getRegionsAtPoint), + JF("getRegions", "(Ljava/lang/String;)[Lscript/region;", getRegions), + JF("getRegionsWithPvP", "(Ljava/lang/String;I)[Lscript/region;", getRegionsWithPvP), + JF("getRegionsWithBuildable", "(Ljava/lang/String;I)[Lscript/region;", getRegionsWithBuildable), + JF("getRegionsWithMunicipal", "(Ljava/lang/String;I)[Lscript/region;", getRegionsWithMunicipal), + JF("getRegionsWithGeographical", "(Ljava/lang/String;I)[Lscript/region;", getRegionsWithGeographical), + JF("getRegionsWithDifficulty", "(Ljava/lang/String;I)[Lscript/region;", getRegionsWithDifficulty), + JF("getRegionsWithSpawnable", "(Ljava/lang/String;I)[Lscript/region;", getRegionsWithSpawnable), + JF("getRegionsWithMission", "(Ljava/lang/String;I)[Lscript/region;", getRegionsWithMission), + JF("getRegionsWithPvPAtPoint", "(Lscript/location;I)[Lscript/region;", getRegionsWithPvPAtPoint), + JF("getRegionsWithBuildableAtPoint", "(Lscript/location;I)[Lscript/region;", getRegionsWithBuildableAtPoint), + JF("getRegionsWithMunicipalAtPoint", "(Lscript/location;I)[Lscript/region;", getRegionsWithMunicipalAtPoint), + JF("getRegionsWithGeographicalAtPoint", "(Lscript/location;I)[Lscript/region;", getRegionsWithGeographicalAtPoint), + JF("getRegionsWithDifficultyAtPoint", "(Lscript/location;I)[Lscript/region;", getRegionsWithDifficultyAtPoint), + JF("getRegionsWithSpawnableAtPoint", "(Lscript/location;I)[Lscript/region;", getRegionsWithSpawnableAtPoint), + JF("getRegionsWithMissionAtPoint", "(Lscript/location;I)[Lscript/region;", getRegionsWithMissionAtPoint), + JF("getSmallestRegionAtPoint", "(Lscript/location;)Lscript/region;", getSmallestRegionAtPoint), + JF("getSmallestVisibleRegionAtPoint", "(Lscript/location;)Lscript/region;", getSmallestVisibleRegionAtPoint), + JF("wipeRegionsFromPlanet", "(Ljava/lang/String;)Z", wipeRegionsFromPlanet), + JF("deleteRegion", "(Lscript/region;)Z", deleteRegion), + JF("findPointInRegion", "(Lscript/region;)Lscript/location;", findPointInRegion), + JF("getRegionExtent", "(Lscript/region;)[Lscript/location;", getRegionExtent), + JF("isNotifyRegion", "(Lscript/region;)Z", isNotifyRegion), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +//----------------------------------------------------------------------- + +/** Get all the regions at the given location + */ +LocalObjectArrayRefPtr ScriptMethodsRegionNamespace::_getRegionsAtPoint(jobject location) +{ + //pull the data from the java Location objects + Vector locationVec; + std::string sceneId; + if(!ScriptConversion::convertWorld(location, locationVec, sceneId)) + return LocalObjectArrayRef::cms_nullPtr; + + std::vector result; + RegionMaster::getRegionsAtPoint(sceneId, locationVec.x, locationVec.z, result); + + //-- return null instead of a zero-length array + if (result.empty ()) + return LocalObjectArrayRef::cms_nullPtr; + + //put them into the jobjectarray + LocalObjectArrayRefPtr regions = createNewObjectArray(result.size(), JavaLibrary::getClsRegion()); + + int index = 0; + for(std::vector::iterator it = result.begin(); it != result.end(); ++it, ++index) + { + LocalRefPtr javaRegion; + const Region * r = *it; + if (r != NULL) + { + if (!ScriptConversion::convert(*r, javaRegion)) + return LocalObjectArrayRef::cms_nullPtr; + setObjectArrayElement(*regions, index, *javaRegion); + } + else + setObjectArrayElement(*regions, index, LocalRef(0)); + } + return regions; +} + +//----------------------------------------------------------------------- + +/** Create a rectangular region given the locations. + */ +void JNICALL ScriptMethodsRegionNamespace::createRectRegion(JNIEnv *env, jobject self, + jobject lowerLeftLocation, jobject upperRightLocation, + jstring name, jint pvp, jint buildable, jint municipal, jint geography, + jint minDifficulty, jint maxDifficulty, jint spawnable, jint mission, + jboolean visible, jboolean notify) +{ + UNREF(self); + + //validate scripter's input + if (lowerLeftLocation == 0 || upperRightLocation == 0 || name == 0) + return; + + JavaStringParam jname(name); + Unicode::String regionName; + if (!JavaLibrary::convert(jname, regionName)) + return; + + //pull the data from the java Location objects + Vector llLocationVec; + std::string llSceneId; + NetworkId llCell; + if (!ScriptConversion::convert(lowerLeftLocation, llLocationVec, llSceneId, llCell)) + return; + Vector urLocationVec; + std::string urSceneId; + NetworkId urCell; + if(!ScriptConversion::convert(upperRightLocation, urLocationVec, urSceneId, urCell)) + return; + + //locations must be on the same planet + if (llSceneId != urSceneId) + return; + + //create the region + RegionMaster::createNewDynamicRegion(llLocationVec.x, + llLocationVec.z, urLocationVec.x, urLocationVec.z, regionName, llSceneId, + pvp, buildable, municipal, geography, minDifficulty, maxDifficulty, + spawnable, mission, visible, notify); +} + +//----------------------------------------------------------------------- + +/** Create a circular region given the location and radius. + */ +void JNICALL ScriptMethodsRegionNamespace::createCircleRegion(JNIEnv *env, jobject self, + jobject center, jfloat radius, jstring name, jint pvp, jint buildable, + jint municipal, jint geography, jint minDifficulty, jint maxDifficulty, + jint spawnable, jint mission, jboolean visible, jboolean notify) +{ + UNREF(self); + + // validate scripter's input + if (center == NULL || radius <= 0 || name == 0) + return; + + JavaStringParam jname(name); + Unicode::String regionName; + if (!JavaLibrary::convert(jname, regionName)) + return; + + // pull the data from the java Location objects + Vector locationVec; + std::string sceneId; + if (!ScriptConversion::convertWorld(center, locationVec, sceneId)) + return; + + // create the region + RegionMaster::createNewDynamicRegion(locationVec.x, locationVec.z, + radius, regionName, sceneId, pvp, buildable, municipal, geography, minDifficulty, + maxDifficulty, spawnable, mission, visible, notify); +} + +//----------------------------------------------------------------------- + +/** + * Gets the region object for a given planet and region name. + */ +jobject JNICALL ScriptMethodsRegionNamespace::getRegion(JNIEnv *env, jobject self, jstring planet, + jstring region) +{ + UNREF(self); + + if (planet == 0 || region == 0) + return 0; + + JavaStringParam jplanet(planet); + std::string planetName; + if (!JavaLibrary::convert(jplanet, planetName)) + return 0; + + JavaStringParam jregion(region); + Unicode::String regionName; + if (!JavaLibrary::convert(jregion, regionName)) + return 0; + + const Region * r = RegionMaster::getRegionByName(planetName, regionName); + if (r == NULL) + return 0; + + LocalRefPtr jr; + if (!ScriptConversion::convert(*r, jr)) + return 0; + return jr->getReturnValue(); +} // JavaLibrary::getRegion + +//----------------------------------------------------------------------- + +/** Get all the regions at the given location + */ +jobjectArray JNICALL ScriptMethodsRegionNamespace::getRegionsAtPoint(JNIEnv *env, jobject self, jobject location) +{ + LocalObjectArrayRefPtr regions = _getRegionsAtPoint(location); + if (regions.get() == NULL) + return 0; + return regions->getReturnValue(); +} + +//----------------------------------------------------------------------- + +/** Return all the regions on the given planet + */ +jobjectArray JNICALL ScriptMethodsRegionNamespace::getRegions(JNIEnv *env, jobject self, jstring planet) +{ + UNREF(self); + + JavaStringParam localPlanet(planet); + + //get the planet name and the planet object + std::string sceneId; + if (!JavaLibrary::convert(localPlanet, sceneId)) + return 0; + + //get the planet's regions + std::vector result; + RegionMaster::getRegionsForPlanet(sceneId, result); + + //-- return null instead of a zero-length array + if (result.empty ()) + return NULL; + + //put them into the jobjectarray + LocalObjectArrayRefPtr regions = createNewObjectArray(result.size(), JavaLibrary::getClsRegion()); + + int index = 0; + for(std::vector::iterator i = result.begin(); i != result.end(); ++i, ++index) + { + LocalRefPtr javaRegion; + const Region * r = *i; + if (r != NULL) + { + if (!ScriptConversion::convert(*r, javaRegion)) + { + return NULL; + } + } + setObjectArrayElement(*regions, index, *javaRegion); + } + return regions->getReturnValue(); +} + +//----------------------------------------------------------------------- + +/** Get all the regions with the PvP property set to the given value on the given planet + */ +jobjectArray JNICALL ScriptMethodsRegionNamespace::getRegionsWithPvP(JNIEnv *env, jobject self, jstring planet, jint value) +{ + UNREF(self); + + JavaStringParam localPlanet(planet); + + //get the planet name + std::string sceneId; + JavaLibrary::convert(localPlanet, sceneId); + + //get the planet's regions + std::vector regions; + RegionMaster::getRegionsForPlanet(sceneId, regions); + + // get the regions that have the right property + std::vector goodRegions; + for (std::vector::iterator i = regions.begin(); i != regions.end(); ++i) + { + if ((*i)->getPvp() == value) + goodRegions.push_back(*i); + } + + //-- return null instead of a zero-length array + if (goodRegions.empty()) + return 0; + + //put them into the jobjectarray + int index = 0; + LocalObjectArrayRefPtr result = createNewObjectArray(goodRegions.size(), JavaLibrary::getClsRegion()); + for (std::vector::iterator it = goodRegions.begin(); + it != goodRegions.end(); ++it, ++index) + { + LocalRefPtr javaRegion; + if (!ScriptConversion::convert(**it, javaRegion)) + { + return NULL; + } + setObjectArrayElement(*result, index, *javaRegion); + } + return result->getReturnValue(); +} + +//----------------------------------------------------------------------- + +/** Get all the regions with the Buildable property set to the given value on the given planet + */ +jobjectArray JNICALL ScriptMethodsRegionNamespace::getRegionsWithBuildable(JNIEnv *env, jobject self, jstring planet, jint value) +{ + UNREF(self); + + JavaStringParam localPlanet(planet); + + //get the planet name + std::string sceneId; + JavaLibrary::convert(localPlanet, sceneId); + + //get the planet's regions + std::vector regions; + RegionMaster::getRegionsForPlanet(sceneId, regions); + + // get the regions that have the right property + std::vector goodRegions; + for (std::vector::iterator i = regions.begin(); i != regions.end(); ++i) + { + if ((*i)->getBuildable() == value) + goodRegions.push_back(*i); + } + + //-- return null instead of a zero-length array + if (goodRegions.empty()) + return 0; + + //put them into the jobjectarray + int index = 0; + LocalObjectArrayRefPtr result = createNewObjectArray(goodRegions.size(), JavaLibrary::getClsRegion()); + for (std::vector::iterator it = goodRegions.begin(); + it != goodRegions.end(); ++it, ++index) + { + LocalRefPtr javaRegion; + if (!ScriptConversion::convert(**it, javaRegion)) + { + return NULL; + } + setObjectArrayElement(*result, index, *javaRegion); + } + return result->getReturnValue(); +} + +//----------------------------------------------------------------------- + +/** Get all the regions with the Municipal property set to the given value on the given planet + */ +jobjectArray JNICALL ScriptMethodsRegionNamespace::getRegionsWithMunicipal(JNIEnv *env, jobject self, jstring planet, jint value) +{ + UNREF(self); + + JavaStringParam localPlanet(planet); + + //get the planet name + std::string sceneId; + JavaLibrary::convert(localPlanet, sceneId); + + //get the planet's regions + std::vector regions; + RegionMaster::getRegionsForPlanet(sceneId, regions); + + // get the regions that have the right property + std::vector goodRegions; + for (std::vector::iterator i = regions.begin(); i != regions.end(); ++i) + { + if ((*i)->getMunicipal() == value) + goodRegions.push_back(*i); + } + + //-- return null instead of a zero-length array + if (goodRegions.empty()) + return 0; + + //put them into the jobjectarray + int index = 0; + LocalObjectArrayRefPtr result = createNewObjectArray(goodRegions.size(), JavaLibrary::getClsRegion()); + for (std::vector::iterator it = goodRegions.begin(); + it != goodRegions.end(); ++it, ++index) + { + LocalRefPtr javaRegion; + if (!ScriptConversion::convert(**it, javaRegion)) + { + return NULL; + } + setObjectArrayElement(*result, index, *javaRegion); + } + return result->getReturnValue(); +} + +//----------------------------------------------------------------------- + +/** Get all the regions with the Geographical property set to the given value on the given planet + */ +jobjectArray JNICALL ScriptMethodsRegionNamespace::getRegionsWithGeographical(JNIEnv *env, jobject self, jstring planet, jint value) +{ + UNREF(self); + + JavaStringParam localPlanet(planet); + + //get the planet name + std::string sceneId; + JavaLibrary::convert(localPlanet, sceneId); + + //get the planet's regions + std::vector regions; + RegionMaster::getRegionsForPlanet(sceneId, regions); + + // get the regions that have the right property + std::vector goodRegions; + for (std::vector::iterator i = regions.begin(); i != regions.end(); ++i) + { + if ((*i)->getGeography() == value) + goodRegions.push_back(*i); + } + + //-- return null instead of a zero-length array + if (goodRegions.empty()) + return 0; + + //put them into the jobjectarray + int index = 0; + LocalObjectArrayRefPtr result = createNewObjectArray(goodRegions.size(), JavaLibrary::getClsRegion()); + for (std::vector::iterator it = goodRegions.begin(); + it != goodRegions.end(); ++it, ++index) + { + LocalRefPtr javaRegion; + if (!ScriptConversion::convert(**it, javaRegion)) + { + return NULL; + } + setObjectArrayElement(*result, index, *javaRegion); + } + return result->getReturnValue(); +} + +//----------------------------------------------------------------------- + +/** Get all the regions with the Difficulty property set to the given value on the given planet + */ +jobjectArray JNICALL ScriptMethodsRegionNamespace::getRegionsWithDifficulty(JNIEnv *env, jobject self, jstring planet, jint value) +{ + UNREF(self); + + JavaStringParam localPlanet(planet); + + //get the planet name + std::string sceneId; + JavaLibrary::convert(localPlanet, sceneId); + + //get the planet's regions + std::vector regions; + RegionMaster::getRegionsForPlanet(sceneId, regions); + + // get the regions that have the right property + std::vector goodRegions; + for (std::vector::iterator i = regions.begin(); i != regions.end(); ++i) + { + if (value >= (*i)->getMinDifficulty() && value <= (*i)->getMaxDifficulty()) + goodRegions.push_back(*i); + } + + //-- return null instead of a zero-length array + if (goodRegions.empty()) + return 0; + + //put them into the jobjectarray + int index = 0; + LocalObjectArrayRefPtr result = createNewObjectArray(goodRegions.size(), JavaLibrary::getClsRegion()); + for (std::vector::iterator it = goodRegions.begin(); + it != goodRegions.end(); ++it, ++index) + { + LocalRefPtr javaRegion; + if (!ScriptConversion::convert(**it, javaRegion)) + { + return NULL; + } + setObjectArrayElement(*result, index, *javaRegion); + } + return result->getReturnValue(); +} + +//----------------------------------------------------------------------- + +/** Get all the regions with the Spawnable property set to the given value on the given planet + */ +jobjectArray JNICALL ScriptMethodsRegionNamespace::getRegionsWithSpawnable(JNIEnv *env, jobject self, jstring planet, jint value) +{ + UNREF(self); + + JavaStringParam localPlanet(planet); + + //get the planet name + std::string sceneId; + JavaLibrary::convert(localPlanet, sceneId); + + //get the planet's regions + std::vector regions; + RegionMaster::getRegionsForPlanet(sceneId, regions); + + // get the regions that have the right property + std::vector goodRegions; + for (std::vector::iterator i = regions.begin(); i != regions.end(); ++i) + { + if ((*i)->getSpawn() == value) + goodRegions.push_back(*i); + } + + //-- return null instead of a zero-length array + if (goodRegions.empty()) + return 0; + + //put them into the jobjectarray + int index = 0; + LocalObjectArrayRefPtr result = createNewObjectArray(goodRegions.size(), JavaLibrary::getClsRegion()); + for (std::vector::iterator it = goodRegions.begin(); + it != goodRegions.end(); ++it, ++index) + { + LocalRefPtr javaRegion; + if (!ScriptConversion::convert(**it, javaRegion)) + { + return NULL; + } + setObjectArrayElement(*result, index, *javaRegion); + } + return result->getReturnValue(); +} + +//----------------------------------------------------------------------- + +/** Get all the regions with the Mission property set to the given value on the given planet + */ +jobjectArray JNICALL ScriptMethodsRegionNamespace::getRegionsWithMission(JNIEnv *env, jobject self, jstring planet, jint value) +{ + UNREF(self); + + JavaStringParam localPlanet(planet); + + //get the planet name + std::string sceneId; + JavaLibrary::convert(localPlanet, sceneId); + + //get the planet's regions + std::vector regions; + RegionMaster::getRegionsForPlanet(sceneId, regions); + + // get the regions that have the right property + std::vector goodRegions; + for (std::vector::iterator i = regions.begin(); i != regions.end(); ++i) + { + if ((*i)->getMission() == value) + goodRegions.push_back(*i); + } + + //-- return null instead of a zero-length array + if (goodRegions.empty()) + return 0; + + //put them into the jobjectarray + int index = 0; + LocalObjectArrayRefPtr result = createNewObjectArray(goodRegions.size(), JavaLibrary::getClsRegion()); + for (std::vector::iterator it = goodRegions.begin(); + it != goodRegions.end(); ++it, ++index) + { + LocalRefPtr javaRegion; + if (!ScriptConversion::convert(**it, javaRegion)) + { + return NULL; + } + setObjectArrayElement(*result, index, *javaRegion); + } + return result->getReturnValue(); +} + +//----------------------------------------------------------------------- + +/** Delete all the regions on the given planet + */ +jboolean JNICALL ScriptMethodsRegionNamespace::wipeRegionsFromPlanet(JNIEnv *env, jobject self, jstring planet) +{ + UNREF(self); + return JNI_FALSE; + + //@todo implement this +} + +//----------------------------------------------------------------------- + +/** Delete the given region + * @return true on success, false on failure (if the region doesn't point to a valid const Region, if region isn't of the script.region class, etc.) + */ +jboolean JNICALL ScriptMethodsRegionNamespace::deleteRegion(JNIEnv *env, jobject self, jobject region) +{ + + UNREF(self); + if (region == 0) + return JNI_FALSE; + + const Region* r = 0; + if (!ScriptConversion::convert(region, r)) + return JNI_FALSE; + + if (!r->isDynamic()) + return JNI_FALSE; + + UniverseObject * regionObject = dynamic_cast(r->getDynamicRegionId().getObject()); + if (regionObject == NULL) + return JNI_FALSE; + regionObject->permanentlyDestroy(DeleteReasons::Script); + return JNI_TRUE; +} + +//----------------------------------------------------------------------- + +/** Find the extent of the given region + * @return true on success, false on failure (if the region doesn't point to a valid const Region, if region isn't of the script.region class, etc.) + */ +jobjectArray JNICALL ScriptMethodsRegionNamespace::getRegionExtent(JNIEnv *env, jobject self, jobject region) +{ + UNREF (self); + + if (env->IsInstanceOf (region, JavaLibrary::getClsRegion()) != JNI_TRUE) + { + DEBUG_WARNING (true, ("getRegionExtent (): jobject region is not a region")); + return 0; + } + + const Region * r = 0; + if (!ScriptConversion::convert(region, r)) + { + DEBUG_WARNING (true, ("getRegionExtent (): could not convert region to a const Region")); + return 0; + } + const MxCifQuadTreeBounds & bounds = r->getBounds(); + + LocalObjectArrayRefPtr locations = createNewObjectArray (2, JavaLibrary::getClsLocation()); + + LocalRefPtr lowerLeftLocation; + if (!ScriptConversion::convert (Vector(bounds.getMinX(), 0.f, bounds.getMinY()), r->getPlanet(), NetworkId::cms_invalid, lowerLeftLocation)) + { + DEBUG_WARNING (true, ("getRegionExtent (): could not convert lower-left location")); + return 0; + } + + LocalRefPtr upperRightLocation; + if (!ScriptConversion::convert (Vector (bounds.getMaxX(), 0.f, bounds.getMaxY()), r->getPlanet(), NetworkId::cms_invalid, upperRightLocation)) + { + DEBUG_WARNING (true, ("getRegionExtent (): could not convert upper-right location")); + return 0; + } + + setObjectArrayElement(*locations, 0, *lowerLeftLocation); + setObjectArrayElement(*locations, 1, *upperRightLocation); + + return locations->getReturnValue(); +} + +//----------------------------------------------------------------------- + +/** Find a random point in the given region + * @return a script.location inside the region, or a null reference if any problems occur + */ +jobject JNICALL ScriptMethodsRegionNamespace::findPointInRegion(JNIEnv *env, jobject self, jobject region) +{ + UNREF(self); + + const Region* r = 0; + if (!ScriptConversion::convert(region, r)) + return 0; + const MxCifQuadTreeBounds & bounds = r->getBounds(); + + float x,z; + do + { + x = Random::randomReal(bounds.getMinX(), bounds.getMaxX()); + z = Random::randomReal(bounds.getMinY(), bounds.getMaxY()); + } while (!bounds.isPointIn(x, z)); + + Vector loc3d(x, 0, z); + LocalRefPtr location; + if (!ScriptConversion::convert(loc3d, r->getPlanet(), NetworkId::cms_invalid, location)) + return NULL; + return location->getReturnValue(); +} + +//----------------------------------------------------------------------- + +/** Return an array of all the regions with the given value for the PvP property that cover the given point + */ +jobjectArray JNICALL ScriptMethodsRegionNamespace::getRegionsWithPvPAtPoint(JNIEnv *env, jobject self, jobject location, jint value) +{ + //get all the regions at the given point + LocalObjectArrayRefPtr regionsAtPoint = _getRegionsAtPoint(location); + if (regionsAtPoint.get() == NULL || regionsAtPoint == LocalObjectArrayRef::cms_nullPtr) + return 0; + + //parse out the ones with the right property + int count = getArrayLength(*regionsAtPoint); + std::vector result; + for (int i = 0; i < count; ++i) + { + LocalRefPtr region = getObjectArrayElement(*regionsAtPoint, i); + const Region* r = 0; + if (!ScriptConversion::convert(*region, r)) + return 0; + if(r->getPvp() == value) + result.push_back(r); + } + + //-- return null instead of a zero-length array + if (result.empty ()) + return NULL; + + //put them into the jobjectarray + LocalObjectArrayRefPtr regions = createNewObjectArray(result.size(), JavaLibrary::getClsRegion()); + + int index = 0; + for(std::vector::iterator it = result.begin(); it != result.end(); ++it, ++index) + { + LocalRefPtr javaRegion; + const Region * r = *it; + if (r != NULL) + { + if (!ScriptConversion::convert(*r, javaRegion)) + return NULL; + } + setObjectArrayElement(*regions, index, *javaRegion); + } + return regions->getReturnValue(); +} + +//----------------------------------------------------------------------- + +/** Return an array of all the regions with the given value for the Buildable property that cover the given point + */ +jobjectArray JNICALL ScriptMethodsRegionNamespace::getRegionsWithBuildableAtPoint(JNIEnv *env, jobject self, jobject location, jint value) +{ + //get all the regions at the given point + LocalObjectArrayRefPtr regionsAtPoint = _getRegionsAtPoint(location); + if (regionsAtPoint.get() == NULL || regionsAtPoint == LocalObjectArrayRef::cms_nullPtr) + return 0; + + //parse out the ones with the right property + int count = getArrayLength(*regionsAtPoint); + std::vector result; + for (int i = 0; i < count; ++i) + { + LocalRefPtr region = getObjectArrayElement(*regionsAtPoint, i); + const Region* r = 0; + if (!ScriptConversion::convert(*region, r)) + return 0; + if(r->getBuildable() == value) + result.push_back(r); + } + + //-- return null instead of a zero-length array + if (result.empty ()) + return NULL; + + //put them into the jobjectarray + LocalObjectArrayRefPtr regions = createNewObjectArray(result.size(), JavaLibrary::getClsRegion()); + + int index = 0; + for(std::vector::iterator it = result.begin(); it != result.end(); ++it, ++index) + { + LocalRefPtr javaRegion; + const Region * r = *it; + if (r != NULL) + { + if(!ScriptConversion::convert(*r, javaRegion)) + return NULL; + } + setObjectArrayElement(*regions, index, *javaRegion); + } + return regions->getReturnValue(); +} + +//----------------------------------------------------------------------- + +/** Return an array of all the regions with the given value for the Municipal property that cover the given point + */ +jobjectArray JNICALL ScriptMethodsRegionNamespace::getRegionsWithMunicipalAtPoint(JNIEnv *env, jobject self, jobject location, jint value) +{ + PROFILER_AUTO_BLOCK_DEFINE("JNI::getRegionsWithMunicipalAtPoint"); + //get all the regions at the given point + LocalObjectArrayRefPtr regionsAtPoint = _getRegionsAtPoint(location); + if (regionsAtPoint.get() == NULL || regionsAtPoint == LocalObjectArrayRef::cms_nullPtr) + return 0; + + //parse out the ones with the right property + int count = getArrayLength(*regionsAtPoint); + std::vector result; + for (int i = 0; i < count; ++i) + { + LocalRefPtr region = getObjectArrayElement(*regionsAtPoint, i); + const Region* r = 0; + if (!ScriptConversion::convert(*region, r)) + return 0; + if(r->getMunicipal() == value) + result.push_back(r); + } + + //-- return null instead of a zero-length array + if (result.empty ()) + return NULL; + + //put them into the jobjectarray + LocalObjectArrayRefPtr regions = createNewObjectArray(result.size(), JavaLibrary::getClsRegion()); + + int index = 0; + for(std::vector::iterator it = result.begin(); it != result.end(); ++it, ++index) + { + LocalRefPtr javaRegion; + const Region * r = *it; + if (r != NULL) + { + if(!ScriptConversion::convert(*r, javaRegion)) + return NULL; + } + setObjectArrayElement(*regions, index, *javaRegion); + } + return regions->getReturnValue(); +} + +//----------------------------------------------------------------------- + +/** Return an array of all the regions with the given value for the Geographical property that cover the given point + */ +jobjectArray JNICALL ScriptMethodsRegionNamespace::getRegionsWithGeographicalAtPoint(JNIEnv *env, jobject self, jobject location, jint value) +{ + PROFILER_AUTO_BLOCK_DEFINE("JNI::getRegionsWithGeographicalAtPoint"); + //get all the regions at the given point + LocalObjectArrayRefPtr regionsAtPoint = _getRegionsAtPoint(location); + if (regionsAtPoint.get() == NULL || regionsAtPoint == LocalObjectArrayRef::cms_nullPtr) + return 0; + + //parse out the ones with the right property + int count = getArrayLength(*regionsAtPoint); + std::vector result; + for (int i = 0; i < count; ++i) + { + LocalRefPtr region = getObjectArrayElement(*regionsAtPoint, i); + const Region* r = 0; + if (!ScriptConversion::convert(*region, r)) + return 0; + if(r->getGeography() == value) + result.push_back(r); + } + + //-- return null instead of a zero-length array + if (result.empty ()) + return NULL; + + //put them into the jobjectarray + LocalObjectArrayRefPtr regions = createNewObjectArray(result.size(), JavaLibrary::getClsRegion()); + + int index = 0; + for(std::vector::iterator it = result.begin(); it != result.end(); ++it, ++index) + { + LocalRefPtr javaRegion; + const Region * r = *it; + if (r != NULL) + { + if(!ScriptConversion::convert(*r, javaRegion)) + return NULL; + } + setObjectArrayElement(*regions, index, *javaRegion); + } + return regions->getReturnValue(); +} + +//----------------------------------------------------------------------- + +/** Return an array of all the regions with the given value for the Difficulty property that cover the given point + */ +jobjectArray JNICALL ScriptMethodsRegionNamespace::getRegionsWithDifficultyAtPoint(JNIEnv *env, jobject self, jobject location, jint value) +{ + //get all the regions at the given point + LocalObjectArrayRefPtr regionsAtPoint = _getRegionsAtPoint(location); + if (regionsAtPoint.get() == NULL || regionsAtPoint == LocalObjectArrayRef::cms_nullPtr) + return 0; + + //parse out the ones with the right property + int count = getArrayLength(*regionsAtPoint); + std::vector result; + for (int i = 0; i < count; ++i) + { + LocalRefPtr region = getObjectArrayElement(*regionsAtPoint, i); + const Region* r = 0; + if (!ScriptConversion::convert(*region, r)) + return 0; + if (value >= r->getMinDifficulty() && value <= r->getMaxDifficulty()) + result.push_back(r); + } + + //-- return null instead of a zero-length array + if (result.empty ()) + return NULL; + + //put them into the jobjectarray + LocalObjectArrayRefPtr regions = createNewObjectArray(result.size(), JavaLibrary::getClsRegion()); + + int index = 0; + for(std::vector::iterator it = result.begin(); it != result.end(); ++it, ++index) + { + LocalRefPtr javaRegion; + const Region * r = *it; + if (r != NULL) + { + if(!ScriptConversion::convert(*r, javaRegion)) + return NULL; + } + setObjectArrayElement(*regions, index, *javaRegion); + } + return regions->getReturnValue(); +} + +//----------------------------------------------------------------------- + +/** Return an array of all the regions with the given value for the Spawnable property that cover the given point + */ +jobjectArray JNICALL ScriptMethodsRegionNamespace::getRegionsWithSpawnableAtPoint(JNIEnv *env, jobject self, jobject location, jint value) +{ + //get all the regions at the given point + LocalObjectArrayRefPtr regionsAtPoint = _getRegionsAtPoint(location); + if (regionsAtPoint.get() == NULL || regionsAtPoint == LocalObjectArrayRef::cms_nullPtr) + return 0; + + //parse out the ones with the right property + int count = getArrayLength(*regionsAtPoint); + std::vector result; + for (int i = 0; i < count; ++i) + { + LocalRefPtr region = getObjectArrayElement(*regionsAtPoint, i); + const Region* r = 0; + if (!ScriptConversion::convert(*region, r)) + return 0; + if (r->getSpawn() == value) + result.push_back(r); + } + + //-- return null instead of a zero-length array + if (result.empty ()) + return NULL; + + //put them into the jobjectarray + LocalObjectArrayRefPtr regions = createNewObjectArray(result.size(), JavaLibrary::getClsRegion()); + + int index = 0; + for(std::vector::iterator it = result.begin(); it != result.end(); ++it, ++index) + { + LocalRefPtr javaRegion; + const Region * r = *it; + if (r != NULL) + { + if(!ScriptConversion::convert(*r, javaRegion)) + return NULL; + } + setObjectArrayElement(*regions, index, *javaRegion); + } + return regions->getReturnValue(); +} + +//----------------------------------------------------------------------- + +/** Return an array of all the regions with the given value for the Mission property that cover the given point + */ +jobjectArray JNICALL ScriptMethodsRegionNamespace::getRegionsWithMissionAtPoint(JNIEnv *env, jobject self, jobject location, jint value) +{ + //get all the regions at the given point + LocalObjectArrayRefPtr regionsAtPoint = _getRegionsAtPoint(location); + if (regionsAtPoint.get() == NULL || regionsAtPoint == LocalObjectArrayRef::cms_nullPtr) + return 0; + + //parse out the ones with the right property + int count = getArrayLength(*regionsAtPoint); + std::vector result; + for (int i = 0; i < count; ++i) + { + LocalRefPtr region = getObjectArrayElement(*regionsAtPoint, i); + const Region* r = 0; + if (!ScriptConversion::convert(*region, r)) + return 0; + if(r->getMission() == value) + result.push_back(r); + } + + //-- return null instead of a zero-length array + if (result.empty ()) + return NULL; + + //put them into the jobjectarray + LocalObjectArrayRefPtr regions = createNewObjectArray(result.size(), JavaLibrary::getClsRegion()); + + int index = 0; + for(std::vector::iterator it = result.begin(); it != result.end(); ++it, ++index) + { + LocalRefPtr javaRegion; + const Region * r = *it; + if (r != NULL) + { + if(!ScriptConversion::convert(*r, javaRegion)) + return NULL; + } + setObjectArrayElement(*regions, index, *javaRegion); + } + return regions->getReturnValue(); +} + +//----------------------------------------------------------------------- + +/** Get the "most appropriate" region at the given location. Specifically, return the region that: + * 1: has a value for its fictional name, and + * 2: of the above, has the smallest area + */ +jobject JNICALL ScriptMethodsRegionNamespace::getSmallestRegionAtPoint(JNIEnv *env, jobject self, + jobject location) +{ + Vector locationVec; + std::string sceneId; + if(!ScriptConversion::convertWorld(location, locationVec, sceneId)) + return NULL; + + const Region * r = RegionMaster::getSmallestRegionAtPoint(sceneId, locationVec.x, + locationVec.z); + if (r == NULL) + return NULL; + + LocalRefPtr region; + if (!ScriptConversion::convert(*r, region)) + return NULL; + return region->getReturnValue(); +} + +//----------------------------------------------------------------------- + +/** Same as getSmallestRegionAtPoint, but the region must be flagged as visible. + */ +jobject JNICALL ScriptMethodsRegionNamespace::getSmallestVisibleRegionAtPoint(JNIEnv *env, jobject self, + jobject location) +{ + Vector locationVec; + std::string sceneId; + if(!ScriptConversion::convertWorld(location, locationVec, sceneId)) + return NULL; + + const Region * r = RegionMaster::getSmallestVisibleRegionAtPoint(sceneId, locationVec.x, + locationVec.z); + if (r == NULL) + return NULL; + + LocalRefPtr region; + if (!ScriptConversion::convert(*r, region)) + return NULL; + return region->getReturnValue(); +} + +//----------------------------------------------------------------------- + +/** Checks to see if a region is a notify region +* @return true or false +*/ +jboolean JNICALL ScriptMethodsRegionNamespace::isNotifyRegion(JNIEnv *env, jobject self, jobject region) +{ + UNREF(self); + if (region == 0) + return JNI_FALSE; + + const Region* r = 0; + if (!ScriptConversion::convert(region, r)) + return JNI_FALSE; + + return (r->getNotify()); +} + +//----------------------------------------------------------------------- + +//----------------------------------------------------------------------- + +/** Create a circular region given the location and radius and spawn creatures with it! +*/ +jlong JNICALL ScriptMethodsRegionNamespace::createCircleRegionWithSpawn(JNIEnv *env, jobject self, + jobject center, jfloat radius, jstring name, jint pvp, jint buildable, + jint municipal, jint geography, jint minDifficulty, jint maxDifficulty, + jint spawnable, jint mission, jboolean visible, jboolean notify, jstring spawnTable, jint duration) +{ + UNREF(self); + + // validate scripter's input + if (center == NULL || radius <= 0 || name == 0) + return 0; + + JavaStringParam jname(name); + Unicode::String regionName; + if (!JavaLibrary::convert(jname, regionName)) + return 0; + + // pull the data from the java Location objects + Vector locationVec; + std::string sceneId; + if (!ScriptConversion::convertWorld(center, locationVec, sceneId)) + return 0; + + JavaStringParam spawn(spawnTable); + Unicode::String spawnDataTable; + if(!JavaLibrary::convert(spawn, spawnDataTable)) + return 0; + + // create the region + NetworkId regionObject = RegionMaster::createNewDynamicRegionWithSpawn(locationVec.x, locationVec.y, locationVec.z, + radius, regionName, sceneId, pvp, buildable, municipal, geography, minDifficulty, + maxDifficulty, spawnable, mission, visible, notify, Unicode::wideToNarrow(spawnDataTable), duration); + + return regionObject.getValue(); +} diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsRegion3d.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsRegion3d.cpp new file mode 100644 index 00000000..37c9f942 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsRegion3d.cpp @@ -0,0 +1,275 @@ +// ====================================================================== +// +// ScriptMethodsRegion3d.cpp +// +// Copyright 2003 Sony Online Entertainment +// +// ====================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "serverGame/Region3d.h" +#include "serverGame/Region3dMaster.h" +#include "serverGame/RegionBox.h" +#include "serverGame/RegionSphere.h" +#include "serverScript/ScriptParameters.h" + +using namespace JNIWrappersNamespace; + + +// ====================================================================== +// ScriptMethodsRegion3dNamespace +// ====================================================================== + +namespace ScriptMethodsRegion3dNamespace +{ + bool install(); + ScriptParams *convertRegionDictionaryToScriptParams(jobject regionDictionary); + + jobject JNICALL get3dRegionByName(JNIEnv *env, jobject self, jstring regionName); + jobject JNICALL getSmallest3dRegionAtPoint(JNIEnv *env, jobject self, jobject location); + jobjectArray JNICALL get3dRegionsAtPoint(JNIEnv *env, jobject self, jobject location); + void JNICALL createSphereRegion(JNIEnv *env, jobject self, jstring regionName, jobject centerJ, jfloat radius, jobject regionDictionary); + void JNICALL createBoxRegion(JNIEnv *env, jobject self, jstring regionName, jobject extentMinJ, jobject extentMaxJ, jobject regionDictionary); + void JNICALL destroy3dRegion(JNIEnv *env, jobject self, jstring regionName); +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsRegion3dNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsRegion3dNamespace::c)} + JF("get3dRegionByName", "(Ljava/lang/String;)Lscript/dictionary;", get3dRegionByName), + JF("getSmallest3dRegionAtPoint", "(Lscript/location;)Lscript/dictionary;", getSmallest3dRegionAtPoint), + JF("get3dRegionsAtPoint", "(Lscript/location;)[Lscript/dictionary;", get3dRegionsAtPoint), + JF("createSphereRegion", "(Ljava/lang/String;Lscript/vector;FLscript/dictionary;)V", createSphereRegion), + JF("createBoxRegion", "(Ljava/lang/String;Lscript/vector;Lscript/vector;Lscript/dictionary;)V", createBoxRegion), + JF("destroy3dRegion", "(Ljava/lang/String;)V", destroy3dRegion), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +// ====================================================================== + +static JavaDictionaryPtr get3dRegionScriptDataReturnValue(Region3d const *region) +{ + if (region) + { + ScriptParams const *params = region->getRegionScriptData(); + if (params) + { + JavaDictionaryPtr dict; + JavaLibrary::instance()->convert(*params, dict); + return dict; + } + } + return JavaDictionary::cms_nullPtr; +} + +// ---------------------------------------------------------------------- + +struct Region3dPtrVolumeComparator +{ + bool operator()(Region3d const *lhs, Region3d const *rhs) const + { + return lhs->getVolume() < rhs->getVolume(); + } +}; + +// ====================================================================== + +ScriptParams *ScriptMethodsRegion3dNamespace::convertRegionDictionaryToScriptParams(jobject regionDictionary) +{ + // If we're passed a null dictionary, we just don't have any extra data but + // we still want to return a ScriptParams to fill in the standard values. + if (!regionDictionary) + return new ScriptParams; + + LocalRefParam regionDictionaryParam(regionDictionary); + + if (!isInstanceOf(regionDictionaryParam, JavaLibrary::getClsDictionary())) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::convertRegionDictionaryToScriptParams bad regionDictionary")); + return 0; + } + + ScriptParams *regionScriptData = new ScriptParams; + + LocalRefPtr keyEnumeration = callObjectMethod(regionDictionaryParam, JavaLibrary::getMidDictionaryKeys()); + while (callBooleanMethod(*keyEnumeration, JavaLibrary::getMidEnumerationHasMoreElements())) + { + LocalRefPtr key = callObjectMethod(*keyEnumeration, JavaLibrary::getMidEnumerationNextElement()); + if (!isInstanceOf(*key, JavaLibrary::getClsString())) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::convertRegionDictionaryToScriptParams regionDictionary has bad key")); + delete regionScriptData; + return 0; + } + JavaStringParam localKeyStr(*key); + std::string keyStr; + JavaLibrary::convert(localKeyStr, keyStr); + LocalRefPtr value = callObjectMethod(regionDictionaryParam, JavaLibrary::getMidDictionaryGet(), key->getValue()); + if (isInstanceOf(*value, JavaLibrary::getClsInteger())) + { + jint intValue = callIntMethod(*value, JavaLibrary::getMidIntegerIntValue()); + regionScriptData->addParam(intValue, keyStr, true); + } + else if (isInstanceOf(*value, JavaLibrary::getClsFloat())) + { + jfloat floatValue = callFloatMethod(*value, JavaLibrary::getMidFloatFloatValue()); + regionScriptData->addParam(floatValue, keyStr, true); + } + else if (isInstanceOf(*value, JavaLibrary::getClsBoolean())) + { + jboolean booleanValue = callBooleanMethod(*value, JavaLibrary::getMidBooleanBooleanValue()); + regionScriptData->addParam(booleanValue, keyStr, true); + } + else if (isInstanceOf(*value, JavaLibrary::getClsString())) + { + JavaStringParam localValueStr(*value); + std::string valueStr; + JavaLibrary::convert(localValueStr, valueStr); + char *s = new char[valueStr.size()+1]; + strcpy(s, valueStr.c_str()); + regionScriptData->addParam(s, keyStr, true); + } + else + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::convertRegionDictionaryToScriptParams bad type for regionDictionary value, key=%s", keyStr.c_str())); + delete regionScriptData; + return 0; + } + } + + return regionScriptData; +} + +// ====================================================================== + +jobject JNICALL ScriptMethodsRegion3dNamespace::get3dRegionByName(JNIEnv *env, jobject self, jstring regionName) +{ + JavaStringParam regionNameParam(regionName); + std::string regionNameString; + if (JavaLibrary::convert(regionNameParam, regionNameString)) + return get3dRegionScriptDataReturnValue(Region3dMaster::getRegionByName(regionNameString))->getReturnValue(); + return 0; +} + +// ---------------------------------------------------------------------- + +jobject JNICALL ScriptMethodsRegion3dNamespace::getSmallest3dRegionAtPoint(JNIEnv *env, jobject self, jobject location) +{ + Vector target; + if (ScriptConversion::convertWorld(location, target)) + return get3dRegionScriptDataReturnValue(Region3dMaster::getSmallestRegionAtPoint(target))->getReturnValue(); + return 0; +} + +// ---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsRegion3dNamespace::get3dRegionsAtPoint(JNIEnv *env, jobject self, jobject location) +{ + Vector target; + if (ScriptConversion::convertWorld(location, target)) + { + std::vector results; + Region3dMaster::getRegionsAtPoint(target, results); + if (!results.empty()) + { + std::sort(results.begin(), results.end(), Region3dPtrVolumeComparator()); + LocalObjectArrayRefPtr regions = createNewObjectArray(results.size(), JavaLibrary::getClsDictionary()); + for (unsigned int i = 0; i < results.size(); ++i) + setObjectArrayElement(*regions, i, *get3dRegionScriptDataReturnValue(results[i])); + return regions->getReturnValue(); + } + } + return 0; +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsRegion3dNamespace::createSphereRegion(JNIEnv *env, jobject self, jstring regionName, jobject centerJ, jfloat radius, jobject regionDictionary) +{ + JavaStringParam localRegionNameStr((jstring)regionName); + std::string regionNameStr; + JavaLibrary::convert(localRegionNameStr, regionNameStr); + + Vector center; + if (!ScriptConversion::convert(centerJ, center)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::createSphereRegion bad center vector, region '%s'", regionNameStr.c_str())); + else if (radius <= 0.0f) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::createSphereRegion non-positive radius, region '%s'", regionNameStr.c_str())); + else + { + ScriptParams *regionScriptData = convertRegionDictionaryToScriptParams(regionDictionary); + if (regionScriptData) + { + char *s = new char[regionNameStr.size()+1]; + strcpy(s, regionNameStr.c_str()); + regionScriptData->addParam(s, "regionName", true); + regionScriptData->addParam(0, "geometry", true); + regionScriptData->addParam(center.x, "x1", true); + regionScriptData->addParam(center.y, "y1", true); + regionScriptData->addParam(center.z, "z1", true); + regionScriptData->addParam(static_cast(radius), "radius", true); + IGNORE_RETURN(new RegionSphere(regionNameStr, center, radius, regionScriptData)); + } + } +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsRegion3dNamespace::createBoxRegion(JNIEnv *env, jobject self, jstring regionName, jobject extentMinJ, jobject extentMaxJ, jobject regionDictionary) +{ + JavaStringParam localRegionNameStr((jstring)regionName); + std::string regionNameStr; + JavaLibrary::convert(localRegionNameStr, regionNameStr); + + Vector extentMin, extentMax; + if (!ScriptConversion::convert(extentMinJ, extentMin)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::createBoxRegion bad extentMin vector, region '%s'", regionNameStr.c_str())); + else if (!ScriptConversion::convert(extentMaxJ, extentMax)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::createBoxRegion bad extentMax vector, region '%s'", regionNameStr.c_str())); + else if (extentMax.x <= extentMin.x || extentMax.y <= extentMin.y || extentMax.z <= extentMin.z) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::createBoxRegion has inverted coordinates, region '%s'", regionNameStr.c_str())); + else + { + ScriptParams *regionScriptData = convertRegionDictionaryToScriptParams(regionDictionary); + if (regionScriptData) + { + char *s = new char[regionNameStr.size()+1]; + strcpy(s, regionNameStr.c_str()); + regionScriptData->addParam(s, "regionName", true); + regionScriptData->addParam(1, "geometry", true); + regionScriptData->addParam(extentMin.x, "x1", true); + regionScriptData->addParam(extentMin.y, "y1", true); + regionScriptData->addParam(extentMin.z, "z1", true); + regionScriptData->addParam(extentMax.x, "x2", true); + regionScriptData->addParam(extentMax.y, "y2", true); + regionScriptData->addParam(extentMax.z, "z2", true); + IGNORE_RETURN(new RegionBox(regionNameStr, extentMin, extentMax, regionScriptData)); + } + } +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsRegion3dNamespace::destroy3dRegion(JNIEnv *env, jobject self, jstring regionName) +{ + JavaStringParam localRegionNameStr((jstring)regionName); + std::string regionNameStr; + JavaLibrary::convert(localRegionNameStr, regionNameStr); + + Region3d const *reg = Region3dMaster::getRegionByName(regionNameStr); + delete reg; +} + +// ====================================================================== + diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsRemoteDebug.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsRemoteDebug.cpp new file mode 100644 index 00000000..b60e5cd3 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsRemoteDebug.cpp @@ -0,0 +1,54 @@ +//----------------------------------------------------------------------- + +// ScriptMethodsRemoteDebug.cpp +// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved. +// Author: Justin Randall + +//----------------------------------------------------------------------- + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + + +// ====================================================================== +// ScriptMethodsRemoteDebugNamespace +// ====================================================================== + +namespace ScriptMethodsRemoteDebugNamespace +{ + bool install(); + + void JNICALL printChannelMessage (JNIEnv *env, jobject self, jstring channel, jstring message); +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsRemoteDebugNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsRemoteDebugNamespace::c)} + JF("printChannelMessage", "(Ljava/lang/String;Ljava/lang/String;)V", printChannelMessage), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +//----------------------------------------------------------------------- + +void JNICALL ScriptMethodsRemoteDebugNamespace::printChannelMessage (JNIEnv *env, jobject self, jstring channel, jstring message) +{ + JavaStringParam localChannel(channel); + std::string channelText; + JavaLibrary::convert(localChannel, channelText); + JavaStringParam localMessage(message); + std::string messageText; + JavaLibrary::convert(localMessage, messageText); + + DEBUG_OUTPUT_CHANNEL(channelText.c_str(), ("%s", messageText.c_str())); +} + +//----------------------------------------------------------------------- diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsResource.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsResource.cpp new file mode 100644 index 00000000..e908612c --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsResource.cpp @@ -0,0 +1,1198 @@ +//======================================================================== +// +// ScriptMethodsResource.cpp - implements script methods dealing with resource +// movement. +// +// copyright 2001 Sony Online Entertainment +// +//======================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "UnicodeUtils.h" +#include "serverGame/Client.h" +#include "serverGame/PlanetObject.h" +#include "serverGame/ResourceContainerObject.h" +#include "serverGame/ResourcePoolObject.h" +#include "serverGame/ResourceTypeObject.h" +#include "serverGame/ServerObject.h" +#include "serverGame/ServerResourceClassObject.h" +#include "serverGame/ServerUniverse.h" +#include "serverGame/ServerWorld.h" +#include "serverGame/SurveySystem.h" +#include "sharedGame/ResourceClassObject.h" +#include "sharedLog/Log.h" +#include "sharedNetworkMessages/ResourceHarvesterActivatePageMessage.h" +#include "sharedObject/NetworkIdManager.h" + +using namespace JNIWrappersNamespace; + + +// ====================================================================== +// ScriptMethodsResourceNamespace +// ====================================================================== + +namespace ScriptMethodsResourceNamespace +{ + bool install(); + + void JNICALL activateHarvesterExtractionPage (JNIEnv *env, jobject self, jlong player, jlong harvester); + jboolean JNICALL requestResourceListForSurvey(JNIEnv *env, jobject self, jlong player, jlong tool, jstring parentResourceClass); + jboolean JNICALL requestSurvey(JNIEnv *env, jobject self, jlong player, jstring parentResourceClass, jstring resourceTypeName, jint surveyRange, jint numPoints); + jlong JNICALL pickRandomNonDepeletedResource(JNIEnv *env, jobject self, jstring parentResourceClass); + jint JNICALL oneTimeHarvest(JNIEnv *env, jobject self, jlong resourceType, jint amount, jobject where); + jlong JNICALL getResourceContainerResourceType(JNIEnv *env, jobject self, jlong resourceContainer); + jint JNICALL getResourceContainerQuantity(JNIEnv *env, jobject self, jlong resourceContainer); + jstring JNICALL getResourceCtsData(JNIEnv *env, jobject self, jlong resourceContainer); + void JNICALL setResourceCtsData(JNIEnv *env, jobject self, jlong resourceContainer, jint quantity, jstring resourceData); + jboolean JNICALL addResourceToContainer(JNIEnv *env, jobject self, jlong resourceContainer, jlong resourceType, jint amount, jlong sourcePlayer); + jboolean JNICALL removeResourceFromContainer(JNIEnv *env, jobject self, jlong resourceContainer, jlong resourceType, jint amount); + jboolean JNICALL transferToResourceContainer(JNIEnv *env, jobject self, jlong sourceResourceContainer, jlong destinationResourceContainer, jint amount); + jfloat JNICALL getResourceEfficiency(JNIEnv *env, jobject self, jlong resourceType, jobject where); + jboolean JNICALL isResourceDerivedFrom(JNIEnv *env, jobject self, jlong resourceType, jstring parentResourceClass); + jboolean JNICALL isResourceClassDerivedFrom(JNIEnv *env, jobject self, jstring resourceClass, jstring parentResourceClass); + jlong JNICALL getResourceTypeByName(JNIEnv *env, jobject self, jstring typeName); + jstring JNICALL getResourceContainerForType(JNIEnv *env, jobject self, jlong resourceType); + jstring JNICALL getResourceName(JNIEnv *env, jobject self, jlong resourceType); + jobjectArray JNICALL getResourceNames(JNIEnv *env, jobject self, jlongArray resourceTypes); + jstring JNICALL getResourceClassName(JNIEnv *env, jobject self, jstring resourceClass); + jobjectArray JNICALL getResourceClassNames(JNIEnv *env, jobject self, jobjectArray resourceClasses); + jlongArray JNICALL getResourceTypes(JNIEnv *env, jobject self, jstring resourceClass); + jstring JNICALL getResourceClass(JNIEnv *env, jobject self, jlong resourceType); + jstring JNICALL getResourceParentClass(JNIEnv *env, jobject self, jstring resourceClass); + jobjectArray JNICALL getResourceChildClasses(JNIEnv *env, jobject self, jstring resourceClass); + jobjectArray JNICALL getImmediateResourceChildClasses(JNIEnv *env, jobject self, jstring resourceClass); + jobjectArray JNICALL getLeafResourceChildClasses(JNIEnv *env, jobject self, jstring resourceClass); + jboolean JNICALL hasResourceType(JNIEnv *env, jobject self, jstring resourceClass); + jlong JNICALL createResourceCrate(JNIEnv *env, jobject self, jlong resourceType, jint amount, jlong destination); + jobjectArray JNICALL requestResourceList(JNIEnv *env, jobject self, jobject loc, jfloat minDensity, jfloat maxDensity, jstring resourceClass); + jobjectArray JNICALL getResourceAttributes(JNIEnv *env, jobject self, jlong resourceType); + jobjectArray JNICALL getScaledResourceAttributes(JNIEnv *env, jobject self, jlong resourceType, jstring resourceClass); + jint JNICALL getResourceAttribute(JNIEnv *env, jobject self, jlong resourceType, jstring attributeName); + jlong JNICALL getRecycledVersionOfResourceType(JNIEnv * env, jobject self, jlong resourceType); + jboolean JNICALL isValidResourceId(JNIEnv *env, jobject self, jlong resourceType); +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsResourceNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsResourceNamespace::c)} + JF("_activateHarvesterExtractionPage", "(JJ)V", activateHarvesterExtractionPage), + JF("_requestResourceListForSurvey","(JJLjava/lang/String;)Z",requestResourceListForSurvey), + JF("_requestSurvey","(JLjava/lang/String;Ljava/lang/String;II)Z",requestSurvey), + JF("_pickRandomNonDepeletedResource","(Ljava/lang/String;)J",pickRandomNonDepeletedResource), + JF("_oneTimeHarvest","(JILscript/location;)I",oneTimeHarvest), + JF("_addResourceToContainer","(JJIJ)Z",addResourceToContainer), + JF("_removeResourceFromContainer","(JJI)Z",removeResourceFromContainer), + JF("_transferToResourceContainer","(JJI)Z",transferToResourceContainer), + JF("_getResourceEfficiency","(JLscript/location;)F",getResourceEfficiency), + JF("_isResourceDerivedFrom","(JLjava/lang/String;)Z",isResourceDerivedFrom), + JF("isResourceClassDerivedFrom","(Ljava/lang/String;Ljava/lang/String;)Z",isResourceClassDerivedFrom), + JF("_getResourceTypeByName","(Ljava/lang/String;)J",getResourceTypeByName), + JF("_getResourceContainerForType","(J)Ljava/lang/String;",getResourceContainerForType), + JF("_getResourceName", "(J)Ljava/lang/String;", getResourceName), + JF("_getResourceNames", "([J)[Ljava/lang/String;", getResourceNames), + JF("getResourceClassName", "(Ljava/lang/String;)Ljava/lang/String;", getResourceClassName), + JF("getResourceClassNames", "([Ljava/lang/String;)[Ljava/lang/String;", getResourceClassNames), + JF("_getResourceTypes", "(Ljava/lang/String;)[J", getResourceTypes), + JF("_getResourceClass", "(J)Ljava/lang/String;", getResourceClass), + JF("getResourceParentClass", "(Ljava/lang/String;)Ljava/lang/String;", getResourceParentClass), + JF("getResourceChildClasses", "(Ljava/lang/String;)[Ljava/lang/String;", getResourceChildClasses), + JF("getImmediateResourceChildClasses", "(Ljava/lang/String;)[Ljava/lang/String;", getImmediateResourceChildClasses), + JF("getLeafResourceChildClasses", "(Ljava/lang/String;)[Ljava/lang/String;", getLeafResourceChildClasses), + JF("hasResourceType", "(Ljava/lang/String;)Z", hasResourceType), + JF("_createResourceCrate", "(JIJ)J", createResourceCrate), + JF("requestResourceList", "(Lscript/location;FFLjava/lang/String;)[Lscript/resource_density;", requestResourceList), + JF("_getResourceAttributes", "(J)[Lscript/resource_attribute;", getResourceAttributes), + JF("_getScaledResourceAttributes", "(JLjava/lang/String;)[Lscript/resource_attribute;", getScaledResourceAttributes), + JF("_getResourceAttribute", "(JLjava/lang/String;)I", getResourceAttribute), + JF("_getRecycledVersionOfResourceType", "(J)J", getRecycledVersionOfResourceType), + JF("_isValidResourceId", "(J)Z", isValidResourceId), + JF("_getResourceContainerResourceType", "(J)J", getResourceContainerResourceType), + JF("_getResourceContainerQuantity", "(J)I", getResourceContainerQuantity), + JF("_getResourceCtsData", "(J)Ljava/lang/String;", getResourceCtsData), + JF("_setResourceCtsData", "(JILjava/lang/String;)V", setResourceCtsData), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +// ====================================================================== + +void JNICALL ScriptMethodsResourceNamespace::activateHarvesterExtractionPage (JNIEnv *env, jobject self, jlong player, jlong harvester) +{ + UNREF(self); + UNREF (env); + + const NetworkId harvesterId (harvester); + + ServerObject * playerObject = 0; + if (!JavaLibrary::getObject(player, playerObject)) + return; + + Client * const client = playerObject->getClient (); + if (!client) + return; + + ResourceHarvesterActivatePageMessage const msg(harvesterId); + client->send(msg, true); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsResourceNamespace::requestResourceListForSurvey(JNIEnv * /*env*/, jobject /*self*/, jlong player, jlong tool, jstring parentResourceClass) +{ + const NetworkId myPlayer(player); + Unicode::String myParentResourceClass; + const NetworkId surveyTool(tool); + + JavaString temp(parentResourceClass); + if (!JavaLibrary::convert(temp,myParentResourceClass)) + return JNI_FALSE; + + SurveySystem::getInstance().requestResourceListForSurvey(myPlayer,surveyTool,Unicode::wideToNarrow(myParentResourceClass)); + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsResourceNamespace::requestSurvey(JNIEnv * /*env*/, jobject /*self*/, jlong player, jstring parentResourceClass, jstring resourceTypeName, jint surveyRange, jint numPoints) +{ + const NetworkId myPlayer(player); + const Object* myPlayerObject = ServerWorld::findObjectByNetworkId(myPlayer); + Unicode::String myParentResourceClass; + std::string myResourceTypeName; + const int mySurveyRange = static_cast(surveyRange); + const int myNumPoints = static_cast(numPoints); + + JavaString temp(parentResourceClass); + if (!JavaLibrary::convert(temp,myParentResourceClass)) + return JNI_FALSE; + JavaString temp2(resourceTypeName); + if (!JavaLibrary::convert(temp2,myResourceTypeName)) + return JNI_FALSE; + if (!myPlayerObject) + return JNI_FALSE; + + SurveySystem::getInstance().requestSurvey(myPlayer, Unicode::wideToNarrow(myParentResourceClass), myResourceTypeName, myPlayerObject->getPosition_w(), mySurveyRange, myNumPoints); + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsResourceNamespace::pickRandomNonDepeletedResource(JNIEnv * /*env*/, jobject /*self*/, jstring parentResourceClass) +{ + std::string myParentResourceClass; + JavaString temp(parentResourceClass); + if (!JavaLibrary::convert(temp,myParentResourceClass)) + return 0; + + ResourceTypeObject const * const typeObj = ServerUniverse::getInstance().pickRandomNonDepletedResource(myParentResourceClass); + if (typeObj) + { + return typeObj->getNetworkId().getValue(); + } + else + return 0; +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsResourceNamespace::oneTimeHarvest(JNIEnv * /*env*/, jobject /*self*/, jlong resourceType, jint amount, jobject where) +{ + ResourceTypeObject const * const typeObj = ServerUniverse::getInstance().getResourceTypeById(NetworkId(resourceType)); + if (!typeObj) + return 0; + + Vector pos; + NetworkId cell; + if (!ScriptConversion::convert(where, pos, cell)) + return 0; + + if (cell != NetworkId::cms_invalid) + { + DEBUG_REPORT_LOG(true,("Can't call oneTimeHarvest() with a location in a cell.\n")); + return 0; + } + + ResourcePoolObject const * const poolObj=typeObj->getPoolForCurrentPlanet(); + if (poolObj) + return poolObj->oneTimeHarvest(amount, pos); + else + return 0; +} + +// ---------------------------------------------------------------------- + +/** + * Get the ResourceType contained in a container + * + * @param env Java environment + * @param self class calling this function + * @param resourceContainer the resource container + * @return A reference to the ResourceTypeObject + * @todo Maybe make a ScriptMethodsResource file, when there are a few more resource-related script methods. + */ +jlong JNICALL ScriptMethodsResourceNamespace::getResourceContainerResourceType(JNIEnv * /*env*/, jobject /*self*/, jlong resourceContainer) +{ + ResourceContainerObject * sourceObj = 0; + if (!JavaLibrary::getObject(resourceContainer, sourceObj)) + return JNI_FALSE; + + NetworkId const & result = sourceObj->getResourceTypeId(); + + return result.getValue(); +} // JavaLibrary::getResourceContainerResourceType + +// ---------------------------------------------------------------------- + +/** + * Get the quantity of resources in a container. + * + * @param env Java environment + * @param self class calling this function + * @param resourceContainer the resource container + * @return the amount + */ +jint JNICALL ScriptMethodsResourceNamespace::getResourceContainerQuantity(JNIEnv * /*env*/, jobject /*self*/, jlong resourceContainer) +{ + ResourceContainerObject * sourceObj = 0; + if (!JavaLibrary::getObject(resourceContainer, sourceObj)) + return JNI_FALSE; + + return (sourceObj->getQuantity()); +} // JavaLibrary::getResourceContainerQuantity + +// ---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsResourceNamespace::getResourceCtsData(JNIEnv *env, jobject self, jlong resourceContainer) +{ + ResourceContainerObject const * sourceObj = 0; + if (!JavaLibrary::getObject(resourceContainer, sourceObj)) + return 0; + + std::string resourceData = sourceObj->getResourceCtsData(); + if (resourceData.empty()) + return 0; + + return JavaString(resourceData).getReturnValue(); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsResourceNamespace::setResourceCtsData(JNIEnv *env, jobject self, jlong resourceContainer, jint quantity, jstring resourceData) +{ + ResourceContainerObject * sourceObj = 0; + if (!JavaLibrary::getObject(resourceContainer, sourceObj)) + return; + + if (resourceData == 0) + return; + + JavaStringParam jspResourceData(resourceData); + std::string sResourceData; + if (!JavaLibrary::convert(jspResourceData, sResourceData)) + return; + + if (sResourceData.empty()) + return; + + sourceObj->setResourceCtsData(quantity, sResourceData); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsResourceNamespace::addResourceToContainer(JNIEnv * /*env*/, jobject /*self*/, jlong resourceContainer, jlong resourceType, jint amount, jlong sourcePlayer) +{ + ResourceContainerObject * sourceObj = 0; + if (!JavaLibrary::getObject(resourceContainer, sourceObj)) + return JNI_FALSE; + + NetworkId resourceTypeId(resourceType); + NetworkId sourcePlayerId(sourcePlayer); + + if (sourceObj->addResource(resourceTypeId, amount, sourcePlayerId)) + return JNI_TRUE; + else + return JNI_FALSE; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsResourceNamespace::removeResourceFromContainer(JNIEnv * /*env*/, jobject /*self*/, jlong resourceContainer, jlong resourceType, jint amount) +{ + ResourceContainerObject * sourceObj = 0; + if (!JavaLibrary::getObject(resourceContainer, sourceObj)) + return JNI_FALSE; + + NetworkId resourceTypeId(resourceType); + + if (sourceObj->removeResourceWithoutExperience(resourceTypeId, amount)) + return JNI_TRUE; + else + return JNI_FALSE; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsResourceNamespace::transferToResourceContainer(JNIEnv * /*env*/, jobject /*self*/, jlong sourceResourceContainer, jlong destinationResourceContainer, jint amount) +{ + ResourceContainerObject * sourceObj = 0; + if (!JavaLibrary::getObject(sourceResourceContainer, sourceObj)) + return JNI_FALSE; + + ResourceContainerObject * destObj = 0; + if (!JavaLibrary::getObject(destinationResourceContainer, destObj)) + return JNI_FALSE; + + if (sourceObj->transferTo(*destObj, amount)) + return JNI_TRUE; + else + return JNI_FALSE; +} + +// ---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsResourceNamespace::getResourceEfficiency(JNIEnv * /*env*/, jobject /*self*/, jlong resourceType, jobject where) +{ + ResourceTypeObject const * const typeObj = ServerUniverse::getInstance().getResourceTypeById(NetworkId(resourceType)); + if (!typeObj) + return 0; + + Vector pos; + NetworkId cell; + if (!ScriptConversion::convert(where, pos, cell)) + return 0; + + if (cell != NetworkId::cms_invalid) + { + DEBUG_REPORT_LOG(true,("Can't call getResourceEfficiency() with a location in a cell.\n")); + return 0; + } + + if (!typeObj->isDepleted()) + { + ResourcePoolObject const * const poolObj=typeObj->getPoolForCurrentPlanet(); + if (poolObj) + return poolObj->getEfficiencyAtLocation(pos.x,pos.z); + else + return 0; + } + else + return 0; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsResourceNamespace::isResourceDerivedFrom(JNIEnv * /*env*/, jobject /*self*/, jlong resourceType, jstring parentResourceClass) +{ + std::string myParentResourceClass; + JavaStringParam temp(parentResourceClass); + if (!JavaLibrary::convert(temp,myParentResourceClass)) + return false; + + ResourceTypeObject const * const typeObj = ServerUniverse::getInstance().getResourceTypeById(NetworkId(resourceType)); + if (!typeObj) + return 0; + + const ResourceClassObject *classObj=Universe::getInstance().getResourceClassByName(myParentResourceClass); + if (!classObj) + return false; + + return typeObj->isDerivedFrom(*classObj); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsResourceNamespace::isResourceClassDerivedFrom(JNIEnv * /*env*/, jobject /*self*/, jstring resourceClass, jstring parentResourceClass) +{ + std::string myResourceClass; + JavaStringParam temp(resourceClass); + if (!JavaLibrary::convert(temp,myResourceClass)) + return false; + + std::string myParentResourceClass; + JavaStringParam temp2(parentResourceClass); + if (!JavaLibrary::convert(temp2,myParentResourceClass)) + return false; + + const ResourceClassObject *classObj=ServerUniverse::getInstance().getResourceClassByName(myResourceClass); + if (!classObj) + return false; + + const ResourceClassObject *parentClassObj=Universe::getInstance().getResourceClassByName(myParentResourceClass); + if (!parentClassObj) + return false; + + return classObj->isDerivedFrom(*parentClassObj); +} + +// ---------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsResourceNamespace::getResourceTypeByName(JNIEnv * /*env*/, jobject /*self*/, jstring typeName) +{ + std::string myTypeName; + JavaStringParam temp(typeName); + if (!JavaLibrary::convert(temp,myTypeName)) + return 0; + + ResourceTypeObject const * const typeObj = ServerUniverse::getInstance().getResourceTypeByName(myTypeName); + if (typeObj) + return (typeObj->getNetworkId()).getValue(); + else + { + WARNING(true,("getResourceTypeByName called for resource %s, which could not be found.",myTypeName.c_str())); + return 0; + } +} + +// ---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsResourceNamespace::getResourceContainerForType(JNIEnv * /*env*/, jobject /*self*/, jlong resourceType) +{ + ResourceTypeObject const * const typeObj = ServerUniverse::getInstance().getResourceTypeById(NetworkId(resourceType)); + if (!typeObj) + return NULL; + + std::string templateName; + typeObj->getCrateTemplate(templateName); + + return JavaString(Unicode::narrowToWide(templateName)).getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsResourceNamespace::getResourceName(JNIEnv * /*env*/, jobject /*self*/, jlong resourceType) +{ + if (resourceType == 0) + { + WARNING(true, ("JavaLibrary::getResourceName passed null resource type")); + return 0; + } + + ResourceTypeObject const * const rt = ServerUniverse::getInstance().getResourceTypeById(NetworkId(resourceType)); + if (!rt) + { + WARNING(true, ("JavaLibrary::getResourceName passed unknown resource type")); + return 0; + } + + JavaString resourceTypeName(rt->getResourceName()); + return resourceTypeName.getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsResourceNamespace::getResourceNames(JNIEnv *env, jobject self, jlongArray resourceTypes) +{ + if (resourceTypes == 0) + { + WARNING(true, ("JavaLibrary::getResourceNames passed null resource types")); + return 0; + } + + int count = env->GetArrayLength(resourceTypes); + LocalObjectArrayRefPtr names = createNewObjectArray(count, JavaLibrary::getClsString()); + jlong jlongTmp; + for (int i = 0; i < count; ++i) + { + env->GetLongArrayRegion(resourceTypes, i, 1, &jlongTmp); + LocalRef resName(getResourceName(env, self, jlongTmp)); + setObjectArrayElement(*names, i, resName); + } + + return names->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsResourceNamespace::getResourceClassName(JNIEnv *env, jobject self, jstring resourceClass) +{ + if (resourceClass == 0) + { + WARNING(true, ("JavaLibrary::getResourceClassName passed null resource class")); + return 0; + } + + JavaStringParam jresourceClass(resourceClass); + std::string resourceClassName; + if (!JavaLibrary::convert(jresourceClass, resourceClassName)) + { + WARNING(true, ("JavaLibrary::getResourceClassName cannot convert resource class name")); + return 0; + } + + const ServerResourceClassObject * resClass = safe_cast( + ServerUniverse::getInstance().getResourceClassByName(resourceClassName)); + if (resClass == NULL) + { + WARNING(true, ("JavaLibrary::getResourceClassName cannot find resource class for %s", resourceClassName.c_str())); + return 0; + } + + JavaString friendlyName("@" + resClass->getFriendlyName().getCanonicalRepresentation()); + return friendlyName.getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsResourceNamespace::getResourceClassNames(JNIEnv *env, jobject self, jobjectArray resourceClasses) +{ + if (resourceClasses == 0) + { + WARNING(true, ("JavaLibrary::getResourceClassNames passed null resource classes")); + return 0; + } + + int count = env->GetArrayLength(resourceClasses); + LocalObjectArrayRefPtr names = createNewObjectArray(count, JavaLibrary::getClsString()); + for (int i = 0; i < count; ++i) + { + LocalRef resClass(env->GetObjectArrayElement(resourceClasses, i)); + LocalRef resName(getResourceClassName(env, self, static_cast(resClass.getValue()))); + setObjectArrayElement(*names, i, resName); + } + + return names->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jlongArray JNICALL ScriptMethodsResourceNamespace::getResourceTypes(JNIEnv * env, jobject /*self*/, jstring resourceClass) +{ + if (resourceClass == 0) + { + WARNING(true, ("JavaLibrary::getResourceTypes passed null resource class")); + return 0; + } + + JavaStringParam jresourceClass(resourceClass); + std::string resourceClassName; + if (!JavaLibrary::convert(jresourceClass, resourceClassName)) + { + WARNING(true, ("JavaLibrary::getResourceTypes cannot convert resource class name")); + return 0; + } + + const ServerResourceClassObject * resClass = safe_cast( + ServerUniverse::getInstance().getResourceClassByName(resourceClassName)); + if (resClass == NULL) + { + WARNING(true, ("JavaLibrary::getResourceTypes cannot find resource class for %s", resourceClassName.c_str())); + return 0; + } + + std::vector types; + resClass->getResourceTypes(types); + + size_t count = types.size(); + + LocalLongArrayRefPtr jtypes = createNewLongArray(count); + if (jtypes == LocalLongArrayRef::cms_nullPtr) + { + WARNING(true, ("JavaLibrary::getResourceTypes cannot create obj_id array of size %d", count)); + return 0; + } + + jlong jlongTmp; + for (size_t i = 0; i < count; ++i) + { + if (types[i] != NULL) + { + jlongTmp = (types[i]->getNetworkId()).getValue(); + setLongArrayRegion(*jtypes, i, 1, &jlongTmp); + } + } + return jtypes->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsResourceNamespace::getResourceClass(JNIEnv * /*env*/, jobject /*self*/, jlong resourceType) +{ + if (resourceType == 0) + { + WARNING(true, ("JavaLibrary::getResourceClass passed null resource type")); + return 0; + } + + ResourceTypeObject const * const rt = ServerUniverse::getInstance().getResourceTypeById(NetworkId(resourceType)); + if (!rt) + { + WARNING(true, ("JavaLibrary::getResourceClass passed unknown resource type")); + return 0; + } + + ResourceClassObject const & resourceClass = rt->getParentClass(); + + JavaString resourceClassName(resourceClass.getResourceClassName()); + return resourceClassName.getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsResourceNamespace::getResourceParentClass(JNIEnv * /*env*/, jobject /*self*/, jstring resourceClass) +{ + if (resourceClass == 0) + { + WARNING(true, ("JavaLibrary::getResourceParentClass passed null resource class")); + return 0; + } + + JavaStringParam jresourceClass(resourceClass); + std::string resourceClassName; + if (!JavaLibrary::convert(jresourceClass, resourceClassName)) + { + WARNING(true, ("JavaLibrary::getResourceParentClass cannot convert resource class name")); + return 0; + } + + const ResourceClassObject * resClass = ServerUniverse::getInstance().getResourceClassByName(resourceClassName); + if (resClass == NULL) + { + WARNING(true, ("JavaLibrary::getResourceParentClass cannot find resource class for %s", resourceClassName.c_str())); + return 0; + } + + const ResourceClassObject * parentClass = resClass->getParent(); + if (parentClass == NULL) + return 0; + + JavaString parentClassName(parentClass->getResourceClassName()); + return parentClassName.getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsResourceNamespace::getResourceChildClasses(JNIEnv * env, jobject /*self*/, jstring resourceClass) +{ + if (resourceClass == 0) + { + WARNING(true, ("JavaLibrary::getResourceChildClasses passed null resource class")); + return 0; + } + + JavaStringParam jresourceClass(resourceClass); + std::string resourceClassName; + if (!JavaLibrary::convert(jresourceClass, resourceClassName)) + { + WARNING(true, ("JavaLibrary::getResourceChildClasses cannot convert resource class name")); + return 0; + } + + const ResourceClassObject * resClass = ServerUniverse::getInstance().getResourceClassByName(resourceClassName); + if (resClass == NULL) + { + WARNING(true, ("JavaLibrary::getResourceChildClasses cannot find resource class for %s", resourceClassName.c_str())); + return 0; + } + + std::vector children; + resClass->getChildren(children, true); + + size_t count = children.size(); + LocalObjectArrayRefPtr childrenArray = createNewObjectArray(static_cast(count), JavaLibrary::getClsString()); + for (size_t i = 0; i < count; ++i) + { + if (children[i] != NULL) + { + JavaString name(children[i]->getResourceClassName()); + setObjectArrayElement(*childrenArray, static_cast(i), name); + } + } + return childrenArray->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsResourceNamespace::getImmediateResourceChildClasses(JNIEnv *env, jobject self, jstring resourceClass) +{ + if (resourceClass == 0) + { + WARNING(true, ("JavaLibrary::getImmediateResourceChildClasses passed null resource class")); + return 0; + } + + JavaStringParam jresourceClass(resourceClass); + std::string resourceClassName; + if (!JavaLibrary::convert(jresourceClass, resourceClassName)) + { + WARNING(true, ("JavaLibrary::getImmediateResourceChildClasses cannot convert resource class name")); + return 0; + } + + const ResourceClassObject * resClass = ServerUniverse::getInstance().getResourceClassByName(resourceClassName); + if (resClass == NULL) + { + WARNING(true, ("JavaLibrary::getImmediateResourceChildClasses cannot find resource class for %s", resourceClassName.c_str())); + return 0; + } + + std::vector children; + resClass->getChildren(children, false); + + int count = children.size(); + LocalObjectArrayRefPtr childrenArray = createNewObjectArray(count, JavaLibrary::getClsString()); + for (int i = 0; i < count; ++i) + { + if (children[i] != NULL) + { + JavaString name(children[i]->getResourceClassName()); + setObjectArrayElement(*childrenArray, i, name); + } + } + return childrenArray->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsResourceNamespace::getLeafResourceChildClasses(JNIEnv *env, jobject self, jstring resourceClass) +{ + if (resourceClass == 0) + { + WARNING(true, ("JavaLibrary::getLeafResourceChildClasses passed null resource class")); + return 0; + } + + JavaStringParam jresourceClass(resourceClass); + std::string resourceClassName; + if (!JavaLibrary::convert(jresourceClass, resourceClassName)) + { + WARNING(true, ("JavaLibrary::getLeafResourceChildClasses cannot convert resource class name")); + return 0; + } + + const ResourceClassObject * resClass = ServerUniverse::getInstance().getResourceClassByName(resourceClassName); + if (resClass == NULL) + { + WARNING(true, ("JavaLibrary::getLeafResourceChildClasses cannot find resource class for %s", resourceClassName.c_str())); + return 0; + } + + std::vector children; + resClass->getLeafChildren(children); + + int count = children.size(); + LocalObjectArrayRefPtr childrenArray = createNewObjectArray(count, JavaLibrary::getClsString()); + for (int i = 0; i < count; ++i) + { + if (children[i] != NULL) + { + JavaString name(children[i]->getResourceClassName()); + setObjectArrayElement(*childrenArray, i, name); + } + } + return childrenArray->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsResourceNamespace::hasResourceType(JNIEnv *env, jobject self, jstring resourceClass) +{ + if (resourceClass == 0) + { + WARNING(true, ("JavaLibrary::hasResourceType passed null resource class")); + return JNI_FALSE; + } + + JavaStringParam jresourceClass(resourceClass); + std::string resourceClassName; + if (!JavaLibrary::convert(jresourceClass, resourceClassName)) + { + WARNING(true, ("JavaLibrary::hasResourceType cannot convert resource class name")); + return JNI_FALSE; + } + + ServerResourceClassObject const * const resClass = safe_cast(ServerUniverse::getInstance().getResourceClassByName(resourceClassName)); + if (resClass == NULL) + { + WARNING(true, ("JavaLibrary::hasResourceType cannot find resource class for %s", resourceClassName.c_str())); + return JNI_FALSE; + } + + return (resClass->hasDerivedResourceType()) ? static_cast(JNI_TRUE) : static_cast(JNI_FALSE); +} + +// ---------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsResourceNamespace::createResourceCrate(JNIEnv * /*env*/, jobject /*self*/, jlong resourceType, jint amount, jlong destination) +{ + if (resourceType == 0) + { + WARNING(true, ("JavaLibrary::createResourceCrate passed null resource type")); + return 0; + } + + if (destination == 0) + { + WARNING(true, ("JavaLibrary::createResourceCrate passed null destination")); + return 0; + } + + if (amount <= 0) + { + WARNING(true, ("JavaLibrary::createResourceCrate passed amount %d <= 0", amount)); + return 0; + } + + ResourceTypeObject const * const rt = ServerUniverse::getInstance().getResourceTypeById(NetworkId(resourceType)); + if (!rt) + { + WARNING(true, ("JavaLibrary::createResourceCrate passed unknown resource type")); + return 0; + } + + ServerObject * container = NULL; + if (!JavaLibrary::getObject(destination, container)) + { + WARNING(true, ("JavaLibrary::createResourceCrate cannot find destination object")); + return 0; + } + + std::string crateTemplateName; + rt->getCrateTemplate(crateTemplateName); + + ServerObject * object = ServerWorld::createNewObject(crateTemplateName, *container, true); + if (object == NULL) + { + WARNING(true, ("JavaLibrary::createResourceCrate cannot create crate from template %s", crateTemplateName.c_str())); + return 0; + } + + ResourceContainerObject * crate = dynamic_cast(object); + if (crate == NULL) + { + IGNORE_RETURN(object->permanentlyDestroy(DeleteReasons::SetupFailed)); + WARNING(true, ("JavaLibrary::createResourceCrate crate %s is not a resource container", crateTemplateName.c_str())); + return 0; + } + + IGNORE_RETURN(crate->addResource(rt->getNetworkId(), amount, NetworkId::cms_invalid)); + + // cause the new crate to auto-combine with anything else in the container + crate = safe_cast(container->combineResourceContainers(*crate)); + + return (crate->getNetworkId()).getValue(); +} + +// ---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsResourceNamespace::requestResourceList(JNIEnv * env, jobject /*self*/, jobject loc, jfloat minDensity, jfloat maxDensity, jstring resourceClass) +{ + if (loc == 0) + { + WARNING(true, ("JavaLibrary::requestResourceList passed null location")); + return 0; + } + + if (resourceClass == 0) + { + WARNING(true, ("JavaLibrary::requestResourceList passed null resource class")); + return 0; + } + + if (minDensity > maxDensity) + { + WARNING(true, ("JavaLibrary::requestResourceList minDensity %f > maxDensity %f", minDensity, maxDensity)); + return 0; + } + + JavaStringParam jresourceClass(resourceClass); + std::string resourceClassName; + if (!JavaLibrary::convert(jresourceClass, resourceClassName)) + { + WARNING(true, ("JavaLibrary::requestResourceList passed unknown resource class")); + return 0; + } + + Location location; + if (!ScriptConversion::convert(LocalRefParam(loc), location)) + { + WARNING(true, ("JavaLibrary::requestResourceList cannot convert Java location to C")); + return 0; + } + const Vector & locationPos = location.getCoordinates(); + + const PlanetObject * planet = ServerUniverse::getInstance().getPlanetByName(location.getSceneId()); + if (planet == NULL) + { + WARNING(true, ("JavaLibrary::requestResourceList cannot find planet %s", location.getSceneId())); + return 0; + } + + // get the resource class and all its children + ServerResourceClassObject const * const resClass = safe_cast(ServerUniverse::getInstance().getResourceClassByName(resourceClassName)); + if (resClass == NULL) + { + WARNING(true, ("JavaLibrary::requestResourceList cannot find resource class %s", resourceClassName.c_str())); + return 0; + } + + std::vector types; + resClass->getAllDerivedResourceTypes(types); + + // create parallel vectors to store the resource types and their densities in + std::vector goodTypes; + std::vector goodDensities; + goodTypes.reserve(types.size()); + goodDensities.reserve(types.size()); + + // for each resource type, see if its density is in the desired range, and + // add it to goodTypes/goodDensities if it is + for (std::vector::const_iterator i=types.begin(); i!=types.end(); ++i) + { + if (!(*i)->isDepleted()) + { + ResourcePoolObject const * const pool = (*i)->getPoolForPlanet(*planet); + if (pool != NULL) + { + float density = pool->getEfficiencyAtLocation(locationPos.x, locationPos.z); + if (density >= minDensity && density <= maxDensity) + { + goodTypes.push_back(*i); + goodDensities.push_back(density); + } + } + } + } + + size_t count = goodTypes.size(); + LocalObjectArrayRefPtr densityArray = createNewObjectArray(count, JavaLibrary::getClsResourceDensity()); + if (densityArray == LocalObjectArrayRef::cms_nullPtr) + { + WARNING(true, ("JavaLibrary::requestResourceList cannot create resource density array of size %d", count)); + return 0; + } + + { + for (size_t i = 0; i < count; ++i) + { + LocalRefPtr densityObject = allocObject(JavaLibrary::getClsResourceDensity()); + if (densityObject != LocalRef::cms_nullPtr) + { + LocalRefPtr oid = JavaLibrary::getObjId(goodTypes[i]->getNetworkId()); + setObjectField(*densityObject, JavaLibrary::getFidResourceDensityResourceType(), *oid); + setFloatField(*densityObject, JavaLibrary::getFidResourceDensityDensity(), goodDensities[i]); + setObjectArrayElement(*densityArray, i, *densityObject); + } + } + } + + return densityArray->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsResourceNamespace::getResourceAttributes(JNIEnv * env, jobject /*self*/, jlong resourceType) +{ + ResourceTypeObject const * const resourceTypeObject = ServerUniverse::getInstance().getResourceTypeById(NetworkId(resourceType)); + if (!resourceTypeObject) + { + WARNING(true, ("JavaLibrary::getResourceAttributes passed invalid resource type %s",NetworkId(resourceType).getValueString().c_str())); + return 0; + } + + const std::map & attribs = resourceTypeObject->getResourceAttributes(); + + LocalObjectArrayRefPtr attribArray = createNewObjectArray(attribs.size(), JavaLibrary::getClsResourceAttribute()); + if (attribArray == LocalObjectArrayRef::cms_nullPtr) + { + WARNING(true, ("JavaLibrary::getResourceAttributes could not create Java resource array of size %u", attribs.size())); + return 0; + } + + int j = 0; + for (std::map::const_iterator i = attribs.begin(); i != attribs.end(); ++i, ++j) + { + const std::pair & data = *i; + JavaString name(data.first); + + LocalRefPtr attrib = allocObject(JavaLibrary::getClsResourceAttribute()); + if (attrib == LocalRef::cms_nullPtr) + { + WARNING(true, ("JavaLibrary::getResourceAttributes could not allocate memory for a Java resource_attribute")); + return 0; + } + + setObjectField(*attrib, JavaLibrary::getFidResourceAttributeName(), name); + setIntField(*attrib, JavaLibrary::getFidResourceAttributeValue(), data.second); + setObjectArrayElement(*attribArray, j, *attrib); + } + + return attribArray->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsResourceNamespace::getScaledResourceAttributes(JNIEnv * env, jobject /*self*/, jlong resourceType, jstring resourceClass) +{ + // convert the params to C + ResourceTypeObject const * const resourceTypeObject = ServerUniverse::getInstance().getResourceTypeById(NetworkId(resourceType)); + if (!resourceTypeObject) + { + WARNING(true, ("JavaLibrary::getScaledResourceAttributes passed invalid resource type %s",NetworkId(resourceType).getValueString().c_str())); + return 0; + } + + JavaStringParam jresourceClass(resourceClass); + std::string resourceClassName; + if (!JavaLibrary::convert(jresourceClass, resourceClassName)) + { + WARNING(true, ("JavaLibrary::getScaledResourceAttributes cannot convert resource class name")); + return 0; + } + ServerResourceClassObject const * const resClass = safe_cast(ServerUniverse::getInstance().getResourceClassByName(resourceClassName)); + if (resClass == NULL) + { + WARNING(true, ("JavaLibrary::getScaledResourceAttributes cannot find resource class %s", resourceClassName.c_str())); + return 0; + } + + // make sure the resource type is derived from the resource class + if (!resourceTypeObject->isDerivedFrom(*resClass)) + { + WARNING(true, ("JavaLibrary::getScaledResourceAttributes passed resource " + "type %s that is not derived from resource class %s", + resourceTypeObject->getResourceName().c_str(), resourceClassName.c_str())); + return 0; + } + + // rescale the resource type values to 1-1000, based on the resource class ranges + std::map attribs(resourceTypeObject->getResourceAttributes()); + { + const ServerResourceClassObject::ResourceAttributeRangesType & classAttribs = resClass->getResourceAttributeRanges(); + for (std::map::iterator i = attribs.begin(); i != attribs.end(); ++i) + { + ServerResourceClassObject::ResourceAttributeRangesType::const_iterator found = classAttribs.find((*i).first); + if (found != classAttribs.end()) + { + int const min = (*found).second.first; + int const max = (*found).second.second; + if ((max != min) && (max > 0)) + { + int scaledAttrib = ((*i).second * 1000) / max; + if (((*i).second * 1000) % max) + ++scaledAttrib; + + if (scaledAttrib > 1000) + scaledAttrib = 1000; + else if (scaledAttrib < 1) + scaledAttrib = 1; + + DEBUG_LOG("crafting", ("Scaled resource %s attrib %s from %d to %d\n", + resourceTypeObject->getResourceName().c_str(), (*i).first.c_str(), + (*i).second, scaledAttrib)); + (*i).second = scaledAttrib; + } + } + else + { + WARNING(true, ("JavaLibrary::getScaledResourceAttributes, resource " + "type %s has attribute %s that is not in resource class %s", + resourceTypeObject->getResourceName().c_str(), (*i).first.c_str(), + resourceClassName.c_str())); + } + + if ((*i).second > 1000) + (*i).second = 1000; + else if ((*i).second < 1) + (*i).second = 1; + } + } + + // conver the C data to Java + LocalObjectArrayRefPtr attribArray = createNewObjectArray(attribs.size(), JavaLibrary::getClsResourceAttribute()); + if (attribArray == LocalObjectArrayRef::cms_nullPtr) + { + WARNING(true, ("JavaLibrary::getScaledResourceAttributes could not create Java resource array of size %u", attribs.size())); + return 0; + } + + { + int j = 0; + for (std::map::const_iterator i = attribs.begin(); i != attribs.end(); ++i, ++j) + { + const std::pair & data = *i; + JavaString name(data.first); + + LocalRefPtr attrib = allocObject(JavaLibrary::getClsResourceAttribute()); + if (attrib == LocalRef::cms_nullPtr) + { + WARNING(true, ("JavaLibrary::getScaledResourceAttributes could not allocate memory for a Java resource_attribute")); + return 0; + } + + setObjectField(*attrib, JavaLibrary::getFidResourceAttributeName(), name); + setIntField(*attrib, JavaLibrary::getFidResourceAttributeValue(), data.second); + setObjectArrayElement(*attribArray, j, *attrib); + } + } + + return attribArray->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsResourceNamespace::getResourceAttribute(JNIEnv * /*env*/, jobject /*self*/, jlong resourceType, jstring attributeName) +{ + JavaStringParam jattributeName(attributeName); + std::string attributeNameStr; + if (!JavaLibrary::convert(jattributeName, attributeNameStr)) + { + WARNING(true, ("JavaLibrary::getResourceAttribute cannot convert attribute name")); + return -1; + } + + if (resourceType == 0) + { + WARNING(true, ("JavaLibrary::getResourceAttribute passed null resource type")); + return -1; + } + + ResourceTypeObject const * const resourceTypeObject = ServerUniverse::getInstance().getResourceTypeById(NetworkId(resourceType)); + if (!resourceTypeObject) + { + WARNING(true, ("JavaLibrary::getResourceAttribute passed invalid resource type %s",NetworkId(resourceType).getValueString().c_str())); + return -1; + } + + return (resourceTypeObject->getAttribute(attributeNameStr)); +} + +// ---------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsResourceNamespace::getRecycledVersionOfResourceType(JNIEnv * /*env*/, jobject /*self*/, jlong resourceType) +{ + ResourceTypeObject const * const resourceTypeObject = ServerUniverse::getInstance().getResourceTypeById(NetworkId(resourceType)); + ResourceTypeObject const * const recycledTypeObject = resourceTypeObject ? resourceTypeObject->getRecycledVersion() : NULL; + if (recycledTypeObject) + return (recycledTypeObject->getNetworkId()).getValue(); + else + return 0; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsResourceNamespace::isValidResourceId(JNIEnv * /*env*/, jobject /*self*/, jlong resourceType) +{ + if (resourceType == 0) + { + return JNI_FALSE; + } + + ResourceTypeObject const * const rt = ServerUniverse::getInstance().getResourceTypeById(NetworkId(resourceType)); + if (!rt) + { + return JNI_FALSE; + } + return JNI_TRUE; +} + +// ====================================================================== diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsScript.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsScript.cpp new file mode 100644 index 00000000..7d600707 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsScript.cpp @@ -0,0 +1,724 @@ +//======================================================================== +// +// ScriptMethodsScript.cpp - implements script methods dealing with scripts. +// +// copyright 2001 Sony Online Entertainment +// +//======================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "boost/smart_ptr.hpp" +#include "UnicodeUtils.h" +#include "serverGame/GameServer.h" +#include "serverGame/MessageToQueue.h" +#include "serverGame/ServerObject.h" +#include "serverGame/ServerWorld.h" +#include "serverScript/GameScriptObject.h" +#include "serverScript/ScriptMessage.h" +#include "serverUtility/ServerClock.h" +#include "sharedFoundation/CalendarTime.h" +#include "sharedFoundation/Crc.h" +#include "sharedNetworkMessages/GenericValueTypeMessage.h" + +using namespace JNIWrappersNamespace; + + +// ====================================================================== +// ScriptMethodsScriptNamespace +// ====================================================================== + +namespace ScriptMethodsScriptNamespace +{ + bool install(); + + jint JNICALL attachScript(JNIEnv *env, jobject self, jlong objId, jstring scriptName); + jboolean JNICALL detachScript(JNIEnv *env, jobject self, jlong objId, jstring scriptName); + jboolean JNICALL detachAllScripts(JNIEnv *env, jobject self, jlong objId); + jboolean JNICALL hasScript(JNIEnv *env, jobject self, jobject objId, jstring scriptName); + jboolean JNICALL reloadScriptFromScript(JNIEnv * env, jobject self, jstring scriptName); + jint JNICALL triggerScript(JNIEnv *env, jobject self, jlong object, jstring script, jint triggerId, jobjectArray params); + jboolean JNICALL localMessageTo(JNIEnv *env, jobject self, jlong receiver, jstring methodName, jobject params); + jboolean JNICALL remoteMessageTo(JNIEnv *env, jobject self, jlong receiver, jstring methodName, jbyteArray params, jfloat delay, jboolean guaranteed, jlong undeliveredCallbackObject, jstring undeliveredCallbackMethodName); + void JNICALL messageToPlayersOnPlanet(JNIEnv *env, jobject self, jstring methodName, jbyteArray params, jfloat delay, jobject loc, jfloat radius, jboolean includeDisconnectedPlayers); + jint JNICALL remoteMessageToCalendarTimeDayOfWeek(JNIEnv *env, jobject self, jlong receiver, jstring methodName, jbyteArray params, jint dayOfWeek, jint hour, jint minute, jint second); + jint JNICALL remoteMessageToCalendarTimeDayOfMonth(JNIEnv *env, jobject self, jlong receiver, jstring methodName, jbyteArray params, jint month, jint dayOfMonth, jint hour, jint minute, jint second); + void JNICALL recurringMessageTo(JNIEnv *env, jobject self, jlong receiver, jstring methodName, jbyteArray params, jfloat delay); + void JNICALL cancelRecurringMessageTo(JNIEnv *env, jobject self, jlong receiver, jstring methodName); + jint JNICALL timeUntilMessageTo(JNIEnv *env, jobject self, jlong object, jstring methodName); + jint JNICALL getServerFrame(JNIEnv * env, jobject self); + jint JNICALL getGameTimeSeconds(JNIEnv * env, jobject self); + jint JNICALL getCalendarTimeSeconds(JNIEnv * env, jobject self); + jint JNICALL getCalendarTimeSeconds2(JNIEnv * env, jobject self, jint year, jint month, jint day, jint hour, jint minute, jint second); + jstring JNICALL getCalendarTimeStringGMT(JNIEnv *env, jobject self, jint calendarTimeSeconds); + jstring JNICALL getCalendarTimeStringGMT_YYYYMMDDHHMMSS(JNIEnv *env, jobject self, jint calendarTimeSeconds); + jstring JNICALL getCalendarTimeStringLocal(JNIEnv *env, jobject self, jint calendarTimeSeconds); + jstring JNICALL getCalendarTimeStringLocal_YYYYMMDDHHMMSS(JNIEnv *env, jobject self, jint calendarTimeSeconds); + jint JNICALL secondsUntilCalendarTimeDayOfWeek(JNIEnv *env, jobject self, jint dayOfWeek, jint hour, jint minute, jint second); + jint JNICALL secondsUntilCalendarTimeDayOfMonth(JNIEnv *env, jobject self, jint month, jint dayOfMonth, jint hour, jint minute, jint second); +} + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsScriptNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsScriptNamespace::c)} + JF("_attachScript", "(JLjava/lang/String;)I", attachScript), + JF("_detachScript", "(JLjava/lang/String;)Z", detachScript), + JF("_detachAllScripts", "(J)Z", detachAllScripts), + JF("reloadScript", "(Ljava/lang/String;)Z", reloadScriptFromScript), + JF("_triggerScript", "(JLjava/lang/String;I[Ljava/lang/Object;)I", triggerScript), + JF("_localMessageTo", "(JLjava/lang/String;Lscript/dictionary;)Z", localMessageTo), + JF("_remoteMessageTo", "(JLjava/lang/String;[BFZJLjava/lang/String;)Z", remoteMessageTo), + JF("_messageToPlayersOnPlanet", "(Ljava/lang/String;[BFLscript/location;FZ)V", messageToPlayersOnPlanet), + JF("_remoteMessageTo", "(JLjava/lang/String;[BIIII)I", remoteMessageToCalendarTimeDayOfWeek), + JF("_remoteMessageTo", "(JLjava/lang/String;[BIIIII)I", remoteMessageToCalendarTimeDayOfMonth), + JF("_internalRecurringMessageTo", "(JLjava/lang/String;[BF)V", recurringMessageTo), + JF("_cancelRecurringMessageTo", "(JLjava/lang/String;)V", cancelRecurringMessageTo), + JF("_timeUntilMessageTo", "(JLjava/lang/String;)I", timeUntilMessageTo), + JF("getServerFrame", "()I", getServerFrame), + JF("getGameTime", "()I", getGameTimeSeconds), + JF("getCalendarTime", "()I", getCalendarTimeSeconds), + JF("getCalendarTime", "(IIIIII)I", getCalendarTimeSeconds2), + JF("getCalendarTimeStringGMT", "(I)Ljava/lang/String;", getCalendarTimeStringGMT), + JF("getCalendarTimeStringGMT_YYYYMMDDHHMMSS", "(I)Ljava/lang/String;", getCalendarTimeStringGMT_YYYYMMDDHHMMSS), + JF("getCalendarTimeStringLocal", "(I)Ljava/lang/String;", getCalendarTimeStringLocal), + JF("getCalendarTimeStringLocal_YYYYMMDDHHMMSS", "(I)Ljava/lang/String;", getCalendarTimeStringLocal_YYYYMMDDHHMMSS), + JF("secondsUntilCalendarTimeDayOfWeek", "(IIII)I", secondsUntilCalendarTimeDayOfWeek), + JF("secondsUntilCalendarTimeDayOfMonth", "(IIIII)I", secondsUntilCalendarTimeDayOfMonth), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +//======================================================================== +// class JavaLibrary JNI script callback methods +//======================================================================== + +/** + * Adds a script to an object. + * + * @param env Java environment + * @param self class calling this function + * @param objId id of class to attach the script to + * @param scriptName name of the script + * + * @return SCRIPT_CONTINUE on success, SCRIPT_OVERRIDE on error + */ +jint JNICALL ScriptMethodsScriptNamespace::attachScript(JNIEnv *env, jobject self, jlong objId, jstring scriptName) +{ + UNREF(self); + + JavaStringParam localScriptName(scriptName); + + ServerObject * object = 0; + if (!JavaLibrary::getObject(objId, object)) + return SCRIPT_OVERRIDE; + + GameScriptObject* scripts = object->getScriptObject(); + if (scripts == NULL) + return SCRIPT_OVERRIDE; + + char buffer[MAX_SCRIPT_NAME_LEN]; + localScriptName.fillBuffer(buffer, sizeof(buffer)); + + if (!*buffer) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("attachScript attempt to attach empty script name to [%s]", object->getNetworkId().getValueString().c_str())); + return SCRIPT_CONTINUE; + } + + if (scripts->hasScript(buffer)) + { + return SCRIPT_OVERRIDE; + } + + return scripts->attachScript(buffer, true); +} // JavaLibrary::attachScript + +/** + * Removes a script from an object. + * + * @param env Java environment + * @param self class calling this function + * @param objId id of class to detach the script from + * @param scriptName name of the script + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsScriptNamespace::detachScript(JNIEnv *env, jobject self, jlong objId, jstring scriptName) +{ + UNREF(self); + + JavaStringParam localScriptName(scriptName); + + ServerObject * object = 0; + if (!JavaLibrary::getObject(objId, object)) + return JNI_FALSE; + + GameScriptObject* scripts = object->getScriptObject(); + if (scripts == NULL) + return JNI_FALSE; + + char buffer[MAX_SCRIPT_NAME_LEN]; + localScriptName.fillBuffer(buffer, sizeof(buffer)); + + if (scripts->detachScript(buffer)) + return JNI_TRUE; + else + return JNI_FALSE; +} // JavaLibrary::detachScript + +/** + * Removes all scripts from an object. + * + * @param env Java environment + * @param self class calling this function + * @param objId id of class to detach the script from + * + * @return true if all the scripts were detached, false if not + */ +jboolean JNICALL ScriptMethodsScriptNamespace::detachAllScripts(JNIEnv *env, jobject self, jlong objId) +{ + UNREF(self); + + ServerObject * object = 0; + if (!JavaLibrary::getObject(objId, object)) + return JNI_FALSE; + + GameScriptObject* scriptObject = object->getScriptObject(); + if (scriptObject == NULL) + return JNI_FALSE; + + std::vector scriptNames; + scriptObject->enumerateScripts(scriptNames); + + // go through all the scripts and detach them + jboolean result = JNI_TRUE; + for (std::vector::const_iterator i = scriptNames.begin(); i != scriptNames.end(); ++i) + { + if (!scriptObject->detachScript(*i)) + result = JNI_FALSE; + } + return result; +} // JavaLibrary::detachAllScripts + +/** + * Checks if a class has a script. + * + * @param env Java environment + * @param self class calling this function + * @param objId id of class to check + * @param scriptName name of the script + * + * @return true on success, false on fail + */ +jboolean JNICALL ScriptMethodsScriptNamespace::hasScript(JNIEnv *env, jobject self, jobject objId, + jstring scriptName) +{ + UNREF(self); + + JavaStringParam localScriptName(scriptName); + + ServerObject* object = 0; + if (!JavaLibrary::getObject(objId, object)) + return JNI_FALSE; + + GameScriptObject* scripts = object->getScriptObject(); + if (scripts == NULL) + return JNI_FALSE; + + char buffer[MAX_SCRIPT_NAME_LEN]; + localScriptName.fillBuffer(buffer, sizeof(buffer)); + + if (scripts->hasScript(buffer)) + return JNI_TRUE; + return JNI_FALSE; +} // JavaLibrary::hasScript + +/** + * Executes a script trigger. + * + * @param env Java environment + * @param self class calling this function + * @param objId id of class to run the script from + * @param scriptName name of the script + * @param triggerId id of trigger to run + * @param params paramaters to send to the trigger + * + * @return results from calling script, or SCRIPT_OVERRIDE on error + */ +jint JNICALL ScriptMethodsScriptNamespace::triggerScript(JNIEnv *env, jobject self, jlong objId, jstring scriptName, jint triggerId, jobjectArray params) +{ + UNREF(self); + + JavaStringParam localScriptName(scriptName); + + // get the trigger info + if (triggerId < 0 || triggerId >= Scripting::TRIG_LAST_TRIGGER) + return SCRIPT_OVERRIDE; + Scripting::_ScriptFuncHashMap::const_iterator funcIter = Scripting::ScriptFuncHashMap->find(triggerId); + if (funcIter == Scripting::ScriptFuncHashMap->end()) + return SCRIPT_OVERRIDE; + const Scripting::ScriptFuncTable *func = (*funcIter).second; + + // get the object to run the script on + ServerObject* object = 0; + if (!JavaLibrary::getObject(objId, object)) + return SCRIPT_OVERRIDE; + + // convert the script name to ansii + char buffer[MAX_SCRIPT_NAME_LEN]; + localScriptName.fillBuffer(buffer, sizeof(buffer)); + + // run the script; note that we are not checking if the paramaters match the + // types given in ScriptFuncTable + return JavaLibrary::instance()->runScript(object->getNetworkId(), buffer, func->name, params); +} // JavaLibrary::triggerScript + + +//======================================================================== +// class JavaLibrary JNI messaging callback methods +//======================================================================== + +/** + * Sets up a timed message to be called on an object's script. + * + * @param env Java environment + * @param self class calling this function + * @param receiver object id of object the message is attached to + * @param methodName script method to be called when the message is signalled + * @param params parameters to be sent to the methodName + * @param delay time (in secs) before the message is signalled + * @param guaranteed flag to guarantee the message will be signaled (even if the object is unloaded) + * + * @return JNI_TRUE on success, JNI_FALSE on fail + */ +jboolean JNICALL ScriptMethodsScriptNamespace::localMessageTo(JNIEnv *env, jobject self, jlong receiver, jstring methodName, jobject params) +{ + UNREF(self); + + JavaStringParam localMethodName(methodName); + + if (receiver == 0 || methodName == 0 || params == 0) + return JNI_FALSE; + + if (!env->IsInstanceOf(params, JavaLibrary::getClsDictionary())) + return JNI_FALSE; + + jboolean result = JNI_FALSE; + std::string methodNameStdString; + if (JavaLibrary::convert(localMethodName, methodNameStdString)) + { + // get the receiver object + ServerObject * object = 0; + if (!(JavaLibrary::getObject(receiver, object) && object && object->isAuthoritative())) + { + DEBUG_WARNING(true,("localMessageTo called for an object which was not authoritative on this server.\n")); + result = JNI_FALSE; + } + else + { + GameScriptObject* scripts = object->getScriptObject(); + if (scripts == NULL) + return JNI_FALSE; + + ScriptDictionaryPtr dictionary(new JavaDictionary(params)); + scripts->handleMessage(methodNameStdString, dictionary); // was addMessage, changed name because it now fires right away + + result = JNI_TRUE; + } + } + return result; +} + +// ---------------------------------------------------------------------- + +/** + * Sets up a timed message to be called on an object's script. + * + * @param env Java environment + * @param self class calling this function + * @param receiver object id of object the message is attached to + * @param methodName script method to be called when the message is signalled + * @param params parameters to be sent to the methodName + * @param delay time (in secs) before the message is signalled + * @param guaranteed flag to guarantee the message will be signaled (even if the object is unloaded) + * + * @return JNI_TRUE on success, JNI_FALSE on fail + */ +jboolean JNICALL ScriptMethodsScriptNamespace::remoteMessageTo(JNIEnv *env, jobject self, jlong receiver, jstring methodName, jbyteArray params, jfloat delay, jboolean guaranteed, jlong undeliveredCallbackObject, jstring undeliveredCallbackMethodName) +{ + UNREF(self); + + JavaStringParam localMethodName(methodName); + std::string methodNameStdString; + if (!JavaLibrary::convert(localMethodName, methodNameStdString)) + return JNI_FALSE; + + std::string undeliveredCallbackMethodNameStdString; + if (undeliveredCallbackMethodName) + { + JavaStringParam temp(undeliveredCallbackMethodName); + if (!JavaLibrary::convert(temp, undeliveredCallbackMethodNameStdString)) + return JNI_FALSE; + } + + if (guaranteed==JNI_TRUE && !undeliveredCallbackMethodNameStdString.empty()) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("Sending message \"%s\" to object %s, the message was guaranteed but also had an undelivered callback specified.", methodNameStdString.c_str(), NetworkId(receiver).getValueString().c_str())); + return false; + } + + if (params != 0) + { + std::vector localParams; + if (!ScriptConversion::convert(params, localParams)) + return JNI_FALSE; + + // add crc info to the string so we can verify it when we get the message + if (!localParams.empty()) + { + MessageToQueue::getInstance().sendMessageToJava(NetworkId(receiver), methodNameStdString, localParams, static_cast(delay), guaranteed == JNI_TRUE, NetworkId(undeliveredCallbackObject), undeliveredCallbackMethodNameStdString); + } + } + else + { + MessageToQueue::getInstance().sendMessageToJava(NetworkId(receiver), methodNameStdString, std::vector(), static_cast(delay), guaranteed == JNI_TRUE, NetworkId(undeliveredCallbackObject), undeliveredCallbackMethodNameStdString); + } + + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- +/** +* "messageTo" for players on the current planet +* +* If you want everyone on the planet to receive the message, +* specify null for loc and -1.0f for radius; otherwise, specify +* a loc and a radius and only players on the planet within the +* specified area will receive the message +*/ +void JNICALL ScriptMethodsScriptNamespace::messageToPlayersOnPlanet(JNIEnv *env, jobject self, jstring methodName, jbyteArray params, jfloat delay, jobject loc, jfloat radius, jboolean includeDisconnectedPlayers) +{ + UNREF(self); + + JavaStringParam localMethodName(methodName); + std::string methodNameStdString; + if (!JavaLibrary::convert(localMethodName, methodNameStdString)) + return; + + std::vector localParams; + if (params) + { + if (!ScriptConversion::convert(params, localParams)) + return; + } + + Vector vectorLocation; + if (loc) + { + if (!ScriptConversion::convertWorld(loc, vectorLocation)) + return; + } + + // send to planet server for distribution to all game servers + // running this planet; each game server will then check for + // all players within the range and send the player the messageTo; + // we need to do this because the range could cover multiple game servers + GenericValueTypeMessage >, std::pair >, std::pair > > const m("MessageToPlayersOnPlanet", std::make_pair(std::make_pair(std::make_pair(methodNameStdString, localParams), std::make_pair(delay, (includeDisconnectedPlayers != JNI_FALSE))), std::make_pair(vectorLocation, (loc ? radius : -1.0f)))); + GameServer::getInstance().sendToPlanetServer(m); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsScriptNamespace::remoteMessageToCalendarTimeDayOfWeek(JNIEnv *env, jobject self, jlong receiver, jstring methodName, jbyteArray params, jint dayOfWeek, jint hour, jint minute, jint second) +{ + UNREF(self); + + JavaStringParam localMethodName(methodName); + std::string methodNameStdString; + if (!JavaLibrary::convert(localMethodName, methodNameStdString)) + return -1; + + // calculate the absolute time when the messageTo should go off + time_t const timeNow = ::time(NULL); + time_t const timeTarget = CalendarTime::getNextGMTTimeOcurrence(timeNow, dayOfWeek, hour, minute, second); + + if ((timeTarget <= 0) || (timeTarget <= timeNow)) + return -1; + + int const timeUntil = static_cast(timeTarget - timeNow); + + if (params != 0) + { + std::vector localParams; + if (!ScriptConversion::convert(params, localParams)) + return -1; + + // add crc info to the string so we can verify it when we get the message + if (!localParams.empty()) + { + MessageToQueue::getInstance().sendMessageToJava(NetworkId(receiver), methodNameStdString, localParams, std::max(static_cast(1), timeUntil + 2), false); + } + } + else + { + MessageToQueue::getInstance().sendMessageToJava(NetworkId(receiver), methodNameStdString, std::vector(), std::max(static_cast(1), timeUntil + 2), false); + } + + return timeUntil; +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsScriptNamespace::remoteMessageToCalendarTimeDayOfMonth(JNIEnv *env, jobject self, jlong receiver, jstring methodName, jbyteArray params, jint month, jint dayOfMonth, jint hour, jint minute, jint second) +{ + UNREF(self); + + JavaStringParam localMethodName(methodName); + std::string methodNameStdString; + if (!JavaLibrary::convert(localMethodName, methodNameStdString)) + return -1; + + // calculate the absolute time when the messageTo should go off + time_t const timeNow = ::time(NULL); + time_t const timeTarget = CalendarTime::getNextGMTTimeOcurrence(timeNow, month, dayOfMonth, hour, minute, second); + + if ((timeTarget <= 0) || (timeTarget <= timeNow)) + return -1; + + int const timeUntil = static_cast(timeTarget - timeNow); + + if (params != 0) + { + std::vector localParams; + if (!ScriptConversion::convert(params, localParams)) + return -1; + + // add crc info to the string so we can verify it when we get the message + if (!localParams.empty()) + { + MessageToQueue::getInstance().sendMessageToJava(NetworkId(receiver), methodNameStdString, localParams, std::max(static_cast(1), timeUntil + 2), false); + } + } + else + { + MessageToQueue::getInstance().sendMessageToJava(NetworkId(receiver), methodNameStdString, std::vector(), std::max(static_cast(1), timeUntil + 2), false); + } + + return timeUntil; +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsScriptNamespace::recurringMessageTo(JNIEnv * /*env*/, jobject /*self*/, jlong receiver, jstring methodName, jbyteArray params, jfloat delay) +{ + JavaStringParam localMethodName(methodName); + std::string methodNameStdString; + if (!JavaLibrary::convert(localMethodName, methodNameStdString)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::recurringMessageTo was not able to convert methodName into a string")); + return; + } + + if (params != 0) + { + std::vector localParams; + if (!ScriptConversion::convert(params, localParams) || localParams.empty()) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::recurringMessageTo was not able to convert params into a std::vector")); + return; + } + + MessageToQueue::getInstance().sendRecurringMessageToJava(NetworkId(receiver), methodNameStdString, localParams, static_cast(delay)); + } + else + MessageToQueue::getInstance().sendRecurringMessageToJava(NetworkId(receiver), methodNameStdString, std::vector(), static_cast(delay)); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsScriptNamespace::cancelRecurringMessageTo(JNIEnv *env, jobject self, jlong receiver, jstring methodName) +{ + JavaStringParam localMethodName(methodName); + std::string methodNameStdString; + if (!JavaLibrary::convert(localMethodName, methodNameStdString)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::cancelRecurringMessageTo was not able to convert methodName into a string")); + return; + } + + MessageToQueue::getInstance().cancelRecurringMessageTo(NetworkId(receiver), methodNameStdString); +} + +// ---------------------------------------------------------------------- +// returns the number of seconds until the messageTo fires, which *CAN* be 0 +// returns -1 if object doesn't have the messageTo +jint JNICALL ScriptMethodsScriptNamespace::timeUntilMessageTo(JNIEnv *env, jobject self, jlong object, jstring methodName) +{ + ServerObject const * so = NULL; + if (!JavaLibrary::getObject(object, so)) + return -1; + + JavaStringParam localMethodName(methodName); + std::string methodNameStdString; + if (!JavaLibrary::convert(localMethodName, methodNameStdString)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::timeUntilMessageTo was not able to convert methodName into a string")); + return -1; + } + + return so->timeUntilMessageTo(methodNameStdString); +} + +//----------------------------------------------------------------------- + +jint JNICALL ScriptMethodsScriptNamespace::getServerFrame(JNIEnv * env, jobject self) +{ + if(env == 0) + return 0; + + unsigned long t = ServerClock::getInstance().getServerFrame(); + return t; +} + +//----------------------------------------------------------------------- + +jint JNICALL ScriptMethodsScriptNamespace::getGameTimeSeconds(JNIEnv * env, jobject self) +{ + if(env == 0) + return 0; + + unsigned long t = ServerClock::getInstance().getGameTimeSeconds(); + return t; +} + +//----------------------------------------------------------------------- + +jint JNICALL ScriptMethodsScriptNamespace::getCalendarTimeSeconds(JNIEnv * env, jobject self) +{ + if(env == 0) + return 0; + + return ::time(NULL); +} + +//----------------------------------------------------------------------- + +jint JNICALL ScriptMethodsScriptNamespace::getCalendarTimeSeconds2(JNIEnv * env, jobject self, jint year, jint month, jint day, jint hour, jint minute, jint second) +{ + if(env == 0) + return -1; + + time_t const rawtime = ::time(NULL); + struct tm * timeinfo = ::localtime(&rawtime); + if (!timeinfo) + return -1; + + timeinfo->tm_year = year - 1900; + timeinfo->tm_mon = month - 1; + timeinfo->tm_mday = day; + timeinfo->tm_hour = hour; + timeinfo->tm_min = minute; + timeinfo->tm_sec = second; + + return ::mktime(timeinfo); +} + +//----------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsScriptNamespace::getCalendarTimeStringGMT(JNIEnv *env, jobject self, jint calendarTimeSeconds) +{ + if(env == 0) + return 0; + + return JavaString(CalendarTime::convertEpochToTimeStringGMT(calendarTimeSeconds)).getReturnValue(); +} + +//----------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsScriptNamespace::getCalendarTimeStringGMT_YYYYMMDDHHMMSS(JNIEnv *env, jobject self, jint calendarTimeSeconds) +{ + if(env == 0) + return 0; + + return JavaString(CalendarTime::convertEpochToTimeStringGMT_YYYYMMDDHHMMSS(calendarTimeSeconds)).getReturnValue(); +} + +//----------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsScriptNamespace::getCalendarTimeStringLocal(JNIEnv *env, jobject self, jint calendarTimeSeconds) +{ + if(env == 0) + return 0; + + return JavaString(CalendarTime::convertEpochToTimeStringLocal(calendarTimeSeconds)).getReturnValue(); +} + +//----------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsScriptNamespace::getCalendarTimeStringLocal_YYYYMMDDHHMMSS(JNIEnv *env, jobject self, jint calendarTimeSeconds) +{ + if(env == 0) + return 0; + + return JavaString(CalendarTime::convertEpochToTimeStringLocal_YYYYMMDDHHMMSS(calendarTimeSeconds)).getReturnValue(); +} + +//----------------------------------------------------------------------- + +jint JNICALL ScriptMethodsScriptNamespace::secondsUntilCalendarTimeDayOfWeek(JNIEnv *env, jobject self, jint dayOfWeek, jint hour, jint minute, jint second) +{ + UNREF(self); + + // calculate the time between now and the specified time + time_t const timeNow = ::time(NULL); + time_t const timeTarget = CalendarTime::getNextGMTTimeOcurrence(timeNow, dayOfWeek, hour, minute, second); + + if ((timeTarget <= 0) || (timeTarget <= timeNow)) + return -1; + + return static_cast(timeTarget - timeNow); +} + +//----------------------------------------------------------------------- + +jint JNICALL ScriptMethodsScriptNamespace::secondsUntilCalendarTimeDayOfMonth(JNIEnv *env, jobject self, jint month, jint dayOfMonth, jint hour, jint minute, jint second) +{ + UNREF(self); + + // calculate the time between now and the specified time + time_t const timeNow = ::time(NULL); + time_t const timeTarget = CalendarTime::getNextGMTTimeOcurrence(timeNow, month, dayOfMonth, hour, minute, second); + + if ((timeTarget <= 0) || (timeTarget <= timeNow)) + return -1; + + return static_cast(timeTarget - timeNow); +} + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsScriptNamespace::reloadScriptFromScript(JNIEnv * env, jobject self, jstring scriptName) +{ + jboolean result = JNI_FALSE; + + JavaStringParam localScriptName(scriptName); + std::string scriptNameStdString; + if (!JavaLibrary::convert(localScriptName, scriptNameStdString)) + return JNI_FALSE; + + if(GameScriptObject::reloadScript(scriptNameStdString)) + { + result = JNI_TRUE; + } + return result; +} + +//----------------------------------------------------------------------- diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsServerUI.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsServerUI.cpp new file mode 100644 index 00000000..db36bd13 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsServerUI.cpp @@ -0,0 +1,480 @@ +//----------------------------------------------------------------------- +// ScriptMethodsServerUI.cpp +// Copyright 2002, Sony Online Entertainment Inc., all rights reserved. +//----------------------------------------------------------------------- + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "serverGame/Client.h" +#include "serverGame/CreatureObject.h" +#include "serverGame/ServerObject.h" +#include "serverGame/ServerUIManager.h" +#include "serverGame/ServerUIPage.h" +#include "sharedGame/SuiPageData.h" + +#include "sharedUtility/ValueDictionary.h" + +// ====================================================================== +// ScriptMethodsServerUINamespace +// ====================================================================== + +namespace ScriptMethodsServerUINamespace +{ + bool install(); + + jint JNICALL createSuiPage (JNIEnv *env, jobject self, jstring pageName, jlong owner, jlong client); + jboolean JNICALL clearSuiDataSource (JNIEnv *env, jobject self, jint pageId, jstring dataSource); + jboolean JNICALL clearSuiDataSourceContainer(JNIEnv *env, jobject self, jint pageId, jstring dataSource); + jboolean JNICALL addSuiDataItem (JNIEnv *env, jobject self, jint pageId, jstring dataSource, jstring dataItemValue); + jboolean JNICALL addSuiDataSourceContainer (JNIEnv *env, jobject self, jint pageId, jstring dataSource, jstring dataItemValue); + jboolean JNICALL addSuiDataSource (JNIEnv *env, jobject self, jint pageId, jstring dataSource, jstring dataItemValue); + jboolean JNICALL addSuiChildWidget (JNIEnv *env, jobject self, jint pageId, jstring widgetType, jstring widgetName, jstring partentWidgetName); + jboolean JNICALL setSuiProperty (JNIEnv *env, jobject self, jint pageId, jstring widgetName, jstring propertyName, jstring propertyValue); + jboolean JNICALL subscribeToSuiEvent (JNIEnv *env, jobject self, jint pageId, jint eventType, jstring widgetName, jstring callback); + jboolean JNICALL subscribeToSuiPropertyForEvent (JNIEnv *env, jobject self, jint pageId, jint eventType, jstring eventWidgetName, jstring propertyWidgetName, jstring propertyName); + jboolean JNICALL showSuiPage (JNIEnv *env, jobject self, jint pageId); + jboolean JNICALL forceCloseSuiPage (JNIEnv *env, jobject self, jint pageId); + jboolean JNICALL setSuiAssociatedObject (JNIEnv *env, jobject self, jint pageId, jlong j_associatedObjectId); + jboolean JNICALL setSuiAssociatedLocation (JNIEnv *env, jobject self, jint pageId, jlong j_associatedObjectId); + jboolean JNICALL setSuiMaxRangeToObject (JNIEnv *env, jobject self, jint pageId, jfloat j_maxRange); + jboolean JNICALL clientMinigameOpen(JNIEnv *env, jobject self, jlong player, jobject data); + jboolean JNICALL clientMinigameClose(JNIEnv *env, jobject self, jlong player, jobject data); + +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsServerUINamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsServerUINamespace::c)} + JF("_createSUIPage", "(Ljava/lang/String;JJ)I", createSuiPage), + JF("clearSUIDataSource", "(ILjava/lang/String;)Z", clearSuiDataSource), + JF("clearSUIDataSourceContainer", "(ILjava/lang/String;)Z", clearSuiDataSourceContainer), + JF("addSUIDataItem", "(ILjava/lang/String;Ljava/lang/String;)Z", addSuiDataItem), + JF("addSUIDataSourceContainer", "(ILjava/lang/String;Ljava/lang/String;)Z", addSuiDataSourceContainer), + JF("addSUIDataSource", "(ILjava/lang/String;Ljava/lang/String;)Z", addSuiDataSource), + JF("addSUIChildWidget", "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z", addSuiChildWidget), + JF("setSUIProperty", "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z", setSuiProperty), + JF("subscribeToSUIEvent", "(IILjava/lang/String;Ljava/lang/String;)Z", subscribeToSuiEvent), + JF("subscribeToSUIPropertyForEvent", "(IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z", subscribeToSuiPropertyForEvent), + JF("showSUIPage", "(I)Z", showSuiPage), + JF("forceCloseSUIPage", "(I)Z", forceCloseSuiPage), + JF("_setSUIAssociatedObject", "(IJ)Z", setSuiAssociatedObject), + JF("_setSUIAssociatedLocation", "(IJ)Z", setSuiAssociatedLocation), + JF("setSUIMaxRangeToObject", "(IF)Z", setSuiMaxRangeToObject), + JF("_clientMinigameOpen", "(JLscript/dictionary;)Z", clientMinigameOpen), + JF("_clientMinigameClose", "(JLscript/dictionary;)Z", clientMinigameClose), + +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +//----------------------------------------------------------------------- + +jint JNICALL ScriptMethodsServerUINamespace::createSuiPage(JNIEnv *env, jobject self, jstring pageName, jlong ownerobject, jlong client) +{ + JavaStringParam localPageName(pageName); + + jint failureCode = -1; + ServerObject* owner = NULL; + if(!JavaLibrary::getObject(ownerobject, owner)) + { + WARNING(true, ("SUI: couldn't get owner ServerObject*, can't create a page")); + return failureCode; + } + + ServerObject* so = NULL; + if(!JavaLibrary::getObject(client, so)) + return failureCode; + + std::string pn; + JavaLibrary::convert(localPageName, pn); + + //Still going to check for client even though we don't use it anymore -- ARH + Client* const c = so->getClient(); + if(!c) + { + WARNING(true, ("SUI: couldn't get Client object [%s], can't create a page [%s]", + so->getDebugInformation(false).c_str(), pn.c_str())); + return failureCode; + } + + //make a serverui page for the given client + int const pId = ServerUIManager::createPage(pn, *owner, so->getNetworkId()); + //fail if can't create page + if(pId == -1) + { + WARNING(true, ("SUI: ServerManager::createPage could not create a SUI page")); + return failureCode; + } + return pId; +} + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsServerUINamespace::clearSuiDataSource(JNIEnv *env, jobject self, jint pageId, jstring dataSource) +{ + JavaStringParam localDataSource(dataSource); + + ServerUIPage * const p = ServerUIManager::getPage(pageId); + if(!p) + { + DEBUG_WARNING(true, ("SUI: Could not find page %d, cannot clear datasource", pageId)); + return JNI_FALSE; + } + + std::string ds; + JavaLibrary::convert(localDataSource, ds); + + p->clearDataSource(ds); + return JNI_TRUE; +} + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsServerUINamespace::clearSuiDataSourceContainer(JNIEnv * env, jobject self, jint pageId, jstring dataSourceContainer) +{ + JavaStringParam localDataSource(dataSourceContainer); + + ServerUIPage * const p = ServerUIManager::getPage(pageId); + if(!p) + { + DEBUG_WARNING(true, ("SUI: Could not find page %d, cannot clear datasource", pageId)); + return JNI_FALSE; + } + + std::string ds; + JavaLibrary::convert(localDataSource, ds); + + p->clearDataSourceContainer(ds); + return JNI_TRUE; +} + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsServerUINamespace::addSuiDataItem(JNIEnv *env, jobject self, jint pageId, jstring dataSource, jstring dataItemValue) +{ + JavaStringParam localDataSource(dataSource); + JavaStringParam localDataItemValue(dataItemValue); + + ServerUIPage* p = ServerUIManager::getPage(pageId); + if(!p) + { + DEBUG_WARNING(true, ("SUI: Could not find page %d, cannot add the item", pageId)); + return JNI_FALSE; + } + + std::string ds; + JavaLibrary::convert(localDataSource, ds); + + Unicode::String div; + JavaLibrary::convert(localDataItemValue, div); + + std::string din = "Name"; + p->addDataItem(ds, din, div); + return JNI_TRUE; +} + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsServerUINamespace::addSuiDataSourceContainer(JNIEnv *env, jobject self, jint pageId, jstring dataSource, jstring dataItemValue) +{ + JavaStringParam localDataSource(dataSource); + JavaStringParam localDataItemValue(dataItemValue); + + ServerUIPage* p = ServerUIManager::getPage(pageId); + if(!p) + { + DEBUG_WARNING(true, ("SUI: Could not find page %d, cannot add the item", pageId)); + return JNI_FALSE; + } + + std::string ds; + JavaLibrary::convert(localDataSource, ds); + + Unicode::String div; + JavaLibrary::convert(localDataItemValue, div); + + std::string din = "Name"; + p->addDataSourceContainer(ds, din, div); + return JNI_TRUE; +} + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsServerUINamespace::addSuiDataSource(JNIEnv *env, jobject self, jint pageId, jstring dataSource, jstring dataItemValue) +{ + JavaStringParam localDataSource(dataSource); + JavaStringParam localDataItemValue(dataItemValue); + + ServerUIPage* p = ServerUIManager::getPage(pageId); + if(!p) + { + DEBUG_WARNING(true, ("SUI: Could not find page %d, cannot add the item", pageId)); + return JNI_FALSE; + } + + std::string ds; + JavaLibrary::convert(localDataSource, ds); + + Unicode::String div; + JavaLibrary::convert(localDataItemValue, div); + + std::string din = "Name"; + p->addDataSource(ds, din, div); + return JNI_TRUE; +} + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsServerUINamespace::addSuiChildWidget(JNIEnv *env, jobject self, jint pageId, jstring widgetType, jstring widgetName, jstring parentWidgetName) +{ + JavaStringParam localWidgetType(widgetType); + JavaStringParam localWidgetName(widgetName); + JavaStringParam localParentWidgetName(parentWidgetName); + + ServerUIPage* p = ServerUIManager::getPage(pageId); + if(!p) + { + DEBUG_WARNING(true, ("SUI: Could not find page %d, cannot add a child widget", pageId)); + return JNI_FALSE; + } + + std::string wt; + JavaLibrary::convert(localWidgetType, wt); + std::string wn; + JavaLibrary::convert(localWidgetName, wn); + std::string pwn; + JavaLibrary::convert(localParentWidgetName, pwn); + + p->addChildWidget(wt, wn, pwn); + return JNI_TRUE; +} + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsServerUINamespace::setSuiProperty(JNIEnv *env, jobject self, jint pageId, jstring widgetName, jstring propertyName, jstring propertyValue) +{ + JavaStringParam localWidgetName(widgetName); + JavaStringParam localPropertyName(propertyName); + JavaStringParam localPropertyValue(propertyValue); + + ServerUIPage* p = ServerUIManager::getPage(pageId); + if(!p) + { + DEBUG_WARNING(true, ("SUI: Could not find page %d, cannot set the property", pageId)); + return JNI_FALSE; + } + + std::string wn; + JavaLibrary::convert(localWidgetName, wn); + std::string pn; + JavaLibrary::convert(localPropertyName, pn); + Unicode::String pv; + JavaLibrary::convert(localPropertyValue, pv); + + p->setProperty(wn, pn, pv); + return JNI_TRUE; +} + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsServerUINamespace::subscribeToSuiEvent(JNIEnv *env, jobject self, jint pageId, jint eventType, jstring eventWidgetName, jstring callback) +{ + ServerUIPage* p = ServerUIManager::getPage(pageId); + if(!p) + { + DEBUG_WARNING(true, ("SUI: Could not find page %d, cannot subscribe to the property", pageId)); + return JNI_FALSE; + } + + std::string ewn; + if (eventWidgetName != NULL) + { + JavaStringParam localEventWidgetName(eventWidgetName); + JavaLibrary::convert(localEventWidgetName, ewn); + } + + JavaStringParam localCallback(callback); + + std::string cb; + JavaLibrary::convert(localCallback, cb); + + p->getPageData().subscribeToEvent(eventType, ewn, cb); + return JNI_TRUE; +} +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsServerUINamespace::subscribeToSuiPropertyForEvent(JNIEnv *env, jobject self, jint pageId, jint eventType, jstring eventWidgetName, jstring propertyWidgetName, jstring propertyName) +{ + + ServerUIPage* p = ServerUIManager::getPage(pageId); + if(!p) + { + DEBUG_WARNING(true, ("SUI: Could not find page %d, cannot subscribe to the property", pageId)); + return JNI_FALSE; + } + + std::string ewn; + if (eventWidgetName != NULL) + { + JavaStringParam localEventWidgetName(eventWidgetName); + JavaLibrary::convert(localEventWidgetName, ewn); + } + + JavaStringParam localPropertyWidgetName(propertyWidgetName); + JavaStringParam localPropertyName(propertyName); + + std::string pwn; + JavaLibrary::convert(localPropertyWidgetName, pwn); + + std::string pn; + JavaLibrary::convert(localPropertyName, pn); + + p->getPageData().subscribeToPropertyForEvent(eventType, ewn, pwn, pn); + return JNI_TRUE; +} + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsServerUINamespace::showSuiPage(JNIEnv *env, jobject self, jint pageId) +{ + if (ServerUIManager::showPage(pageId)) + return JNI_TRUE; + + return JNI_FALSE; +} + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsServerUINamespace::forceCloseSuiPage(JNIEnv *env, jobject self, jint pageId) +{ + bool result = ServerUIManager::closePage(pageId); + if(result) + return JNI_TRUE; + else + { + DEBUG_WARNING(true, ("SUI: Couldn't force close the page", pageId)); + return JNI_FALSE; + } +} + +//---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsServerUINamespace::setSuiAssociatedObject(JNIEnv *env, jobject self, jint pageId, jlong j_associatedObjectId) +{ + ServerUIPage * const p = ServerUIManager::getPage(pageId); + if(!p) + { + DEBUG_WARNING(true, ("Could not find page %d, cannot set property", pageId)); + return JNI_FALSE; + } + + if (!j_associatedObjectId) + { + DEBUG_WARNING(true, ("bad associatedObjectId sent to setAssociatedObject", pageId)); + return JNI_FALSE; + } + + NetworkId id(j_associatedObjectId); + if (id == NetworkId::cms_invalid) + { + DEBUG_WARNING(true, ("could not convert associatedObjectid", pageId)); + return JNI_FALSE; + } + + p->setAssociatedObjectId (id); + return JNI_TRUE; +} + +//---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsServerUINamespace::setSuiAssociatedLocation(JNIEnv *env, jobject self, jint pageId, jlong j_associatedObjectId) +{ + ServerUIPage * const p = ServerUIManager::getPage(pageId); + if(!p) + { + DEBUG_WARNING(true, ("Could not find page %d, cannot set property", pageId)); + return JNI_FALSE; + } + + if (!j_associatedObjectId) + { + DEBUG_WARNING(true, ("bad associatedObjectId sent to setAssociatedObject")); + return JNI_FALSE; + } + + ServerObject* associatedObject = NULL; + if(!JavaLibrary::getObject(j_associatedObjectId, associatedObject)) + { + DEBUG_WARNING(true, ("could not find object for associatedObjectid")); + return JNI_FALSE; + } + + p->setAssociatedLocation (associatedObject->findPosition_w()); + return JNI_TRUE; +} + +//---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsServerUINamespace::setSuiMaxRangeToObject(JNIEnv *env, jobject self, jint pageId, jfloat j_maxRange) +{ + ServerUIPage * const p = ServerUIManager::getPage(pageId); + if(!p) + { + DEBUG_WARNING(true, ("Could not find page %d, cannot set property", pageId)); + return JNI_FALSE; + } + + p->setMaxRangeFromObject (j_maxRange); + return JNI_TRUE; +} + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsServerUINamespace::clientMinigameOpen(JNIEnv *env, jobject self, jlong player, jobject data) +{ + ServerObject* playerServerObject = NULL; + if(!JavaLibrary::getObject(player, playerServerObject)) + return JNI_FALSE; + + CreatureObject * creatureObject = playerServerObject->asCreatureObject(); + if(creatureObject != NULL) + { + ValueDictionary gameData; + JavaLibrary::convert(data, gameData); + + creatureObject->clientMinigameOpen(gameData); + return JNI_TRUE; + } + + return JNI_FALSE; +} + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsServerUINamespace::clientMinigameClose(JNIEnv *env, jobject self, jlong player, jobject data) +{ + ServerObject* playerServerObject = NULL; + if(!JavaLibrary::getObject(player, playerServerObject)) + return JNI_FALSE; + + CreatureObject * creatureObject = playerServerObject->asCreatureObject(); + if(creatureObject != NULL) + { + ValueDictionary gameData; + JavaLibrary::convert(data, gameData); + + creatureObject->clientMinigameClose(gameData); + return JNI_TRUE; + } + + return JNI_FALSE; +} diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsShip.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsShip.cpp new file mode 100644 index 00000000..988e3cb1 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsShip.cpp @@ -0,0 +1,4162 @@ +// ====================================================================== +// +// ScriptMethodsShip.cpp +// Copyright 2003, Sony Online Entertainment, Inc. +// All rights reserved. +// +// ====================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "UnicodeUtils.h" +#include "serverGame/AiShipController.h" +#include "serverGame/ConfigServerGame.h" +#include "serverGame/ConnectionServerConnection.h" +#include "serverGame/ContainerInterface.h" +#include "serverGame/CreatureObject.h" +#include "serverGame/GameServer.h" +#include "serverGame/MiningAsteroidController.h" +#include "serverGame/Missile.h" +#include "serverGame/MissileManager.h" +#include "serverGame/Pvp.h" +#include "serverGame/ServerObjectTemplate.h" +#include "serverGame/ServerWorld.h" +#include "serverGame/ShipInternalDamageOverTime.h" +#include "serverGame/ShipInternalDamageOverTimeManager.h" +#include "serverGame/ShipObject.h" +#include "serverGame/SpaceVisibilityManager.h" +#include "serverNetworkMessages/GameConnectionServerMessages.h" +#include "sharedNetworkMessages/MessageQueueShipHit.h" +#include "sharedFoundation/ConstCharCrcLowerString.h" +#include "sharedFoundation/ConstCharCrcString.h" +#include "sharedFoundation/Crc.h" +#include "sharedFoundation/GameControllerMessage.h" +#include "sharedGame/Nebula.h" +#include "sharedGame/NebulaManager.h" +#include "sharedGame/ShipChassis.h" +#include "sharedGame/ShipChassisSlot.h" +#include "sharedGame/ShipComponentData.h" +#include "sharedGame/ShipComponentDescriptor.h" +#include "sharedGame/ShipComponentWeaponManager.h" +#include "sharedNetworkMessages/DestroyShipComponentMessage.h" +#include "sharedNetworkMessages/DestroyShipMessage.h" +#include "sharedNetworkMessages/GameNetworkMessage.h" +#include "sharedNetworkMessages/GenericValueTypeMessage.h" +#include "sharedNetworkMessages/MessageQueueGenericValueType.h" +#include "sharedNetworkMessages/ShipDamageMessage.h" +#include "sharedObject/Appearance.h" +#include "sharedObject/CellProperty.h" +#include "sharedObject/Controller.h" +#include "sharedObject/NetworkIdManager.h" +#include "sharedObject/ObjectTemplateList.h" + +using namespace JNIWrappersNamespace; + + +// ====================================================================== + +namespace ScriptMethodsShipNamespace +{ + bool verifyShipsEnabled() + { + if (!ConfigServerGame::getShipsEnabled()) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("Ship support is not enabled. Make sure [GameServer] shipsEnabled=1 is in your config file.")); + return false; + } + + return true; + } + + ShipChassisSlotType::Type getSlotType(int slotType) + { + if(slotType < ShipChassisSlotType::SCST_first || slotType > ShipChassisSlotType::SCST_num_types) + return ShipChassisSlotType::SCST_num_types; + else + return static_cast(slotType); + } + + //---------------------------------------------------------------------- + + ShipObject * const getShipThrowTestSlot(JNIEnv * env, jlong jobject_shipId, char const * const functionName, bool throwIfNotOnServer, int chassisSlot) + { + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return NULL; + + char buf[256]; + snprintf(buf, sizeof(buf), "JavaLibrary::%s: ship obj_id did not resolve to a ShipObject", functionName); + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, buf, throwIfNotOnServer); + if (!shipObject) + return NULL; + + if (chassisSlot != ShipChassisSlotType::SCST_num_types && !shipObject->isSlotInstalled(chassisSlot)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::%s chassisSlot [%d] not installed", functionName, chassisSlot)); + + return shipObject; + } + + //---------------------------------------------------------------------- + + void sendGameNetworkMessageToObservers(ServerObject const & sourceObject, GameNetworkMessage const & message, bool sendToSourceObject) + { + // send the projectile to all clients observing the owner except the owner + // time is in the context of the connection server's sync stamp, so we need a unique message per connection server + typedef std::map > DistributionList; + DistributionList distributionList; + + //-- Build distribution list of clients observing object, but don't include the client doing the firing + { + typedef std::set ObserverList; + ObserverList const & observers = sourceObject.getObservers(); + for (ObserverList::const_iterator iter = observers.begin(); iter != observers.end(); ++iter) + { + Client * const client = *iter; + if (sendToSourceObject || client != sourceObject.getClient()) + distributionList[client->getConnection()].push_back(client->getCharacterObjectId()); + } + } + + //-- Send message to distribution list + { + for (DistributionList::const_iterator iter = distributionList.begin(); iter != distributionList.end(); ++iter) + { + GameClientMessage const gameClientMessage(iter->second, true, message); + iter->first->send(gameClientMessage, true); + } + } + } + + bool install(); + + jboolean JNICALL pilotShip(JNIEnv *env, jobject self, jlong pilotId, jlong shipIdId); + jboolean JNICALL unpilotShip(JNIEnv *env, jobject self, jlong pilotId); + jlong JNICALL getShipPilot(JNIEnv * env, jobject self, jlong shipId); + jlong JNICALL getPilotedShip(JNIEnv * env, jobject self, jlong pilotId); + jboolean JNICALL getShipHasWings(JNIEnv * env, jobject self, jlong shipId); + jfloat JNICALL getShipCurrentSpeed(JNIEnv * env, jobject self, jlong shipId); + jboolean JNICALL setShipSlideDampener(JNIEnv * env, jobject self, jlong shipId, jfloat slideDampener); + jfloat JNICALL getShipSlideDampener(JNIEnv * env, jobject self, jlong shipId); + jboolean JNICALL setShipCurrentYaw(JNIEnv * env, jobject self, jlong shipId, jfloat currentYaw); + jfloat JNICALL getShipCurrentYaw(JNIEnv * env, jobject self, jlong shipId); + jboolean JNICALL setShipCurrentPitch(JNIEnv * env, jobject self, jlong shipId, jfloat currentPitch); + jfloat JNICALL getShipCurrentPitch(JNIEnv * env, jobject self, jlong shipId); + jboolean JNICALL setShipCurrentRoll(JNIEnv * env, jobject self, jlong shipId, jfloat currentRoll); + jfloat JNICALL getShipCurrentRoll(JNIEnv * env, jobject self, jlong shipId); + jboolean JNICALL setShipCurrentChassisHitPoints(JNIEnv * env, jobject self, jlong shipId, jfloat currentChassisHitPoints); + jfloat JNICALL getShipCurrentChassisHitPoints(JNIEnv * env, jobject self, jlong shipId); + jboolean JNICALL setShipMaximumChassisHitPoints(JNIEnv * env, jobject self, jlong shipId, jfloat maximumChassisHitPoints); + jfloat JNICALL getShipMaximumChassisHitPoints(JNIEnv * env, jobject self, jlong shipId); + jboolean JNICALL launchMissile(JNIEnv * env, jobject self, jlong player, jlong ship, jlong target, jint missileInfo, jint targetedComponent); + jboolean JNICALL launchCountermeasure(JNIEnv * env, jobject self, jlong ship, jint targettedMissile, jboolean successful, jint countermeasureType); + jint JNICALL getNearestUnlockedMissileForTarget(JNIEnv * env, jobject self, jlong target); + jintArray JNICALL getAllUnlockedMissilesForTarget(JNIEnv * env, jobject self, jlong jtarget); + jboolean JNICALL destroyMissile(JNIEnv * env, jobject self, jint missileId); + jint JNICALL getTypeByMissile(JNIEnv * env, jobject self, jint missileId); + jint JNICALL getWeaponIndexByMissile(JNIEnv * env, jobject self, jint missileId); + jint JNICALL getTimeSinceFiredByMissile(JNIEnv * env, jobject self, jint missileId); + jint JNICALL getTotalTimeByMissile(JNIEnv * env, jobject self, jint missileId); + jlong JNICALL getWhoFiredByMissile(JNIEnv * env, jobject self, jint missileId); + jboolean JNICALL setLookAtTargetShipComponent(JNIEnv * env, jobject self, jlong ship, jint targetedComponent); + jint JNICALL getLookAtTargetShipComponent(JNIEnv * env, jobject self, jlong ship); + jlongArray JNICALL getObservedShips(JNIEnv *env, jobject self, jlong jsource, jboolean excludeSource); + jlongArray JNICALL getObservedPlayerShips(JNIEnv *env, jobject self, jlong jsource, jboolean excludeSource); + jlongArray JNICALL getObservedEnemyShips(JNIEnv *env, jobject self, jlong jsource); + jlongArray JNICALL getObservedEnemyPlayerShips(JNIEnv *env, jobject self, jlong jsource); + void JNICALL notifyShipDamage(JNIEnv * env, jobject self, jlong victim, jlong attacker, jfloat totalDamage); + jfloat JNICALL getShipChassisSpeedMaximumModifier (JNIEnv * env, jobject self, jlong shipId); + void JNICALL setShipChassisSpeedMaximumModifier (JNIEnv * env, jobject self, jlong shipId, jfloat value); + jfloat JNICALL getShipActualAccelerationRate (JNIEnv * env, jobject self, jlong shipId); + jfloat JNICALL getShipActualDecelerationRate (JNIEnv * env, jobject self, jlong shipId); + jfloat JNICALL getShipActualPitchAccelerationRateDegrees (JNIEnv * env, jobject self, jlong shipId); + jfloat JNICALL getShipActualYawAccelerationRateDegrees (JNIEnv * env, jobject self, jlong shipId); + jfloat JNICALL getShipActualRollAccelerationRateDegrees (JNIEnv * env, jobject self, jlong shipId); + jfloat JNICALL getShipActualPitchRateMaximumDegrees (JNIEnv * env, jobject self, jlong shipId); + jfloat JNICALL getShipActualYawRateMaximumDegrees (JNIEnv * env, jobject self, jlong shipId); + jfloat JNICALL getShipActualRollRateMaximumDegrees (JNIEnv * env, jobject self, jlong shipId); + jfloat JNICALL getShipActualSpeedMaximum (JNIEnv * env, jobject self, jlong shipId); + jstring JNICALL getShipChassisType (JNIEnv * env, jobject self, jlong shipId); + jfloat JNICALL getChassisComponentMassCurrent (JNIEnv * env, jobject self, jlong shipId); + jfloat JNICALL getChassisComponentMassMaximum (JNIEnv * env, jobject self, jlong shipId); + jboolean JNICALL setChassisComponentMassMaximum (JNIEnv * env, jobject self, jlong shipId, jfloat chassisComponentMassMaximum); + jboolean JNICALL isShipSlotInstalled (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot); + jboolean JNICALL isShipComponentDisabled (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot); + jboolean JNICALL isShipComponentLowPower (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot); + jboolean JNICALL isShipComponentDisabledNeedsPower (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot); + jfloat JNICALL getShipComponentArmorHitpointsMaximum (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot); + jfloat JNICALL getShipComponentArmorHitpointsCurrent (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot); + jfloat JNICALL getShipComponentEfficiencyGeneral (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot); + jfloat JNICALL getShipComponentEfficiencyEnergy (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot); + jfloat JNICALL getShipComponentEnergyMaintenanceRequirement (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot); + jfloat JNICALL getShipComponentMass (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot); + jint JNICALL getShipComponentCrc (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot); + jfloat JNICALL getShipComponentHitpointsCurrent (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot); + jfloat JNICALL getShipComponentHitpointsMaximum (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot); + jint JNICALL getShipComponentFlags (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot); + jstring JNICALL getShipComponentName (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot); + jfloat JNICALL getShipWeaponDamageMaximum (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot); + jfloat JNICALL getShipWeaponDamageMinimum (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot); + jfloat JNICALL getShipWeaponEffectivenessShields (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot); + jfloat JNICALL getShipWeaponEffectivenessArmor (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot); + jfloat JNICALL getShipWeaponEnergyPerShot (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot); + jfloat JNICALL getShipWeaponRefireRate (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot); + jfloat JNICALL getShipWeaponActualRefireRate (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot); + jfloat JNICALL getShipWeaponEfficiencyRefireRate (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot); + jint JNICALL getShipWeaponAmmoCurrent (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot); + jint JNICALL getShipWeaponAmmoMaximum (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot); + jint JNICALL getShipWeaponAmmoType (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot); + jfloat JNICALL getShipShieldHitpointsFrontCurrent (JNIEnv * env, jobject self, jlong shipId); + jfloat JNICALL getShipShieldHitpointsFrontMaximum (JNIEnv * env, jobject self, jlong shipId); + jfloat JNICALL getShipShieldHitpointsBackCurrent (JNIEnv * env, jobject self, jlong shipId); + jfloat JNICALL getShipShieldHitpointsBackMaximum (JNIEnv * env, jobject self, jlong shipId); + jfloat JNICALL getShipShieldRechargeRate (JNIEnv * env, jobject self, jlong shipId); + jfloat JNICALL getShipCapacitorEnergyCurrent (JNIEnv * env, jobject self, jlong shipId); + jfloat JNICALL getShipCapacitorEnergyMaximum (JNIEnv * env, jobject self, jlong shipId); + jfloat JNICALL getShipCapacitorEnergyRechargeRate (JNIEnv * env, jobject self, jlong shipId); + jfloat JNICALL getShipEngineAccelerationRate (JNIEnv * env, jobject self, jlong shipId); + jfloat JNICALL getShipEngineDecelerationRate (JNIEnv * env, jobject self, jlong shipId); + jfloat JNICALL getShipEnginePitchAccelerationRateDegrees (JNIEnv * env, jobject self, jlong shipId); + jfloat JNICALL getShipEngineYawAccelerationRateDegrees (JNIEnv * env, jobject self, jlong shipId); + jfloat JNICALL getShipEngineRollAccelerationRateDegrees (JNIEnv * env, jobject self, jlong shipId); + jfloat JNICALL getShipEnginePitchRateMaximumDegrees (JNIEnv * env, jobject self, jlong shipId); + jfloat JNICALL getShipEngineYawRateMaximumDegrees (JNIEnv * env, jobject self, jlong shipId); + jfloat JNICALL getShipEngineRollRateMaximumDegrees (JNIEnv * env, jobject self, jlong shipId); + jfloat JNICALL getShipEngineSpeedMaximum (JNIEnv * env, jobject self, jlong shipId); + jfloat JNICALL getShipEngineSpeedRotationFactorMaximum (JNIEnv * env, jobject self, jlong shipId); + jfloat JNICALL getShipEngineSpeedRotationFactorMinimum (JNIEnv * env, jobject self, jlong shipId); + jfloat JNICALL getShipEngineSpeedRotationFactorOptimal (JNIEnv * env, jobject self, jlong shipId); + jfloat JNICALL getShipReactorEnergyGenerationRate (JNIEnv * env, jobject self, jlong shipId); + jfloat JNICALL getShipBoosterEnergyCurrent (JNIEnv * env, jobject self, jlong shipId); + jfloat JNICALL getShipBoosterEnergyMaximum (JNIEnv * env, jobject self, jlong shipId); + jfloat JNICALL getShipBoosterEnergyRechargeRate (JNIEnv * env, jobject self, jlong shipId); + jfloat JNICALL getShipBoosterEnergyConsumptionRate (JNIEnv * env, jobject self, jlong shipId); + jfloat JNICALL getShipBoosterAcceleration (JNIEnv * env, jobject self, jlong shipId); + jfloat JNICALL getShipBoosterSpeedMaximum (JNIEnv * env, jobject self, jlong shipId); + jboolean JNICALL isShipBoosterActive (JNIEnv * env, jobject self, jlong shipId); + jfloat JNICALL getShipDroidInterfaceCommandSpeed (JNIEnv * env, jobject self, jlong shipId); + int JNICALL getShipCargoHoldContentsMaximum (JNIEnv * env, jobject self, jlong shipId); + int JNICALL getShipCargoHoldContentsCurrent (JNIEnv * env, jobject self, jlong shipId); + void JNICALL setShipComponentArmorHitpointsMaximum (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot, jfloat componentArmorHitpointsMaximum); + void JNICALL setShipComponentArmorHitpointsCurrent (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot, jfloat componentArmorHitpointsCurrent); + void JNICALL setShipComponentEfficiencyGeneral (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot, jfloat componentEfficiencyGeneral); + void JNICALL setShipComponentEfficiencyEnergy (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot, jfloat componentEfficiencyEnergy); + void JNICALL setShipComponentEnergyMaintenanceRequirement (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot, jfloat componentEnergyMaintenanceRequirement); + void JNICALL setShipComponentMass (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot, jfloat componentMass); + void JNICALL setShipComponentHitpointsCurrent (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot, jfloat componentHitpointsCurrent); + void JNICALL setShipComponentHitpointsMaximum (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot, jfloat componentHitpointsMaximum); + void JNICALL setShipComponentFlags (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot, jint componentFlags); + void JNICALL setShipComponentName (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot, jstring componentName); + void JNICALL setShipComponentDisabled (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot, jboolean componentDisabled); + void JNICALL setShipComponentLowPower (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot, jboolean componentLowPower); + void JNICALL setShipComponentDisabledNeedsPower (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot, jboolean componentDisabledNeedsPower); + void JNICALL setShipWeaponDamageMaximum (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot, jfloat weaponDamageMaximum); + void JNICALL setShipWeaponDamageMinimum (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot, jfloat weaponDamageMinimum); + void JNICALL setShipWeaponEffectivenessShields (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot, jfloat weaponEffectivenessShields); + void JNICALL setShipWeaponEffectivenessArmor (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot, jfloat weaponEffectivenessArmor); + void JNICALL setShipWeaponEnergyPerShot (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot, jfloat weaponEnergyPerShot); + void JNICALL setShipWeaponRefireRate (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot, jfloat weaponRefireRate); + void JNICALL setShipWeaponEfficiencyRefireRate (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot, jfloat weaponEfficiencyRefireRate); + void JNICALL setShipWeaponAmmoCurrent (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot, jint ammoCurrent); + void JNICALL setShipWeaponAmmoMaximum (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot, jint ammoMaximum); + void JNICALL setShipWeaponAmmoType (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot, jint ammoType); + void JNICALL setShipShieldHitpointsFrontCurrent (JNIEnv * env, jobject self, jlong shipId, jfloat shieldHitpointsFrontCurrent); + void JNICALL setShipShieldHitpointsFrontMaximum (JNIEnv * env, jobject self, jlong shipId, jfloat shieldHitpointsFrontMaximum); + void JNICALL setShipShieldHitpointsBackCurrent (JNIEnv * env, jobject self, jlong shipId, jfloat shieldHitpointsBackCurrent); + void JNICALL setShipShieldHitpointsBackMaximum (JNIEnv * env, jobject self, jlong shipId, jfloat shieldHitpointsBackMaximum); + void JNICALL setShipShieldRechargeRate (JNIEnv * env, jobject self, jlong shipId, jfloat shieldRechargeRate); + void JNICALL setShipCapacitorEnergyCurrent (JNIEnv * env, jobject self, jlong shipId, jfloat capacitorEnergyCurrent); + void JNICALL setShipCapacitorEnergyMaximum (JNIEnv * env, jobject self, jlong shipId, jfloat capacitorEnergyMaximum); + void JNICALL setShipCapacitorEnergyRechargeRate (JNIEnv * env, jobject self, jlong shipId, jfloat capacitorEnergyRechargeRate); + void JNICALL setShipEngineAccelerationRate (JNIEnv * env, jobject self, jlong shipId, jfloat engineAccelerationRate); + void JNICALL setShipEngineDecelerationRate (JNIEnv * env, jobject self, jlong shipId, jfloat engineDecelerationRate); + void JNICALL setShipEnginePitchAccelerationRateDegrees (JNIEnv * env, jobject self, jlong shipId, jfloat enginePitchAccelerationRateDegrees); + void JNICALL setShipEngineYawAccelerationRateDegrees (JNIEnv * env, jobject self, jlong shipId, jfloat engineYawAccelerationRateDegrees); + void JNICALL setShipEngineRollAccelerationRateDegrees (JNIEnv * env, jobject self, jlong shipId, jfloat engineRollAccelerationRateDegrees); + void JNICALL setShipEnginePitchRateMaximumDegrees (JNIEnv * env, jobject self, jlong shipId, jfloat enginePitchRateMaximumDegrees); + void JNICALL setShipEngineYawRateMaximumDegrees (JNIEnv * env, jobject self, jlong shipId, jfloat engineYawRateMaximumDegrees); + void JNICALL setShipEngineRollRateMaximumDegrees (JNIEnv * env, jobject self, jlong shipId, jfloat engineRollRateMaximumDegrees); + void JNICALL setShipEngineSpeedMaximum (JNIEnv * env, jobject self, jlong shipId, jfloat engineSpeedMaximum); + void JNICALL setShipEngineSpeedRotationFactorMaximum (JNIEnv * env, jobject self, jlong shipId, jfloat engineSpeedRotationFactorMaximum); + void JNICALL setShipEngineSpeedRotationFactorMinimum (JNIEnv * env, jobject self, jlong shipId, jfloat engineSpeedRotationFactorMinimum); + void JNICALL setShipEngineSpeedRotationFactorOptimal (JNIEnv * env, jobject self, jlong shipId, jfloat engineSpeedRotationFactorOptimal); + void JNICALL setShipReactorEnergyGenerationRate (JNIEnv * env, jobject self, jlong shipId, jfloat reactorEnergyGenerationRate); + void JNICALL setShipBoosterEnergyCurrent (JNIEnv * env, jobject self, jlong shipId, jfloat boosterEnergyCurrent); + void JNICALL setShipBoosterEnergyMaximum (JNIEnv * env, jobject self, jlong shipId, jfloat boosterEnergyMaximum); + void JNICALL setShipBoosterEnergyRechargeRate (JNIEnv * env, jobject self, jlong shipId, jfloat boosterEnergyRechargeRate); + void JNICALL setShipBoosterEnergyConsumptionRate (JNIEnv * env, jobject self, jlong shipId, jfloat boosterEnergyConsumptionRate); + void JNICALL setShipBoosterAcceleration (JNIEnv * env, jobject self, jlong shipId, jfloat boosterAcceleration); + void JNICALL setShipBoosterSpeedMaximum (JNIEnv * env, jobject self, jlong shipId, jfloat boosterSpeedMaximum); + void JNICALL setShipDroidInterfaceCommandSpeed (JNIEnv * env, jobject self, jlong shipId, jfloat droidInterfaceCommandSpeed); + void JNICALL setShipCargoHoldContentsMaximum (JNIEnv * env, jobject self, jlong shipId, jint contentsMaximum); + void JNICALL setShipCargoHoldContent (JNIEnv * env, jobject self, jlong shipId, jlong resourceTypeId, jint amount); + jint JNICALL getShipCargoHoldContent (JNIEnv * env, jobject self, jlong shipId, jlong resourceTypeId); + jlongArray JNICALL getShipCargoHoldContentsResourceTypes (JNIEnv * env, jobject self, jlong shipId); + jintArray JNICALL getShipCargoHoldContentsAmounts (JNIEnv * env, jobject self, jlong shipId); + jboolean JNICALL shipCanInstallComponent (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot, jlong component); + jboolean JNICALL shipPseudoInstallComponent (JNIEnv * env, jobject self, jlong jship, jint chassisSlot, jint componentCrc); + jboolean JNICALL shipInstallComponent (JNIEnv * env, jobject self, jlong installerId, jlong shipId, jint chassisSlot, jlong component); + jlong JNICALL shipUninstallComponent (JNIEnv * env, jobject self, jlong uninstallerId, jlong shipId, jint chassisSlot, jlong containerTarget); + // allow an uninstalled component to overflow the container. + jlong JNICALL shipUninstallComponentAllowOverload (JNIEnv * env, jobject self, jlong uninstallerId, jlong shipId, jint chassisSlot, jlong containerTarget); + jlong JNICALL shipUninstallComponentBase (JNIEnv * env, jobject self, jlong uninstallerId, jlong shipId, jint chassisSlot, jlong containerTarget, bool allowOverload); + jintArray JNICALL getShipChassisSlots (JNIEnv * env, jobject self, jlong shipId); + void JNICALL setShipSlotTargetable (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot, jboolean targetable); + jboolean JNICALL isShipSlotTargetable (JNIEnv * env, jobject self, jlong shipId, jint chassisSlot); + jint JNICALL getShipComponentDescriptorType (JNIEnv * env, jobject self, jlong component); + jint JNICALL getShipComponentDescriptorTypeByName (JNIEnv * env, jobject self, jstring typeName); + jstring JNICALL getShipComponentDescriptorTypeName (JNIEnv * env, jobject self, jint componentType); + jint JNICALL getShipComponentDescriptorCrc (JNIEnv * env, jobject self, jlong component); + jstring JNICALL getShipComponentDescriptorCrcName (JNIEnv * env, jobject self, jint componentCrc); + jstring JNICALL getShipComponentDescriptorCompatibility (JNIEnv * env, jobject self, jint componentCrc); + jboolean JNICALL getShipComponentDescriptorWeaponIsAmmoConsuming (JNIEnv * env, jobject self, jint componentCrc); + jboolean JNICALL getShipComponentDescriptorWeaponIsMissile (JNIEnv * env, jobject self, jint componentCrc); + jboolean JNICALL getShipComponentDescriptorWeaponIsCountermeasure (JNIEnv * env, jobject self, jint componentCrc); + jboolean JNICALL getShipComponentDescriptorWeaponIsMining (JNIEnv * env, jobject self, jint componentCrc); + jboolean JNICALL getShipComponentDescriptorWeaponIsTractor (JNIEnv * env, jobject self, jint componentCrc); + jfloat JNICALL getShipComponentDescriptorWeaponRange (JNIEnv * env, jobject self, jint componentCrc); + jfloat JNICALL getShipComponentDescriptorWeaponProjectileSpeed (JNIEnv * env, jobject self, jint componentCrc); + jlong JNICALL getDroidControlDeviceForShip (JNIEnv * env, jobject self, jlong jship); + jboolean JNICALL associateDroidControlDeviceWithShip (JNIEnv * env, jobject self, jlong jship, jlong jdroidControlDevice); + jboolean JNICALL removeDroidControlDeviceFromShip (JNIEnv * env, jobject self, jlong jship); + jlong JNICALL launchShipFromHangar (JNIEnv * env, jobject self, jlong jshipId, jstring templateToSpawn, jobject deltaFromHangarHardpoint); + void JNICALL commPlayers (JNIEnv * env, jobject self, jlong jtaunter, jstring appearanceOverloadServerTemplate, jstring soundeffect, jfloat duration, jlongArray jplayers, jstring jtauntOob, jboolean chronicles); + void JNICALL handleShipDestruction(JNIEnv * env, jobject self, jlong ship, jfloat severity); + void JNICALL handleShipComponentDestruction(JNIEnv * env, jobject self, jlong ship, jint chassisSlot, jfloat severity); + jboolean JNICALL setShipInternalDamageOverTime(JNIEnv * env, jobject self, jlong ship, jint chassisSlot, jfloat damageRate, jfloat damageThreshold); + jboolean JNICALL removeShipInternalDamageOverTime(JNIEnv * env, jobject self, jlong ship, jint chassisSlot); + jfloat JNICALL getShipInternalDamageOverTimeDamageRate(JNIEnv * env, jobject self, jlong ship, jint chassisSlot); + jfloat JNICALL getShipInternalDamageOverTimeDamageThreshold(JNIEnv * env, jobject self, jlong ship, jint chassisSlot); + jboolean JNICALL hasShipInternalDamageOverTime(JNIEnv * env, jobject self, jlong ship, jint chassisSlot); + jint JNICALL shipGetSpaceFaction(JNIEnv *env, jobject self, jlong jship); + jintArray JNICALL shipGetSpaceFactionAllies(JNIEnv *env, jobject self, jlong jship); + jintArray JNICALL shipGetSpaceFactionEnemies(JNIEnv *env, jobject self, jlong jship); + jboolean JNICALL shipGetSpaceFactionIsAggro(JNIEnv *env, jobject self, jlong jship); + void JNICALL shipSetSpaceFaction(JNIEnv *env, jobject self, jlong jship, jint spaceFaction); + void JNICALL shipSetSpaceFactionAllies(JNIEnv *env, jobject self, jlong jship, jintArray jfactionList); + void JNICALL shipSetSpaceFactionEnemies(JNIEnv *env, jobject self, jlong jship, jintArray jfactionList); + void JNICALL shipSetSpaceFactionIsAggro(JNIEnv *env, jobject self, jlong jship, jboolean isAggro); + jboolean JNICALL shipIsInNebula(JNIEnv *env, jobject self, jlong ship, jstring nebulaName); + jboolean JNICALL setShipWingName(JNIEnv *env, jobject self, jlong target, jstring str); + jstring JNICALL getShipWingName(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL setShipTypeName(JNIEnv *env, jobject self, jlong target, jstring str); + jstring JNICALL getShipTypeName(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL setShipDifficulty(JNIEnv *env, jobject self, jlong target, jstring str); + jstring JNICALL getShipDifficulty(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL setShipFaction(JNIEnv *env, jobject self, jlong target, jstring str); + jstring JNICALL getShipFaction(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL addMissionCriticalObject(JNIEnv *env, jobject self, jlong playerObjectId, jlong missionCriticalObjectId); + jboolean JNICALL removeMissionCriticalObject(JNIEnv *env, jobject self, jlong playerObjectId, jlong missionCriticalObjectId); + jboolean JNICALL clearMissionCriticalObjects(JNIEnv *env, jobject self, jlong playerObjectId); + jboolean JNICALL isMissionCriticalObject(JNIEnv *env, jobject self, jlong playerObjectId, jlong missionCriticalObjectId); + jstring JNICALL getShipComponentDebugString(JNIEnv * env, jobject self, jlong jobject_shipId, jint chassisSlot); + void JNICALL notifyShipHit(JNIEnv * env, jobject self, jlong jobject_shipId, jobject jobject_vectorUp_w, jobject jobject_vectorHitLocation_o, jint type, jfloat integrity, jfloat previousIntegrity); + void JNICALL setDynamicMiningAsteroidVelocity(JNIEnv * env, jobject self, jlong jobject_asteroidId, jobject jobject_velocity_w); + jobject JNICALL getDynamicMiningAsteroidVelocity(JNIEnv * env, jobject self, jlong jobject_asteroidId); + void JNICALL openSpaceMiningUi(JNIEnv * env, jobject self, jlong player, jlong spaceStation, jstring spaceStationName); +} + +using namespace ScriptMethodsShipNamespace; + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsShipNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsShipNamespace::c)} + JF("_pilotShip", "(JJ)Z", pilotShip), + JF("_unpilotShip", "(J)Z", unpilotShip), + JF("_getPilotId", "(J)J", getShipPilot), + JF("_getShipPilot", "(J)J", getShipPilot), + JF("_getPilotedShip", "(J)J", getPilotedShip), + JF("_getShipHasWings", "(J)Z", getShipHasWings), + JF("_getShipCurrentSpeed", "(J)F", getShipCurrentSpeed), + JF("_setShipSlideDampener", "(JF)Z", setShipSlideDampener), + JF("_getShipSlideDampener", "(J)F", getShipSlideDampener), + JF("_setShipCurrentYaw", "(JF)Z", setShipCurrentYaw), + JF("_getShipCurrentYaw", "(J)F", getShipCurrentYaw), + JF("_setShipCurrentPitch", "(JF)Z", setShipCurrentPitch), + JF("_getShipCurrentPitch", "(J)F", getShipCurrentPitch), + JF("_setShipCurrentRoll", "(JF)Z", setShipCurrentRoll), + JF("_getShipCurrentRoll", "(J)F", getShipCurrentRoll), + JF("_setShipCurrentChassisHitPoints", "(JF)Z", setShipCurrentChassisHitPoints), + JF("_getShipCurrentChassisHitPoints", "(J)F", getShipCurrentChassisHitPoints), + JF("_setShipMaximumChassisHitPoints", "(JF)Z", setShipMaximumChassisHitPoints), + JF("_getShipMaximumChassisHitPoints", "(J)F", getShipMaximumChassisHitPoints), + JF("_launchMissile", "(JJJII)Z", launchMissile), + JF("_launchCountermeasure", "(JIZI)Z", launchCountermeasure), + JF("_getNearestUnlockedMissileForTarget", "(J)I", getNearestUnlockedMissileForTarget), + JF("_getAllUnlockedMissilesForTarget", "(J)[I", getAllUnlockedMissilesForTarget), + JF("destroyMissile", "(I)Z", destroyMissile), + JF("getTypeByMissile","(I)I", getTypeByMissile), + JF("getWeaponIndexByMissile","(I)I",getWeaponIndexByMissile), + JF("getTimeSinceFiredByMissile","(I)I",getTimeSinceFiredByMissile), + JF("getTotalTimeByMissile","(I)I",getTotalTimeByMissile), + JF("_getWhoFiredByMissile","(I)J",getWhoFiredByMissile), + JF("_setLookAtTargetShipComponent", "(JI)Z", setLookAtTargetShipComponent), + JF("_getLookAtTargetShipComponent", "(J)I", getLookAtTargetShipComponent), + JF("_getObservedShips", "(JZ)[J", getObservedShips), + JF("_getObservedPlayerShips", "(JZ)[J", getObservedPlayerShips), + JF("_getObservedEnemyShips", "(J)[J", getObservedEnemyShips), + JF("_getObservedEnemyPlayerShips", "(J)[J", getObservedEnemyPlayerShips), + JF("_notifyShipDamage", "(JJF)V", notifyShipDamage), + JF("_getShipChassisSpeedMaximumModifier", "(J)F", getShipChassisSpeedMaximumModifier), + JF("_setShipChassisSpeedMaximumModifier", "(JF)V", setShipChassisSpeedMaximumModifier), + JF("_getShipActualAccelerationRate", "(J)F", getShipActualAccelerationRate), + JF("_getShipActualDecelerationRate", "(J)F", getShipActualDecelerationRate), + JF("_getShipActualPitchAccelerationRateDegrees", "(J)F", getShipActualPitchAccelerationRateDegrees), + JF("_getShipActualYawAccelerationRateDegrees", "(J)F", getShipActualYawAccelerationRateDegrees), + JF("_getShipActualRollAccelerationRateDegrees", "(J)F", getShipActualRollAccelerationRateDegrees), + JF("_getShipActualPitchRateMaximumDegrees", "(J)F", getShipActualPitchRateMaximumDegrees), + JF("_getShipActualYawRateMaximumDegrees", "(J)F", getShipActualYawRateMaximumDegrees), + JF("_getShipActualRollRateMaximumDegrees", "(J)F", getShipActualRollRateMaximumDegrees), + JF("_getShipActualSpeedMaximum", "(J)F", getShipActualSpeedMaximum), + JF("_handleShipDestruction", "(JF)V", handleShipDestruction), + JF("_handleShipComponentDestruction", "(JIF)V", handleShipComponentDestruction), + JF("_setShipInternalDamageOverTime", "(JIFF)Z", setShipInternalDamageOverTime), + JF("_removeShipInternalDamageOverTime", "(JI)Z", removeShipInternalDamageOverTime), + JF("_getShipInternalDamageOverTimeDamageRate", "(JI)F", getShipInternalDamageOverTimeDamageRate), + JF("_getShipInternalDamageOverTimeDamageThreshold", "(JI)F", getShipInternalDamageOverTimeDamageThreshold), + JF("_hasShipInternalDamageOverTime", "(JI)Z", hasShipInternalDamageOverTime), + JF("_shipGetSpaceFaction", "(J)I", shipGetSpaceFaction), + JF("_shipGetSpaceFactionAllies", "(J)[I", shipGetSpaceFactionAllies), + JF("_shipGetSpaceFactionEnemies", "(J)[I", shipGetSpaceFactionEnemies), + JF("_shipGetSpaceFactionIsAggro", "(J)Z", shipGetSpaceFactionIsAggro), + JF("_shipSetSpaceFaction", "(JI)V", shipSetSpaceFaction), + JF("_shipSetSpaceFactionAllies", "(J[I)V", shipSetSpaceFactionAllies), + JF("_shipSetSpaceFactionEnemies", "(J[I)V", shipSetSpaceFactionEnemies), + JF("_shipSetSpaceFactionIsAggro", "(JZ)V", shipSetSpaceFactionIsAggro), + JF("_getShipChassisType", "(J)Ljava/lang/String;", getShipChassisType), + JF("_getChassisComponentMassCurrent", "(J)F", getChassisComponentMassCurrent), + JF("_getChassisComponentMassMaximum", "(J)F", getChassisComponentMassMaximum), + JF("_setChassisComponentMassMaximum", "(JF)Z", setChassisComponentMassMaximum), + JF("_isShipSlotInstalled", "(JI)Z", isShipSlotInstalled), + JF("_isShipComponentDisabled", "(JI)Z", isShipComponentDisabled), + JF("_isShipComponentLowPower", "(JI)Z", isShipComponentLowPower), + JF("_isShipComponentDisabledNeedsPower", "(JI)Z", isShipComponentDisabledNeedsPower), + JF("_getShipComponentArmorHitpointsMaximum", "(JI)F", getShipComponentArmorHitpointsMaximum), + JF("_getShipComponentArmorHitpointsCurrent", "(JI)F", getShipComponentArmorHitpointsCurrent), + JF("_getShipComponentEfficiencyGeneral", "(JI)F", getShipComponentEfficiencyGeneral), + JF("_getShipComponentEfficiencyEnergy", "(JI)F", getShipComponentEfficiencyEnergy), + JF("_getShipComponentEnergyMaintenanceRequirement", "(JI)F", getShipComponentEnergyMaintenanceRequirement), + JF("_getShipComponentMass", "(JI)F", getShipComponentMass), + JF("_getShipComponentCrc", "(JI)I", getShipComponentCrc), + JF("_getShipComponentHitpointsCurrent", "(JI)F", getShipComponentHitpointsCurrent), + JF("_getShipComponentHitpointsMaximum", "(JI)F", getShipComponentHitpointsMaximum), + JF("_getShipComponentFlags", "(JI)I", getShipComponentFlags), + JF("_getShipComponentName", "(JI)Ljava/lang/String;", getShipComponentName), + JF("_getShipWeaponDamageMaximum", "(JI)F", getShipWeaponDamageMaximum), + JF("_getShipWeaponDamageMinimum", "(JI)F", getShipWeaponDamageMinimum), + JF("_getShipWeaponEffectivenessShields", "(JI)F", getShipWeaponEffectivenessShields), + JF("_getShipWeaponEffectivenessArmor", "(JI)F", getShipWeaponEffectivenessArmor), + JF("_getShipWeaponEnergyPerShot", "(JI)F", getShipWeaponEnergyPerShot), + JF("_getShipWeaponRefireRate", "(JI)F", getShipWeaponRefireRate), + JF("_getShipWeaponActualRefireRate", "(JI)F", getShipWeaponActualRefireRate), + JF("_getShipWeaponEfficiencyRefireRate", "(JI)F", getShipWeaponEfficiencyRefireRate), + JF("_getShipWeaponAmmoCurrent", "(JI)I", getShipWeaponAmmoCurrent), + JF("_getShipWeaponAmmoMaximum", "(JI)I", getShipWeaponAmmoMaximum), + JF("_getShipWeaponAmmoType", "(JI)I", getShipWeaponAmmoType), + JF("_getShipShieldHitpointsFrontCurrent", "(J)F", getShipShieldHitpointsFrontCurrent), + JF("_getShipShieldHitpointsFrontMaximum", "(J)F", getShipShieldHitpointsFrontMaximum), + JF("_getShipShieldHitpointsBackCurrent", "(J)F", getShipShieldHitpointsBackCurrent), + JF("_getShipShieldHitpointsBackMaximum", "(J)F", getShipShieldHitpointsBackMaximum), + JF("_getShipShieldRechargeRate", "(J)F", getShipShieldRechargeRate), + JF("_getShipCapacitorEnergyCurrent", "(J)F", getShipCapacitorEnergyCurrent), + JF("_getShipCapacitorEnergyMaximum", "(J)F", getShipCapacitorEnergyMaximum), + JF("_getShipCapacitorEnergyRechargeRate", "(J)F", getShipCapacitorEnergyRechargeRate), + JF("_getShipEngineAccelerationRate", "(J)F", getShipEngineAccelerationRate), + JF("_getShipEngineDecelerationRate", "(J)F", getShipEngineDecelerationRate), + JF("_getShipEnginePitchAccelerationRateDegrees", "(J)F", getShipEnginePitchAccelerationRateDegrees), + JF("_getShipEngineYawAccelerationRateDegrees", "(J)F", getShipEngineYawAccelerationRateDegrees), + JF("_getShipEngineRollAccelerationRateDegrees", "(J)F", getShipEngineRollAccelerationRateDegrees), + JF("_getShipEnginePitchRateMaximumDegrees", "(J)F", getShipEnginePitchRateMaximumDegrees), + JF("_getShipEngineYawRateMaximumDegrees", "(J)F", getShipEngineYawRateMaximumDegrees), + JF("_getShipEngineRollRateMaximumDegrees", "(J)F", getShipEngineRollRateMaximumDegrees), + JF("_getShipEngineSpeedMaximum", "(J)F", getShipEngineSpeedMaximum), + JF("_getShipEngineSpeedRotationFactorMaximum", "(J)F", getShipEngineSpeedRotationFactorMaximum), + JF("_getShipEngineSpeedRotationFactorMinimum", "(J)F", getShipEngineSpeedRotationFactorMinimum), + JF("_getShipEngineSpeedRotationFactorOptimal", "(J)F", getShipEngineSpeedRotationFactorOptimal), + JF("_getShipReactorEnergyGenerationRate", "(J)F", getShipReactorEnergyGenerationRate), + JF("_getShipBoosterEnergyCurrent", "(J)F", getShipBoosterEnergyCurrent), + JF("_getShipBoosterEnergyMaximum", "(J)F", getShipBoosterEnergyMaximum), + JF("_getShipBoosterEnergyRechargeRate", "(J)F", getShipBoosterEnergyRechargeRate), + JF("_getShipBoosterEnergyConsumptionRate", "(J)F", getShipBoosterEnergyConsumptionRate), + JF("_getShipBoosterAcceleration", "(J)F", getShipBoosterAcceleration), + JF("_getShipBoosterSpeedMaximum", "(J)F", getShipBoosterSpeedMaximum), + JF("_isShipBoosterActive", "(J)Z", isShipBoosterActive), + JF("_getShipDroidInterfaceCommandSpeed", "(J)F", getShipDroidInterfaceCommandSpeed), + JF("_getShipCargoHoldContentsMaximum", "(J)I", getShipCargoHoldContentsMaximum), + JF("_getShipCargoHoldContentsCurrent", "(J)I", getShipCargoHoldContentsCurrent), + JF("_setShipComponentArmorHitpointsMaximum", "(JIF)V", setShipComponentArmorHitpointsMaximum), + JF("_setShipComponentArmorHitpointsCurrent", "(JIF)V", setShipComponentArmorHitpointsCurrent), + JF("_setShipComponentEfficiencyGeneral", "(JIF)V", setShipComponentEfficiencyGeneral), + JF("_setShipComponentEfficiencyEnergy", "(JIF)V", setShipComponentEfficiencyEnergy), + JF("_setShipComponentEnergyMaintenanceRequirement", "(JIF)V", setShipComponentEnergyMaintenanceRequirement), + JF("_setShipComponentMass", "(JIF)V", setShipComponentMass), + JF("_setShipComponentHitpointsCurrent", "(JIF)V", setShipComponentHitpointsCurrent), + JF("_setShipComponentHitpointsMaximum", "(JIF)V", setShipComponentHitpointsMaximum), + JF("_setShipComponentFlags", "(JII)V", setShipComponentFlags), + JF("_setShipComponentName", "(JILjava/lang/String;)V", setShipComponentName), + JF("_setShipComponentDisabled", "(JIZ)V", setShipComponentDisabled), + JF("_setShipComponentLowPower", "(JIZ)V", setShipComponentLowPower), + JF("_setShipComponentDisabledNeedsPower", "(JIZ)V", setShipComponentDisabledNeedsPower), + JF("_setShipWeaponDamageMaximum", "(JIF)V", setShipWeaponDamageMaximum), + JF("_setShipWeaponDamageMinimum", "(JIF)V", setShipWeaponDamageMinimum), + JF("_setShipWeaponEffectivenessShields", "(JIF)V", setShipWeaponEffectivenessShields), + JF("_setShipWeaponEffectivenessArmor", "(JIF)V", setShipWeaponEffectivenessArmor), + JF("_setShipWeaponEnergyPerShot", "(JIF)V", setShipWeaponEnergyPerShot), + JF("_setShipWeaponRefireRate", "(JIF)V", setShipWeaponRefireRate), + JF("_setShipWeaponEfficiencyRefireRate", "(JIF)V", setShipWeaponEfficiencyRefireRate), + JF("_setShipWeaponAmmoCurrent", "(JII)V", setShipWeaponAmmoCurrent), + JF("_setShipWeaponAmmoMaximum", "(JII)V", setShipWeaponAmmoMaximum), + JF("_setShipWeaponAmmoType", "(JII)V", setShipWeaponAmmoType), + JF("_setShipShieldHitpointsFrontCurrent", "(JF)V", setShipShieldHitpointsFrontCurrent), + JF("_setShipShieldHitpointsFrontMaximum", "(JF)V", setShipShieldHitpointsFrontMaximum), + JF("_setShipShieldHitpointsBackCurrent", "(JF)V", setShipShieldHitpointsBackCurrent), + JF("_setShipShieldHitpointsBackMaximum", "(JF)V", setShipShieldHitpointsBackMaximum), + JF("_setShipShieldRechargeRate", "(JF)V", setShipShieldRechargeRate), + JF("_setShipCapacitorEnergyCurrent", "(JF)V", setShipCapacitorEnergyCurrent), + JF("_setShipCapacitorEnergyMaximum", "(JF)V", setShipCapacitorEnergyMaximum), + JF("_setShipCapacitorEnergyRechargeRate", "(JF)V", setShipCapacitorEnergyRechargeRate), + JF("_setShipEngineAccelerationRate", "(JF)V", setShipEngineAccelerationRate), + JF("_setShipEngineDecelerationRate", "(JF)V", setShipEngineDecelerationRate), + JF("_setShipEnginePitchAccelerationRateDegrees", "(JF)V", setShipEnginePitchAccelerationRateDegrees), + JF("_setShipEngineYawAccelerationRateDegrees", "(JF)V", setShipEngineYawAccelerationRateDegrees), + JF("_setShipEngineRollAccelerationRateDegrees", "(JF)V", setShipEngineRollAccelerationRateDegrees), + JF("_setShipEnginePitchRateMaximumDegrees", "(JF)V", setShipEnginePitchRateMaximumDegrees), + JF("_setShipEngineYawRateMaximumDegrees", "(JF)V", setShipEngineYawRateMaximumDegrees), + JF("_setShipEngineRollRateMaximumDegrees", "(JF)V", setShipEngineRollRateMaximumDegrees), + JF("_setShipEngineSpeedMaximum", "(JF)V", setShipEngineSpeedMaximum), + JF("_setShipEngineSpeedRotationFactorMaximum", "(JF)V", setShipEngineSpeedRotationFactorMaximum), + JF("_setShipEngineSpeedRotationFactorMinimum", "(JF)V", setShipEngineSpeedRotationFactorMinimum), + JF("_setShipEngineSpeedRotationFactorOptimal", "(JF)V", setShipEngineSpeedRotationFactorOptimal), + JF("_setShipReactorEnergyGenerationRate", "(JF)V", setShipReactorEnergyGenerationRate), + JF("_setShipBoosterEnergyCurrent", "(JF)V", setShipBoosterEnergyCurrent), + JF("_setShipBoosterEnergyMaximum", "(JF)V", setShipBoosterEnergyMaximum), + JF("_setShipBoosterEnergyRechargeRate", "(JF)V", setShipBoosterEnergyRechargeRate), + JF("_setShipBoosterEnergyConsumptionRate", "(JF)V", setShipBoosterEnergyConsumptionRate), + JF("_setShipBoosterAcceleration", "(JF)V", setShipBoosterAcceleration), + JF("_setShipBoosterSpeedMaximum", "(JF)V", setShipBoosterSpeedMaximum), + JF("_setShipDroidInterfaceCommandSpeed", "(JF)V", setShipDroidInterfaceCommandSpeed), + JF("_setShipCargoHoldContentsMaximum", "(JI)V", setShipCargoHoldContentsMaximum), + JF("_setShipCargoHoldContent", "(JJI)V", setShipCargoHoldContent), + JF("_getShipCargoHoldContent", "(JJ)I", getShipCargoHoldContent), + JF("_getShipCargoHoldContentsResourceTypes", "(J)[J", getShipCargoHoldContentsResourceTypes), + JF("_getShipCargoHoldContentsAmounts", "(J)[I", getShipCargoHoldContentsAmounts), + JF("_shipCanInstallComponent", "(JIJ)Z", shipCanInstallComponent), + JF("_shipPseudoInstallComponent", "(JII)Z", shipPseudoInstallComponent), + JF("_shipInstallComponent", "(JJIJ)Z", shipInstallComponent), + JF("_shipUninstallComponent", "(JJIJ)J", shipUninstallComponent), + JF("_shipUninstallComponentAllowOverload", "(JJIJ)J", shipUninstallComponentAllowOverload), + JF("_getShipChassisSlots", "(J)[I", getShipChassisSlots), + JF("_setShipSlotTargetable", "(JIZ)V", setShipSlotTargetable), + JF("_isShipSlotTargetable", "(JI)Z", isShipSlotTargetable), + JF("_getShipComponentDescriptorType", "(J)I", getShipComponentDescriptorType), + JF("getShipComponentDescriptorTypeName", "(I)Ljava/lang/String;", getShipComponentDescriptorTypeName), + JF("getShipComponentDescriptorTypeByName", "(Ljava/lang/String;)I", getShipComponentDescriptorTypeByName), + JF("_getShipComponentDescriptorCrc", "(J)I", getShipComponentDescriptorCrc), + JF("getShipComponentDescriptorCrcName", "(I)Ljava/lang/String;", getShipComponentDescriptorCrcName), + JF("getShipComponentDescriptorCompatibility", "(I)Ljava/lang/String;", getShipComponentDescriptorCompatibility), + JF("getShipComponentDescriptorWeaponIsAmmoConsuming", "(I)Z", getShipComponentDescriptorWeaponIsAmmoConsuming), + JF("getShipComponentDescriptorWeaponIsMissile", "(I)Z", getShipComponentDescriptorWeaponIsMissile), + JF("getShipComponentDescriptorWeaponIsCountermeasure","(I)Z", getShipComponentDescriptorWeaponIsCountermeasure), + JF("getShipComponentDescriptorWeaponIsMining", "(I)Z", getShipComponentDescriptorWeaponIsMining), + JF("getShipComponentDescriptorWeaponIsTractor", "(I)Z", getShipComponentDescriptorWeaponIsTractor), + JF("getShipComponentDescriptorWeaponRange", "(I)F", getShipComponentDescriptorWeaponRange), + JF("getShipComponentDescriptorWeaponProjectileSpeed", "(I)F", getShipComponentDescriptorWeaponProjectileSpeed), + JF("_getDroidControlDeviceForShip", "(J)J", getDroidControlDeviceForShip), + JF("_associateDroidControlDeviceWithShip", "(JJ)Z", associateDroidControlDeviceWithShip), + JF("_removeDroidControlDeviceFromShip", "(J)Z", removeDroidControlDeviceFromShip), + JF("_launchShipFromHangar", "(JLjava/lang/String;Lscript/transform;)J", launchShipFromHangar), + JF("__commPlayers", "(JLjava/lang/String;Ljava/lang/String;F[JLjava/lang/String;Z)V", commPlayers), + JF("_shipIsInNebula", "(JLjava/lang/String;)Z", shipIsInNebula), + JF("_setShipWingName", "(JLjava/lang/String;)Z", setShipWingName), + JF("_getShipWingName", "(J)Ljava/lang/String;", getShipWingName), + JF("_setShipTypeName", "(JLjava/lang/String;)Z", setShipTypeName), + JF("_getShipTypeName", "(J)Ljava/lang/String;", getShipTypeName), + JF("_setShipDifficulty", "(JLjava/lang/String;)Z", setShipDifficulty), + JF("_getShipDifficulty", "(J)Ljava/lang/String;", getShipDifficulty), + JF("_setShipFaction", "(JLjava/lang/String;)Z", setShipFaction), + JF("_getShipFaction", "(J)Ljava/lang/String;", getShipFaction), + JF("_addMissionCriticalObject", "(JJ)Z", addMissionCriticalObject), + JF("_removeMissionCriticalObject", "(JJ)Z", removeMissionCriticalObject), + JF("_clearMissionCriticalObjects", "(J)Z", clearMissionCriticalObjects), + JF("_isMissionCriticalObject", "(JJ)Z", isMissionCriticalObject), + JF("_getShipComponentDebugString", "(JI)Ljava/lang/String;", getShipComponentDebugString), + JF("_notifyShipHit", "(JLscript/vector;Lscript/vector;IFF)V", notifyShipHit), + JF("_setDynamicMiningAsteroidVelocity", "(JLscript/vector;)V", setDynamicMiningAsteroidVelocity), + JF("_getDynamicMiningAsteroidVelocity", "(J)Lscript/vector;", getDynamicMiningAsteroidVelocity), + JF("_openSpaceMiningUi", "(JJLjava/lang/String;)V", openSpaceMiningUi), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +// ====================================================================== + +jboolean JNICALL ScriptMethodsShipNamespace::pilotShip(JNIEnv *env, jobject /*self*/, jlong pilotId, jlong pilotSlotId) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return JNI_FALSE; + + //-- Get the pilot object. + CreatureObject * const pilotObject = JavaLibrary::getCreatureThrow(env, pilotId, "pilotShip(): error in pilotId arg"); + if (!pilotObject) + return JNI_FALSE; + + //-- Ensure that the pilot is not already piloting a ship. + if (pilotObject->getPilotedShip()) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::pilotShip(): pilot id=[%s] is already riding a ship.", pilotObject->getNetworkId().getValueString().c_str())); + return JNI_FALSE; + } + + //-- Get the pilot slot object. + ServerObject * pilotSlotObject = 0; + if (!JavaLibrary::getObject(pilotSlotId, pilotSlotObject)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::pilotShip: could not resolve pilotSlotObject")); + return JNI_FALSE; + } + + //-- Make sure the ship is a player controlled ship + if (pilotObject->isPlayerControlled()) + { + //-- Get the containing ship + ShipObject * const shipObject = ShipObject::getContainingShipObject(pilotSlotObject); + if (!shipObject) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::pilotShip: pilotSlotObject [id=%s, template=%s] does not have a containing ship", pilotSlotObject->getNetworkId().getValueString().c_str(), pilotSlotObject->getObjectTemplateName())); + return JNI_FALSE; + } + + if (!shipObject->isPlayerShip()) + return JNI_FALSE; + } + + //-- Have the pilot mount the ship. + if (!pilotObject->pilotShip(*pilotSlotObject)) + return JNI_FALSE; + + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsShipNamespace::unpilotShip(JNIEnv *env, jobject /*self*/, jlong pilotId) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return JNI_FALSE; + + //-- Get the pilot. + CreatureObject * const pilotObject = JavaLibrary::getCreatureThrow(env, pilotId, "unpilotShip(): error in pilotId arg"); + if (!pilotObject) + return JNI_FALSE; + + //-- Get the ship. + ShipObject * const shipObject = pilotObject->getPilotedShip(); + if (!shipObject) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::unpilotShip(): pilot id=[%s] is not piloting a ship.", pilotObject->getNetworkId().getValueString().c_str())); + return JNI_FALSE; + } + + //-- Detach the pilot from the ship. + if (!pilotObject->unpilotShip()) + return JNI_FALSE; + + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsShipNamespace::getShipPilot(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return 0; + + //-- Get the ship object. + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipPilot(): obj_id shipId did not resolve to a ShipObject", false); + if (!shipObject) + return 0; + + //-- Get the pilot object + CreatureObject const * const pilotObject = shipObject->getPilot(); + NetworkId const pilotNetworkId = (pilotObject ? pilotObject->getNetworkId() : NetworkId::cms_invalid); + + return pilotNetworkId.getValue(); +} + +// ---------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsShipNamespace::getPilotedShip(JNIEnv * env, jobject /*self*/, jlong jobject_pilotId) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return 0; + + //-- Get the pilot object. + CreatureObject const * const creatureObject = JavaLibrary::getCreatureThrow(env, jobject_pilotId, "getPilotedShip(): obj_id pilotId did not resolve to a ShipObject", false); + if (!creatureObject) + return 0; + + ShipObject const * const shipObject = creatureObject->getPilotedShip(); + NetworkId const shipNetworkId = (shipObject ? shipObject->getNetworkId() : NetworkId::cms_invalid); + + return shipNetworkId.getValue(); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsShipNamespace::getShipHasWings(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return JNI_FALSE; + + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipHasWings(): shipId obj_id did not resolve to a ShipObject", false); + if (!shipObject) + return JNI_FALSE; + + if (!shipObject->hasWings()) + return JNI_FALSE; + + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipCurrentSpeed(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return 0.f; + + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipCurrentSpeed(): shipId obj_id did not resolve to a ShipObject", false); + if (!shipObject) + return 0.f; + + return shipObject->getCurrentSpeed(); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsShipNamespace::setShipSlideDampener(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jfloat jfloat_slideDampener) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return JNI_FALSE; + + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "setShipSlideDampener(): shipId obj_id did not resolve to a ShipObject", false); + if (!shipObject) + return JNI_FALSE; + + bool const result = shipObject->setSlideDampener(jfloat_slideDampener); + if (!result) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipSlideDampener(): could not set value %1.2f (possibly out of range)", jfloat_slideDampener)); + return JNI_FALSE; + } + + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipSlideDampener(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return 0.f; + + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipSlideDampener(): shipId obj_id did not resolve to a ShipObject", false); + if (!shipObject) + return 0.f; + + return shipObject->getSlideDampener(); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsShipNamespace::setShipCurrentYaw(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jfloat jfloat_currentYaw) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return JNI_FALSE; + + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "setShipCurrentYaw(): shipId obj_id did not resolve to a ShipObject", false); + if (!shipObject) + return JNI_FALSE; + + bool const result = shipObject->setCurrentYaw(jfloat_currentYaw); + if (!result) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipCurrentYaw(): could not set value %1.2f (possibly out of range)", jfloat_currentYaw)); + return JNI_FALSE; + } + + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipCurrentYaw(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return 0.f; + + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipCurrentYaw(): shipId obj_id did not resolve to a ShipObject", false); + if (!shipObject) + return 0.f; + + return shipObject->getCurrentYaw(); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsShipNamespace::setShipCurrentPitch(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jfloat jfloat_currentPitch) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return JNI_FALSE; + + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "setShipCurrentPitch(): shipId obj_id did not resolve to a ShipObject", false); + if (!shipObject) + return JNI_FALSE; + + bool const result = shipObject->setCurrentPitch(jfloat_currentPitch); + if (!result) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipCurrentPitch(): could not set value %1.2f (possibly out of range)", jfloat_currentPitch)); + return JNI_FALSE; + } + + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipCurrentPitch(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return 0.f; + + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipCurrentPitch(): shipId obj_id did not resolve to a ShipObject", false); + if (!shipObject) + return 0.f; + + return shipObject->getCurrentPitch(); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsShipNamespace::setShipCurrentRoll(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jfloat jfloat_currentRoll) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return JNI_FALSE; + + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "setShipCurrentRoll(): shipId obj_id did not resolve to a ShipObject", false); + if (!shipObject) + return JNI_FALSE; + + bool const result = shipObject->setCurrentRoll(jfloat_currentRoll); + if (!result) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipCurrentRoll(): could not set value %1.2f (possibly out of range)", jfloat_currentRoll)); + return JNI_FALSE; + } + + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipCurrentRoll(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return 0.f; + + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipCurrentRoll(): shipId obj_id did not resolve to a ShipObject", false); + if (!shipObject) + return 0.f; + + return shipObject->getCurrentRoll(); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsShipNamespace::setShipCurrentChassisHitPoints(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jfloat jfloat_currentChassisHitPoints) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return JNI_FALSE; + + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "setShipCurrentChassisHitPoints(): shipId obj_id did not resolve to a ShipObject", false); + if (!shipObject) + return JNI_FALSE; + + bool const result = shipObject->setCurrentChassisHitPoints(jfloat_currentChassisHitPoints); + if (!result) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipCurrentChassisHitPoints(): could not set value %1.2f (possibly out of range)", jfloat_currentChassisHitPoints)); + return JNI_FALSE; + } + + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipCurrentChassisHitPoints(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return 0.f; + + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipCurrentChassisHitPoints(): shipId obj_id did not resolve to a ShipObject", false); + if (!shipObject) + return 0.f; + + return shipObject->getCurrentChassisHitPoints(); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsShipNamespace::setShipMaximumChassisHitPoints(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jfloat jfloat_currentChassisHitPoints) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return JNI_FALSE; + + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "setShipMaximumChassisHitPoints(): shipId obj_id did not resolve to a ShipObject", false); + if (!shipObject) + return JNI_FALSE; + + bool const result = shipObject->setMaximumChassisHitPoints(jfloat_currentChassisHitPoints); + if (!result) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipMaximumChassisHitPoints(): could not set value %1.2f (possibly out of range)", jfloat_currentChassisHitPoints)); + return JNI_FALSE; + } + + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipMaximumChassisHitPoints(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return 0.f; + + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipMaximumChassisHitPoints(): shipId obj_id did not resolve to a ShipObject", false); + if (!shipObject) + return 0.f; + + return shipObject->getMaximumChassisHitPoints(); +} + +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +//-- component system +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- + +//-- ship component methods + +jfloat JNICALL ScriptMethodsShipNamespace::getShipActualAccelerationRate(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return 0.f; + + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipActualAccelerationRate(): shipId obj_id did not resolve to a ShipObject", false); + if (!shipObject) + return 0.f; + + return shipObject->getShipActualAccelerationRate(); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipActualDecelerationRate(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return 0.f; + + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipActualDecelerationRate(): shipId obj_id did not resolve to a ShipObject", false); + if (!shipObject) + return 0.f; + + return shipObject->getShipActualDecelerationRate(); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipActualPitchAccelerationRateDegrees(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return 0.f; + + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipActualPitchAccelerationRate(): shipId obj_id did not resolve to a ShipObject", false); + if (!shipObject) + return 0.f; + + return convertRadiansToDegrees(shipObject->getShipActualPitchAccelerationRate()); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipActualYawAccelerationRateDegrees(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return 0.f; + + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipActualYawAccelerationRate(): shipId obj_id did not resolve to a ShipObject", false); + if (!shipObject) + return 0.f; + + return convertRadiansToDegrees(shipObject->getShipActualYawAccelerationRate()); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipActualRollAccelerationRateDegrees(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return 0.f; + + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipActualRollAccelerationRate(): shipId obj_id did not resolve to a ShipObject", false); + if (!shipObject) + return 0.f; + + return convertRadiansToDegrees(shipObject->getShipActualRollAccelerationRate()); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipActualPitchRateMaximumDegrees(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return 0.f; + + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipActualPitchRateMaximum(): shipId obj_id did not resolve to a ShipObject", false); + if (!shipObject) + return 0.f; + + return convertRadiansToDegrees(shipObject->getShipActualPitchRateMaximum()); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipActualYawRateMaximumDegrees(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return 0.f; + + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipActualYawRateMaximum(): shipId obj_id did not resolve to a ShipObject", false); + if (!shipObject) + return 0.f; + + return convertRadiansToDegrees(shipObject->getShipActualYawRateMaximum()); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipActualRollRateMaximumDegrees(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return 0.f; + + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipActualRollRateMaximum(): shipId obj_id did not resolve to a ShipObject", false); + if (!shipObject) + return 0.f; + + return convertRadiansToDegrees(shipObject->getShipActualRollRateMaximum()); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipActualSpeedMaximum(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return 0.f; + + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipActualSpeedMaximum(): shipId obj_id did not resolve to a ShipObject", false); + if (!shipObject) + return 0.f; + + return shipObject->getShipActualSpeedMaximum(); +} + +//---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsShipNamespace::getShipChassisType(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return NULL; + + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipChassisType(): shipId obj_id did not resolve to a ShipObject", false); + if (!shipObject) + return NULL; + + ShipChassis const * const shipChassis = ShipChassis::findShipChassisByCrc (shipObject->getChassisType()); + if (shipChassis) + return JavaString(shipChassis->getName ().getString ()).getReturnValue(); + + return NULL; +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getChassisComponentMassCurrent(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return 0.0f; + + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipChassisType(): shipId obj_id did not resolve to a ShipObject", false); + if (!shipObject) + return 0.0f; + + return shipObject->getChassisComponentMassCurrent(); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getChassisComponentMassMaximum(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return 0.0f; + + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipChassisType(): shipId obj_id did not resolve to a ShipObject", false); + if (!shipObject) + return 0.0f; + + return shipObject->getChassisComponentMassMaximum(); +} + +//---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsShipNamespace::setChassisComponentMassMaximum(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, float chassisComponentMassMaximum) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return JNI_FALSE; + + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipChassisType(): shipId obj_id did not resolve to a ShipObject", false); + if (!shipObject) + return JNI_FALSE; + + shipObject->setChassisComponentMassMaximum(chassisComponentMassMaximum); + + return JNI_TRUE; +} + +//---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsShipNamespace::isShipSlotInstalled(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return false; + + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "JavaLibrary::isShipSlotInstalled ship obj_id did not resolve to a ShipObject", false); + if (!shipObject) + return false; + + return shipObject->isSlotInstalled(chassisSlot); +} + +//---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsShipNamespace::isShipComponentDisabled(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "isShipComponentDisabled() invalid ship", false); + if (!shipObject) + return false; + + return shipObject->isComponentDisabled(chassisSlot); +} + +//---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsShipNamespace::isShipComponentDisabledNeedsPower(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "isShipComponentDisabledNeedsPower() invalid ship", false); + if (!shipObject) + return false; + + return shipObject->isComponentDisabledNeedsPower(chassisSlot); +} + +//---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsShipNamespace::isShipComponentLowPower(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "isShipComponentLowPower() invalid ship", false); + if (!shipObject) + return false; + + return shipObject->isComponentLowPower(chassisSlot); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipComponentArmorHitpointsMaximum(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipComponentArmorHitpointsMaximum() invalid ship", false); + if (!shipObject) + return false; + + return shipObject->getComponentArmorHitpointsMaximum(chassisSlot); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipComponentArmorHitpointsCurrent(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipComponentArmorHitpointsCurrent() invalid ship", false); + if (!shipObject) + return false; + + return shipObject->getComponentArmorHitpointsCurrent(chassisSlot); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipComponentEfficiencyGeneral(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipComponentEfficiencyGeneral() invalid ship", false); + if (!shipObject) + return false; + + return shipObject->getComponentEfficiencyGeneral(chassisSlot); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipComponentEfficiencyEnergy(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipComponentEfficiencyEnergy() invalid ship", false); + if (!shipObject) + return false; + + return shipObject->getComponentEfficiencyEnergy(chassisSlot); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipComponentEnergyMaintenanceRequirement(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipComponentEnergyMaintenanceRequirement() invalid ship", false); + if (!shipObject) + return false; + + return shipObject->getComponentEnergyMaintenanceRequirement(chassisSlot); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipComponentMass(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipComponentMass() invalid ship", false); + if (!shipObject) + return false; + + return shipObject->getComponentMass(chassisSlot); +} + +//---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsShipNamespace::getShipComponentCrc(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipComponentCrc() invalid ship", false); + if (!shipObject) + return false; + + return static_cast(shipObject->getComponentCrc(chassisSlot)); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipComponentHitpointsCurrent(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipComponentHitpointsCurrent() invalid ship", false); + if (!shipObject) + return false; + + return shipObject->getComponentHitpointsCurrent(chassisSlot); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipComponentHitpointsMaximum(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipComponentHitpointsMaximum() invalid ship", false); + if (!shipObject) + return false; + + return shipObject->getComponentHitpointsMaximum(chassisSlot); +} + +//---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsShipNamespace::getShipComponentFlags(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipComponentFlags() invalid ship", false); + if (!shipObject) + return false; + + return shipObject->getComponentFlags(chassisSlot); +} + +//---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsShipNamespace::getShipComponentName(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipComponentName() invalid ship", false); + if (!shipObject) + return false; + + Unicode::String const & name = shipObject->getComponentName(chassisSlot); + if (!name.empty()) + return JavaString(name).getReturnValue(); + + ShipComponentDescriptor const * const shipComponentDescriptor = ShipComponentDescriptor::findShipComponentDescriptorByCrc(shipObject->getComponentCrc(chassisSlot)); + if (shipComponentDescriptor) + { + ObjectTemplate const * const t = shipComponentDescriptor->getSharedObjectTemplate(); + if (t) + { + SharedObjectTemplate const * const sharedTemplate = t->asSharedObjectTemplate(); + if (sharedTemplate) + return JavaString("@"+sharedTemplate->getObjectName().getCanonicalRepresentation()).getReturnValue(); + } + } + return JavaString("").getReturnValue(); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipWeaponDamageMaximum(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipWeaponDamageMaximum() invalid ship", false); + if (!shipObject) + return false; + + return shipObject->getWeaponDamageMaximum(chassisSlot); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipWeaponDamageMinimum(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipWeaponDamageMinimum() invalid ship", false); + if (!shipObject) + return false; + + return shipObject->getWeaponDamageMinimum(chassisSlot); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipWeaponEffectivenessShields(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipWeaponEffectivenessShields() invalid ship", false); + if (!shipObject) + return false; + + return shipObject->getWeaponEffectivenessShields(chassisSlot); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipWeaponEffectivenessArmor(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipWeaponEffectivenessArmor() invalid ship", false); + if (!shipObject) + return false; + + return shipObject->getWeaponEffectivenessArmor(chassisSlot); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipWeaponEnergyPerShot(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipWeaponEnergyPerShot() invalid ship", false); + if (!shipObject) + return false; + + return shipObject->getWeaponEnergyPerShot(chassisSlot); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipWeaponRefireRate(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipWeaponRefireRate() invalid ship", false); + if (!shipObject) + return false; + + return shipObject->getWeaponRefireRate(chassisSlot); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipWeaponActualRefireRate(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipWeaponActualRefireRate() invalid ship", false); + if (!shipObject) + return false; + + return shipObject->getWeaponActualRefireRate(chassisSlot); +} +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipWeaponEfficiencyRefireRate(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipWeaponEfficiencyRefireRate() invalid ship", false); + if (!shipObject) + return false; + + return shipObject->getWeaponEfficiencyRefireRate(chassisSlot); +} + +//---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsShipNamespace::getShipWeaponAmmoCurrent(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipWeaponAmmoCurrent() invalid ship", false); + if (!shipObject) + return false; + + return shipObject->getWeaponAmmoCurrent(chassisSlot); +} + +//---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsShipNamespace::getShipWeaponAmmoMaximum(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipWeaponAmmoMaximum() invalid ship", false); + if (!shipObject) + return false; + + return shipObject->getWeaponAmmoMaximum(chassisSlot); +} + + +//---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsShipNamespace::getShipWeaponAmmoType(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipWeaponAmmoType() invalid ship", false); + if (!shipObject) + return false; + + return static_cast(shipObject->getWeaponAmmoType(chassisSlot)); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipShieldHitpointsFrontCurrent(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipShieldHitpointsFrontCurrent() invalid ship", false); + if (!shipObject) + return false; + + return shipObject->getShieldHitpointsFrontCurrent(); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipShieldHitpointsFrontMaximum(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipShieldHitpointsFrontMaximum() invalid ship", false); + if (!shipObject) + return false; + + return shipObject->getShieldHitpointsFrontMaximum(); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipShieldHitpointsBackCurrent(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipShieldHitpointsBackCurrent() invalid ship", false); + if (!shipObject) + return false; + + return shipObject->getShieldHitpointsBackCurrent(); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipShieldHitpointsBackMaximum(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipShieldHitpointsBackMaximum() invalid ship", false); + if (!shipObject) + return false; + + return shipObject->getShieldHitpointsBackMaximum(); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipShieldRechargeRate(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipShieldRechargeRate() invalid ship", false); + if (!shipObject) + return false; + + return shipObject->getShieldRechargeRate(); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipCapacitorEnergyCurrent(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipCapacitorEnergyCurrent() invalid ship", false); + if (!shipObject) + return false; + + return shipObject->getCapacitorEnergyCurrent(); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipCapacitorEnergyMaximum(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipCapacitorEnergyMaximum() invalid ship", false); + if (!shipObject) + return false; + + return shipObject->getCapacitorEnergyEffectiveMaximum(); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipCapacitorEnergyRechargeRate(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipCapacitorEnergyRechargeRate() invalid ship", false); + if (!shipObject) + return false; + + return shipObject->getCapacitorEnergyRechargeRate(); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipEngineAccelerationRate(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipEngineAccelerationRate() invalid ship", false); + if (!shipObject) + return false; + + return shipObject->getEngineAccelerationRate(); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipEngineDecelerationRate(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipEngineDecelerationRate() invalid ship", false); + if (!shipObject) + return false; + + return shipObject->getEngineDecelerationRate(); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipEnginePitchAccelerationRateDegrees(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipEnginePitchAccelerationRateDegrees() invalid ship", false); + if (!shipObject) + return false; + + return convertRadiansToDegrees(shipObject->getEnginePitchAccelerationRate()); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipEngineYawAccelerationRateDegrees(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipEngineYawAccelerationRateDegrees() invalid ship", false); + if (!shipObject) + return false; + + return convertRadiansToDegrees(shipObject->getEngineYawAccelerationRate()); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipEngineRollAccelerationRateDegrees(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipEngineRollAccelerationRateDegrees() invalid ship", false); + if (!shipObject) + return false; + + return convertRadiansToDegrees(shipObject->getEngineRollAccelerationRate()); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipEnginePitchRateMaximumDegrees(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipEnginePitchRateMaximumDegrees() invalid ship", false); + if (!shipObject) + return false; + + return convertRadiansToDegrees(shipObject->getEnginePitchRateMaximum()); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipEngineYawRateMaximumDegrees(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipEngineYawRateMaximumDegrees() invalid ship", false); + if (!shipObject) + return false; + + return convertRadiansToDegrees(shipObject->getEngineYawRateMaximum()); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipEngineRollRateMaximumDegrees(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipEngineRollRateMaximumDegrees() invalid ship", false); + if (!shipObject) + return false; + + return convertRadiansToDegrees(shipObject->getEngineRollRateMaximum()); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipEngineSpeedMaximum(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipEngineSpeedMaximum() invalid ship", false); + if (!shipObject) + return false; + + return shipObject->getEngineSpeedMaximum(); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipEngineSpeedRotationFactorMaximum(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipEngineSpeedRotationFactorMaximum() invalid ship", false); + if (!shipObject) + return false; + + return shipObject->getEngineSpeedRotationFactorMaximum(); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipEngineSpeedRotationFactorMinimum(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipEngineSpeedRotationFactorMinimum() invalid ship", false); + if (!shipObject) + return false; + + return shipObject->getEngineSpeedRotationFactorMinimum(); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipEngineSpeedRotationFactorOptimal(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipEngineSpeedRotationFactorOptimal() invalid ship", false); + if (!shipObject) + return false; + + return shipObject->getEngineSpeedRotationFactorOptimal(); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipReactorEnergyGenerationRate(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipReactorEnergyGenerationRate() invalid ship", false); + if (!shipObject) + return false; + + return shipObject->getReactorEnergyGenerationRate(); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipBoosterEnergyCurrent(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipBoosterEnergyCurrent() invalid ship", false); + if (!shipObject) + return false; + + return shipObject->getBoosterEnergyCurrent(); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipBoosterEnergyMaximum(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipBoosterEnergyMaximum() invalid ship", false); + if (!shipObject) + return false; + + return shipObject->getBoosterEnergyMaximum(); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipBoosterEnergyRechargeRate(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipBoosterEnergyRechargeRate() invalid ship", false); + if (!shipObject) + return false; + + return shipObject->getBoosterEnergyRechargeRate(); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipBoosterEnergyConsumptionRate(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipBoosterEnergyConsumptionRate() invalid ship", false); + if (!shipObject) + return false; + + return shipObject->getBoosterEnergyConsumptionRate(); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipBoosterAcceleration(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipBoosterAcceleration() invalid ship", false); + if (!shipObject) + return false; + + return shipObject->getBoosterAcceleration(); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipBoosterSpeedMaximum(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipBoosterSpeedMaximum() invalid ship", false); + if (!shipObject) + return false; + + return shipObject->getBoosterSpeedMaximum(); +} + +//---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsShipNamespace::isShipBoosterActive(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "isShipBoosterActive() invalid ship", false); + if (!shipObject) + return false; + + return shipObject->isBoosterActive(); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipDroidInterfaceCommandSpeed(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipDroidInterfaceCommandSpeed() invalid ship", false); + if (!shipObject) + return false; + + return shipObject->getDroidInterfaceCommandSpeed(); +} + +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// component setters +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipComponentArmorHitpointsMaximum(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot, jfloat componentArmorHitpointsMaximum) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipComponentArmorHitpointsMaximum()", false, chassisSlot); + if (!shipObject) + return; + + if (!shipObject->setComponentArmorHitpointsMaximum(chassisSlot, componentArmorHitpointsMaximum)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipComponentArmorHitpointsMaximum (): component at slot [%d] error", chassisSlot)); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipComponentArmorHitpointsCurrent(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot, jfloat componentArmorHitpointsCurrent) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipComponentArmorHitpointsCurrent()", false, chassisSlot); + if (!shipObject) + return; + + if (!shipObject->setComponentArmorHitpointsCurrent(chassisSlot, componentArmorHitpointsCurrent)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipComponentArmorHitpointsCurrent (): component at slot [%d] error", chassisSlot)); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipComponentEfficiencyGeneral(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot, jfloat componentEfficiencyGeneral) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipComponentEfficiencyGeneral()", false, chassisSlot); + if (!shipObject) + return; + + if (!shipObject->setComponentEfficiencyGeneral(chassisSlot, componentEfficiencyGeneral)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipComponentEfficiencyGeneral (): component at slot [%d] error", chassisSlot)); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipComponentEfficiencyEnergy(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot, jfloat componentEfficiencyEnergy) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipComponentEfficiencyEnergy()", false, chassisSlot); + if (!shipObject) + return; + + if (!shipObject->setComponentEfficiencyEnergy(chassisSlot, componentEfficiencyEnergy)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipComponentEfficiencyEnergy (): component at slot [%d] error", chassisSlot)); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipComponentEnergyMaintenanceRequirement(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot, jfloat componentEnergyMaintenanceRequirement) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipComponentEnergyMaintenanceRequirement()", false, chassisSlot); + if (!shipObject) + return; + + if (!shipObject->setComponentEnergyMaintenanceRequirement(chassisSlot, componentEnergyMaintenanceRequirement)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipComponentEnergyMaintenanceRequirement (): component at slot [%d] error", chassisSlot)); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipComponentMass(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot, jfloat componentMass) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipComponentMass()", false, chassisSlot); + if (!shipObject) + return; + + if (!shipObject->setComponentMass(chassisSlot, componentMass)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipComponentMass (): component at slot [%d] error", chassisSlot)); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipComponentHitpointsCurrent(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot, jfloat componentHitpointsCurrent) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipComponentHitpointsCurrent()", false, chassisSlot); + if (!shipObject) + return; + + if (!shipObject->setComponentHitpointsCurrent(chassisSlot, componentHitpointsCurrent)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipComponentHitpointsCurrent (): component at slot [%d] error", chassisSlot)); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipComponentHitpointsMaximum(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot, jfloat componentHitpointsMaximum) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipComponentHitpointsMaximum()", false, chassisSlot); + if (!shipObject) + return; + + if (!shipObject->setComponentHitpointsMaximum(chassisSlot, componentHitpointsMaximum)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipComponentHitpointsMaximum (): component at slot [%d] error", chassisSlot)); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipComponentFlags(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot, jint componentFlags) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipComponentFlags()", false, chassisSlot); + if (!shipObject) + return; + + if (!shipObject->setComponentFlags(chassisSlot, componentFlags)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipComponentFlags (): component at slot [%d] error", chassisSlot)); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipComponentName(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot, jstring componentName) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipComponentName()", false, chassisSlot); + if (!shipObject) + return; + + if (componentName == NULL) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipComponentName (): null name")); + return; + } + + JavaStringParam const jsp(componentName); + Unicode::String nameString; + if (!JavaLibrary::convert(jsp, nameString)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipComponentName (): failed to convert name string")); + else + { + if (!shipObject->setComponentName(chassisSlot, nameString)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipComponentName (): component at slot [%d] error", chassisSlot)); + } +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipComponentDisabled(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot, jboolean componentDisabled) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipComponentDisabled()", false, chassisSlot); + if (!shipObject) + return; + + if (!shipObject->setComponentDisabled(chassisSlot, componentDisabled == JNI_TRUE)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipComponentDisabled (): component at slot [%d] error", chassisSlot)); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipComponentDisabledNeedsPower(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot, jboolean componentDisabledNeedsPower) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipComponentDisabledNeedsPower()", false, chassisSlot); + if (!shipObject) + return; + + if (!shipObject->setComponentDisabledNeedsPower(chassisSlot, componentDisabledNeedsPower == JNI_TRUE)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipComponentDisabledNeedsPower(): component at slot [%d] error", chassisSlot)); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipComponentLowPower(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot, jboolean componentLowPower) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipComponentLowPower()", false, chassisSlot); + if (!shipObject) + return; + + if (!shipObject->setComponentLowPower(chassisSlot, componentLowPower == JNI_TRUE)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipComponentLowPower (): component at slot [%d] error", chassisSlot)); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipWeaponDamageMaximum(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot, jfloat weaponDamageMaximum) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipWeaponDamageMaximum()", false, chassisSlot); + if (!shipObject) + return; + + if (!shipObject->setWeaponDamageMaximum(chassisSlot, weaponDamageMaximum)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipWeaponDamageMaximum (): component at slot [%d] error", chassisSlot)); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipWeaponDamageMinimum(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot, jfloat weaponDamageMinimum) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipWeaponDamageMinimum()", false, chassisSlot); + if (!shipObject) + return; + + if (!shipObject->setWeaponDamageMinimum(chassisSlot, weaponDamageMinimum)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipWeaponDamageMinimum (): component at slot [%d] error", chassisSlot)); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipWeaponEffectivenessShields(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot, jfloat weaponEffectivenessShields) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipWeaponEffectivenessShields()", false, chassisSlot); + if (!shipObject) + return; + + if (!shipObject->setWeaponEffectivenessShields(chassisSlot, weaponEffectivenessShields)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipWeaponEffectivenessShields (): component at slot [%d] error", chassisSlot)); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipWeaponEffectivenessArmor(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot, jfloat weaponEffectivenessArmor) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipWeaponEffectivenessArmor()", false, chassisSlot); + if (!shipObject) + return; + + if (!shipObject->setWeaponEffectivenessArmor(chassisSlot, weaponEffectivenessArmor)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipWeaponEffectivenessArmor (): component at slot [%d] error", chassisSlot)); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipWeaponEnergyPerShot(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot, jfloat weaponEnergyPerShot) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipWeaponEnergyPerShot()", false, chassisSlot); + if (!shipObject) + return; + + if (!shipObject->setWeaponEnergyPerShot(chassisSlot, weaponEnergyPerShot)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipWeaponEnergyPerShot (): component at slot [%d] error", chassisSlot)); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipWeaponRefireRate(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot, jfloat weaponRefireRate) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipWeaponRefireRate()", false, chassisSlot); + if (!shipObject) + return; + + if (!shipObject->setWeaponRefireRate(chassisSlot, weaponRefireRate)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipWeaponRefireRate (): component at slot [%d] error", chassisSlot)); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipWeaponEfficiencyRefireRate(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot, jfloat weaponEfficiencyRefireRate) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipWeaponEfficiencyRefireRate()", false, chassisSlot); + if (!shipObject) + return; + + if (!shipObject->setWeaponEfficiencyRefireRate(chassisSlot, weaponEfficiencyRefireRate)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipWeaponEfficiencyRefireRate (): component at slot [%d] error", chassisSlot)); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipWeaponAmmoCurrent(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot, jint weaponAmmoCurrent) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipWeaponAmmoCurrent()", false, chassisSlot); + if (!shipObject) + return; + + if (!shipObject->setWeaponAmmoCurrent(chassisSlot, weaponAmmoCurrent)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipWeaponAmmoCurrent (): component at slot [%d] error", chassisSlot)); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipWeaponAmmoMaximum(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot, jint weaponAmmoMaximum) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipWeaponAmmoMaximum()", false, chassisSlot); + if (!shipObject) + return; + + if (!shipObject->setWeaponAmmoMaximum(chassisSlot, weaponAmmoMaximum)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipWeaponAmmoMaximum (): component at slot [%d] error", chassisSlot)); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipWeaponAmmoType(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot, jint weaponAmmoType) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipWeaponAmmoType()", false, chassisSlot); + if (!shipObject) + return; + + if (!shipObject->setWeaponAmmoType(chassisSlot, static_cast(weaponAmmoType))) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipWeaponAmmoType (): component at slot [%d] error", chassisSlot)); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipShieldHitpointsFrontCurrent(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jfloat shieldHitpointsFrontCurrent) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipShieldHitpointsFrontCurrent()", false, ShipChassisSlotType::SCST_shield_0); + if (!shipObject) + return; + + if (!shipObject->setShieldHitpointsFrontCurrent(shieldHitpointsFrontCurrent)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipShieldHitpointsFrontCurrent (): component error")); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipShieldHitpointsFrontMaximum(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jfloat shieldHitpointsFrontMaximum) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipShieldHitpointsFrontMaximum()", false, ShipChassisSlotType::SCST_shield_0); + if (!shipObject) + return; + + if (!shipObject->setShieldHitpointsFrontMaximum(shieldHitpointsFrontMaximum)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipShieldHitpointsFrontMaximum (): component error")); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipShieldHitpointsBackCurrent(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jfloat shieldHitpointsBackCurrent) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipShieldHitpointsBackCurrent()", false, ShipChassisSlotType::SCST_shield_0); + if (!shipObject) + return; + + if (!shipObject->setShieldHitpointsBackCurrent(shieldHitpointsBackCurrent)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipShieldHitpointsBackCurrent (): component error")); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipShieldHitpointsBackMaximum(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jfloat shieldHitpointsBackMaximum) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipShieldHitpointsBackMaximum()", false, ShipChassisSlotType::SCST_shield_0); + if (!shipObject) + return; + + if (!shipObject->setShieldHitpointsBackMaximum(shieldHitpointsBackMaximum)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipShieldHitpointsBackMaximum (): component error")); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipShieldRechargeRate(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jfloat shieldRechargeRate) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipShieldRechargeRate()", false, ShipChassisSlotType::SCST_shield_0); + if (!shipObject) + return; + + if (!shipObject->setShieldRechargeRate(shieldRechargeRate)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipShieldRechargeRate (): component error")); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipCapacitorEnergyCurrent(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jfloat capacitorEnergyCurrent) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipCapacitorEnergyCurrent()", false, ShipChassisSlotType::SCST_capacitor); + if (!shipObject) + return; + + if (!shipObject->setCapacitorEnergyCurrent(capacitorEnergyCurrent)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipCapacitorEnergyCurrent (): component error")); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipCapacitorEnergyMaximum(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jfloat capacitorEnergyMaximum) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipCapacitorEnergyMaximum()", false, ShipChassisSlotType::SCST_capacitor); + if (!shipObject) + return; + + if (!shipObject->setCapacitorEnergyMaximum(capacitorEnergyMaximum)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipCapacitorEnergyMaximum (): component error")); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipCapacitorEnergyRechargeRate(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jfloat capacitorEnergyRechargeRate) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipCapacitorEnergyRechargeRate()", false, ShipChassisSlotType::SCST_capacitor); + if (!shipObject) + return; + + if (!shipObject->setCapacitorEnergyRechargeRate(capacitorEnergyRechargeRate)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipCapacitorEnergyRechargeRate (): component error")); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipEngineAccelerationRate(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jfloat engineAccelerationRate) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipEngineAccelerationRate()", false, ShipChassisSlotType::SCST_engine); + if (!shipObject) + return; + + if (!shipObject->setEngineAccelerationRate(engineAccelerationRate)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipEngineAccelerationRate (): component error")); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipEngineDecelerationRate(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jfloat engineDecelerationRate) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipEngineDecelerationRate()", false, ShipChassisSlotType::SCST_engine); + if (!shipObject) + return; + + if (!shipObject->setEngineDecelerationRate(engineDecelerationRate)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipEngineDecelerationRate (): component error")); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipEnginePitchAccelerationRateDegrees(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jfloat enginePitchAccelerationRateDegrees) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipEnginePitchAccelerationRateDegrees()", false, ShipChassisSlotType::SCST_engine); + if (!shipObject) + return; + + if (!shipObject->setEnginePitchAccelerationRate(convertDegreesToRadians(enginePitchAccelerationRateDegrees))) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipEnginePitchAccelerationRateDegrees (): component error")); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipEngineYawAccelerationRateDegrees(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jfloat engineYawAccelerationRateDegrees) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipEngineYawAccelerationRateDegrees()", false, ShipChassisSlotType::SCST_engine); + if (!shipObject) + return; + + if (!shipObject->setEngineYawAccelerationRate(convertDegreesToRadians(engineYawAccelerationRateDegrees))) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipEngineYawAccelerationRateDegrees (): component error")); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipEngineRollAccelerationRateDegrees(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jfloat engineRollAccelerationRateDegrees) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipEngineRollAccelerationRateDegrees()", false, ShipChassisSlotType::SCST_engine); + if (!shipObject) + return; + + if (!shipObject->setEngineRollAccelerationRate(convertDegreesToRadians(engineRollAccelerationRateDegrees))) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipEngineRollAccelerationRateDegrees (): component error")); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipEnginePitchRateMaximumDegrees(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jfloat enginePitchRateMaximumDegrees) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipEnginePitchRateMaximumDegrees()", false, ShipChassisSlotType::SCST_engine); + if (!shipObject) + return; + + if (!shipObject->setEnginePitchRateMaximum(convertDegreesToRadians(enginePitchRateMaximumDegrees))) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipEnginePitchRateMaximumDegrees (): component error")); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipEngineYawRateMaximumDegrees(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jfloat engineYawRateMaximumDegrees) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipEngineYawRateMaximumDegrees()", false, ShipChassisSlotType::SCST_engine); + if (!shipObject) + return; + + if (!shipObject->setEngineYawRateMaximum(convertDegreesToRadians(engineYawRateMaximumDegrees))) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipEngineYawRateMaximumDegrees (): component error")); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipEngineRollRateMaximumDegrees(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jfloat engineRollRateMaximumDegrees) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipEngineRollRateMaximumDegrees()", false, ShipChassisSlotType::SCST_engine); + if (!shipObject) + return; + + if (!shipObject->setEngineRollRateMaximum(convertDegreesToRadians(engineRollRateMaximumDegrees))) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipEngineRollRateMaximumDegrees (): component error")); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipEngineSpeedMaximum(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jfloat engineSpeedMaximum) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipEngineSpeedMaximum()", false, ShipChassisSlotType::SCST_engine); + if (!shipObject) + return; + + if (!shipObject->setEngineSpeedMaximum(engineSpeedMaximum)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipEngineSpeedMaximum (): component error")); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipEngineSpeedRotationFactorMaximum(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jfloat engineSpeedRotationRate) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipEngineSpeedRotationFactorMaximum()", false, ShipChassisSlotType::SCST_engine); + if (!shipObject) + return; + + if (!shipObject->setEngineSpeedRotationFactorMaximum(engineSpeedRotationRate)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipEngineSpeedRotationFactorMaximum(): component error %s", shipObject->getDebugInformation(false).c_str())); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipEngineSpeedRotationFactorMinimum(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jfloat engineSpeedRotationRate) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipEngineSpeedRotationFactorMinimum()", false, ShipChassisSlotType::SCST_engine); + if (!shipObject) + return; + + if (!shipObject->setEngineSpeedRotationFactorMinimum(engineSpeedRotationRate)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipEngineSpeedRotationFactorMinimum(): component error %s", shipObject->getDebugInformation(false).c_str())); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipEngineSpeedRotationFactorOptimal(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jfloat engineSpeedRotationRate) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipEngineSpeedRotationFactorOptimal()", false, ShipChassisSlotType::SCST_engine); + if (!shipObject) + return; + + if (!shipObject->setEngineSpeedRotationFactorOptimal(engineSpeedRotationRate)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipEngineSpeedRotationFactorOptimal(): component error %s", shipObject->getDebugInformation(false).c_str())); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipReactorEnergyGenerationRate(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jfloat reactorEnergyGenerationRate) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipReactorEnergyGenerationRate()", false, ShipChassisSlotType::SCST_reactor); + if (!shipObject) + return; + + if (!shipObject->setReactorEnergyGenerationRate(reactorEnergyGenerationRate)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipReactorEnergyGenerationRate (): component error")); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipBoosterEnergyCurrent(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jfloat boosterEnergyCurrent) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipBoosterEnergyCurrent()", false, ShipChassisSlotType::SCST_booster); + if (!shipObject) + return; + + if (!shipObject->setBoosterEnergyCurrent(boosterEnergyCurrent)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipBoosterEnergyCurrent (): component error")); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipBoosterEnergyMaximum(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jfloat boosterEnergyMaximum) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipBoosterEnergyMaximum()", false, ShipChassisSlotType::SCST_booster); + if (!shipObject) + return; + + if (!shipObject->setBoosterEnergyMaximum(boosterEnergyMaximum)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipBoosterEnergyMaximum (): component error")); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipBoosterEnergyRechargeRate(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jfloat boosterEnergyRechargeRate) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipBoosterEnergyRechargeRate()", false, ShipChassisSlotType::SCST_booster); + if (!shipObject) + return; + + if (!shipObject->setBoosterEnergyRechargeRate(boosterEnergyRechargeRate)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipBoosterEnergyRechargeRate (): component error")); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipBoosterEnergyConsumptionRate(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jfloat boosterEnergyConsumptionRate) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipBoosterEnergyConsumptionRate()", false, ShipChassisSlotType::SCST_booster); + if (!shipObject) + return; + + if (!shipObject->setBoosterEnergyConsumptionRate(boosterEnergyConsumptionRate)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipBoosterEnergyConsumptionRate (): component error")); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipBoosterAcceleration(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jfloat boosterAcceleration) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipBoosterAcceleration()", false, ShipChassisSlotType::SCST_booster); + if (!shipObject) + return; + + if (!shipObject->setBoosterAcceleration(boosterAcceleration)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipBoosterAcceleration (): component error")); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipBoosterSpeedMaximum(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jfloat boosterSpeedMaximum) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "isShipSlotInstalledActual()", false, ShipChassisSlotType::SCST_booster); + if (!shipObject) + return; + + if (!shipObject->setBoosterSpeedMaximum(boosterSpeedMaximum)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipBoosterSpeedMaximum (): component error")); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipDroidInterfaceCommandSpeed(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jfloat droidInterfaceCommandSpeed) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipDroidInterfaceCommandSpeed()", false, ShipChassisSlotType::SCST_droid_interface); + if (!shipObject) + return; + + if (!shipObject->setDroidInterfaceCommandSpeed(droidInterfaceCommandSpeed)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipDroidInterfaceCommandSpeed (): component error")); +} + +//---------------------------------------------------------------------- + +//-- component support + +jboolean JNICALL ScriptMethodsShipNamespace::shipCanInstallComponent(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot, jlong component) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return false; + + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "shipCanInstallComponent(): shipId obj_id did not resolve to a ShipObject", false); + if (!shipObject) + return false; + + TangibleObject * tangibleComponent = 0; + if (JavaLibrary::getObject (component, tangibleComponent) && tangibleComponent != NULL) + return shipObject->canInstallComponent(chassisSlot, *tangibleComponent); + else + { + JAVA_THROW_SCRIPT_EXCEPTION (true, ("shipCanInstallComponent(): invalid component")); + return false; + } +} + +//---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsShipNamespace::shipPseudoInstallComponent(JNIEnv *env, jobject, jlong jship, jint chassisSlot, jint componentCrc) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return false; + + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, jship, "shipInstallComponent(): ship obj_id did not resolve to a ShipObject", false); + if (!shipObject) + return false; + + return shipObject->pseudoInstallComponent(static_cast(chassisSlot), static_cast(componentCrc)); +} + +//---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsShipNamespace::shipInstallComponent(JNIEnv * env, jobject /*self*/, jlong jobject_installerId, jlong jobject_shipId, jint chassisSlot, jlong component) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return false; + + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "shipInstallComponent(): shipId obj_id did not resolve to a ShipObject", false); + if (!shipObject) + return false; + + NetworkId installerId(jobject_installerId); + + TangibleObject * tangibleComponent = 0; + if (JavaLibrary::getObject (component, tangibleComponent) && tangibleComponent != NULL) + return shipObject->installComponent(installerId, chassisSlot, *tangibleComponent); + else + { + JAVA_THROW_SCRIPT_EXCEPTION (true, ("shipInstallComponent(): invalid component")); + return false; + } +} + +//---------------------------------------------------------------------- +jlong JNICALL ScriptMethodsShipNamespace::shipUninstallComponentAllowOverload(JNIEnv * env, jobject self, jlong jobject_uninstallerId, jlong jobject_shipId, jint chassisSlot, jlong containerTarget) +{ + return shipUninstallComponentBase(env, self, jobject_uninstallerId, jobject_shipId, chassisSlot, containerTarget, true); +} + +jlong JNICALL ScriptMethodsShipNamespace::shipUninstallComponent(JNIEnv * env, jobject self, jlong jobject_uninstallerId, jlong jobject_shipId, jint chassisSlot, jlong containerTarget) +{ + return shipUninstallComponentBase(env, self, jobject_uninstallerId, jobject_shipId, chassisSlot, containerTarget, false); +} + +jlong JNICALL ScriptMethodsShipNamespace::shipUninstallComponentBase(JNIEnv * env, jobject /*self*/, jlong jobject_uninstallerId, jlong jobject_shipId, jint chassisSlot, jlong containerTarget, bool allowOverload) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return 0; + + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "shipUninstallComponent(): shipId obj_id did not resolve to a ShipObject", false); + if (!shipObject) + return 0; + + ServerObject * containerTargetObject = 0; + + if (containerTarget) + { + if (!JavaLibrary::getObject (containerTarget, containerTargetObject)) + { + JAVA_THROW_SCRIPT_EXCEPTION (true, ("shipUninstallComponent(): containerTarget did not resolve")); + return 0; + } + + NetworkId uninstallerId(jobject_uninstallerId); + + TangibleObject * const component = shipObject->uninstallComponent(uninstallerId, chassisSlot, *containerTargetObject, allowOverload); + if (component) + return (component->getNetworkId()).getValue(); + else + { + JAVA_THROW_SCRIPT_EXCEPTION (true, ("shipUninstallComponent(): invalid result component")); + return 0; + } + } + else + { + shipObject->purgeComponent (chassisSlot); + return 0; + } +} + + +//---------------------------------------------------------------------- + +jintArray JNICALL ScriptMethodsShipNamespace::getShipChassisSlots(JNIEnv * env, jobject /*self*/, jlong jobject_shipId) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return NULL; + + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipChassisSlots(): shipId obj_id did not resolve to a ShipObject", false); + if (!shipObject) + return NULL; + + ShipChassis const * const shipChassis = ShipChassis::findShipChassisByCrc (shipObject->getChassisType()); + if (shipChassis) + { + ShipChassis::SlotVector const & slots = shipChassis->getSlots (); + + LocalIntArrayRefPtr jslots = createNewIntArray(static_cast(slots.size ())); + if (jslots != LocalIntArrayRef::cms_nullPtr) + { + int index = 0; + for (ShipChassis::SlotVector::const_iterator it = slots.begin (); it != slots.end (); ++it, ++index) + { + ShipChassisSlot const & slot = *it; + jint value = static_cast(slot.getSlotType ()); + setIntArrayRegion(*jslots, index, 1, &value); + } + return jslots->getReturnValue(); + } + } + + return NULL; +} + +//---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsShipNamespace::getShipComponentDescriptorType(JNIEnv * /*env*/, jobject /*self*/, jlong jobject_component) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return static_cast(ShipComponentType::SCT_num_types); + + TangibleObject * tangibleComponent = 0; + if (JavaLibrary::getObject (jobject_component, tangibleComponent)) + { + if (tangibleComponent != NULL && tangibleComponent->getObjectTemplate () != NULL) + { + ShipComponentDescriptor const * const shipComponentDescriptor = + ShipComponentDescriptor::findShipComponentDescriptorByObjectTemplate (tangibleComponent->getObjectTemplate ()->getCrcName ().getCrc ()); + if (shipComponentDescriptor) + return static_cast(shipComponentDescriptor->getComponentType ()); + } + } + + return static_cast(ShipComponentType::SCT_num_types); +} + +//---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsShipNamespace::getShipComponentDescriptorTypeByName(JNIEnv * /*env*/, jobject /*self*/, jstring typeName) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return static_cast(ShipComponentType::SCT_num_types); + + JavaStringParam const jsp(typeName); + std::string nameString; + if (!JavaLibrary::convert(jsp, nameString)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::getShipComponentDescriptorTypeByName (): failed to convert typeName string")); + else + { + return ShipComponentType::getTypeFromName(nameString); + } + + return static_cast(ShipComponentType::SCT_num_types); +} + +//---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsShipNamespace::getShipComponentDescriptorTypeName(JNIEnv * /*env*/, jobject /*self*/, jint componentType) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return NULL; + + std::string const & typeName = ShipComponentType::getNameFromType(static_cast(componentType)); + + return JavaString(typeName).getReturnValue(); +} + +//---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsShipNamespace::getShipComponentDescriptorCrc(JNIEnv * /*env*/, jobject /*self*/, jlong jobject_component) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return static_cast(ShipComponentType::SCT_num_types); + + TangibleObject * tangibleComponent = 0; + if (JavaLibrary::getObject (jobject_component, tangibleComponent)) + { + if (tangibleComponent != NULL && tangibleComponent->getObjectTemplate () != NULL) + { + ShipComponentDescriptor const * const shipComponentDescriptor = + ShipComponentDescriptor::findShipComponentDescriptorByObjectTemplate (tangibleComponent->getObjectTemplate ()->getCrcName ().getCrc ()); + if (shipComponentDescriptor) + return static_cast(shipComponentDescriptor->getCrc ()); + } + } + + return 0; +} + +//---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsShipNamespace::getShipComponentDescriptorCrcName(JNIEnv * /*env*/, jobject /*self*/, jint componentCrc) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return NULL; + + ShipComponentDescriptor const * const shipComponentDescriptor = ShipComponentDescriptor::findShipComponentDescriptorByCrc(static_cast(componentCrc)); + if (shipComponentDescriptor == NULL) + return NULL; + + return JavaString(shipComponentDescriptor->getName().getString()).getReturnValue(); +} + +//---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsShipNamespace::getShipComponentDescriptorCompatibility(JNIEnv * /*env*/, jobject /*self*/, jint componentCrc) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return NULL; + + ShipComponentDescriptor const * const shipComponentDescriptor = ShipComponentDescriptor::findShipComponentDescriptorByCrc(static_cast(componentCrc)); + if (shipComponentDescriptor == NULL) + return NULL; + + return JavaString(shipComponentDescriptor->getCompatibility().getString()).getReturnValue(); +} + +//---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsShipNamespace::getShipComponentDescriptorWeaponIsAmmoConsuming(JNIEnv * /*env*/, jobject /*self*/, jint componentCrc) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return false; + + return ShipComponentWeaponManager::isAmmoConsuming(static_cast(componentCrc)); +} + +//---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsShipNamespace::getShipComponentDescriptorWeaponIsMissile(JNIEnv * /*env*/, jobject /*self*/, jint componentCrc) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return false; + + return ShipComponentWeaponManager::isMissile(static_cast(componentCrc)); +} + +//---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsShipNamespace::getShipComponentDescriptorWeaponIsCountermeasure(JNIEnv * /*env*/, jobject /*self*/, jint componentCrc) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return false; + + return ShipComponentWeaponManager::isCountermeasure(static_cast(componentCrc)); +} + +//---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsShipNamespace::getShipComponentDescriptorWeaponIsMining(JNIEnv * /*env*/, jobject /*self*/, jint componentCrc) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return false; + + return ShipComponentWeaponManager::isMining(static_cast(componentCrc)); +} + +//---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsShipNamespace::getShipComponentDescriptorWeaponIsTractor(JNIEnv * /*env*/, jobject /*self*/, jint componentCrc) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return false; + + return ShipComponentWeaponManager::isTractor(static_cast(componentCrc)); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipComponentDescriptorWeaponRange(JNIEnv * /*env*/, jobject /*self*/, jint componentCrc) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return 0.0f; + + return ShipComponentWeaponManager::getRange(static_cast(componentCrc)); +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipComponentDescriptorWeaponProjectileSpeed(JNIEnv * /*env*/, jobject /*self*/, jint componentCrc) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return 0.0f; + + return ShipComponentWeaponManager::getProjectileSpeed(static_cast(componentCrc)); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::notifyShipDamage(JNIEnv * env, jobject /*self*/, jlong jobject_victim, jlong jobject_attacker, jfloat totalDamage) +{ + //-- Make sure ships are enabled + if (!verifyShipsEnabled()) + return; + + //-- Get the victim ship object. + ShipObject * const victimShipObject = JavaLibrary::getShipThrow(env, jobject_victim, "notifyShipDamage(): jobject_victim did not resolve to a ShipObject", false); + if (victimShipObject) + { + //-- Ensure we have a player controlled ship object. + if (victimShipObject->isPlayerShip()) + { + //-- Get the attacker object. It can be any tangible object. + TangibleObject const * attackerTangibleObject = NULL; + if (jobject_attacker) + IGNORE_RETURN(JavaLibrary::getObject(jobject_attacker, attackerTangibleObject)); + + Controller * const victimShipController = victimShipObject->getController(); + if (victimShipController) + { + ShipDamageMessage shipDamage(attackerTangibleObject != NULL ? attackerTangibleObject->getNetworkId() : NetworkId::cms_invalid, + attackerTangibleObject != NULL ? attackerTangibleObject->getPosition_w() : victimShipObject->getPosition_w(), + totalDamage ); + + //lint -esym(429, damageMessage) + + MessageQueueGenericValueType * const damageMessage = new MessageQueueGenericValueType(shipDamage); + + victimShipController->appendMessage(CM_shipDamageMessage, 0.0f, damageMessage, + GameControllerMessageFlags::SEND | + GameControllerMessageFlags::RELIABLE | + GameControllerMessageFlags::DEST_AUTH_CLIENT); + } + } + } +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsShipNamespace::launchMissile(JNIEnv * /*env*/, jobject /*self*/, jlong jplayer, jlong jship, jlong jtarget, jint missileInfo, jint targetedComponent) +{ + if (!verifyShipsEnabled()) + return false; + + const TangibleObject * player = 0; + if (!JavaLibrary::getObject (jplayer, player)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::launchMissile: could not resolve player")); + return JNI_FALSE; + } + + const TangibleObject * ship = 0; + if (!JavaLibrary::getObject (jship, ship)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::launchMissile: could not resolve ship")); + return JNI_FALSE; + } + + const TangibleObject * target = 0; + if (!JavaLibrary::getObject (jtarget, target)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::launchMissile: could not resolve target")); + return JNI_FALSE; + } + + if (player && ship && target) + return MissileManager::getInstance().requestFireMissile(player->getNetworkId(), ship->getNetworkId(), target->getNetworkId(), -1, missileInfo, getSlotType(targetedComponent)); + else + return JNI_FALSE; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsShipNamespace::launchCountermeasure(JNIEnv * /*env*/, jobject /*self*/, jlong ship, jint targettedMissile, jboolean successful, jint countermeasureType) +{ + if (!verifyShipsEnabled()) + return false; + + NetworkId const shipId(ship); + + bool result= MissileManager::getInstance().fireCountermeasure(shipId, targettedMissile, (successful==static_cast(JNI_TRUE)), countermeasureType); + return result ? static_cast(JNI_TRUE) : static_cast(JNI_FALSE); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsShipNamespace::getNearestUnlockedMissileForTarget(JNIEnv * /*env*/, jobject /*self*/, jlong jtarget) +{ + return MissileManager::getInstance().getNearestUnlockedMissileForTarget(NetworkId(jtarget)); +} + +// ---------------------------------------------------------------------- + +jintArray JNICALL ScriptMethodsShipNamespace::getAllUnlockedMissilesForTarget(JNIEnv * env, jobject /*self*/, jlong jtarget) +{ + std::vector missiles; + MissileManager::getInstance().getAllUnlockedMissilesForTarget(NetworkId(jtarget),missiles); + + LocalIntArrayRefPtr results = createNewIntArray(static_cast(missiles.size())); + + setIntArrayRegion(*results, 0 , static_cast(missiles.size()), reinterpret_cast(&(missiles[0]))); + return results->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsShipNamespace::destroyMissile(JNIEnv * /*env*/, jobject /*self*/, jint missileId) +{ + return (MissileManager::getInstance().destroyMissile(missileId)) ? static_cast(JNI_TRUE) : static_cast(JNI_FALSE); +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsShipNamespace::getTypeByMissile(JNIEnv * /*env*/, jobject /*self*/, jint missileId) +{ + const Missile* missile = MissileManager::getInstance().getConstMissile(missileId); + if (missile) + return missile->getType(); + else + return -1; +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsShipNamespace::getWeaponIndexByMissile(JNIEnv * /*env*/, jobject /*self*/, jint missileId) +{ + const Missile* missile = MissileManager::getInstance().getConstMissile(missileId); + if (missile) + return missile->getWeaponIndex(); + else + return -1; +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsShipNamespace::getTimeSinceFiredByMissile(JNIEnv * /*env*/, jobject /*self*/, jint missileId) +{ + const Missile* missile = MissileManager::getInstance().getConstMissile(missileId); + if (missile) + return missile->getTimeSinceFired(); + else + return -1; +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsShipNamespace::getTotalTimeByMissile(JNIEnv * /*env*/, jobject /*self*/, jint missileId) +{ + const Missile* missile = MissileManager::getInstance().getConstMissile(missileId); + if (missile) + return missile->getTotalTime(); + else + return -1; +} + +// ---------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsShipNamespace::getWhoFiredByMissile(JNIEnv * /*env*/, jobject /*self*/, jint missileId) +{ + const Missile* missile = MissileManager::getInstance().getConstMissile(missileId); + if (missile) + return (missile->getSource()).getValue(); + else + return 0; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsShipNamespace::setLookAtTargetShipComponent(JNIEnv * env, jobject /*self*/, jlong jship, jint targetedComponentChassisSlot) +{ + if (!verifyShipsEnabled()) + return JNI_FALSE; + + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, jship, "setLookAtTargetShipComponent(): shipId obj_id did not resolve to a ShipObject", false); + if (!shipObject) + return JNI_FALSE; + + shipObject->setPilotLookAtTargetSlot(getSlotType(targetedComponentChassisSlot)); + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsShipNamespace::getLookAtTargetShipComponent(JNIEnv * env, jobject /*self*/, jlong jship) +{ + if (!verifyShipsEnabled()) + return static_cast(ShipChassisSlotType::SCST_num_types); + + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, jship, "getLookAtTargetShipComponent(): shipId obj_id did not resolve to a ShipObject", false); + if (!shipObject) + return static_cast(ShipChassisSlotType::SCST_num_types); + + return static_cast(shipObject->getPilotLookAtTargetSlot()); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsShipNamespace::associateDroidControlDeviceWithShip(JNIEnv * env, jobject /*self*/, jlong jship, jlong jdroidControlDevice) +{ + if (!verifyShipsEnabled()) + return JNI_FALSE; + + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, jship, "associateDroidControlDeviceWithShip(): shipId obj_id did not resolve to a ShipObject", false); + if (!shipObject) + return JNI_FALSE; + + const ServerObject * droidControlDevice = 0; + if (!JavaLibrary::getObject (jdroidControlDevice, droidControlDevice)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::associateDroidControlDeviceWithShip: could not resolve droid control device")); + return JNI_FALSE; + } + + shipObject->setInstalledDroidControlDevice(droidControlDevice->getNetworkId()); + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsShipNamespace::removeDroidControlDeviceFromShip(JNIEnv * env, jobject /*self*/, jlong jship) +{ + if (!verifyShipsEnabled()) + return JNI_FALSE; + + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, jship, "removeDroidControlDeviceFromShip(): shipId obj_id did not resolve to a ShipObject", false); + if (!shipObject) + return JNI_FALSE; + + shipObject->setInstalledDroidControlDevice(NetworkId::cms_invalid); + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsShipNamespace::getDroidControlDeviceForShip(JNIEnv * env, jobject /*self*/, jlong jship) +{ + if (!verifyShipsEnabled()) + return JNI_FALSE; + + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jship, "getDroidControlDeviceForShip(): shipId obj_id did not resolve to a ShipObject", false); + if (!shipObject) + return JNI_FALSE; + + NetworkId const & droidControlDeviceId = shipObject->getInstalledDroidControlDevice(); + Object const * const droidControlDevice = NetworkIdManager::getObjectById(droidControlDeviceId); + ServerObject const * const serverDroidControlDevice = droidControlDevice ? droidControlDevice->asServerObject() : NULL; + if(!serverDroidControlDevice) + return 0; + else + return (serverDroidControlDevice->getNetworkId()).getValue(); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::commPlayers(JNIEnv *env, jobject /*self*/, jlong jtaunter, jstring jappearanceOverloadServerTemplate, jstring jSoundEffect, jfloat jDuration, jlongArray jplayers, jstring jtauntOob, jboolean chronicles) +{ + ServerObject const *taunter = 0; + if (!JavaLibrary::getObject(jtaunter, taunter)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::commPlayers: could not resolve taunter")); + return; + } + + Unicode::String oob; + if (jtauntOob) + { + JavaStringParam localTauntOob(jtauntOob); + if (!JavaLibrary::convert(localTauntOob, oob)) + { + JAVA_THROW_SCRIPT_EXCEPTION (true, ("JavaLibrary::commPlayers unable to convert tauntOob")); + return; + } + } + + Unicode::String appearanceOverloadServerTemplateWide; + if (jappearanceOverloadServerTemplate) + { + JavaStringParam localAppearanceOverloadServerTemplate(jappearanceOverloadServerTemplate); + if (!JavaLibrary::convert(localAppearanceOverloadServerTemplate, appearanceOverloadServerTemplateWide)) + { + JAVA_THROW_SCRIPT_EXCEPTION (true, ("JavaLibrary::commPlayers unable to convert jappearanceOverloadServerTemplate to a string")); + return; + } + } + + uint32 appearanceOverloadSharedTemplateCrc = 0; + ObjectTemplate const * const ot = ObjectTemplateList::fetch(Unicode::wideToNarrow(appearanceOverloadServerTemplateWide)); + ServerObjectTemplate const * const sot = ot ? ot->asServerObjectTemplate() : NULL; + if(sot) + { + std::string const & sharedTemplateName = sot->getSharedTemplate(); + appearanceOverloadSharedTemplateCrc = Crc::calculate(sharedTemplateName.c_str()); + } + + typedef std::map > DistributionList; + DistributionList distributionList; + + jsize const count = env->GetArrayLength(jplayers); + jlong jlongTmp; + for (jsize i = 0; i < count; ++i) + { + ServerObject const *player = 0; + env->GetLongArrayRegion(jplayers, i, 1, &jlongTmp); + if (JavaLibrary::getObject(jlongTmp, player)) + { + Client * const client = player->getClient(); + if (client) + distributionList[client->getConnection()].push_back(client->getCharacterObjectId()); + } + } + + std::string soundEffect; + if (jSoundEffect) + { + JavaStringParam soundEffectParam(jSoundEffect); + if (!JavaLibrary::convert(soundEffectParam, soundEffect)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::commPlayers unable to convert jSoundEffect to a string.")); + return; + } + } + + bool chroniclesMessage = (chronicles == JNI_TRUE ? true : false); + if (!distributionList.empty()) + { + GenericValueTypeMessage > > > > > const message("CommPlayerMessage", std::make_pair(chroniclesMessage, std::make_pair(taunter->getNetworkId(), std::make_pair(oob, std::make_pair(appearanceOverloadSharedTemplateCrc, std::make_pair(soundEffect, jDuration)))))); + for (DistributionList::const_iterator iter = distributionList.begin(); iter != distributionList.end(); ++iter) + { + GameClientMessage const gcm( + (*iter).second, + true, + message); + (*iter).first->send(gcm, true); + } + } +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipSlotTargetable(JNIEnv * env, jobject /*self*/, jlong jshipId, jint slot, jboolean targetable) +{ + if (!verifyShipsEnabled()) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipComponentTargetable ships not enabled")); + return; + } + + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, jshipId, "setShipComponentTargetable(): shipId obj_id did not resolve to a ShipObject", false); + if (!shipObject) + return; + + if(targetable) + shipObject->setSlotTargetable(getSlotType(slot)); + else + shipObject->clearSlotTargetable(getSlotType(slot)); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsShipNamespace::isShipSlotTargetable(JNIEnv * env, jobject /*self*/, jlong jshipId, jint slot) +{ + if (!verifyShipsEnabled()) + return JNI_FALSE; + + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, jshipId, "getShipComponentTargetable(): shipId obj_id did not resolve to a ShipObject", false); + if (!shipObject) + return JNI_FALSE; + + bool const result = shipObject->getSlotTargetable(getSlotType(slot)); + if(result) + return JNI_TRUE; + else + return JNI_FALSE; +} + +//-------------------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsShipNamespace::launchShipFromHangar(JNIEnv *env, jobject /*self*/, jlong jlaunchingShipId, jstring templateToSpawn, jobject deltaFromHangarHardpoint) +{ + if (!verifyShipsEnabled()) + return 0; + + //convert ship + ShipObject * const launchingShip = JavaLibrary::getShipThrow(env, jlaunchingShipId, "getShipComponentTargetable(): shipId obj_id did not resolve to a ShipObject", false); + if (!launchingShip) + return 0; + + //convert transform + Transform deltaFromHangarTransform; + if (!ScriptConversion::convert(deltaFromHangarHardpoint, deltaFromHangarTransform)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("[designer bug] JavaLibrary::spawnShipFromHangar called with bad transform")); + return 0; + } + + // get the template name into an std::string + JavaStringParam const localSource(templateToSpawn); + std::string templateName; + IGNORE_RETURN(JavaLibrary::convert(localSource, templateName)); + + ConstCharCrcString const crcName(ObjectTemplateList::lookUp(templateName.c_str())); + if (crcName.getCrc() == 0) + + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("[designer bug] JavaLibrary::spawnShipFromHangar called with unknown template %s", templateName.c_str())); + return 0; + } + + //put spawned ship in same cell as the launching ship + ServerObject *cell = 0; + CellProperty * const cellProperty = launchingShip->getParentCell(); + if (cellProperty && cellProperty != CellProperty::getWorldCellProperty()) + cell = safe_cast(&cellProperty->getOwner()); + + //get the hardpoint from the launching ship + Transform hangarHardpointDelta; + Appearance const * const launchingShipAppearance = launchingShip->getAppearance(); + if(launchingShipAppearance) + { + static char const * const hangarHardpointName = "hangar"; + if (!launchingShipAppearance->findHardpoint(ConstCharCrcLowerString(hangarHardpointName), hangarHardpointDelta)) + WARNING(true, ("JavaLibrary::launchShipFromHangar - could not find hangar hardpoint [%s] for %s, launching from center of ship", hangarHardpointName, launchingShip->getNetworkId().getValueString().c_str())); + } + else + { + WARNING(true, ("JavaLibrary::launchShipFromHangar - could not find hangar %s, which has no appearance.", launchingShip->getNetworkId().getValueString().c_str())); + } + + //build the final hangar offset from the hangar hardpoint transform and the delta transform from script + Transform finalHangarDelta_o(Transform::IF_none); + finalHangarDelta_o.multiply(hangarHardpointDelta, deltaFromHangarTransform); + Transform const & finalCreateTransform = launchingShip->getTransform_o2p().rotateTranslate_l2p(finalHangarDelta_o); + + ServerObject * const newShip = ServerWorld::createNewObject(crcName.getCrc(), finalCreateTransform, cell, false); + if (newShip == NULL) + return 0; + + // create an objId to return + NetworkId netId = newShip->getNetworkId(); + if (netId == NetworkId::cms_invalid) + { + delete newShip; + return 0; + } + + if (!cell) + newShip->addToWorld(); + + return netId.getValue(); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::handleShipDestruction(JNIEnv * env, jobject /*self*/, jlong jship, jfloat severity) +{ + if (!verifyShipsEnabled()) + return; + + //convert ship + ShipObject * const ship = JavaLibrary::getShipThrow(env, jship, "handleShipDestruction(): shipId obj_id did not resolve to a ShipObject", false); + if (ship == NULL) + return; + + DestroyShipMessage const msg(ship->getNetworkId(), severity); + sendGameNetworkMessageToObservers(*ship, msg, true); + + if (ship->isPlayerShip()) + Pvp::removeDuelEnemyFlags(*ship, NetworkId::cms_invalid); + else + IGNORE_RETURN(ship->permanentlyDestroy(DeleteReasons::Script)); + + //@todo: we must handle player ship destruction differently +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::handleShipComponentDestruction(JNIEnv * env, jobject /*self*/, jlong jship, jint chassisSlot, jfloat severity) +{ + ShipObject * const ship = getShipThrowTestSlot(env, jship, "handleShipComponentDestruction()", false, chassisSlot); + if (!ship) + return; + + DestroyShipComponentMessage const msg(ship->getNetworkId(), chassisSlot, severity); + sendGameNetworkMessageToObservers(*ship, msg, true); + + ship->purgeComponent(chassisSlot); +} + +// ---------------------------------------------------------------------- + +jlongArray JNICALL ScriptMethodsShipNamespace::getObservedShips(JNIEnv *, jobject, jlong jsource, jboolean excludeSource) +{ + ServerObject const *source = 0; + if (JavaLibrary::getObject(jsource, source)) + { + std::vector visibleObjects; + SpaceVisibilityManager::getObjectsVisibleFromLocation(source->getPosition_w(), visibleObjects); + if (!visibleObjects.empty()) + { + std::vector results(visibleObjects.size()); + for (std::vector::const_iterator i = visibleObjects.begin(); i != visibleObjects.end(); ++i) + if ( (*i)->asShipObject() + && ((*i) != source || !excludeSource)) + results.push_back(*i); + if (!results.empty()) + { + LocalLongArrayRefPtr rv; + if (ScriptConversion::convert(results, rv)) + return rv->getReturnValue(); + } + } + } + return 0; +} + +// ---------------------------------------------------------------------- + +jlongArray JNICALL ScriptMethodsShipNamespace::getObservedPlayerShips(JNIEnv *, jobject, jlong jsource, jboolean excludeSource) +{ + ServerObject const *source = 0; + if (JavaLibrary::getObject(jsource, source)) + { + std::vector visibleObjects; + SpaceVisibilityManager::getObjectsVisibleFromLocation(source->getPosition_w(), visibleObjects); + if (!visibleObjects.empty()) + { + std::vector results(visibleObjects.size()); + for (std::vector::const_iterator i = visibleObjects.begin(); i != visibleObjects.end(); ++i) + { + ShipObject * const ship = (*i)->asShipObject(); + if ( ship + && ship->isPlayerShip() + && ((*i) != source || !excludeSource)) + results.push_back(*i); + } + if (!results.empty()) + { + LocalLongArrayRefPtr rv; + if (ScriptConversion::convert(results, rv)) + return rv->getReturnValue(); + } + } + } + return 0; +} + +// ---------------------------------------------------------------------- + +jlongArray JNICALL ScriptMethodsShipNamespace::getObservedEnemyShips(JNIEnv *, jobject, jlong jsource) +{ + ShipObject const *source = 0; + if (JavaLibrary::getObject(jsource, source)) + { + std::vector visibleObjects; + SpaceVisibilityManager::getObjectsVisibleFromLocation(source->getPosition_w(), visibleObjects); + if (!visibleObjects.empty()) + { + std::vector results(visibleObjects.size()); + for (std::vector::const_iterator i = visibleObjects.begin(); i != visibleObjects.end(); ++i) + { + ShipObject * const ship = (*i)->asShipObject(); + if ( ship + && Pvp::isEnemy(*source, *ship)) + results.push_back(*i); + } + if (!results.empty()) + { + LocalLongArrayRefPtr rv; + if (ScriptConversion::convert(results, rv)) + return rv->getReturnValue(); + } + } + } + return 0; +} + +// ---------------------------------------------------------------------- + +jlongArray JNICALL ScriptMethodsShipNamespace::getObservedEnemyPlayerShips(JNIEnv *, jobject, jlong jsource) +{ + ShipObject const *source = 0; + if (JavaLibrary::getObject(jsource, source)) + { + std::vector visibleObjects; + SpaceVisibilityManager::getObjectsVisibleFromLocation(source->getPosition_w(), visibleObjects); + if (!visibleObjects.empty()) + { + std::vector results(visibleObjects.size()); + for (std::vector::const_iterator i = visibleObjects.begin(); i != visibleObjects.end(); ++i) + { + ShipObject * const ship = (*i)->asShipObject(); + if ( ship + && ship->isPlayerShip() + && Pvp::isEnemy(*source, *ship)) + results.push_back(*i); + } + if (!results.empty()) + { + LocalLongArrayRefPtr rv; + if (ScriptConversion::convert(results, rv)) + return rv->getReturnValue(); + } + } + } + return 0; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsShipNamespace::setShipInternalDamageOverTime(JNIEnv * env, jobject, jlong jship, jint chassisSlot, jfloat damageRate, jfloat damageThreshold) +{ + ShipObject * const ship = getShipThrowTestSlot(env, jship, "setShipInternalDamageOverTime()", false, chassisSlot); + if (!ship) + return false; + + return ShipInternalDamageOverTimeManager::setEntry(*ship, chassisSlot, damageRate, damageThreshold); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsShipNamespace::removeShipInternalDamageOverTime(JNIEnv * env, jobject, jlong jship, jint chassisSlot) +{ + ShipObject * const ship = getShipThrowTestSlot(env, jship, "removeShipInternalDamageOverTime()", false, chassisSlot); + if (!ship) + return false; + + return ShipInternalDamageOverTimeManager::removeEntry(*ship, chassisSlot); +} + +// ---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipInternalDamageOverTimeDamageRate(JNIEnv * env, jobject, jlong jship, jint chassisSlot) +{ + ShipObject * const ship = getShipThrowTestSlot(env, jship, "getShipInternalDamageOverTimeDamageThreshold()", false, chassisSlot); + if (!ship) + return 0.0f; + + static ShipInternalDamageOverTime const * const idot = ShipInternalDamageOverTimeManager::findEntry(*ship, chassisSlot); + if (idot == NULL) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::getShipInternalDamageOverTimeDamageThreshold idot for [%s] slot [%d] not found", ship->getNetworkId().getValueString().c_str(), chassisSlot)); + return 0.0f; + } + + return idot->getDamageRate(); +} + +// ---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipInternalDamageOverTimeDamageThreshold(JNIEnv * env, jobject, jlong jship, jint chassisSlot) +{ + ShipObject * const ship = getShipThrowTestSlot(env, jship, "getShipInternalDamageOverTimeDamageThreshold()", false, chassisSlot); + if (!ship) + return 0.0f; + + static ShipInternalDamageOverTime const * const idot = ShipInternalDamageOverTimeManager::findEntry(*ship, chassisSlot); + if (idot == NULL) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::getShipInternalDamageOverTimeDamageThreshold idot for [%s] slot [%d] not found", ship->getNetworkId().getValueString().c_str(), chassisSlot)); + return 0.0f; + } + + return idot->getDamageThreshold(); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsShipNamespace::hasShipInternalDamageOverTime(JNIEnv * env, jobject, jlong jship, jint chassisSlot) +{ + if (!verifyShipsEnabled()) + return false; + + //convert ship + ShipObject * const ship = JavaLibrary::getShipThrow(env, jship, "hasShipInternalDamageOverTime(): shipId obj_id did not resolve to a ShipObject", false); + if (ship == NULL) + return false; + + static ShipInternalDamageOverTime const * const idot = ShipInternalDamageOverTimeManager::findEntry(*ship, chassisSlot); + return idot != NULL; +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsShipNamespace::shipGetSpaceFaction(JNIEnv *env, jobject, jlong jship) +{ + ShipObject const * const ship = JavaLibrary::getShipThrow(env, jship, "shipGetSpaceFaction(): shipId obj_id did not resolve to a ShipObject", false); + if (ship) + return static_cast(ship->getSpaceFaction()); + return 0; +} + +// ---------------------------------------------------------------------- + +jintArray JNICALL ScriptMethodsShipNamespace::shipGetSpaceFactionAllies(JNIEnv *env, jobject, jlong jship) +{ + ShipObject const * const ship = JavaLibrary::getShipThrow(env, jship, "shipGetSpaceFactionAllies(): shipId obj_id did not resolve to a ShipObject", false); + if (ship) + { + std::vector const &factionList = ship->getSpaceFactionAllies(); + if (!factionList.empty()) + { + LocalIntArrayRefPtr ret = createNewIntArray(static_cast(factionList.size())); + setIntArrayRegion(*ret, 0, static_cast(factionList.size()), reinterpret_cast(const_cast(&factionList[0]))); + return ret->getReturnValue(); + } + } + return 0; +} + +// ---------------------------------------------------------------------- + +jintArray JNICALL ScriptMethodsShipNamespace::shipGetSpaceFactionEnemies(JNIEnv *env, jobject, jlong jship) +{ + ShipObject const * const ship = JavaLibrary::getShipThrow(env, jship, "shipGetSpaceFactionEnemies(): shipId obj_id did not resolve to a ShipObject", false); + if (ship) + { + std::vector const &factionList = ship->getSpaceFactionEnemies(); + if (!factionList.empty()) + { + LocalIntArrayRefPtr ret = createNewIntArray(static_cast(factionList.size())); + setIntArrayRegion(*ret, 0, static_cast(factionList.size()), reinterpret_cast(const_cast(&factionList[0]))); + return ret->getReturnValue(); + } + } + return 0; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsShipNamespace::shipGetSpaceFactionIsAggro(JNIEnv *env, jobject, jlong jship) +{ + ShipObject const * const ship = JavaLibrary::getShipThrow(env, jship, "shipGetSpaceFactionIsAggro(): shipId obj_id did not resolve to a ShipObject", false); + if (ship) + return static_cast(ship->getSpaceFactionIsAggro()); + return JNI_FALSE; +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::shipSetSpaceFaction(JNIEnv *env, jobject, jlong jship, jint spaceFaction) +{ + ShipObject * const ship = JavaLibrary::getShipThrow(env, jship, "shipSetSpaceFaction(): shipId obj_id did not resolve to a ShipObject", false); + if (ship) + ship->setSpaceFaction(static_cast(spaceFaction)); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::shipSetSpaceFactionAllies(JNIEnv *env, jobject, jlong jship, jintArray jfactionList) +{ + ShipObject * const ship = JavaLibrary::getShipThrow(env, jship, "shipSetSpaceFactionAllies(): shipId obj_id did not resolve to a ShipObject", false); + if (ship) + { + std::vector factionList; + if (jfactionList) + { + unsigned int const factionCount = static_cast(env->GetArrayLength(jfactionList)); + if (factionCount > 0) + { + factionList.reserve(factionCount); + jint * const factionArray = env->GetIntArrayElements(jfactionList, 0); + for (unsigned int i = 0; i < factionCount; ++i) + factionList.push_back(static_cast(factionArray[i])); + env->ReleaseIntArrayElements(jfactionList, factionArray, JNI_ABORT); + } + } + ship->setSpaceFactionAllies(factionList); + } +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::shipSetSpaceFactionEnemies(JNIEnv *env, jobject, jlong jship, jintArray jfactionList) +{ + ShipObject * const ship = JavaLibrary::getShipThrow(env, jship, "shipSetSpaceFactionEnemies(): shipId obj_id did not resolve to a ShipObject", false); + if (ship) + { + std::vector factionList; + if (jfactionList) + { + unsigned int const factionCount = static_cast(env->GetArrayLength(jfactionList)); + if (factionCount > 0) + { + factionList.reserve(factionCount); + jint * const factionArray = env->GetIntArrayElements(jfactionList, 0); + for (unsigned int i = 0; i < factionCount; ++i) + factionList.push_back(static_cast(factionArray[i])); + env->ReleaseIntArrayElements(jfactionList, factionArray, JNI_ABORT); + } + } + ship->setSpaceFactionEnemies(factionList); + } +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::shipSetSpaceFactionIsAggro(JNIEnv *env, jobject, jlong jship, jboolean isAggro) +{ + ShipObject * const ship = JavaLibrary::getShipThrow(env, jship, "shipSetSpaceFactionIsAggro(): shipId obj_id did not resolve to a ShipObject", false); + if (ship) + ship->setSpaceFactionIsAggro(isAggro ? true : false); +} + +//---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsShipNamespace::shipIsInNebula(JNIEnv *env, jobject, jlong jship, jstring j_nebulaName) +{ + ShipObject * const ship = JavaLibrary::getShipThrow(env, jship, "shipIsInNebula(): shipId obj_id did not resolve to a ShipObject", false); + if (!ship) + return JNI_FALSE; + + std::string nebulaName; + + if (NULL != j_nebulaName) + { + JavaStringParam const jsp(j_nebulaName); + if (!JavaLibrary::convert(jsp, nebulaName)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::shipIsInNebula (): failed to convert nebulaName string")); + } + + ShipObject::IntVector const & nebulas = ship->getNebulas(); + + //-- empty nebula name matches any nebula + if (nebulaName.empty() && !nebulas.empty()) + return JNI_TRUE; + + for (ShipObject::IntVector::const_iterator it = nebulas.begin(); it != nebulas.end(); ++it) + { + int const id = *it; + Nebula const * const nebula = NebulaManager::getNebulaById(id); + if (NULL != nebula) + { + if (nebula->getName() == nebulaName) + return JNI_TRUE; + } + } + + return JNI_FALSE; +} + +//---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsShipNamespace::setShipWingName(JNIEnv * /*env*/, jobject /*self*/, jlong target, jstring jstr) +{ + ServerObject * object = 0; + if(!JavaLibrary::getObject(target, object)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipWingName (): failed to convert target")); + return JNI_FALSE; + } + ShipObject * const ship = object->asShipObject(); + if(!ship) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipWingName (): target not a ship")); + return JNI_FALSE; + } + + JavaStringParam const jsp(jstr); + std::string wingName; + if (!JavaLibrary::convert(jsp, wingName)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipWingName (): failed to convert mobileName string")); + return JNI_FALSE; + } + + ship->setWingName(wingName); + + return JNI_TRUE; +} + +//---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsShipNamespace::getShipWingName(JNIEnv * /*env*/, jobject /*self*/, jlong target) +{ + ServerObject const * object = NULL; + if (!JavaLibrary::getObject(target, object)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::getShipWingName (): could not convert the target")); + return 0; + } + ShipObject const * const ship = object->asShipObject(); + if(!ship) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::getShipWingName (): target is not a ship")); + return 0; + } + + return JavaString(ship->getWingName()).getReturnValue(); +} + +//---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsShipNamespace::setShipTypeName(JNIEnv * /*env*/, jobject /*self*/, jlong target, jstring jstr) +{ + ServerObject * object = 0; + if(!JavaLibrary::getObject(target, object)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipTypeName (): failed to convert target")); + return JNI_FALSE; + } + ShipObject * const ship = object->asShipObject(); + if(!ship) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipTypeName (): target not a ship")); + return JNI_FALSE; + } + + JavaStringParam const jsp(jstr); + std::string typeName; + if (!JavaLibrary::convert(jsp, typeName)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipWingName (): failed to convert mobileName string")); + return JNI_FALSE; + } + ship->setTypeName(typeName); + + return JNI_TRUE; +} + +//---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsShipNamespace::getShipTypeName(JNIEnv * /*env*/, jobject /*self*/, jlong target) +{ + ServerObject const * object = NULL; + if (!JavaLibrary::getObject(target, object)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::getShipTypeName (): could not convert the target")); + return 0; + } + ShipObject const * const ship = object->asShipObject(); + if(!ship) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::getShipTypeName (): target is not a ship")); + return 0; + } + + return JavaString(ship->getTypeName()).getReturnValue(); +} + +//---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsShipNamespace::setShipDifficulty(JNIEnv * /*env*/, jobject /*self*/, jlong target, jstring jstr) +{ + ServerObject * object = 0; + if(!JavaLibrary::getObject(target, object)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipDifficultyName (): failed to convert target")); + return JNI_FALSE; + } + ShipObject * const ship = object->asShipObject(); + if(!ship) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipDifficultyName (): target not a ship")); + return JNI_FALSE; + } + + JavaStringParam const jsp(jstr); + std::string difficulty; + if (!JavaLibrary::convert(jsp, difficulty)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipWingName (): failed to convert mobileName string")); + return JNI_FALSE; + } + ship->setDifficulty(difficulty); + + return JNI_TRUE; +} + +//---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsShipNamespace::getShipDifficulty(JNIEnv * /*env*/, jobject /*self*/, jlong target) +{ + ServerObject const * object = NULL; + if (!JavaLibrary::getObject(target, object)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::getShipDifficulty (): could not convert the target")); + return 0; + } + ShipObject const * const ship = object->asShipObject(); + if(!ship) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::getShipDifficulty (): target is not a ship")); + return 0; + } + return JavaString(ship->getDifficulty()).getReturnValue(); +} + +//---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsShipNamespace::setShipFaction(JNIEnv * /*env*/, jobject /*self*/, jlong target, jstring jstr) +{ + ServerObject * object = 0; + if(!JavaLibrary::getObject(target, object)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipFactionName (): failed to convert target")); + return JNI_FALSE; + } + ShipObject * const ship = object->asShipObject(); + if(!ship) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipFactionName (): target not a ship")); + return JNI_FALSE; + } + + JavaStringParam const jsp(jstr); + std::string faction; + if (!JavaLibrary::convert(jsp, faction)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipWingName (): failed to convert mobileName string")); + return JNI_FALSE; + } + ship->setFaction(faction); + + return JNI_TRUE; +} + +//---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsShipNamespace::getShipFaction(JNIEnv * /*env*/, jobject /*self*/, jlong target) +{ + ServerObject const * object = NULL; + if (!JavaLibrary::getObject(target, object)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::getShipFaction (): could not convert the target")); + return 0; + } + ShipObject const * const ship = object->asShipObject(); + if(!ship) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::getShipFaction (): target is not a ship")); + return 0; + } + return JavaString(ship->getFaction()).getReturnValue(); +} + +//---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsShipNamespace::addMissionCriticalObject(JNIEnv * env, jobject /*self*/, jlong playerId, jlong missionCriticalObject) +{ + PROFILER_AUTO_BLOCK_DEFINE("JNI::addMissionCriticalObject"); + + CreatureObject * const creatureObject = JavaLibrary::getCreatureThrow(env, playerId, "addMissionCriticalObject(): playerId did not resolve to a CreatureObject", false); + if (!creatureObject) + return JNI_FALSE; + + NetworkId missionCriticalObjectId(missionCriticalObject); + + if (missionCriticalObject) + { + if(missionCriticalObjectId == NetworkId::cms_invalid) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("addMissionCriticalObject(): missionCriticalObject is not an obj_id")); + return JNI_FALSE; + } + + if (missionCriticalObjectId != NetworkId::cms_invalid) + creatureObject->addMissionCriticalObject(missionCriticalObjectId); + } + return JNI_TRUE; +} + +//---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsShipNamespace::removeMissionCriticalObject(JNIEnv * env, jobject /*self*/, jlong playerId, jlong missionCriticalObject) +{ + CreatureObject * const creatureObject = JavaLibrary::getCreatureThrow(env, playerId, "removeMissionCriticalObject(): playerId did not resolve to a CreatureObject", false); + if (!creatureObject) + return JNI_FALSE; + + NetworkId missionCriticalObjectId(missionCriticalObject); + + if (missionCriticalObject) + { + if (missionCriticalObjectId == NetworkId::cms_invalid) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("removeMissionCriticalObject(): missionCriticalObject is not an obj_id")); + return JNI_FALSE; + } + + if (missionCriticalObjectId != NetworkId::cms_invalid) + creatureObject->removeMissionCriticalObject(missionCriticalObjectId); + } + return JNI_TRUE; +} + +//---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsShipNamespace::clearMissionCriticalObjects(JNIEnv * env, jobject /*self*/, jlong playerId) +{ + CreatureObject * const creatureObject = JavaLibrary::getCreatureThrow(env, playerId, "clearMissionCriticalObjects(): playerId did not resolve to a CreatureObject", false); + if (!creatureObject) + return JNI_FALSE; + + creatureObject->clearMissionCriticalObjects(); + + return JNI_TRUE; +} + +//---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsShipNamespace::isMissionCriticalObject(JNIEnv * env, jobject /*self*/, jlong playerId, jlong ship) +{ + CreatureObject * const creatureObject = JavaLibrary::getCreatureThrow(env, playerId, "isMissionCriticalObject(): playerId did not resolve to a CreatureObject", false); + if (!creatureObject) + return JNI_FALSE; + + if (!ship) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("isMissionCriticalObject(): playerId ship is null")); + return JNI_FALSE; + } + + NetworkId shipId(ship); + if (shipId == NetworkId::cms_invalid) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("isMissionCriticalObject(): playerId is not an obj_id")); + return JNI_FALSE; + } + + return creatureObject->isMissionCriticalObject(shipId); +} + +// ---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsShipNamespace::getShipComponentDebugString(JNIEnv * env, jobject /*self*/, jlong jobject_shipId, jint chassisSlot) +{ + ShipObject const * const ship = JavaLibrary::getShipThrow(env, jobject_shipId, "getShipComponentDebugString(): obj_id shipId did not resolve to a ShipObject", false); + if (ship && ship->isSlotInstalled(chassisSlot)) + { + ShipComponentData * const shipComponentData = ship->createShipComponentData(chassisSlot); + if (shipComponentData) + { + Unicode::String result; + shipComponentData->printDebugString(result, Unicode::emptyString); + delete shipComponentData; + if (!result.empty()) + return JavaString(result).getReturnValue(); + } + } + return 0; +} + +//---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsShipNamespace::getShipChassisSpeedMaximumModifier(JNIEnv * env, jobject self, jlong shipId) +{ + ShipObject const * const shipObject = JavaLibrary::getShipThrow(env, shipId, "getShipChassisMaximumSpeedModifier(): shipId did not resolve to a ShipObject", false); + if (!shipObject) + return JNI_FALSE; + + return shipObject->getChassisSpeedMaximumModifier(); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipChassisSpeedMaximumModifier(JNIEnv * env, jobject self, jlong shipId, jfloat value) +{ + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, shipId, "setShipChassisMaximumSpeedModifier(): shipId did not resolve to a ShipObject", false); + if (!shipObject) + return; + + shipObject->setChassisSpeedMaximumModifier(value); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::notifyShipHit(JNIEnv * env, jobject self, jlong jobject_shipId, jobject jobject_vectorUp_w, jobject jobject_vectorHitLocation_o, jint type, jfloat integrity, jfloat previousIntegrity) +{ + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, jobject_shipId, "notifyShipHit(): shipId did not resolve to a ShipObject", false); + if (!shipObject) + return; + + Vector up_w; + if (!ScriptConversion::convert(jobject_vectorUp_w, up_w)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("notifyShipHit(): unable to convert up_w vector")); + return; + } + + Vector hitLocation_o; + if (!ScriptConversion::convert(jobject_vectorHitLocation_o, hitLocation_o)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("notifyShipHit(): unable to convert hitLocation_o vector")); + return; + } + + MessageQueueShipHit * const msg = new MessageQueueShipHit(up_w, hitLocation_o, type, integrity, previousIntegrity); + shipObject->getController()->appendMessage( + CM_spaceShipHit, 0.0f, msg, + GameControllerMessageFlags::SEND | + GameControllerMessageFlags::RELIABLE | + GameControllerMessageFlags::DEST_ALL_CLIENT); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setDynamicMiningAsteroidVelocity(JNIEnv * env, jobject self, jlong jobject_asteroidId, jobject jobject_velocity_w) +{ + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, jobject_asteroidId, "setDynamicMiningAsteroidVelocity(): shipId did not resolve to a ShipObject", false); + if (!shipObject) + return; + + Vector velocity_w; + if (!ScriptConversion::convert(jobject_velocity_w, velocity_w)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("setDynamicMiningAsteroidVelocity(): unable to convert velocity_w vector")); + return; + } + + MiningAsteroidController * const miningAsteroidController = dynamic_cast(shipObject->getController()); + if (NULL == miningAsteroidController) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("setDynamicMiningAsteroidVelocity(): called on a ship which is not a dynamic mining asteroid")); + return; + } + + miningAsteroidController->setVelocity_w(velocity_w); +} + +//---------------------------------------------------------------------- + +jobject JNICALL ScriptMethodsShipNamespace::getDynamicMiningAsteroidVelocity(JNIEnv * env, jobject self, jlong jobject_asteroidId) +{ + ShipObject * const shipObject = JavaLibrary::getShipThrow(env, jobject_asteroidId, "getDynamicMiningAsteroidVelocity(): shipId did not resolve to a ShipObject", false); + if (!shipObject) + return NULL; + MiningAsteroidController * const miningAsteroidController = dynamic_cast(shipObject->getController()); + if (NULL == miningAsteroidController) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("setDynamicMiningAsteroidVelocity(): called on a ship which is not a dynamic mining asteroid")); + return NULL; + } + + Vector const & velocity_w = miningAsteroidController->getVelocity_w(); + + LocalRefPtr vec; + if (!ScriptConversion::convert(velocity_w, vec)) + return 0; + + return vec->getReturnValue(); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipCargoHoldContentsMaximum (JNIEnv * env, jobject self, jlong jobject_shipId, jint contentsMaximum) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipCargoHoldContentsMaximum()", false, static_cast(ShipChassisSlotType::SCST_cargo_hold)); + if (!shipObject) + return; + + if (!shipObject->setCargoHoldContentsMaximum(contentsMaximum)) + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipCargoHoldContentsMaximum (): component at slot [%d] error", static_cast(ShipChassisSlotType::SCST_cargo_hold))); +} + +//---------------------------------------------------------------------- + +int JNICALL ScriptMethodsShipNamespace::getShipCargoHoldContentsMaximum (JNIEnv * env, jobject self, jlong jobject_shipId) +{ + ShipObject const * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "getShipCargoHoldContentsMaximum()", false, static_cast(ShipChassisSlotType::SCST_cargo_hold)); + if (!shipObject) + return false; + + return shipObject->getCargoHoldContentsMaximum(); +} + +//---------------------------------------------------------------------- + +int JNICALL ScriptMethodsShipNamespace::getShipCargoHoldContentsCurrent (JNIEnv * env, jobject self, jlong jobject_shipId) +{ + ShipObject const * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "getShipCargoHoldContentsCurrent()", false, static_cast(ShipChassisSlotType::SCST_cargo_hold)); + if (!shipObject) + return false; + + return shipObject->getCargoHoldContentsCurrent(); +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::setShipCargoHoldContent(JNIEnv * env, jobject self, jlong jobject_shipId, jlong jobject_resourceTypeId, jint amount) +{ + ShipObject * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "setShipCargoHoldContent()", false, static_cast(ShipChassisSlotType::SCST_cargo_hold)); + if (!shipObject) + return; + + NetworkId const & resourceTypeId = NetworkId(jobject_resourceTypeId); + + //-- check existence if amount != 0 + + shipObject->setCargoHoldContent(resourceTypeId, amount); +} + +//---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsShipNamespace::getShipCargoHoldContent(JNIEnv * env, jobject self, jlong jobject_shipId, jlong jobject_resourceTypeId) +{ + ShipObject const * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "getShipCargoHoldContent()", false, static_cast(ShipChassisSlotType::SCST_cargo_hold)); + if (!shipObject) + return false; + + NetworkId const & resourceTypeId = NetworkId(jobject_resourceTypeId); + + return shipObject->getCargoHoldContent(resourceTypeId); +} + +//---------------------------------------------------------------------- + +jlongArray JNICALL ScriptMethodsShipNamespace::getShipCargoHoldContentsResourceTypes(JNIEnv * env, jobject self, jlong jobject_shipId) +{ + ShipObject const * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "getShipCargoHoldContents()", false, static_cast(ShipChassisSlotType::SCST_cargo_hold)); + if (!shipObject) + return false; + + ShipObject::NetworkIdIntMap const & contents = shipObject->getCargoHoldContents(); + + LocalLongArrayRefPtr jids = createNewLongArray(contents.size()); + + if (jids != LocalLongArrayRef::cms_nullPtr) + { + int index = 0; + for (ShipObject::NetworkIdIntMap::const_iterator it = contents.begin(); it != contents.end(); ++it, ++index) + { + jlong jlongTmp = ((*it).first).getValue(); + setLongArrayRegion(*jids, index, 1, &jlongTmp); + } + return jids->getReturnValue(); + } + + return NULL; +} + +//---------------------------------------------------------------------- + +jintArray JNICALL ScriptMethodsShipNamespace::getShipCargoHoldContentsAmounts(JNIEnv * env, jobject self, jlong jobject_shipId) +{ + ShipObject const * const shipObject = getShipThrowTestSlot(env, jobject_shipId, "getShipCargoHoldContents()", false, static_cast(ShipChassisSlotType::SCST_cargo_hold)); + if (!shipObject) + return false; + + ShipObject::NetworkIdIntMap const & contents = shipObject->getCargoHoldContents(); + + LocalIntArrayRefPtr jamounts = createNewIntArray(static_cast(contents.size ())); + if (jamounts != LocalIntArrayRef::cms_nullPtr) + { + int index = 0; + for (ShipObject::NetworkIdIntMap::const_iterator it = contents.begin(); it != contents.end(); ++it) + { + jint amount = (*it).second; + setIntArrayRegion(*jamounts, index, 1, &amount); + } + return jamounts->getReturnValue(); + } + + return NULL; +} + +//---------------------------------------------------------------------- + +void JNICALL ScriptMethodsShipNamespace::openSpaceMiningUi(JNIEnv * env, jobject self, jlong jobject_player, jlong jobject_spaceStation, jstring jstring_spaceStationName) +{ + NetworkId const & playerId = NetworkId(jobject_player); + NetworkId const & spaceStationId = NetworkId(jobject_spaceStation); + + if (jstring_spaceStationName == NULL) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipComponentName (): null name")); + return; + } + + JavaStringParam const jsp(jstring_spaceStationName); + std::string spaceStationName; + if (!JavaLibrary::convert(jsp, spaceStationName)) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("JavaLibrary::setShipComponentName (): failed to convert name string")); + return; + } + + Object * const player = NetworkIdManager::getObjectById(playerId); + Controller * const controller = player ? player->getController(): NULL; + + if (!controller) + { + WARNING(true, ("JavaLibrary::openSpaceMiningUi failed, no player or controller")); + return; + } + + typedef std::pair MessageData; + typedef MessageQueueGenericValueType MessageType; + MessageType * const msg = new MessageType(MessageData(spaceStationId, spaceStationName)); + + controller->appendMessage(CM_spaceMiningSaleOpen, 0.0f, msg, + GameControllerMessageFlags::SEND | + GameControllerMessageFlags::RELIABLE | + GameControllerMessageFlags::DEST_AUTH_CLIENT); +} + +// ====================================================================== + diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsSkill.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsSkill.cpp new file mode 100644 index 00000000..df5453bf --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsSkill.cpp @@ -0,0 +1,1483 @@ +// ScriptMethodsSkill.cpp +// Copyright 2000-01, Sony Online Entertainment Inc., all rights reserved. +// Author: Justin Randall + +//----------------------------------------------------------------------- + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "serverGame/Chat.h" +#include "serverGame/CreatureObject.h" +#include "serverGame/MessageToQueue.h" +#include "serverGame/NameManager.h" +#include "serverGame/PlayerCreatureController.h" +#include "serverGame/PlayerObject.h" +#include "serverGame/ServerObjectTemplate.h" +#include "serverGame/ServerUniverse.h" +#include "sharedFoundation/Crc.h" +#include "sharedGame/DraftSchematicGroupManager.h" +#include "sharedLog/Log.h" +#include "sharedObject/NetworkIdManager.h" +#include "sharedSkillSystem/SkillManager.h" +#include "sharedSkillSystem/SkillObject.h" + +#include "UnicodeUtils.h" +using namespace JNIWrappersNamespace; + + +// ====================================================================== +// ScriptMethodsSkillNamespace +// ====================================================================== + +namespace ScriptMethodsSkillNamespace +{ + bool install(); + + jint JNICALL getModValue(JNIEnv * env, jobject self, jlong target, jstring modName); + void JNICALL setModValue(JNIEnv * env, jobject self, jlong target, jstring modName, jint value); + jint JNICALL getExperiencePoints(JNIEnv *env, jobject self, jlong target, jstring experienceType); + jobject JNICALL getExperiencePointsMap(JNIEnv * env, jobject self, jlong target); + jint JNICALL getSkillExperienceLimit(JNIEnv *env, jobject self, jlong target, jstring experienceType); + jobjectArray JNICALL getSkillCommandsProvided(JNIEnv *env, jobject self, jstring skillName); + jobjectArray JNICALL getSkillListingForPlayer(JNIEnv * env, jobject self, jlong player); + jobject JNICALL getSkillPrerequisiteExperience(JNIEnv *env, jobject self, jstring skillName); + jobjectArray JNICALL getSkillPrerequisiteSkills(JNIEnv *env, jobject self, jstring skillName); + jobject JNICALL getSkillPrerequisiteSpecies(JNIEnv *env, jobject self, jstring skillName); + jstring JNICALL getSkillProfession(JNIEnv *env, jobject self, jstring skillName); + jobject JNICALL getSkillStatisticModifiers(JNIEnv *env, jobject self, jstring skillName); + jint JNICALL getCreatureSkillStatisticModifier(JNIEnv *env, jobject self, jlong creature, jstring skillStatName); + jintArray JNICALL getCreatureSkillStatisticModifiers(JNIEnv *env, jobject self, jlong creature, jobjectArray skillStatNames); + jobject JNICALL getEnhancedSkillStatisticModifiers(JNIEnv *env, jobject self, jstring skillName); + jint JNICALL getCreatureEnhancedSkillStatisticModifier(JNIEnv *env, jobject self, jlong creature, jstring skillStatName); + jintArray JNICALL getCreatureEnhancedSkillStatisticModifiers(JNIEnv *env, jobject self, jlong creature, jobjectArray skillStatNames); + jint JNICALL getCreatureEnhancedSkillStatisticModifierUncapped(JNIEnv *env, jobject self, jlong creature, jstring skillStatName); + jintArray JNICALL getCreatureEnhancedSkillStatisticModifiersUncapped(JNIEnv *env, jobject self, jlong creature, jobjectArray skillStatNames); + jint JNICALL internalGetCreatureEnhancedSkillStatisticModifier(JNIEnv *env, jobject self, jlong creature, jstring skillStatName, jboolean useBonusCap); + jintArray JNICALL internalGetCreatureEnhancedSkillStatisticModifiers(JNIEnv *env, jobject self, jlong creature, jobjectArray skillStatNames, jboolean useBonusCap); + jstring JNICALL getSkillTitleGranted(JNIEnv *env, jobject self, jstring skillName); + jboolean JNICALL grantCommand(JNIEnv *env, jobject self, jlong target, jstring commandName); + jint JNICALL grantExperiencePointsByString(JNIEnv *env, jobject self, jlong target, jstring experienceType, jint amount); + jint JNICALL grantExperiencePointsByInt(JNIEnv *env, jobject self, jlong target, jint experienceType, jint amount); + jstring JNICALL getStringExperienceType(JNIEnv *env, jobject self, jint xpType); + jboolean JNICALL grantSkill(JNIEnv *env, jobject self, jlong target, jstring skillName); + jboolean JNICALL hasCommand(JNIEnv *env, jobject, jlong target, jstring commandName); + jboolean JNICALL hasSkill(JNIEnv *env, jobject self, jlong target, jstring skillName); + void JNICALL revokeCommand(JNIEnv *env, jobject self, jlong target, jstring commandName); + void JNICALL revokeSkill(JNIEnv *env, jobject self, jlong target, jstring skillName); + void JNICALL revokeSkillSilent(JNIEnv *env, jobject self, jlong target, jstring skillName); + jboolean JNICALL grantSchematicGroup(JNIEnv *env, jobject self, jlong target, jstring groupName); + jboolean JNICALL revokeSchematicGroup(JNIEnv *env, jobject self, jlong target, jstring groupName); + jboolean JNICALL grantSchematicName(JNIEnv *env, jobject self, jlong target, jstring schematicName); + jboolean JNICALL grantSchematicCrc(JNIEnv *env, jobject self, jlong target, jint schematicCrc); + jboolean JNICALL revokeSchematicName(JNIEnv *env, jobject self, jlong target, jstring schematicName); + jboolean JNICALL revokeSchematicCrc(JNIEnv *env, jobject self, jlong target, jint schematicCrc); + jboolean JNICALL hasSchematicName(JNIEnv *env, jobject self, jlong target, jstring schematicName); + jboolean JNICALL hasSchematicCrc(JNIEnv *env, jobject self, jlong target, jint schematicCrc); + jobjectArray JNICALL getSkillStatModListingForPlayer(JNIEnv *env, jobject self, jlong player); + jobjectArray JNICALL getCommandListingForPlayer(JNIEnv *env, jobject self, jlong player); + jintArray JNICALL getSkillSchematicsGranted(JNIEnv *env, jobject self, jstring skillName); + jintArray JNICALL getSchematicListingForPlayer(JNIEnv *env, jobject self, jlong player); + jboolean JNICALL hasCertificationsForItem(JNIEnv *env, jobject self, jlong player, jlong item); + jobjectArray JNICALL getRequiredCertifications(JNIEnv *env, jobject self, jlong item); + jint JNICALL getSkillStatMod(JNIEnv * env, jobject self, jlong player, jstring statModName); + jboolean JNICALL applySkillStatisticModifier(JNIEnv *env, jobject self, jlong player, jstring statName, jint value); + jstring JNICALL getSkillTemplate(JNIEnv *env, jobject self, jlong player); + void JNICALL setSkillTemplate(JNIEnv *env, jobject self, jlong player, jstring skillTemplateName); + jstring JNICALL getWorkingSkill(JNIEnv *env, jobject self, jlong player); + void JNICALL setWorkingSkill(JNIEnv *env, jobject self, jlong player, jstring skillTemplateName); + void JNICALL recomputeCommandSeries(JNIEnv *env, jobject self, jlong player); + void JNICALL resetExpertises(JNIEnv *env, jobject self, jlong player); +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsSkillNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsSkillNamespace::c)} + JF("__getModValue", "(JLjava/lang/String;)I", getModValue), + JF("__setModValue", "(JLjava/lang/String;I)V", setModValue), + JF("_getExperiencePoints", "(JLjava/lang/String;)I", getExperiencePoints), + JF("_getExperiencePoints", "(J)Lscript/dictionary;", getExperiencePointsMap), + JF("_getExperienceCap", "(JLjava/lang/String;)I", getSkillExperienceLimit), + JF("getSkillCommandsProvided", "(Ljava/lang/String;)[Ljava/lang/String;", getSkillCommandsProvided), + JF("_getSkillListingForPlayer", "(J)[Ljava/lang/String;", getSkillListingForPlayer), + JF("getSkillPrerequisiteExperience", "(Ljava/lang/String;)Lscript/dictionary;", getSkillPrerequisiteExperience), + JF("getSkillPrerequisiteSkills", "(Ljava/lang/String;)[Ljava/lang/String;", getSkillPrerequisiteSkills), + JF("getSkillPrerequisiteSpecies", "(Ljava/lang/String;)Lscript/dictionary;", getSkillPrerequisiteSpecies), + JF("getSkillProfession", "(Ljava/lang/String;)Ljava/lang/String;", getSkillProfession), + JF("getSkillStatisticModifiers", "(Ljava/lang/String;)Lscript/dictionary;", getSkillStatisticModifiers), + JF("_getSkillStatisticModifier", "(JLjava/lang/String;)I", getCreatureSkillStatisticModifier), + JF("_getSkillStatisticModifiers", "(J[Ljava/lang/String;)[I", getCreatureSkillStatisticModifiers), + JF("_getEnhancedSkillStatisticModifier", "(JLjava/lang/String;)I", getCreatureEnhancedSkillStatisticModifier), + JF("_getEnhancedSkillStatisticModifiers", "(J[Ljava/lang/String;)[I", getCreatureEnhancedSkillStatisticModifiers), + JF("_getEnhancedSkillStatisticModifierUncapped", "(JLjava/lang/String;)I", getCreatureEnhancedSkillStatisticModifierUncapped), + JF("_getEnhancedSkillStatisticModifiersUncapped", "(J[Ljava/lang/String;)[I", getCreatureEnhancedSkillStatisticModifiersUncapped), + JF("getSkillTitleGranted", "(Ljava/lang/String;)Ljava/lang/String;", getSkillTitleGranted), + JF("_grantCommand", "(JLjava/lang/String;)Z", grantCommand), + JF("__grantExperiencePoints", "(JLjava/lang/String;I)I", grantExperiencePointsByString), + JF("__grantExperiencePoints", "(JII)I", grantExperiencePointsByInt), + JF("getStringExperienceType", "(I)Ljava/lang/String;", getStringExperienceType), + JF("_grantSkill", "(JLjava/lang/String;)Z", grantSkill), + JF("_hasCommand", "(JLjava/lang/String;)Z", hasCommand), + JF("_hasSkill", "(JLjava/lang/String;)Z", hasSkill), + JF("_revokeCommand", "(JLjava/lang/String;)V", revokeCommand), + JF("_revokeSkill", "(JLjava/lang/String;)V", revokeSkill), + JF("_revokeSkillSilent", "(JLjava/lang/String;)V", revokeSkillSilent), + JF("_grantSchematicGroup", "(JLjava/lang/String;)Z", grantSchematicGroup), + JF("_revokeSchematicGroup", "(JLjava/lang/String;)Z", revokeSchematicGroup), + JF("_grantSchematic", "(JLjava/lang/String;)Z", grantSchematicName), + JF("_grantSchematic", "(JI)Z", grantSchematicCrc), + JF("_revokeSchematic", "(JLjava/lang/String;)Z", revokeSchematicName), + JF("_revokeSchematic", "(JI)Z", revokeSchematicCrc), + JF("_hasSchematic", "(JLjava/lang/String;)Z", hasSchematicName), + JF("_hasSchematic", "(JI)Z", hasSchematicCrc), + JF("_getSkillStatModListingForPlayer", "(J)[Ljava/lang/String;", getSkillStatModListingForPlayer), + JF("_getCommandListingForPlayer", "(J)[Ljava/lang/String;", getCommandListingForPlayer), + JF("getSkillSchematicsGranted", "(Ljava/lang/String;)[I", getSkillSchematicsGranted), + JF("_getSchematicListingForPlayer", "(J)[I", getSchematicListingForPlayer), + JF("_hasCertificationsForItem", "(JJ)Z", hasCertificationsForItem), + JF("_getRequiredCertifications", "(J)[Ljava/lang/String;", getRequiredCertifications), + JF("_getSkillStatMod", "(JLjava/lang/String;)I", getSkillStatMod), + JF("_applySkillStatisticModifier", "(JLjava/lang/String;I)Z", applySkillStatisticModifier), + JF("_getSkillTemplate", "(J)Ljava/lang/String;", getSkillTemplate), + JF("_setSkillTemplate", "(JLjava/lang/String;)V", setSkillTemplate), + JF("_getWorkingSkill", "(J)Ljava/lang/String;", getWorkingSkill), + JF("_setWorkingSkill", "(JLjava/lang/String;)V", setWorkingSkill), + JF("_recomputeCommandSeries", "(J)V", recomputeCommandSeries), + JF("_resetExpertises", "(J)V", resetExpertises), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +//----------------------------------------------------------------------- + +static const SkillObject * getSkill(const JavaStringParam & skillName) +{ + const SkillObject * result = 0; + + std::string name; + if(!JavaLibrary::convert(skillName, name)) + return 0; + + result = SkillManager::getInstance().getSkill(name); + + return result; +} + +//----------------------------------------------------------------------- + +jint JNICALL ScriptMethodsSkillNamespace::getModValue(JNIEnv * env, jobject self, jlong target, jstring modName) +{ + jint result = 0; + CreatureObject * creature = 0; + if(!JavaLibrary::getObject(target, creature)) + return result; + + JavaStringParam localModName(modName); + std::string m; + if(!JavaLibrary::convert(localModName, m)) + return result; + + result = creature->getModValue(m); + + return result; +} + +//----------------------------------------------------------------------- + +jint JNICALL ScriptMethodsSkillNamespace::getExperiencePoints(JNIEnv *env, jobject self, jlong target, jstring experienceType) +{ + JavaStringParam localExperienceType(experienceType); + + jint result = 0; + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return result; + + std::string name; + if(!JavaLibrary::convert(localExperienceType, name)) + return result; + + result = creature->getExperiencePoints(name); + return result; +} + +//----------------------------------------------------------------------- + +jobject JNICALL ScriptMethodsSkillNamespace::getExperiencePointsMap(JNIEnv * env, jobject self, jlong target) +{ + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return 0; + + JavaDictionaryPtr dict; + if (!JavaLibrary::convert(creature->getExperiencePoints(), dict)) + return 0; + return dict->getReturnValue(); +} + +//----------------------------------------------------------------------- + +jint JNICALL ScriptMethodsSkillNamespace::getSkillStatMod(JNIEnv * env, jobject self, jlong player, jstring statName) +{ + JavaStringParam localStatName(statName); + + jint result = 0; + CreatureObject * obj = 0; + if(JavaLibrary::getObject(player, obj)) + { + std::string stat; + if(JavaLibrary::convert(localStatName, stat)) + result = obj->getModValue(stat); + } + return result; +} + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsSkillNamespace::applySkillStatisticModifier(JNIEnv * env, jobject self, jlong player, jstring statName, jint value) +{ + JavaStringParam localStatName(statName); + + if (!player) + { + return false; + } + + CreatureObject * obj = 0; + if(JavaLibrary::getObject(player, obj)) + { + std::string stat; + if(JavaLibrary::convert(localStatName, stat)) + { + obj->addModValue(stat, value, false); + return true; + } + } + return false; +} + +//----------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsSkillNamespace::getSkillCommandsProvided(JNIEnv *env, jobject self, jstring skillName) +{ + JavaStringParam localSkillName(skillName); + + const SkillObject * skill = getSkill(localSkillName); + if(! skill) + return NULL; + + LocalObjectArrayRefPtr strArray; + if(! ScriptConversion::convert(skill->getCommandsProvided(), strArray)) + return 0; + + return strArray->getReturnValue(); +} + +//----------------------------------------------------------------------- + +jobject JNICALL ScriptMethodsSkillNamespace::getSkillPrerequisiteExperience(JNIEnv *env, jobject self, jstring skillName) +{ + JavaStringParam localSkillName(skillName); + + const SkillObject * skill = getSkill(localSkillName); + if(! skill) + return NULL; + + JavaDictionaryPtr dict; + if (!JavaLibrary::convert(skill->getPrerequisiteExperienceVector(), dict)) + return 0; + return dict->getReturnValue(); +} + +//----------------------------------------------------------------------- + +jint JNICALL ScriptMethodsSkillNamespace::getSkillExperienceLimit(JNIEnv * env, jobject self, jlong player, jstring skillName) +{ + JavaStringParam localSkillName(skillName); + jint result = 0; + + CreatureObject * creature = 0; + if (JavaLibrary::getObject(player, creature)) + { + const PlayerObject * playerObject = PlayerCreatureController::getPlayerObject(creature); + if (playerObject) + { + std::string name; + if (JavaLibrary::convert(localSkillName, name)) + { + result = playerObject->getExperienceLimit(name); + if (result < 1) + result = 0; + } + } + } + return result; +} + +//----------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsSkillNamespace::getSkillPrerequisiteSkills(JNIEnv *env, jobject self, jstring skillName) +{ + JavaStringParam localSkillName(skillName); + + const SkillObject * skill = getSkill(localSkillName); + if(! skill) + return NULL; + + std::vector skillNames; + std::vector::const_iterator i; + for(i = skill->getPrerequisiteSkills().begin(); i != skill->getPrerequisiteSkills().end(); ++i) + { + skillNames.push_back((*i)->getSkillName()); + } + + LocalObjectArrayRefPtr strArray; + if(! ScriptConversion::convert(skillNames, strArray)) + return 0; + + return strArray->getReturnValue();; +} + +//----------------------------------------------------------------------- + +jobject JNICALL ScriptMethodsSkillNamespace::getSkillPrerequisiteSpecies(JNIEnv *env, jobject self, jstring skillName) +{ + JavaStringParam localSkillName(skillName); + + const SkillObject * skill = getSkill(localSkillName); + if(! skill) + return NULL; + + JavaDictionaryPtr dict; + if (!JavaLibrary::convert(skill->getPrerequisiteSpecies(), dict)) + return 0; + return dict->getReturnValue(); +} + +//----------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsSkillNamespace::getSkillProfession(JNIEnv *env, jobject self, jstring skillName) +{ + JavaStringParam localSkillName(skillName); + + const SkillObject * const skill = getSkill(localSkillName); + if(!skill) + return NULL; + const SkillObject * const prof = skill->findProfessionForSkill (); + if(prof) + { + JavaString str(prof->getSkillName().c_str()); + return str.getReturnValue(); + } + return NULL; +} + +//----------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsSkillNamespace::getSkillListingForPlayer(JNIEnv * env, jobject self, jlong jplayerId) +{ + const CreatureObject * player = 0; + if (!JavaLibrary::getObject(jplayerId, player)) + return 0; + + CreatureObject::SkillList const & skills = player->getSkillList(); + std::vector skillList; + for (CreatureObject::SkillList::const_iterator i = skills.begin(); i != skills.end(); ++i) + if (*i) + skillList.push_back((*i)->getSkillName()); + + LocalObjectArrayRefPtr strArray; + if (!ScriptConversion::convert(skillList, strArray)) + return 0; + + return strArray->getReturnValue(); +} + +//----------------------------------------------------------------------- + +/** + * Returns a dictionary of skill stat modifier values on a creature for a given skill. + * + * @param env Java environment + * @param self class calling this function + * @param skillName the skill name + * + * @return a dictionary of skillmod name -> mod valus + */ +jobject JNICALL ScriptMethodsSkillNamespace::getSkillStatisticModifiers(JNIEnv *env, jobject self, + jstring skillName) +{ + JavaStringParam localSkillName(skillName); + + const SkillObject * skill = getSkill(localSkillName); + if(! skill) + return NULL; + + JavaDictionaryPtr dict; + if (!JavaLibrary::convert(skill->getStatisticModifiers(), dict)) + return 0; + return dict->getReturnValue(); +} + +//----------------------------------------------------------------------- + +/** + * Returns the skill stat modifier value on a creature for a given skill stat + * modifier name. + * + * @param env Java environment + * @param self class calling this function + * @param creature the creature whose stat mod we want + * @param skillStatName the name of the skill stat mod we want + * + * @return the skill stat mod value + */ +jint JNICALL ScriptMethodsSkillNamespace::getCreatureSkillStatisticModifier(JNIEnv *env, jobject self, jlong creature, jstring skillStatName) +{ + UNREF(self); + + JavaStringParam jskillStatName(skillStatName); + + const CreatureObject * object = NULL; + if (!JavaLibrary::getObject(creature, object)) + return 0; + + std::string statName; + if (!JavaLibrary::convert(jskillStatName, statName)) + return 0; + + return object->getModValue(statName); +} // JavaLibrary::getCreatureSkillStatisticModifier + +//----------------------------------------------------------------------- + +/** + * Returns an array of skill stat modifier values on a creature for a list of + * given skill stat modifier names. + * + * @param env Java environment + * @param self class calling this function + * @param creature the creature whose stat mod we want + * @param skillStatNames array of names of the skill stat mods we want + * + * @return the skill stat mod values, or null on error + */ +jintArray JNICALL ScriptMethodsSkillNamespace::getCreatureSkillStatisticModifiers(JNIEnv *env, jobject self, jlong creature, jobjectArray skillStatNames) +{ + UNREF(self); + + if (skillStatNames == 0) + return 0; + + const CreatureObject * object = NULL; + if (!JavaLibrary::getObject(creature, object)) + return 0; + + std::string statName; + + int count = env->GetArrayLength(skillStatNames); + std::vector stats(count, 0); + for (int i = 0; i < count; ++i) + { + JavaStringPtr jstatName = getStringArrayElement(LocalObjectArrayRefParam(skillStatNames), i); + if (jstatName != JavaString::cms_nullPtr) + { + if (!JavaLibrary::convert(*jstatName, statName)) + return 0; + stats.at(i) = object->getModValue(statName); + } + } + + LocalIntArrayRefPtr jstats = createNewIntArray(count); + if (jstats == LocalIntArrayRef::cms_nullPtr) + return 0; + + setIntArrayRegion(*jstats, 0, count, &stats[0]); + return jstats->getReturnValue(); +} // JavaLibrary::getCreatureSkillStatisticModifiers + +//----------------------------------------------------------------------- + +jint JNICALL ScriptMethodsSkillNamespace::getCreatureEnhancedSkillStatisticModifier(JNIEnv *env, jobject self, jlong creature, jstring skillStatName) +{ + return internalGetCreatureEnhancedSkillStatisticModifier(env, self, creature, skillStatName, true); +} + +//----------------------------------------------------------------------- + +jint JNICALL ScriptMethodsSkillNamespace::getCreatureEnhancedSkillStatisticModifierUncapped(JNIEnv *env, jobject self, jlong creature, jstring skillStatName) +{ + return internalGetCreatureEnhancedSkillStatisticModifier(env, self, creature, skillStatName, false); +} + +//----------------------------------------------------------------------- + +jintArray JNICALL ScriptMethodsSkillNamespace::getCreatureEnhancedSkillStatisticModifiers(JNIEnv *env, jobject self, jlong creature, jobjectArray skillStatNames) +{ + return internalGetCreatureEnhancedSkillStatisticModifiers(env, self, creature, skillStatNames, true); +} + +//----------------------------------------------------------------------- + +jintArray JNICALL ScriptMethodsSkillNamespace::getCreatureEnhancedSkillStatisticModifiersUncapped(JNIEnv *env, jobject self, jlong creature, jobjectArray skillStatNames) +{ + return internalGetCreatureEnhancedSkillStatisticModifiers(env, self, creature, skillStatNames, false); +} + +//----------------------------------------------------------------------- + +/** + * Returns the skill stat modifier value, enhanced by equipment, on a creature + * for a given skill stat modifier name. + * + * @param env Java environment + * @param self class calling this function + * @param creature the creature whose stat mod we want + * @param skillStatName the name of the skill stat mod we want + * + * @return the skill stat mod value + */ +jint JNICALL ScriptMethodsSkillNamespace::internalGetCreatureEnhancedSkillStatisticModifier(JNIEnv *env, jobject self, jlong creature, jstring skillStatName, jboolean useBonusCap) +{ + UNREF(self); + + JavaStringParam jskillStatName(skillStatName); + + const CreatureObject * object = NULL; + if (!JavaLibrary::getObject(creature, object)) + return 0; + + std::string statName; + if (!JavaLibrary::convert(jskillStatName, statName)) + return 0; + + return (useBonusCap ? object->getEnhancedModValue(statName) : object->getEnhancedModValueUncapped(statName)); +} // JavaLibrary::getCreatureEnhancedSkillStatisticModifier + +//----------------------------------------------------------------------- + +/** + * Returns an array of skill stat modifier values, enhanced by equipment, on a + * creature for a list of given skill stat modifier names. + * + * @param env Java environment + * @param self class calling this function + * @param creature the creature whose stat mod we want + * @param skillStatNames array of names of the skill stat mods we want + * + * @return the skill stat mod values, or null on error + */ +jintArray JNICALL ScriptMethodsSkillNamespace::internalGetCreatureEnhancedSkillStatisticModifiers(JNIEnv *env, jobject self, jlong creature, jobjectArray skillStatNames, jboolean useBonusCap) +{ + UNREF(self); + + if (skillStatNames == 0) + return 0; + + const CreatureObject * object = NULL; + if (!JavaLibrary::getObject(creature, object)) + return 0; + + std::string statName; + + int count = env->GetArrayLength(skillStatNames); + std::vector stats(count, 0); + for (int i = 0; i < count; ++i) + { + JavaStringPtr jstatName = getStringArrayElement(LocalObjectArrayRefParam(skillStatNames), i); + if (jstatName != JavaString::cms_nullPtr) + { + if (!JavaLibrary::convert(*jstatName, statName)) + return 0; + stats.at(i) = (useBonusCap ? object->getEnhancedModValue(statName) : object->getEnhancedModValueUncapped(statName)); + } + } + + LocalIntArrayRefPtr jstats = createNewIntArray(count); + if (jstats == LocalIntArrayRef::cms_nullPtr) + return 0; + + setIntArrayRegion(*jstats, 0, count, &stats[0]); + return jstats->getReturnValue(); +} // JavaLibrary::getCreatureEnhancedSkillStatisticModifiers + +//----------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsSkillNamespace::getSkillTitleGranted(JNIEnv *env, jobject self, jstring skillName) +{ + JavaStringParam localSkillName(skillName); + + const SkillObject * const skill = getSkill(localSkillName); + if(! skill) + return NULL; + + if (skill->isTitle ()) + return JavaString(skill->getSkillName ().c_str()).getReturnValue(); + else + return 0; +} + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsSkillNamespace::grantCommand(JNIEnv *env, jobject self, jlong target, jstring commandName) +{ + JavaStringParam localCommandName(commandName); + + jboolean result = JNI_FALSE; + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return result; + + std::string name; + if(!JavaLibrary::convert(localCommandName, name)) + return result; + + result = creature->grantCommand(name, false); + return result; +} + +//----------------------------------------------------------------------- + +jint JNICALL ScriptMethodsSkillNamespace::grantExperiencePointsByString(JNIEnv *env, jobject self, jlong target, jstring experienceType, jint amount) +{ + if (target == 0 || experienceType == 0) + return INT_MIN; + + JavaStringParam localExperienceType(experienceType); + std::string name; + if(!JavaLibrary::convert(localExperienceType, name)) + return INT_MIN; + + jint result = INT_MIN; + if(name.empty()) + { + // throw java exception + JavaLibrary::throwInternalScriptError("JavaLibrary::grantExperiencePoints() was passed an EMPTY or NULL experience name. This is probably not what the script intends to do, and the database cannot save unnamed XP. Change your script to ensure that it is calling grantExperiencePoints with the intended parameters."); + } + else + { + CachedNetworkId targetId(target); + if (targetId == CachedNetworkId::cms_cachedInvalid) + { + WARNING(true, ("JavaLibrary::grantExperiencePointsByString called " + "with target id = 0")); + } + else if (targetId.getObject() == NULL) + { + if (NameManager::getInstance().getPlayerName(targetId).empty()) + { + WARNING(true, ("JavaLibrary::grantExperiencePointsByString called " + "with target id = %s, who is not in the player name map", + targetId.getValueString().c_str())); + } +// else if (ServerUniverse::getInstance().getXpManager() != NULL) +// { +// ServerUniverse::getInstance().getXpManager()->grantXp(targetId, +// name, amount); +// } + else + { + // send a message to the object for when it comes online + char buffer[1024]; + sprintf(buffer, "%s %d", name.c_str(), static_cast(amount)); + MessageToQueue::getInstance().sendMessageToC(targetId, + "C++experience", buffer, 1, true); + result = amount; + } + } + else + { + CreatureObject * creature = dynamic_cast(targetId.getObject()); + if (creature != NULL) + { + result = creature->grantExperiencePoints(name, static_cast(amount)); + } + + } + } + + return result; +} + +//----------------------------------------------------------------------- + + +/** + * Grants a specific type of experience to a creature + * + * @param env Java environment + * @param self class calling this function + * @param target creature that will receive the named experience points + * @param experienceType the id of the type of experience to grant to the creature + * @param amount the amount of experience to grant + * + * @return the xp amount granted, or -1 on error + */ +jint JNICALL ScriptMethodsSkillNamespace::grantExperiencePointsByInt(JNIEnv *env, jobject self, jlong target, jint experienceType, jint amount) +{ + UNREF(self); + + if (target == 0) + return INT_MIN; + + // get the experience type string from ServerObjectTemplate + const std::string & experienceTypeString = ServerObjectTemplate::getXpString( + static_cast(experienceType)); + if (experienceTypeString.empty()) + return INT_MIN; + + jint result = INT_MIN; + CachedNetworkId targetId(target); + if (targetId.getObject() == NULL) + { + if (targetId == CachedNetworkId::cms_cachedInvalid) + { + WARNING(true, ("JavaLibrary::grantExperiencePointsByInt called " + "with target id = 0")); + } + else if (NameManager::getInstance().getPlayerName(targetId).empty()) + { + WARNING(true, ("JavaLibrary::grantExperiencePointsByInt called " + "with target id = %s, who is not in the player name map", + targetId.getValueString().c_str())); + } +// else if (ServerUniverse::getInstance().getXpManager() != NULL) +// { +// ServerUniverse::getInstance().getXpManager()->grantXp(targetId, +// experienceTypeString, amount); +// } + else + { + // send a message to the object for when it comes online + char buffer[1024]; + sprintf(buffer, "%s %d", experienceTypeString.c_str(), static_cast(amount)); + MessageToQueue::getInstance().sendMessageToC(targetId, + "C++experience", buffer, 1, true); + result = amount; + } + } + else + { + CreatureObject * creature = dynamic_cast(targetId.getObject()); + if (creature != NULL) + { + result = creature->grantExperiencePoints(experienceTypeString, static_cast(amount)); + } + } + return result; +} // JavaLibrary::grantExperiencePointsByInt + +//----------------------------------------------------------------------- + +/** + * Returns the string experience type for an int xp type + * + * @param env Java environment + * @param self class calling this function + * @param xpType int version of the xp + * + * @returns string version of the xp + */ +jstring JNICALL ScriptMethodsSkillNamespace::getStringExperienceType(JNIEnv *env, jobject self, jint xpType) +{ + UNREF(self); + + // get the experience type string from ServerObjectTemplate + const std::string & experienceTypeString = ServerObjectTemplate::getXpString(static_cast(xpType)); + + JavaString str(experienceTypeString.c_str()); + return str.getReturnValue(); +} // JavaLibrary::grantCrafterExperiencePoints + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsSkillNamespace::grantSkill(JNIEnv *env, jobject self, jlong target, jstring skillName) +{ + JavaStringParam localSkillName(skillName); + + jboolean result = JNI_FALSE; + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return result; + + std::string name; + if(!JavaLibrary::convert(localSkillName, name)) + return result; + + const SkillObject * skill = SkillManager::getInstance().getSkill(name); + + if(!skill) + return result; + + result = creature->grantSkill(*skill); + + return result; +} + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsSkillNamespace::hasCommand(JNIEnv *env, jobject, jlong target, jstring commandName) +{ + JavaStringParam localCommandName(commandName); + + jboolean result = JNI_FALSE; + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return result; + + std::string name; + if(!JavaLibrary::convert(localCommandName, name)) + return result; + + result = creature->hasCommand(name); + + return result; +} + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsSkillNamespace::hasSkill(JNIEnv *env, jobject self, jlong target, jstring skillName) +{ + JavaStringParam localSkillName(skillName); + + jboolean result = JNI_FALSE; + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return result; + + std::string name; + if(!JavaLibrary::convert(localSkillName, name)) + return result; + + const SkillObject * skill = SkillManager::getInstance().getSkill(name); + + if(!skill) + return result; + + result = creature->hasSkill(*skill); + + return result; +} + +//----------------------------------------------------------------------- + +void JNICALL ScriptMethodsSkillNamespace::revokeCommand(JNIEnv *env, jobject self, jlong target, jstring commandName) +{ + JavaStringParam localCommandName(commandName); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return; + + std::string name; + if(!JavaLibrary::convert(localCommandName, name)) + return; + + creature->revokeCommand(name, false); +} + +//----------------------------------------------------------------------- + + +void JNICALL ScriptMethodsSkillNamespace::revokeSkill(JNIEnv *env, jobject self, jlong target, jstring skillName) +{ + JavaStringParam localSkillName(skillName); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return; + + std::string name; + if(!JavaLibrary::convert(localSkillName, name)) + return; + + const SkillObject * skill = SkillManager::getInstance().getSkill(name); + + if(!skill) + return; + + LOG("CustomerService", ("Skill: Script has requested the removal of skill %s from character %s.", + name.c_str(), creature->getNetworkId().getValueString().c_str())); + creature->revokeSkill(*skill, false); +} + +//----------------------------------------------------------------------- + +void JNICALL ScriptMethodsSkillNamespace::revokeSkillSilent(JNIEnv *env, jobject self, jlong target, jstring skillName) +{ + JavaStringParam localSkillName(skillName); + + CreatureObject * creature = 0; + if (!JavaLibrary::getObject(target, creature)) + return; + + std::string name; + if(!JavaLibrary::convert(localSkillName, name)) + return; + + const SkillObject * skill = SkillManager::getInstance().getSkill(name); + + if(!skill) + return; + + LOG("CustomerService", ("Skill: Script has requested the removal of skill %s from character %s.", + name.c_str(), creature->getNetworkId().getValueString().c_str())); + creature->revokeSkill(*skill, true); +} + +//----------------------------------------------------------------------- + +void JNICALL ScriptMethodsSkillNamespace::setModValue(JNIEnv * env, jobject self, jlong target, jstring modName, jint value) +{ + CreatureObject * creature = 0; + if(!JavaLibrary::getObject(target, creature)) + return; + + JavaStringParam lmn(modName); + std::string m; + if(!JavaLibrary::convert(lmn, m)) + return; + creature->setModValue(m, value); +} + +//----------------------------------------------------------------------- + +/** + * Adds a schematic group to a creature. + * + * @param env Java environment + * @param self class calling this function + * @param target the creature + * @param groupName the schematic group name + * + * @return true on success, false on error + */ +jboolean JNICALL ScriptMethodsSkillNamespace::grantSchematicGroup(JNIEnv *env, jobject self, jlong target, jstring groupName) +{ + UNREF(self); + + if (target == 0 || groupName == 0) + return JNI_FALSE; + + JavaStringParam groupNameParam(groupName); + + CreatureObject * creature = NULL; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + std::string group; + if (!JavaLibrary::convert(groupNameParam, group)) + return JNI_FALSE; + + creature->grantSchematicGroup("+" + group, false); + return JNI_TRUE; +} // JavaLibrary::grantSchematicGroup + +//----------------------------------------------------------------------- + +/** + * Removes a schematic group from a creature. + * + * @param env Java environment + * @param self class calling this function + * @param target the creature + * @param groupName the schematic group name + * + * @return true on success, false on error + */ +jboolean JNICALL ScriptMethodsSkillNamespace::revokeSchematicGroup(JNIEnv *env, jobject self, jlong target, jstring groupName) +{ + UNREF(self); + + if (target == 0 || groupName == 0) + return JNI_FALSE; + + JavaStringParam groupNameParam(groupName); + + CreatureObject * creature = NULL; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + std::string group; + if (!JavaLibrary::convert(groupNameParam, group)) + return JNI_FALSE; + + creature->grantSchematicGroup("-" + group, false); + return JNI_TRUE; +} // JavaLibrary::revokeSchematicGroup + +//----------------------------------------------------------------------- + +/** + * Adds a schematic to a creature. + * + * @param env Java environment + * @param self class calling this function + * @param target the creature + * @param schematicName the schematic name + * + * @return true on success, false on error + */ +jboolean JNICALL ScriptMethodsSkillNamespace::grantSchematicName(JNIEnv *env, jobject self, jlong target, jstring schematicName) +{ + UNREF(self); + + if (target == 0 || schematicName == 0) + return JNI_FALSE; + + JavaStringParam schematicNameParam(schematicName); + + std::string schematic; + if (!JavaLibrary::convert(schematicNameParam, schematic)) + return JNI_FALSE; + + return grantSchematicCrc(env, self, target, static_cast(Crc::calculate( + schematic.c_str()))); +} // JavaLibrary::grantSchematicName + +//----------------------------------------------------------------------- + +/** + * Adds a schematic to a creature. + * + * @param env Java environment + * @param self class calling this function + * @param target the creature + * @param schematicCrc the schematic name crc + * + * @return true on success, false on error + */ +jboolean JNICALL ScriptMethodsSkillNamespace::grantSchematicCrc(JNIEnv *env, jobject self, jlong target, jint schematicCrc) +{ + UNREF(self); + + CreatureObject * creature = NULL; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + creature->grantSchematic(static_cast(schematicCrc), false); + return JNI_TRUE; +} // JavaLibrary::grantSchematicCrc + +//----------------------------------------------------------------------- + +/** + * Removes a schematic from a creature. + * + * @param env Java environment + * @param self class calling this function + * @param target the creature + * @param schematicName the schematic name + * + * @return true on success, false on error + */ +jboolean JNICALL ScriptMethodsSkillNamespace::revokeSchematicName(JNIEnv *env, jobject self, jlong target, jstring schematicName) +{ + UNREF(self); + + if (target == 0 || schematicName == 0) + return JNI_FALSE; + + JavaStringParam schematicNameParam(schematicName); + + std::string schematic; + if (!JavaLibrary::convert(schematicNameParam, schematic)) + return JNI_FALSE; + + return revokeSchematicCrc(env, self, target, static_cast(Crc::calculate( + schematic.c_str()))); +} // JavaLibrary::revokeSchematicName + +//----------------------------------------------------------------------- + +/** + * Removes a schematic from a creature. + * + * @param env Java environment + * @param self class calling this function + * @param target the creature + * @param schematicCrc the schematic name crc + * + * @return true on success, false on error + */ +jboolean JNICALL ScriptMethodsSkillNamespace::revokeSchematicCrc(JNIEnv *env, jobject self, jlong target, jint schematicCrc) +{ + UNREF(self); + + CreatureObject * creature = NULL; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + creature->revokeSchematic(static_cast(schematicCrc), false); + return JNI_TRUE; +} // JavaLibrary::revokeSchematicCrc + +//----------------------------------------------------------------------- + +/** + * Tests if a creature has a given schematic. + * + * @param env Java environment + * @param self class calling this function + * @param target the creature + * @param schematicName the schematic name + * + * @return true on success, false on error + */ +jboolean JNICALL ScriptMethodsSkillNamespace::hasSchematicName(JNIEnv *env, jobject self, jlong target, jstring schematicName) +{ + UNREF(self); + + if (target == 0 || schematicName == 0) + return JNI_FALSE; + + JavaStringParam schematicNameParam(schematicName); + + std::string schematic; + if (!JavaLibrary::convert(schematicNameParam, schematic)) + return JNI_FALSE; + + return hasSchematicCrc(env, self, target, static_cast(Crc::calculate( + schematic.c_str()))); +} // JavaLibrary::hasSchematicName + +//----------------------------------------------------------------------- + +/** + * Tests if a creature has a given schematic. + * + * @param env Java environment + * @param self class calling this function + * @param target the creature + * @param schematicCrc the schematic name crc + * + * @return true on success, false on error + */ +jboolean JNICALL ScriptMethodsSkillNamespace::hasSchematicCrc(JNIEnv *env, jobject self, jlong target, jint schematicCrc) +{ + UNREF(self); + + CreatureObject * creature = NULL; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + if (creature->hasSchematic(static_cast(schematicCrc))) + return JNI_TRUE; + return JNI_FALSE; +} // JavaLibrary::hasSchematicCrc + +//----------------------------------------------------------------------- + +/** + * Finds the skill mods attached to a player. + * + * @param env Java environment + * @param self class calling this function + * @param player the player + * + * @return the skill mod names the player has, or null on error + */ +jobjectArray JNICALL ScriptMethodsSkillNamespace::getSkillStatModListingForPlayer(JNIEnv *env, jobject self, jlong player) +{ + const CreatureObject * creature = NULL; + if (!JavaLibrary::getObject(player, creature)) + return 0; + + typedef std::map > ModMap; + const ModMap & mods = creature->getModMap(); + int count = mods.size(); + LocalObjectArrayRefPtr jmods = createNewObjectArray(count, JavaLibrary::getClsString()); + int i = 0; + for (ModMap::const_iterator iter = mods.begin(); iter != mods.end(); ++iter, ++i) + { + JavaString mod((*iter).first); + setObjectArrayElement(*jmods, i, mod); + } + return jmods->getReturnValue(); +} // JavaLibrary::getSkillStatModListingForPlayer + +//----------------------------------------------------------------------- + +/** + * Finds the skill commands attached to a player + * + * @param env Java environment + * @param self class calling this function + * @param player the player + * + * @return the commands the player has, or null on error + */ +jobjectArray JNICALL ScriptMethodsSkillNamespace::getCommandListingForPlayer(JNIEnv *env, jobject self, jlong player) +{ + const CreatureObject * creature = NULL; + if (!JavaLibrary::getObject(player, creature)) + return 0; + + const std::map & commands = creature->getCommandList(); + int count = commands.size(); + LocalObjectArrayRefPtr jcommands = createNewObjectArray(count, JavaLibrary::getClsString()); + int index = 0; + for (std::map::const_iterator i = commands.begin(); i != commands.end(); ++i) + { + JavaString command((*i).first); + setObjectArrayElement(*jcommands, index++, command); + } + return jcommands->getReturnValue(); +} // JavaLibrary::getCommandListingForPlayer + +//----------------------------------------------------------------------- + +/** + * Finds the schematics granted by a skill. + * + * @param env Java environment + * @param self class calling this function + * @param skillName the skill + * + * @return the schematic names the skill grants + */ +jintArray JNICALL ScriptMethodsSkillNamespace::getSkillSchematicsGranted(JNIEnv *env, jobject self, + jstring skillName) +{ + JavaStringParam jskillName(skillName); + std::string name; + if (!JavaLibrary::convert(jskillName, name)) + return 0; + + const SkillObject * skill = SkillManager::getInstance().getSkill(name); + if (skill == NULL) + return 0; + + // get all the granted schematics from the skill groups for the skill + std::vector schematics; + DraftSchematicGroupManager::SchematicVector drafts; + const SkillObject::StringVector & groups = skill->getSchematicsGranted(); + for (SkillObject::StringVector::const_iterator iter = groups.begin(); + iter != groups.end(); ++iter) + { + drafts.clear(); + if (!DraftSchematicGroupManager::getSchematicsForGroup (*iter, drafts)) + { + WARNING(true, ("JavaLibrary::getSkillSchematicsGranted found bad " + "schematic group [%s]", (*iter).c_str())); + } + else + { + for (DraftSchematicGroupManager::SchematicVector::const_iterator jiter = + drafts.begin (); jiter != drafts.end (); ++jiter) + { + schematics.push_back((*jiter).first); + } + } + } + + // xlate the schematic names to Java + int count = schematics.size(); + LocalIntArrayRefPtr jschematics = createNewIntArray(count); + if (count > 0) + setIntArrayRegion(*jschematics, 0, count, &schematics[0]); + return jschematics->getReturnValue(); +} // JavaLibrary::getSkillSchematicsGranted + +//----------------------------------------------------------------------- + +/** + * Finds the draft schematics a player has. + * + * @param env Java environment + * @param self class calling this function + * @param player the player + * + * @return the schematics' crc, or null on error + */ +jintArray JNICALL ScriptMethodsSkillNamespace::getSchematicListingForPlayer(JNIEnv *env, jobject self, jlong player) +{ + const CreatureObject * creature = NULL; + if (!JavaLibrary::getObject(player, creature)) + return 0; + + const std::map,int> & schematics = creature->getDraftSchematics(); + int count = schematics.size(); + LocalIntArrayRefPtr jschematics = createNewIntArray(count); + if (count > 0) + { + jint * buffer = new jint[count]; + int index = 0; + for (std::map,int>::const_iterator i = schematics.begin(); i != schematics.end(); ++i) + { + buffer[index++] = (*i).first.first; + } + setIntArrayRegion(*jschematics, 0, count, buffer); + delete[] buffer; + } + + + return jschematics->getReturnValue(); +} // JavaLibrary::getSchematicListingForPlayer + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsSkillNamespace::hasCertificationsForItem(JNIEnv *env, jobject self, jlong player, jlong item) +{ + const CreatureObject * creatureObject = NULL; + if (!JavaLibrary::getObject(player, creatureObject) || !creatureObject) + return JNI_FALSE; + + Client const * const client = creatureObject->getClient(); + if(client) + { + if(client->isGod()) + { + Chat::sendSystemMessage(*creatureObject, Unicode::narrowToWide("(unloclized) Bypassing certification check due to GOD mode."), Unicode::emptyString); + return JNI_TRUE; + } + } + + const TangibleObject * itemObject = NULL; + if (!JavaLibrary::getObject(item, itemObject) || !itemObject) + return JNI_FALSE; + + return creatureObject->hasCertificationsForItem(*itemObject); +} + +// ---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsSkillNamespace::getRequiredCertifications(JNIEnv *env, jobject self, jlong item) +{ + const TangibleObject * itemAsTangible = NULL; + if (!JavaLibrary::getObject(item, itemAsTangible) || !itemAsTangible) + { + JAVA_THROW_SCRIPT_EXCEPTION(true,("getRequiredCertifications called with an object that does not exist")); + return NULL; + } + + std::vector certs; + itemAsTangible->getRequiredCertifications(certs); + + LocalObjectArrayRefPtr results; + if (!ScriptConversion::convert(certs, results)) + return NULL; + + return results->getReturnValue(); +} + +// ---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsSkillNamespace::getSkillTemplate(JNIEnv *env, jobject self, jlong player) +{ + CreatureObject const * creature = NULL; + + if (JavaLibrary::getObject(player, creature)) + { + PlayerObject const * const player = PlayerCreatureController::getPlayerObject(creature); + if (player) + { + JavaString str(player->getSkillTemplate().c_str()); + return str.getReturnValue(); + } + } + + return NULL; +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsSkillNamespace::setSkillTemplate(JNIEnv *env, jobject self, jlong player, jstring skillTemplateName) +{ + CreatureObject * creature = NULL; + + if (JavaLibrary::getObject(player, creature)) + { + PlayerObject * const player = PlayerCreatureController::getPlayerObject(creature); + + if (player) + { + JavaStringParam const javaSkillTemplateName(skillTemplateName); + std::string skill; + if (JavaLibrary::convert(javaSkillTemplateName, skill)) + { + player->setSkillTemplate(skill, false); + } + } + } +} + +// ---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsSkillNamespace::getWorkingSkill(JNIEnv *env, jobject self, jlong player) +{ + CreatureObject const * creature = NULL; + + if (JavaLibrary::getObject(player, creature)) + { + PlayerObject const * const player = PlayerCreatureController::getPlayerObject(creature); + + if (player) + { + JavaString str(player->getWorkingSkill().c_str()); + return str.getReturnValue(); + } + } + + return NULL; +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsSkillNamespace::setWorkingSkill(JNIEnv *env, jobject self, jlong player, jstring workingSkillName) +{ + CreatureObject * creature = NULL; + + if (JavaLibrary::getObject(player, creature)) + { + PlayerObject * const player = PlayerCreatureController::getPlayerObject(creature); + + if (player) + { + JavaStringParam const javaWorkingSkillName(workingSkillName); + std::string skill; + if (JavaLibrary::convert(javaWorkingSkillName, skill)) + { + player->setWorkingSkill(skill, false); + } + } + } +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsSkillNamespace::recomputeCommandSeries(JNIEnv *env, jobject self, jlong player) +{ + CreatureObject * creature = NULL; + + if (JavaLibrary::getObject(player, creature)) + { + creature->recomputeCommandSeries(); + } +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsSkillNamespace::resetExpertises(JNIEnv *env, jobject self, jlong player) +{ + CreatureObject * creature = NULL; + + if (JavaLibrary::getObject(player, creature)) + { + creature->clearAllExpertises(); + } +} +// ====================================================================== diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsSpawner.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsSpawner.cpp new file mode 100644 index 00000000..9fee9f96 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsSpawner.cpp @@ -0,0 +1,51 @@ +// ScriptMethodsSpawner.cpp +// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved. +// Author: Justin Randall + +//----------------------------------------------------------------------- + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "serverGame/ConfigServerGame.h" +#include "serverGame/CreatureObject.h" +#include "serverGame/GameServer.h" +#include "serverGame/ServerWorld.h" +#include "sharedFoundation/ConfigFile.h" + +//----------------------------------------------------------------------- + +namespace ScriptMethodsSpawnerNamespace +{ + bool install(); + + jint JNICALL getServerSpawnLimit(JNIEnv * env, jobject self); +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsSpawnerNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsSpawnerNamespace::c)} + JF("getServerSpawnLimit", "()I", getServerSpawnLimit), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +//----------------------------------------------------------------------- + +jint JNICALL ScriptMethodsSpawnerNamespace::getServerSpawnLimit(JNIEnv * env, jobject self) +{ + UNREF(env); + UNREF(self); + + return GameServer::getServerSpawnLimit(); +} + +//----------------------------------------------------------------------- diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsString.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsString.cpp new file mode 100644 index 00000000..47a378f8 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsString.cpp @@ -0,0 +1,202 @@ +//======================================================================= +// +// ScriptMethodsString.cpp +// Copyright 2000-05, Sony Online Entertainment Inc., all rights reserved. +// +//======================================================================= + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "serverGame/NameManager.h" +#include "sharedGame/TextManager.h" + +using namespace JNIWrappersNamespace; + + +// ====================================================================== +// ScriptMethodsStringNamespace +// ====================================================================== + +namespace ScriptMethodsStringNamespace +{ + bool install(); + + jstring JNICALL getString(JNIEnv *env, jobject self, jobject id); + jobjectArray JNICALL getStrings(JNIEnv *env, jobject self, jobjectArray ids); + jboolean JNICALL isObscene(JNIEnv *env, jobject self, jstring data); + jboolean JNICALL isAppropriateText(JNIEnv *env, jobject self, jstring data); +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsStringNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsStringNamespace::c)} + JF("getString", "(Lscript/string_id;)Ljava/lang/String;", getString), + JF("getStrings", "([Lscript/string_id;)[Ljava/lang/String;", getStrings), + JF("isObscene", "(Ljava/lang/String;)Z", isObscene), + JF("isAppropriateText", "(Ljava/lang/String;)Z", isAppropriateText), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +//---------------------------------------------------------------------- + +/** + * Returns the string associated with a stringId. + * + * @param env Java environment + * @param self class calling this function + * @param id the stringId to find + * + * @return the string, or null on error + */ +jstring JNICALL ScriptMethodsStringNamespace::getString(JNIEnv *env, jobject self, jobject id) +{ + UNREF(self); + + if (id == 0) + { + WARNING(true, ("JavaLibrary::log getString is NULL.")); + return 0; + } + + // convert the string id to a char string + if (!env->IsInstanceOf(id, JavaLibrary::getClsStringId())) + { + WARNING(true, ("JavaLibrary::log IsInstanceOf failed.")); + return 0; + } + + // get the table + JavaStringPtr tempString = getStringField(LocalRefParam(id), JavaLibrary::getFidStringIdTable()); + std::string table; + if(! JavaLibrary::convert(*tempString, table)) + { + WARNING(true, ("JavaLibrary::log failed to get the string table.")); + return 0; + } + + std::string asciiId; + JavaStringPtr tempAsciiIdString = getStringField(LocalRefParam(id), JavaLibrary::getFidStringIdAsciiId()); + if(! JavaLibrary::convert(*tempAsciiIdString, asciiId)) + { + WARNING(true, ("JavaLibrary::log failed to get the string asciiId.")); + return 0; + } + + const StringId stringId(table, asciiId); + Unicode::String localized; + + if (stringId.localize(localized)) + { + JavaString result(localized); + return result.getReturnValue(); + } + else + { + WARNING(true, ("JavaLibrary::log failed to localize the stringId(%s, %s)", table.c_str(), asciiId.c_str())); + } + + return 0; + +} // JavaLibrary::getString + +//---------------------------------------------------------------------- + +/** + * Returns the strings associated with an array of stringIds. + * + * @param env Java environment + * @param self class calling this function + * @param ids array of stringIds to find + * + * @return an array of strings, or null on error + */ +jobjectArray JNICALL ScriptMethodsStringNamespace::getStrings(JNIEnv *env, jobject self, jobjectArray ids) +{ + UNREF(self); + + if (ids == 0) + return 0; + + if (!env->IsInstanceOf(ids, JavaLibrary::getClsStringIdArray())) + return 0; + + jsize count = env->GetArrayLength(ids); + + // create the string array to return + LocalObjectArrayRefPtr strings = createNewObjectArray(count, JavaLibrary::getClsString()); + if (strings == LocalObjectArrayRef::cms_nullPtr) + return 0; + + // fill the array + for (jsize i = 0; i < count; ++i) + { + LocalRefPtr id = getObjectArrayElement(LocalObjectArrayRefParam(ids), i); + setObjectArrayElement(*strings, i, LocalRef(getString(env, self, id->getValue()))); + } + + return strings->getReturnValue(); +} // JavaLibrary::getStrings + +//---------------------------------------------------------------------- + +/** + * Finds if a string is obscene. + * + * @param env Java environment + * @param self class calling this function + * @param data string to test + * + * @return true if the string is obscene, false if not + */ +jboolean JNICALL ScriptMethodsStringNamespace::isObscene(JNIEnv *env, jobject self, jstring data) +{ + if (data == 0) + return JNI_FALSE; + + JavaStringParam jtext(data); + Unicode::String text; + if (JavaLibrary::convert(jtext, text)) + { + return NameManager::getInstance().isNameReserved(text); + } + + return JNI_FALSE; +} // JavaLibrary::isObscene + +//---------------------------------------------------------------------- + +/** + * Tests is a string is appropriate, whatever that means. + * + * @param env Java environment + * @param self class calling this function + * @param data string to test + * + * @return true if the string is appropriate, false if not + */ +jboolean JNICALL ScriptMethodsStringNamespace::isAppropriateText(JNIEnv *env, jobject self, jstring data) +{ + if (data == 0) + return JNI_FALSE; + + JavaStringParam jtext(data); + Unicode::String text; + if (JavaLibrary::convert(jtext, text)) + { + return TextManager::isAppropriateText(text); + } + + return JNI_FALSE; +} // JavaLibrary::isAppropriateText + +//---------------------------------------------------------------------- diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsSystem.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsSystem.cpp new file mode 100644 index 00000000..90861085 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsSystem.cpp @@ -0,0 +1,238 @@ +// ScriptMethodsSystem.cpp - implements script methods that are stubs needing real implementation +// +// copyright 2002 Sony Online Entertainment +// +//======================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "serverGame/BuildingObject.h" +#include "serverGame/Client.h" +#include "serverGame/ServerObject.h" +#include "sharedFoundation/ConfigFile.h" +#include "sharedNetworkMessages/ConsoleChannelMessages.h" +#include "sharedNetworkMessages/GenericValueTypeMessage.h" +#include "sharedNetworkMessages/PlayCutSceneMessage.h" + + +// ====================================================================== +// ScriptMethodsSystemNamespace +// ====================================================================== + +namespace ScriptMethodsSystemNamespace +{ + bool install(); + + jboolean JNICALL sendConsoleCommand(JNIEnv * env, jobject self, jstring command, jlong target); + jstring JNICALL getConfigSetting(JNIEnv * env, jobject self, jstring section, jstring key); + jboolean JNICALL fixHouseItemLimit(JNIEnv * env, jobject self, jlong target); + void JNICALL saveTextOnClient(JNIEnv * env, jobject self, jlong jclient, jstring jfilename, jstring jfiletext); + void JNICALL saveBytesOnClient(JNIEnv * env, jobject self, jlong jclient, jstring jfilename, jbyteArray bytes); + void JNICALL launchClientWebBrowser(JNIEnv *env, jobject self, jlong player, jstring url); + void JNICALL playCutScene(JNIEnv * env, jobject self, jlong jclient, jstring jfilename); +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsSystemNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsSystemNamespace::c)} + JF("_sendConsoleCommand", "(Ljava/lang/String;J)Z", sendConsoleCommand), + JF("getConfigSetting", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", getConfigSetting), + JF("_fixHouseItemLimit", "(J)Z", fixHouseItemLimit), + JF("_saveTextOnClient", "(JLjava/lang/String;Ljava/lang/String;)V", saveTextOnClient), + JF("_saveBytesOnClient", "(JLjava/lang/String;[B)V", saveBytesOnClient), + JF("_launchClientWebBrowser", "(JLjava/lang/String;)V", launchClientWebBrowser), + JF("_playCutScene", "(JLjava/lang/String;)V", playCutScene), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsSystemNamespace::sendConsoleCommand(JNIEnv * env, jobject self, jstring command, jlong target) +{ + JavaStringParam localCommand(command); + + ServerObject* object = NULL; + if (!JavaLibrary::getObject(target, object)) + return JNI_FALSE; + + Client* client = object->getClient(); + if (!client) + return JNI_FALSE; + + std::string commandName; + JavaLibrary::convert(localCommand, commandName); + + ExecuteConsoleCommand msg(commandName); + client->send(msg,true); + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- +/** + * Returns the value of a config file key. + * + * @param env Java environment + * @param self class calling this function + * @param section the config file section + * @param key the config file key + * + * @return the key value, or null if the key doesn't exist + */ +jstring JNICALL ScriptMethodsSystemNamespace::getConfigSetting(JNIEnv * env, jobject self, + jstring section, jstring key) +{ + UNREF(self); + + if (section == 0 || key == 0) + return 0; + + JavaStringParam jsection(section); + JavaStringParam jkey(key); + + std::string sectionName; + if (!JavaLibrary::convert(jsection, sectionName)) + return 0; + + std::string keyName; + if (!JavaLibrary::convert(jkey, keyName)) + return 0; + + const ConfigFile::Section * sec = ConfigFile::getSection(sectionName.c_str()); + if (sec == NULL) + return 0; + + const ConfigFile::Key * ky = sec->findKey(keyName.c_str()); + if (ky == NULL) + return NULL; + + JavaString jvalue(ky->getAsString(ky->getCount()-1, "")); + return jvalue.getReturnValue(); +} // JavaLibrary::getConfigSetting + +// ---------------------------------------------------------------------- +/** + * Utility function to fix a bug with houses. + * + * @param env Java environment + * @param self class calling this function + * @param target the house to fix + * + * @return true on success, false if target isn't a building + */ +jboolean JNICALL ScriptMethodsSystemNamespace::fixHouseItemLimit(JNIEnv * env, jobject self, jlong target) +{ + UNREF(self); + + TangibleObject *pob = 0; + if (!JavaLibrary::getObject(target, pob) || !pob->getPortalProperty()) + return JNI_FALSE; + + pob->fixUpPobItemLimit(); + return JNI_TRUE; +} // JavaLibrary::fixHouseItemLimit + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsSystemNamespace::saveTextOnClient(JNIEnv *, jobject, jlong jclient, jstring jfilename, jstring jfiletext) +{ + ServerObject *obj = 0; + if (JavaLibrary::getObject(jclient, obj)) + { + Client * const client = obj->getClient(); + if (client && client->isGod()) + { + JavaStringParam filenameParam(jfilename); + JavaStringParam filetextParam(jfiletext); + std::string filename, filetext; + if (JavaLibrary::convert(filenameParam, filename) && JavaLibrary::convert(filetextParam, filetext)) + { + GenericValueTypeMessage > const msg("SaveTextOnClient", std::make_pair(filename, filetext)); + client->send(msg, true); + } + } + } +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsSystemNamespace::saveBytesOnClient(JNIEnv *, jobject, jlong jclient, jstring jfilename, jbyteArray bytes) +{ + ServerObject *obj = 0; + if (JavaLibrary::getObject(jclient, obj)) + { + Client * const client = obj->getClient(); + if (client && client->isGod()) + { + JavaStringParam filenameParam(jfilename); + std::string filename; + if (JavaLibrary::convert(filenameParam, filename)) + { + if (bytes != 0) + { + std::vector bytesStr; + if (ScriptConversion::convert(bytes, bytesStr)) + { + GenericValueTypeMessage > const msg("SaveTextOnClient", std::make_pair(filename, std::string(bytesStr.begin(), bytesStr.end()))); + client->send(msg, true); + } + } + } + } + } +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsSystemNamespace::launchClientWebBrowser(JNIEnv *env, jobject self, jlong player, jstring url) +{ + ServerObject const * obj = 0; + if (JavaLibrary::getObject(player, obj)) + { + Client const * const client = obj->getClient(); + if (client) + { + JavaStringParam urlParam(url); + std::string urlString; + if (JavaLibrary::convert(urlParam, urlString)) + client->launchWebBrowser(urlString); + else + JAVA_THROW_SCRIPT_EXCEPTION(true, ("launchClientWebBrowser called with a url parameter that could not be converted to a string (network id was %s)",obj->getNetworkId().getValueString().c_str())); + } + } + else + JAVA_THROW_SCRIPT_EXCEPTION(true, ("launchClientWebBrowser was called with a network id paramter that could not be converted to an object.")); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsSystemNamespace::playCutScene(JNIEnv * env, jobject self, jlong jclient, jstring jfilename) +{ + ServerObject *obj = 0; + if (JavaLibrary::getObject(jclient, obj)) + { + Client * const client = obj->getClient(); + if (client) + { + JavaStringParam filenameParam(jfilename); + std::string fileName; + if(JavaLibrary::convert(filenameParam, fileName)) + { + PlayCutSceneMessage cutScene(fileName); + client->send(cutScene, true); + } + } + } +} + +// ====================================================================== + diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsTerrain.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsTerrain.cpp new file mode 100644 index 00000000..c56803c1 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsTerrain.cpp @@ -0,0 +1,1206 @@ +// ====================================================================== +// +// ScriptMethodsTerrain.cpp +// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved. +// +// ====================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "serverGame/CreatureObject.h" +#include "serverGame/GameServer.h" +#include "serverGame/PlanetObject.h" +#include "serverGame/ServerObject.h" +#include "serverGame/ServerObjectTemplate.h" +#include "serverGame/ServerUniverse.h" +#include "serverGame/ServerWorld.h" +#include "serverNetworkMessages/LocationRequest.h" +#include "serverPathfinding/ServerPathBuilder.h" +#include "serverUtility/ServerClock.h" +#include "sharedCollision/CollisionProperty.h" +#include "sharedCollision/CollisionWorld.h" +#include "sharedCollision/FloorContactShape.h" +#include "sharedCollision/Floor.h" +#include "sharedCollision/Footprint.h" +#include "sharedCollision/MultiList.h" +#include "sharedDebug/Profiler.h" +#include "sharedGame/SharedTangibleObjectTemplate.h" +#include "sharedGame/SharedTerrainSurfaceObjectTemplate.h" +#include "sharedMath/Rectangle2d.h" +#include "sharedMath/Sphere.h" +#include "sharedNetworkMessages/CreateClientPathMessage.h" +#include "sharedNetworkMessages/DestroyClientPathMessage.h" +#include "sharedNetworkMessages/EnterStructurePlacementModeMessage.h" +#include "sharedObject/CellProperty.h" +#include "sharedObject/LotManager.h" +#include "sharedObject/ObjectTemplateList.h" +#include "sharedObject/StructureFootprint.h" +#include "sharedTerrain/TerrainObject.h" + +#include +#include + +using namespace JNIWrappersNamespace; + + +// ====================================================================== +// ScriptMethodsTerrainNamespace +// ====================================================================== + +namespace ScriptMethodsTerrainNamespace +{ + bool install(); + + jfloat JNICALL getHeightAtLocation (JNIEnv* env, jobject self, jfloat x, jfloat z); + jfloat JNICALL getCoverAtLocation (JNIEnv* env, jobject self, jfloat x, jfloat z); + jobject JNICALL getGoodLocation (JNIEnv* env, jobject self, jfloat hintX, jfloat hintY, jobject searchRectLowerLeftLocation, jobject searchRectUpperRightLocation, jboolean dontCheckWater, jboolean dontCheckSlope); + jobject JNICALL getGoodLocationAvoidCollidables (JNIEnv* env, jobject self, jfloat hintX, jfloat hintY, jobject searchRectLowerLeftLocation, jobject searchRectUpperRightLocation, jboolean dontCheckWater, jboolean dontCheckSlope, jfloat staticObjDistance); + jboolean JNICALL enterClientStructurePlacementMode (JNIEnv* env, jobject self, jlong player, jlong deed, jstring serverObjectTemplateName); + jfloat JNICALL canPlaceStructure (JNIEnv* env, jobject self, jstring serverObjectTemplateName, jobject position, jint rotation); + jlong JNICALL createTemporaryStructure (JNIEnv* env, jobject self, jstring serverObjectTemplateName, jobject position, jint rotation); + jint JNICALL getNumberOfLots (JNIEnv* env, jobject self, jstring serverObjectTemplateName); + jfloat JNICALL getLocalTime (JNIEnv* env, jobject self); + jfloat JNICALL getLocalDayLength (JNIEnv* env, jobject self); + jboolean JNICALL setWeatherData (JNIEnv* env, jobject self, jint index, jfloat windVelocityX, jfloat windVelocityZ); + jboolean JNICALL isBelowWater (JNIEnv* env, jobject self, jobject location); + jboolean JNICALL isWaterInRect (JNIEnv* env, jobject self, jfloat x0, jfloat y0, jfloat x1, jfloat y1); + jboolean JNICALL createClientPath (JNIEnv * env, jobject self, jlong player, jobject start, jobject end); + jboolean JNICALL createClientPathAdvanced(JNIEnv * env, jobject self, jlong player, jobject locationStart, jobject locationEnd, jstring appearanceTableEntry); + jboolean JNICALL destroyClientPath (JNIEnv * env, jobject self, jlong player); + jfloat JNICALL getWaterTableHeight (JNIEnv* env, jobject self, jobject location); + jboolean JNICALL requestLocation (JNIEnv * env, jobject self, jlong scriptObject, jstring locationId, jobject searchLocation, jfloat searchRadius, jfloat locationReservationRadius, jboolean checkWater, jboolean checkSlope); + jboolean JNICALL isRelativePointOnSameFloorAsObject(JNIEnv * env, jobject self, jlong scriptObject, jfloat relativeXLocation, jfloat relativeZLocation); + jfloat JNICALL getFloorHeightAtRelativePointOnSameFloorAsObject(JNIEnv * env, jobject self, jlong scriptObject, jfloat relativeXLocation, jfloat relativeZLocation); + jboolean JNICALL isOnAFloor (JNIEnv * env, jobject self, jlong scriptObject); + jboolean JNICALL setCreatureCoverDefault(JNIEnv *env, jobject self, jlong target); + jboolean JNICALL setCreatureCover(JNIEnv *env, jobject self, jlong target, jint cover); + void JNICALL setCreatureCoverVisibility(JNIEnv * env, jobject self, jlong target, jboolean isVisibile); + jboolean JNICALL getCreatureCoverVisibility(JNIEnv * env, jobject self, jlong target); + jlong JNICALL getStandingOn(JNIEnv *env, jobject self, jlong target); +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsTerrainNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsTerrainNamespace::c)} + JF("getHeightAtLocation", "(FF)F", getHeightAtLocation), + JF("getCoverAtLocation", "(FF)F", getCoverAtLocation), + JF("getGoodLocation", "(FFLscript/location;Lscript/location;ZZ)Lscript/location;", getGoodLocation), + JF("getGoodLocationAvoidCollidables", "(FFLscript/location;Lscript/location;ZZF)Lscript/location;", getGoodLocationAvoidCollidables), + JF("_enterClientStructurePlacementMode", "(JJLjava/lang/String;)Z", enterClientStructurePlacementMode), + JF("canPlaceStructure", "(Ljava/lang/String;Lscript/location;I)F", canPlaceStructure), + JF("_createTemporaryStructure", "(Ljava/lang/String;Lscript/location;I)J", createTemporaryStructure), + JF("getNumberOfLots", "(Ljava/lang/String;)I", getNumberOfLots), + JF("getLocalTime", "()F", getLocalTime), + JF("getLocalDayLength", "()F", getLocalDayLength), + JF("setWeatherData", "(IFF)Z", setWeatherData), + JF("isBelowWater", "(Lscript/location;)Z", isBelowWater), + JF("isWaterInRect", "(FFFF)Z", isWaterInRect), + JF("_createClientPath", "(JLscript/location;Lscript/location;)Z", createClientPath), + JF("_createClientPathAdvanced", "(JLscript/location;Lscript/location;Ljava/lang/String;)Z", createClientPathAdvanced), + JF("_destroyClientPath", "(J)Z", destroyClientPath), + JF("getWaterTableHeight", "(Lscript/location;)F", getWaterTableHeight), + JF("_requestLocation", "(JLjava/lang/String;Lscript/location;FFZZ)Z", requestLocation), + JF("_isRelativePointOnSameFloorAsObject", "(JFF)Z", isRelativePointOnSameFloorAsObject), + JF("_getFloorHeightAtRelativePointOnSameFloorAsObject", "(JFF)F", getFloorHeightAtRelativePointOnSameFloorAsObject), + JF("_isOnAFloor", "(J)Z", isOnAFloor), + JF("_setCreatureCover", "(J)Z", setCreatureCoverDefault), + JF("_setCreatureCover", "(JI)Z", setCreatureCover), + JF("_setCreatureCoverVisibility", "(JZ)V", setCreatureCoverVisibility), + JF("_getCreatureCoverVisibility", "(J)Z", getCreatureCoverVisibility), + JF("_getStandingOn", "(J)J", getStandingOn), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +// ====================================================================== + +jfloat JNICALL ScriptMethodsTerrainNamespace::getHeightAtLocation(JNIEnv * /*env*/, jobject /*self*/, jfloat x, jfloat z) +{ + PROFILER_AUTO_BLOCK_DEFINE("JNI::getHeightAtLocation"); + float height = 0.f; + const bool result = TerrainObject::getInstance()->getHeightForceChunkCreation(Vector(x, 0.f, z), height); + DEBUG_WARNING (!result, ("JavaLibrary::getHeightAtLocation: failed for position %1.2f, %1.2f", x, z)); + UNREF (result); + + return height; +} + +// ---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsTerrainNamespace::getCoverAtLocation(JNIEnv * /*env*/, jobject /*self*/, jfloat x, jfloat z) +{ + const Vector position (x, 0.f, z); + + float cover = 0.f; + const SharedTerrainSurfaceObjectTemplate* const sharedTerrainSurfaceObjectTemplate = safe_cast (TerrainObject::getInstance ()->getSurfaceProperties (position)); + if (sharedTerrainSurfaceObjectTemplate) + cover += sharedTerrainSurfaceObjectTemplate->getCover (); + + float height = 0.f; + if (TerrainObject::getInstance ()->getHeight (position, height)) + { + const Sphere sphere (Vector (x, height, z), 4.f); + + ObjectVec objectList; + if (CollisionWorld::query (sphere, &objectList) && !objectList.empty ()) + cover += 1.f; + } + + return 100.f * clamp (0.f, cover, 1.f); +} + +// ---------------------------------------------------------------------- + +jobject JNICALL ScriptMethodsTerrainNamespace::getGoodLocation(JNIEnv * /*env*/, jobject /*self*/, jfloat areaSizeX, jfloat areaSizeZ, jobject searchRectLowerLeftLocation, jobject searchRectUpperRightLocation, jboolean dontCheckWater, jboolean dontCheckSlope) +{ + PROFILER_AUTO_BLOCK_DEFINE("JNI::getGoodLocation"); + + //validate scripter's input + if (searchRectLowerLeftLocation == NULL) + { + DEBUG_WARNING (true, ("getGoodLocation (): DB lower left is NULL")); + return NULL; + } + + if (searchRectUpperRightLocation == NULL) + { + DEBUG_WARNING (true, ("getGoodLocation (): DB upper right is NULL")); + return NULL; + } + + //pull the data from the java Location objects. sceneid and cell are not checked or used, but sent back in the good location, if one exists + std::string sceneId; + + Vector srLLLocationVec; + if (!ScriptConversion::convertWorld(searchRectLowerLeftLocation, srLLLocationVec, sceneId)) + { + DEBUG_WARNING (true, ("getGoodLocation (): DB could not convert lower left coordinates")); + return NULL; + } + + Vector srURLocationVec; + if (!ScriptConversion::convertWorld(searchRectUpperRightLocation, srURLocationVec, sceneId)) + { + DEBUG_WARNING (true, ("getGoodLocation (): DB could not convert upper right coordinates")); + return NULL; + } + + // get the good location from ServerWorld + Vector successLoc3d = ServerWorld::getGoodLocation(areaSizeX, areaSizeZ, srLLLocationVec, srURLocationVec, dontCheckWater, dontCheckSlope); + if (successLoc3d.x == 0 && successLoc3d.y == 0 && successLoc3d.z == 0) + { + // no good location available + return NULL; + } + + //convert it back into scripter lingo (a "location"), using the default scene and cell ids + LocalRefPtr goodLocation; + if (!ScriptConversion::convert(successLoc3d, sceneId, NetworkId(), goodLocation)) + { + DEBUG_WARNING (true, ("getGoodLocation (): PB could not convert result back to a location")); + return NULL; + } + + return goodLocation->getReturnValue(); +} + +jobject JNICALL ScriptMethodsTerrainNamespace::getGoodLocationAvoidCollidables(JNIEnv * /*env*/, jobject /*self*/, jfloat areaSizeX, jfloat areaSizeZ, jobject searchRectLowerLeftLocation, jobject searchRectUpperRightLocation, jboolean dontCheckWater, jboolean dontCheckSlope, jfloat staticObjDistance) +{ + PROFILER_AUTO_BLOCK_DEFINE("JNI::getGoodLocationAvoidCollidables"); + + //validate scripter's input + if (searchRectLowerLeftLocation == NULL) + { + DEBUG_WARNING (true, ("getGoodLocationAvoidCollidables (): DB lower left is NULL")); + return NULL; + } + + if (searchRectUpperRightLocation == NULL) + { + DEBUG_WARNING (true, ("getGoodLocationAvoidCollidables (): DB upper right is NULL")); + return NULL; + } + + //pull the data from the java Location objects. sceneid and cell are not checked or used, but sent back in the good location, if one exists + std::string sceneId; + + Vector srLLLocationVec; + if (!ScriptConversion::convertWorld(searchRectLowerLeftLocation, srLLLocationVec, sceneId)) + { + DEBUG_WARNING (true, ("getGoodLocationAvoidCollidables (): DB could not convert lower left coordinates")); + return NULL; + } + + Vector srURLocationVec; + if (!ScriptConversion::convertWorld(searchRectUpperRightLocation, srURLocationVec, sceneId)) + { + DEBUG_WARNING (true, ("getGoodLocationAvoidCollidables (): DB could not convert upper right coordinates")); + return NULL; + } + + // get the good location from ServerWorld + Vector successLoc3d = ServerWorld::getGoodLocationAvoidCollidables(areaSizeX, areaSizeZ, srLLLocationVec, srURLocationVec, dontCheckWater, dontCheckSlope, staticObjDistance); + if (successLoc3d.x == 0 && successLoc3d.y == 0 && successLoc3d.z == 0) + { + // no good location available + return NULL; + } + + //convert it back into scripter lingo (a "location"), using the default scene and cell ids + LocalRefPtr goodLocation; + if (!ScriptConversion::convert(successLoc3d, sceneId, NetworkId(), goodLocation)) + { + DEBUG_WARNING (true, ("getGoodLocationAvoidCollidables (): PB could not convert result back to a location")); + return NULL; + } + + return goodLocation->getReturnValue(); +} +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsTerrainNamespace::enterClientStructurePlacementMode (JNIEnv* /*env*/, jobject /*self*/, jlong jobject_player, jlong jobject_deed, jstring jstring_serverObjectTemplateName) +{ + //-- get the player object + ServerObject* player = 0; + if (!JavaLibrary::getObject (jobject_player, player)) + { + DEBUG_WARNING (true, ("enterClientStructurePlacementMode (): DB could not find player object")); + return JNI_FALSE; + } + + //-- get the client associated with the player + Client* const client = player->getClient (); + if (!client) + { + DEBUG_WARNING (true, ("enterClientStructurePlacementMode (): PB could get the player's client object")); + return JNI_FALSE; + } + + //-- make sure we have a valid object template name + JavaStringParam javaStringParam_serverObjectTemplateName (jstring_serverObjectTemplateName); + std::string serverObjectTemplateName; + if (!JavaLibrary::convert (javaStringParam_serverObjectTemplateName, serverObjectTemplateName)) + { + DEBUG_WARNING (true, ("enterClientStructurePlacementMode (): DB failed to convert parameter 3 (serverObjectTemplateName) to string")); + return JNI_FALSE; + } + + //-- make sure the name is not empty + if (serverObjectTemplateName.empty ()) + { + DEBUG_WARNING (true, ("enterClientStructurePlacementMode (): DB serverObjectTemplateName is empty")); + return JNI_FALSE; + } + + //-- fetch the object template + const ObjectTemplate* const objectTemplate = ObjectTemplateList::fetch (serverObjectTemplateName); + if (!objectTemplate) + { + DEBUG_WARNING (true, ("enterClientStructurePlacementMode (): DB serverObjectTemplate [%s] does not exist", serverObjectTemplateName.c_str ())); + return JNI_FALSE; + } + + //-- fetch the server object template + const ServerObjectTemplate* const serverObjectTemplate = dynamic_cast (objectTemplate); + if (!serverObjectTemplate) + { + objectTemplate->releaseReference (); + + DEBUG_WARNING (true, ("enterClientStructurePlacementMode (): DB objectTemplate [%s] exists, but is not a valid server object template", serverObjectTemplateName.c_str ())); + return JNI_FALSE; + } + + //-- fetch the shared object template + const std::string sharedObjectTemplateName = serverObjectTemplate->getSharedTemplate (); + serverObjectTemplate->releaseReference (); + if (sharedObjectTemplateName.empty ()) + { + DEBUG_WARNING (true, ("enterClientStructurePlacementMode (): DB sharedObjectTemplateName specified by serverObjectTemplate [%s] is empty", serverObjectTemplateName.c_str ())); + return JNI_FALSE; + } + + //-- get the id of the deed + const NetworkId deedNetworkId(jobject_deed); + if (deedNetworkId == NetworkId::cms_invalid) + { + DEBUG_WARNING (true, ("enterClientStructurePlacementMode (): DB jobject_deed is not a valid object")); + return JNI_FALSE; + } + + //-- send the message to the client + client->send (EnterStructurePlacementModeMessage (deedNetworkId, sharedObjectTemplateName), true); + + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsTerrainNamespace::canPlaceStructure (JNIEnv* /*env*/, jobject /*self*/, jstring jstring_serverObjectTemplateName, jobject jobject_location, jint jint_rotation) +{ + //-- has the position to lot x, z + const TerrainObject* const terrainObject = TerrainObject::getConstInstance (); + if (!terrainObject) + { + DEBUG_WARNING (true, ("canPlaceStructure (): PB there is no terrain")); + return -9997.f; + } + + const LotManager* const lotManager = ServerWorld::getConstLotManager (); + if (!lotManager) + { + DEBUG_WARNING (true, ("canPlaceStructure (): PB there is no lot system")); + return -9997.f; + } + + //-- make sure we have a valid object template name + JavaStringParam javaStringParam_serverObjectTemplateName (jstring_serverObjectTemplateName); + std::string serverObjectTemplateName; + if (!JavaLibrary::convert (javaStringParam_serverObjectTemplateName, serverObjectTemplateName)) + { + DEBUG_WARNING (true, ("canPlaceStructure (): DB failed to convert parameter 3 (serverObjectTemplateName) to string")); + return -9998.f; + } + + //-- make sure the name is not empty + if (serverObjectTemplateName.empty ()) + { + DEBUG_WARNING (true, ("canPlaceStructure (): DB serverObjectTemplateName is empty")); + return -9998.f; + } + + //-- fetch the object template + const ObjectTemplate* objectTemplate = ObjectTemplateList::fetch (serverObjectTemplateName); + if (!objectTemplate) + { + DEBUG_WARNING (true, ("canPlaceStructure (): DB serverObjectTemplate [%s] does not exist", serverObjectTemplateName.c_str ())); + return -9998.f; + } + + //-- fetch the server object template + const ServerObjectTemplate* const serverObjectTemplate = dynamic_cast (objectTemplate); + if (!serverObjectTemplate) + { + objectTemplate->releaseReference (); + + DEBUG_WARNING (true, ("canPlaceStructure (): DB objectTemplate [%s] exists, but is not a valid server object template", serverObjectTemplateName.c_str ())); + return -9998.f; + } + + //-- fetch the shared object template name + const std::string sharedObjectTemplateName = serverObjectTemplate->getSharedTemplate (); + serverObjectTemplate->releaseReference (); + if (sharedObjectTemplateName.empty ()) + { + DEBUG_WARNING (true, ("canPlaceStructure (): DB sharedObjectTemplateName specified by serverObjectTemplate [%s] is empty", serverObjectTemplateName.c_str ())); + return -9998.f; + } + + //-- fetch the object template + objectTemplate = ObjectTemplateList::fetch (sharedObjectTemplateName); + if (!objectTemplate) + { + DEBUG_WARNING (true, ("canPlaceStructure (): DB sharedObjectTemplate [%s] does not exist", sharedObjectTemplateName.c_str ())); + return -9998.f; + } + + //-- fetch the shared object template + const SharedTangibleObjectTemplate* const tangibleObjectTemplate = dynamic_cast (objectTemplate); + if (!tangibleObjectTemplate) + { + objectTemplate->releaseReference (); + + DEBUG_WARNING (true, ("canPlaceStructure (): DB objectTemplate [%s] exists, but is not a valid shared tangible object template", sharedObjectTemplateName.c_str ())); + return -9998.f; + } + + //-- get the structure footprint + const StructureFootprint* const structureFootprint = tangibleObjectTemplate->getStructureFootprint (); + if (!structureFootprint) + { + DEBUG_WARNING (true, ("canPlaceStructure (): DB objectTemplate [%s] does not have a structure footprint", sharedObjectTemplateName.c_str ())); + return -9998.f; + } + + std::string sceneId; + Vector position_w; + if (!ScriptConversion::convertWorld (jobject_location, position_w, sceneId)) + { + DEBUG_WARNING (true, ("canPlaceStructure (): DB failed to convert parameter 2 (location) to sceneId and position_w")); + return -9998.f; + } + + if (jint_rotation < 0 || jint_rotation > 3) + { + DEBUG_WARNING (true, ("canPlaceStructure (): DB failed to convert parameter 3 (rotation) [%i] to valid rotation (0, 1, 2, or 3)", jint_rotation)); + return -9998.f; + } + + const int x = terrainObject->calculateChunkX (position_w); + const int z = terrainObject->calculateChunkZ (position_w); + const RotationType rotationType = static_cast (jint_rotation); + + float height_w = 0.f; + if (lotManager->canPlace (structureFootprint, x, z, rotationType, height_w)) + return height_w; + + return -9999.f; +} + +// ---------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsTerrainNamespace::createTemporaryStructure (JNIEnv* /*env*/, jobject /*self*/, jstring jstring_serverObjectTemplateName, jobject jobject_position, jint jint_rotation) +{ + UNREF (jstring_serverObjectTemplateName); + UNREF (jobject_position); + UNREF (jint_rotation); + + return 0; +} + +// ---------------------------------------------------------------------- + +jint JNICALL ScriptMethodsTerrainNamespace::getNumberOfLots (JNIEnv* /*env*/, jobject /*self*/, jstring jstring_serverObjectTemplateName) +{ + //-- make sure we have a valid object template name + JavaStringParam javaStringParam_serverObjectTemplateName (jstring_serverObjectTemplateName); + std::string serverObjectTemplateName; + if (!JavaLibrary::convert (javaStringParam_serverObjectTemplateName, serverObjectTemplateName)) + { + DEBUG_WARNING (true, ("getNumberOfLots (): DB failed to convert parameter 3 (serverObjectTemplateName) to string")); + return 0; + } + + //-- make sure the name is not empty + if (serverObjectTemplateName.empty ()) + { + DEBUG_WARNING (true, ("getNumberOfLots (): DB serverObjectTemplateName is empty")); + return 0; + } + + //-- fetch the object template + const ObjectTemplate* objectTemplate = ObjectTemplateList::fetch (serverObjectTemplateName); + if (!objectTemplate) + { + DEBUG_WARNING (true, ("getNumberOfLots (): DB serverObjectTemplate [%s] does not exist", serverObjectTemplateName.c_str ())); + return 0; + } + + //-- fetch the server object template + const ServerObjectTemplate* const serverObjectTemplate = dynamic_cast (objectTemplate); + if (!serverObjectTemplate) + { + objectTemplate->releaseReference (); + + DEBUG_WARNING (true, ("getNumberOfLots (): DB objectTemplate [%s] exists, but is not a valid server object template", serverObjectTemplateName.c_str ())); + return 0; + } + + //-- fetch the shared object template name + const std::string sharedObjectTemplateName = serverObjectTemplate->getSharedTemplate (); + serverObjectTemplate->releaseReference (); + if (sharedObjectTemplateName.empty ()) + { + DEBUG_WARNING (true, ("getNumberOfLots (): DB sharedObjectTemplateName specified by serverObjectTemplate [%s] is empty", serverObjectTemplateName.c_str ())); + return 0; + } + + //-- fetch the object template + objectTemplate = ObjectTemplateList::fetch (sharedObjectTemplateName); + if (!objectTemplate) + { + DEBUG_WARNING (true, ("getNumberOfLots (): DB sharedObjectTemplate [%s] does not exist", sharedObjectTemplateName.c_str ())); + return 0; + } + + //-- fetch the shared object template + const SharedTangibleObjectTemplate* const tangibleObjectTemplate = dynamic_cast (objectTemplate); + if (!tangibleObjectTemplate) + { + objectTemplate->releaseReference (); + + DEBUG_WARNING (true, ("getNumberOfLots (): DB objectTemplate [%s] exists, but is not a valid shared tangible object template", sharedObjectTemplateName.c_str ())); + return 0; + } + + //-- get the structure footprint + const StructureFootprint* const structureFootprint = tangibleObjectTemplate->getStructureFootprint (); + if (!structureFootprint) + { + DEBUG_WARNING (true, ("getNumberOfLots (): DB objectTemplate [%s] does not have a structure footprint", sharedObjectTemplateName.c_str ())); + return 0; + } + + //-- return the number of lots + return structureFootprint->getNumberOfStructureReservations (); +} + +// ---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsTerrainNamespace::getLocalTime (JNIEnv* /*env*/, jobject /*self*/) +{ + const TerrainObject* const terrainObject = TerrainObject::getInstance (); + if (!terrainObject) + { + DEBUG_WARNING (true, ("getLocalTime (): PB no terrain")); + return 0.f; + } + + const float environmentCycleTime = terrainObject->getEnvironmentCycleTime (); + if (environmentCycleTime == 0.f) + { + DEBUG_WARNING (true, ("getLocalTime (): DB terrain exists, but environmentCycleTime is 0")); + return 0.f; + } + + return fmodf (static_cast (ServerClock::getInstance ().getGameTimeSeconds ()), environmentCycleTime) / environmentCycleTime; +} + +// ---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsTerrainNamespace::getLocalDayLength (JNIEnv* /*env*/, jobject /*self*/) +{ + const TerrainObject* const terrainObject = TerrainObject::getInstance (); + if (!terrainObject) + { + DEBUG_WARNING (true, ("getLocalDayLength (): PB no terrain")); + return 0.f; + } + + return 0.5f; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsTerrainNamespace::setWeatherData (JNIEnv* env, jobject self, jint index, + jfloat windVelocityX, jfloat windVelocityZ) +{ + UNREF(env); + UNREF(self); + + PlanetObject * planet = ServerUniverse::getInstance().getCurrentPlanet(); + if (planet != NULL) + { + planet->setWeather(index, windVelocityX, 0.f, windVelocityZ); + return JNI_TRUE; + } + else + { + WARNING(true, ("JavaLibrary::setWeatherData could not get current planet")); + return JNI_FALSE; + } +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsTerrainNamespace::isBelowWater (JNIEnv* /*env*/, jobject /*self*/, jobject location) +{ + if (location == NULL) + { + DEBUG_WARNING(true, ("[designer bug] isBelowWater script hook was passed a NULL location reference")); + return JNI_FALSE; + } + + Vector loc; + std::string sceneId; + NetworkId cell; + if(!ScriptConversion::convert(location, loc, sceneId, cell)) + { + DEBUG_WARNING(true, ("isBelowWater could not convert given location to internal Vector/scene/cell format, was a location object passed in?")); + return JNI_FALSE; + } + + const CellProperty* worldCell = CellProperty::getWorldCellProperty(); + if(!worldCell) + { + DEBUG_WARNING(true, ("isBelowWater got a NULL worldCell back from CellProperty::getWorldCellProperty()")); + return JNI_FALSE; + } + const NetworkId& worldCellId = worldCell->getOwner().getNetworkId(); + if(worldCellId != cell) + { + DEBUG_WARNING(true, ("isBelowWater was given a location not in the world cell")); + return JNI_FALSE; + } + + const TerrainObject* const terrainObject = TerrainObject::getInstance (); + if (!terrainObject) + { + DEBUG_WARNING(true, ("isBelowWater can't get the TerrainObject")); + return JNI_FALSE; + } + + return terrainObject->isBelowWater(loc); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsTerrainNamespace::isWaterInRect (JNIEnv* /*env*/, jobject /*self*/, jfloat x0, jfloat y0, jfloat x1, jfloat y1) +{ + const TerrainObject* const terrainObject = TerrainObject::getInstance (); + if (!terrainObject) + { + DEBUG_WARNING(true, ("isWaterInRect can't get the TerrainObject")); + return JNI_FALSE; + } + + Rectangle2d rect(x0,y0,x1,y1); + return terrainObject->getWater(rect); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsTerrainNamespace::createClientPath (JNIEnv * /*env*/, jobject /*self*/, jlong jobject_player, jobject jobject_start, jobject jobject_end) +{ + //-- get the player object + CreatureObject * player = 0; + if (!JavaLibrary::getObject (jobject_player, player)) + { + DEBUG_WARNING (true, ("createClientPath (): DB could not find player object")); + return JNI_FALSE; + } + + //-- get the client associated with the player + Client * const client = player->getClient (); + if (!client) + { + DEBUG_WARNING (true, ("createClientPath (): PB could get the player's client object")); + return JNI_FALSE; + } + + //-- get the start position + std::string sceneId; + Vector startPosition_w; + if (!ScriptConversion::convertWorld (jobject_start, startPosition_w, sceneId)) + { + DEBUG_WARNING (true, ("createClientPath (): DB failed to convert parameter 2 (start) to sceneId and position_w")); + return JNI_FALSE; + } + + //-- get the end position + Vector endPosition_w; + if (!ScriptConversion::convertWorld (jobject_end, endPosition_w, sceneId)) + { + DEBUG_WARNING (true, ("createClientPath (): DB failed to convert parameter 2 (end) to sceneId and position_w")); + return JNI_FALSE; + } + + //-- send path to client + std::vector pointList; + + ServerPathBuilder builder; + + AiLocation const startAiLocation(CellProperty::getWorldCellProperty(), startPosition_w); + AiLocation const endAiLocation(CellProperty::getWorldCellProperty(), endPosition_w); + + builder.buildWorldPath(startAiLocation, endAiLocation); + + if (builder.buildFailed()) + { + DEBUG_WARNING(true, ("createClientPath (): Path search failed to find a path to the goal\n")); + return JNI_FALSE; + } + + AiPath * const path = builder.getPath(); + + for (AiPath::iterator it = path->begin(); it != path->end(); ++it) + { + AiLocation const &loc = (*it); + Vector position_w(loc.getPosition_w()); + position_w.y = 0.0f; // let the client resolve the height. + pointList.push_back(position_w); + } + + //-- send the message to the client + CreateClientPathMessage const createClientPathMessage(pointList); + client->send(createClientPathMessage, true); + + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsTerrainNamespace::destroyClientPath (JNIEnv * /*env*/, jobject /*self*/, jlong jobject_player) +{ + //-- get the player object + ServerObject * player = 0; + if (!JavaLibrary::getObject (jobject_player, player)) + { + DEBUG_WARNING (true, ("destroyClientPath (): DB could not find player object")); + return JNI_FALSE; + } + + //-- get the client associated with the player + Client * const client = player->getClient (); + if (!client) + { + DEBUG_WARNING (true, ("destroyClientPath (): PB could get the player's client object")); + return JNI_FALSE; + } + + //-- send the message to the client + client->send(DestroyClientPathMessage(), true); + + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsTerrainNamespace::getWaterTableHeight (JNIEnv* /*env*/, jobject /*self*/, jobject location) +{ + float zero = 0.0f; + + if (location == NULL) + { + DEBUG_WARNING(true, ("[designer bug] getWaterTableHeight script hook was passed a NULL location reference")); + return zero; + } + + Vector loc; + std::string sceneId; + NetworkId cell; + if(!ScriptConversion::convert(location, loc, sceneId, cell)) + { + DEBUG_WARNING(true, ("getWaterTableHeight could not convert given location to internal Vector/scene/cell format, was a location object passed in?")); + return zero; + } + + const CellProperty* worldCell = CellProperty::getWorldCellProperty(); + if(!worldCell) + { + DEBUG_WARNING(true, ("getWaterTableHeight got a NULL worldCell back from CellProperty::getWorldCellProperty()")); + return zero; + } + const NetworkId& worldCellId = worldCell->getOwner().getNetworkId(); + if(worldCellId != cell) + { + DEBUG_WARNING(true, ("getWaterTableHeight was given a location not in the world cell")); + return zero; + } + + const TerrainObject* const terrainObject = TerrainObject::getInstance (); + if (!terrainObject) + { + DEBUG_WARNING(true, ("getWaterTableHeight can't get the TerrainObject")); + return zero; + } + + float height = 0.0f; + bool success = terrainObject->getWaterHeight(loc, height); + if(!success) + { + DEBUG_WARNING(true, ("getWaterTableHeight failed TerrainObject call")); + return zero; + } + + return height; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsTerrainNamespace::requestLocation (JNIEnv * /*env*/, jobject /*self*/, jlong jobject_scriptObject, jstring jstring_locationId, jobject jobject_searchLocation, jfloat searchRadius, jfloat locationReservationRadius, jboolean checkWater, jboolean checkSlope) +{ + //-- make sure we have a valid trigger object + ServerObject * scriptObject = 0; + if (!JavaLibrary::getObject (jobject_scriptObject, scriptObject)) + { + DEBUG_WARNING (true, ("requestLocation (): DB could not find scriptObject")); + return JNI_FALSE; + } + + //-- extract the locationId + JavaStringParam javaStringParam_locationId (jstring_locationId); + std::string locationId; + if (!JavaLibrary::convert (javaStringParam_locationId, locationId)) + { + DEBUG_WARNING (true, ("requestLocation (): DB failed to convert parameter 2 (locationId) to string")); + return JNI_FALSE; + } + + //-- extract the scene and the position + std::string sceneId; + Vector position_w; + if (!ScriptConversion::convertWorld (jobject_searchLocation, position_w, sceneId)) + { + DEBUG_WARNING (true, ("requestLocation (): DB failed to convert parameter 3 (searchLocation) to scene and position")); + return JNI_FALSE; + } + + //-- make sure the location is on the same planet + if (sceneId != ServerWorld::getSceneId ()) + { + DEBUG_WARNING (true, ("requestLocation (): DB parameter 3 (searchLocation) specified a different planet (%s != %s)", sceneId.c_str(), ServerWorld::getSceneId ().c_str())); + return JNI_FALSE; + } + + LocationRequest const locationRequest ( + GameServer::getInstance ().getProcessId (), + scriptObject->getNetworkId (), + locationId, + position_w.x, + position_w.z, + searchRadius, + locationReservationRadius, + checkWater, + checkSlope); + + GameServer::getInstance ().sendToPlanetServer (locationRequest); + + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsTerrainNamespace::isOnAFloor (JNIEnv * env, jobject self, jlong scriptObject) +{ + //-- make sure we have a valid object + ServerObject * theObject = NULL; + if (!JavaLibrary::getObject (scriptObject, theObject)) + { + DEBUG_WARNING (true, ("isOnAFloor (): could not find scriptObject")); + return JNI_FALSE; + } + + CollisionProperty * const objectCollisionProp = theObject->getCollisionProperty(); + if(!objectCollisionProp) + { + DEBUG_WARNING (true, ("isOnAFloor (): could not get the collision property for scriptObject")); + return JNI_FALSE; + } + + if(objectCollisionProp->getStandingOn() != NULL) + return JNI_TRUE; + else + return JNI_FALSE; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsTerrainNamespace::isRelativePointOnSameFloorAsObject(JNIEnv * env, jobject self, jlong scriptObject, jfloat relativeXLocation, jfloat relativeZLocation) +{ + if(!isOnAFloor(env, self, scriptObject)) + return JNI_FALSE; + + //-- make sure we have a valid object + ServerObject * theObject = NULL; + if (!JavaLibrary::getObject (scriptObject, theObject)) + { + DEBUG_WARNING (true, ("isRelativePointOnSameFloorAsObject (): could not find scriptObject")); + return JNI_FALSE; + } + + Floor const * floorObjectStandingOn = CollisionWorld::getFloorStandingOn (*theObject); + + Vector testPosition_w = theObject->getPosition_w(); + testPosition_w.x += relativeXLocation; + testPosition_w.z += relativeZLocation; + + Vector capsuleTopLocation = testPosition_w; + testPosition_w.y += 5000.0f; + Vector capsuleBottomLocation = testPosition_w; + testPosition_w.y -= 5000.0f; + + SpatialDatabase const * database = CollisionWorld::getDatabase(); + if(!database) + { + DEBUG_WARNING (true, ("isRelativePointOnSameFloorAsObject (): could not get the database")); + return JNI_FALSE; + } + + FloorVec results; + Capsule cap(capsuleBottomLocation, capsuleTopLocation, 1.0f); + database->queryFloors(cap, &results); + for(uint i = 0; i < results.size(); ++i) + { + Floor const * const queriedFloor = results.at(i); + if(queriedFloor == floorObjectStandingOn) + return JNI_TRUE; + } + + return JNI_FALSE; +} + +// ---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsTerrainNamespace::getFloorHeightAtRelativePointOnSameFloorAsObject(JNIEnv * env, jobject self, jlong scriptObject, jfloat relativeXLocation, jfloat relativeZLocation) +{ + float result = 0.0f; + + if(!isOnAFloor(env, self, scriptObject)) + return JNI_FALSE; + + //-- make sure we have a valid object + ServerObject * theObject = NULL; + if (!JavaLibrary::getObject (scriptObject, theObject)) + { + DEBUG_WARNING (true, ("getFloorHeightAtRelativePointOnSameFloorAsObject (): could not find scriptObject")); + return result; + } + + Floor const * floorObjectStandingOn = CollisionWorld::getFloorStandingOn (*theObject); + + Vector testPosition_p = theObject->getPosition_p(); + testPosition_p.x += relativeXLocation; + testPosition_p.z += relativeZLocation; + + Vector capsuleTopLocation = testPosition_p; + testPosition_p.y += 5000.0f; + Vector capsuleBottomLocation = testPosition_p; + testPosition_p.y -= 5000.0f; + + SpatialDatabase const * database = CollisionWorld::getDatabase(); + if(!database) + { + DEBUG_WARNING (true, ("getFloorHeightAtRelativePointOnSameFloorAsObject (): could not get the database")); + return result; + } + + FloorVec results; + Capsule cap(capsuleBottomLocation, capsuleTopLocation, 1.0f); + database->queryFloors(cap, &results); + for(uint i = 0; i < results.size(); ++i) + { + Floor const * const queriedFloor = results.at(i); + if(queriedFloor == floorObjectStandingOn) + { + FloorLocator tempLoc; + if(queriedFloor->dropTest(testPosition_p,tempLoc)) + { + result = tempLoc.getPosition_w().y; + break; + } + } + } + + return result; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsTerrainNamespace::createClientPathAdvanced(JNIEnv * /*env*/, jobject /*self*/, jlong jPlayer, jobject jStartLocation, jobject jEndLocation, jstring /*jAppearanceTableEntry*/) +{ + //-- get the player object + CreatureObject * player = 0; + if (!JavaLibrary::getObject(jPlayer, player)) + { + DEBUG_WARNING(true,("createClientPathAdvanced(): Could not find player object")); + return JNI_FALSE; + } + + //-- get the client associated with the player + Client * const client = player->getClient(); + if (!client) + { + DEBUG_WARNING(true,("createClientPathAdvanced(): Could get the player's client object")); + return JNI_FALSE; + } + + //-- get the start location + Location startLocation; + if (!ScriptConversion::convert(LocalRefParam(jStartLocation), startLocation)) + { + DEBUG_WARNING(true,("createClientPathAdvanced(): Failed to convert jStartLocation to startLocation")); + return JNI_FALSE; + } + + //-- get the end location + Location endLocation; + if (!ScriptConversion::convert(LocalRefParam(jEndLocation), endLocation)) + { + DEBUG_WARNING(true,("createClientPathAdvanced(): Failed to convert jEndLocation to endLocation")); + return JNI_FALSE; + } + + //-- send path to client + std::vector pointList; + + ServerPathBuilder builder; + + AiLocation const startAiLocation(startLocation.getCell(), startLocation.getCoordinates()); + AiLocation const endAiLocation(endLocation.getCell(), endLocation.getCoordinates()); + + builder.buildPathImmediate(startAiLocation, endAiLocation); + + if (builder.buildFailed()) + { + DEBUG_WARNING(true,("createClientPathAdvanced(): Path search failed to find a path to the goal\n")); + return JNI_FALSE; + } + + // add the start position. + { + Vector startPosition_w(startAiLocation.getPosition_w()); + if (!startAiLocation.getCell() || startAiLocation.getCell()->isWorldCell()) + { + startPosition_w.y = 0.0f; + } + pointList.push_back(startPosition_w); + } + + AiPath * const path = builder.getPath(); + if (path) + { + // erase the first and last nodes because they are wrong. + if (!path->empty()) + { + path->pop_front(); + } + + if (!path->empty()) + { + path->pop_back(); + } + + // iterate over the remaining nodes. + for(AiPath::iterator it = path->begin(); it != path->end(); ++it) + { + AiLocation const &loc =(*it); + + Vector position_w(loc.getPosition_w()); + + CellProperty const * const cell = loc.getCell(); + if (!cell || cell->isWorldCell()) + { + position_w.y = 0.0f; // let the client resolve the height. + } + + pointList.push_back(position_w); + } + } + + // add the end position. + { + Vector endPosition_w(endAiLocation.getPosition_w()); + if (!endAiLocation.getCell() || endAiLocation.getCell()->isWorldCell()) + { + endPosition_w.y = 0.0f; + } + pointList.push_back(endAiLocation.getPosition_w()); + } + + //-- send the message to the client + CreateClientPathMessage const createClientPathMessage(pointList); + client->send(createClientPathMessage, true); + + return JNI_TRUE; +} + +//----------------------------------------------------------------------- + +/** + * Sets a creature's cover value based on it's current chunk. + * + * @param env Java environment + * @param self class calling this function + * @param target creature we want to set + * + * @return JNI_TRUE on success, JNI_FALSE on error + */ +jboolean JNICALL ScriptMethodsTerrainNamespace::setCreatureCoverDefault(JNIEnv *env, jobject self, jlong target) +{ + CreatureObject * creature = NULL; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + jint cover = 0; + if (creature->getParentCell() == CellProperty::getWorldCellProperty()) + { + const Vector pos = creature->getPosition_w(); + cover = static_cast(getCoverAtLocation(env, self, pos.x, pos.z) * 100); + } + creature->setCover(cover); + + return JNI_TRUE; +} // JavaLibrary::setCreatureCoverDefault + +//----------------------------------------------------------------------- + +/** + * Sets a creature's cover value. + * + * @param env Java environment + * @param self class calling this function + * @param target creature we want to set + * @param cover the cover value + * + * @return JNI_TRUE on success, JNI_FALSE on error + */ +jboolean JNICALL ScriptMethodsTerrainNamespace::setCreatureCover(JNIEnv *env, jobject self, jlong target, jint cover) +{ + UNREF(self); + + CreatureObject * creature = NULL; + if (!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + creature->setCover(cover); + return JNI_TRUE; +} // JavaLibrary::setCreatureCover + +//----------------------------------------------------------------------- + +void JNICALL ScriptMethodsTerrainNamespace::setCreatureCoverVisibility(JNIEnv * env, jobject self, jlong target, jboolean isVisible) +{ + CreatureObject * creature = NULL; + if(!JavaLibrary::getObject(target, creature)) + return; + + creature->setCoverVisibility(isVisible); +} + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsTerrainNamespace::getCreatureCoverVisibility(JNIEnv * env, jobject self, jlong target) +{ + CreatureObject * creature = NULL; + if(!JavaLibrary::getObject(target, creature)) + return JNI_FALSE; + + if(creature->getCoverVisibility()) + return JNI_TRUE; + + return JNI_FALSE; +} + +//----------------------------------------------------------------------- + +/** +* Returns the id of the object that target is standing on +* +* @param env Java environment +* @param self class calling this function +* @param target object we want to check +* +* @return id of the object that target is standing on or invalid if target is not standing on an object (e.g. standing on terrain) +*/ +jlong JNICALL ScriptMethodsTerrainNamespace::getStandingOn(JNIEnv *env, jobject self, jlong target) +{ + UNREF(self); + + CreatureObject const * creature = 0; + + if (JavaLibrary::getObject(target, creature)) + { + CollisionProperty const * const collision = creature->getCollisionProperty(); + + if (collision) + { + Object const * const object = collision->getStandingOn(); + + if (object) + return object->getNetworkId().getValue(); + } + } + + return NetworkId::cms_invalid.getValue(); +} + +// ====================================================================== diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsTriggerVolume.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsTriggerVolume.cpp new file mode 100644 index 00000000..f5bea66f --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsTriggerVolume.cpp @@ -0,0 +1,413 @@ +// ScriptMethodsTriggerVolume.cpp +// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved. +// Author: Justin Randall + +//----------------------------------------------------------------------- + +#include "serverScript/FirstServerScript.h" +#include "JavaLibrary.h" +#include "serverGame/AiLogManager.h" +#include "serverGame/ConfigServerGame.h" +#include "serverGame/ContainerInterface.h" +#include "serverGame/CreatureObject.h" +#include "serverGame/TriggerVolume.h" +#include "sharedLog/Log.h" +#include "sharedTerrain/TerrainObject.h" +#include "UnicodeUtils.h" + +using namespace JNIWrappersNamespace; + + +// ====================================================================== +// ScriptMethodsTriggerVolumeNamespace +// ====================================================================== + +namespace ScriptMethodsTriggerVolumeNamespace +{ + bool install(); + + void JNICALL createTriggerVolume(JNIEnv * env, jobject script, jlong target, jstring triggerVolumeName, jfloat radius, jboolean isPromiscuous); + jlongArray JNICALL getTriggerVolumeContents(JNIEnv * env, jobject script, jlong target, jstring triggerVolumeName); + jboolean JNICALL isInTriggerVolume(JNIEnv * env, jobject script, jlong owner, jstring triggerVolumeName, jlong target); + jfloat JNICALL getTriggerVolumeRadius(JNIEnv * env, jobject script, jlong targetObject, jstring triggerVolumeName); + jboolean JNICALL hasTriggerVolume(JNIEnv * env, jobject script, jlong target, jstring triggerVolumeName); + jboolean JNICALL isTriggerVolumePromiscuous(JNIEnv * env, jobject script, jlong me, jstring triggerVolumeName); + void JNICALL listenToTriggerEventsFrom(JNIEnv * env, jobject script, jlong self, jstring volumeName, jlong who); + void JNICALL removeTriggerVolume(JNIEnv * env, jobject script, jlong target, jstring triggerVolumeName); + void JNICALL setTriggerVolumeIsPromiscuous(JNIEnv * env, jobject script, jlong self, jstring triggerVolumeName, jboolean isPromiscuous); + void JNICALL stopListeningToTriggerEventsFrom(JNIEnv * env, jobject script, jlong self, jstring volumeName, jlong who); + jboolean JNICALL expelFromTriggerVolume(JNIEnv * env, jobject script, jlong self, jstring triggerVolumeName, jlong targetObject); + jboolean JNICALL confineToTriggerVolume(JNIEnv * env, jobject script, jlong self, jstring triggerVolumeName, jlong targetObject); +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsTriggerVolumeNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsTriggerVolumeNamespace::c)} + JF("__createTriggerVolume", "(JLjava/lang/String;FZ)V", createTriggerVolume), + JF("_getTriggerVolumeContents", "(JLjava/lang/String;)[J", getTriggerVolumeContents), + JF("_isInTriggerVolume", "(JLjava/lang/String;J)Z", isInTriggerVolume), + JF("_getTriggerVolumeRadius", "(JLjava/lang/String;)F", getTriggerVolumeRadius), + JF("_hasTriggerVolume", "(JLjava/lang/String;)Z", hasTriggerVolume), + JF("_isTriggerVolumePromiscuous", "(JLjava/lang/String;)Z", isTriggerVolumePromiscuous), + JF("__addTriggerVolumeEventSource", "(JLjava/lang/String;J)V", listenToTriggerEventsFrom), + JF("__removeTriggerVolume", "(JLjava/lang/String;)V", removeTriggerVolume), + JF("__setTriggerVolumePromiscuous", "(JLjava/lang/String;Z)V", setTriggerVolumeIsPromiscuous), + JF("__removeTriggerVolumeEventSource", "(JLjava/lang/String;J)V", stopListeningToTriggerEventsFrom), + JF("_expelFromTriggerVolume", "(JLjava/lang/String;J)Z", expelFromTriggerVolume), + JF("_confineToTriggerVolume", "(JLjava/lang/String;J)Z", confineToTriggerVolume), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +//----------------------------------------------------------------------- + +void JNICALL ScriptMethodsTriggerVolumeNamespace::createTriggerVolume(JNIEnv * env, jobject script, jlong targetObject, jstring triggerVolumeName, jfloat radius, jboolean isPromiscuous) +{ + JavaStringParam localTriggerVolumeName(triggerVolumeName); + + if (script == 0 || env == 0) + return; + + ServerObject * target = 0; + if (!JavaLibrary::getObject(targetObject, target)) + return; + + std::string name; + if(!JavaLibrary::convert(localTriggerVolumeName, name)) + return; + + float r = radius; + target->createTriggerVolume(r, name, isPromiscuous); + + LOGC(AiLogManager::isLogging(target->getNetworkId()), "debug_ai", ("ScriptMethodsTriggerVolume::createTriggerVolume() object(%s:%s) volumeName(%s) radius(%.2f) promiscuous(%s)", target->getNetworkId().getValueString().c_str(), Unicode::wideToNarrow(target->getEncodedObjectName()).c_str(), name.c_str(), radius, isPromiscuous ? "yes" : "no")); +} + +//----------------------------------------------------------------------- + +jlongArray JNICALL ScriptMethodsTriggerVolumeNamespace::getTriggerVolumeContents(JNIEnv * env, jobject script, jlong targetObject, jstring triggerVolumeName) +{ + JavaStringParam localTriggerVolumeName(triggerVolumeName); + + if(script == 0 || env == 0) + return 0; + + ServerObject * target = 0; + if (!JavaLibrary::getObject(targetObject, target)) + return 0; + + std::string name; + if(!JavaLibrary::convert(localTriggerVolumeName, name)) + return 0; + + const TriggerVolume * t = target->getTriggerVolume(name); + if(t == 0) + return 0; + + int count = t->getContents().size(); + LocalLongArrayRefPtr items = createNewLongArray(count); + TriggerVolume::ContentsSet::const_iterator begin = t->getContents().begin(); + TriggerVolume::ContentsSet::const_iterator end = t->getContents().end(); + TriggerVolume::ContentsSet::const_iterator i; + int index = 0; + jlong jlongTmp; + for (i = begin; i != end; ++i) + { + jlongTmp = ((*i)->getNetworkId()).getValue(); + setLongArrayRegion(*items, index, 1, &jlongTmp); + index++; + } + + return items->getReturnValue(); +} + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsTriggerVolumeNamespace::isInTriggerVolume(JNIEnv * /*env*/, jobject /*script*/, jlong owner, jstring triggerVolumeName, jlong target) +{ + ServerObject * ownerServerObject = 0; + if (!JavaLibrary::getObject(owner, ownerServerObject)) + return JNI_FALSE; + + ServerObject * targetServerObject = 0; + if (!JavaLibrary::getObject(target, targetServerObject)) + return JNI_FALSE; + + JavaStringParam localTriggerVolumeName(triggerVolumeName); + std::string name; + if(!JavaLibrary::convert(localTriggerVolumeName, name)) + return JNI_FALSE; + + TriggerVolume const * const triggerVolume = ownerServerObject->getTriggerVolume(name); + if(triggerVolume == 0) + return JNI_FALSE; + + TriggerVolume::ContentsSet const & contents = triggerVolume->getContents(); + + return (contents.find(targetServerObject) != contents.end()); +} + +//----------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsTriggerVolumeNamespace::getTriggerVolumeRadius(JNIEnv * env, jobject script, jlong targetObject, jstring triggerVolumeName) +{ + JavaStringParam localTriggerVolumeName(triggerVolumeName); + + if(script == 0 || env == 0) + return 0; + + ServerObject * target = 0; + if (!JavaLibrary::getObject(targetObject, target)) + return 0; + + std::string name; + if(!JavaLibrary::convert(localTriggerVolumeName, name)) + return 0; + + const TriggerVolume * t = target->getTriggerVolume(name); + if(t == 0) + return 0; + + return t->getRadius(); +} + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsTriggerVolumeNamespace::hasTriggerVolume(JNIEnv * env, jobject script, jlong targetObject, jstring triggerVolumeName) +{ + JavaStringParam localTriggerVolumeName(triggerVolumeName); + + if(script == 0 || env == 0) + return JNI_FALSE; + + ServerObject * target = 0; + if (!JavaLibrary::getObject(targetObject, target)) + return JNI_FALSE; + + std::string name; + if(!JavaLibrary::convert(localTriggerVolumeName, name)) + return JNI_FALSE; + + const TriggerVolume * t = target->getTriggerVolume(name); + + if(t == 0) + return JNI_FALSE; + + return JNI_TRUE; +} + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsTriggerVolumeNamespace::isTriggerVolumePromiscuous(JNIEnv * env, jobject script, jlong me, jstring triggerVolumeName) +{ + JavaStringParam localTriggerVolumeName(triggerVolumeName); + + jboolean result = JNI_FALSE; + if(script == 0 || env == 0) + return result; + + ServerObject * target = 0; + if (!JavaLibrary::getObject(me, target)) + return result; + + std::string name; + if(!JavaLibrary::convert(localTriggerVolumeName, name)) + return result; + + const TriggerVolume * t = target->getTriggerVolume(name); + + if(t == 0) + return result; + + result = t->getPromiscuous(); + + return result; +} + +//----------------------------------------------------------------------- + +void JNICALL ScriptMethodsTriggerVolumeNamespace::listenToTriggerEventsFrom(JNIEnv * env, jobject script, jlong self, jstring volumeName, jlong who) +{ + JavaStringParam localVolumeName(volumeName); + + ServerObject * me = 0; + if (!JavaLibrary::getObject(self, me)) + return; + + ServerObject * target = 0; + if(!JavaLibrary::getObject(who, target)) + return; + + std::string name; + if(!JavaLibrary::convert(localVolumeName, name)) + return; + + TriggerVolume * t = me->getTriggerVolume(name); + if(! t) + { + JAVA_THROW_SCRIPT_EXCEPTION(true, ("ScriptMethodsTriggerVolume::listenToTriggerEventsFrom() Unable to find triggerVolume(%s) for %s listening for %s", name.c_str(), me->getNetworkId().getValueString().c_str(), target->getNetworkId().getValueString().c_str())); + return; + } + + t->addEventSource(target->getNetworkId()); + + LOGC(AiLogManager::isLogging(me->getNetworkId()), "debug_ai", ("ScriptMethodsTriggerVolume::listenToTriggerEventsFrom() object(%s:%s) from(%s:%s) volumeName(%s)", me->getNetworkId().getValueString().c_str(), Unicode::wideToNarrow(me->getEncodedObjectName()).c_str(), target->getNetworkId().getValueString().c_str(), Unicode::wideToNarrow(target->getEncodedObjectName()).c_str(), name.c_str())); +} + +//----------------------------------------------------------------------- + +void JNICALL ScriptMethodsTriggerVolumeNamespace::removeTriggerVolume(JNIEnv * env, jobject script, jlong targetObject, jstring triggerVolumeName) +{ + JavaStringParam localTriggerVolumeName(triggerVolumeName); + + if(script == 0 || env == 0) + return; + + ServerObject * target = 0; + if (!JavaLibrary::getObject(targetObject, target)) + return; + + std::string name; + if(!JavaLibrary::convert(localTriggerVolumeName, name)) + return; + + LOGC(AiLogManager::isLogging(target->getNetworkId()), "debug_ai", ("ScriptMethodsTriggerVolume::removeTriggerVolume() object(%s:%s) volumeName(%s)", target->getNetworkId().getValueString().c_str(), Unicode::wideToNarrow(target->getEncodedObjectName()).c_str(), name.c_str())); + + target->removeTriggerVolume(name); +} + +//----------------------------------------------------------------------- + +void JNICALL ScriptMethodsTriggerVolumeNamespace::setTriggerVolumeIsPromiscuous(JNIEnv * env, jobject script, jlong self, jstring volumeName, jboolean isPromiscuous) +{ + JavaStringParam localVolumeName(volumeName); + + ServerObject * me = 0; + if (!JavaLibrary::getObject(self, me)) + return; + + std::string name; + if(!JavaLibrary::convert(localVolumeName, name)) + return; + + TriggerVolume * t = me->getTriggerVolume(name); + if(! t) + return; + + t->setPromiscuous(isPromiscuous); +} + +//----------------------------------------------------------------------- + +void JNICALL ScriptMethodsTriggerVolumeNamespace::stopListeningToTriggerEventsFrom(JNIEnv * env, jobject script, jlong self, jstring volumeName, jlong who) +{ + JavaStringParam localVolumeName(volumeName); + + ServerObject * me = 0; + if (!JavaLibrary::getObject(self, me)) + return; + + ServerObject * target = 0; + if(!JavaLibrary::getObject(who, target)) + return; + + std::string name; + if(!JavaLibrary::convert(localVolumeName, name)) + return; + + TriggerVolume * t = me->getTriggerVolume(name); + if(! t) + return; + + t->removeEventSource(target->getNetworkId()); + + LOGC(ConfigServerGame::isAiLoggingEnabled(), "debug_ai", ("ScriptMethodsTriggerVolume::stopListeningToTriggerEventsFrom() object(%s:%s) from(%s:%s) volumeName(%s)", me->getNetworkId().getValueString().c_str(), Unicode::wideToNarrow(me->getEncodedObjectName()).c_str(), target->getNetworkId().getValueString().c_str(), Unicode::wideToNarrow(target->getEncodedObjectName()).c_str(), name.c_str())); +} + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsTriggerVolumeNamespace::expelFromTriggerVolume(JNIEnv * env, jobject script, jlong self, jstring triggerVolumeName, jlong targetObject) +{ + const float EXPEL_DISTANCE = 10.0f; + + JavaStringParam localTriggerVolumeName(triggerVolumeName); + + if (script == 0 || env == 0) + return JNI_FALSE; + + ServerObject * me = 0; + if (!JavaLibrary::getObject(self, me)) + return JNI_FALSE; + + ServerObject * target = 0; + if (!JavaLibrary::getObject(targetObject, target)) + return JNI_FALSE; + + std::string name; + if (!JavaLibrary::convert(localTriggerVolumeName, name)) + return JNI_FALSE; + + const TriggerVolume * triggerVolume = me->getTriggerVolume(name); + if (triggerVolume == 0) + return JNI_FALSE; + + Vector const &trigLoc = triggerVolume->getOwner().getPosition_w(); + Vector newLoc(target->getPosition_w()); + newLoc -= trigLoc; + newLoc.normalize(); + newLoc *= triggerVolume->getRadius()+EXPEL_DISTANCE; + newLoc += trigLoc; + IGNORE_RETURN(TerrainObject::getInstance()->getHeightForceChunkCreation(newLoc, newLoc.y)); + + + target->teleportObject(newLoc, NetworkId::cms_invalid, "", Vector::zero, ""); + return JNI_TRUE; +} + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsTriggerVolumeNamespace::confineToTriggerVolume(JNIEnv * env, jobject script, jlong self, jstring triggerVolumeName, jlong targetObject) +{ + const float CONFINE_DISTANCE = 10.0f; + + JavaStringParam localTriggerVolumeName(triggerVolumeName); + + if (script == 0 || env == 0) + return JNI_FALSE; + + ServerObject * me = 0; + if (!JavaLibrary::getObject(self, me)) + return JNI_FALSE; + + ServerObject * target = 0; + if (!JavaLibrary::getObject(targetObject, target)) + return JNI_FALSE; + + std::string name; + if (!JavaLibrary::convert(localTriggerVolumeName, name)) + return JNI_FALSE; + + const TriggerVolume * triggerVolume = me->getTriggerVolume(name); + if (triggerVolume == 0) + return JNI_FALSE; + + Vector const &trigLoc = triggerVolume->getOwner().getPosition_w(); + Vector newLoc(target->getPosition_w()); + newLoc -= trigLoc; + newLoc.normalize(); + newLoc *= triggerVolume->getRadius()-CONFINE_DISTANCE; + newLoc += trigLoc; + + target->teleportObject(newLoc, NetworkId::cms_invalid, "", Vector::zero, ""); + return JNI_TRUE; +} + +//----------------------------------------------------------------------- + diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsVeteran.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsVeteran.cpp new file mode 100644 index 00000000..d751acee --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsVeteran.cpp @@ -0,0 +1,369 @@ +// ====================================================================== +// +// ScriptMethodsVeteran.cpp +// copyright (c) 2004 Sony Online Entertainment +// +// ====================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "serverGame/CreatureObject.h" +#include "serverGame/GameServer.h" +#include "serverGame/VeteranRewardManager.h" +#include "serverNetworkMessages/AccountFeatureIdRequest.h" +#include "sharedGame/PlatformFeatureBits.h" +#include "sharedObject/NetworkIdManager.h" +#include "UnicodeUtils.h" + +// ====================================================================== + +using namespace JNIWrappersNamespace; + + +// ====================================================================== +// ScriptMethodsVeteranNamespace +// ====================================================================== + +namespace ScriptMethodsVeteranNamespace +{ + bool install(); + + void JNICALL veteranWriteAccountDataToObjvars(JNIEnv * env, jobject self, jlong player); + jobjectArray JNICALL veteranGetTriggeredEvents(JNIEnv *env, jobject self, jlong player); + jboolean JNICALL veteranAccountFeatureIdRequest(JNIEnv * env, jobject self, jlong player); + jobjectArray JNICALL veteranGetRewardChoicesDescriptions(JNIEnv *env, jobject self, jlong player, jstring event); + jobjectArray JNICALL veteranGetRewardChoicesTags(JNIEnv *env, jobject self, jlong player, jstring event); + jboolean JNICALL veteranClaimReward(JNIEnv *env, jobject self, jlong player, jstring event, jstring rewardTag); + jstring JNICALL veteranGetEventAnnouncement(JNIEnv *env, jobject self, jstring event); + jstring JNICALL veteranGetEventDescription(JNIEnv *env, jobject self, jstring event); + jstring JNICALL veteranGetEventUrl(JNIEnv *env, jobject self, jstring event); + jboolean JNICALL veteranIsEventAccountUnique(JNIEnv *env, jobject self, jstring event); + jboolean JNICALL veteranIsItemAccountUnique(JNIEnv *env, jobject self, jstring item); + jboolean JNICALL veteranIsItemAccountUniqueFeatureId(JNIEnv *env, jobject self, jstring item); + jboolean JNICALL veteranCanTradeInReward(JNIEnv *env, jobject self, jlong player, jlong item); + void JNICALL veteranTradeInReward(JNIEnv *env, jobject self, jlong player, jlong item); + void JNICALL adjustSwgTcgAccountFeatureId(JNIEnv *env, jobject self, jlong player, jlong item, jint featureId, jint adjustment); +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsVeteranNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsVeteranNamespace::c)} + JF("_veteranWriteAccountDataToObjvars", "(J)V", veteranWriteAccountDataToObjvars), + JF("_veteranGetTriggeredEvents", "(J)[Ljava/lang/String;", veteranGetTriggeredEvents), + JF("_veteranAccountFeatureIdRequest", "(J)Z", veteranAccountFeatureIdRequest), + JF("_veteranGetRewardChoicesDescriptions", "(JLjava/lang/String;)[Ljava/lang/String;", veteranGetRewardChoicesDescriptions), + JF("_veteranGetRewardChoicesTags", "(JLjava/lang/String;)[Ljava/lang/String;", veteranGetRewardChoicesTags), + JF("_veteranClaimReward", "(JLjava/lang/String;Ljava/lang/String;)Z", veteranClaimReward), + JF("veteranGetEventAnnouncement", "(Ljava/lang/String;)Ljava/lang/String;", veteranGetEventAnnouncement), + JF("veteranGetEventDescription", "(Ljava/lang/String;)Ljava/lang/String;", veteranGetEventDescription), + JF("veteranGetEventUrl", "(Ljava/lang/String;)Ljava/lang/String;", veteranGetEventUrl), + JF("veteranIsEventAccountUnique", "(Ljava/lang/String;)Z", veteranIsEventAccountUnique), + JF("veteranIsItemAccountUnique", "(Ljava/lang/String;)Z", veteranIsItemAccountUnique), + JF("veteranIsItemAccountUniqueFeatureId", "(Ljava/lang/String;)Z", veteranIsItemAccountUniqueFeatureId), + JF("_veteranCanTradeInReward", "(JJ)Z", veteranCanTradeInReward), + JF("_veteranTradeInReward", "(JJ)V", veteranTradeInReward), + JF("_adjustSwgTcgAccountFeatureId", "(JJII)V", adjustSwgTcgAccountFeatureId), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +// ====================================================================== + +jobjectArray JNICALL ScriptMethodsVeteranNamespace::veteranGetTriggeredEvents(JNIEnv * /*env*/, jobject /*self*/, jlong player) +{ + ServerObject const * const so = safe_cast(NetworkIdManager::getObjectById(NetworkId(player))); + CreatureObject const * const playerCreature = so ? so->asCreatureObject() : NULL; + + if (playerCreature) + { + std::vector eventsIds; + VeteranRewardManager::getTriggeredEventsIds(*playerCreature, eventsIds); + + if (eventsIds.empty()) + return NULL; + + int i = 0; + LocalObjectArrayRefPtr valueArray = createNewObjectArray(eventsIds.size(), JavaLibrary::getClsString()); + for (std::vector::const_iterator iter = eventsIds.begin(); iter != eventsIds.end(); ++iter) + { + JavaString jval(*iter); + setObjectArrayElement(*valueArray, i++, jval); + } + + return valueArray->getReturnValue(); + } + + return NULL; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsVeteranNamespace::veteranAccountFeatureIdRequest(JNIEnv * /*env*/, jobject /*self*/, jlong player) +{ + ServerObject * const so = safe_cast(NetworkIdManager::getObjectById(NetworkId(player))); + CreatureObject * const playerCreature = so ? so->asCreatureObject() : NULL; + + if (playerCreature) + { + Client * const client = playerCreature->getClient(); + if (client && !client->isUsingAdminLogin()) + { + AccountFeatureIdRequest const req(playerCreature->getNetworkId(), GameServer::getInstance().getProcessId(), playerCreature->getNetworkId(), static_cast(client->getStationId()), PlatformGameCode::SWG, AccountFeatureIdRequest::RR_ReloadRewardCheck); + client->sendToConnectionServer(req); + return JNI_TRUE; + } + } + + return JNI_FALSE; +} + +// ---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsVeteranNamespace::veteranGetRewardChoicesDescriptions(JNIEnv * /*env*/, jobject /*self*/, jlong player, jstring event) +{ + ServerObject const * const so = safe_cast(NetworkIdManager::getObjectById(NetworkId(player))); + CreatureObject const * const playerCreature = so ? so->asCreatureObject() : NULL; + + if (playerCreature) + { + std::string eventString; + JavaStringParam temp(event); + if (JavaLibrary::convert(temp,eventString)) + { + std::vector value; + + VeteranRewardManager::getRewardChoicesDescriptions(*playerCreature, eventString, value); + LocalObjectArrayRefPtr valueArray = createNewObjectArray(static_cast(value.size()), JavaLibrary::getClsString()); + for (size_t i = 0; i < value.size(); ++i) + { + JavaString jval(value[i]); + setObjectArrayElement(*valueArray, static_cast(i), jval); + } + return valueArray->getReturnValue(); + } + } + + return NULL; +} + +// ---------------------------------------------------------------------- + +jobjectArray JNICALL ScriptMethodsVeteranNamespace::veteranGetRewardChoicesTags(JNIEnv * /*env*/, jobject /*self*/, jlong player, jstring event) +{ + ServerObject const * const so = safe_cast(NetworkIdManager::getObjectById(NetworkId(player))); + CreatureObject const * const playerCreature = so ? so->asCreatureObject() : NULL; + + if (playerCreature) + { + std::string eventString; + JavaStringParam temp(event); + if (JavaLibrary::convert(temp,eventString)) + { + std::vector value; + + VeteranRewardManager::getRewardChoicesTags(*playerCreature, eventString, value); + LocalObjectArrayRefPtr valueArray = createNewObjectArray(static_cast(value.size()), JavaLibrary::getClsString()); + for (size_t i = 0; i < value.size(); ++i) + { + JavaString jval(value[i]); + setObjectArrayElement(*valueArray, static_cast(i), jval); + } + return valueArray->getReturnValue(); + } + } + + return NULL; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsVeteranNamespace::veteranClaimReward(JNIEnv * /*env*/, jobject /*self*/, jlong player, jstring event, jstring rewardTag) +{ + ServerObject const * const so = safe_cast(NetworkIdManager::getObjectById(NetworkId(player))); + CreatureObject const * const playerCreature = so ? so->asCreatureObject() : NULL; + + if (playerCreature) + { + std::string eventString; + JavaStringParam temp(event); + if (JavaLibrary::convert(temp,eventString)) + { + std::string rewardTagString; + JavaStringParam temp2(rewardTag); + if (JavaLibrary::convert(temp2,rewardTagString)) + { + std::string debugMessage; + if (VeteranRewardManager::claimRewards(*playerCreature, eventString, rewardTagString, &debugMessage)) + return true; + else + DEBUG_REPORT_LOG(true,("Claim failed: %s",debugMessage.c_str())); + } + } + } + return false; +} + +// ---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsVeteranNamespace::veteranGetEventAnnouncement(JNIEnv * /*env*/, jobject /*self*/, jstring event) +{ + std::string eventString; + JavaStringParam temp(event); + if (JavaLibrary::convert(temp,eventString)) + { + StringId const * const eventStringId = VeteranRewardManager::getEventAnnouncement(eventString); + if (eventStringId) + { + JavaString eventAnnouncement(Unicode::narrowToWide(std::string("@") + eventStringId->getCanonicalRepresentation())); + return eventAnnouncement.getReturnValue(); + } + } + return NULL; +} + +// ---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsVeteranNamespace::veteranGetEventDescription(JNIEnv * /*env*/, jobject /*self*/, jstring event) +{ + std::string eventString; + JavaStringParam temp(event); + if (JavaLibrary::convert(temp,eventString)) + { + StringId const * const eventStringId = VeteranRewardManager::getEventDescription(eventString); + if (eventStringId) + { + JavaString eventDescription(Unicode::narrowToWide(std::string("@") + eventStringId->getCanonicalRepresentation())); + return eventDescription.getReturnValue(); + } + } + return NULL; +} + +// ---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsVeteranNamespace::veteranGetEventUrl(JNIEnv * /*env*/, jobject /*self*/, jstring event) +{ + std::string eventString; + JavaStringParam temp(event); + if (JavaLibrary::convert(temp,eventString)) + { + std::string const * const eventUrl = VeteranRewardManager::getEventUrl(eventString); + if (eventUrl) + { + JavaString temp2(*eventUrl); + return temp2.getReturnValue(); + } + } + return NULL; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsVeteranNamespace::veteranIsEventAccountUnique(JNIEnv * /*env*/, jobject /*self*/, jstring event) +{ + std::string eventString; + JavaStringParam temp(event); + if (JavaLibrary::convert(temp,eventString)) + { + return VeteranRewardManager::isEventAccountUnique(eventString); + } + else + return false; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsVeteranNamespace::veteranIsItemAccountUnique(JNIEnv * /*env*/, jobject /*self*/, jstring item) +{ + std::string itemString; + JavaStringParam temp(item); + if (JavaLibrary::convert(temp,itemString)) + { + return VeteranRewardManager::isItemAccountUnique(itemString); + } + else + return false; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsVeteranNamespace::veteranIsItemAccountUniqueFeatureId(JNIEnv * /*env*/, jobject /*self*/, jstring item) +{ + std::string itemString; + JavaStringParam temp(item); + if (JavaLibrary::convert(temp,itemString)) + { + return VeteranRewardManager::isItemAccountUniqueFeatureId(itemString); + } + else + return false; +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsVeteranNamespace::veteranWriteAccountDataToObjvars(JNIEnv * /*env*/, jobject /*self*/, jlong player) +{ + ServerObject * const so = safe_cast(NetworkIdManager::getObjectById(NetworkId(player))); + CreatureObject * const playerCreature = so ? so->asCreatureObject() : NULL; + + if (playerCreature) + VeteranRewardManager::writeAccountDataToObjvars(*playerCreature); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsVeteranNamespace::veteranCanTradeInReward(JNIEnv *env, jobject self, jlong player, jlong item) +{ + CreatureObject const * playerCreature = NULL; + if (!JavaLibrary::getObject(player, playerCreature) || !playerCreature) + return JNI_FALSE; + + ServerObject * itemObject = NULL; + if (!JavaLibrary::getObject(item, itemObject) || !itemObject) + return JNI_FALSE; + + // just validate the trade in + return VeteranRewardManager::tradeInReward(*playerCreature, *itemObject, true); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsVeteranNamespace::veteranTradeInReward(JNIEnv *env, jobject self, jlong player, jlong item) +{ + CreatureObject const * playerCreature = NULL; + if (!JavaLibrary::getObject(player, playerCreature) || !playerCreature) + return; + + ServerObject * itemObject = NULL; + if (!JavaLibrary::getObject(item, itemObject) || !itemObject) + return; + + // validate and perform the trade in + VeteranRewardManager::tradeInReward(*playerCreature, *itemObject, false); +} + +// ---------------------------------------------------------------------- + +void JNICALL ScriptMethodsVeteranNamespace::adjustSwgTcgAccountFeatureId(JNIEnv *env, jobject self, jlong player, jlong item, jint featureId, jint adjustment) +{ + CreatureObject const * playerCreature = NULL; + if (!JavaLibrary::getObject(player, playerCreature) || !playerCreature) + return; + + ServerObject * itemObject = NULL; + if (!JavaLibrary::getObject(item, itemObject) || !itemObject) + return; + + VeteranRewardManager::tcgRedemption(*playerCreature, *itemObject, featureId, adjustment); +} + +// ====================================================================== diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsWaypoint.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsWaypoint.cpp new file mode 100644 index 00000000..e9b3c546 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsWaypoint.cpp @@ -0,0 +1,441 @@ +// ScriptMethodsWaypoint.cpp +// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved. +// Author: Justin Randall + +//----------------------------------------------------------------------- + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "serverGame/CreatureObject.h" +#include "serverGame/MissionObject.h" +#include "serverGame/ObjectIdManager.h" +#include "serverGame/PlayerCreatureController.h" +#include "serverGame/PlayerObject.h" +#include "serverGame/Region.h" +#include "serverGame/RegionMaster.h" +#include "serverGame/ServerWorld.h" +#include "sharedFoundation/TemporaryCrcString.h" +#include "sharedGame/Waypoint.h" +#include "sharedMathArchive/VectorArchive.h" + + +namespace ScriptMethodsWaypointNamespace +{ + NetworkId getWaypointCellIdFromTemplateNameAndCelllName(jstring const & buildingTemplate, jstring const & cellName) + { + JavaStringParam jbt(buildingTemplate); + Unicode::String jbtn; + if (!JavaLibrary::convert(jbt, jbtn)) + { + DEBUG_WARNING(true, ("JavaLibrary::createWaypointInMissionInternal(): failed to buildingTemplate to a string")); + } + TemporaryCrcString crcBuilding(Unicode::wideToNarrow(jbtn).c_str(), true); + uint64 buildingValue(crcBuilding.getCrc()); + buildingValue <<= static_cast(32); + + JavaStringParam jcn(cellName); + Unicode::String jcnb; + if (!JavaLibrary::convert(jcn, jcnb)) + { + DEBUG_WARNING(true, ("JavaLibrary::createWaypointInMissionInternal(): failed to cellName to a string")); + } + TemporaryCrcString crcCell(Unicode::wideToNarrow(jcnb).c_str(), true); + uint64 cellValue(crcCell.getCrc()); + + // rls - since the cell id is not used in the waypoint system, + // we will combine the building and cell name crcs into the cell id. + NetworkId const staticCellId(static_cast(buildingValue | cellValue)); + + return staticCellId; + } + + bool install(); + + jlong JNICALL createWaypointInDatapadFromLocation (JNIEnv * env, jobject self, jlong target, jobject loc); + jlong JNICALL createWaypointInMissionObjectFromLocation (JNIEnv * env, jobject self, jlong target, jobject loc); + jlong JNICALL createWaypointInDatapadFromObject (JNIEnv * env, jobject self, jlong target, jlong obj); + jlong JNICALL createWaypointInMissionObjectFromObject (JNIEnv * env, jobject self, jlong target, jlong obj); + jlong JNICALL createWaypointInDatapadWithLimitsFromLocation (JNIEnv * env, jobject self, jlong target, jobject obj); + jlong JNICALL createWaypointInMissionInternal(JNIEnv * env, jobject self, jlong target, jobject jLoc, jstring buildingTemplate, jstring cellName); + jlong JNICALL createWaypointInDatapadInternal(JNIEnv * env, jobject self, jlong target, jobject jLoc, jstring buildingTemplate, jstring cellName); + void JNICALL destroyWaypointInDatapad (JNIEnv * env, jobject self, jlong waypoint, jlong player); + jboolean JNICALL getWaypointActive (JNIEnv * env, jobject self, jlong waypoint); + jobject JNICALL getWaypointLocation (JNIEnv * env, jobject self, jlong waypoint); + jstring JNICALL getWaypointName (JNIEnv *, jobject, jlong waypoint); + jlongArray JNICALL getWaypointsInDatapad (JNIEnv *, jobject, jlong player); + jobject JNICALL getWaypointRegion (JNIEnv * env, jobject self, jlong waypoint); + void JNICALL setWaypointActive (JNIEnv * env, jobject self, jlong waypoint, jboolean isActive); + void JNICALL setWaypointName (JNIEnv * env, jobject, jlong waypoint, jstring name); + void JNICALL setWaypointLocation (JNIEnv * env, jobject self, jlong waypoint, jobject loc); + jboolean JNICALL setWaypointColor (JNIEnv * env, jobject self, jlong waypoint, jstring jscolor); +} + +using namespace JNIWrappersNamespace; +using namespace ScriptMethodsWaypointNamespace; + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsWaypointNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsWaypointNamespace::c)} + JF("_createWaypointInDatapad", "(JLscript/location;)J", createWaypointInDatapadFromLocation), + JF("_createWaypointInMissionObject", "(JLscript/location;)J", createWaypointInMissionObjectFromLocation), + JF("_createWaypointInDatapad", "(JJ)J", createWaypointInDatapadFromObject), + JF("_createWaypointInMissionObject", "(JJ)J", createWaypointInMissionObjectFromObject), + JF("_createWaypointInDatapadWithLimits", "(JLscript/location;)J", createWaypointInDatapadWithLimitsFromLocation), + JF("_createWaypointInMissionInternal", "(JLscript/location;Ljava/lang/String;Ljava/lang/String;)J", createWaypointInMissionInternal), + JF("_createWaypointInDatapadInternal", "(JLscript/location;Ljava/lang/String;Ljava/lang/String;)J", createWaypointInDatapadInternal), + JF("_destroyWaypointInDatapad", "(JJ)V", destroyWaypointInDatapad), + JF("_getWaypointActive", "(J)Z", getWaypointActive), + JF("_getWaypointsInDatapad", "(J)[J", getWaypointsInDatapad), + JF("_getWaypointLocation", "(J)Lscript/location;", getWaypointLocation), + JF("_getWaypointName", "(J)Ljava/lang/String;", getWaypointName), + JF("_getWaypointRegion", "(J)Lscript/region;", getWaypointRegion), + JF("_setWaypointName", "(JLjava/lang/String;)V", setWaypointName), + JF("__setWaypointActiveNative", "(JZ)V", setWaypointActive), + JF("__setWaypointLocationNative", "(JLscript/location;)V", setWaypointLocation), + JF("__setWaypointColorNative", "(JLjava/lang/String;)Z", setWaypointColor), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +//----------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsWaypointNamespace::createWaypointInDatapadFromLocation(JNIEnv * env, jobject self, jlong target, jobject jLoc) +{ + CreatureObject *targetCreature = 0; + Location location; + if (env && target && jLoc && JavaLibrary::getObject(target, targetCreature) && ScriptConversion::convert(LocalRefParam(jLoc), location)) + { + PlayerObject * player = PlayerCreatureController::getPlayerObject(targetCreature); + if(player) + { + Waypoint waypoint(player->createWaypoint(location, true)); + return (waypoint.getNetworkId()).getValue(); + } + } + return 0; +} + +// ---------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsWaypointNamespace::createWaypointInDatapadWithLimitsFromLocation(JNIEnv * env, jobject self, jlong target, jobject jLoc) +{ + CreatureObject *targetCreature = 0; + Location location; + if (env && target && jLoc && JavaLibrary::getObject(target, targetCreature) && ScriptConversion::convert(LocalRefParam(jLoc), location)) + { + PlayerObject * player = PlayerCreatureController::getPlayerObject(targetCreature); + if(player) + { + Waypoint waypoint(player->createWaypoint(location, false)); + if (waypoint.isValid()) + return (waypoint.getNetworkId()).getValue(); + } + } + return 0; +} + +//----------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsWaypointNamespace::createWaypointInMissionObjectFromLocation(JNIEnv * env, jobject self, jlong target, jobject jLoc) +{ + MissionObject *targetMissionObj = 0; + Location location; + if (env && target && jLoc && JavaLibrary::getObject(target, targetMissionObj) && ScriptConversion::convert(LocalRefParam(jLoc), location)) + { + Waypoint w = targetMissionObj->getWaypoint(); + w.setLocation(location); + targetMissionObj->setWaypoint(w); + return (w.getNetworkId()).getValue(); + } + return 0; +} + +//----------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsWaypointNamespace::createWaypointInDatapadFromObject(JNIEnv * env, jobject self, jlong target, jlong obj) +{ + CreatureObject *targetCreature = 0; + ServerObject *s = 0; + if (env && target && obj && JavaLibrary::getObject(target, targetCreature) && JavaLibrary::getObject(obj, s)) + { + PlayerObject * player = PlayerCreatureController::getPlayerObject(targetCreature); + if(player) + { + Waypoint w(player->createWaypoint(Location(s->getPosition_w(), NetworkId::cms_invalid, Location::getCrcBySceneName(ServerWorld::getSceneId())), true)); + w.setName(s->getAssignedObjectName()); + return (w.getNetworkId()).getValue(); + } + } + return 0; +} + +//----------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsWaypointNamespace::createWaypointInMissionObjectFromObject(JNIEnv * env, jobject self, jlong target, jlong obj) +{ + MissionObject *targetMissionObj = 0; + ServerObject *s = 0; + if (env && target && obj && JavaLibrary::getObject(target, targetMissionObj) && JavaLibrary::getObject(obj, s)) + { + Waypoint w = targetMissionObj->getWaypoint(); + w.setLocation(Location(s->getPosition_w(), NetworkId::cms_invalid, Location::getCrcBySceneName(ServerWorld::getSceneId()))); + w.setName(s->getAssignedObjectName()); + targetMissionObj->setWaypoint(w); + return (w.getNetworkId()).getValue(); + } + return 0; +} + +//----------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsWaypointNamespace::createWaypointInMissionInternal(JNIEnv * env, jobject self, jlong target, jobject jLoc, jstring buildingTemplate, jstring cellName) +{ + MissionObject *targetMissionObj = 0; + Location location; + if (env && target && jLoc && JavaLibrary::getObject(target, targetMissionObj) && ScriptConversion::convert(LocalRefParam(jLoc), location)) + { + Waypoint w = targetMissionObj->getWaypoint(); + + NetworkId const & staticCellId = getWaypointCellIdFromTemplateNameAndCelllName(buildingTemplate, cellName); + location.setCell(staticCellId); + + w.setLocation(location); + targetMissionObj->setWaypoint(w); + return (w.getNetworkId()).getValue(); + } + return 0; +} + +//----------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsWaypointNamespace::createWaypointInDatapadInternal(JNIEnv * env, jobject self, jlong target, jobject jLoc, jstring buildingTemplate, jstring cellName) +{ + CreatureObject *targetCreature = 0; + Location location; + if (env && target && jLoc && JavaLibrary::getObject(target, targetCreature) && ScriptConversion::convert(LocalRefParam(jLoc), location)) + { + PlayerObject * player = PlayerCreatureController::getPlayerObject(targetCreature); + if(player) + { + NetworkId const & staticCellId = getWaypointCellIdFromTemplateNameAndCelllName(buildingTemplate, cellName); + location.setCell(staticCellId); + + Waypoint waypoint(player->createWaypoint(location, true)); + if (waypoint.isValid()) + return (waypoint.getNetworkId()).getValue(); + } + } + return 0; +} + +//----------------------------------------------------------------------- + +void JNICALL ScriptMethodsWaypointNamespace::destroyWaypointInDatapad(JNIEnv *, jobject, jlong waypoint, jlong player) +{ + CreatureObject * targetCreature = 0; + if (JavaLibrary::getObject(player, targetCreature)) + { + PlayerObject * p = PlayerCreatureController::getPlayerObject(targetCreature); + if(p) + { + if(waypoint) + { + NetworkId id(waypoint); + p->destroyWaypoint(id); + } + } + } +} + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsWaypointNamespace::getWaypointActive(JNIEnv * env, jobject self, jlong waypoint) +{ + jboolean result = JNI_FALSE; + if(env) + { + if(waypoint) + { + NetworkId id(waypoint); + const Waypoint w = Waypoint::getWaypointById(id); + if(w.isValid()) + { + result = w.isActive(); + } + } + } + + return result; +} + +//----------------------------------------------------------------------- + +jobject JNICALL ScriptMethodsWaypointNamespace::getWaypointLocation(JNIEnv * env, jobject self, jlong waypoint) +{ + if(waypoint) + { + NetworkId id(waypoint); + const Waypoint w = Waypoint::getWaypointById(id); + if(w.isValid()) + { + LocalRefPtr result; + if (ScriptConversion::convert(w.getLocation(), result)) + return result->getReturnValue(); + } + } + return 0; +} + +//----------------------------------------------------------------------- + +jobject JNICALL ScriptMethodsWaypointNamespace::getWaypointRegion(JNIEnv * env, jobject self, jlong waypoint) +{ + if (waypoint != 0) + { + NetworkId id(waypoint); + const Waypoint w = Waypoint::getWaypointById(id); + if(w.isValid()) + { + const Region * region = RegionMaster::getSmallestVisibleRegionAtPoint(w.getLocation().getSceneId(), w.getLocation().getCoordinates().x, w.getLocation().getCoordinates().z); + if (region != NULL) + { + LocalRefPtr result; + if (ScriptConversion::convert(*region, result)) + return result->getReturnValue(); + } + } + } + return 0; +} + +//----------------------------------------------------------------------- + +jlongArray JNICALL ScriptMethodsWaypointNamespace::getWaypointsInDatapad(JNIEnv *, jobject, jlong player) +{ + CreatureObject * creature = 0; + if (JavaLibrary::getObject(player, creature)) + { + PlayerObject * player = PlayerCreatureController::getPlayerObject(creature); + if (player) + { + std::vector waypoints; + player->getWaypointsInDatapad(waypoints); + LocalLongArrayRefPtr result; + if (ScriptConversion::convert(waypoints, result)) + return result->getReturnValue(); + } + } + return 0; +} + +//----------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsWaypointNamespace::getWaypointName(JNIEnv *, jobject, jlong waypoint) +{ + jstring result = 0; + if(waypoint) + { + NetworkId id(waypoint); + const Waypoint w = Waypoint::getWaypointById(id); + if(w.isValid()) + { + result = JavaString(w.getName()).getReturnValue(); + } + } + return result; +} + +//----------------------------------------------------------------------- + +void JNICALL ScriptMethodsWaypointNamespace::setWaypointActive(JNIEnv * env, jobject self, jlong waypoint, jboolean isActive) +{ + if(env) + { + if(waypoint) + { + NetworkId id(waypoint); + Waypoint w = Waypoint::getWaypointById(id); + if(w.isValid()) + { + w.setActive(isActive == JNI_TRUE); + } + } + } +} + +//----------------------------------------------------------------------- + +void JNICALL ScriptMethodsWaypointNamespace::setWaypointLocation(JNIEnv * env, jobject self, jlong waypoint, jobject jLoc) +{ + if(env) + { + if(waypoint) + { + if(jLoc) + { + NetworkId id(waypoint); + Waypoint w = Waypoint::getWaypointById(id); + if(w.isValid()) + { + Location location; + if(ScriptConversion::convert(LocalRefParam(jLoc), location)) + { + w.setLocation(location); + } + } + } + } + } +} + +//----------------------------------------------------------------------- + +void JNICALL ScriptMethodsWaypointNamespace::setWaypointName(JNIEnv *, jobject, jlong waypoint, jstring name) +{ + JavaStringParam localName(name); + + NetworkId id(waypoint); + Waypoint w = Waypoint::getWaypointById(id); + if(w.isValid()) + { + Unicode::String n; + if (!JavaLibrary::convert (localName, n)) + { + DEBUG_WARNING (true, ("setWaypointColor (): failed to convert name to string")); + } + else + { + w.setName(n); + } + } +} + +//----------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsWaypointNamespace::setWaypointColor(JNIEnv * env, jobject self, jlong waypoint, jstring jscolor) +{ + JavaStringParam localColor(jscolor); + + NetworkId id(waypoint); + Waypoint w = Waypoint::getWaypointById(id); + if(w.isValid()) + { + std::string color; + if (!JavaLibrary::convert (localColor, color)) + { + DEBUG_WARNING (true, ("setWaypointColor (): failed to convert color to string")); + return JNI_FALSE; + } + w.setColor(Waypoint::getColorIdByName(color)); + } + return JNI_TRUE; +} diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsWorldInfo.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsWorldInfo.cpp new file mode 100644 index 00000000..3cc7c024 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsWorldInfo.cpp @@ -0,0 +1,1786 @@ +//======================================================================== +// +// ScriptMethodsWorldInfo.cpp - implements script methods for querying +// world objects +// +// copyright 2001 Sony Online Entertainment +// +//======================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/JavaLibrary.h" + +#include "UnicodeUtils.h" +#include "boost/smart_ptr.hpp" // for boost::shared_ptr and friends +#include "serverGame/ContainerInterface.h" +#include "sharedDebug/Profiler.h" +#include "serverGame/CreatureObject.h" +#include "serverGame/PlanetObject.h" +#include "serverGame/ServerBuildoutManager.h" +#include "serverGame/ServerObject.h" +#include "serverGame/ServerUniverse.h" +#include "serverGame/ServerWorld.h" +#include "serverGame/TangibleObject.h" +#include "serverScript/GameScriptObject.h" +#include "serverScript/ScriptParameters.h" +#include "sharedCollision/CollisionWorld.h" +#include "sharedFoundation/DynamicVariableList.h" +#include "sharedMath/Sphere.h" +#include "sharedObject/NetworkIdManager.h" +#include "sharedRandom/Random.h" +#include "sharedTerrain/TerrainObject.h" + +#include + +using namespace JNIWrappersNamespace; + + +// ====================================================================== +// ScriptMethodsWorldInfoNamespace +// ====================================================================== + +namespace ScriptMethodsWorldInfoNamespace +{ + bool install(); + + jlongArray JNICALL getObjectsInRangeLocation(JNIEnv *env, jobject self, jobject location, jfloat range); + jlongArray JNICALL getObjectsInRangeObject(JNIEnv *env, jobject self, jlong object, jfloat range); + jlongArray JNICALL getCreaturesInRangeLocation(JNIEnv *env, jobject self, jobject location, jfloat range); + jlongArray JNICALL getCreaturesInRangeObject(JNIEnv *env, jobject self, jlong object, jfloat range); + jlongArray JNICALL getCreaturesOfNicheInRangeLocation(JNIEnv *env, jobject self, jobject location, jfloat range, jint niche, jint mask); + jlongArray JNICALL getCreaturesOfNicheInRangeObject(JNIEnv *env, jobject self, jlong object, jfloat range, jint niche, jint mask); + jlongArray JNICALL getCreaturesOfSpeciesInRangeLocation(JNIEnv *env, jobject self, jobject location, jfloat range, jint species); + jlongArray JNICALL getCreaturesOfSpeciesInRangeObject(JNIEnv *env, jobject self, jlong object, jfloat range, jint species); + jlongArray JNICALL getCreaturesOfRaceInRangeLocation(JNIEnv *env, jobject self, jobject location, jfloat range, jint species, jint race); + jlongArray JNICALL getCreaturesOfRaceInRangeObject(JNIEnv *env, jobject self, jlong object, jfloat range, jint species, jint race); + jlongArray JNICALL getNonCreaturesInRangeLocation(JNIEnv *env, jobject self, jobject location, jfloat range); + jlongArray JNICALL getNonCreaturesInRangeObject(JNIEnv *env, jobject self, jlong object, jfloat range); + jlongArray JNICALL getNPCsInRangeLocation(JNIEnv *env, jobject self, jobject location, jfloat range); + jlongArray JNICALL getNPCsInRangeObject(JNIEnv *env, jobject self, jlong object, jfloat range); + jlongArray JNICALL getPlayerCreaturesInRangeLocation(JNIEnv *env, jobject self, jobject location, jfloat range); + jlongArray JNICALL getPlayerCreaturesInRangeObject(JNIEnv *env, jobject self, jlong object, jfloat range); + jlongArray JNICALL getObjectsInCone(JNIEnv *env, jobject self, jlong coneCenterObjectId, jlong coneDirectionObjectId, jfloat range, jfloat angle); + jlongArray JNICALL getObjectsInConeLocation(JNIEnv *env, jobject self, jlong coneCenterObjectId, jobject coneDirectionLocation, jfloat range, jfloat angle); + jlongArray JNICALL getCreaturesInCone(JNIEnv *env, jobject self, jlong coneCenterObjectId, jlong coneDirectionObjectId, jfloat range, jfloat angle); + jlongArray JNICALL getCreaturesInConeLocation(JNIEnv *env, jobject self, jlong coneCenterObjectId, jobject coneDirectionLocation, jfloat range, jfloat angle); + jlongArray JNICALL getCreaturesOfNicheInCone(JNIEnv *env, jobject self, jlong coneCenterObjectId, jlong coneDirectionObjectId, jfloat range, jfloat angle, jint niche, jint mask); + jlongArray JNICALL getCreaturesOfSpeciesInCone(JNIEnv *env, jobject self, jlong coneCenterObjectId, jlong coneDirectionObjectId, jfloat range, jfloat angle, jint species); + jlongArray JNICALL getCreaturesOfRaceInCone(JNIEnv *env, jobject self, jlong coneCenterObjectId, jlong coneDirectionObjectId, jfloat range, jfloat angle, jint species, jint race); + jlongArray JNICALL getNonCreaturesInCone(JNIEnv *env, jobject self, jlong coneCenterObjectId, jlong coneDirectionObjectId, jfloat range, jfloat angle); + jlongArray JNICALL getNPCsInCone(JNIEnv *env, jobject self, jlong coneCenterObjectId, jlong coneDirectionObjectId, jfloat range, jfloat angle); + jlongArray JNICALL getPlayerCreaturesInCone(JNIEnv *env, jobject self, jlong coneCenterObjectId, jlong coneDirectionObjectId, jfloat range, jfloat angle); + jlongArray JNICALL getPerformanceListenersInRange(JNIEnv *env, jobject self, jlong performer, jfloat range); + jlongArray JNICALL getPerformanceWatchersInRange(JNIEnv *env, jobject self, jlong performer, jfloat range); + jboolean JNICALL isSpaceBattlefieldZone(JNIEnv *env, jobject self); + jboolean JNICALL isSpaceScene(JNIEnv *env, jobject self); + jboolean JNICALL isValidLocation(JNIEnv *env, jobject self, jobject objectPosition, jfloat objectRadius ); + jobject JNICALL getValidLocation(JNIEnv *env, jobject self, jobject corralCenter, jfloat corralRadius, jobject desiredPosition, jfloat objectRadius ); + jboolean JNICALL canSee(JNIEnv *env, jobject self, jlong source, jlong target); + jboolean JNICALL canSeeLocation(JNIEnv *env, jobject self, jlong source, jobject target); + jboolean JNICALL canManipulate(JNIEnv *env, jobject self, jlong player, jlong target, jboolean move, jboolean doPermission, float distance, jboolean sendMessage, jboolean skipNoTradeCheck); + jfloat JNICALL getElevation(JNIEnv *env, jobject self, jobject loc); + jfloat JNICALL getDirection(JNIEnv *env, jobject self, jobject loc1, jobject loc2); + jobject JNICALL findSpotNear(JNIEnv *env, jobject self, jlong target, jobject loc, jfloat radius); + jlongArray JNICALL getAllNpcs(JNIEnv *env, jobject self, jobject loc, jfloat radius); + jlongArray JNICALL getAllPlayers(JNIEnv *env, jobject self, jobject loc, jfloat radius); + jlong JNICALL getClosestMobile(JNIEnv *env, jobject self, jobject loc); + jlong JNICALL getClosestPlayer(JNIEnv *env, jobject self, jobject loc); + jlong JNICALL getFirstObjectWithScript(JNIEnv *env, jobject self, jobject loc, jfloat range, jstring script); + jlong JNICALL getFirstObjectWithObjVar(JNIEnv *env, jobject self, jobject loc, jfloat range, jstring objvar); + jlong JNICALL getFirstObjectWithTemplate(JNIEnv *env, jobject self, jobject loc, jfloat range, jstring templateName); + jlongArray JNICALL getAllObjectsWithScript(JNIEnv *env, jobject self, jobject loc, jfloat range, jstring script); + jlongArray JNICALL getAllObjectsWithObjVar(JNIEnv *env, jobject self, jobject loc, jfloat range, jstring objvar); + jlongArray JNICALL getAllObjectsWithTemplate(JNIEnv *env, jobject self, jobject loc, jfloat range, jstring templateName); + jobject JNICALL getLocationBetweenLocs(JNIEnv *env, jobject self, jobject target1, jobject target2); + jlong JNICALL getPlanetByName(JNIEnv * env, jobject self, jstring name); + jstring JNICALL getNameForPlanetObject(JNIEnv * env, jobject self, jlong planet); + jboolean JNICALL getCollidesWithObject(JNIEnv * env, jobject self, jobject loc, jfloat radius); + jboolean JNICALL startUniverseWideEvent(JNIEnv * env, jobject self, jstring eventName); + jboolean JNICALL stopUniverseWideEvent(JNIEnv * env, jobject self, jstring eventName); + jstring JNICALL getCurrentUniverseWideEvents(JNIEnv * env, jobject self); +} + + +//======================================================================== +// install +//======================================================================== + +bool ScriptMethodsWorldInfoNamespace::install() +{ +const JNINativeMethod NATIVES[] = { + #define JF(a,b,c) {a,b,(void*)(ScriptMethodsWorldInfoNamespace::c)} + JF("_getObjectsInRange", "(JF)[J", getObjectsInRangeObject), + JF("_getObjectsInRange", "(Lscript/location;F)[J", getObjectsInRangeLocation), + JF("_getCreaturesInRange", "(JF)[J", getCreaturesInRangeObject), + JF("_getCreaturesInRange", "(Lscript/location;F)[J", getCreaturesInRangeLocation), + JF("_getCreaturesOfNicheInRange", "(JFII)[J", getCreaturesOfNicheInRangeObject), + JF("_getCreaturesOfNicheInRange", "(Lscript/location;FII)[J", getCreaturesOfNicheInRangeLocation), + JF("_getCreaturesOfSpeciesInRange", "(JFI)[J", getCreaturesOfSpeciesInRangeObject), + JF("_getCreaturesOfSpeciesInRange", "(Lscript/location;FI)[J", getCreaturesOfSpeciesInRangeLocation), + JF("_getCreaturesOfRaceInRange", "(JFII)[J", getCreaturesOfRaceInRangeObject), + JF("_getCreaturesOfRaceInRange", "(Lscript/location;FII)[J", getCreaturesOfRaceInRangeLocation), + JF("_getNonCreaturesInRange", "(JF)[J", getNonCreaturesInRangeObject), + JF("_getNonCreaturesInRange", "(Lscript/location;F)[J", getNonCreaturesInRangeLocation), + JF("_getNPCsInRange", "(JF)[J", getNPCsInRangeObject), + JF("_getNPCsInRange", "(Lscript/location;F)[J", getNPCsInRangeLocation), + JF("_getPlayerCreaturesInRange", "(JF)[J", getPlayerCreaturesInRangeObject), + JF("_getPlayerCreaturesInRange", "(Lscript/location;F)[J", getPlayerCreaturesInRangeLocation), + JF("_getPerformanceListenersInRange", "(JF)[J", getPerformanceListenersInRange), + JF("_getPerformanceWatchersInRange", "(JF)[J", getPerformanceWatchersInRange), + JF("isSpaceBattlefieldZone", "()Z", isSpaceBattlefieldZone), + JF("isSpaceScene", "()Z", isSpaceScene), + JF("_getObjectsInCone", "(JJFF)[J", getObjectsInCone), + JF("_getObjectsInCone", "(JLscript/location;FF)[J", getObjectsInConeLocation), + JF("_getCreaturesInCone", "(JJFF)[J", getCreaturesInCone), + JF("_getCreaturesInCone", "(JLscript/location;FF)[J", getCreaturesInConeLocation), + JF("_getCreaturesOfNicheInCone", "(JJFFII)[J", getCreaturesOfNicheInCone), + JF("_getCreaturesOfSpeciesInCone", "(JJFFI)[J", getCreaturesOfSpeciesInCone), + JF("_getCreaturesOfRaceInCone", "(JJFFII)[J", getCreaturesOfRaceInCone), + JF("_getNonCreaturesInCone", "(JJFF)[J", getNonCreaturesInCone), + JF("_getNPCsInCone", "(JJFF)[J", getNPCsInCone), + JF("_getPlayerCreaturesInCone", "(JJFF)[J", getPlayerCreaturesInCone), + JF("isValidLocation","(Lscript/location;F)Z",isValidLocation), + JF("getValidLocation","(Lscript/location;FLscript/location;F)Lscript/location;",getValidLocation), + JF("_canSee", "(JJ)Z", canSee), + JF("_canSee", "(JLscript/location;)Z", canSeeLocation), + JF("_canManipulate", "(JJZZFZZ)Z", canManipulate), + JF("getElevation", "(Lscript/location;)F",getElevation), + JF("getDirection", "(Lscript/location;Lscript/location;)F",getDirection), + JF("_findSpotNear", "(JLscript/location;F)Lscript/location;",findSpotNear), + JF("_getAllNpcs", "(Lscript/location;F)[J",getAllNpcs), + JF("_getAllPlayers", "(Lscript/location;F)[J",getAllPlayers), + JF("_getClosestMobile", "(Lscript/location;)J",getClosestMobile), + JF("_getClosestPlayer", "(Lscript/location;)J",getClosestPlayer), + JF("_getFirstObjectWithScript", "(Lscript/location;FLjava/lang/String;)J",getFirstObjectWithScript), + JF("_getFirstObjectWithObjVar", "(Lscript/location;FLjava/lang/String;)J",getFirstObjectWithObjVar), + JF("_getFirstObjectWithTemplate", "(Lscript/location;FLjava/lang/String;)J",getFirstObjectWithTemplate), + JF("_getAllObjectsWithScript", "(Lscript/location;FLjava/lang/String;)[J",getAllObjectsWithScript), + JF("_getAllObjectsWithObjVar", "(Lscript/location;FLjava/lang/String;)[J",getAllObjectsWithObjVar), + JF("_getAllObjectsWithTemplate", "(Lscript/location;FLjava/lang/String;)[J",getAllObjectsWithTemplate), + JF("getLocationBetweenLocs", "(Lscript/location;Lscript/location;)Lscript/location;",getLocationBetweenLocs), + JF("_getPlanetByName", "(Ljava/lang/String;)J", getPlanetByName), + JF("_getNameForPlanetObject", "(J)Ljava/lang/String;", getNameForPlanetObject), + JF("_getCollidesWithObject", "(Lscript/location;F)Z", getCollidesWithObject), + JF("_startUniverseWideEvent", "(Ljava/lang/String;)Z", startUniverseWideEvent), + JF("_stopUniverseWideEvent", "(Ljava/lang/String;)Z", stopUniverseWideEvent), + JF("_getCurrentUniverseWideEvents", "()Ljava/lang/String;", getCurrentUniverseWideEvents), +}; + + return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); +} + + +//======================================================================== +// class JavaLibrary JNI world info callback methods +//======================================================================== + +/** + * + * + * @param env Java environment + * @param self class calling this function + * @param location location that is the center of the search area + * @param range radius of search area + * + * @return array of obj_ids of the objects in range, or null on error + */ +jlongArray JNICALL ScriptMethodsWorldInfoNamespace::getObjectsInRangeLocation(JNIEnv *env, jobject self, jobject location, jfloat range) +{ + PROFILER_AUTO_BLOCK_DEFINE("JNI::getObjectsInRange"); + UNREF(self); + + if (location == 0) + return 0; + + std::vector results; + Vector target; + if (!ScriptConversion::convertWorld(location, target)) + return 0; + ServerWorld::findObjectsInRange(target, range, results); + + LocalLongArrayRefPtr rv; + if (ScriptConversion::convert(results, rv)) + return rv->getReturnValue(); + return 0; +} + +/** + * + * + * @param env Java environment + * @param self class calling this function + * @param location object that is the center of the search area + * @param range radius of search area + * + * @return array of obj_ids of the objects in range, or null on error + */ +jlongArray JNICALL ScriptMethodsWorldInfoNamespace::getObjectsInRangeObject(JNIEnv *env, jobject self, jlong object, jfloat range) +{ + PROFILER_AUTO_BLOCK_DEFINE("JNI::getObjectsInRange"); + UNREF(self); + + if (object == 0) + return 0; + + std::vector results; + Vector target; + if (!ScriptConversion::convertWorld(object, target)) + return 0; + ServerWorld::findObjectsInRange(target, range, results); + + LocalLongArrayRefPtr rv; + if (ScriptConversion::convert(results, rv)) + return rv->getReturnValue(); + return 0; +} + +/** + * + * + * @param env Java environment + * @param self class calling this function + * @param location location that is the center of the search area + * @param range radius of search area + * + * @return array of obj_ids of the objects in range, or null on error + */ +jlongArray JNICALL ScriptMethodsWorldInfoNamespace::getCreaturesInRangeLocation(JNIEnv *env, jobject self, jobject location, jfloat range) +{ + UNREF(self); + + if (location == 0) + return 0; + + std::vector results; + Vector target; + if (!ScriptConversion::convertWorld(location, target)) + return 0; + ServerWorld::findCreaturesInRange(target, range, results); + + LocalLongArrayRefPtr rv; + if (ScriptConversion::convert(results, rv)) + return rv->getReturnValue(); + return 0; +} + +/** + * + * + * @param env Java environment + * @param self class calling this function + * @param location object that is the center of the search area + * @param range radius of search area + * + * @return array of obj_ids of the objects in range, or null on error + */ +jlongArray JNICALL ScriptMethodsWorldInfoNamespace::getCreaturesInRangeObject(JNIEnv *env, jobject self, jlong object, jfloat range) +{ + UNREF(self); + + if (object == 0) + return 0; + + std::vector results; + Vector target; + if (!ScriptConversion::convertWorld(object, target)) + return 0; + ServerWorld::findCreaturesInRange(target, range, results); + + LocalLongArrayRefPtr rv; + if (ScriptConversion::convert(results, rv)) + return rv->getReturnValue(); + return 0; +} + +/** + * + * + * @param env Java environment + * @param self class calling this function + * @param location location that is the center of the search area + * @param range radius of search area + * @param type + * @param mask + * + * @return array of obj_ids of the objects in range, or null on error + */ +jlongArray JNICALL ScriptMethodsWorldInfoNamespace::getCreaturesOfNicheInRangeLocation(JNIEnv *env, jobject self, jobject location, jfloat range, jint type, jint mask) +{ + UNREF(self); + + if (location == 0) + return 0; + + std::vector results; + Vector target; + if (!ScriptConversion::convertWorld(location, target)) + return 0; + ServerWorld::findCreaturesOfNicheInRange(target, range, type, mask, results); + + LocalLongArrayRefPtr rv; + if (ScriptConversion::convert(results, rv)) + return rv->getReturnValue(); + return 0; +} + +/** + * + * + * @param env Java environment + * @param self class calling this function + * @param location object that is the center of the search area + * @param range radius of search area + * @param type + * @param mask + * + * @return array of obj_ids of the objects in range, or null on error + */ +jlongArray JNICALL ScriptMethodsWorldInfoNamespace::getCreaturesOfNicheInRangeObject(JNIEnv *env, jobject self, jlong object, jfloat range, jint type, jint mask) +{ + UNREF(self); + + if (object == 0) + return 0; + + std::vector results; + Vector target; + if (!ScriptConversion::convertWorld(object, target)) + return 0; + ServerWorld::findCreaturesOfNicheInRange(target, range, type, mask, results); + + LocalLongArrayRefPtr rv; + if (ScriptConversion::convert(results, rv)) + return rv->getReturnValue(); + return 0; +} + +/** + * + * + * @param env Java environment + * @param self class calling this function + * @param location location that is the center of the search area + * @param range radius of search area + * @param species + * + * @return array of obj_ids of the objects in range, or null on error + */ +jlongArray JNICALL ScriptMethodsWorldInfoNamespace::getCreaturesOfSpeciesInRangeLocation(JNIEnv *env, jobject self, jobject location, jfloat range, jint species) +{ + UNREF(self); + + if (location == 0) + return 0; + + std::vector results; + Vector target; + if (!ScriptConversion::convertWorld(location, target)) + return 0; + ServerWorld::findCreaturesOfSpeciesInRange(target, range, species, results); + + LocalLongArrayRefPtr rv; + if (ScriptConversion::convert(results, rv)) + return rv->getReturnValue(); + return 0; +} + +/** + * + * + * @param env Java environment + * @param self class calling this function + * @param location object that is the center of the search area + * @param range radius of search area + * @param species + * + * @return array of obj_ids of the objects in range, or null on error + */ +jlongArray JNICALL ScriptMethodsWorldInfoNamespace::getCreaturesOfSpeciesInRangeObject(JNIEnv *env, jobject self, jlong object, jfloat range, jint species) +{ + UNREF(self); + + if (object == 0) + return 0; + + std::vector results; + Vector target; + if (!ScriptConversion::convertWorld(object, target)) + return 0; + ServerWorld::findCreaturesOfSpeciesInRange(target, range, species, results); + + LocalLongArrayRefPtr rv; + if (ScriptConversion::convert(results, rv)) + return rv->getReturnValue(); + return 0; +} + +/** + * + * + * @param env Java environment + * @param self class calling this function + * @param location location that is the center of the search area + * @param range radius of search area + * @param species + * @param race + * + * @return array of obj_ids of the objects in range, or null on error + */ +jlongArray JNICALL ScriptMethodsWorldInfoNamespace::getCreaturesOfRaceInRangeLocation(JNIEnv *env, jobject self, jobject location, jfloat range, jint species, jint race) +{ + UNREF(self); + + if (location == 0) + return 0; + + std::vector results; + Vector target; + if (!ScriptConversion::convertWorld(location, target)) + return 0; + ServerWorld::findCreaturesOfRaceInRange(target, range, species, race, results); + + LocalLongArrayRefPtr rv; + if (ScriptConversion::convert(results, rv)) + return rv->getReturnValue(); + return 0; +} + +/** + * + * + * @param env Java environment + * @param self class calling this function + * @param location object that is the center of the search area + * @param range radius of search area + * @param species + * @param race + * + * @return array of obj_ids of the objects in range, or null on error + */ +jlongArray JNICALL ScriptMethodsWorldInfoNamespace::getCreaturesOfRaceInRangeObject(JNIEnv *env, jobject self, jlong object, jfloat range, jint species, jint race) +{ + UNREF(self); + + if (object == 0) + return 0; + + std::vector results; + Vector target; + if (!ScriptConversion::convertWorld(object, target)) + return 0; + ServerWorld::findCreaturesOfRaceInRange(target, range, species, race, results); + + LocalLongArrayRefPtr rv; + if (ScriptConversion::convert(results, rv)) + return rv->getReturnValue(); + return 0; +} + +/** + * + * + * @param env Java environment + * @param self class calling this function + * @param location location that is the center of the search area + * @param range radius of search area + * + * @return array of obj_ids of the objects in range, or null on error + */ +jlongArray JNICALL ScriptMethodsWorldInfoNamespace::getNonCreaturesInRangeLocation(JNIEnv *env, jobject self, jobject location, jfloat range) +{ + UNREF(self); + + if (location == 0) + return 0; + + std::vector results; + Vector target; + if (!ScriptConversion::convertWorld(location, target)) + return 0; + ServerWorld::findNonCreaturesInRange(target, range, results); + + LocalLongArrayRefPtr rv; + if (ScriptConversion::convert(results, rv)) + return rv->getReturnValue(); + return 0; +} + +/** + * + * + * @param env Java environment + * @param self class calling this function + * @param location object that is the center of the search area + * @param range radius of search area + * + * @return array of obj_ids of the objects in range, or null on error + */ +jlongArray JNICALL ScriptMethodsWorldInfoNamespace::getNonCreaturesInRangeObject(JNIEnv *env, jobject self, jlong object, jfloat range) +{ + UNREF(self); + + if (object == 0) + return 0; + + std::vector results; + Vector target; + if (!ScriptConversion::convertWorld(object, target)) + return 0; + ServerWorld::findNonCreaturesInRange(target, range, results); + + LocalLongArrayRefPtr rv; + if (ScriptConversion::convert(results, rv)) + return rv->getReturnValue(); + return 0; +} + +/** + * + * + * @param env Java environment + * @param self class calling this function + * @param location location that is the center of the search area + * @param range radius of search area + * + * @return array of obj_ids of the objects in range, or null on error + */ +jlongArray JNICALL ScriptMethodsWorldInfoNamespace::getNPCsInRangeLocation(JNIEnv *env, jobject self, jobject location, jfloat range) +{ + UNREF(self); + + if (location == 0) + return 0; + + std::vector results; + Vector target; + if (!ScriptConversion::convertWorld(location, target)) + return 0; + ServerWorld::findNPCsInRange(target, range, results); + + LocalLongArrayRefPtr rv; + if (ScriptConversion::convert(results, rv)) + return rv->getReturnValue(); + return 0; +} + +/** + * + * + * @param env Java environment + * @param self class calling this function + * @param location object that is the center of the search area + * @param range radius of search area + * + * @return array of obj_ids of the objects in range, or null on error + */ +jlongArray JNICALL ScriptMethodsWorldInfoNamespace::getNPCsInRangeObject(JNIEnv *env, jobject self, jlong object, jfloat range) +{ + UNREF(self); + + if (object == 0) + return 0; + + std::vector results; + Vector target; + if (!ScriptConversion::convertWorld(object, target)) + return 0; + ServerWorld::findNPCsInRange(target, range, results); + + LocalLongArrayRefPtr rv; + if (ScriptConversion::convert(results, rv)) + return rv->getReturnValue(); + return 0; +} + +/** + * + * + * @param env Java environment + * @param self class calling this function + * @param location location that is the center of the search area + * @param range radius of search area + * + * @return array of obj_ids of the objects in range, or null on error + */ +jlongArray JNICALL ScriptMethodsWorldInfoNamespace::getPlayerCreaturesInRangeLocation(JNIEnv *env, jobject self, jobject location, jfloat range) +{ + UNREF(self); + + if (location == 0) + return 0; + + std::vector results; + Vector target; + if (!ScriptConversion::convertWorld(location, target)) + return 0; + ServerWorld::findPlayerCreaturesInRange(target, range, results); + + LocalLongArrayRefPtr rv; + if (ScriptConversion::convert(results, rv)) + return rv->getReturnValue(); + return 0; +} + +/** + * + * + * @param env Java environment + * @param self class calling this function + * @param location object that is the center of the search area + * @param range radius of search area + * + * @return array of obj_ids of the objects in range, or null on error + */ +jlongArray JNICALL ScriptMethodsWorldInfoNamespace::getPlayerCreaturesInRangeObject(JNIEnv *env, jobject self, jlong object, jfloat range) +{ + UNREF(self); + + if (object == 0) + return 0; + + std::vector results; + Vector target; + if (!ScriptConversion::convertWorld(object, target)) + return 0; + ServerWorld::findPlayerCreaturesInRange(target, range, results); + + LocalLongArrayRefPtr rv; + if (ScriptConversion::convert(results, rv)) + return rv->getReturnValue(); + return 0; +} + +// ---------------------------------------------------------------------- + +/** + * + * + * @param env Java environment + * @param self class calling this function + * + * @return array of obj_ids of the objects in range, or null on error + */ +jlongArray JNICALL ScriptMethodsWorldInfoNamespace::getObjectsInCone(JNIEnv *env, jobject self, jlong coneCenterObjectId, jlong coneDirectionObjectId, jfloat range, jfloat angle) +{ + UNREF(self); + + // Validate preconditions. + if (!coneCenterObjectId || !coneDirectionObjectId) + return 0; + + Object * coneCenterObject = 0; + Object * coneDirectionObject = 0; + + // Get the cone and base objects. + if (!JavaLibrary::getObject(coneCenterObjectId, coneCenterObject)) + return 0; + + if (!JavaLibrary::getObject(coneDirectionObjectId, coneDirectionObject)) + return 0; + + // Query for the results. + std::vector results; + + ServerWorld::findObjectsInCone(*coneCenterObject, *coneDirectionObject, range, convertDegreesToRadians(angle), + results); + + LocalLongArrayRefPtr rv; + if (ScriptConversion::convert(results, rv)) + return rv->getReturnValue(); + return 0; +} + +// ---------------------------------------------------------------------- + +/** + * Get an array of objects which are in a cone of a location. + * + * @param env Java environment + * @param self class calling this function + * + * @return array of obj_ids of the objects in range, or null on error + */ +jlongArray JNICALL ScriptMethodsWorldInfoNamespace::getObjectsInConeLocation(JNIEnv *env, jobject self, jlong coneCenterObjectId, jobject coneDirectionLocation, jfloat range, jfloat angle) +{ + UNREF(self); + + // Validate preconditions. + if (!coneCenterObjectId || !coneDirectionLocation) + return 0; + + Object * coneCenterObject = 0; + + // Get the cone and base objects. + if (!JavaLibrary::getObject(coneCenterObjectId, coneCenterObject)) + return 0; + + Location coneDirection; + if (!ScriptConversion::convert(LocalRefParam(coneDirectionLocation), coneDirection)) + return 0; + + // Query for the results. + std::vector results; + + ServerWorld::findObjectsInCone(*coneCenterObject, coneDirection, range, convertDegreesToRadians(angle), + results); + + LocalLongArrayRefPtr rv; + if (ScriptConversion::convert(results, rv)) + return rv->getReturnValue(); + return 0; +} + +// ---------------------------------------------------------------------- + +/** + * + * + * @param env Java environment + * @param self class calling this function + * + * @return array of obj_ids of the objects in range, or null on error + */ +jlongArray JNICALL ScriptMethodsWorldInfoNamespace::getCreaturesInCone(JNIEnv *env, jobject self, jlong coneCenterObjectId, jlong coneDirectionObjectId, jfloat range, jfloat angle) +{ + UNREF(self); + + // Validate preconditions. + if (!coneCenterObjectId || !coneDirectionObjectId) + return 0; + + Object * coneCenterObject = 0; + Object * coneDirectionObject = 0; + + // Get the cone and base objects. + if (!JavaLibrary::getObject(coneCenterObjectId, coneCenterObject)) + return 0; + + if (!JavaLibrary::getObject(coneDirectionObjectId, coneDirectionObject)) + return 0; + + // Query for the results. + std::vector results; + + ServerWorld::findCreaturesInCone(*coneCenterObject, *coneDirectionObject, range, + convertDegreesToRadians(angle), results); + + // Convert C-style results to Java. + LocalLongArrayRefPtr rv; + if (ScriptConversion::convert(results, rv)) + return rv->getReturnValue(); + return 0; +} + +// ---------------------------------------------------------------------- + +/** + * Get an array of creatures which are in a specified cone. + * + * @param env Java environment + * @param self class calling this function + * + * @return array of obj_ids of the objects in range, or null on error + */ +jlongArray JNICALL ScriptMethodsWorldInfoNamespace::getCreaturesInConeLocation(JNIEnv *env, jobject self, jlong coneCenterObjectId, jobject coneDirectionLocation, jfloat range, jfloat angle) +{ + UNREF(self); + + // Validate preconditions. + if (!coneCenterObjectId || !coneDirectionLocation) + return 0; + + Object * coneCenterObject = 0; + + // Get the cone and base objects. + if (!JavaLibrary::getObject(coneCenterObjectId, coneCenterObject)) + return 0; + + Location coneDirection; + if (!ScriptConversion::convert(LocalRefParam(coneDirectionLocation), coneDirection)) + return 0; + + // Query for the results. + std::vector results; + + ServerWorld::findCreaturesInCone(*coneCenterObject, coneDirection, range, + convertDegreesToRadians(angle), results); + + // Convert C-style results to Java. + LocalLongArrayRefPtr rv; + if (ScriptConversion::convert(results, rv)) + return rv->getReturnValue(); + return 0; +} + +// ---------------------------------------------------------------------- + +/** + * + * + * @param env Java environment + * @param self class calling this function + * + * @return array of obj_ids of the objects in range, or null on error + */ +jlongArray JNICALL ScriptMethodsWorldInfoNamespace::getCreaturesOfNicheInCone(JNIEnv *env, jobject self, jlong coneCenterObjectId, jlong coneDirectionObjectId, jfloat range, jfloat angle, jint niche, jint mask) +{ + UNREF(self); + + // Validate preconditions. + if (!coneCenterObjectId || !coneDirectionObjectId) + return 0; + + Object * coneCenterObject = 0; + Object * coneDirectionObject = 0; + + // Get the cone and base objects. + if (!JavaLibrary::getObject(coneCenterObjectId, coneCenterObject)) + return 0; + + if (!JavaLibrary::getObject(coneDirectionObjectId, coneDirectionObject)) + return 0; + + // Query for the results. + std::vector results; + + ServerWorld::findCreaturesOfNicheInCone(*coneCenterObject, *coneDirectionObject, + range, convertDegreesToRadians(angle), niche, mask, results); + + LocalLongArrayRefPtr rv; + if (ScriptConversion::convert(results, rv)) + return rv->getReturnValue(); + return 0; +} + +// ---------------------------------------------------------------------- + +/** + * + * + * @param env Java environment + * @param self class calling this function + * + * @return array of obj_ids of the objects in range, or null on error + */ +jlongArray JNICALL ScriptMethodsWorldInfoNamespace::getCreaturesOfSpeciesInCone(JNIEnv *env, jobject self, jlong coneCenterObjectId, jlong coneDirectionObjectId, jfloat range, jfloat angle, jint species) +{ + UNREF(self); + + // Validate preconditions. + if (!coneCenterObjectId || !coneDirectionObjectId) + return 0; + + Object * coneCenterObject = 0; + Object * coneDirectionObject = 0; + + // Get the cone and base objects. + if (!JavaLibrary::getObject(coneCenterObjectId, coneCenterObject)) + return 0; + + if (!JavaLibrary::getObject(coneDirectionObjectId, coneDirectionObject)) + return 0; + + // Query for the results. + std::vector results; + + ServerWorld::findCreaturesOfSpeciesInCone(*coneCenterObject, *coneDirectionObject, + range, convertDegreesToRadians(angle), species, results); + + LocalLongArrayRefPtr rv; + if (ScriptConversion::convert(results, rv)) + return rv->getReturnValue(); + return 0; +} + +// ---------------------------------------------------------------------- + +/** + * + * + * @param env Java environment + * @param self class calling this function + * + * @return array of obj_ids of the objects in range, or null on error + */ +jlongArray JNICALL ScriptMethodsWorldInfoNamespace::getCreaturesOfRaceInCone(JNIEnv *env, jobject self, jlong coneCenterObjectId, jlong coneDirectionObjectId, jfloat range, jfloat angle, jint species, jint race) +{ + UNREF(self); + + // Validate preconditions. + if (!coneCenterObjectId || !coneDirectionObjectId) + return 0; + + Object * coneCenterObject = 0; + Object * coneDirectionObject = 0; + + // Get the cone and base objects. + if (!JavaLibrary::getObject(coneCenterObjectId, coneCenterObject)) + return 0; + + if (!JavaLibrary::getObject(coneDirectionObjectId, coneDirectionObject)) + return 0; + + // Query for the results. + std::vector results; + + ServerWorld::findCreaturesOfRaceInCone(*coneCenterObject, *coneDirectionObject, + range, convertDegreesToRadians(angle), species, race, results); + + LocalLongArrayRefPtr rv; + if (ScriptConversion::convert(results, rv)) + return rv->getReturnValue(); + return 0; +} + +// ---------------------------------------------------------------------- + +/** + * + * + * @param env Java environment + * @param self class calling this function + * + * @return array of obj_ids of the objects in range, or null on error + */ +jlongArray JNICALL ScriptMethodsWorldInfoNamespace::getNonCreaturesInCone(JNIEnv *env, jobject self, jlong coneCenterObjectId, jlong coneDirectionObjectId, jfloat range, jfloat angle) +{ + UNREF(self); + + // Validate preconditions. + if (!coneCenterObjectId || !coneDirectionObjectId) + return 0; + + Object * coneCenterObject = 0; + Object * coneDirectionObject = 0; + + // Get the cone and base objects. + if (!JavaLibrary::getObject(coneCenterObjectId, coneCenterObject)) + return 0; + + if (!JavaLibrary::getObject(coneDirectionObjectId, coneDirectionObject)) + return 0; + + // Query for the results. + std::vector results; + + ServerWorld::findNonCreaturesInCone(*coneCenterObject, *coneDirectionObject, + range, convertDegreesToRadians(angle), results); + + LocalLongArrayRefPtr rv; + if (ScriptConversion::convert(results, rv)) + return rv->getReturnValue(); + return 0; +} + +// ---------------------------------------------------------------------- + +/** + * + * + * @param env Java environment + * @param self class calling this function + * + * @return array of obj_ids of the objects in range, or null on error + */ +jlongArray JNICALL ScriptMethodsWorldInfoNamespace::getNPCsInCone(JNIEnv *env, jobject self, jlong coneCenterObjectId, jlong coneDirectionObjectId, jfloat range, jfloat angle) +{ + UNREF(self); + + // Validate preconditions. + if (!coneCenterObjectId || !coneDirectionObjectId) + return 0; + + Object * coneCenterObject = 0; + Object * coneDirectionObject = 0; + + // Get the cone and base objects. + if (!JavaLibrary::getObject(coneCenterObjectId, coneCenterObject)) + return 0; + + if (!JavaLibrary::getObject(coneDirectionObjectId, coneDirectionObject)) + return 0; + + // Query for the results. + std::vector results; + + ServerWorld::findNPCsInCone(*coneCenterObject, *coneDirectionObject, + range, convertDegreesToRadians(angle), results); + + LocalLongArrayRefPtr rv; + if (ScriptConversion::convert(results, rv)) + return rv->getReturnValue(); + return 0; +} + +// ---------------------------------------------------------------------- + +/** + * + * + * @param env Java environment + * @param self class calling this function + * + * @return array of obj_ids of the objects in range, or null on error + */ +jlongArray JNICALL ScriptMethodsWorldInfoNamespace::getPlayerCreaturesInCone(JNIEnv *env, jobject self, jlong coneCenterObjectId, jlong coneDirectionObjectId, jfloat range, jfloat angle) +{ + UNREF(self); + + // Validate preconditions. + if (!coneCenterObjectId || !coneDirectionObjectId) + return 0; + + Object * coneCenterObject = 0; + Object * coneDirectionObject = 0; + + // Get the cone and base objects. + if (!JavaLibrary::getObject(coneCenterObjectId, coneCenterObject)) + return 0; + + if (!JavaLibrary::getObject(coneDirectionObjectId, coneDirectionObject)) + return 0; + + // Query for the results. + std::vector results; + + ServerWorld::findPlayerCreaturesInCone(*coneCenterObject, *coneDirectionObject, + range, convertDegreesToRadians(angle), results); + + LocalLongArrayRefPtr rv; + if (ScriptConversion::convert(results, rv)) + return rv->getReturnValue(); + return 0; +} + +// ---------------------------------------------------------------------- + +jfloat JNICALL ScriptMethodsWorldInfoNamespace::getElevation(JNIEnv *env, jobject self, jobject loc) +{ + PROFILER_AUTO_BLOCK_DEFINE("JNI::getElevation"); + Vector where; + NetworkId cell; + if (!ScriptConversion::convert(loc, where, cell)) + return 0.0f; + + const TerrainObject *terrain=TerrainObject::getConstInstance (); + NOT_NULL(terrain); + + float height; + if (terrain->getHeight(where,height)) + return height; + else + return 0.0f; +} + +jfloat JNICALL ScriptMethodsWorldInfoNamespace::getDirection(JNIEnv *env, jobject self, jobject loc1, jobject loc2) +{ + Vector from; + if (!ScriptConversion::convertWorld(loc1, from)) + { + return 0.0f; + } + + Vector to; + if (!ScriptConversion::convertWorld(loc2, to)) + { + return 0.0f; + } + + Vector difference=(to-from); + float theta=convertRadiansToDegrees(difference.theta()); + if (theta > 0) + return theta; + else + return (360.0f+theta); +} + +jobject JNICALL ScriptMethodsWorldInfoNamespace::findSpotNear(JNIEnv *env, jobject self, jlong target, jobject loc, jfloat radius) +{ + PROFILER_AUTO_BLOCK_DEFINE("JNI::findSpotNear"); + Vector where; + if (!ScriptConversion::convertWorld(loc, where)) + { + return 0; + } + + Vector result(where.x+Random::randomReal(radius*2) - radius,0,where.z+Random::randomReal(radius*2) - radius); + + const TerrainObject *terrain=TerrainObject::getConstInstance(); + NOT_NULL(terrain); + + float height; + if (terrain->getHeight(where,height)) + { + result.y=height; + LocalRefPtr temp; + if (ScriptConversion::convert(result, NetworkId(), temp)) + return temp->getReturnValue(); + else + return 0; + } + else + return 0; +} + +jlongArray JNICALL ScriptMethodsWorldInfoNamespace::getAllNpcs(JNIEnv *env, jobject self, jobject loc, jfloat radius) +{ + UNREF(self); + + std::vector results; + + Vector target; + if (!ScriptConversion::convertWorld(loc, target)) + return 0; + + ServerWorld::findNPCsInRange(target, radius, results); + + LocalLongArrayRefPtr rv; + if (ScriptConversion::convert(results, rv)) + return rv->getReturnValue(); + return 0; +} + +jlongArray JNICALL ScriptMethodsWorldInfoNamespace::getAllPlayers(JNIEnv *env, jobject self, jobject loc, jfloat radius) +{ + UNREF(self); + + std::vector results; + + Vector target; + if (!ScriptConversion::convertWorld(loc, target)) + return 0; + + ServerWorld::findPlayerCreaturesInRange(target, radius, results); + + LocalLongArrayRefPtr rv; + if (ScriptConversion::convert(results, rv)) + return rv->getReturnValue(); + return 0; +} + +jlong JNICALL ScriptMethodsWorldInfoNamespace::getClosestMobile(JNIEnv *env, jobject self, jobject loc) + //TODO: Rename getClosestNPC for consistency +{ + jfloat radius=128; //TODO: make this a paramter + UNREF(self); + + Vector target; + if (!ScriptConversion::convertWorld(loc, target)) + return 0; + + ServerObject * npc = ServerWorld::findClosestNPC(target, radius); + if (npc == NULL) + return 0; + return (npc->getNetworkId()).getValue(); +} + +jlong JNICALL ScriptMethodsWorldInfoNamespace::getClosestPlayer(JNIEnv *env, jobject self, jobject loc) +{ + jfloat radius=128; //TODO: make this a paramter + UNREF(self); + + Vector target; + if (!ScriptConversion::convertWorld(loc, target)) + return 0; + + ServerObject * player = ServerWorld::findClosestPlayer(target, radius); + if (player == NULL) + return 0; + return (player->getNetworkId()).getValue(); +} + +jlong JNICALL ScriptMethodsWorldInfoNamespace::getFirstObjectWithScript(JNIEnv *env, jobject self, jobject loc, jfloat range, jstring script) +{ + JavaStringParam localScript(script); + + UNREF(self); + + Vector target; + if (!ScriptConversion::convertWorld(loc, target)) + return 0; + + std::string scriptName; + if (!JavaLibrary::convert(localScript, scriptName)) + return 0; + + typedef std::vector ResultsType; + ResultsType results; + ServerWorld::findObjectsInRange(target, range, results); + + for (ResultsType::iterator i=results.begin(); i!=results.end(); ++i) + { + if (*i != NULL && (*i)->getScriptObject()->hasScript(scriptName)) + return ((*i)->getNetworkId()).getValue(); + } + + return 0; +} + +jlong JNICALL ScriptMethodsWorldInfoNamespace::getFirstObjectWithObjVar(JNIEnv *env, jobject self, jobject loc, jfloat range, jstring objvar) +{ + PROFILER_AUTO_BLOCK_DEFINE("JNI::getFirstObjectWithObjvar"); + JavaStringParam localObjvar(objvar); + + UNREF(self); + + Vector target; + if (!ScriptConversion::convertWorld(loc, target)) + return 0; + + std::string objvarName; + if (!JavaLibrary::convert(localObjvar, objvarName)) + return 0; + + typedef std::vector ResultsType; + ResultsType results; + ServerWorld::findObjectsInRange(target, range, results); + + for (ResultsType::iterator i=results.begin(); i!=results.end(); ++i) + { + if (*i != NULL && (*i)->getObjVars().hasItem(objvarName)) + return ((*i)->getNetworkId()).getValue(); + } + + return 0; +} + +jlong JNICALL ScriptMethodsWorldInfoNamespace::getFirstObjectWithTemplate(JNIEnv *env, jobject self, jobject loc, jfloat range, jstring templateName) +{ + PROFILER_AUTO_BLOCK_DEFINE("JNI::getFirstObjectWithTemplate"); + JavaStringParam localTemplateName(templateName); + + UNREF(self); + + Vector target; + if (!ScriptConversion::convertWorld(loc, target)) + return 0; + + std::string templateStr; + if (!JavaLibrary::convert(localTemplateName, templateStr)) + return 0; + + typedef std::vector ResultsType; + ResultsType results; + ServerWorld::findObjectsInRange(target, range, results); + + for (ResultsType::iterator i=results.begin(); i!=results.end(); ++i) + { + if (*i != NULL && templateStr == (*i)->getTemplateName()) + return ((*i)->getNetworkId()).getValue(); + } + + return 0; +} + +jlongArray JNICALL ScriptMethodsWorldInfoNamespace::getAllObjectsWithScript(JNIEnv *env, jobject self, jobject loc, jfloat range, jstring script) +{ + JavaStringParam localScript(script); + + UNREF(self); + + Vector target; + if (!ScriptConversion::convertWorld(loc, target)) + return 0; + + std::string scriptName; + if (!JavaLibrary::convert(localScript,scriptName)) + return 0; + + typedef std::vector ResultsType; + ResultsType results, filteredResults; + ServerWorld::findObjectsInRange(target, range, results); + + for (ResultsType::iterator i=results.begin(); i!=results.end(); ++i) + { + if ((*i)->getScriptObject()->hasScript(scriptName)) + filteredResults.push_back(*i); + } + + LocalLongArrayRefPtr rv; + if (ScriptConversion::convert(filteredResults, rv)) + return rv->getReturnValue(); + return 0; +} + +jlongArray JNICALL ScriptMethodsWorldInfoNamespace::getAllObjectsWithObjVar(JNIEnv *env, jobject self, jobject loc, jfloat range, jstring objvar) +{ + UNREF(self); + + PROFILER_AUTO_BLOCK_DEFINE("JNI::getObjectsWithObjvar"); + + JavaStringParam localObjvar(objvar); + + Vector target; + if (!ScriptConversion::convertWorld(loc, target)) + return 0; + + std::string objvarName; + if (!JavaLibrary::convert(localObjvar, objvarName)) + return 0; + + typedef std::vector ResultsType; + ResultsType results, filteredResults; + ServerWorld::findObjectsInRange(target, range, results); + + for (ResultsType::iterator i=results.begin(); i!=results.end(); ++i) + { + if ((*i)->getObjVars().hasItem(objvarName)) + filteredResults.push_back(*i); + } + + LocalLongArrayRefPtr rv; + if (ScriptConversion::convert(filteredResults, rv)) + return rv->getReturnValue(); + return 0; +} + +jlongArray JNICALL ScriptMethodsWorldInfoNamespace::getAllObjectsWithTemplate(JNIEnv *env, jobject self, jobject loc, jfloat range, jstring templateName) +{ + UNREF(self); + + PROFILER_AUTO_BLOCK_DEFINE("JNI::getAllObjectsWithTemplate"); + + JavaStringParam localTemplateName(templateName); + + Vector target; + if (!ScriptConversion::convertWorld(loc, target)) + return 0; + + std::string templateStr; + if (!JavaLibrary::convert(localTemplateName, templateStr)) + return 0; + + typedef std::vector ResultsType; + ResultsType results, filteredResults; + ServerWorld::findObjectsInRange(target, range, results); + + for (ResultsType::iterator i=results.begin(); i!=results.end(); ++i) + { + if (templateStr == (*i)->getTemplateName()) + filteredResults.push_back(*i); + } + + LocalLongArrayRefPtr rv; + if (ScriptConversion::convert(filteredResults, rv)) + return rv->getReturnValue(); + return 0; +} + +jobject JNICALL ScriptMethodsWorldInfoNamespace::getLocationBetweenLocs(JNIEnv *env, jobject self, jobject target1, jobject target2) +{ + Vector loc1; + if (!ScriptConversion::convertWorld(target1, loc1)) + return 0; + Vector loc2; + if (!ScriptConversion::convertWorld(target2, loc2)) + return 0; + + float factor=Random::randomReal(); // how far along the line between the two points + Vector result(loc1.x+(loc2.x-loc1.x)*factor,0,loc1.z+(loc2.z-loc1.z)*factor); + + const TerrainObject *terrain=TerrainObject::getConstInstance(); + NOT_NULL(terrain); + + float height; + if (terrain->getHeight(result,height)) + { + result.y=height; + LocalRefPtr temp; + // @todo: what cell do we use? + if (ScriptConversion::convert(result, NetworkId::cms_invalid, temp)) + return temp->getReturnValue(); + else + { + DEBUG_REPORT_LOG(true,("(ScriptConversion::convert(result,temp)) failed.\n")); + } + } + DEBUG_REPORT_LOG(true,("(terrain->getHeight(result,height)) failed\n")); + return 0; +} + +//----------------------------------------------------------------------- + +jlong JNICALL ScriptMethodsWorldInfoNamespace::getPlanetByName(JNIEnv * env, jobject self, jstring name) +{ + JavaStringParam localName(name); + + PROFILER_AUTO_BLOCK_DEFINE("JNI::getPlanetByName"); + + jlong result = 0; + std::string n; + if(JavaLibrary::convert(localName, n)) + { + PlanetObject * p = ServerUniverse::getInstance().getPlanetByName(n); + if (p) + { + result = (p->getNetworkId()).getValue(); + } + } + return result; +} + +// ---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsWorldInfoNamespace::getNameForPlanetObject(JNIEnv * env, jobject self, jlong planet) +{ + NetworkId planetObjId(planet); + if (planetObjId!=NetworkId::cms_invalid) + { + const PlanetObject *planetObj = dynamic_cast(NetworkIdManager::getObjectById(planetObjId)); + if (planetObj) + { + JavaString str(Unicode::narrowToWide(planetObj->getName())); + return str.getReturnValue(); + } + } + + return NULL; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsWorldInfoNamespace::isValidLocation(JNIEnv *env, jobject self, jobject jObjectPos, jfloat jObjectRadius ) +{ + return true; +} + +jobject JNICALL ScriptMethodsWorldInfoNamespace::getValidLocation(JNIEnv *env, jobject self, jobject jCorralCenter, jfloat jCorralRadius, jobject jDesiredPos, jfloat jObjectRadius ) +{ + // convert java objects to C++ objects + + PROFILER_AUTO_BLOCK_DEFINE("JNI::getValidLocation"); + + Vector corralCenter; + float corralRadius = jCorralRadius; + + Vector desiredPos; + float objectRadius = jObjectRadius; + + UNREF(corralRadius); + UNREF(objectRadius); + + ScriptConversion::convertWorld(jCorralCenter, corralCenter); + ScriptConversion::convertWorld(jDesiredPos, desiredPos); + + // ---------- + + const TerrainObject *terrain=TerrainObject::getConstInstance (); + NOT_NULL(terrain); + + for (int testCount = 0; testCount < 20; testCount++) + { + // ---------- + // Find a random point inside the corral + + float rad = (corralRadius - objectRadius); + float rad2 = rad * rad; + + Vector corralPoint; + + do + { + corralPoint.x = Random::randomReal(-rad,rad); + corralPoint.y = 0; + corralPoint.z = Random::randomReal(-rad,rad); + } + while(corralPoint.magnitudeSquared() > rad2); + + corralPoint += corralCenter; + + // ---------- + // CorralPoint is now a random point in the corral. + + // Pop CorralPoint down onto the terrain. If we can't, try and find another point. + + if (!terrain->getHeight(corralPoint,corralPoint.y)) + { + continue; + } + + // Determine if it's a valid point, and if not search for another one. + + bool isValid = !CollisionWorld::query( Sphere(corralPoint,objectRadius),NULL); + + // ---------- + + if(isValid) + { + LocalRefPtr result; + if (ScriptConversion::convert(corralPoint, NetworkId(), result)) + return result->getReturnValue(); + } + else + { + continue; + } + } + + // We failed to find a valid location + + return NULL; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsWorldInfoNamespace::getCollidesWithObject(JNIEnv * env, jobject self, jobject jlocation, jfloat jradius) +{ + if (jlocation == NULL) + return JNI_FALSE; + + float const radius = jradius; + Vector location; + if (!ScriptConversion::convertWorld(jlocation, location)) + return JNI_FALSE; + + bool const result = CollisionWorld::query(Sphere(location, radius), NULL); + + if(result) + return JNI_TRUE; + else + return JNI_FALSE; +} + +// ---------------------------------------------------------------------- + +/** + * Tests to see if an object can see another object. + * + * @param env Java environment + * @param self class calling this function + * @param source object that is looking + * @param target object that is being looked at + * + * @return JNI_TRUE if the source can see the target, JNI_FALSE otherwise + */ +jboolean JNICALL ScriptMethodsWorldInfoNamespace::canSee(JNIEnv *env, jobject self, jlong source, jlong target) +{ + UNREF(self); + + const ServerObject * sourceObject = NULL; + if (!JavaLibrary::getObject(source, sourceObject)) + { + NetworkId id(source); + if (id == NetworkId::cms_invalid) + { + DEBUG_WARNING(true,("JavaLibrary::canSee - source object %s doesn't exist, returning true as a workaround\n",id.getValueString().c_str())); + } + else + { + DEBUG_WARNING(true,("JavaLibrary::canSee - source object doesn't exist and we can't get a network ID for it, returning true as a workaround\n")); + } + + return JNI_TRUE; + } + + const ServerObject * targetObject = NULL; + if (!JavaLibrary::getObject(target, targetObject)) + { + NetworkId id(target); + if (id == NetworkId::cms_invalid) + { + DEBUG_WARNING(true,("JavaLibrary::canSee - target object %s doesn't exist, returning true as a workaround\n",id.getValueString().c_str())); + } + else + { + DEBUG_WARNING(true,("JavaLibrary::canSee - target object doesn't exist and we can't get a network ID for it, returning true as a workaround\n")); + } + + return JNI_TRUE; + } + + return sourceObject->checkLOSTo(*targetObject); + +} // JavaLibrary::canSee + +// ---------------------------------------------------------------------- + +/** + * Tests to see if an object can see a location. + * + * @param env Java environment + * @param self class calling this function + * @param source object that is looking + * @param target location the source is looking at + * + * @return JNI_TRUE if the source can see the target, JNI_FALSE otherwise + */ +jboolean JNICALL ScriptMethodsWorldInfoNamespace::canSeeLocation(JNIEnv *env, jobject self, jlong source, jobject target) +{ + UNREF(self); + + const ServerObject * sourceObject = NULL; + if (!JavaLibrary::getObject(source, sourceObject)) + { + NetworkId id(source); + if (id == NetworkId::cms_invalid) + { + DEBUG_WARNING(true,("JavaLibrary::canSee - source object %s doesn't exist, returning true as a workaround\n",id.getValueString().c_str())); + } + else + { + DEBUG_WARNING(true,("JavaLibrary::canSee - source object doesn't exist and we can't get a network ID for it, returning true as a workaround\n")); + } + + return JNI_TRUE; + } + + Location targetLocation; + if (!ScriptConversion::convert(LocalRefParam(target), targetLocation)) + { + DEBUG_WARNING(true,("JavaLibrary::canSeeLocation - can't convert target location, returning true as a workaround\n")); + return JNI_TRUE; + } + + return sourceObject->checkLOSTo(targetLocation); +} // JavaLibrary::canSeeLocation + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsWorldInfoNamespace::canManipulate(JNIEnv *env, jobject self, jlong player, jlong target, jboolean move, jboolean doPermission, float distance, jboolean sendMessage, jboolean skipNoTradeCheck) +{ + UNREF(self); + + const CreatureObject * sourceObject = NULL; + if (!JavaLibrary::getObject(player, sourceObject)) + return JNI_FALSE; + + const ServerObject * targetObject = NULL; + if (!JavaLibrary::getObject(target, targetObject)) + return JNI_FALSE; + + Container::ContainerErrorCode code = Container::CEC_Success; + bool retval = sourceObject->canManipulateObject(*targetObject, move, doPermission, doPermission, distance, code, skipNoTradeCheck); + if (!retval && sendMessage && sourceObject->getClient()) + { + ContainerInterface::sendContainerMessageToClient(*sourceObject, code); + } + return retval; +} + +/** + * @param env Java environment + * @param self class calling this function + * @param performer performer we are looking for listeners of + * @param range radius of search area + * + * @return array of obj_ids of the objects in range, or null on error + */ +jlongArray JNICALL ScriptMethodsWorldInfoNamespace::getPerformanceListenersInRange(JNIEnv *env, jobject self, jlong performer, jfloat range) +{ + UNREF(self); + + if (performer == 0) + return 0; + + std::vector creatures; + const TangibleObject * object = 0; + if (!JavaLibrary::getObject(performer, object)) + return 0; + ServerWorld::findCreaturesInRange(object->getPosition_w(), range, creatures); + + std::vector results; + for (std::vector::iterator i = creatures.begin(); i != creatures.end(); ++i) + if (safe_cast(*i)->getPerformanceListenTarget() == object->getNetworkId()) + results.push_back(*i); + + LocalLongArrayRefPtr rv; + if (ScriptConversion::convert(results, rv)) + return rv->getReturnValue(); + return 0; +} + +// ---------------------------------------------------------------------- + +/** + * @param env Java environment + * @param self class calling this function + * @param performer performer we are looking for watchers of + * @param range radius of search area + * + * @return array of obj_ids of the objects in range, or null on error + */ +jlongArray JNICALL ScriptMethodsWorldInfoNamespace::getPerformanceWatchersInRange(JNIEnv *env, jobject self, jlong performer, jfloat range) +{ + UNREF(self); + + if (performer == 0) + return 0; + + std::vector creatures; + const TangibleObject * object = 0; + if (!JavaLibrary::getObject(performer, object)) + return 0; + ServerWorld::findCreaturesInRange(object->getPosition_w(), range, creatures); + + std::vector results; + for (std::vector::iterator i = creatures.begin(); i != creatures.end(); ++i) + if (safe_cast(*i)->getPerformanceWatchTarget() == object->getNetworkId()) + results.push_back(*i); + + LocalLongArrayRefPtr rv; + if (ScriptConversion::convert(results, rv)) + return rv->getReturnValue(); + return 0; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsWorldInfoNamespace::isSpaceBattlefieldZone(JNIEnv *, jobject) +{ + return static_cast(ServerWorld::isSpaceBattlefieldZone()); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsWorldInfoNamespace::isSpaceScene(JNIEnv *, jobject) +{ + return static_cast(ServerWorld::isSpaceScene()); +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsWorldInfoNamespace::startUniverseWideEvent(JNIEnv * env, jobject self, jstring eventName) +{ + JavaStringParam localEventName(eventName); + std::string eventString; + + if (!JavaLibrary::convert(localEventName, eventString)) + return JNI_FALSE; + + ServerUniverse::addUniverseEvent(eventString); + //ServerBuildoutManager::onEventStarted(eventString); + + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +jboolean JNICALL ScriptMethodsWorldInfoNamespace::stopUniverseWideEvent(JNIEnv * env, jobject self, jstring eventName) +{ + JavaStringParam localEventName(eventName); + std::string eventString; + + if (!JavaLibrary::convert(localEventName, eventString)) + return JNI_FALSE; + + ServerUniverse::removeUniverseEvent(eventString); + //ServerBuildoutManager::onEventStopped(eventString); + + + return JNI_TRUE; +} + +// ---------------------------------------------------------------------- + +jstring JNICALL ScriptMethodsWorldInfoNamespace::getCurrentUniverseWideEvents(JNIEnv * env, jobject self) +{ + const std::string events = ServerUniverse::getCurrentEvents(); + + JavaString str(Unicode::narrowToWide(events)); + + return str.getReturnValue(); + +} + +// ====================================================================== + diff --git a/engine/server/library/serverScript/src/shared/ScriptParamArchive.cpp b/engine/server/library/serverScript/src/shared/ScriptParamArchive.cpp new file mode 100644 index 00000000..0dd8aca8 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptParamArchive.cpp @@ -0,0 +1,563 @@ +// ScriptParamArchive.cpp +// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved. +// Author: Justin Randall + +//----------------------------------------------------------------------- + +#include "serverScript/FirstServerScript.h" +#include "serverScript/ScriptParamArchive.h" + +#include "Archive/Archive.h" +#include "UnicodeUtils.h" +#include "localizationArchive/StringIdArchive.h" +#include "serverScript/ScriptParameters.h" +#include "sharedFoundation/NetworkIdArchive.h" +#include "sharedGame/AttribMod.h" +#include "sharedGame/AttribModArchive.h" +#include "sharedMathArchive/VectorArchive.h" +#include "sharedNetworkMessages/ObjectMenuRequestData.h" +#include "sharedNetworkMessages/ObjectMenuRequestDataArchive.h" +#include "sharedObject/CachedNetworkIdArchive.h" +#include "sharedUtility/ValueDictionary.h" +#include "sharedUtility/ValueDictionaryArchive.h" +#include "unicodeArchive/UnicodeArchive.h" +#include + +//----------------------------------------------------------------------- + +namespace Archive +{ + +void get(ReadIterator & source, std::vector *> & target) +{ + target.clear(); + signed int length = 0; + get(source, length); + for (int i = 0; i < length; ++i) + { + std::vector * inner = new std::vector(); + NOT_NULL(inner); + signed int innerLength = 0; + get(source, innerLength); + NetworkId id; + for (int j = 0; j < innerLength; ++j) + { + get(source, id); + inner->push_back(id); + } + target.push_back(inner); + } +} + +void put(ByteStream & target, const std::vector *> & source) +{ + signed int length = source.size(); + put(target, length); + for (int i = 0; i < length; ++i) + { + const std::vector * inner = source[i]; + signed int innerLength = 0; + if (inner != NULL) + innerLength = inner->size(); + put(target, innerLength); + for (int j = 0; j < innerLength; ++j) + { + put(target, inner->at(j)); + } + } +} + +//----------------------------------------------------------------------- + +void get(ReadIterator & source, Param & target) +{ + Param * p = ⌖ + p->m_owned = true; + int paramType; + get(source, paramType); + p->m_type = static_cast(paramType); + get(source, p->m_name); + switch(paramType) + { + case Param::BOOL: + { + get(source, p->m_param.bParam); + } + break; + case Param::BOOL_ARRAY: + { + std::deque * b = new std::deque; + get(source, *b); + p->m_param.baParam = b; + } + break; + case Param::INT: + { + get(source, p->m_param.iParam); + } + break; + case Param::INT_ARRAY: + { + std::vector * v = new std::vector; + get(source, *v); + p->m_param.iaParam = v; + } + break; + case Param::FLOAT: + { + get(source, p->m_param.fParam); + } + break; + case Param::FLOAT_ARRAY: + { + std::vector * v = new std::vector; + get(source, *v); + p->m_param.faParam = v; + } + break; + case Param::STRING: + { + std::string s; + get(source, s); + char * str = new char[s.length() + 1]; + strcpy(str, s.c_str()); + p->m_param.sParam = str; + } + break; + case Param::STRING_ARRAY: + { + std::vector v; + get(source, v); + std::vector::const_iterator si; + std::vector * s = new std::vector; + for(si = v.begin(); si != v.end(); ++si) + { + char * str = new char[(*si).length() + 1]; + strcpy(str, (*si).c_str()); + s->push_back(str); + } + p->m_param.saParam = s; + } + break; + case Param::UNICODE: + { + Unicode::String * s = new Unicode::String; + get(source, *s); + p->m_param.uParam = s; + } + break; + case Param::UNICODE_ARRAY: + { + std::vector * s = new std::vector; + int count; + get(source, count); + int index; + for(index = 0; index < count; ++index) + { + Unicode::String tmp; + get(source, tmp); + Unicode::String * entry = new Unicode::String(tmp); + s->push_back(entry); + } + p->m_param.uaParam = s; + } + break; + case Param::OBJECT_ID: + { + NetworkId * id = new NetworkId; + get(source, *id); + p->m_param.oidParam = id; + } + break; + case Param::OBJECT_ID_ARRAY: + { + std::vector * ids = new std::vector; + get(source, *ids); + p->m_param.oidaParam = ids; + } + break; + case Param::CACHED_OBJECT_ID_ARRAY: + { + std::vector * ids = new std::vector; + get(source, *ids); + p->m_param.coidaParam = ids; + } + break; + case Param::OBJECT_ID_ARRAY_ARRAY: + { + std::vector *> * ids = new std::vector *>; + get(source, *ids); + p->m_param.oidaaParam = ids; + } + break; + case Param::STRING_ID: + { + StringId * s = new StringId; + get(source, *s); + p->m_param.sidParam = s; + } + break; + case Param::STRING_ID_ARRAY: + { + int count; + get(source, count); + std::vector * s = new std::vector; + int index; + for(index = 0; index < count; ++index) + { + StringId * id = new StringId; + get(source, *id); + s->push_back(id); + } + p->m_param.sidaParam = s; + } + break; + case Param::ATTRIB_MOD: + { + AttribMod::AttribMod * m = new AttribMod::AttribMod; + get(source, *m); + p->m_param.amParam = m; + } + break; + case Param::ATTRIB_MOD_ARRAY: + { + std::vector * m = new std::vector; + int count; + get(source, count); + int index; + for(index = 0; index < count; ++index) + { + AttribMod::AttribMod mod; + get(source, mod); + m->push_back(mod); + } + p->m_param.amaParam = m; + } + break; + case Param::MENTAL_STATE_MOD: + { + ServerObjectTemplate::MentalStateMod * m = new ServerObjectTemplate::MentalStateMod; + int t ; + get(source, t); + m->target = static_cast(t); + get(source, m->value); + get(source, m->timeAtValue); + get(source, m->decay); + p->m_param.msmParam = m; + } + break; + case Param::MENTAL_STATE_MOD_ARRAY: + { + std::vector * m = new std::vector; + int count; + get(source, count); + int index; + for(index = 0; index < count; ++index) + { + ServerObjectTemplate::MentalStateMod mod; + int t; + get(source, t); + mod.target = static_cast(t); + get(source, mod.value); + get(source, mod.timeAtValue); + get(source, mod.decay); + m->push_back(mod); + } + p->m_param.amsmParam = m; + } + break; + case Param::OBJECT_MENU_INFO: + { + MenuDataVector * v = new MenuDataVector; + get(source, *v); + p->m_param.aomrdParam = v; + } + break; + case Param::MANUFACTURE_SCHEMATIC: + { + DEBUG_FATAL(true, ("This NEVER is sent over the network! --sjakab\n")); + } + break; + case Param::INGREDIENT_SLOT: + { + DEBUG_FATAL(true, ("This NEVER is sent over the network! --sjakab\n")); + } + break; + case Param::LOCATION: + { + Vector * v = new Vector; + get(source, *v); + p->m_param.lParam = v; + } + break; + case Param::LOCATION_ARRAY: + { + std::vector * v = new std::vector; + get_ptr(source, *v); + p->m_param.laParam = v; + } + break; + case Param::DICTIONARY: + { + ValueDictionary * dictionary = new ValueDictionary; + get(source, *dictionary); + p->m_param.valueDictionaryParam = dictionary; + } + break; + case Param::DICTIONARY_ARRAY: + { + int32 count; + get(source, count); + + std::vector * dictionaryArray = new std::vector; + ValueDictionary dictionary; + + int index; + for(index = 0; index < static_cast(count); ++index) + { + get(source, dictionary); + dictionaryArray->push_back(dictionary); + } + + p->m_param.valueDictionaryArrayParam = dictionaryArray; + } + break; + case Param::BYTE_ARRAY: + { + std::vector * v = new std::vector; + get(source, *v); + p->m_param.byteArrayParam = v; + } + break; + default: + { + DEBUG_FATAL(true, ("Unknown or unhandled ScriptParam type!!!!\n")); + } + break; + } +} + +//----------------------------------------------------------------------- + +void put(ByteStream & target, const Param & source) +{ + Archive::put(target, source.m_type); + Archive::put(target, source.m_name); + switch(source.m_type) + { + case Param::BOOL: + { + Archive::put(target, source.m_param.bParam); + } + break; + case Param::BOOL_ARRAY: + { + Archive::put(target, *source.m_param.baParam); + } + break; + case Param::INT: + { + Archive::put(target, source.m_param.iParam); + } + break; + case Param::INT_ARRAY: + { + Archive::put(target, *source.m_param.iaParam); + } + break; + case Param::FLOAT: + { + Archive::put(target, source.m_param.fParam); + } + break; + case Param::FLOAT_ARRAY: + { + Archive::put(target, *source.m_param.faParam); + } + break; + case Param::STRING: + { + std::string s = source.m_param.sParam; + Archive::put(target, s); + } + break; + case Param::STRING_ARRAY: + { + std::vector s; + std::vector::const_iterator c; + for(c = source.m_param.saParam->begin(); c != source.m_param.saParam->end(); ++c) + { + if (*c) + { + s.push_back(std::string(*c)); + } + else + { + s.push_back(std::string("")); + } + } + Archive::put(target, s); + } + break; + case Param::UNICODE: + { + Archive::put(target, *source.m_param.uParam); + } + break; + case Param::UNICODE_ARRAY: + { + std::vector::const_iterator ui; + int count = source.m_param.uaParam->size(); + Archive::put(target, count); + for(ui = source.m_param.uaParam->begin(); ui != source.m_param.uaParam->end(); ++ui) + { + if ((*ui)) + { + Archive::put(target, *(*ui)); + } + else + { + static const Unicode::String emptyStr = + Unicode::narrowToWide(""); + Archive::put(target, emptyStr); + } + } + + } + break; + case Param::OBJECT_ID: + { + Archive::put(target, *source.m_param.oidParam); + } + break; + case Param::OBJECT_ID_ARRAY: + { + Archive::put(target, *source.m_param.oidaParam); + } + break; + case Param::CACHED_OBJECT_ID_ARRAY: + { + Archive::put(target, *source.m_param.coidaParam); + } + break; + case Param::OBJECT_ID_ARRAY_ARRAY: + { + Archive::put(target, *source.m_param.oidaaParam); + } + break; + case Param::STRING_ID: + { + Archive::put(target, *source.m_param.sidParam); + } + break; + case Param::STRING_ID_ARRAY: + { + int count = source.m_param.sidaParam->size(); + Archive::put(target, count); + std::vector::const_iterator si; + for(si = source.m_param.sidaParam->begin(); si != source.m_param.sidaParam->end(); ++si) + { + Archive::put(target, *(*si)); + } + } + break; + case Param::ATTRIB_MOD: + { + const AttribMod::AttribMod * m = source.m_param.amParam; + Archive::put(target, *m); + } + break; + case Param::ATTRIB_MOD_ARRAY: + { + std::vector::const_iterator mi; + int count = source.m_param.amaParam->size(); + Archive::put(target, count); + for (mi = source.m_param.amaParam->begin(); mi != source.m_param.amaParam->end(); ++mi) + { + Archive::put(target, *mi); + } + } + break; + case Param::MENTAL_STATE_MOD: + { + const ServerObjectTemplate::MentalStateMod * m = source.m_param.msmParam; + int t = m->target; + Archive::put(target, t); + Archive::put(target, m->value); + Archive::put(target, m->timeAtValue); + Archive::put(target, m->decay); + } + break; + case Param::MENTAL_STATE_MOD_ARRAY: + { + std::vector::const_iterator mi; + int count = source.m_param.amsmParam->size(); + Archive::put(target, count); + for(mi = source.m_param.amsmParam->begin(); mi != source.m_param.amsmParam->end(); ++mi) + { + int t = (*mi).target; + Archive::put(target, t); + Archive::put(target, (*mi).value); + Archive::put(target, (*mi).timeAtValue); + Archive::put(target, (*mi).decay); + } + } + break; + case Param::OBJECT_MENU_INFO: + { + Archive::put(target, *source.m_param.aomrdParam); + } + break; + case Param::MANUFACTURE_SCHEMATIC: + { + DEBUG_FATAL(true, ("This NEVER is sent over the network! --sjakab\n")); + } + break; + case Param::INGREDIENT_SLOT: + { + DEBUG_FATAL(true, ("This NEVER is sent over the network! --sjakab\n")); + } + break; + case Param::LOCATION: + { + Archive::put(target, *source.m_param.lParam); + } + break; + case Param::LOCATION_ARRAY: + { + Archive::put(target, *source.m_param.laParam); + } + break; + case Param::DICTIONARY: + { + Archive::put(target, *source.m_param.valueDictionaryParam); + } + break; + case Param::DICTIONARY_ARRAY: + { + int32 count = static_cast(source.m_param.valueDictionaryArrayParam->size()); + Archive::put(target, count); + std::vector::const_iterator iter; + for(iter = source.m_param.valueDictionaryArrayParam->begin(); iter != source.m_param.valueDictionaryArrayParam->end(); ++iter) + { + Archive::put(target, (*iter)); + } + } + break; + case Param::BYTE_ARRAY: + { + Archive::put(target, *source.m_param.byteArrayParam); + } + break; + default: + DEBUG_FATAL(true, ("Unknown or unhandled ScriptParam type!!!!\n")); + break; + } +} + +//----------------------------------------------------------------------- + +}//namespace Archive + +//----------------------------------------------------------------------- + diff --git a/engine/server/library/serverScript/src/shared/ScriptParamArchive.h b/engine/server/library/serverScript/src/shared/ScriptParamArchive.h new file mode 100644 index 00000000..baa52f64 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptParamArchive.h @@ -0,0 +1,25 @@ +// ScriptParamArchive.h +// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved. +// Author: Justin Randall + +#ifndef _INCLUDED_ScriptParamArchive_H +#define _INCLUDED_ScriptParamArchive_H + +//----------------------------------------------------------------------- + +struct Param; + +//----------------------------------------------------------------------- + +namespace Archive +{ + class ReadIterator; + class ByteStream; + + void get(Archive::ReadIterator & source, Param & target); + void put(Archive::ByteStream & target, const Param & source); +} + +//----------------------------------------------------------------------- + +#endif // _INCLUDED_ScriptParamArchive_H diff --git a/engine/server/library/serverScript/src/shared/ScriptParameters.cpp b/engine/server/library/serverScript/src/shared/ScriptParameters.cpp new file mode 100644 index 00000000..78c5fde4 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptParameters.cpp @@ -0,0 +1,811 @@ +//======================================================================== +// +// ScriptParams.cpp - varargs substitute for passing params to scripts. +// +// copyright 2001 Sony Online Entertainment +// +//======================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/ScriptParameters.h" + +#include "serverScript/JavaLibrary.h" +#include "serverScript/ScriptParamArchive.h" +#include "sharedGame/AttribMod.h" +#include "sharedMath/Vector.h" +#include "sharedNetworkMessages/ObjectMenuRequestData.h" //@todo: move this to a different library (sharedUserInterface) +#include "sharedNetworkMessages/ObjectMenuRequestDataArchive.h" +#include "sharedUtility/ValueDictionary.h" +#include + +//======================================================================== + +/** + * Class constructor. + */ +ScriptParams::ScriptParams(void) : +m_params() +{ +} // ScriptParams::ScriptParams + +/** + * Class destructor. + */ +ScriptParams::~ScriptParams(void) +{ + // delete data that we own + for (std::vector::iterator i = m_params.begin(); i != m_params.end(); ++i) + { + Param & p = (*i); + if (p.m_owned) + { + switch(p.m_type) + { + case Param::BOOL_ARRAY: + { + delete p.m_param.baParam; + } + break; + case Param::INT_ARRAY: + { + delete p.m_param.iaParam; + } + break; + case Param::FLOAT_ARRAY: + { + delete p.m_param.faParam; + } + break; + case Param::STRING: + { + // @todo : what is this bullshit? Can't vector delete a const pointer? + delete [] const_cast(p.m_param.sParam); + } + break; + case Param::STRING_ARRAY: + { + std::vector::const_iterator s; + for(s = p.m_param.saParam->begin(); s != p.m_param.saParam->end(); ++s) + { + const char * c = (*s); + delete [] const_cast(c); + } + delete p.m_param.saParam; + } + break; + case Param::UNICODE: + { + delete p.m_param.uParam; + } + break; + case Param::UNICODE_ARRAY: + { + std::vector::const_iterator s; + for(s = p.m_param.uaParam->begin(); s != p.m_param.uaParam->end(); ++s) + { + const Unicode::String * c = (*s); + delete const_cast(c); + } + delete p.m_param.uaParam; + } + break; + case Param::OBJECT_ID: + { + delete p.m_param.oidParam; + } + break; + case Param::OBJECT_ID_ARRAY: + { + delete p.m_param.oidaParam; + } + break; + case Param::CACHED_OBJECT_ID_ARRAY: + { + delete p.m_param.coidaParam; + } + break; + case Param::OBJECT_ID_ARRAY_ARRAY: + { + std::vector *>::const_iterator iter; + for (iter = p.m_param.oidaaParam->begin(); + iter != p.m_param.oidaaParam->end(); ++iter) + { + delete *iter; + } + delete p.m_param.oidaaParam; + } + break; + case Param::STRING_ID: + { + delete p.m_param.sidParam; + } + break; + case Param::STRING_ID_ARRAY: + { + std::vector::const_iterator s; + for(s = p.m_param.sidaParam->begin(); s != p.m_param.sidaParam->end(); ++s) + { + const StringId * c = (*s); + delete c; + } + delete p.m_param.sidaParam; + } + break; + case Param::ATTRIB_MOD: + { + delete const_cast(p.m_param.amParam); + } + break; + case Param::ATTRIB_MOD_ARRAY: + { + delete p.m_param.amaParam; + } + break; + case Param::MENTAL_STATE_MOD: + { + delete const_cast(p.m_param.msmParam); + } + break; + case Param::MENTAL_STATE_MOD_ARRAY: + { + delete p.m_param.amsmParam; + } + break; + case Param::OBJECT_MENU_INFO: + { + delete p.m_param.aomrdParam; + } + break; + case Param::LOCATION: + { + delete const_cast(p.m_param.lParam); + } + break; + case Param::LOCATION_ARRAY: + { + std::vector::const_iterator s; + for(s = p.m_param.laParam->begin(); s != p.m_param.laParam->end(); ++s) + { + const Vector * c = (*s); + delete const_cast(c); + } + delete p.m_param.laParam; + } + break; + case Param::DICTIONARY: + { + delete p.m_param.valueDictionaryParam; + } + break; + case Param::DICTIONARY_ARRAY: + { + delete p.m_param.valueDictionaryArrayParam; + } + break; + default: + break; + } + } + } +} // ScriptParams::~ScriptParams + +/** + * Adds a boolean param. + */ +void ScriptParams::addParam(bool param, const std::string & paramName, bool owned) +{ + m_params.push_back(Param()); + Param &p = m_params.back(); + p.m_type = Param::BOOL; + p.m_param.bParam = param; + p.m_name = paramName; + p.m_owned = owned; +} // ScriptParams::addParam(bool) + +/** + * INTENTIONALLY COMMENTED OUT WHILE LEAVING DECLARATION + * This call occurs because of a conversion of a datatype passing through this function from std::string to Unicode::String. + * Basically, most times it is called with std::string the c_str() function is called. Since this is still valid when the + * type is changed to Unicode::String and the const Unicode::unicode_char_t * is successfully auto-converted to const char * + * you wind up having a NULL string when it get explicitly converted to const char * on the other side. So, this should never + * be called except in error. + * +void ScriptParams::addParam(const Unicode::unicode_char_t * param, const std::string & paramName, bool owned) +{ + DEBUG_FATAL(true, ("ScriptParams::addParam(const Unicode::unicode_char_t *, const std::string &, bool) called when ScriptParams::addParam(const Unicode::String, ...) expected.")); + WARNING(true, ("ScriptParams::addParam(const Unicode::unicode_char_t *, const std::string &, bool) called when ScriptParams::addParam(const Unicode::String, ...) expected.")); +} // ScriptParams::addParam(const Unicode::unicode_char_t *) +*/ + +/** + * Adds a boolean array param. + */ +void ScriptParams::addParam(const std::deque & param, const std::string & paramName, bool owned) +{ + m_params.push_back(Param()); + Param &p = m_params.back(); + p.m_type = Param::BOOL_ARRAY; + p.m_param.baParam = ¶m; + p.m_name = paramName; + p.m_owned = owned; +} // ScriptParams::addParam(const std::vector &) + +/** + * Adds an integer param. + */ +void ScriptParams::addParam(int param, const std::string & paramName, bool owned) +{ + m_params.push_back(Param()); + Param &p = m_params.back(); + p.m_type = Param::INT; + p.m_param.iParam = param; + p.m_name = paramName; + p.m_owned = owned; +} // ScriptParams::addParam(int) + +/** + * Adds an integer array param. + */ +void ScriptParams::addParam(const std::vector & param, const std::string & paramName, bool owned) +{ + m_params.push_back(Param()); + Param &p = m_params.back(); + p.m_type = Param::INT_ARRAY; + p.m_param.iaParam = ¶m; + p.m_name = paramName; + p.m_owned = owned; +} // ScriptParams::addParam(const std::vector &) + +/** + * Adds a float param. + */ +void ScriptParams::addParam(float param, const std::string & paramName, bool owned) +{ + m_params.push_back(Param()); + Param &p = m_params.back(); + p.m_type = Param::FLOAT; + p.m_param.fParam = param; + p.m_name = paramName; + p.m_owned = owned; +} // ScriptParams::addParam(float) + +/** + * Adds a float array param. + */ +void ScriptParams::addParam(const std::vector & param, const std::string & paramName, bool owned) +{ + m_params.push_back(Param()); + Param &p = m_params.back(); + p.m_type = Param::FLOAT_ARRAY; + p.m_param.faParam = ¶m; + p.m_name = paramName; + p.m_owned = owned; +} // ScriptParams::addParam(const std::vector &) + +/** + * Adds a string param. + */ +void ScriptParams::addParam(const char * param, const std::string & paramName, bool owned) +{ + m_params.push_back(Param()); + Param &p = m_params.back(); + p.m_type = Param::STRING; + p.m_param.sParam = param; + p.m_name = paramName; + p.m_owned = owned; +} // ScriptParams::addParam(const char *) + +/** + * Adds a string array param. + */ +void ScriptParams::addParam(std::vector & param, const std::string & paramName, bool owned) +{ + m_params.push_back(Param()); + Param &p = m_params.back(); + p.m_type = Param::STRING_ARRAY; + p.m_param.saParam = ¶m; + p.m_name = paramName; + p.m_owned = owned; +} // ScriptParams::addParam(std::vector &) + +/** + * Adds a unicode param. + */ +void ScriptParams::addParam(const Unicode::String & param, const std::string & paramName, bool owned) +{ + m_params.push_back(Param()); + Param &p = m_params.back(); + p.m_type = Param::UNICODE; + p.m_param.uParam = ¶m; + p.m_name = paramName; + p.m_owned = owned; +} // ScriptParams::addParam(const Unicode::String &) + +/** + * Adds a unicode array param. + */ +void ScriptParams::addParam(std::vector & param, const std::string & paramName, bool owned) +{ + m_params.push_back(Param()); + Param &p = m_params.back(); + p.m_type = Param::UNICODE_ARRAY; + p.m_param.uaParam = ¶m; + p.m_name = paramName; + p.m_owned = owned; +} // ScriptParams::addParam(std::vector &) + +/** + * Adds a location param. + */ +void ScriptParams::addParam(const Vector & param, const std::string & paramName, bool owned) +{ + m_params.push_back(Param()); + Param &p = m_params.back(); + p.m_type = Param::LOCATION; + p.m_param.lParam = ¶m; + p.m_name = paramName; + p.m_owned = owned; +} // ScriptParams::addParam(const char *) + +/** + * Adds a location array param. + */ +void ScriptParams::addParam(const std::vector & param, const std::string & paramName, bool owned) +{ + m_params.push_back(Param()); + Param &p = m_params.back(); + p.m_type = Param::LOCATION_ARRAY; + p.m_param.laParam = ¶m; + p.m_name = paramName; + p.m_owned = owned; +} // ScriptParams::addParam(const std::vector &) + +/** + * Adds an object id param. + */ +void ScriptParams::addParam(const NetworkId & param, const std::string & paramName, bool owned) +{ + m_params.push_back(Param()); + Param &p = m_params.back(); + p.m_type = Param::OBJECT_ID; + p.m_param.oidParam = ¶m; + p.m_name = paramName; + p.m_owned = owned; +} // ScriptParams::addParam(NetworkId) + +/** + * Adds an object id array param. + */ +void ScriptParams::addParam(const std::vector & param, const std::string & paramName, bool owned) +{ + m_params.push_back(Param()); + Param &p = m_params.back(); + p.m_type = Param::OBJECT_ID_ARRAY; + p.m_param.oidaParam = ¶m; + p.m_name = paramName; + p.m_owned = owned; +} // ScriptParams::addParam(const std::vector &) + +/** + * Adds a cached object id array param. + */ +void ScriptParams::addParam(const std::vector & param, const std::string & paramName, bool owned) +{ + m_params.push_back(Param()); + Param &p = m_params.back(); + p.m_type = Param::CACHED_OBJECT_ID_ARRAY; + p.m_param.coidaParam = ¶m; + p.m_name = paramName; + p.m_owned = owned; +} // ScriptParams::addParam(const std::vector &) + +/** + * Adds an object id array param. + */ +void ScriptParams::addParam(const std::vector *> & param, const std::string & paramName, bool owned) +{ + m_params.push_back(Param()); + Param &p = m_params.back(); + p.m_type = Param::OBJECT_ID_ARRAY_ARRAY; + p.m_param.oidaaParam = ¶m; + p.m_name = paramName; + p.m_owned = owned; +} // ScriptParams::addParam(const std::vector > &) + +/** + * Adds a string id param. + */ +void ScriptParams::addParam(const StringId & param, const std::string & paramName, bool owned) +{ + m_params.push_back(Param()); + Param &p = m_params.back(); + p.m_type = Param::STRING_ID; + p.m_param.sidParam = ¶m; + p.m_name = paramName; + p.m_owned = owned; +} // ScriptParams::addParam(const StringId &) + +/** + * Adds a string id array param. + */ +void ScriptParams::addParam(const std::vector & param, const std::string & paramName, bool owned) +{ + m_params.push_back(Param()); + Param &p = m_params.back(); + p.m_type = Param::STRING_ID_ARRAY; + p.m_param.sidaParam = ¶m; + p.m_name = paramName; + p.m_owned = owned; +} // ScriptParams::addParam(const std::vector &) + +/** + * Adds an attribute mod param. + */ +void ScriptParams::addParam(const AttribMod::AttribMod & param, const std::string & paramName, bool owned) +{ + m_params.push_back(Param()); + Param &p = m_params.back(); + p.m_type = Param::ATTRIB_MOD; + p.m_param.amParam = ¶m; + p.m_name = paramName; + p.m_owned = owned; +} // ScriptParams::addParam(const AttribMod::AttribMod &) + +/** + * Adds an attribute mod array param. + */ +void ScriptParams::addParam(const std::vector & param, const std::string & paramName, bool owned) +{ + m_params.push_back(Param()); + Param &p = m_params.back(); + p.m_type = Param::ATTRIB_MOD_ARRAY; + p.m_param.amaParam = ¶m; + p.m_name = paramName; + p.m_owned = owned; +} // ScriptParams::addParam(const std::vector &) + +/** + * Adds a mental state mod param. + */ +void ScriptParams::addParam(const ServerObjectTemplate::MentalStateMod & param, const std::string & paramName, bool owned) +{ + m_params.push_back(Param()); + Param &p = m_params.back(); + p.m_type = Param::ATTRIB_MOD; + p.m_param.msmParam = ¶m; + p.m_name = paramName; + p.m_owned = owned; +} // ScriptParams::addParam(const ServerObjectTemplate::MentalStateMod &) + +/** + * Adds a mental state mod array param. + */ +void ScriptParams::addParam(const std::vector & param, const std::string & paramName, bool owned) +{ + m_params.push_back(Param()); + Param &p = m_params.back(); + p.m_type = Param::ATTRIB_MOD_ARRAY; + p.m_param.amsmParam = ¶m; + p.m_name = paramName; + p.m_owned = owned; +} //ScriptParams::addParam(const std::vector &) + +/** + * Adds an array of menu info data + */ +void ScriptParams::addParam(const MenuDataVector & param, const std::string & paramName, bool owned) +{ + m_params.push_back(Param()); + Param &p = m_params.back(); + p.m_type = Param::OBJECT_MENU_INFO; + p.m_param.aomrdParam = ¶m; + p.m_name = paramName; + p.m_owned = owned; +} // ScriptParams::addParam(const MenuDataVector &) + +/** + * Adds a manufacture schematic object param. + */ +void ScriptParams::addParam(const ManufactureObjectInterface & param, const std::string & paramName, bool owned) +{ + m_params.push_back(Param()); + Param &p = m_params.back(); + p.m_type = Param::MANUFACTURE_SCHEMATIC; + p.m_param.msoParam = ¶m; + p.m_name = paramName; + p.m_owned = owned; +} // ScriptParams::addParam(const ManufactureSchematicObject &) + +/** + * Adds a Crafting::IngredientSlot param. + */ +void ScriptParams::addParam(const Crafting::IngredientSlot & param, + const ManufactureObjectInterface & schematic, int amountRequired, + const std::string & appearance, const std::string & paramName, bool owned) +{ + m_params.push_back(Param()); + Param &p = m_params.back(); + p.m_type = Param::INGREDIENT_SLOT; + p.m_param.isParam.slot = ¶m; + p.m_param.isParam.schematic = &schematic; + p.m_param.isParam.amountRequired = amountRequired; + p.m_param.isParam.appearance = &appearance; + p.m_name = paramName; + p.m_owned = owned; +} // ScriptParams::addParam(const Crafting::IngredientSlot &) + +/** + * Adds a ValueDictionary param. + */ +void ScriptParams::addParam(const ValueDictionary & param, const std::string & paramName, bool owned) +{ + m_params.push_back(Param()); + Param &p = m_params.back(); + p.m_type = Param::DICTIONARY; + p.m_param.valueDictionaryParam = ¶m; + p.m_name = paramName; + p.m_owned = owned; +} + +/** + * Adds a ValueDictionary array param. + */ +void ScriptParams::addParam(const std::vector & param, const std::string & paramName, bool owned) +{ + m_params.push_back(Param()); + Param &p = m_params.back(); + p.m_type = Param::DICTIONARY_ARRAY; + p.m_param.valueDictionaryArrayParam = ¶m; + p.m_name = paramName; + p.m_owned = owned; +} + +/** + * Adds an integer array param. + */ +void ScriptParams::addParam(const std::vector & param, const std::string & paramName, bool owned) +{ + m_params.push_back(Param()); + Param &p = m_params.back(); + p.m_type = Param::BYTE_ARRAY; + p.m_param.byteArrayParam = ¶m; + p.m_name = paramName; + p.m_owned = owned; +} // ScriptParams::addParam(const std::vector &) + +/** + * Changes the value of a parameter. + * + * @index the index of the parameter + * @param the new value of the parameter + * + * @return true if the value was changed, false if not + */ +bool ScriptParams::changeParam(int index, int param, bool owned) +{ + if (m_params.size() <= static_cast::size_type>(index)) + return false; + + Param &p = m_params[index]; + if (p.m_type != Param::INT) + return false; + + p.m_param.iParam = param; + p.m_owned = owned; + return true; +} // ScriptParams::changeParam(int, int) + +/** + * Changes the value of a parameter. + * + * @index the index of the parameter + * @param the new value of the parameter + * + * @return true if the value was changed, false if not + */ +bool ScriptParams::changeParam(int index, std::vector & param, bool owned) +{ + if (m_params.size() <= static_cast::size_type>(index)) + return false; + + Param &p = m_params[index]; + if (p.m_type != Param::INT_ARRAY) + return false; + + if (p.m_owned) + delete p.m_param.iaParam; + + p.m_param.iaParam = ¶m; + p.m_owned = owned; + return true; +} // ScriptParams::changeParam(int, const std::vector &) + +/** + * Changes the value of a parameter. + * + * @index the index of the parameter + * @param the new value of the parameter + * + * @return true if the value was changed, false if not + */ +bool ScriptParams::changeParam(int index, float param, bool owned) +{ + if (m_params.size() <= static_cast::size_type>(index)) + return false; + + Param &p = m_params[index]; + if (p.m_type != Param::FLOAT) + return false; + + p.m_param.fParam = param; + p.m_owned = owned; + return true; +} // ScriptParams::changeParam(int, float) + +/** + * Changes the value of a parameter. + * + * @index the index of the parameter + * @param the new value of the parameter + * + * @return true if the value was changed, false if not + */ +bool ScriptParams::changeParam(int index, const StringId & param, bool owned) +{ + if (m_params.size() <= static_cast::size_type>(index)) + return false; + + Param &p = m_params[index]; + if (p.m_type != Param::STRING_ID) + return false; + + if (p.m_param.sidParam == NULL) + return false; + + if (p.m_owned) + delete p.m_param.sidParam; + + p.m_param.sidParam = ¶m; + p.m_owned = owned; + return true; +} // ScriptParams::changeParam(int, const StringId &) + +/** + * Changes the value of a parameter. + * + * @index the index of the parameter + * @param the new value of the parameter + * + * @return true if the value was changed, false if not + */ +bool ScriptParams::changeParam(int index, const MenuDataVector & param, bool owned) +{ + if (m_params.size() <= static_cast::size_type>(index)) + return false; + + Param &p = m_params[index]; + if (p.m_type != Param::OBJECT_MENU_INFO) + return false; + + if (p.m_owned) + delete p.m_param.aomrdParam; + + p.m_param.aomrdParam = ¶m; + p.m_owned = owned; + return true; +} // ScriptParams::changeParam(int, const MenuDataVector &) + +/** + * Changes the value of a parameter. + * + * @index the index of the parameter + * @param the new value of the parameter + * + * @return true if the value was changed, false if not + */ +bool ScriptParams::changeParam(int index, std::vector & param, bool owned) +{ + if (m_params.size() <= static_cast::size_type>(index)) + return false; + + Param &p = m_params[index]; + if (p.m_type != Param::STRING_ARRAY) + return false; + + if (p.m_owned) + { + std::vector::const_iterator s; + for(s = p.m_param.saParam->begin(); s != p.m_param.saParam->end(); ++s) + { + const char * c = (*s); + delete [] const_cast(c); + } + delete p.m_param.saParam; + } + + p.m_param.saParam = ¶m; + p.m_owned = owned; + return true; +} // ScriptParams::changeParam(int, const std::vector &) + +/** + * Changes the value of a parameter. + * + * @index the index of the parameter + * @param the new value of the parameter + * + * @return true if the value was changed, false if not + */ +bool ScriptParams::changeParam(int index, std::vector & param, bool owned) +{ + if (m_params.size() <= static_cast::size_type>(index)) + return false; + + Param &p = m_params[index]; + if (p.m_type != Param::UNICODE_ARRAY) + return false; + + if (p.m_owned) + { + std::vector::const_iterator s; + for(s = p.m_param.uaParam->begin(); s != p.m_param.uaParam->end(); ++s) + { + const Unicode::String * c = (*s); + delete const_cast(c); + } + delete p.m_param.uaParam; + } + + p.m_param.uaParam = ¶m; + p.m_owned = owned; + return true; +} // ScriptParams::changeParam(int, const std::vector &) + +/** + * Changes the value of a parameter. + * + * @index the index of the parameter + * @param the new value of the parameter + * + * @return true if the value was changed, false if not + */ +bool ScriptParams::changeParam(int index, std::vector & param, bool owned) +{ + if (m_params.size() <= static_cast::size_type>(index)) + return false; + + Param &p = m_params[index]; + if (p.m_type != Param::BYTE_ARRAY) + return false; + + if (p.m_owned) + delete p.m_param.byteArrayParam; + + p.m_param.byteArrayParam = ¶m; + p.m_owned = owned; + return true; +} // ScriptParams::changeParam(int, const std::vector &) + +//----------------------------------------------------------------------- + +namespace Archive { + + +//----------------------------------------------------------------------- + +void put(ByteStream & target, const ScriptParams & source) +{ + Archive::put(target, source.getParams()); +} + +//----------------------------------------------------------------------- + +void get(ReadIterator & source, ScriptParams & target) +{ + Archive::get(source, target.getParams()); +} + +//----------------------------------------------------------------------- + +}//namespace Archive + diff --git a/engine/server/library/serverScript/src/shared/ScriptParameters.h b/engine/server/library/serverScript/src/shared/ScriptParameters.h new file mode 100644 index 00000000..dabb3269 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/ScriptParameters.h @@ -0,0 +1,409 @@ +//======================================================================== +// +// ScriptParams.h - varargs substitute for passing params to scripts. +// +// copyright 2001 Sony Online Entertainment +// +//======================================================================== + +#ifndef _INCLUDED_ScriptParams_H +#define _INCLUDED_ScriptParams_H + +#include "serverGame/ServerObjectTemplate.h" +#include "sharedFoundation/NetworkId.h" +#include "sharedObject/CachedNetworkId.h" + +class ValueDictionary; +struct ObjectMenuRequestData; +class ManufactureObjectInterface; + +namespace AttribMod +{ + struct AttribMod; +} + +namespace Crafting +{ + struct IngredientSlot; +} + +typedef stdvector::fwd MenuDataVector; + +struct SlotData +{ + const Crafting::IngredientSlot * slot; + const ManufactureObjectInterface * schematic; + int amountRequired; + const std::string * appearance; +}; + +struct Param +{ + enum ParamType + { + NONE, + BOOL, + BOOL_ARRAY, + INT, + INT_ARRAY, + FLOAT, + FLOAT_ARRAY, + STRING, + STRING_ARRAY, + UNICODE, + UNICODE_ARRAY, + OBJECT_ID, + OBJECT_ID_ARRAY, + CACHED_OBJECT_ID_ARRAY, + STRING_ID, + STRING_ID_ARRAY, + ATTRIB_MOD, + ATTRIB_MOD_ARRAY, + MENTAL_STATE_MOD, + MENTAL_STATE_MOD_ARRAY, + OBJECT_MENU_INFO, + MANUFACTURE_SCHEMATIC, + INGREDIENT_SLOT, + LOCATION, + LOCATION_ARRAY, + DICTIONARY, + DICTIONARY_ARRAY, + BYTE_ARRAY, + OBJECT_ID_ARRAY_ARRAY + }; + + ParamType m_type; + bool m_owned; + std::string m_name; + union + { + bool bParam; + const stddeque::fwd * baParam; + int iParam; + const stdvector::fwd * iaParam; + float fParam; + const stdvector::fwd * faParam; + const char * sParam; + stdvector::fwd *saParam; + const Unicode::String * uParam; + stdvector::fwd * uaParam; + const NetworkId * oidParam; + const stdvector::fwd *oidaParam; + const stdvector::fwd *coidaParam; + const stdvector::fwd *>::fwd *oidaaParam; + const StringId * sidParam; + const stdvector::fwd *sidaParam; + const AttribMod::AttribMod * amParam; + const stdvector::fwd * amaParam; + const ServerObjectTemplate::MentalStateMod * msmParam; + const stdvector::fwd * amsmParam; + const MenuDataVector * aomrdParam; + const ManufactureObjectInterface * msoParam; + const Vector * lParam; + const stdvector::fwd * laParam; + SlotData isParam; + const ValueDictionary * valueDictionaryParam; + const stdvector::fwd * valueDictionaryArrayParam; + const stdvector::fwd * byteArrayParam; + + } m_param; +}; +class ScriptParams; +namespace Archive +{ + class ByteStream; + class ReadIterator; + void get(ReadIterator & source, ScriptParams & target); + void put(ByteStream & target, const ScriptParams & source); + void get(ReadIterator & source, stdvector::fwd *>::fwd & target); + void put(ByteStream & target, const stdvector::fwd *>::fwd & source); +} + +class ScriptParams +{ +public: + +public: + + ScriptParams(void); + ~ScriptParams(void); + + void clear(void); + + void addParam(const Unicode::unicode_char_t *, const std::string & paramName = "", bool owned = false); + void addParam(bool param, const std::string & paramName = "", bool owned = false); + void addParam(const stddeque::fwd & param, const std::string & paramName = "", bool owned = false); + void addParam(int param, const std::string & paramName = "", bool owned = false); + void addParam(const stdvector::fwd & param, const std::string & paramName = "", bool owned = false); + void addParam(float param, const std::string & paramName = "", bool owned = false); + void addParam(const stdvector::fwd & param, const std::string & paramName = "", bool owned = false); + void addParam(const char * param, const std::string & paramName = "", bool owned = false); + void addParam(stdvector::fwd & param, const std::string & paramName = "", bool owned = false); + void addParam(const Unicode::String & param, const std::string & paramName = "", bool owned = false); + void addParam(stdvector::fwd & param, const std::string & paramName = "", bool owned = false); + void addParam(const NetworkId & param, const std::string & paramName = "", bool owned = false); + void addParam(const stdvector::fwd & param, const std::string & paramName = "", bool owned = false); + void addParam(const stdvector::fwd & param, const std::string & paramName = "", bool owned = false); + void addParam(const stdvector::fwd *>::fwd & param, const std::string & paramName = "", bool owned = false); + void addParam(const StringId & param, const std::string & paramName = "", bool owned = false); + void addParam(const stdvector::fwd & param, const std::string & paramName = "", bool owned = false); +// void addParam(SlotData param); +// void addParam(const std::vector & param); + void addParam(const AttribMod::AttribMod & param, const std::string & paramName = "", bool owned = false); + void addParam(const stdvector::fwd & param, const std::string & paramName = "", bool owned = false); + void addParam(const ServerObjectTemplate::MentalStateMod & param, const std::string & paramName = "", bool owned = false); + void addParam(const stdvector::fwd & param, const std::string & paramName = "", bool owned = false); + void addParam(const ManufactureObjectInterface & param, const std::string & paramName = "", bool owned = false); + void addParam(const Crafting::IngredientSlot & param, const ManufactureObjectInterface & schematic, int amountRequired, const std::string & appearance, const std::string & paramName = "", bool owned = false); + void addParam(const Vector &location, const std::string ¶mName = "", bool owned = false); + void addParam(const stdvector::fwd &location, const std::string ¶mName = "", bool owned = false); + void addParam(const ValueDictionary & param, const std::string & paramName = "", bool owned = false); + void addParam(const stdvector::fwd & param, const std::string & paramName = "", bool owned = false); + + void addParam(const MenuDataVector & param, const std::string & paramName = "", bool owned = false); + void addParam(const stdvector::fwd & param, const std::string & paramName = "", bool owned = false); + + bool changeParam(int index, int param, bool owned = false); + bool changeParam(int index, stdvector::fwd & param, bool owned = false); + bool changeParam(int index, float param, bool owned = false); + bool changeParam(int index, const StringId & param, bool owned = false); + bool changeParam(int index, const MenuDataVector & param, bool owned = false); + bool changeParam(int index, stdvector::fwd & param, bool owned = false); + bool changeParam(int index, stdvector::fwd & param, bool owned = false); + bool changeParam(int index, stdvector::fwd & param, bool owned = false); + + stdvector::fwd & getParams(); + const stdvector::fwd & getParams() const; + int getParamCount(void) const; + Param::ParamType getParamType(int index) const; + const std::string & getParamName(int index) const; + bool getBoolParam(int index) const; + const stddeque::fwd & getBoolArrayParam(int index) const; + int getIntParam(int index) const; + const stdvector::fwd & getIntArrayParam(int index) const; + float getFloatParam(int index) const; + const stdvector::fwd & getFloatArrayParam(int index) const; + const char * getStringParam(int index) const; + const stdvector::fwd & getStringArrayParam(int index) const; + const Unicode::String & getUnicodeParam(int index) const; + const stdvector::fwd & getUnicodeArrayParam(int index) const; + const NetworkId & getObjIdParam(int index) const; + const stdvector::fwd & getObjIdArrayParam(int index) const; + const stdvector::fwd & getCachedObjIdArrayParam(int index) const; + const stdvector::fwd *>::fwd & getObjIdArrayArrayParam(int index) const; + const Vector & getLocationParam(int index) const; + const stdvector::fwd & getLocationArrayParam(int index) const; + const StringId & getStringIdParam(int index) const; + const stdvector::fwd & getStringIdArrayParam(int index) const; + const AttribMod::AttribMod & getAttribModParam(int index) const; + const stdvector::fwd & getByteArrayParam(int index) const; + const stdvector::fwd & getAttribModArrayParam(int index) const; + const ServerObjectTemplate::MentalStateMod & getMentalStateModParam(int index) const; + const stdvector::fwd & getMentalStateModArrayParam(int index) const; + const MenuDataVector & getObjectMenuRequestDataArrayParam(int index) const; + const ManufactureObjectInterface & getManufactureSchematicParam(int index) const; + const Crafting::IngredientSlot & getIngredientSlotParam(int index) const; + const ManufactureObjectInterface & getIngredientSlotParamSchematic(int index) const; + int getIngredientSlotParamAmountRequired(int index) const; + const std::string & getIngredientSlotParamAppearance(int index) const; + const ValueDictionary & getValueDictionaryParam(int index) const; + const stdvector::fwd & getValueDictionaryArrayParam(int index) const; + +protected: + friend void Archive::get(ReadIterator & source, ScriptParams & target); + +private: + + stdvector::fwd m_params; +}; + + + +inline void ScriptParams::clear(void) +{ + m_params.clear(); +} // ScriptParams::clear + +inline stdvector::fwd & ScriptParams::getParams() +{ + return m_params; +} + +inline const stdvector::fwd & ScriptParams::getParams() const +{ + return m_params; +} + +inline int ScriptParams::getParamCount(void) const +{ + return m_params.size(); +} // ScriptParams::getParamCount + +inline Param::ParamType ScriptParams::getParamType(int index) const +{ + return m_params[index].m_type; +} // ScriptParams::getParamType + +inline const std::string & ScriptParams::getParamName(int index) const +{ + return m_params[index].m_name; +} + +inline bool ScriptParams::getBoolParam(int index) const +{ + return m_params[index].m_param.bParam; +} // ScriptParams::getBoolParam + +inline const stddeque::fwd & ScriptParams::getBoolArrayParam(int index) const +{ + return *m_params[index].m_param.baParam; +} // ScriptParams::getBoolArrayParam + +inline int ScriptParams::getIntParam(int index) const +{ + return m_params[index].m_param.iParam; +} // ScriptParams::getIntParam + +inline const stdvector::fwd & ScriptParams::getIntArrayParam(int index) const +{ + return *m_params[index].m_param.iaParam; +} // ScriptParams::getIntArrayParam + +inline float ScriptParams::getFloatParam(int index) const +{ + return m_params[index].m_param.fParam; +} // ScriptParams::getFloatParam + +inline const stdvector::fwd & ScriptParams::getFloatArrayParam(int index) const +{ + return *m_params[index].m_param.faParam; +} // ScriptParams::getFloatArrayParam + +inline const char * ScriptParams::getStringParam(int index) const +{ + return m_params[index].m_param.sParam; +} // ScriptParams::getStringParam + +inline const stdvector::fwd & ScriptParams::getStringArrayParam(int index) const +{ + return *m_params[index].m_param.saParam; +} // ScriptParams::getStringArrayParam + +inline const Unicode::String & ScriptParams::getUnicodeParam(int index) const +{ + return *m_params[index].m_param.uParam; +} // ScriptParams::getUnicodeParam + +inline const stdvector::fwd & ScriptParams::getUnicodeArrayParam(int index) const +{ + return *m_params[index].m_param.uaParam; +} // ScriptParams::getUnicodeArrayParam + +inline const Vector &ScriptParams::getLocationParam(int index) const +{ + return *m_params[index].m_param.lParam; +} // ScriptParams::getIntParam + +inline const stdvector::fwd & ScriptParams::getLocationArrayParam(int index) const +{ + return *m_params[index].m_param.laParam; +} // ScriptParams::getIntArrayParam + +inline const NetworkId & ScriptParams::getObjIdParam(int index) const +{ + if (m_params[index].m_param.oidParam != NULL) + return *m_params[index].m_param.oidParam; + return NetworkId::cms_invalid; +} // ScriptParams::getObjIdParam + +inline const stdvector::fwd & ScriptParams::getObjIdArrayParam(int index) const +{ + return *m_params[index].m_param.oidaParam; +} // ScriptParams::getObjIdArrayParam + +inline const stdvector::fwd & ScriptParams::getCachedObjIdArrayParam(int index) const +{ + return *m_params[index].m_param.coidaParam; +} // ScriptParams::getCachedObjIdArrayParam + +inline const stdvector::fwd *>::fwd & ScriptParams::getObjIdArrayArrayParam(int index) const +{ + return *m_params[index].m_param.oidaaParam; +} + +inline const StringId & ScriptParams::getStringIdParam(int index) const +{ + return *m_params[index].m_param.sidParam; +} // ScriptParams::getStringIdParam + +inline const stdvector::fwd & ScriptParams::getStringIdArrayParam(int index) const +{ + return *m_params[index].m_param.sidaParam; +} // ScriptParams::getStringIdArrayParam + +inline const AttribMod::AttribMod & ScriptParams::getAttribModParam(int index) const +{ + return *m_params[index].m_param.amParam; +} // ScriptParams::getAttribModParam + +inline const stdvector::fwd & ScriptParams::getAttribModArrayParam(int index) const +{ + return *m_params[index].m_param.amaParam; +} // ScriptParams::getAttribModArrayParam + +inline const ServerObjectTemplate::MentalStateMod & ScriptParams::getMentalStateModParam(int index) const +{ + return *m_params[index].m_param.msmParam; +} // ScriptParams::getMentalStateModParam + +inline const stdvector::fwd & ScriptParams::getMentalStateModArrayParam(int index) const +{ + return *m_params[index].m_param.amsmParam; +} // ScriptParams::getMentalStateModArrayParam + +inline const MenuDataVector & ScriptParams::getObjectMenuRequestDataArrayParam(int index) const +{ + return *m_params[index].m_param.aomrdParam; +} + +inline const ManufactureObjectInterface & ScriptParams::getManufactureSchematicParam(int index) const +{ + return *m_params[index].m_param.msoParam; +} + +inline const Crafting::IngredientSlot & ScriptParams::getIngredientSlotParam(int index) const +{ + return *m_params[index].m_param.isParam.slot; +} + +inline const ManufactureObjectInterface & ScriptParams::getIngredientSlotParamSchematic(int index) const +{ + return *m_params[index].m_param.isParam.schematic; +} + +inline int ScriptParams::getIngredientSlotParamAmountRequired(int index) const +{ + return m_params[index].m_param.isParam.amountRequired; +} + +inline const std::string & ScriptParams::getIngredientSlotParamAppearance(int index) const +{ + return *m_params[index].m_param.isParam.appearance; +} + +inline const ValueDictionary & ScriptParams::getValueDictionaryParam(int index) const +{ + return *m_params[index].m_param.valueDictionaryParam; +} + +inline const stdvector::fwd & ScriptParams::getValueDictionaryArrayParam(int index) const +{ + return *m_params[index].m_param.valueDictionaryArrayParam; +} + +inline const stdvector::fwd & ScriptParams::getByteArrayParam(int index) const +{ + return *m_params[index].m_param.byteArrayParam; +} // ScriptParams::getIntArrayParam + +#endif // _INCLUDED_ScriptParams_H diff --git a/engine/server/library/serverScript/src/shared/SetupScript.cpp b/engine/server/library/serverScript/src/shared/SetupScript.cpp new file mode 100644 index 00000000..296fc3b0 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/SetupScript.cpp @@ -0,0 +1,51 @@ +// ====================================================================== +// +// SetupScript.cpp +// +// copyright 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverScript/FirstServerScript.h" +#include "serverScript/SetupScript.h" + +#include "serverScript/ConfigServerScript.h" + +// ---------------------------------------------------------------------- +/** + * Install the engine. + * + * The settings in the Data structure will determine which subsystems + * get initialized. + */ + +void SetupScript::install() +{ + // setup the engine configuration + ConfigServerScript::install(); +} + +// ---------------------------------------------------------------------- +/** + * Uninstall the engine. + * + * This routine will properly uninstall the engine componenets that were + * installed by SetupScript::install(). + */ + +void SetupScript::remove(void) +{ +} + +// ---------------------------------------------------------------------- + +void SetupScript::setupDefaultGameData(Data &data) +{ + Zero(data); + + data.version = DATA_VERSION; + data.useRemoteDebugJava = false; +} + +// ---------------------------------------------------------------------- + diff --git a/engine/server/library/serverScript/src/shared/SetupScript.h b/engine/server/library/serverScript/src/shared/SetupScript.h new file mode 100644 index 00000000..853275e7 --- /dev/null +++ b/engine/server/library/serverScript/src/shared/SetupScript.h @@ -0,0 +1,48 @@ +// ====================================================================== +// +// SetupScript.h +// copyright 1998 Bootprint Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_SETUPSCRIPT_H +#define INCLUDED_SETUPSCRIPT_H + +// ====================================================================== + +class SetupScript +{ +private: + + // **** INCREMENT THIS VERSION NUMBER WHENEVER THIS STRUCT CHANAGES **** + + // This enum is private so that a game can't use it directly. If the + // struct changes, the game programmers should be forced to look at the + // changes and update their data and version number manually. + + enum + { + DATA_VERSION = 0 + }; + +public: + + struct Data + { + int version; + + // script data + bool useRemoteDebugJava; // flag to use the jvm for remote debugging + }; + +public: + + static void setupDefaultGameData(Data &data); + + static void install(); + static void remove(void); +}; + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverScript/src/win32/FirstServerScript.cpp b/engine/server/library/serverScript/src/win32/FirstServerScript.cpp new file mode 100644 index 00000000..46a6979d --- /dev/null +++ b/engine/server/library/serverScript/src/win32/FirstServerScript.cpp @@ -0,0 +1,2 @@ + +#include "serverScript/FirstServerScript.h" \ No newline at end of file