diff --git a/src/servers/sapphire_api/PlayerMinimal.h b/src/servers/sapphire_api/PlayerMinimal.h index 38019e10..7a3b31e1 100644 --- a/src/servers/sapphire_api/PlayerMinimal.h +++ b/src/servers/sapphire_api/PlayerMinimal.h @@ -150,6 +150,16 @@ namespace Core { m_gmRank = rank; } + bool getGminvis() const + { + return m_gmInvis; + } + + bool setGminvis( bool invis ) + { + m_gmInvis = invis; + } + void createInvDbContainer( uint16_t slot ) const; uint32_t m_modelEquip[10]; @@ -177,6 +187,7 @@ namespace Core { uint8_t m_look[26]; uint8_t m_gmRank; + bool m_gmInvis; char m_name[34]; diff --git a/src/servers/sapphire_zone/Actor/Player.cpp b/src/servers/sapphire_zone/Actor/Player.cpp index 6ccc061f..e05308f4 100644 --- a/src/servers/sapphire_zone/Actor/Player.cpp +++ b/src/servers/sapphire_zone/Actor/Player.cpp @@ -132,6 +132,16 @@ void Core::Entity::Player::setGmRank( uint8_t rank ) m_gmRank = rank; } +bool Core::Entity::Player::getGmInvis() const +{ + return m_gmInvis; +} + +void Core::Entity::Player::setGmInvis( bool invis ) +{ + m_gmInvis = invis; +} + uint8_t Core::Entity::Player::getMode() const { return m_mode; @@ -167,6 +177,16 @@ Core::Common::OnlineStatus Core::Entity::Player::getOnlineStatus() uint64_t ptMask = uint64_t( 1 ) << static_cast< uint32_t >( OnlineStatus::LookingforParty ); uint64_t rpMask = uint64_t( 1 ) << static_cast< uint32_t >( OnlineStatus::Roleplaying ); + uint64_t prodMask = uint64_t( 1 ) << static_cast< uint32_t >( OnlineStatus::Producer ); + uint64_t gmMask = uint64_t( 1 ) << static_cast< uint32_t >( OnlineStatus::GameMaster ); + uint64_t gm1Mask = uint64_t( 1 ) << static_cast< uint32_t >( OnlineStatus::GameMaster1 ); + uint64_t gm2Mask = uint64_t( 1 ) << static_cast< uint32_t >( OnlineStatus::GameMaster2 ); + + uint64_t menMask = uint64_t( 1 ) << static_cast< uint32_t >( OnlineStatus::Mentor ); + uint64_t retMask = uint64_t( 1 ) << static_cast< uint32_t >( OnlineStatus::Returner ); + uint64_t trialMask = uint64_t( 1 ) << static_cast< uint32_t >( OnlineStatus::TrialAdventurer ); + + OnlineStatus status = OnlineStatus::Online; //if( hasStateFlag( Common::PlayerStateFlag::NewAdventurer ) ) @@ -191,6 +211,27 @@ Core::Common::OnlineStatus Core::Entity::Player::getOnlineStatus() if( m_onlineStatus & rpMask ) status = OnlineStatus::Roleplaying; + if( m_onlineStatus & prodMask ) + status = OnlineStatus::Producer; + + if( m_onlineStatus & gmMask ) + status = OnlineStatus::GameMaster; + + if( m_onlineStatus & gm1Mask ) + status = OnlineStatus::GameMaster1; + + if( m_onlineStatus & gm2Mask ) + status = OnlineStatus::GameMaster2; + + if( m_onlineStatus & menMask ) + status = OnlineStatus::Mentor; + + if( m_onlineStatus & retMask ) + status = OnlineStatus::Returner; + + if( m_onlineStatus & trialMask ) + status = OnlineStatus::TrialAdventurer; + if( hasStateFlag( PlayerStateFlag::WatchingCutscene ) ) status = OnlineStatus::ViewingCutscene; @@ -1606,11 +1647,17 @@ void Core::Entity::Player::finishZoning() switch( getZoningType() ) { case ZoneingType::None: - sendToInRangeSet( ActorControlPacket143( getId(), ZoneIn, 0x01 ), true ); + if (getGmInvis() == false) + sendToInRangeSet( ActorControlPacket143( getId(), ZoneIn, 0x01 ), true ); + else + queuePacket( ActorControlPacket143( getId(), ZoneIn, 0x01 ) ); break; case ZoneingType::Teleport: - sendToInRangeSet( ActorControlPacket143( getId(), ZoneIn, 0x01, 0, 0, 110 ), true ); + if( getGmInvis() == false ) + sendToInRangeSet( ActorControlPacket143( getId(), ZoneIn, 0x01, 0, 0, 110 ), true ); + else + queuePacket( ActorControlPacket143( getId(), ZoneIn, 0x01, 0, 0, 110 ) ); break; case ZoneingType::Return: @@ -1621,13 +1668,18 @@ void Core::Entity::Player::finishZoning() resetHp(); resetMp(); setStatus( Entity::Chara::ActorStatus::Idle ); - - sendToInRangeSet( ActorControlPacket143( getId(), ZoneIn, 0x01, 0x01, 0, 111 ), true ); + if( getGmInvis() == false ) + sendToInRangeSet( ActorControlPacket143( getId(), ZoneIn, 0x01, 0x01, 0, 111 ), true ); + else + queuePacket( ActorControlPacket143( getId(), ZoneIn, 0x01, 0x01, 0, 111 ) ); sendToInRangeSet( ActorControlPacket142( getId(), SetStatus, static_cast< uint8_t >( Entity::Chara::ActorStatus::Idle ) ), true ); } else - sendToInRangeSet( ActorControlPacket143( getId(), ZoneIn, 0x01, 0x00, 0, 111 ), true ); + if( getGmInvis() == false ) + sendToInRangeSet( ActorControlPacket143( getId(), ZoneIn, 0x01, 0x00, 0, 111 ), true ); + else + queuePacket( ActorControlPacket143( getId(), ZoneIn, 0x01, 0x00, 0, 111 ) ); } break; diff --git a/src/servers/sapphire_zone/Actor/Player.h b/src/servers/sapphire_zone/Actor/Player.h index 8a6da096..9863d428 100644 --- a/src/servers/sapphire_zone/Actor/Player.h +++ b/src/servers/sapphire_zone/Actor/Player.h @@ -546,6 +546,9 @@ public: uint8_t getGmRank() const; void setGmRank( uint8_t rank ); + bool getGmInvis() const; + void setGmInvis( bool invis ); + uint8_t getMode() const; void setMode( uint8_t mode ); @@ -671,6 +674,7 @@ private: uint8_t m_stateFlags[12]; uint8_t m_gmRank; uint16_t zoneId; + bool m_gmInvis = false; uint8_t m_equipDisplayFlags; diff --git a/src/servers/sapphire_zone/Network/Handlers/GMCommandHandlers.cpp b/src/servers/sapphire_zone/Network/Handlers/GMCommandHandlers.cpp index f1470ff9..8c170ccc 100644 --- a/src/servers/sapphire_zone/Network/Handlers/GMCommandHandlers.cpp +++ b/src/servers/sapphire_zone/Network/Handlers/GMCommandHandlers.cpp @@ -224,6 +224,32 @@ void Core::Network::GameConnection::gm1Handler( const Packets::GamePacket& inPac player.sendNotice( "Speed for " + targetPlayer->getName() + " was set to " + std::to_string( param1 ) ); break; } + case GmCommand::Invis: + { + if( targetPlayer->getGmInvis() == false ) { + targetPlayer->setGmInvis( true ); + auto inRange = targetPlayer->getInRangeActors(); + for( auto actor : inRange ) + { + targetPlayer->despawn( actor->getAsPlayer() ); + targetPlayer->spawn( actor->getAsPlayer() ); + } + player.sendNotice( "Invisibility flag for " + targetPlayer->getName() + " was toggled to on" ); + break; + } + else + { + targetPlayer->setGmInvis( false ); + auto inRange = targetPlayer->getInRangeActors(); + for( auto actor : inRange ) + { + targetPlayer->despawn( actor->getAsPlayer() ); + targetPlayer->spawn( actor->getAsPlayer() ); + } + player.sendNotice( "Invisibility flag for " + targetPlayer->getName() + " was toggled to off" ); + break; + } + } case GmCommand::Kill: { targetActor->getAsChara()->takeDamage( 9999999 ); diff --git a/src/servers/sapphire_zone/Network/Handlers/PacketHandlers.cpp b/src/servers/sapphire_zone/Network/Handlers/PacketHandlers.cpp index 4ad33d62..76fb6a99 100644 --- a/src/servers/sapphire_zone/Network/Handlers/PacketHandlers.cpp +++ b/src/servers/sapphire_zone/Network/Handlers/PacketHandlers.cpp @@ -515,16 +515,25 @@ void Core::Network::GameConnection::chatHandler( const Packets::GamePacket& inPa { case ChatType::Say: { + if (player.getGmRank() > 0) + chatPacket.data().chatType = ChatType::GMSay; + player.getCurrentZone()->queueOutPacketForRange( player, 50, chatPacket ); break; } case ChatType::Yell: { + if( player.getGmRank() > 0 ) + chatPacket.data().chatType = ChatType::GMYell; + player.getCurrentZone()->queueOutPacketForRange( player, 6000, chatPacket ); break; } case ChatType::Shout: { + if( player.getGmRank() > 0 ) + chatPacket.data().chatType = ChatType::GMShout; + player.getCurrentZone()->queueOutPacketForRange( player, 6000, chatPacket ); break; } diff --git a/src/servers/sapphire_zone/Network/PacketWrappers/PlayerSpawnPacket.h b/src/servers/sapphire_zone/Network/PacketWrappers/PlayerSpawnPacket.h index e3cdcb73..e35524b4 100644 --- a/src/servers/sapphire_zone/Network/PacketWrappers/PlayerSpawnPacket.h +++ b/src/servers/sapphire_zone/Network/PacketWrappers/PlayerSpawnPacket.h @@ -91,7 +91,7 @@ namespace Server { // 0x20 == spawn hidden to be displayed by the spawneffect control m_data.displayFlags = player.getStance(); - if( player.getZoningType() != Common::ZoneingType::None ) + if( player.getZoningType() != Common::ZoneingType::None || player.getGmInvis() == true ) { m_data.displayFlags |= Entity::Chara::DisplayFlags::Invisible; }