1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-04-27 14:57:44 +00:00

generally simplify scripting system internals

This commit is contained in:
Adam 2018-01-04 16:14:14 +11:00
parent 6fd9bb1813
commit 7ee0ba330e
5 changed files with 42 additions and 137 deletions

View file

@ -20,11 +20,12 @@ using namespace Core;
enum ScriptType enum ScriptType
{ {
StatusEffect, None,
Action, ScriptedStatusEffect,
Quest, ScriptedAction,
BattleNpc, ScriptedEvent,
Zone ScriptedBattleNpc,
ScriptedZone
}; };
class ScriptObject class ScriptObject
@ -62,7 +63,7 @@ class StatusEffectScript : public ScriptObject
{ {
public: public:
StatusEffectScript( std::string name, uint32_t effectId ) : StatusEffectScript( std::string name, uint32_t effectId ) :
ScriptObject( name, effectId, ScriptType::StatusEffect ) ScriptObject( name, effectId, ScriptType::ScriptedStatusEffect )
{ } { }
virtual void onTick( Entity::Actor& actor ) { } virtual void onTick( Entity::Actor& actor ) { }
@ -80,7 +81,7 @@ class ActionScript : public ScriptObject
{ {
public: public:
ActionScript( std::string name, uint32_t abilityId ) : ActionScript( std::string name, uint32_t abilityId ) :
ScriptObject( name, abilityId, ScriptType::Action ) ScriptObject( name, abilityId, ScriptType::ScriptedAction )
{ } { }
virtual void onStart( Entity::Actor& sourceActor, Entity::Actor& targetActor ) { } virtual void onStart( Entity::Actor& sourceActor, Entity::Actor& targetActor ) { }
@ -93,7 +94,7 @@ class EventScript : public ScriptObject
{ {
public: public:
EventScript( std::string name, uint32_t questId ) : EventScript( std::string name, uint32_t questId ) :
ScriptObject( name, questId, ScriptType::Quest ) ScriptObject( name, questId, ScriptType::ScriptedEvent )
{ } { }
virtual void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) { } virtual void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) { }
@ -111,7 +112,7 @@ class BattleNpcScript : public ScriptObject
{ {
public: public:
BattleNpcScript( std::string name, uint32_t npcId ) : BattleNpcScript( std::string name, uint32_t npcId ) :
ScriptObject( name, npcId, ScriptType::BattleNpc ) ScriptObject( name, npcId, ScriptType::ScriptedBattleNpc )
{ } { }
}; };
@ -119,7 +120,7 @@ class ZoneScript : public ScriptObject
{ {
public: public:
ZoneScript( std::string name, uint32_t zoneId ) : ZoneScript( std::string name, uint32_t zoneId ) :
ScriptObject( name, zoneId, ScriptType::Zone ) ScriptObject( name, zoneId, ScriptType::ScriptedZone )
{ } { }
virtual void onZoneInit() { } virtual void onZoneInit() { }

View file

@ -1,55 +1,7 @@
#include "NativeScriptManager.h" #include "NativeScriptManager.h"
namespace Core { namespace Core {
namespace Scripting { namespace Scripting {
NativeScriptManager::NativeScriptManager( )
{ }
StatusEffectScript* NativeScriptManager::getStatusEffectScript( uint32_t statusId )
{
auto script = m_statusEffectScripts.find( statusId );
if( script == m_statusEffectScripts.end() )
return nullptr;
return script->second;
}
ActionScript* NativeScriptManager::getActionScript( uint32_t actionId )
{
auto script = m_actionScripts.find( actionId );
if( script == m_actionScripts.end() )
return nullptr;
return script->second;
}
EventScript* NativeScriptManager::getEventScript( uint32_t questId )
{
auto script = m_eventScripts.find( questId );
if( script == m_eventScripts.end() )
return nullptr;
return script->second;
}
BattleNpcScript* NativeScriptManager::getBattleNpcScript( uint32_t npcId )
{
auto script = m_battleNpcScripts.find( npcId );
if( script == m_battleNpcScripts.end() )
return nullptr;
return script->second;
}
ZoneScript* NativeScriptManager::getZoneScript( uint32_t zoneId )
{
auto script = m_zoneScripts.find( zoneId );
if( script == m_zoneScripts.end() )
return nullptr;
return script->second;
}
bool NativeScriptManager::loadScript( const std::string& path ) bool NativeScriptManager::loadScript( const std::string& path )
{ {
@ -75,24 +27,7 @@ namespace Core {
auto script = scripts[i]; auto script = scripts[i];
module->scripts.push_back( script ); module->scripts.push_back( script );
switch( script->getType() ) m_scripts[ script->getType() ][ script->getId() ] = script;
{
case ScriptType::StatusEffect:
m_statusEffectScripts[ script->getId() ] = dynamic_cast< StatusEffectScript* >( script );
break;
case ScriptType::Action:
m_actionScripts[ script->getId() ] = dynamic_cast< ActionScript* >( script );
break;
case ScriptType::Quest:
m_eventScripts[ script->getId() ] = dynamic_cast< EventScript* >( script );
break;
case ScriptType::BattleNpc:
m_battleNpcScripts[ script->getId() ] = dynamic_cast< BattleNpcScript* >( script );
break;
case ScriptType::Zone:
m_zoneScripts[ script->getId() ] = dynamic_cast< ZoneScript* >( script );
break;
}
success = true; success = true;
} }
@ -124,27 +59,7 @@ namespace Core {
{ {
for( auto& script : info->scripts ) for( auto& script : info->scripts )
{ {
switch( script->getType() ) m_scripts[ script->getType() ].erase( script->getId() );
{
case ScriptType::StatusEffect:
removeValueFromMap< uint32_t, StatusEffectScript* >( script, m_statusEffectScripts );
break;
case ScriptType::Action:
removeValueFromMap< uint32_t, ActionScript* >( script, m_actionScripts );
break;
case ScriptType::Quest:
removeValueFromMap< uint32_t, EventScript* >( script, m_eventScripts );
break;
case ScriptType::BattleNpc:
removeValueFromMap< uint32_t, BattleNpcScript* >( script, m_battleNpcScripts );
break;
case ScriptType::Zone:
removeValueFromMap< uint32_t, ZoneScript* >( script, m_zoneScripts );
break;
default:
continue;
}
delete script; delete script;
} }

View file

@ -1,5 +1,5 @@
#ifndef NATIVE_SCRIPT_H #ifndef NATIVE_SCRIPT_MGR_H
#define NATIVE_SCRIPT_H #define NATIVE_SCRIPT_MGR_H
#include <unordered_map> #include <unordered_map>
#include <set> #include <set>
@ -19,11 +19,7 @@ namespace Scripting {
class NativeScriptManager class NativeScriptManager
{ {
protected: protected:
std::unordered_map< uint32_t, StatusEffectScript* > m_statusEffectScripts; std::unordered_map< ScriptType, std::unordered_map< uint32_t, ScriptObject* > > m_scripts;
std::unordered_map< uint32_t, ActionScript* > m_actionScripts;
std::unordered_map< uint32_t, EventScript* > m_eventScripts;
std::unordered_map< uint32_t, BattleNpcScript* > m_battleNpcScripts;
std::unordered_map< uint32_t, ZoneScript* > m_zoneScripts;
ScriptLoader m_loader; ScriptLoader m_loader;
@ -32,13 +28,7 @@ namespace Scripting {
bool unloadScript( ScriptInfo* info ); bool unloadScript( ScriptInfo* info );
public: public:
NativeScriptManager( ); NativeScriptManager( ) = default;
StatusEffectScript* getStatusEffectScript( uint32_t statusId );
ActionScript* getActionScript( uint32_t actionId );
EventScript* getEventScript( uint32_t questId );
BattleNpcScript* getBattleNpcScript( uint32_t npcId );
ZoneScript* getZoneScript( uint32_t zoneId );
bool loadScript( const std::string& path ); bool loadScript( const std::string& path );
bool unloadScript( const std::string& name ); bool unloadScript( const std::string& name );
@ -50,19 +40,16 @@ namespace Scripting {
const std::string getModuleExtension(); const std::string getModuleExtension();
bool isModuleLoaded( const std::string& name ); bool isModuleLoaded( const std::string& name );
template< typename key, typename val > // todo: use some template magic (type_traits is_same?) to avoid ScriptType param
bool removeValueFromMap( ScriptObject* ptr, std::unordered_map< key, val >& map ) // not sure if worthwhile given that it adds an extra place where script types need to be managed
template< typename T >
T* getScript( ScriptType type, uint32_t scriptId )
{ {
for( typename std::unordered_map< key, val >::iterator it = map.begin(); it != map.end(); ++it ) auto script = m_scripts[ type ].find( scriptId );
{ if( script == m_scripts[ type ].end() )
if( ptr == static_cast< ScriptObject* >( it->second ) ) return nullptr;
{
map.erase( it );
return true;
}
}
return false; return static_cast< T* >( script->second );
} }
}; };

View file

@ -134,10 +134,11 @@ bool Core::Scripting::ScriptLoader::unloadScript( ModuleHandle handle )
if( it->second->handle == handle ) if( it->second->handle == handle )
{ {
auto info = it->second; auto info = it->second;
m_scriptMap.erase( it );
if( unloadModule( handle ) ) if( unloadModule( handle ) )
{ {
m_scriptMap.erase( it );
// remove cached file // remove cached file
fs::remove( info->cache_path ); fs::remove( info->cache_path );

View file

@ -166,7 +166,7 @@ bool Core::Scripting::ScriptManager::onTalk( Entity::Player& player, uint64_t ac
scriptId = EVENTSCRIPT_AETHERNET_ID; scriptId = EVENTSCRIPT_AETHERNET_ID;
} }
auto script = m_nativeScriptManager->getEventScript( scriptId ); auto script = m_nativeScriptManager->getScript< EventScript >( ScriptType::ScriptedEvent, scriptId );
if( script ) if( script )
{ {
player.sendDebug( "Calling: " + objName + "." + eventName ); player.sendDebug( "Calling: " + objName + "." + eventName );
@ -203,7 +203,7 @@ bool Core::Scripting::ScriptManager::onEnterTerritory( Entity::Player& player, u
player.sendDebug( "Calling: " + objName + "." + eventName + " - " + std::to_string( eventId ) ); player.sendDebug( "Calling: " + objName + "." + eventName + " - " + std::to_string( eventId ) );
auto script = m_nativeScriptManager->getEventScript( eventId ); auto script = m_nativeScriptManager->getScript< EventScript >( ScriptType::ScriptedEvent, eventId );
if( script ) if( script )
{ {
player.eventStart( player.getId(), eventId, Event::Event::EnterTerritory, 0, player.getZoneId() ); player.eventStart( player.getId(), eventId, Event::Event::EnterTerritory, 0, player.getZoneId() );
@ -226,7 +226,7 @@ bool Core::Scripting::ScriptManager::onWithinRange( Entity::Player& player, uint
std::string objName = Event::getEventName( eventId ); std::string objName = Event::getEventName( eventId );
player.sendDebug( "Calling: " + objName + "." + eventName + " - " + std::to_string( eventId ) + " p1: " + std::to_string( param1 ) ); player.sendDebug( "Calling: " + objName + "." + eventName + " - " + std::to_string( eventId ) + " p1: " + std::to_string( param1 ) );
auto script = m_nativeScriptManager->getEventScript( eventId ); auto script = m_nativeScriptManager->getScript< EventScript >( ScriptType::ScriptedEvent, eventId );
if( script ) if( script )
{ {
player.eventStart( player.getId(), eventId, Event::Event::WithinRange, 1, param1 ); player.eventStart( player.getId(), eventId, Event::Event::WithinRange, 1, param1 );
@ -248,7 +248,7 @@ bool Core::Scripting::ScriptManager::onOutsideRange( Entity::Player& player, uin
std::string objName = Event::getEventName( eventId ); std::string objName = Event::getEventName( eventId );
player.sendDebug( "Calling: " + objName + "." + eventName + " - " + std::to_string( eventId ) ); player.sendDebug( "Calling: " + objName + "." + eventName + " - " + std::to_string( eventId ) );
auto script = m_nativeScriptManager->getEventScript( eventId ); auto script = m_nativeScriptManager->getScript< EventScript >( ScriptType::ScriptedEvent, eventId );
if( script ) if( script )
{ {
player.eventStart( player.getId(), eventId, Event::Event::WithinRange, 1, param1 ); player.eventStart( player.getId(), eventId, Event::Event::WithinRange, 1, param1 );
@ -269,7 +269,7 @@ bool Core::Scripting::ScriptManager::onEmote( Entity::Player& player, uint64_t a
std::string eventName = "onEmote"; std::string eventName = "onEmote";
std::string objName = Event::getEventName( eventId ); std::string objName = Event::getEventName( eventId );
auto script = m_nativeScriptManager->getEventScript( eventId ); auto script = m_nativeScriptManager->getScript< EventScript >( ScriptType::ScriptedEvent, eventId );
if( script ) if( script )
{ {
player.sendDebug( "Calling: " + objName + "." + eventName ); player.sendDebug( "Calling: " + objName + "." + eventName );
@ -346,7 +346,7 @@ bool Core::Scripting::ScriptManager::onEventHandlerReturn( Entity::Player& playe
bool Core::Scripting::ScriptManager::onEventHandlerTradeReturn( Entity::Player& player, uint32_t eventId, bool Core::Scripting::ScriptManager::onEventHandlerTradeReturn( Entity::Player& player, uint32_t eventId,
uint16_t subEvent, uint16_t param, uint32_t catalogId ) uint16_t subEvent, uint16_t param, uint32_t catalogId )
{ {
auto script = m_nativeScriptManager->getEventScript( eventId ); auto script = m_nativeScriptManager->getScript< EventScript >( ScriptType::ScriptedEvent, eventId );
if( script ) if( script )
{ {
script->onEventHandlerTradeReturn( player, eventId, subEvent, param, catalogId ); script->onEventHandlerTradeReturn( player, eventId, subEvent, param, catalogId );
@ -364,7 +364,7 @@ bool Core::Scripting::ScriptManager::onEventItem( Entity::Player& player, uint32
std::string objName = Event::getEventName( eventId ); std::string objName = Event::getEventName( eventId );
player.sendDebug( "Calling: " + objName + "." + eventName + " - " + std::to_string( eventId ) ); player.sendDebug( "Calling: " + objName + "." + eventName + " - " + std::to_string( eventId ) );
auto script = m_nativeScriptManager->getEventScript( eventId ); auto script = m_nativeScriptManager->getScript< EventScript >( ScriptType::ScriptedEvent, eventId );
if( script ) if( script )
{ {
player.eventStart( targetId, eventId, Event::Event::Item, 0, 0 ); player.eventStart( targetId, eventId, Event::Event::Item, 0, 0 );
@ -391,7 +391,7 @@ bool Core::Scripting::ScriptManager::onMobKill( Entity::Player& player, uint16_t
uint16_t questId = activeQuests->c.questId; uint16_t questId = activeQuests->c.questId;
auto script = m_nativeScriptManager->getEventScript( questId ); auto script = m_nativeScriptManager->getScript< EventScript >( ScriptType::ScriptedEvent, questId );
if( script ) if( script )
{ {
std::string objName = Event::getEventName( 0x00010000 | questId ); std::string objName = Event::getEventName( 0x00010000 | questId );
@ -407,7 +407,7 @@ bool Core::Scripting::ScriptManager::onMobKill( Entity::Player& player, uint16_t
bool Core::Scripting::ScriptManager::onCastFinish( Entity::Player& player, Entity::ActorPtr pTarget, uint32_t actionId ) bool Core::Scripting::ScriptManager::onCastFinish( Entity::Player& player, Entity::ActorPtr pTarget, uint32_t actionId )
{ {
auto script = m_nativeScriptManager->getActionScript( actionId ); auto script = m_nativeScriptManager->getScript< ActionScript >( ScriptType::ScriptedAction, actionId );
if( script ) if( script )
script->onCastFinish( player, *pTarget ); script->onCastFinish( player, *pTarget );
@ -417,7 +417,8 @@ bool Core::Scripting::ScriptManager::onCastFinish( Entity::Player& player, Entit
bool Core::Scripting::ScriptManager::onStatusReceive( Entity::ActorPtr pActor, uint32_t effectId ) bool Core::Scripting::ScriptManager::onStatusReceive( Entity::ActorPtr pActor, uint32_t effectId )
{ {
auto script = m_nativeScriptManager->getStatusEffectScript( effectId ); auto script = m_nativeScriptManager->getScript< StatusEffectScript >( ScriptType::ScriptedStatusEffect, effectId );
if( script ) if( script )
{ {
if( pActor->isPlayer() ) if( pActor->isPlayer() )
@ -433,7 +434,7 @@ bool Core::Scripting::ScriptManager::onStatusReceive( Entity::ActorPtr pActor, u
bool Core::Scripting::ScriptManager::onStatusTick( Entity::ActorPtr pActor, Core::StatusEffect::StatusEffect& effect ) bool Core::Scripting::ScriptManager::onStatusTick( Entity::ActorPtr pActor, Core::StatusEffect::StatusEffect& effect )
{ {
auto script = m_nativeScriptManager->getStatusEffectScript( effect.getId() ); auto script = m_nativeScriptManager->getScript< StatusEffectScript >( ScriptType::ScriptedStatusEffect, effect.getId() );
if( script ) if( script )
{ {
if( pActor->isPlayer() ) if( pActor->isPlayer() )
@ -449,7 +450,7 @@ bool Core::Scripting::ScriptManager::onStatusTick( Entity::ActorPtr pActor, Core
bool Core::Scripting::ScriptManager::onStatusTimeOut( Entity::ActorPtr pActor, uint32_t effectId ) bool Core::Scripting::ScriptManager::onStatusTimeOut( Entity::ActorPtr pActor, uint32_t effectId )
{ {
auto script = m_nativeScriptManager->getStatusEffectScript( effectId ); auto script = m_nativeScriptManager->getScript< StatusEffectScript >( ScriptType::ScriptedStatusEffect, effectId );
if( script ) if( script )
{ {
if( pActor->isPlayer() ) if( pActor->isPlayer() )
@ -465,7 +466,7 @@ bool Core::Scripting::ScriptManager::onStatusTimeOut( Entity::ActorPtr pActor, u
bool Core::Scripting::ScriptManager::onZoneInit( ZonePtr pZone ) bool Core::Scripting::ScriptManager::onZoneInit( ZonePtr pZone )
{ {
auto script = m_nativeScriptManager->getZoneScript( pZone->getId() ); auto script = m_nativeScriptManager->getScript< ZoneScript >( ScriptType::ScriptedZone, pZone->getId() );
if( script ) if( script )
{ {
script->onZoneInit(); script->onZoneInit();