Merge DarkflameServer

This commit is contained in:
TheMatt2
2022-01-30 13:40:08 -05:00
77 changed files with 1019 additions and 331 deletions

View File

@@ -451,6 +451,13 @@ bool Character::GetPlayerFlag(const uint32_t flagId) const {
return false; //by def, return false.
}
void Character::SetRetroactiveFlags() {
// Retroactive check for if player has joined a faction to set their 'joined a faction' flag to true.
if (GetPlayerFlag(ePlayerFlags::VENTURE_FACTION) || GetPlayerFlag(ePlayerFlags::ASSEMBLY_FACTION) || GetPlayerFlag(ePlayerFlags::PARADOX_FACTION) || GetPlayerFlag(ePlayerFlags::SENTINEL_FACTION)) {
SetPlayerFlag(ePlayerFlags::JOINED_A_FACTION, true);
}
}
void Character::SaveXmlRespawnCheckpoints()
{
//Export our respawn points:

View File

@@ -413,6 +413,12 @@ public:
*/
void SendMuteNotice() const;
/**
* Sets any flags that are meant to have been set that may not have been set due to them being
* missing in a previous patch.
*/
void SetRetroactiveFlags();
/**
* Get the equipped items for this character, only used for character creation
* @return the equipped items for this character on world load

View File

@@ -552,7 +552,7 @@ void UserManager::LoginCharacter(const SystemAddress& sysAddr, uint32_t playerID
if (zoneID == LWOZONEID_INVALID) zoneID = 1000; //Send char to VE
ZoneInstanceManager::Instance()->RequestZoneTransfer(Game::server, zoneID, character->GetZoneClone(), false, [=](bool mythranShift, uint32_t zoneID, uint32_t zoneInstance, uint32_t zoneClone, std::string serverIP, uint16_t serverPort) {
Game::logger->Log("UserManager", "Transferring %s to Zone %i (Instance %i | Clone %i | Mythran Shift: %s) with IP %s and Port %i\n", sysAddr.ToString(), zoneID, zoneInstance, zoneClone, mythranShift == true ? "true" : "false", serverIP.c_str(), serverPort);
Game::logger->Log("UserManager", "Transferring %s to Zone %i (Instance %i | Clone %i | Mythran Shift: %s) with IP %s and Port %i\n", character->GetName().c_str(), zoneID, zoneInstance, zoneClone, mythranShift == true ? "true" : "false", serverIP.c_str(), serverPort);
if (character) {
character->SetZoneID(zoneID);
character->SetZoneInstance(zoneInstance);
@@ -566,114 +566,34 @@ void UserManager::LoginCharacter(const SystemAddress& sysAddr, uint32_t playerID
}
}
uint32_t GetShirtColorId(uint32_t color) {
// get the index of the color in shirtColorVector
auto colorId = std::find(shirtColorVector.begin(), shirtColorVector.end(), color);
return color = std::distance(shirtColorVector.begin(), colorId);
}
uint32_t FindCharShirtID(uint32_t shirtColor, uint32_t shirtStyle) {
uint32_t shirtID = 0;
// s p e c i a l code follows
switch (shirtColor) {
case 0: {
shirtID = shirtStyle >= 35 ? 5730 : SHIRT_BRIGHT_RED;
break;
}
case 1: {
shirtID = shirtStyle >= 35 ? 5736 : SHIRT_BRIGHT_BLUE;
break;
}
case 3: {
shirtID = shirtStyle >= 35 ? 5808 : SHIRT_DARK_GREEN;
break;
}
case 5: {
shirtID = shirtStyle >= 35 ? 5754 : SHIRT_BRIGHT_ORANGE;
break;
}
case 6: {
shirtID = shirtStyle >= 35 ? 5760 : SHIRT_BLACK;
break;
}
case 7: {
shirtID = shirtStyle >= 35 ? 5766 : SHIRT_DARK_STONE_GRAY;
break;
}
case 8: {
shirtID = shirtStyle >= 35 ? 5772 : SHIRT_MEDIUM_STONE_GRAY;
break;
}
case 9: {
shirtID = shirtStyle >= 35 ? 5778 : SHIRT_REDDISH_BROWN;
break;
}
case 10: {
shirtID = shirtStyle >= 35 ? 5784 : SHIRT_WHITE;
break;
}
case 11: {
shirtID = shirtStyle >= 35 ? 5802 : SHIRT_MEDIUM_BLUE;
break;
}
case 13: {
shirtID = shirtStyle >= 35 ? 5796 : SHIRT_DARK_RED;
break;
}
case 14: {
shirtID = shirtStyle >= 35 ? 5802 : SHIRT_EARTH_BLUE;
break;
}
case 15: {
shirtID = shirtStyle >= 35 ? 5808 : SHIRT_EARTH_GREEN;
break;
}
case 16: {
shirtID = shirtStyle >= 35 ? 5814 : SHIRT_BRICK_YELLOW;
break;
}
case 84: {
shirtID = shirtStyle >= 35 ? 5820 : SHIRT_SAND_BLUE;
break;
}
case 96: {
shirtID = shirtStyle >= 35 ? 5826 : SHIRT_SAND_GREEN;
shirtColor = 16;
break;
}
}
// Initialize another variable for the shirt color
uint32_t editedShirtColor = shirtID;
// This will be the final shirt ID
uint32_t shirtIDFinal;
// For some reason, if the shirt color is 35 - 40,
shirtStyle--; // to start at 0 instead of 1
uint32_t stylesCount = 34;
uint32_t colorId = GetShirtColorId(shirtColor);
uint32_t startID = 4049; // item ID of the shirt with color 0 (red) and style 0 (plain)
// For some reason, if the shirt style is 34 - 39,
// The ID is different than the original... Was this because
// these shirts were added later?
if (shirtStyle >= 35) {
shirtIDFinal = editedShirtColor += (shirtStyle - 35);
}
else {
// Get the final ID of the shirt by adding the shirt
// style to the editedShirtColor
shirtIDFinal = editedShirtColor += (shirtStyle - 1);
if (shirtStyle >= 34) {
startID = 5730; // item ID of the shirt with color 0 (red) and style 34 (butterflies)
shirtStyle -= stylesCount; //change style from range 35-40 to range 0-5
stylesCount = 6;
}
// Get the final ID of the shirt
uint32_t shirtID = startID + (colorId * stylesCount) + shirtStyle;
//cout << "Shirt ID is: " << shirtIDFinal << endl;
return shirtIDFinal;
return shirtID;
}
uint32_t FindCharPantsID(uint32_t pantsColor) {

View File

@@ -33,10 +33,10 @@ public:
bool IsNamePreapproved(const std::string& requestedName);
void RequestCharacterList(const SystemAddress& sysAddr);
void CreateCharacter(const SystemAddress& sysAddr, Packet* packet);
void DeleteCharacter(const SystemAddress& sysAddr, Packet* packet);
void RenameCharacter(const SystemAddress& sysAddr, Packet* packet);
void LoginCharacter(const SystemAddress& sysAddr, uint32_t playerID);
void CreateCharacter(const SystemAddress& sysAddr, Packet* packet);
void DeleteCharacter(const SystemAddress& sysAddr, Packet* packet);
void RenameCharacter(const SystemAddress& sysAddr, Packet* packet);
void LoginCharacter(const SystemAddress& sysAddr, uint32_t playerID);
void SaveAllActiveCharacters();
@@ -48,9 +48,9 @@ private:
std::map<SystemAddress, User*> m_Users;
std::vector<User*> m_UsersToDelete;
std::vector<std::string> m_FirstNames;
std::vector<std::string> m_MiddleNames;
std::vector<std::string> m_LastNames;
std::vector<std::string> m_FirstNames;
std::vector<std::string> m_MiddleNames;
std::vector<std::string> m_LastNames;
std::vector<std::string> m_PreapprovedNames;
};
@@ -73,24 +73,24 @@ enum CharCreatePantsColor : uint32_t {
PANTS_DARK_RED = 2527
};
enum CharCreateShirtColor : uint32_t {
SHIRT_BRIGHT_RED = 4049,
SHIRT_BRIGHT_BLUE = 4083,
SHIRT_BRIGHT_YELLOW = 4117,
SHIRT_DARK_GREEN = 4151,
SHIRT_BRIGHT_ORANGE = 4185,
SHIRT_BLACK = 4219,
SHIRT_DARK_STONE_GRAY = 4253,
SHIRT_MEDIUM_STONE_GRAY = 4287,
SHIRT_REDDISH_BROWN = 4321,
SHIRT_WHITE = 4355,
SHIRT_MEDIUM_BLUE = 4389,
SHIRT_DARK_RED = 4423,
SHIRT_EARTH_BLUE = 4457,
SHIRT_EARTH_GREEN = 4491,
SHIRT_BRICK_YELLOW = 4525,
SHIRT_SAND_BLUE = 4559,
SHIRT_SAND_GREEN = 4593
const std::vector<uint32_t> shirtColorVector {
0, // BRIGHT_RED
1, // BRIGHT_BLUE
2, // BRIGHT_YELLOW
3, // DARK_GREEN
5, // BRIGHT_ORANGE
6, // BLACK
7, // DARK_STONE_GRAY
8, // MEDIUM_STONE_GRAY
9, // REDDISH_BROWN
10, // WHITE
11, // MEDIUM_BLUE
13, // DARK_RED
14, // EARTH_BLUE
15, // EARTH_GREEN
16, // BRICK_YELLOW
84, // SAND_BLUE
96 // SAND_GREEN
};
#endif // USERMANAGER_H

View File

@@ -74,7 +74,8 @@ void AreaOfEffectBehavior::Calculate(BehaviorContext* context, RakNet::BitStream
includeFaction = 1;
}
for (auto validTarget : context->GetValidTargets(m_ignoreFaction , includeFaction, m_TargetSelf == 1))
// Gets all of the valid targets, passing in if should target enemies and friends
for (auto validTarget : context->GetValidTargets(m_ignoreFaction , includeFaction, m_TargetSelf == 1, m_targetEnemy == 1, m_targetFriend == 1))
{
auto* entity = EntityManager::Instance()->GetEntity(validTarget);
@@ -156,5 +157,9 @@ void AreaOfEffectBehavior::Load()
this->m_includeFaction = GetInt("include_faction");
this->m_TargetSelf = GetInt("target_self");
this->m_TargetSelf = GetInt("target_self");
this->m_targetEnemy = GetInt("target_enemy");
this->m_targetFriend = GetInt("target_friend");
}

View File

@@ -14,7 +14,11 @@ public:
int32_t m_includeFaction;
int32_t m_TargetSelf;
int32_t m_TargetSelf;
int32_t m_targetEnemy;
int32_t m_targetFriend;
/*
* Inherited

View File

@@ -55,6 +55,7 @@
#include "SkillEventBehavior.h"
#include "SpeedBehavior.h"
#include "DamageReductionBehavior.h"
#include "JetPackBehavior.h"
//CDClient includes
#include "CDBehaviorParameterTable.h"
@@ -183,7 +184,9 @@ Behavior* Behavior::CreateBehavior(const uint32_t behaviorId)
case BehaviorTemplates::BEHAVIOR_BUFF:
behavior = new BuffBehavior(behaviorId);
break;
case BehaviorTemplates::BEHAVIOR_JETPACK: break;
case BehaviorTemplates::BEHAVIOR_JETPACK:
behavior = new JetPackBehavior(behaviorId);
break;
case BehaviorTemplates::BEHAVIOR_SKILL_EVENT:
behavior = new SkillEventBehavior(behaviorId);
break;
@@ -457,21 +460,21 @@ Behavior::Behavior(const uint32_t behaviorId)
}
float Behavior::GetFloat(const std::string& name) const
float Behavior::GetFloat(const std::string& name, const float defaultValue) const
{
return BehaviorParameterTable->GetEntry(this->m_behaviorId, name);
return BehaviorParameterTable->GetEntry(this->m_behaviorId, name, defaultValue);
}
bool Behavior::GetBoolean(const std::string& name) const
bool Behavior::GetBoolean(const std::string& name, const bool defaultValue) const
{
return GetFloat(name) > 0;
return GetFloat(name, defaultValue) > 0;
}
int32_t Behavior::GetInt(const std::string& name) const
int32_t Behavior::GetInt(const std::string& name, const int defaultValue) const
{
return static_cast<int32_t>(GetFloat(name));
return static_cast<int32_t>(GetFloat(name, defaultValue));
}

View File

@@ -49,11 +49,11 @@ public:
* Behavior parameters
*/
float GetFloat(const std::string& name) const;
float GetFloat(const std::string& name, const float defaultValue = 0) const;
bool GetBoolean(const std::string& name) const;
bool GetBoolean(const std::string& name, const bool defaultValue = false) const;
int32_t GetInt(const std::string& name) const;
int32_t GetInt(const std::string& name, const int32_t defaultValue = 0) const;
Behavior* GetAction(const std::string& name) const;

View File

@@ -325,7 +325,7 @@ void BehaviorContext::Reset()
this->scheduledUpdates.clear();
}
std::vector<LWOOBJID> BehaviorContext::GetValidTargets(int32_t ignoreFaction, int32_t includeFaction, bool targetSelf) const
std::vector<LWOOBJID> BehaviorContext::GetValidTargets(int32_t ignoreFaction, int32_t includeFaction, bool targetSelf, bool targetEnemy, bool targetFriend) const
{
auto* entity = EntityManager::Instance()->GetEntity(this->caster);
@@ -366,7 +366,7 @@ std::vector<LWOOBJID> BehaviorContext::GetValidTargets(int32_t ignoreFaction, in
{
const auto id = candidate->GetObjectID();
if ((id != entity->GetObjectID() || targetSelf) && destroyableComponent->CheckValidity(id, ignoreFaction || includeFaction))
if ((id != entity->GetObjectID() || targetSelf) && destroyableComponent->CheckValidity(id, ignoreFaction || includeFaction, targetEnemy, targetFriend))
{
targets.push_back(id);
}

View File

@@ -102,7 +102,7 @@ struct BehaviorContext
void Reset();
std::vector<LWOOBJID> GetValidTargets(int32_t ignoreFaction = 0, int32_t includeFaction = 0, const bool targetSelf = false) const;
std::vector<LWOOBJID> GetValidTargets(int32_t ignoreFaction = 0, int32_t includeFaction = 0, const bool targetSelf = false, const bool targetEnemy = true, const bool targetFriend = false) const;
explicit BehaviorContext(LWOOBJID originator, bool calculation = false);

View File

@@ -0,0 +1,29 @@
#include "JetPackBehavior.h"
#include "BehaviorBranchContext.h"
#include "GameMessages.h"
void JetPackBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bit_stream, const BehaviorBranchContext branch) {
auto* entity = EntityManager::Instance()->GetEntity(branch.target);
GameMessages::SendSetJetPackMode(entity, true, this->m_BypassChecks, this->m_EnableHover, this->m_effectId, this->m_Airspeed, this->m_MaxAirspeed, this->m_VerticalVelocity, this->m_WarningEffectID);
}
void JetPackBehavior::UnCast(BehaviorContext* context, BehaviorBranchContext branch) {
auto* entity = EntityManager::Instance()->GetEntity(branch.target);
GameMessages::SendSetJetPackMode(entity, false);
}
void JetPackBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bit_stream, const BehaviorBranchContext branch) {
Handle(context, bit_stream, branch);
}
void JetPackBehavior::Load() {
this->m_WarningEffectID = GetInt("warning_effect_id");
this->m_Airspeed = GetFloat("airspeed");
this->m_MaxAirspeed = GetFloat("max_airspeed");
this->m_VerticalVelocity = GetFloat("vertical_velocity");
this->m_EnableHover = GetBoolean("enable_hover");
this->m_BypassChecks = GetBoolean("bypass_checks", true);
}

View File

@@ -0,0 +1,28 @@
#pragma once
#include "Behavior.h"
class JetPackBehavior final : public Behavior
{
public:
int32_t m_WarningEffectID;
float m_Airspeed;
float m_MaxAirspeed;
float m_VerticalVelocity;
bool m_EnableHover;
bool m_BypassChecks = true; // from what I can tell this defaulted true in live
/*
* Inherited
*/
explicit JetPackBehavior(const uint32_t behavior_id) : Behavior(behavior_id) {
}
void Handle(BehaviorContext* context, RakNet::BitStream* bit_stream, BehaviorBranchContext branch) override;
void UnCast(BehaviorContext* context, BehaviorBranchContext branch) override;
void Calculate(BehaviorContext* context, RakNet::BitStream* bit_stream, BehaviorBranchContext branch) override;
void Load() override;
};

View File

@@ -498,29 +498,28 @@ Entity* DestroyableComponent::GetKiller() const
return EntityManager::Instance()->GetEntity(m_KillerID);
}
bool DestroyableComponent::CheckValidity(const LWOOBJID target, const bool ignoreFactions) const
bool DestroyableComponent::CheckValidity(const LWOOBJID target, const bool ignoreFactions, const bool targetEnemy, const bool targetFriend) const
{
auto* entity = EntityManager::Instance()->GetEntity(target);
auto* targetEntity = EntityManager::Instance()->GetEntity(target);
if (entity == nullptr)
if (targetEntity == nullptr)
{
Game::logger->Log("DestroyableComponent", "Invalid entity for checking validity (%llu)!\n", target);
return false;
}
auto* destroyable = entity->GetComponent<DestroyableComponent>();
auto* targetDestroyable = targetEntity->GetComponent<DestroyableComponent>();
if (destroyable == nullptr)
if (targetDestroyable == nullptr)
{
return false;
}
auto* quickbuild = entity->GetComponent<RebuildComponent>();
auto* targetQuickbuild = targetEntity->GetComponent<RebuildComponent>();
if (quickbuild != nullptr)
if (targetQuickbuild != nullptr)
{
const auto state = quickbuild->GetState();
const auto state = targetQuickbuild->GetState();
if (state != REBUILD_COMPLETED)
{
@@ -533,19 +532,12 @@ bool DestroyableComponent::CheckValidity(const LWOOBJID target, const bool ignor
return true;
}
auto enemyList = GetEnemyFactionsIDs();
// Get if the target entity is an enemy and friend
bool isEnemy = IsEnemy(targetEntity);
bool isFriend = IsFriend(targetEntity);
auto candidateList = destroyable->GetFactionIDs();
for (auto value : candidateList)
{
if (std::find(enemyList.begin(), enemyList.end(), value) != enemyList.end())
{
return true;
}
}
return false;
// Return true if the target type matches what we are targeting
return (isEnemy && targetEnemy) || (isFriend && targetFriend);
}

View File

@@ -371,7 +371,7 @@ public:
* @param ignoreFactions whether or not check for the factions, e.g. just return true if the entity cannot be smashed
* @return if the target ID is a valid enemy
*/
bool CheckValidity(LWOOBJID target, bool ignoreFactions = false) const;
bool CheckValidity(LWOOBJID target, bool ignoreFactions = false, bool targetEnemy = true, bool targetFriend = false) const;
/**
* Attempt to damage this entity, handles everything from health and armor to absorption, immunity and callbacks.

View File

@@ -1001,10 +1001,6 @@ void InventoryComponent::EquipItem(Item* item, const bool skipChecks)
set->OnEquip(lot);
}
if (lot == 1727) GameMessages::SendSetJetpackMode(m_Parent, false, true, false);
if (lot == 7292) GameMessages::SendSetJetpackMode(m_Parent, true, true, false);
if (lot == 14442) GameMessages::SendSetJetpackMode(m_Parent, false, true, true);
if (item->GetInfo().isBOE)
{
item->SetBound(true);
@@ -1042,10 +1038,6 @@ void InventoryComponent::UnEquipItem(Item* item)
set->OnUnEquip(lot);
}
if (lot == 1727) GameMessages::SendSetJetpackMode(m_Parent, false, false, false);
if (lot == 7292) GameMessages::SendSetJetpackMode(m_Parent, true, false, false);
if (lot == 14442) GameMessages::SendSetJetpackMode(m_Parent, false, false, true);
RemoveBuff(item->GetLot());
RemoveItemSkills(item->GetLot());

View File

@@ -257,7 +257,7 @@ void RacingControlComponent::LoadPlayerVehicle(Entity *player,
m_Parent->GetObjectID(), playerID, UNASSIGNED_SYSTEM_ADDRESS);
});
GameMessages::SendSetJetpackMode(player, false, false, false);
GameMessages::SendSetJetPackMode(player, false);
// Set the vehicle's state.
GameMessages::SendNotifyVehicleOfRacingObject(carEntity->GetObjectID(),

View File

@@ -513,7 +513,7 @@ void ActivityInstance::StartZone() {
if (player == nullptr)
return;
Game::logger->Log("UserManager", "Transferring %s to Zone %i (Instance %i | Clone %i | Mythran Shift: %s) with IP %s and Port %i\n", player->GetSystemAddress().ToString(), zoneID, zoneInstance, zoneClone, mythranShift == true ? "true" : "false", serverIP.c_str(), serverPort);
Game::logger->Log("UserManager", "Transferring %s to Zone %i (Instance %i | Clone %i | Mythran Shift: %s) with IP %s and Port %i\n", player->GetCharacter()->GetName().c_str(), zoneID, zoneInstance, zoneClone, mythranShift == true ? "true" : "false", serverIP.c_str(), serverPort);
if (player->GetCharacter()) {
player->GetCharacter()->SetZoneID(zoneID);
player->GetCharacter()->SetZoneInstance(zoneInstance);

View File

@@ -105,9 +105,6 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System
auto items = inv->GetEquippedItems();
for (auto pair : items) {
const auto item = pair.second;
if (item.lot == 1727) GameMessages::SendSetJetpackMode(entity, false, true, false);
if (item.lot == 7292) GameMessages::SendSetJetpackMode(entity, true, true, false);
if (item.lot == 14442) GameMessages::SendSetJetpackMode(entity, false, true, true);
inv->AddItemSkills(item.lot);
}

View File

@@ -872,19 +872,14 @@ void GameMessages::SendSetEmoteLockState(Entity* entity, bool bLock, int emoteID
SEND_PACKET
}
void GameMessages::SendSetJetpackMode(Entity* entity, bool bDoHover, bool bUse, bool bIsJamessterPhysics) {
int effectID = 167;
int iWarningEffectID = -1;
float fAirspeed = 25;
float fMaxAirspeed = 25;
float fVertVel = 2;
bool bBypassChecks = true;
void GameMessages::SendSetJetPackMode(Entity* entity, bool use, bool bypassChecks, bool doHover, int effectID, float airspeed, float maxAirspeed, float verticalVelocity, int warningEffectID) {
/* historical jamesster jetpack values
if (bIsJamessterPhysics) {
fAirspeed = 75;
fMaxAirspeed = 75;
fVertVel = 15;
}
*/
CBITSTREAM
CMSGHEADER
@@ -892,24 +887,24 @@ void GameMessages::SendSetJetpackMode(Entity* entity, bool bDoHover, bool bUse,
bitStream.Write(entity->GetObjectID());
bitStream.Write(uint16_t(GAME_MSG_SET_JET_PACK_MODE));
bitStream.Write(bBypassChecks);
bitStream.Write(bDoHover);
bitStream.Write(bUse);
bitStream.Write(bypassChecks);
bitStream.Write(doHover);
bitStream.Write(use);
bitStream.Write(effectID != -1);
if (effectID != -1) bitStream.Write(effectID);
bitStream.Write(fAirspeed != 10);
if (fAirspeed != 10) bitStream.Write(fAirspeed);
bitStream.Write(airspeed != 10);
if (airspeed != 10) bitStream.Write(airspeed);
bitStream.Write(fMaxAirspeed != 15);
if (fMaxAirspeed != 15) bitStream.Write(fMaxAirspeed);
bitStream.Write(maxAirspeed != 15);
if (maxAirspeed != 15) bitStream.Write(maxAirspeed);
bitStream.Write(fVertVel != 1);
if (fVertVel != 1) bitStream.Write(fVertVel);
bitStream.Write(verticalVelocity != 1);
if (verticalVelocity != 1) bitStream.Write(verticalVelocity);
bitStream.Write(iWarningEffectID != -1);
if (iWarningEffectID != -1) bitStream.Write(iWarningEffectID);
bitStream.Write(warningEffectID != -1);
if (warningEffectID != -1) bitStream.Write(warningEffectID);
SEND_PACKET_BROADCAST
}
@@ -4898,7 +4893,7 @@ void GameMessages::HandleFireEventServerSide(RakNet::BitStream* inStream, Entity
}
ZoneInstanceManager::Instance()->RequestZoneTransfer(Game::server, mapId, cloneId, false, [=](bool mythranShift, uint32_t zoneID, uint32_t zoneInstance, uint32_t zoneClone, std::string serverIP, uint16_t serverPort) {
Game::logger->Log("UserManager", "Transferring %s to Zone %i (Instance %i | Clone %i | Mythran Shift: %s) with IP %s and Port %i\n", sysAddr.ToString(), zoneID, zoneInstance, zoneClone, mythranShift == true ? "true" : "false", serverIP.c_str(), serverPort);
Game::logger->Log("UserManager", "Transferring %s to Zone %i (Instance %i | Clone %i | Mythran Shift: %s) with IP %s and Port %i\n", character->GetName().c_str(), zoneID, zoneInstance, zoneClone, mythranShift == true ? "true" : "false", serverIP.c_str(), serverPort);
if (character) {
character->SetZoneID(zoneID);

View File

@@ -91,7 +91,7 @@ namespace GameMessages {
void SendSetInventorySize(Entity* entity, int invType, int size);
void SendSetEmoteLockState(Entity* entity, bool bLock, int emoteID);
void SendSetJetpackMode(Entity* entity, bool bDoHover, bool bUse, bool bIsJamessterPhysics);
void SendSetJetPackMode(Entity* entity, bool use, bool bypassChecks = false, bool doHover = false, int effectID = -1, float airspeed = 10, float maxAirspeed = 15, float verticalVelocity = 1, int warningEffectID = -1);
void SendResurrect(Entity* entity);
void SendStop2DAmbientSound(Entity* entity, bool force, std::string audioGUID, bool result = false);
void SendPlay2DAmbientSound(Entity* entity, std::string audioGUID, bool result = false);

View File

@@ -185,6 +185,7 @@ std::vector<ItemSetPassiveAbility> ItemSetPassiveAbility::FindAbilities(uint32_t
break;
}
// Paradox
case ItemSetPassiveAbilityID::BatLord:
case ItemSetPassiveAbilityID::SpaceMarauderRank1:
case ItemSetPassiveAbilityID::SpaceMarauderRank2:
case ItemSetPassiveAbilityID::SpaceMarauderRank3:
@@ -223,6 +224,12 @@ void ItemSetPassiveAbility::OnEnemySmshed()
switch (id)
{
// Bat Lord
case ItemSetPassiveAbilityID::BatLord: {
if(equippedCount < 5) return;
destroyableComponent->Heal(3);
break;
}
// Sentinel
case ItemSetPassiveAbilityID::KnightRank1: {
if (equippedCount < 5) return;

View File

@@ -438,10 +438,13 @@ void Mission::YieldRewards() {
items.emplace_back(info->reward_item4_repeatable, info->reward_item4_repeat_count);
for (const auto& pair : items) {
if (pair.second <= 0 || (m_Reward > 0 && pair.first != m_Reward)) {
// Some missions reward zero of an item and so they must be allowed through this clause,
// hence pair.second < 0 instead of pair.second <= 0.
if (pair.second < 0 || (m_Reward > 0 && pair.first != m_Reward)) {
continue;
}
// If a mission rewards zero of an item, make it reward 1.
auto count = pair.second > 0 ? pair.second : 1;
// Sanity check, 6 is the max any mission yields
@@ -467,10 +470,13 @@ void Mission::YieldRewards() {
items.emplace_back(info->reward_item4, info->reward_item4_count);
for (const auto& pair : items) {
// Some missions reward zero of an item and so they must be allowed through this clause,
// hence pair.second < 0 instead of pair.second <= 0.
if (pair.second < 0 || (m_Reward > 0 && pair.first != m_Reward)) {
continue;
}
// If a mission rewards zero of an item, make it reward 1.
auto count = pair.second > 0 ? pair.second : 1;
// Sanity check, 6 is the max any mission yields

View File

@@ -340,7 +340,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
const auto sysAddr = entity->GetSystemAddress();
Game::logger->Log("UserManager", "Transferring %s to Zone %i (Instance %i | Clone %i | Mythran Shift: %s) with IP %s and Port %i\n", sysAddr.ToString(), zoneID, zoneInstance, zoneClone, mythranShift == true ? "true" : "false", serverIP.c_str(), serverPort);
Game::logger->Log("UserManager", "Transferring %s to Zone %i (Instance %i | Clone %i | Mythran Shift: %s) with IP %s and Port %i\n", entity->GetCharacter()->GetName().c_str(), zoneID, zoneInstance, zoneClone, mythranShift == true ? "true" : "false", serverIP.c_str(), serverPort);
if (entity->GetCharacter()) {
entity->GetCharacter()->SetZoneID(zoneID);
@@ -675,6 +675,21 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
entity->GetCharacter()->SetPlayerFlag(flagId, true);
}
if (chatCommand == "setflag" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() == 2)
{
uint32_t flagId;
std::string onOffFlag = args[0];
if (!GeneralUtils::TryParse(args[1], flagId))
{
ChatPackets::SendSystemMessage(sysAddr, u"Invalid flag id.");
return;
}
if (onOffFlag != "off" && onOffFlag != "on") {
ChatPackets::SendSystemMessage(sysAddr, u"Invalid flag type.");
return;
}
entity->GetCharacter()->SetPlayerFlag(flagId, onOffFlag == "on");
}
if (chatCommand == "clearflag" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() == 1)
{
uint32_t flagId;
@@ -1938,53 +1953,54 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
}
bool SlashCommandHandler::CheckIfAccessibleZone(const unsigned int zoneID) {
switch (zoneID) {
case 98:
case 1000:
case 1001:
switch (zoneID) {
case 98:
case 1000:
case 1001:
case 1100:
case 1101:
case 1150:
case 1151:
case 1152:
case 1100:
case 1101:
case 1150:
case 1151:
case 1152:
case 1200:
case 1201:
case 1200:
case 1201:
case 1250:
case 1251:
case 1260:
case 1250:
case 1251:
case 1260:
case 1300:
case 1350:
case 1351:
case 1300:
case 1350:
case 1351:
case 1400:
case 1401:
case 1450:
case 1451:
case 1400:
case 1401:
case 1450:
case 1451:
case 1600:
case 1601:
case 1602:
case 1603:
case 1604:
case 1600:
case 1601:
case 1602:
case 1603:
case 1604:
case 1800:
case 1900:
case 2000:
case 1700:
case 1800:
case 1900:
case 2000:
case 58004:
case 58005:
case 58006:
return true;
case 58004:
case 58005:
case 58006:
return true;
default:
return false;
}
default:
return false;
}
return false;
return false;
}
void SlashCommandHandler::SendAnnouncement(const std::string& title, const std::string& message) {