1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-05-25 19:17:45 +00:00

gnb implementation, some old bug fixes as well.

This commit is contained in:
collett 2020-04-09 08:13:20 +09:00
parent a2fd6eda58
commit e67afee887
17 changed files with 292 additions and 22 deletions

View file

@ -20,9 +20,9 @@ public:
{ {
} }
void onExecute( Sapphire::World::Action::Action& action ) override void onBeforeBuildEffect( Sapphire::World::Action::Action& action, uint8_t victimCounter, uint8_t validVictimCounter ) override
{ {
if( action.getSourceChara()->getLevel() >= 2 && Math::CalcStats::getRandomNumber0To99() < 20 ) if( validVictimCounter > 0 && action.getSourceChara()->getLevel() >= 2 && Math::CalcStats::getRandomNumber0To99() < 20 )
{ {
auto pEffect = Sapphire::StatusEffect::make_StatusEffect( STATUS_ID_STRAIGHT_SHOT_READY, action.getSourceChara(), action.getSourceChara(), 10000, 3000 ); auto pEffect = Sapphire::StatusEffect::make_StatusEffect( STATUS_ID_STRAIGHT_SHOT_READY, action.getSourceChara(), action.getSourceChara(), 10000, 3000 );
action.getEffectbuilder()->applyStatusEffect( action.getSourceChara(), action.getSourceChara(), pEffect ); action.getEffectbuilder()->applyStatusEffect( action.getSourceChara(), action.getSourceChara(), pEffect );

View file

@ -0,0 +1,32 @@
#include <Script/NativeScriptApi.h>
#include <ScriptObject.h>
#include <Actor/Player.h>
#include <Action/Action.h>
#include <Math/CalcStats.h>
using namespace Sapphire;
class ActionBloodfest16164 :
public ScriptAPI::ActionScript
{
public:
ActionBloodfest16164() :
ScriptAPI::ActionScript( 16164 )
{
}
void onExecute( Sapphire::World::Action::Action& action ) override
{
auto chara = action.getHitChara();
if( chara )
{
auto source = action.getSourceChara();
auto player = source->getAsPlayer();
assert( player );
chara->onActionHostile( source );
player->gaugeGnbSetAmmo( 2 );
}
}
};
EXPOSE_SCRIPT( ActionBloodfest16164 );

View file

@ -0,0 +1,45 @@
#include <Script/NativeScriptApi.h>
#include <ScriptObject.h>
#include <Actor/Player.h>
#include <Action/Action.h>
#include <Math/CalcStats.h>
#include "StatusEffect/StatusEffect.h"
using namespace Sapphire;
using namespace Sapphire::StatusEffect;
const uint16_t STATUS_ID_BRUTAL_SHELL = 1898;
class ActionBrutalShell16139 :
public ScriptAPI::ActionScript
{
public:
ActionBrutalShell16139() :
ScriptAPI::ActionScript( 16139 )
{
}
void onBeforeBuildEffect( Sapphire::World::Action::Action& action, uint8_t victimCounter, uint8_t validVictimCounter ) override
{
if( validVictimCounter > 0 )
{
auto chara = action.getSourceChara();
auto heal = action.calcHealing( 150 );
heal.first = Math::CalcStats::applyHealingReceiveMultiplier( *chara, heal.first );
action.getEffectbuilder()->heal( chara, chara, heal.first, heal.second );
if( chara->getLevel() > 52 )
{
World::Action::StatusEffectEntry effectEntry;
effectEntry.effectType = static_cast< uint32_t >( Common::StatusEffectType::Shield );
effectEntry.effectValue1 = static_cast< int32_t >( heal.first );
auto pNewEffect = Sapphire::StatusEffect::make_StatusEffect( STATUS_ID_BRUTAL_SHELL, action.getSourceChara(), chara, 10000, 3000 );
pNewEffect->replaceEffectEntry( effectEntry );
action.getEffectbuilder()->applyStatusEffect( chara, chara, pNewEffect );
}
}
}
};
EXPOSE_SCRIPT( ActionBrutalShell16139 );

View file

@ -0,0 +1,41 @@
#include <Script/NativeScriptApi.h>
#include <ScriptObject.h>
#include <Actor/Player.h>
#include <Action/Action.h>
#include <Math/CalcStats.h>
#include "StatusEffect/StatusEffect.h"
using namespace Sapphire;
using namespace Sapphire::StatusEffect;
const uint16_t STATUS_ID_READY_TO_RIP = 1842;
const uint16_t STATUS_ID_READY_TO_TEAR = 1843;
const uint16_t STATUS_ID_READY_TO_GOUGE = 1844;
class ActionGnashingFang16146 :
public ScriptAPI::ActionScript
{
public:
ActionGnashingFang16146() :
ScriptAPI::ActionScript( 16146 )
{
}
void onBeforeBuildEffect( Sapphire::World::Action::Action& action, uint8_t victimCounter, uint8_t validVictimCounter ) override
{
if( validVictimCounter > 0 )
{
auto chara = action.getSourceChara();
auto player = chara->getAsPlayer();
assert( player );
player->removeSingleStatusEffectById( STATUS_ID_READY_TO_TEAR, false );
player->removeSingleStatusEffectById( STATUS_ID_READY_TO_GOUGE, false );
auto pNewEffect = Sapphire::StatusEffect::make_StatusEffect( STATUS_ID_READY_TO_RIP, action.getSourceChara(), player, 10000, 3000 );
action.getEffectbuilder()->applyStatusEffect( chara, chara, pNewEffect, 0 );
player->gaugeGnbSetComboStep( 1 );
}
}
};
EXPOSE_SCRIPT( ActionGnashingFang16146 );

View file

@ -0,0 +1,41 @@
#include <Script/NativeScriptApi.h>
#include <ScriptObject.h>
#include <Actor/Player.h>
#include <Action/Action.h>
#include <Math/CalcStats.h>
#include "StatusEffect/StatusEffect.h"
using namespace Sapphire;
using namespace Sapphire::StatusEffect;
const uint16_t STATUS_ID_READY_TO_RIP = 1842;
const uint16_t STATUS_ID_READY_TO_TEAR = 1843;
const uint16_t STATUS_ID_READY_TO_GOUGE = 1844;
class ActionSavageClaw16147 :
public ScriptAPI::ActionScript
{
public:
ActionSavageClaw16147() :
ScriptAPI::ActionScript( 16147 )
{
}
void onBeforeBuildEffect( Sapphire::World::Action::Action& action, uint8_t victimCounter, uint8_t validVictimCounter ) override
{
if( validVictimCounter > 0 )
{
auto chara = action.getSourceChara();
auto player = chara->getAsPlayer();
assert( player );
player->removeSingleStatusEffectById( STATUS_ID_READY_TO_RIP, false );
player->removeSingleStatusEffectById( STATUS_ID_READY_TO_GOUGE, false );
auto pNewEffect = Sapphire::StatusEffect::make_StatusEffect( STATUS_ID_READY_TO_TEAR, action.getSourceChara(), player, 10000, 3000 );
action.getEffectbuilder()->applyStatusEffect( chara, chara, pNewEffect, 0 );
player->gaugeGnbSetComboStep( 2 );
}
}
};
EXPOSE_SCRIPT( ActionSavageClaw16147 );

View file

@ -0,0 +1,41 @@
#include <Script/NativeScriptApi.h>
#include <ScriptObject.h>
#include <Actor/Player.h>
#include <Action/Action.h>
#include <Math/CalcStats.h>
#include "StatusEffect/StatusEffect.h"
using namespace Sapphire;
using namespace Sapphire::StatusEffect;
const uint16_t STATUS_ID_READY_TO_RIP = 1842;
const uint16_t STATUS_ID_READY_TO_TEAR = 1843;
const uint16_t STATUS_ID_READY_TO_GOUGE = 1844;
class ActionWickedTalon16150 :
public ScriptAPI::ActionScript
{
public:
ActionWickedTalon16150() :
ScriptAPI::ActionScript( 16150 )
{
}
void onBeforeBuildEffect( Sapphire::World::Action::Action& action, uint8_t victimCounter, uint8_t validVictimCounter ) override
{
if( validVictimCounter > 0 )
{
auto chara = action.getSourceChara();
auto player = chara->getAsPlayer();
assert( player );
player->removeSingleStatusEffectById( STATUS_ID_READY_TO_RIP, false );
player->removeSingleStatusEffectById( STATUS_ID_READY_TO_TEAR, false );
auto pNewEffect = Sapphire::StatusEffect::make_StatusEffect( STATUS_ID_READY_TO_GOUGE, action.getSourceChara(), player, 10000, 3000 );
action.getEffectbuilder()->applyStatusEffect( chara, chara, pNewEffect, 0 );
player->gaugeGnbSetComboStep( 0 );
}
}
};
EXPOSE_SCRIPT( ActionWickedTalon16150 );

View file

@ -0,0 +1,29 @@
#include <Script/NativeScriptApi.h>
#include <ScriptObject.h>
#include <Actor/Player.h>
#include <Action/Action.h>
#include <Math/CalcStats.h>
using namespace Sapphire;
class ActionProvoke7533 :
public ScriptAPI::ActionScript
{
public:
ActionProvoke7533() :
ScriptAPI::ActionScript( 7533 )
{
}
void onExecute( Sapphire::World::Action::Action& action ) override
{
auto chara = action.getHitChara();
if( chara )
{
chara->onActionHostile( action.getSourceChara() );
// todo: missing flying text
}
}
};
EXPOSE_SCRIPT( ActionProvoke7533 );

View file

@ -486,6 +486,7 @@ void Action::Action::buildEffects()
if( m_disableGenericHandler || !hasValidLutEntry() ) if( m_disableGenericHandler || !hasValidLutEntry() )
{ {
// send any effect packet added by script or an empty one just to play animation for other players // send any effect packet added by script or an empty one just to play animation for other players
scriptMgr.onBeforeBuildEffect( *this, 0, 0 );
m_effectBuilder->buildAndSendPackets(); m_effectBuilder->buildAndSendPackets();
scriptMgr.onAfterBuildEffect( *this ); scriptMgr.onAfterBuildEffect( *this );
return; return;
@ -502,8 +503,7 @@ void Action::Action::buildEffects()
m_lutEntry.bonusEffect, m_lutEntry.bonusRequirement, m_lutEntry.bonusDataUInt32 ); m_lutEntry.bonusEffect, m_lutEntry.bonusRequirement, m_lutEntry.bonusDataUInt32 );
} }
bool isFirstValidVictim = true; uint8_t victimCounter = 0, validVictimCounter = 0;
int victimCounter = 0;
for( auto& actor : m_hitActors ) for( auto& actor : m_hitActors )
{ {
@ -624,10 +624,8 @@ void Action::Action::buildEffects()
} }
} }
if( isFirstValidVictim ) if( validVictimCounter == 0 )
{ {
isFirstValidVictim = false;
if( isCorrectCombo() ) if( isCorrectCombo() )
m_effectBuilder->comboSucceed( actor ); m_effectBuilder->comboSucceed( actor );
@ -665,6 +663,11 @@ void Action::Action::buildEffects()
player->gaugeDrkSetBlood( std::min( 100, player->gaugeDrkGetBlood() + m_lutEntry.bonusDataByte4 ) ); player->gaugeDrkSetBlood( std::min( 100, player->gaugeDrkGetBlood() + m_lutEntry.bonusDataByte4 ) );
break; break;
} }
case Common::ClassJob::Gunbreaker:
{
player->gaugeGnbSetAmmo( std::min( 2, player->gaugeGnbGetAmmo() + m_lutEntry.bonusDataByte4 ) );
break;
}
} }
} }
} }
@ -684,6 +687,7 @@ void Action::Action::buildEffects()
} }
} }
} }
validVictimCounter++;
} }
} }
@ -707,6 +711,7 @@ void Action::Action::buildEffects()
m_effectBuilder->applyStatusEffect( m_pSource, m_pSource, m_lutEntry.selfStatus, m_lutEntry.selfStatusDuration, m_lutEntry.selfStatusParam ); m_effectBuilder->applyStatusEffect( m_pSource, m_pSource, m_lutEntry.selfStatus, m_lutEntry.selfStatusDuration, m_lutEntry.selfStatusParam );
} }
scriptMgr.onBeforeBuildEffect( *this, victimCounter, validVictimCounter );
m_effectBuilder->buildAndSendPackets(); m_effectBuilder->buildAndSendPackets();
scriptMgr.onAfterBuildEffect( *this ); scriptMgr.onAfterBuildEffect( *this );

