mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-04-25 14:07:46 +00:00
ActionCollision implementation work; More definitions for actionInfo; Fix compiler warnings;
This commit is contained in:
parent
66c5f4be45
commit
15e1c32f8b
9 changed files with 117 additions and 92 deletions
|
@ -345,7 +345,7 @@ bool Core::Data::ExdData::loadActionInfo()
|
||||||
uint8_t points_type = getField< uint8_t >( fields, 30 ); // 30
|
uint8_t points_type = getField< uint8_t >( fields, 30 ); // 30
|
||||||
uint16_t points_cost = getField< uint16_t >( fields, 31 ); // 31
|
uint16_t points_cost = getField< uint16_t >( fields, 31 ); // 31
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
bool is_instant = getField< bool >( fields, 35 ); // 35
|
bool is_instant = getField< bool >( fields, 35 ); // 35
|
||||||
uint16_t cast_time = getField< uint16_t >( fields, 36 ); // 36
|
uint16_t cast_time = getField< uint16_t >( fields, 36 ); // 36
|
||||||
uint16_t recast_time = getField< uint16_t >( fields, 37 ); // 37
|
uint16_t recast_time = getField< uint16_t >( fields, 37 ); // 37
|
||||||
|
@ -353,22 +353,12 @@ bool Core::Data::ExdData::loadActionInfo()
|
||||||
int8_t model = getField< int8_t >( fields, 39 ); // 39
|
int8_t model = getField< int8_t >( fields, 39 ); // 39
|
||||||
uint8_t aspect = getField< uint8_t >( fields, 40 ); // 40
|
uint8_t aspect = getField< uint8_t >( fields, 40 ); // 40
|
||||||
|
|
||||||
|
uint16_t toggle_status_id = getField< uint16_t >( fields, 42 ); // 42
|
||||||
|
bool affects_position = getField< bool >( fields, 47 ); // 47
|
||||||
|
|
||||||
info->id = id;
|
info->id = id;
|
||||||
info->name = name;
|
info->name = name;
|
||||||
info->category = category;
|
info->category = category;
|
||||||
=======
|
|
||||||
bool is_instant = getField< bool >( fields, 35 ); // 35
|
|
||||||
uint16_t cast_time = getField< uint16_t >( fields, 36 ); // 36
|
|
||||||
uint16_t recast_time = getField< uint16_t >( fields, 37 ); // 37
|
|
||||||
|
|
||||||
int8_t model = getField< int8_t >( fields, 39 ); // 39: Action model
|
|
||||||
uint8_t aspect = getField< uint8_t >( fields, 40 ); // 40: Action aspect
|
|
||||||
|
|
||||||
info->id = id;
|
|
||||||
info->name = name;
|
|
||||||
info->category = category;
|
|
||||||
>>>>>>> 08f4c7651fafdaf8f4d98868a94ab4688eb71379
|
|
||||||
|
|
||||||
info->class_job = class_job;
|
info->class_job = class_job;
|
||||||
info->unlock_level = unlock_level;
|
info->unlock_level = unlock_level;
|
||||||
|
@ -382,6 +372,7 @@ bool Core::Data::ExdData::loadActionInfo()
|
||||||
|
|
||||||
info->is_ground_aoe = is_ground_aoe;
|
info->is_ground_aoe = is_ground_aoe;
|
||||||
|
|
||||||
|
|
||||||
info->aoe_type = aoe_type;
|
info->aoe_type = aoe_type;
|
||||||
info->aoe_range = aoe_range;
|
info->aoe_range = aoe_range;
|
||||||
info->aoe_width = aoe_width;
|
info->aoe_width = aoe_width;
|
||||||
|
@ -396,6 +387,12 @@ bool Core::Data::ExdData::loadActionInfo()
|
||||||
info->model = model;
|
info->model = model;
|
||||||
info->aspect = aspect;
|
info->aspect = aspect;
|
||||||
|
|
||||||
|
info->toggle_status_id = toggle_status_id;
|
||||||
|
info->affects_position = affects_position;
|
||||||
|
|
||||||
|
// If action type is SingleTarget with an AoE radius set, or if action type isn't SingleTarget
|
||||||
|
info->is_aoe = ( info->aoe_type == 1 && info->aoe_width != 0 ) || ( info->aoe_type != 1 );
|
||||||
|
|
||||||
m_actionInfoMap.emplace( std::make_pair( info->id, info ) );
|
m_actionInfoMap.emplace( std::make_pair( info->id, info ) );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -250,6 +250,12 @@ namespace Core {
|
||||||
|
|
||||||
int8_t model; // 39
|
int8_t model; // 39
|
||||||
uint8_t aspect; // 40
|
uint8_t aspect; // 40
|
||||||
|
|
||||||
|
uint16_t toggle_status_id; // 42
|
||||||
|
|
||||||
|
bool affects_position; // 47
|
||||||
|
|
||||||
|
bool is_aoe; // Internal only
|
||||||
};
|
};
|
||||||
|
|
||||||
struct EventItemInfo
|
struct EventItemInfo
|
||||||
|
|
|
@ -11,46 +11,46 @@
|
||||||
using namespace Core::Entity;
|
using namespace Core::Entity;
|
||||||
using namespace Core::Common;
|
using namespace Core::Common;
|
||||||
|
|
||||||
// todo: add filters for allies, enemies only etc
|
// todo: add AoE actor limits (16, 32)
|
||||||
|
|
||||||
bool ActionCollision::isActorCollisionValid( ActorPtr actorPtr, AoeFilter aoeFilter )
|
bool ActionCollision::isActorApplicable( ActorPtr actorPtr, TargetFilter targetFilter )
|
||||||
{
|
{
|
||||||
bool collisionApplicable = false;
|
bool actorApplicable = false;
|
||||||
switch ( aoeFilter )
|
switch ( targetFilter )
|
||||||
{
|
{
|
||||||
case AoeFilter::All:
|
case TargetFilter::All:
|
||||||
{
|
{
|
||||||
collisionApplicable = true;
|
actorApplicable = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AoeFilter::Players:
|
case TargetFilter::Players:
|
||||||
{
|
{
|
||||||
collisionApplicable = actorPtr->isPlayer();
|
actorApplicable = actorPtr->isPlayer();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AoeFilter::Allies:
|
case TargetFilter::Allies:
|
||||||
{
|
{
|
||||||
// todo: implement ally NPCs
|
// todo: implement ally NPCs
|
||||||
collisionApplicable = !actorPtr->isMob();
|
actorApplicable = !actorPtr->isMob();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AoeFilter::Party:
|
case TargetFilter::Party:
|
||||||
{
|
{
|
||||||
// todo: implement party
|
// todo: implement party
|
||||||
collisionApplicable = actorPtr->isPlayer();
|
actorApplicable = actorPtr->isPlayer();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AoeFilter::Enemies:
|
case TargetFilter::Enemies:
|
||||||
{
|
{
|
||||||
collisionApplicable = actorPtr->isMob();
|
actorApplicable = actorPtr->isMob();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ( collisionApplicable && actorPtr->isAlive() );
|
return ( actorApplicable && actorPtr->isAlive() );
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set< Core::Entity::ActorPtr > ActionCollision::getActorsHitFromAction( FFXIVARR_POSITION3 aoePosition, std::set< ActorPtr > actorsInRange, boost::shared_ptr< Core::Data::ActionInfo > actionInfo, AoeFilter aoeFilter )
|
std::set< Core::Entity::ActorPtr > ActionCollision::getActorsHitFromAction( FFXIVARR_POSITION3 aoePosition, std::set< ActorPtr > actorsInRange, boost::shared_ptr< Core::Data::ActionInfo > actionInfo, TargetFilter targetFilter )
|
||||||
{
|
{
|
||||||
std::set< ActorPtr > actorsCollided;
|
std::set< ActorPtr > actorsCollided;
|
||||||
|
|
||||||
|
@ -61,15 +61,14 @@ std::set< Core::Entity::ActorPtr > ActionCollision::getActorsHitFromAction( FFXI
|
||||||
{
|
{
|
||||||
// This is actually needed. There is "splash damage" in actions marked as single target.
|
// This is actually needed. There is "splash damage" in actions marked as single target.
|
||||||
// Notice how we're using aoe_width. How collision works for SingleTarget is unknown as of now.
|
// Notice how we're using aoe_width. How collision works for SingleTarget is unknown as of now.
|
||||||
// TODO: Isn't it possible to stack 2 players in the same spot and glitch the action collision this way? Investigate
|
|
||||||
for ( auto pActor : actorsInRange )
|
for ( auto pActor : actorsInRange )
|
||||||
{
|
{
|
||||||
// Make sure actor exists. If it doesn't we done goofed.
|
// Make sure actor exists. If it doesn't we done goofed.
|
||||||
assert( pActor );
|
assert( pActor );
|
||||||
|
|
||||||
// Don't bother wasting on collision if actor doesn't apply for it
|
// Don't bother wasting on collision if actor doesn't apply for it
|
||||||
if ( !isActorCollisionValid( pActor, aoeFilter ) )
|
if ( !isActorApplicable( pActor, targetFilter ) )
|
||||||
break;
|
continue;
|
||||||
|
|
||||||
// Test our collision from actor with the area generated by the action from the AoE data
|
// Test our collision from actor with the area generated by the action from the AoE data
|
||||||
if ( radiusCollision( pActor->getPos(), aoePosition, actionInfo->aoe_width ) )
|
if ( radiusCollision( pActor->getPos(), aoePosition, actionInfo->aoe_width ) )
|
||||||
|
@ -86,8 +85,8 @@ std::set< Core::Entity::ActorPtr > ActionCollision::getActorsHitFromAction( FFXI
|
||||||
{
|
{
|
||||||
assert( pActor );
|
assert( pActor );
|
||||||
|
|
||||||
if ( !isActorCollisionValid( pActor, aoeFilter ) )
|
if ( !isActorApplicable( pActor, targetFilter ) )
|
||||||
break;
|
continue;
|
||||||
|
|
||||||
if ( radiusCollision( pActor->getPos(), aoePosition, actionInfo->aoe_range ) )
|
if ( radiusCollision( pActor->getPos(), aoePosition, actionInfo->aoe_range ) )
|
||||||
{
|
{
|
||||||
|
@ -102,8 +101,8 @@ std::set< Core::Entity::ActorPtr > ActionCollision::getActorsHitFromAction( FFXI
|
||||||
{
|
{
|
||||||
assert( pActor );
|
assert( pActor );
|
||||||
|
|
||||||
if ( !isActorCollisionValid( pActor, aoeFilter ) )
|
if ( !isActorApplicable( pActor, targetFilter ) )
|
||||||
break;
|
continue;
|
||||||
|
|
||||||
if ( boxCollision( pActor->getPos(), aoePosition, actionInfo->aoe_width, actionInfo->aoe_range ) )
|
if ( boxCollision( pActor->getPos(), aoePosition, actionInfo->aoe_width, actionInfo->aoe_range ) )
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
namespace Core {
|
namespace Core {
|
||||||
namespace Entity {
|
namespace Entity {
|
||||||
|
|
||||||
enum class AoeFilter
|
enum class TargetFilter
|
||||||
{
|
{
|
||||||
All, // All actors in the AoE are applicable for collision
|
All, // All actors in the AoE are applicable for collision
|
||||||
Players, // Only players
|
Players, // Only players
|
||||||
|
@ -22,8 +22,8 @@ namespace Core {
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static bool isActorCollisionValid( ActorPtr actorPtr, AoeFilter aoeFilter );
|
static bool isActorApplicable( ActorPtr actorPtr, TargetFilter targetFilter );
|
||||||
static std::set< ActorPtr > getActorsHitFromAction( Common::FFXIVARR_POSITION3 aoePosition, std::set< ActorPtr > actorsInRange, boost::shared_ptr< Data::ActionInfo > actionInfo, AoeFilter aoeFilter );
|
static std::set< ActorPtr > getActorsHitFromAction( Common::FFXIVARR_POSITION3 aoePosition, std::set< ActorPtr > actorsInRange, boost::shared_ptr< Data::ActionInfo > actionInfo, TargetFilter targetFilter );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool radiusCollision( Common::FFXIVARR_POSITION3 actorPosition, Common::FFXIVARR_POSITION3 aoePosition, uint16_t radius );
|
static bool radiusCollision( Common::FFXIVARR_POSITION3 actorPosition, Common::FFXIVARR_POSITION3 aoePosition, uint16_t radius );
|
||||||
|
|
|
@ -639,53 +639,66 @@ void Core::Entity::Actor::handleScriptSkill( uint32_t type, uint32_t actionId, u
|
||||||
getAsPlayer()->sendDebug( "Handle script skill type: " + std::to_string( type ) );
|
getAsPlayer()->sendDebug( "Handle script skill type: " + std::to_string( type ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
auto actionInfoPtr = g_exdData.getActionInfo( actionId );
|
auto actionInfoPtr = g_exdData.getActionInfo( actionId );
|
||||||
|
|
||||||
|
// Todo: Effect packet generator. 90% of this is basically setting params and it's basically unreadable.
|
||||||
// Prepare packet. This is seemingly common for all packets in the action handler.
|
// Prepare packet. This is seemingly common for all packets in the action handler.
|
||||||
|
|
||||||
GamePacketNew< FFXIVIpcEffect, ServerZoneIpcType > effectPacket( getId() );
|
GamePacketNew< FFXIVIpcEffect, ServerZoneIpcType > effectPacket( getId() );
|
||||||
effectPacket.data().targetId = pTarget.getId();
|
effectPacket.data().targetId = pTarget.getId();
|
||||||
effectPacket.data().actionAnimationId = actionId;
|
effectPacket.data().actionAnimationId = actionId;
|
||||||
|
effectPacket.data().unknown_62 = 1; // Affects displaying action name next to number in floating text
|
||||||
effectPacket.data().unknown_2 = 1; // This seems to have an effect on the "double-cast finish" animation
|
effectPacket.data().unknown_2 = 1; // This seems to have an effect on the "double-cast finish" animation
|
||||||
// effectPacket.data().unknown_3 = 1;
|
|
||||||
effectPacket.data().actionTextId = actionId;
|
effectPacket.data().actionTextId = actionId;
|
||||||
effectPacket.data().numEffects = 1;
|
effectPacket.data().numEffects = 1;
|
||||||
effectPacket.data().rotation = Math::Util::floatToUInt16Rot( getRotation() );
|
effectPacket.data().rotation = Math::Util::floatToUInt16Rot( getRotation() );
|
||||||
effectPacket.data().effectTarget = pTarget.getId();
|
effectPacket.data().effectTarget = pTarget.getId();
|
||||||
effectPacket.data().effects[0].value = 0;
|
|
||||||
effectPacket.data().effects[0].effectType = ActionEffectType::Damage;
|
|
||||||
effectPacket.data().effects[0].hitSeverity = ActionHitSeverityType::NormalDamage;
|
|
||||||
effectPacket.data().effects[0].unknown_3 = 7;
|
|
||||||
|
|
||||||
|
// Todo: for each actor, calculate how much damage the calculated value should deal to them - 2-step damage calc. we only have 1-step
|
||||||
switch ( type )
|
switch ( type )
|
||||||
{
|
{
|
||||||
|
|
||||||
case ActionEffectType::Damage:
|
case ActionEffectType::Damage:
|
||||||
{
|
{
|
||||||
|
effectPacket.data().effects[0].value = param1;
|
||||||
effectPacket.data().effects[0].value = static_cast< int16_t >( param1 );
|
|
||||||
effectPacket.data().effects[0].effectType = ActionEffectType::Damage;
|
effectPacket.data().effects[0].effectType = ActionEffectType::Damage;
|
||||||
effectPacket.data().effects[0].hitSeverity = ActionHitSeverityType::NormalDamage;
|
effectPacket.data().effects[0].hitSeverity = ActionHitSeverityType::NormalDamage;
|
||||||
|
effectPacket.data().effects[0].unknown_3 = 7;
|
||||||
|
|
||||||
std::set< ActorPtr > actorsCollided = ActionCollision::getActorsHitFromAction( pTarget.getPos(), getInRangeActors( true ), actionInfoPtr, AoeFilter::Enemies );
|
if ( !actionInfoPtr->is_aoe )
|
||||||
|
|
||||||
for ( auto pHitActor : actorsCollided )
|
|
||||||
{
|
{
|
||||||
effectPacket.data().targetId = pHitActor->getId();
|
// If action on this specific target is valid...
|
||||||
effectPacket.data().unknown_1 = 1; // the magic trick for getting it to work
|
if ( isPlayer() && !ActionCollision::isActorApplicable( pTarget.shared_from_this(), TargetFilter::Enemies ) )
|
||||||
effectPacket.data().unknown_5 = 1;
|
break;
|
||||||
effectPacket.data().unknown_8 = 1;
|
|
||||||
effectPacket.data().actionTextId = 0;
|
|
||||||
effectPacket.data().effectTarget = pHitActor->getId();
|
|
||||||
effectPacket.data().effects[0].value = param1 + ( rand() % 15 );
|
|
||||||
|
|
||||||
pHitActor->sendToInRangeSet( effectPacket, true ); // todo: send to range of what? ourselves? when mob script hits this is going to be lacking
|
pTarget.takeDamage( static_cast< uint32_t >( param1 ) );
|
||||||
pHitActor->takeDamage( static_cast< uint32_t >( param1 ) );
|
pTarget.onActionHostile( shared_from_this() );
|
||||||
pHitActor->onActionHostile( shared_from_this() );
|
sendToInRangeSet( effectPacket, true );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
if ( isPlayer() )
|
std::set< ActorPtr > actorsCollided = ActionCollision::getActorsHitFromAction( pTarget.getPos(), getInRangeActors( true ), actionInfoPtr, TargetFilter::Enemies );
|
||||||
getAsPlayer()->sendDebug( "AoE hit actor " + pHitActor->getName() );
|
|
||||||
|
for ( auto pHitActor : actorsCollided )
|
||||||
|
{
|
||||||
|
effectPacket.data().targetId = pHitActor->getId();
|
||||||
|
effectPacket.data().effectTarget = pHitActor->getId();
|
||||||
|
|
||||||
|
sendToInRangeSet( effectPacket, true ); // todo: send to range of what? ourselves? when mob script hits this is going to be lacking
|
||||||
|
pHitActor->takeDamage( static_cast< uint32_t >( param1 ) );
|
||||||
|
pHitActor->onActionHostile( shared_from_this() );
|
||||||
|
|
||||||
|
// Debug
|
||||||
|
if ( isPlayer() )
|
||||||
|
{
|
||||||
|
if ( pHitActor->isPlayer() ) {
|
||||||
|
getAsPlayer()->sendDebug( "AoE hit actor " + std::to_string( pHitActor->getId() ) + " (" + pHitActor->getName() + ")" );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
getAsPlayer()->sendDebug( "AoE hit actor " + std::to_string( pHitActor->getId() ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -699,29 +712,39 @@ void Core::Entity::Actor::handleScriptSkill( uint32_t type, uint32_t actionId, u
|
||||||
effectPacket.data().effects[0].effectType = ActionEffectType::Heal;
|
effectPacket.data().effects[0].effectType = ActionEffectType::Heal;
|
||||||
effectPacket.data().effects[0].hitSeverity = ActionHitSeverityType::NormalHeal;
|
effectPacket.data().effects[0].hitSeverity = ActionHitSeverityType::NormalHeal;
|
||||||
|
|
||||||
sendToInRangeSet( effectPacket, true );
|
if ( !actionInfoPtr->is_aoe )
|
||||||
|
|
||||||
// todo: get proper packets: the following was just kind of thrown together from what we know
|
|
||||||
|
|
||||||
std::set< ActorPtr > actorsCollided = ActionCollision::getActorsHitFromAction( pTarget.getPos(), getInRangeActors( true ), actionInfoPtr, AoeFilter::Allies );
|
|
||||||
|
|
||||||
for ( auto pHitActor : actorsCollided )
|
|
||||||
{
|
{
|
||||||
effectPacket.data().targetId = pHitActor->getId();
|
if ( isPlayer() && !ActionCollision::isActorApplicable( pTarget.shared_from_this(), TargetFilter::Allies ) )
|
||||||
effectPacket.data().unknown_1 = 1; // the magic trick for getting it to work
|
break;
|
||||||
effectPacket.data().unknown_5 = 1;
|
|
||||||
effectPacket.data().unknown_8 = 1;
|
|
||||||
effectPacket.data().actionTextId = 0;
|
|
||||||
effectPacket.data().effectTarget = pHitActor->getId();
|
|
||||||
effectPacket.data().effects[0].value = calculatedHeal + ( rand() % 15 );
|
|
||||||
|
|
||||||
pHitActor->sendToInRangeSet( effectPacket, true );
|
sendToInRangeSet( effectPacket, true );
|
||||||
pHitActor->heal( calculatedHeal );
|
pTarget.heal( calculatedHeal );
|
||||||
|
|
||||||
if ( isPlayer() )
|
|
||||||
getAsPlayer()->sendDebug( "AoE hit actor " + pHitActor->getName() );
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// todo: get proper packets: the following was just kind of thrown together from what we know. atm buggy (packets look "delayed" from client)
|
||||||
|
|
||||||
|
std::set< ActorPtr > actorsCollided = ActionCollision::getActorsHitFromAction( pTarget.getPos(), getInRangeActors( true ), actionInfoPtr, TargetFilter::Allies );
|
||||||
|
|
||||||
|
for ( auto pHitActor : actorsCollided )
|
||||||
|
{
|
||||||
|
effectPacket.data().targetId = pTarget.getId();
|
||||||
|
effectPacket.data().effectTarget = pHitActor->getId();
|
||||||
|
|
||||||
|
sendToInRangeSet( effectPacket, true );
|
||||||
|
pHitActor->heal( calculatedHeal );
|
||||||
|
|
||||||
|
// Debug
|
||||||
|
if ( isPlayer() )
|
||||||
|
{
|
||||||
|
if ( pHitActor->isPlayer() ) {
|
||||||
|
getAsPlayer()->sendDebug( "AoE hit actor " + std::to_string( pHitActor->getId() ) + " (" + pHitActor->getName() + ")" );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
getAsPlayer()->sendDebug( "AoE hit actor " + std::to_string( pHitActor->getId() ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,7 +103,7 @@ public:
|
||||||
/*! load data for currently active quests */
|
/*! load data for currently active quests */
|
||||||
bool loadActiveQuests();
|
bool loadActiveQuests();
|
||||||
/*! update quest ( register it as active quest if new ) */
|
/*! update quest ( register it as active quest if new ) */
|
||||||
void updateQuest( uint16_t questId, uint16_t sequence );
|
void updateQuest( uint16_t questId, uint8_t sequence );
|
||||||
/*! return true if quest is currently active */
|
/*! return true if quest is currently active */
|
||||||
bool hasQuest( uint16_t questId );
|
bool hasQuest( uint16_t questId );
|
||||||
/*! return the current quest sequence */
|
/*! return the current quest sequence */
|
||||||
|
|
|
@ -74,7 +74,7 @@ bool Core::Entity::Player::loadActiveQuests()
|
||||||
void Core::Entity::Player::finishQuest( uint16_t questId )
|
void Core::Entity::Player::finishQuest( uint16_t questId )
|
||||||
{
|
{
|
||||||
|
|
||||||
int8_t idx = getQuestIndex( static_cast< uint16_t >( questId ) );
|
int16_t idx = getQuestIndex( questId );
|
||||||
|
|
||||||
if( ( idx != -1 ) && ( m_activeQuests[idx] != nullptr ) )
|
if( ( idx != -1 ) && ( m_activeQuests[idx] != nullptr ) )
|
||||||
{
|
{
|
||||||
|
@ -100,7 +100,7 @@ void Core::Entity::Player::finishQuest( uint16_t questId )
|
||||||
m_questTracking[ii] = -1;
|
m_questTracking[ii] = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<QuestActive> pQuest = m_activeQuests[idx];
|
boost::shared_ptr< QuestActive > pQuest = m_activeQuests[idx];
|
||||||
m_activeQuests[idx].reset();
|
m_activeQuests[idx].reset();
|
||||||
|
|
||||||
m_freeQuestIdxQueue.push( idx );
|
m_freeQuestIdxQueue.push( idx );
|
||||||
|
@ -123,7 +123,7 @@ void Core::Entity::Player::unfinishQuest( uint16_t questId )
|
||||||
void Core::Entity::Player::removeQuest( uint16_t questId )
|
void Core::Entity::Player::removeQuest( uint16_t questId )
|
||||||
{
|
{
|
||||||
|
|
||||||
int8_t idx = getQuestIndex( static_cast< uint16_t >( questId ) );
|
int16_t idx = getQuestIndex( questId );
|
||||||
|
|
||||||
if( ( idx != -1 ) && ( m_activeQuests[idx] != nullptr ) )
|
if( ( idx != -1 ) && ( m_activeQuests[idx] != nullptr ) )
|
||||||
{
|
{
|
||||||
|
@ -973,7 +973,7 @@ uint8_t Core::Entity::Player::getQuestSeq( uint16_t questId )
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Core::Entity::Player::updateQuest( uint16_t questId, uint16_t sequence )
|
void Core::Entity::Player::updateQuest( uint16_t questId, uint8_t sequence )
|
||||||
{
|
{
|
||||||
if( hasQuest( questId ) )
|
if( hasQuest( questId ) )
|
||||||
{
|
{
|
||||||
|
|
|
@ -440,14 +440,14 @@ bool Core::Inventory::removeCrystal( CrystalType type, uint32_t amount )
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Core::Inventory::isObtainable( uint32_t catalogId, uint16_t quantity )
|
bool Core::Inventory::isObtainable( uint32_t catalogId, uint8_t quantity )
|
||||||
{
|
{
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int16_t Core::Inventory::addItem( uint16_t inventoryId, int8_t slotId, uint32_t catalogId, uint16_t quantity )
|
int16_t Core::Inventory::addItem( uint16_t inventoryId, int8_t slotId, uint32_t catalogId, uint8_t quantity )
|
||||||
{
|
{
|
||||||
|
|
||||||
auto itemInfo = g_exdData.getItemInfo( catalogId );
|
auto itemInfo = g_exdData.getItemInfo( catalogId );
|
||||||
|
@ -587,7 +587,7 @@ void Core::Inventory::swapItem( uint16_t fromInventoryId, uint8_t fromSlotId, ui
|
||||||
{
|
{
|
||||||
updateContainer( fromInventoryId, fromSlotId, nullptr );
|
updateContainer( fromInventoryId, fromSlotId, nullptr );
|
||||||
fromInventoryId = getArmoryToEquipSlot( toSlot );
|
fromInventoryId = getArmoryToEquipSlot( toSlot );
|
||||||
fromSlotId = m_inventoryMap[fromInventoryId]->getFreeSlot();
|
fromSlotId = static_cast < uint8_t >( m_inventoryMap[fromInventoryId]->getFreeSlot() );
|
||||||
}
|
}
|
||||||
|
|
||||||
auto containerTypeFrom = getContainerType( fromInventoryId );
|
auto containerTypeFrom = getContainerType( fromInventoryId );
|
||||||
|
|
|
@ -140,7 +140,7 @@ public:
|
||||||
|
|
||||||
InvSlotPairVec getSlotsOfItemsInInventory( uint32_t catalogId );
|
InvSlotPairVec getSlotsOfItemsInInventory( uint32_t catalogId );
|
||||||
InvSlotPair getFreeBagSlot();
|
InvSlotPair getFreeBagSlot();
|
||||||
int16_t addItem( uint16_t inventoryId, int8_t slotId, uint32_t catalogId, uint16_t quantity = 1 );
|
int16_t addItem( uint16_t inventoryId, int8_t slotId, uint32_t catalogId, uint8_t quantity = 1 );
|
||||||
void moveItem( uint16_t fromInventoryId, uint8_t fromSlotId, uint16_t toInventoryId, uint8_t toSlot );
|
void moveItem( uint16_t fromInventoryId, uint8_t fromSlotId, uint16_t toInventoryId, uint8_t toSlot );
|
||||||
void swapItem( uint16_t fromInventoryId, uint8_t fromSlotId, uint16_t toInventoryId, uint8_t toSlot );
|
void swapItem( uint16_t fromInventoryId, uint8_t fromSlotId, uint16_t toInventoryId, uint8_t toSlot );
|
||||||
void discardItem( uint16_t fromInventoryId, uint8_t fromSlotId );
|
void discardItem( uint16_t fromInventoryId, uint8_t fromSlotId );
|
||||||
|
@ -175,7 +175,7 @@ public:
|
||||||
bool addCrystal( CrystalType type, uint32_t amount );
|
bool addCrystal( CrystalType type, uint32_t amount );
|
||||||
/*! remove amount from the crystals of type */
|
/*! remove amount from the crystals of type */
|
||||||
bool removeCrystal( CrystalType type, uint32_t amount );
|
bool removeCrystal( CrystalType type, uint32_t amount );
|
||||||
bool isObtainable( uint32_t catalogId, uint16_t quantity );
|
bool isObtainable( uint32_t catalogId, uint8_t quantity );
|
||||||
|
|
||||||
void updateCrystalDb();
|
void updateCrystalDb();
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue