mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-08-09 20:24:16 +00:00
Merge branch 'main' into more-behaviors
This commit is contained in:
@@ -320,7 +320,7 @@ const std::unordered_map<std::string, LWOOBJID>& EntityManager::GetSpawnPointEnt
|
||||
return m_SpawnPoints;
|
||||
}
|
||||
|
||||
void EntityManager::ConstructEntity(Entity* entity, const SystemAddress& sysAddr, const bool skipChecks) {
|
||||
void EntityManager::ConstructEntity(Entity* entity, const SystemAddress& sysAddr) {
|
||||
if (!entity) {
|
||||
LOG("Attempted to construct null entity");
|
||||
return;
|
||||
@@ -363,16 +363,14 @@ void EntityManager::ConstructEntity(Entity* entity, const SystemAddress& sysAddr
|
||||
entity->WriteComponents(stream, eReplicaPacketType::CONSTRUCTION);
|
||||
|
||||
if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) {
|
||||
if (skipChecks) {
|
||||
Game::server->Send(stream, UNASSIGNED_SYSTEM_ADDRESS, true);
|
||||
} else {
|
||||
for (auto* player : PlayerManager::GetAllPlayers()) {
|
||||
if (player->GetPlayerReadyForUpdates()) {
|
||||
Game::server->Send(stream, player->GetSystemAddress(), false);
|
||||
} else {
|
||||
auto* ghostComponent = player->GetComponent<GhostComponent>();
|
||||
if (ghostComponent) ghostComponent->AddLimboConstruction(entity->GetObjectID());
|
||||
}
|
||||
for (auto* player : PlayerManager::GetAllPlayers()) {
|
||||
// Don't need to construct the player to themselves
|
||||
if (entity->GetObjectID() == player->GetObjectID()) continue;
|
||||
if (player->GetPlayerReadyForUpdates()) {
|
||||
Game::server->Send(stream, player->GetSystemAddress(), false);
|
||||
} else {
|
||||
auto* ghostComponent = player->GetComponent<GhostComponent>();
|
||||
if (ghostComponent) ghostComponent->AddLimboConstruction(entity->GetObjectID());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@@ -42,7 +42,7 @@ public:
|
||||
const std::unordered_map<LWOOBJID, Entity*> GetAllEntities() const { return m_Entities; }
|
||||
#endif
|
||||
|
||||
void ConstructEntity(Entity* entity, const SystemAddress& sysAddr = UNASSIGNED_SYSTEM_ADDRESS, bool skipChecks = false);
|
||||
void ConstructEntity(Entity* entity, const SystemAddress& sysAddr = UNASSIGNED_SYSTEM_ADDRESS);
|
||||
void DestructEntity(Entity* entity, const SystemAddress& sysAddr = UNASSIGNED_SYSTEM_ADDRESS);
|
||||
void SerializeEntity(Entity* entity);
|
||||
void SerializeEntity(const Entity& entity);
|
||||
|
@@ -334,7 +334,7 @@ bool ActivityComponent::IsPlayedBy(LWOOBJID playerID) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ActivityComponent::TakeCost(Entity* player) const {
|
||||
bool ActivityComponent::CheckCost(Entity* player) const {
|
||||
if (m_ActivityInfo.optionalCostLOT <= 0 || m_ActivityInfo.optionalCostCount <= 0)
|
||||
return true;
|
||||
|
||||
@@ -345,11 +345,19 @@ bool ActivityComponent::TakeCost(Entity* player) const {
|
||||
if (inventoryComponent->GetLotCount(m_ActivityInfo.optionalCostLOT) < m_ActivityInfo.optionalCostCount)
|
||||
return false;
|
||||
|
||||
inventoryComponent->RemoveItem(m_ActivityInfo.optionalCostLOT, m_ActivityInfo.optionalCostCount);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ActivityComponent::TakeCost(Entity* player) const{
|
||||
|
||||
auto* inventoryComponent = player->GetComponent<InventoryComponent>();
|
||||
if (CheckCost(player)) {
|
||||
inventoryComponent->RemoveItem(m_ActivityInfo.optionalCostLOT, m_ActivityInfo.optionalCostCount);
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
void ActivityComponent::PlayerReady(Entity* player, bool bReady) {
|
||||
for (Lobby* lobby : m_Queue) {
|
||||
for (LobbyPlayer* lobbyPlayer : lobby->players) {
|
||||
@@ -382,7 +390,7 @@ ActivityInstance* ActivityComponent::NewInstance() {
|
||||
void ActivityComponent::LoadPlayersIntoInstance(ActivityInstance* instance, const std::vector<LobbyPlayer*>& lobby) const {
|
||||
for (LobbyPlayer* player : lobby) {
|
||||
auto* entity = player->GetEntity();
|
||||
if (entity == nullptr || !TakeCost(entity)) {
|
||||
if (entity == nullptr || !CheckCost(entity)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@@ -234,10 +234,17 @@ public:
|
||||
*/
|
||||
bool IsPlayedBy(LWOOBJID playerID) const;
|
||||
|
||||
/**
|
||||
* Checks if the entity has enough cost to play this activity
|
||||
* @param player the entity to check
|
||||
* @return true if the entity has enough cost to play this activity, false otherwise
|
||||
*/
|
||||
bool CheckCost(Entity* player) const;
|
||||
|
||||
/**
|
||||
* Removes the cost of the activity (e.g. green imaginate) for the entity that plays this activity
|
||||
* @param player the entity to take cost for
|
||||
* @return true if the cost was successfully deducted, false otherwise
|
||||
* @return true if the cost was taken, false otherwise
|
||||
*/
|
||||
bool TakeCost(Entity* player) const;
|
||||
|
||||
|
@@ -54,6 +54,7 @@ MovementAIComponent::MovementAIComponent(Entity* parent, MovementAIInfo info) :
|
||||
m_SourcePosition = m_Parent->GetPosition();
|
||||
m_Paused = false;
|
||||
m_SavedVelocity = NiPoint3Constant::ZERO;
|
||||
m_IsBounced = false;
|
||||
|
||||
if (!m_Parent->GetComponent<BaseCombatAIComponent>()) SetPath(m_Parent->GetVarAsString(u"attached_path"));
|
||||
}
|
||||
@@ -158,8 +159,9 @@ void MovementAIComponent::Update(const float deltaTime) {
|
||||
if (m_Path->pathBehavior == PathBehavior::Loop) {
|
||||
SetPath(m_Path->pathWaypoints);
|
||||
} else if (m_Path->pathBehavior == PathBehavior::Bounce) {
|
||||
m_IsBounced = !m_IsBounced;
|
||||
std::vector<PathWaypoint> waypoints = m_Path->pathWaypoints;
|
||||
std::reverse(waypoints.begin(), waypoints.end());
|
||||
if (m_IsBounced) std::reverse(waypoints.begin(), waypoints.end());
|
||||
SetPath(waypoints);
|
||||
} else if (m_Path->pathBehavior == PathBehavior::Once) {
|
||||
Stop();
|
||||
|
@@ -321,6 +321,8 @@ private:
|
||||
bool m_Paused;
|
||||
|
||||
NiPoint3 m_SavedVelocity;
|
||||
|
||||
bool m_IsBounced{};
|
||||
};
|
||||
|
||||
#endif // MOVEMENTAICOMPONENT_H
|
||||
|
@@ -42,35 +42,6 @@ std::unordered_map<LWOOBJID, LWOOBJID> PetComponent::activePets{};
|
||||
* Maps all the pet lots to a flag indicating that the player has caught it. All basic pets have been guessed by ObjID
|
||||
* while the faction ones could be checked using their respective missions.
|
||||
*/
|
||||
const std::map<LOT, int32_t> PetComponent::petFlags{
|
||||
{ 3050, 801 }, // Elephant
|
||||
{ 3054, 803 }, // Cat
|
||||
{ 3195, 806 }, // Triceratops
|
||||
{ 3254, 807 }, // Terrier
|
||||
{ 3261, 811 }, // Skunk
|
||||
{ 3672, 813 }, // Bunny
|
||||
{ 3994, 814 }, // Crocodile
|
||||
{ 5635, 815 }, // Doberman
|
||||
{ 5636, 816 }, // Buffalo
|
||||
{ 5637, 818 }, // Robot Dog
|
||||
{ 5639, 819 }, // Red Dragon
|
||||
{ 5640, 820 }, // Tortoise
|
||||
{ 5641, 821 }, // Green Dragon
|
||||
{ 5643, 822 }, // Panda, see mission 786
|
||||
{ 5642, 823 }, // Mantis
|
||||
{ 6720, 824 }, // Warthog
|
||||
{ 3520, 825 }, // Lion, see mission 1318
|
||||
{ 7638, 826 }, // Goat
|
||||
{ 7694, 827 }, // Crab
|
||||
{ 12294, 829 }, // Reindeer
|
||||
{ 12431, 830 }, // Stegosaurus, see mission 1386
|
||||
{ 12432, 831 }, // Saber cat, see mission 1389
|
||||
{ 12433, 832 }, // Gryphon, see mission 1392
|
||||
{ 12434, 833 }, // Alien, see mission 1188
|
||||
// 834: unknown?, see mission 506, 688
|
||||
{ 16210, 836 }, // Ninjago Earth Dragon, see mission 1836
|
||||
{ 13067, 838 }, // Skeleton dragon
|
||||
};
|
||||
|
||||
PetComponent::PetComponent(Entity* parentEntity, uint32_t componentId) : Component{ parentEntity } {
|
||||
m_PetInfo = CDClientManager::GetTable<CDPetComponentTable>()->GetByID(componentId); // TODO: Make reference when safe
|
||||
@@ -556,9 +527,8 @@ void PetComponent::NotifyTamingBuildSuccess(NiPoint3 position) {
|
||||
);
|
||||
|
||||
// Triggers the catch a pet missions
|
||||
if (petFlags.find(m_Parent->GetLOT()) != petFlags.end()) {
|
||||
tamer->GetCharacter()->SetPlayerFlag(petFlags.at(m_Parent->GetLOT()), true);
|
||||
}
|
||||
constexpr auto PET_FLAG_BASE = 800;
|
||||
tamer->GetCharacter()->SetPlayerFlag(PET_FLAG_BASE + m_ComponentId, true);
|
||||
|
||||
auto* missionComponent = tamer->GetComponent<MissionComponent>();
|
||||
|
||||
|
@@ -250,11 +250,6 @@ private:
|
||||
*/
|
||||
static std::unordered_map<LWOOBJID, LWOOBJID> currentActivities;
|
||||
|
||||
/**
|
||||
* Flags that indicate that a player has tamed a pet, indexed by the LOT of the pet
|
||||
*/
|
||||
static const std::map<LOT, int32_t> petFlags;
|
||||
|
||||
/**
|
||||
* The ID of the component in the pet component table
|
||||
*/
|
||||
|
@@ -272,6 +272,10 @@ void PropertyManagementComponent::OnStartBuilding() {
|
||||
model->HandleMsg(reset);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto* const entity : Game::entityManager->GetEntitiesInGroup("SpawnedPropertyEnemies")) {
|
||||
if (entity) entity->Smash();
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyManagementComponent::OnFinishBuilding() {
|
||||
@@ -296,6 +300,10 @@ void PropertyManagementComponent::OnFinishBuilding() {
|
||||
model->HandleMsg(reset);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto* const entity : Game::entityManager->GetEntitiesInGroup("SpawnedPropertyEnemies")) {
|
||||
if (entity) entity->Smash();
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyManagementComponent::UpdateModelPosition(const LWOOBJID id, const NiPoint3 position, NiQuaternion rotation) {
|
||||
|
@@ -84,9 +84,11 @@ void Strip::HandleMsg(MigrateActionsMessage& msg) {
|
||||
|
||||
template<>
|
||||
void Strip::HandleMsg(GameMessages::RequestUse& msg) {
|
||||
if (m_PausedTime > 0.0f) return;
|
||||
if (m_PausedTime > 0.0f || !HasMinimumActions()) return;
|
||||
|
||||
if (m_Actions[m_NextActionIndex].GetType() == "OnInteract") {
|
||||
auto& nextAction = GetNextAction();
|
||||
|
||||
if (nextAction.GetType() == "OnInteract") {
|
||||
IncrementAction();
|
||||
m_WaitingForAction = false;
|
||||
}
|
||||
@@ -113,7 +115,9 @@ void Strip::Spawn(LOT lot, Entity& entity) {
|
||||
info.pos = entity.GetPosition();
|
||||
info.rot = NiQuaternionConstant::IDENTITY;
|
||||
info.spawnerID = entity.GetObjectID();
|
||||
Game::entityManager->ConstructEntity(Game::entityManager->CreateEntity(info, nullptr, &entity));
|
||||
auto* const spawnedEntity = Game::entityManager->CreateEntity(info, nullptr, &entity);
|
||||
spawnedEntity->AddToGroup("SpawnedPropertyEnemies");
|
||||
Game::entityManager->ConstructEntity(spawnedEntity);
|
||||
}
|
||||
|
||||
// Spawns a specific drop for all
|
||||
@@ -139,6 +143,7 @@ void Strip::ProcNormalAction(float deltaTime, ModelComponent& modelComponent) {
|
||||
|
||||
// Default velocity is 3 units per second.
|
||||
entity.SetVelocity(NiPoint3{0.0f, isFlyDown ? -3.0f : 3.0f, 0.0f});
|
||||
modelComponent.SetVelocity(NiPoint3{0.0f, isFlyDown ? -3.0f : 3.0f, 0.0f});
|
||||
}
|
||||
else if (nextActionType == "MoveRight" || nextActionType == "MoveLeft") {
|
||||
bool isMoveLeft = nextActionType == "MoveLeft";
|
||||
@@ -205,7 +210,6 @@ void Strip::ProcNormalAction(float deltaTime, ModelComponent& modelComponent) {
|
||||
LOG("Tried to play action (%s) which is not supported.", nextActionType.data());
|
||||
g_WarnedActions.insert(nextActionType.data());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
IncrementAction();
|
||||
@@ -259,13 +263,19 @@ bool Strip::CheckMovement(float deltaTime, ModelComponent& modelComponent) {
|
||||
}
|
||||
|
||||
void Strip::Update(float deltaTime, ModelComponent& modelComponent) {
|
||||
// No point in running a strip with only one action.
|
||||
// Strips are also designed to have 2 actions or more to run.
|
||||
if (!HasMinimumActions()) return;
|
||||
|
||||
if (!CheckMovement(deltaTime, modelComponent)) return;
|
||||
|
||||
// Don't run this strip if we're paused.
|
||||
m_PausedTime -= deltaTime;
|
||||
if (m_PausedTime > 0.0f) return;
|
||||
|
||||
m_PausedTime = 0.0f;
|
||||
|
||||
// Return here if we're waiting for external interactions to continue.
|
||||
if (m_WaitingForAction) return;
|
||||
|
||||
auto& entity = *modelComponent.GetParent();
|
||||
|
@@ -37,6 +37,9 @@ public:
|
||||
void SpawnDrop(LOT dropLOT, Entity& entity);
|
||||
void ProcNormalAction(float deltaTime, ModelComponent& modelComponent);
|
||||
void RemoveStates(ModelComponent& modelComponent) const;
|
||||
|
||||
// 2 actions are required for strips to work
|
||||
bool HasMinimumActions() const { return m_Actions.size() >= 2; }
|
||||
private:
|
||||
// Indicates this Strip is waiting for an action to be taken upon it to progress to its actions
|
||||
bool m_WaitingForAction{ false };
|
||||
|
Reference in New Issue
Block a user