View file

@ -338,9 +338,8 @@ ActionLut::Lut ActionLut::m_actionLut =
//Stalwart Soul, ストルワートソウル //Stalwart Soul, ストルワートソウル
//has damage: potency 300, combo potency 0, directional potency 0 //has damage: potency 300, combo potency 0, directional potency 0
//applies to self: Darkside, 暗黒, duration 30000, param 0
//has bonus effect: GainMPPercentage, 6 //has bonus effect: GainMPPercentage, 6
{ 16468, { 300, 0, 0, 0, 751, 30000, 0, 0, 0, 0, 4, 0, 6 } }, { 16468, { 300, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 6 } },
//Edge of Shadow, 漆黒の剣 //Edge of Shadow, 漆黒の剣
//has damage: potency 500, combo potency 0, directional potency 0 //has damage: potency 500, combo potency 0, directional potency 0
@ -364,9 +363,7 @@ ActionLut::Lut ActionLut::m_actionLut =
//Brutal Shell, ブルータルシェル //Brutal Shell, ブルータルシェル
//has damage: potency 100, combo potency 300, directional potency 0 //has damage: potency 100, combo potency 300, directional potency 0
//has heal: potency 150 { 16139, { 100, 300, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
//applies to self: Final Word: Escape Prohibition, 確定判決:逃亡禁止命令, duration 10000, param 0
{ 16139, { 100, 300, 0, 150, 2154, 10000, 0, 0, 0, 0, 0, 0, 0 } },
//Camouflage, カモフラージュ //Camouflage, カモフラージュ
//applies to self: Camouflage, カモフラージュ, duration 20000, param 0 //applies to self: Camouflage, カモフラージュ, duration 20000, param 0
@ -391,7 +388,9 @@ ActionLut::Lut ActionLut::m_actionLut =
//Solid Barrel, ソリッドバレル //Solid Barrel, ソリッドバレル
//has damage: potency 100, combo potency 400, directional potency 0 //has damage: potency 100, combo potency 400, directional potency 0
{ 16145, { 100, 400, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, //has bonus effect: GainJobResource, 19202048
//bonus effect requirement: RequireCorrectCombo
{ 16145, { 100, 400, 0, 0, 0, 0, 0, 0, 0, 0, 8, 1, 19202048 } },
//Burst Strike, バーストストライク //Burst Strike, バーストストライク
//has damage: potency 500, combo potency 0, directional potency 0 //has damage: potency 500, combo potency 0, directional potency 0
@ -403,7 +402,9 @@ ActionLut::Lut ActionLut::m_actionLut =
//Demon Slaughter, デーモンスローター //Demon Slaughter, デーモンスローター
//has damage: potency 100, combo potency 250, directional potency 0 //has damage: potency 100, combo potency 250, directional potency 0
{ 16149, { 100, 250, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, //has bonus effect: GainJobResource, 19202048
//bonus effect requirement: RequireCorrectCombo
{ 16149, { 100, 250, 0, 0, 0, 0, 0, 0, 0, 0, 8, 1, 19202048 } },
//Aurora, オーロラ //Aurora, オーロラ
//applies to targets: Aurora, オーロラ, duration 18000, param 0 //applies to targets: Aurora, オーロラ, duration 18000, param 0
@ -424,18 +425,18 @@ ActionLut::Lut ActionLut::m_actionLut =
//Gnashing Fang, ビートファング //Gnashing Fang, ビートファング
//has damage: potency 450, combo potency 0, directional potency 0 //has damage: potency 450, combo potency 0, directional potency 0
//applies to self: Ready to Rip, ジャギュラーリップ実行可, duration 10000, param 0 //comment: status removed need script
{ 16146, { 450, 0, 0, 0, 1842, 10000, 0, 0, 0, 0, 0, 0, 0 } }, { 16146, { 450, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
//Savage Claw, サベッジクロウ //Savage Claw, サベッジクロウ
//has damage: potency 550, combo potency 0, directional potency 0 //has damage: potency 550, combo potency 0, directional potency 0
//applies to self: Ready to Tear, アブドメンテアー実行可, duration 10000, param 0 //comment: status removed need script
{ 16147, { 550, 0, 0, 0, 1843, 10000, 0, 0, 0, 0, 0, 0, 0 } }, { 16147, { 550, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
//Wicked Talon, ウィケッドタロン //Wicked Talon, ウィケッドタロン
//has damage: potency 650, combo potency 0, directional potency 0 //has damage: potency 650, combo potency 0, directional potency 0
//applies to self: Ready to Gouge, アイガウジ実行可, duration 10000, param 0 //comment: status removed need script
{ 16150, { 650, 0, 0, 0, 1844, 10000, 0, 0, 0, 0, 0, 0, 0 } }, { 16150, { 650, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
//Bow Shock, バウショック //Bow Shock, バウショック
//has damage: potency 200, combo potency 0, directional potency 0 //has damage: potency 200, combo potency 0, directional potency 0

View file

@ -190,7 +190,6 @@ void EffectResult::execute()
case Common::ActionEffectType::ApplyStatusEffectTarget: case Common::ActionEffectType::ApplyStatusEffectTarget:
case Common::ActionEffectType::ApplyStatusEffectSource: case Common::ActionEffectType::ApplyStatusEffectSource:
{ {
uint64_t lastTickOverride = 0;
//refreshing old buff //refreshing old buff
for( auto const& entry : m_target->getStatusEffectMap() ) for( auto const& entry : m_target->getStatusEffectMap() )
{ {

View file

@ -576,7 +576,7 @@ void Sapphire::Entity::Chara::removeSingleStatusEffectById( uint32_t id, bool se
{ {
if( effectIt.second->getId() == id ) if( effectIt.second->getId() == id )
{ {
removeStatusEffect( effectIt.first ); removeStatusEffect( effectIt.first, sendStatusList );
break; break;
} }
} }

View file

@ -2434,3 +2434,17 @@ uint8_t Sapphire::Entity::Player::gaugeGnbGetAmmo()
{ {
return m_gauge.gnb.ammo; return m_gauge.gnb.ammo;
} }
void Sapphire::Entity::Player::gaugeGnbSetComboStep( uint8_t value )
{
assert( value >= 0 && value <= 2 );
auto oldValue = gaugeGnbGetComboStep();
m_gauge.gnb.ammoComboStep = value;
if( oldValue != value )
sendActorGauge();
}
uint8_t Sapphire::Entity::Player::gaugeGnbGetComboStep()
{
return m_gauge.gnb.ammoComboStep;
}

View file

@ -1003,6 +1003,8 @@ namespace Sapphire::Entity
void gaugeGnbSetAmmo( uint8_t value ); void gaugeGnbSetAmmo( uint8_t value );
uint8_t gaugeGnbGetAmmo(); uint8_t gaugeGnbGetAmmo();
void gaugeGnbSetComboStep( uint8_t value );
uint8_t gaugeGnbGetComboStep();
////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////

View file

@ -89,6 +89,10 @@ namespace Sapphire::ScriptAPI
{ {
} }
void ActionScript::onBeforeBuildEffect( Sapphire::World::Action::Action& action, uint8_t victimCounter, uint8_t validVictimCounter )
{
}
void ActionScript::onAfterBuildEffect( Sapphire::World::Action::Action& action ) void ActionScript::onAfterBuildEffect( Sapphire::World::Action::Action& action )
{ {
} }

View file

@ -130,6 +130,8 @@ namespace Sapphire::ScriptAPI
virtual void onExecute( Sapphire::World::Action::Action& action ); virtual void onExecute( Sapphire::World::Action::Action& action );
virtual void onBeforeBuildEffect( Sapphire::World::Action::Action& action, uint8_t victimCounter, uint8_t validVictimCounter );
virtual void onAfterBuildEffect( Sapphire::World::Action::Action& action ); virtual void onAfterBuildEffect( Sapphire::World::Action::Action& action );
virtual void onInterrupt( Sapphire::World::Action::Action& action ); virtual void onInterrupt( Sapphire::World::Action::Action& action );

View file

@ -352,6 +352,18 @@ bool Sapphire::Scripting::ScriptMgr::onExecute( World::Action::Action& action )
return false; return false;
} }
bool Sapphire::Scripting::ScriptMgr::onBeforeBuildEffect( World::Action::Action& action, uint8_t victimCounter, uint8_t validVictimCounter )
{
auto script = m_nativeScriptMgr->getScript< Sapphire::ScriptAPI::ActionScript >( action.getId() );
if( script )
{
script->onBeforeBuildEffect( action, victimCounter, validVictimCounter );
return true;
}
return false;
};
bool Sapphire::Scripting::ScriptMgr::onAfterBuildEffect( World::Action::Action& action ) bool Sapphire::Scripting::ScriptMgr::onAfterBuildEffect( World::Action::Action& action )
{ {
auto script = m_nativeScriptMgr->getScript< Sapphire::ScriptAPI::ActionScript >( action.getId() ); auto script = m_nativeScriptMgr->getScript< Sapphire::ScriptAPI::ActionScript >( action.getId() );

View file

@ -79,6 +79,8 @@ namespace Sapphire::Scripting
bool onExecute( World::Action::Action& action ); bool onExecute( World::Action::Action& action );
bool onBeforeBuildEffect( World::Action::Action& action, uint8_t victimCounter, uint8_t validVictimCounter );
bool onAfterBuildEffect( World::Action::Action& action ); bool onAfterBuildEffect( World::Action::Action& action );
bool onStatusReceive( Entity::CharaPtr pActor, uint32_t effectId ); bool onStatusReceive( Entity::CharaPtr pActor, uint32_t effectId );