diff --git a/src/servers/Server_Common/Common.h b/src/servers/Server_Common/Common.h index 15b0ccc6..190e6b9f 100644 --- a/src/servers/Server_Common/Common.h +++ b/src/servers/Server_Common/Common.h @@ -628,6 +628,13 @@ namespace Core { StdDot, }; + enum InvincibilityType : uint8_t + { + InvincibilityNone = 0, + InvincibilityRefill = 1, + InvincibilityStayAlive = 2, + }; + enum struct PlayerStateFlag : uint8_t { NoCombat, diff --git a/src/servers/Server_Zone/Actor/Actor.cpp b/src/servers/Server_Zone/Actor/Actor.cpp index 1b4e3c38..fe358dc0 100644 --- a/src/servers/Server_Zone/Actor/Actor.cpp +++ b/src/servers/Server_Zone/Actor/Actor.cpp @@ -109,6 +109,12 @@ uint16_t Core::Entity::Actor::getGp() const return m_gp; } +/*! \return current GP */ +InvincibilityType Core::Entity::Actor::getInvincibilityType() const +{ + return m_invincibilityType; +} + /*! \return current class or job */ Core::Common::ClassJob Core::Entity::Actor::getClass() const { @@ -161,18 +167,21 @@ uint32_t Core::Entity::Actor::getMaxMp() const void Core::Entity::Actor::resetHp() { m_hp = getMaxHp(); + sendStatusUpdate( true ); } /*! \return reset mp to current max mp */ void Core::Entity::Actor::resetMp() { m_mp = getMaxMp(); + sendStatusUpdate(true); } /*! \param hp amount to set ( caps to maxHp ) */ void Core::Entity::Actor::setHp( uint32_t hp ) { m_hp = hp < getMaxHp() ? hp : getMaxHp(); + sendStatusUpdate(true); } /*! \param mp amount to set ( caps to maxMp ) */ @@ -181,12 +190,19 @@ void Core::Entity::Actor::setMp( uint32_t mp ) m_mp = mp < getMaxMp() ? mp : getMaxMp(); } -/*! \param mp amount to set ( caps to maxMp ) */ +/*! \param gp amount to set*/ void Core::Entity::Actor::setGp( uint32_t gp ) { m_gp = gp; } +/*! \param type invincibility type to set */ +void Core::Entity::Actor::setInvincibilityType( Common::InvincibilityType type ) +{ + m_invincibilityType = type; +} + + /*! \return current status of the actor */ Core::Entity::Actor::ActorStatus Core::Entity::Actor::getStatus() const { @@ -331,8 +347,18 @@ void Core::Entity::Actor::takeDamage( uint32_t damage ) { if( damage >= m_hp ) { - m_hp = 0; - die(); + switch( m_invincibilityType ) { + case InvincibilityNone: + setHp( 0 ); + die(); + break; + case InvincibilityRefill: + resetHp(); + break; + case InvincibilityStayAlive: + setHp( 0 ); + break; + } } else m_hp -= damage; diff --git a/src/servers/Server_Zone/Actor/Actor.h b/src/servers/Server_Zone/Actor/Actor.h index de6b9118..bf316c15 100644 --- a/src/servers/Server_Zone/Actor/Actor.h +++ b/src/servers/Server_Zone/Actor/Actor.h @@ -150,6 +150,8 @@ protected: Action::ActionPtr m_pCurrentAction; /*! Container for status effects */ StatusEffect::StatusEffectContainerPtr m_pStatusEffectContainer; + /*! Invincibility type */ + Common::InvincibilityType m_invincibilityType; public: Actor(); @@ -199,6 +201,8 @@ public: uint16_t getGp() const; + Common::InvincibilityType getInvincibilityType() const; + Common::ClassJob getClass() const; uint8_t getClassAsInt() const; @@ -225,6 +229,8 @@ public: void setGp( uint32_t gp ); + void setInvincibilityType( Common::InvincibilityType type ); + void die(); ActorStatus getStatus() const; diff --git a/src/servers/Server_Zone/Actor/BattleNpc.cpp b/src/servers/Server_Zone/Actor/BattleNpc.cpp index b9891203..1c5f9734 100644 --- a/src/servers/Server_Zone/Actor/BattleNpc.cpp +++ b/src/servers/Server_Zone/Actor/BattleNpc.cpp @@ -82,6 +82,8 @@ Core::Entity::BattleNpc::BattleNpc( uint32_t modelId, uint32_t nameid, const Com m_mobType = mobType; + m_invincibilityType = InvincibilityType::InvincibilityNone; + //m_type = static_cast< Common::ActorType >( type ); } diff --git a/src/servers/Server_Zone/Actor/Player.cpp b/src/servers/Server_Zone/Actor/Player.cpp index 49bc2ad3..03de3b3e 100644 --- a/src/servers/Server_Zone/Actor/Player.cpp +++ b/src/servers/Server_Zone/Actor/Player.cpp @@ -82,6 +82,7 @@ Core::Entity::Player::Player() : m_onlineStatus = 0; m_queuedZoneing = nullptr; m_status = ActorStatus::Idle; + m_invincibilityType = InvincibilityType::InvincibilityNone; memset( m_questTracking, 0, sizeof( m_questTracking ) ); memset( m_name, 0, sizeof( m_name ) ); diff --git a/src/servers/Server_Zone/Network/Handlers/GMCommandHandlers.cpp b/src/servers/Server_Zone/Network/Handlers/GMCommandHandlers.cpp index 973b4bb1..97746ed7 100644 --- a/src/servers/Server_Zone/Network/Handlers/GMCommandHandlers.cpp +++ b/src/servers/Server_Zone/Network/Handlers/GMCommandHandlers.cpp @@ -70,6 +70,7 @@ enum GmCommand Tp = 0x0066, Gp = 0x0067, Exp = 0x0068, + Inv = 0x006A, Item = 0x00C8, Gil = 0x00C9, @@ -352,6 +353,17 @@ void Core::Network::GameConnection::gm1Handler( const Packets::GamePacket& inPac " was set to " + std::to_string( targetPlayer->getGcRankArray()[targetPlayer->getGc() - 1] ) ); break; } + case GmCommand::Inv: + { + if( targetActor->getInvincibilityType() == Common::InvincibilityType::InvincibilityRefill ) + targetActor->setInvincibilityType( Common::InvincibilityType::InvincibilityNone ); + else + targetActor->setInvincibilityType( Common::InvincibilityType::InvincibilityRefill ); + + pPlayer->sendNotice( "Invincibility for " + targetPlayer->getName() + + " was was switched." ); + break; + } default: pPlayer->sendUrgent( "GM1 Command not implemented: " + std::to_string( commandId ) );