Merge branch 'main' into npc-pathing

This commit is contained in:
Aaron Kimbre
2022-11-03 15:39:17 -05:00
603 changed files with 1775 additions and 350 deletions

View File

@@ -44,13 +44,19 @@ foreach(file ${DGAME_DMISSION_SOURCES})
set(DGAME_SOURCES ${DGAME_SOURCES} "dMission/${file}")
endforeach()
add_subdirectory(dPropertyBehaviors)
foreach(file ${DGAME_DPROPERTYBEHAVIORS_SOURCES})
set(DGAME_SOURCES ${DGAME_SOURCES} "dPropertyBehaviors/${file}")
endforeach()
add_subdirectory(dUtilities)
foreach(file ${DGAME_DUTILITIES_SOURCES})
set(DGAME_SOURCES ${DGAME_SOURCES} "dUtilities/${file}")
endforeach()
foreach(file ${DSCRIPT_SOURCES})
foreach(file ${DSCRIPTS_SOURCES})
set(DGAME_SOURCES ${DGAME_SOURCES} "${PROJECT_SOURCE_DIR}/dScripts/${file}")
endforeach()

View File

@@ -656,7 +656,7 @@ void PropertyManagementComponent::Save() {
return;
}
auto* insertion = Database::CreatePreppedStmt("INSERT INTO properties_contents VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);");
auto* insertion = Database::CreatePreppedStmt("INSERT INTO properties_contents VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);");
auto* update = Database::CreatePreppedStmt("UPDATE properties_contents SET x = ?, y = ?, z = ?, rx = ?, ry = ?, rz = ?, rw = ? WHERE id = ?;");
auto* lookup = Database::CreatePreppedStmt("SELECT id FROM properties_contents WHERE property_id = ?;");
auto* remove = Database::CreatePreppedStmt("DELETE FROM properties_contents WHERE id = ?;");
@@ -706,6 +706,13 @@ void PropertyManagementComponent::Save() {
insertion->setDouble(9, rotation.y);
insertion->setDouble(10, rotation.z);
insertion->setDouble(11, rotation.w);
insertion->setString(12, "Objects_" + std::to_string(entity->GetLOT()) + "_name"); // Model name. TODO make this customizable
insertion->setString(13, ""); // Model description. TODO implement this.
insertion->setDouble(14, 0); // behavior 1. TODO implement this.
insertion->setDouble(15, 0); // behavior 2. TODO implement this.
insertion->setDouble(16, 0); // behavior 3. TODO implement this.
insertion->setDouble(17, 0); // behavior 4. TODO implement this.
insertion->setDouble(18, 0); // behavior 5. TODO implement this.
try {
insertion->execute();
} catch (sql::SQLException& ex) {

View File

@@ -68,6 +68,8 @@
#include "PropertyVendorComponent.h"
#include "PropertySelectQueryProperty.h"
#include "TradingManager.h"
#include "ControlBehaviors.h"
#include "AMFDeserialize.h"
void GameMessages::SendFireEventClientSide(const LWOOBJID& objectID, const SystemAddress& sysAddr, std::u16string args, const LWOOBJID& object, int64_t param1, int param2, const LWOOBJID& sender) {
CBITSTREAM;
@@ -2396,8 +2398,24 @@ void GameMessages::SendUnSmash(Entity* entity, LWOOBJID builderID, float duratio
}
void GameMessages::HandleControlBehaviors(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) {
// TODO
Game::logger->Log("GameMessages", "Recieved Control Behavior GameMessage, but property behaviors are unimplemented.");
AMFDeserialize reader;
std::unique_ptr<AMFValue> amfArguments(reader.Read(inStream));
if (amfArguments->GetValueType() != AMFValueType::AMFArray) return;
uint32_t commandLength{};
inStream->Read(commandLength);
std::string command;
for (uint32_t i = 0; i < commandLength; i++) {
unsigned char character;
inStream->Read(character);
command.push_back(character);
}
auto owner = PropertyManagementComponent::Instance()->GetOwner();
if (!owner) return;
ControlBehaviors::ProcessCommand(entity, sysAddr, static_cast<AMFArrayValue*>(amfArguments.get()), command, owner);
}
void GameMessages::HandleBBBSaveRequest(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) {
@@ -2545,7 +2563,7 @@ void GameMessages::HandleBBBSaveRequest(RakNet::BitStream* inStream, Entity* ent
delete ugcs;
//Insert into the db as a BBB model:
auto* stmt = Database::CreatePreppedStmt("INSERT INTO `properties_contents`(`id`, `property_id`, `ugc_id`, `lot`, `x`, `y`, `z`, `rx`, `ry`, `rz`, `rw`) VALUES (?,?,?,?,?,?,?,?,?,?,?)");
auto* stmt = Database::CreatePreppedStmt("INSERT INTO `properties_contents` VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
stmt->setUInt64(1, newIDL);
stmt->setUInt64(2, propertyId);
stmt->setUInt(3, blueprintIDSmall);
@@ -2557,6 +2575,13 @@ void GameMessages::HandleBBBSaveRequest(RakNet::BitStream* inStream, Entity* ent
stmt->setDouble(9, 0.0f); // ry
stmt->setDouble(10, 0.0f); // rz
stmt->setDouble(11, 0.0f); // rw
stmt->setString(12, "Objects_14_name"); // Model name. TODO make this customizable
stmt->setString(13, ""); // Model description. TODO implement this.
stmt->setDouble(14, 0); // behavior 1. TODO implement this.
stmt->setDouble(15, 0); // behavior 2. TODO implement this.
stmt->setDouble(16, 0); // behavior 3. TODO implement this.
stmt->setDouble(17, 0); // behavior 4. TODO implement this.
stmt->setDouble(18, 0); // behavior 5. TODO implement this.
stmt->execute();
delete stmt;

View File

@@ -13,6 +13,7 @@
#include "PossessableComponent.h"
#include "CharacterComponent.h"
#include "eItemType.h"
#include "AssetManager.h"
class Inventory;
@@ -340,18 +341,23 @@ void Item::DisassembleModel() {
std::string renderAsset = result.fieldIsNull(0) ? "" : std::string(result.getStringField(0));
std::vector<std::string> renderAssetSplit = GeneralUtils::SplitString(renderAsset, '\\');
std::string lxfmlPath = "res/BrickModels/" + GeneralUtils::SplitString(renderAssetSplit.back(), '.')[0] + ".lxfml";
std::ifstream file(lxfmlPath);
std::string lxfmlPath = "BrickModels/" + GeneralUtils::SplitString(renderAssetSplit.back(), '.').at(0) + ".lxfml";
auto buffer = Game::assetManager->GetFileAsBuffer(lxfmlPath.c_str());
std::istream file(&buffer);
result.finalize();
if (!file.good()) {
buffer.close();
return;
}
std::stringstream data;
data << file.rdbuf();
buffer.close();
if (data.str().empty()) {
return;
}

View File

@@ -0,0 +1,4 @@
set(DGAME_DPROPERTYBEHAVIORS_SOURCES
"ControlBehaviors.cpp"
PARENT_SCOPE
)

View File

@@ -0,0 +1,81 @@
#include "ControlBehaviors.h"
#include "AMFFormat.h"
#include "Entity.h"
#include "Game.h"
#include "GameMessages.h"
#include "ModelComponent.h"
#include "dLogger.h"
void ControlBehaviors::ProcessCommand(Entity* modelEntity, const SystemAddress& sysAddr, AMFArrayValue* arguments, std::string command, Entity* modelOwner) {
if (!modelEntity || !modelOwner || !arguments) return;
if (command == "sendBehaviorListToClient")
SendBehaviorListToClient(modelEntity, sysAddr, modelOwner);
else if (command == "modelTypeChanged")
Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str());
else if (command == "toggleExecutionUpdates")
Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str());
else if (command == "addStrip")
Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str());
else if (command == "removeStrip")
Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str());
else if (command == "mergeStrips")
Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str());
else if (command == "splitStrip")
Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str());
else if (command == "updateStripUI")
Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str());
else if (command == "addAction")
Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str());
else if (command == "migrateActions")
Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str());
else if (command == "rearrangeStrip")
Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str());
else if (command == "add")
Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str());
else if (command == "removeActions")
Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str());
else if (command == "rename")
Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str());
else if (command == "sendBehaviorBlocksToClient")
Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str());
else if (command == "moveToInventory")
Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str());
else if (command == "updateAction")
Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str());
else
Game::logger->Log("ControlBehaviors", "Unknown behavior command (%s)\n", command.c_str());
}
void ControlBehaviors::SendBehaviorListToClient(
Entity* modelEntity,
const SystemAddress& sysAddr,
Entity* modelOwner
) {
auto* modelComponent = modelEntity->GetComponent<ModelComponent>();
if (!modelComponent) return;
AMFArrayValue behaviorsToSerialize;
AMFArrayValue* behaviors = new AMFArrayValue(); // Empty for now
/**
* The behaviors AMFArray will have up to 5 elements in the dense portion.
* Each element in the dense portion will be made up of another AMFArray
* with the following information mapped in the associative portion
* "id": Behavior ID cast to an AMFString
* "isLocked": AMFTrue or AMFFalse of whether or not the behavior is locked
* "isLoot": AMFTrue or AMFFalse of whether or not the behavior is a custom behavior (true if custom)
* "name": The name of the behavior formatted as an AMFString
*/
behaviorsToSerialize.InsertValue("behaviors", behaviors);
AMFStringValue* amfStringValueForObjectID = new AMFStringValue();
amfStringValueForObjectID->SetStringValue(std::to_string(modelComponent->GetParent()->GetObjectID()));
behaviorsToSerialize.InsertValue("objectID", amfStringValueForObjectID);
GameMessages::SendUIMessageServerToSingleClient(modelOwner, sysAddr, "UpdateBehaviorList", &behaviorsToSerialize);
}

