mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-06-21 14:14:22 +00:00
feat: testmap improvements (#2009)
* feat: testmap improvements fixes #1191 removed the force flag because it would only work to let you softlock your character. tested that taking the lego club door now spawns you at the lego club/ns lego club doors always vs letting you spawn where ever. tested that a testmap no longer spawns you where you last were in a zone and instead spawns you at the spawn point inspect allows you to inspect zoneControl and localCharacter now updated docs with the new info * Update Entity.cpp
This commit is contained in:
@@ -316,15 +316,16 @@ void Entity::Initialize() {
|
|||||||
controllablePhysics->LoadFromXml(m_Character->GetXMLDoc());
|
controllablePhysics->LoadFromXml(m_Character->GetXMLDoc());
|
||||||
|
|
||||||
const auto mapID = Game::server->GetZoneID();
|
const auto mapID = Game::server->GetZoneID();
|
||||||
|
const auto& targetSceneName = m_Character->GetTargetScene();
|
||||||
|
|
||||||
//If we came from another zone, put us in the starting loc
|
//If we came from another zone, put us in the starting loc
|
||||||
if (m_Character->GetZoneID() != Game::server->GetZoneID() || mapID == 1603) { // Exception for Moon Base as you tend to spawn on the roof.
|
// Exception for Moon Base as you tend to spawn on the roof.
|
||||||
|
// second exception if we have a specified targetScene since that would only be possible in a test map
|
||||||
|
if (m_Character->GetZoneID() != Game::server->GetZoneID() || mapID == 1603 || !targetSceneName.empty()) {
|
||||||
NiPoint3 pos;
|
NiPoint3 pos;
|
||||||
NiQuaternion rot = QuatUtils::IDENTITY;
|
NiQuaternion rot = QuatUtils::IDENTITY;
|
||||||
|
|
||||||
const auto& targetSceneName = m_Character->GetTargetScene();
|
|
||||||
auto* targetScene = Game::entityManager->GetSpawnPointEntity(targetSceneName);
|
auto* targetScene = Game::entityManager->GetSpawnPointEntity(targetSceneName);
|
||||||
|
|
||||||
if (m_Character->HasBeenToWorld(mapID) && targetSceneName.empty()) {
|
if (m_Character->HasBeenToWorld(mapID) && targetSceneName.empty()) {
|
||||||
pos = m_Character->GetRespawnPoint(mapID);
|
pos = m_Character->GetRespawnPoint(mapID);
|
||||||
rot = Game::zoneManager->GetZone()->GetSpawnRot();
|
rot = Game::zoneManager->GetZone()->GetSpawnRot();
|
||||||
|
|||||||
@@ -261,7 +261,7 @@ void SlashCommandHandler::Startup() {
|
|||||||
|
|
||||||
Command TestMapCommand{
|
Command TestMapCommand{
|
||||||
.help = "Transfers you to the given zone",
|
.help = "Transfers you to the given zone",
|
||||||
.info = "Transfers you to the given zone by id and clone id. Add \"force\" to skip checking if the zone is accessible (this can softlock your character, though, if you e.g. try to teleport to Frostburgh).",
|
.info = "Transfers you to the given zone by id and clone id and then spawns you at the specified spawn point if one was specified. Ignores instance-id for now.",
|
||||||
.aliases = { "testmap", "tm" },
|
.aliases = { "testmap", "tm" },
|
||||||
.handle = DEVGMCommands::TestMap,
|
.handle = DEVGMCommands::TestMap,
|
||||||
.requiredLevel = eGameMasterLevel::FORUM_MODERATOR
|
.requiredLevel = eGameMasterLevel::FORUM_MODERATOR
|
||||||
@@ -468,7 +468,7 @@ void SlashCommandHandler::Startup() {
|
|||||||
|
|
||||||
Command InspectCommand{
|
Command InspectCommand{
|
||||||
.help = "Inspect an object",
|
.help = "Inspect an object",
|
||||||
.info = "Finds the closest entity with the given component or LNV variable (ignoring players and racing cars), printing its ID, distance from the player, and whether it is sleeping, as well as the the IDs of all components the entity has. See detailed usage in the DLU docs",
|
.info = "Finds the closest entity with the given component or LNV variable (ignoring players and racing cars), printing its ID, distance from the player, and whether it is sleeping, as well as the IDs of all components the entity has. Use `localCharacter` or `zoneControl` to inspect your current character or the zone control object.",
|
||||||
.aliases = { "inspect" },
|
.aliases = { "inspect" },
|
||||||
.handle = DEVGMCommands::Inspect,
|
.handle = DEVGMCommands::Inspect,
|
||||||
.requiredLevel = eGameMasterLevel::DEVELOPER
|
.requiredLevel = eGameMasterLevel::DEVELOPER
|
||||||
|
|||||||
@@ -1051,7 +1051,8 @@ namespace DEVGMCommands {
|
|||||||
|
|
||||||
ChatPackets::SendSystemMessage(sysAddr, u"Requesting map change...");
|
ChatPackets::SendSystemMessage(sysAddr, u"Requesting map change...");
|
||||||
LWOCLONEID cloneId = 0;
|
LWOCLONEID cloneId = 0;
|
||||||
bool force = false;
|
LWOINSTANCEID instanceID{};
|
||||||
|
std::string targetScene;
|
||||||
|
|
||||||
const auto reqZoneOptional = GeneralUtils::TryParse<LWOMAPID>(splitArgs[0]);
|
const auto reqZoneOptional = GeneralUtils::TryParse<LWOMAPID>(splitArgs[0]);
|
||||||
if (!reqZoneOptional) {
|
if (!reqZoneOptional) {
|
||||||
@@ -1061,29 +1062,34 @@ namespace DEVGMCommands {
|
|||||||
const LWOMAPID reqZone = reqZoneOptional.value();
|
const LWOMAPID reqZone = reqZoneOptional.value();
|
||||||
|
|
||||||
if (splitArgs.size() > 1) {
|
if (splitArgs.size() > 1) {
|
||||||
auto index = 1;
|
const auto cloneIdOptional = GeneralUtils::TryParse<LWOCLONEID>(splitArgs[1]);
|
||||||
|
|
||||||
if (splitArgs[index] == "force") {
|
|
||||||
index++;
|
|
||||||
|
|
||||||
force = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (splitArgs.size() > index) {
|
|
||||||
const auto cloneIdOptional = GeneralUtils::TryParse<LWOCLONEID>(splitArgs[index]);
|
|
||||||
if (!cloneIdOptional) {
|
if (!cloneIdOptional) {
|
||||||
ChatPackets::SendSystemMessage(sysAddr, u"Invalid clone id.");
|
ChatPackets::SendSystemMessage(sysAddr, u"Invalid clone id.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cloneId = cloneIdOptional.value();
|
cloneId = cloneIdOptional.value();
|
||||||
|
|
||||||
|
if (splitArgs.size() > 2) {
|
||||||
|
const auto instanceIDVal = GeneralUtils::TryParse<LWOINSTANCEID>(splitArgs[2]);
|
||||||
|
if (!instanceIDVal) {
|
||||||
|
ChatPackets::SendSystemMessage(sysAddr, u"Invalid instance id.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
instanceID = instanceIDVal.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (splitArgs.size() > 3) {
|
||||||
|
targetScene = splitArgs[3];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto objid = entity->GetObjectID();
|
const auto objid = entity->GetObjectID();
|
||||||
|
|
||||||
if (force || Game::zoneManager->CheckIfAccessibleZone(reqZone)) { // to prevent tomfoolery
|
if (Game::zoneManager->CheckIfAccessibleZone(reqZone)) { // to prevent tomfoolery
|
||||||
|
|
||||||
ZoneInstanceManager::Instance()->RequestZoneTransfer(Game::server, reqZone, cloneId, false, [objid](bool mythranShift, uint32_t zoneID, uint32_t zoneInstance, uint32_t zoneClone, std::string serverIP, uint16_t serverPort) {
|
ZoneInstanceManager::Instance()->RequestZoneTransfer(Game::server, reqZone, cloneId, false, [objid, targetScene](bool mythranShift, uint32_t zoneID, uint32_t zoneInstance, uint32_t zoneClone, std::string serverIP, uint16_t serverPort) {
|
||||||
|
|
||||||
auto* entity = Game::entityManager->GetEntity(objid);
|
auto* entity = Game::entityManager->GetEntity(objid);
|
||||||
if (!entity) return;
|
if (!entity) return;
|
||||||
@@ -1101,6 +1107,7 @@ namespace DEVGMCommands {
|
|||||||
entity->GetCharacter()->SetZoneID(zoneID);
|
entity->GetCharacter()->SetZoneID(zoneID);
|
||||||
entity->GetCharacter()->SetZoneInstance(zoneInstance);
|
entity->GetCharacter()->SetZoneInstance(zoneInstance);
|
||||||
entity->GetCharacter()->SetZoneClone(zoneClone);
|
entity->GetCharacter()->SetZoneClone(zoneClone);
|
||||||
|
entity->GetCharacter()->SetTargetScene(targetScene);
|
||||||
entity->GetComponent<CharacterComponent>()->SetLastRocketConfig(u"");
|
entity->GetComponent<CharacterComponent>()->SetLastRocketConfig(u"");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1513,7 +1520,15 @@ namespace DEVGMCommands {
|
|||||||
void Inspect(Entity* entity, const SystemAddress& sysAddr, const std::string args) {
|
void Inspect(Entity* entity, const SystemAddress& sysAddr, const std::string args) {
|
||||||
const auto splitArgs = GeneralUtils::SplitString(args, ' ');
|
const auto splitArgs = GeneralUtils::SplitString(args, ' ');
|
||||||
if (splitArgs.empty()) return;
|
if (splitArgs.empty()) return;
|
||||||
const auto idParsed = GeneralUtils::TryParse<LWOOBJID>(splitArgs[0]);
|
std::optional<LWOOBJID> idIntermed;
|
||||||
|
if (splitArgs[0] == "zoneControl") {
|
||||||
|
idIntermed = 0x3FFF'FFFFFFFE;
|
||||||
|
} else if (splitArgs[0] == "localCharacter") {
|
||||||
|
idIntermed = entity->GetObjectID();
|
||||||
|
} else {
|
||||||
|
idIntermed = GeneralUtils::TryParse<LWOOBJID>(splitArgs[0]);
|
||||||
|
}
|
||||||
|
const auto idParsed = idIntermed;
|
||||||
|
|
||||||
// First try to get the object by its ID if provided.
|
// First try to get the object by its ID if provided.
|
||||||
// Second try to get the object by player name.
|
// Second try to get the object by player name.
|
||||||
|
|||||||
@@ -94,6 +94,9 @@ void BaseConsoleTeleportServer::TransferPlayer(Entity* self, Entity* player, int
|
|||||||
|
|
||||||
const auto& teleportZone = self->GetVar<std::u16string>(u"transferZoneID");
|
const auto& teleportZone = self->GetVar<std::u16string>(u"transferZoneID");
|
||||||
|
|
||||||
|
auto* const character = player->GetCharacter();
|
||||||
|
if (character && self->HasVar(u"spawnPoint")) character->SetTargetScene(self->GetVarAsString(u"spawnPoint"));
|
||||||
|
|
||||||
auto* characterComponent = player->GetComponent<CharacterComponent>();
|
auto* characterComponent = player->GetComponent<CharacterComponent>();
|
||||||
|
|
||||||
if (characterComponent) characterComponent->SendToZone(GeneralUtils::TryParse(GeneralUtils::UTF16ToWTF8(teleportZone), 0));
|
if (characterComponent) characterComponent->SendToZone(GeneralUtils::TryParse(GeneralUtils::UTF16ToWTF8(teleportZone), 0));
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ These commands are primarily for development and testing. The usage of many of t
|
|||||||
|leave-zone|`/leave-zone`|If you are in an instanced zone, transfers you to the closest main world. For example, if you are in an instance of Avant Gardens Survival or the Spider Queen Battle, you are sent to Avant Gardens. If you are in the Battle of Nimbus Station, you are sent to Nimbus Station. Aliases: `/leavezone`.|0|
|
|leave-zone|`/leave-zone`|If you are in an instanced zone, transfers you to the closest main world. For example, if you are in an instance of Avant Gardens Survival or the Spider Queen Battle, you are sent to Avant Gardens. If you are in the Battle of Nimbus Station, you are sent to Nimbus Station. Aliases: `/leavezone`.|0|
|
||||||
|resurrect|`/resurrect`|Resurrects the player.|8|
|
|resurrect|`/resurrect`|Resurrects the player.|8|
|
||||||
|setminifig|`/setminifig <body part> <minifig item id>`|Alters your player's minifig. Body part can be one of "Eyebrows", "Eyes", "HairColor", "HairStyle", "Pants", "LeftHand", "Mouth", "RightHand", "Shirt", or "Hands". Changing minifig parts could break the character so this command is limited to GMs.|1|
|
|setminifig|`/setminifig <body part> <minifig item id>`|Alters your player's minifig. Body part can be one of "Eyebrows", "Eyes", "HairColor", "HairStyle", "Pants", "LeftHand", "Mouth", "RightHand", "Shirt", or "Hands". Changing minifig parts could break the character so this command is limited to GMs.|1|
|
||||||
|testmap|`/testmap <zone> (force) (clone-id)`|Transfers you to the given zone by id and clone id. Add "force" to skip checking if the zone is accessible (this can softlock your character, though, if you e.g. try to teleport to Frostburgh). Aliases: `/tm`.|1|
|
|testmap|`/testmap <zone> (clone-id) (instance-id) (spawn-point)`|Transfers you to the given zone by id and clone id and then spawns you at the specified spawn point if one was specified. Ignores instance-id for now. Aliases: `/tm`.|1|
|
||||||
|reportproxphys|`/reportproxphys`|Prints to console the position and radius of proximity sensors.|9|
|
|reportproxphys|`/reportproxphys`|Prints to console the position and radius of proximity sensors.|9|
|
||||||
|spawnphysicsverts|`/spawnphysicsverts`|Spawns a 1x1 brick at all vertices of phantom physics objects|8|
|
|spawnphysicsverts|`/spawnphysicsverts`|Spawns a 1x1 brick at all vertices of phantom physics objects|8|
|
||||||
|teleport|`/teleport <x/source player> (y) <z/target player>`|Teleports you. If no Y is given, you are teleported to the height of the terrain or physics object at (x, z). Any of the coordinates can use the syntax of an exact position (10.0), or a relative position (~+10.0). A ~ means use the current value of that axis as the base value. Addition or subtraction is supported (~+10) (~-10). If source player and target player are players that exist in the world, then the source player will be teleported to target player. Aliases: `/tele`, `/tp`.|6|
|
|teleport|`/teleport <x/source player> (y) <z/target player>`|Teleports you. If no Y is given, you are teleported to the height of the terrain or physics object at (x, z). Any of the coordinates can use the syntax of an exact position (10.0), or a relative position (~+10.0). A ~ means use the current value of that axis as the base value. Addition or subtraction is supported (~+10) (~-10). If source player and target player are players that exist in the world, then the source player will be teleported to target player. Aliases: `/tele`, `/tp`.|6|
|
||||||
@@ -145,7 +145,7 @@ These commands are primarily for development and testing. The usage of many of t
|
|||||||
|getnavmeshheight|`/getnavmeshheight`|Display the navmesh height at your current position|8|
|
|getnavmeshheight|`/getnavmeshheight`|Display the navmesh height at your current position|8|
|
||||||
|giveuscore|`/giveuscore <uscore>`|Gives uscore|8|
|
|giveuscore|`/giveuscore <uscore>`|Gives uscore|8|
|
||||||
|gmadditem|`/gmadditem <id> (count)`|Adds the given item to your inventory by id. Aliases: `/give`.|8|
|
|gmadditem|`/gmadditem <id> (count)`|Adds the given item to your inventory by id. Aliases: `/give`.|8|
|
||||||
|inspect|`/inspect <component or ldf variable or player name> (-m <waypoint> | -a <animation> | -s | -p | -f (faction) | -t)`|Finds the closest entity with the given component or LNV variable (ignoring players and racing cars), printing its ID, distance from the player, and whether it is sleeping, as well as the IDs of all components the entity has. See detailed usage in the DLU docs|8|
|
|inspect|`/inspect <component or ldf variable or player name> (-m <waypoint> | -a <animation> | -s | -p | -f (faction) | -t)`|Finds the closest entity with the given component or LNV variable (ignoring players and racing cars), printing its ID, distance from the player, and whether it is sleeping, as well as the IDs of all components the entity has. Use `localCharacter` or `zoneControl` to inspect your current character or the zone control object.|8|
|
||||||
|list-spawns|`/list-spawns`|Lists all the character spawn points in the zone. Additionally, this command will display the current scene that plays when the character lands in the next zone, if there is one. Aliases: `/listspawns`.|8|
|
|list-spawns|`/list-spawns`|Lists all the character spawn points in the zone. Additionally, this command will display the current scene that plays when the character lands in the next zone, if there is one. Aliases: `/listspawns`.|8|
|
||||||
|locrow|`/locrow`|Prints your current position and rotation information to the console|8|
|
|locrow|`/locrow`|Prints your current position and rotation information to the console|8|
|
||||||
|lookup|`/lookup <query>`|Searches through the Objects table in the client SQLite database for items whose display name, name, or description contains the query. Query can be multiple words delimited by spaces.|8|
|
|lookup|`/lookup <query>`|Searches through the Objects table in the client SQLite database for items whose display name, name, or description contains the query. Query can be multiple words delimited by spaces.|8|
|
||||||
|
|||||||
Reference in New Issue
Block a user