View File

@@ -0,0 +1,35 @@
#pragma once
#ifndef __CONTROLBEHAVIORS__H__
#define __CONTROLBEHAVIORS__H__
#include <string>
#include "RakNetTypes.h"
class Entity;
class AMFArrayValue;
namespace ControlBehaviors {
/**
* @brief Main driver for processing Property Behavior commands
*
* @param modelEntity The model that sent this command
* @param sysAddr The SystemAddress to respond to
* @param arguments The arguments formatted as an AMFArrayValue
* @param command The command to perform
* @param modelOwner The owner of the model which sent this command
*/
void ProcessCommand(Entity* modelEntity, const SystemAddress& sysAddr, AMFArrayValue* arguments, std::string command, Entity* modelOwner);
/**
* @brief Helper function to send the behavior list to the client
*
* @param modelEntity The model that sent this command
* @param sysAddr The SystemAddress to respond to
* @param modelOwner The owner of the model which sent this command
*/
void SendBehaviorListToClient(Entity* modelEntity, const SystemAddress& sysAddr, Entity* modelOwner);
};
#endif //!__CONTROLBEHAVIORS__H__

View File

@@ -3,6 +3,7 @@
#include "BrickDatabase.h"
#include "Game.h"
#include "AssetManager.h"
std::vector<Brick> BrickDatabase::emptyCache{};
BrickDatabase* BrickDatabase::m_Address = nullptr;
@@ -17,7 +18,8 @@ std::vector<Brick>& BrickDatabase::GetBricks(const std::string& lxfmlPath) {
return cached->second;
}
std::ifstream file(lxfmlPath);
AssetMemoryBuffer buffer = Game::assetManager->GetFileAsBuffer(("client/" + lxfmlPath).c_str());
std::istream file(&buffer);
if (!file.good()) {
return emptyCache;
}
@@ -25,9 +27,12 @@ std::vector<Brick>& BrickDatabase::GetBricks(const std::string& lxfmlPath) {
std::stringstream data;
data << file.rdbuf();
if (data.str().empty()) {
buffer.close();
return emptyCache;
}
buffer.close();
auto* doc = new tinyxml2::XMLDocument();
if (doc->Parse(data.str().c_str(), data.str().size()) != 0) {
delete doc;

View File

@@ -63,6 +63,7 @@
#include "GameConfig.h"
#include "ScriptedActivityComponent.h"
#include "LevelProgressionComponent.h"
#include "AssetManager.h"
void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entity* entity, const SystemAddress& sysAddr) {
std::string chatCommand;
@@ -582,7 +583,8 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
if (args[0].find("/") != std::string::npos) return;
if (args[0].find("\\") != std::string::npos) return;
std::ifstream infile("./res/macros/" + args[0] + ".scm");
auto buf = Game::assetManager->GetFileAsBuffer(("macros/" + args[0] + ".scm").c_str());
std::istream infile(&buf);
if (infile.good()) {
std::string line;
@@ -593,6 +595,8 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
ChatPackets::SendSystemMessage(sysAddr, u"Unknown macro! Is the filename right?");
}
buf.close();
return;
}
@@ -1904,10 +1908,7 @@ bool SlashCommandHandler::CheckIfAccessibleZone(const unsigned int zoneID) {
CDZoneTableTable* zoneTable = CDClientManager::Instance()->GetTable<CDZoneTableTable>("ZoneTable");
const CDZoneTable* zone = zoneTable->Query(zoneID);
if (zone != nullptr) {
std::string zonePath = "./res/maps/" + zone->zoneName;
std::transform(zonePath.begin(), zonePath.end(), zonePath.begin(), ::tolower);
std::ifstream f(zonePath.c_str());
return f.good();
return Game::assetManager->HasFile(("maps/" + zone->zoneName).c_str());
} else {
return false;
}