Ability export parity
This commit is contained in:
parent
46531fa65a
commit
7be649b56b
@ -1,9 +0,0 @@
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: release
|
||||
|
||||
steps:
|
||||
- name: greeting
|
||||
image: alpine
|
||||
commands:
|
||||
- echo "hello world"
|
||||
@ -1,4 +1,4 @@
|
||||
cmake_minimum_required(VERSION 3.27)
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
project(ISXMr VERSION 1.0.0 LANGUAGES CXX)
|
||||
|
||||
# Include the FetchContent module
|
||||
@ -86,8 +86,15 @@ add_library(ISXMr SHARED ${SOURCE_DIR}/ISXMr.cpp
|
||||
src/Commands/CommandExecutor.h
|
||||
src/BotSettings/ExportedAbility.h
|
||||
includes/argh/argh.h
|
||||
includes/picojson/picojson.h
|
||||
src/isxeq2/EQ2.h)
|
||||
src/isxeq2/EQ2.h
|
||||
src/Api/ForWho.h
|
||||
src/isxeq2/GroupMember.cpp
|
||||
src/isxeq2/GroupMember.h
|
||||
src/Api/MrBotApi.cpp
|
||||
src/Api/MrBotApi.h
|
||||
includes/json_struct/json_struct.h
|
||||
includes/json_struct/json_struct_diff.h
|
||||
)
|
||||
|
||||
IF (WIN32)
|
||||
cmake_host_system_information(
|
||||
@ -109,19 +116,12 @@ IF (WIN32)
|
||||
endif ()
|
||||
|
||||
# Set the path to additional libraries
|
||||
set(LIBS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libs/)
|
||||
set(INCLUDES_DIR ${CMAKE_CURRENT_SOURCE_DIR}/includes/)
|
||||
set(LIBS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libs)
|
||||
set(INCLUDES_DIR ${CMAKE_CURRENT_SOURCE_DIR}/includes)
|
||||
set(ISXDK_LIBRARY ${LIBS_DIR}/isxdk/lib64/vs16/ISXDK.lib)
|
||||
|
||||
# Find isxdk library
|
||||
find_library(ISXDK_LIBRARY ISXDK HINTS ${LIBS_DIR}/isxdk/lib64/vs16)
|
||||
if (NOT ISXDK_LIBRARY)
|
||||
message(FATAL_ERROR "isxdk library not found")
|
||||
endif ()
|
||||
set(ISUI_LIBRARY ${LIBS_DIR}/isxdk/lib64/vs16/ISUI.lib)
|
||||
|
||||
find_library(ISUI_LIBRARY ISUI HINTS ${LIBS_DIR}/isxdk/lib64/vs16)
|
||||
if (NOT ISUI_LIBRARY)
|
||||
message(FATAL_ERROR "isxui library not found")
|
||||
endif ()
|
||||
|
||||
# Set include directories for isxdk
|
||||
include_directories(${LIBS_DIR}/isxdk/include)
|
||||
@ -131,7 +131,7 @@ include_directories(${INCLUDES_DIR})
|
||||
|
||||
# Link ISXMr with isxdk library
|
||||
target_link_libraries(ISXMr PRIVATE ${ISUI_LIBRARY} ${ISXDK_LIBRARY})
|
||||
|
||||
target_compile_definitions(ISXMr PRIVATE NOMINMAX JS_STL_MAP)
|
||||
# Set the output directory for the shared library
|
||||
set_target_properties(ISXMr PROPERTIES
|
||||
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin
|
||||
@ -139,22 +139,4 @@ set_target_properties(ISXMr PROPERTIES
|
||||
|
||||
set_property(TARGET ISXMr PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
||||
|
||||
IF (WIN32)
|
||||
cmake_host_system_information(
|
||||
RESULT InnerspacePath
|
||||
QUERY WINDOWS_REGISTRY
|
||||
"HKLM/SOFTWARE/WOW6432Node/Microsoft/Windows/CurrentVersion/App Paths/InnerSpace.exe"
|
||||
VALUE
|
||||
"PATH"
|
||||
)
|
||||
if (InnerspacePath)
|
||||
message(STATUS "Copying isxmr.dll to ${InnerspacePath}")
|
||||
# Normalize the path (optional, but recommended)
|
||||
file(TO_CMAKE_PATH "${InnerspacePath}/x64/Extensions/ISXDK35" NormalizedInnerspacePath)
|
||||
|
||||
add_custom_command(TARGET ISXMr POST_BUILD
|
||||
COMMENT "Copying isxmr.dll to ${NormalizedInnerspacePath}"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:ISXMr> "${NormalizedInnerspacePath}/ISXMr.dll"
|
||||
)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
9164
includes/json_struct/json_struct.h
Normal file
9164
includes/json_struct/json_struct.h
Normal file
File diff suppressed because it is too large
Load Diff
882
includes/json_struct/json_struct_diff.h
Normal file
882
includes/json_struct/json_struct_diff.h
Normal file
@ -0,0 +1,882 @@
|
||||
/*
|
||||
* Copyright © 2018 Øystein Myrmo
|
||||
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting documentation, and
|
||||
* that the name of the copyright holders not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no representations
|
||||
* about the suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
|
||||
/*! \mainpage json_struct_diff
|
||||
*
|
||||
* json_struct_diff is an extension to json_struct to efficiently diff json by
|
||||
* using json_struct itself.
|
||||
*/
|
||||
|
||||
#ifndef JSON_STRUCT_DIFF_H
|
||||
#define JSON_STRUCT_DIFF_H
|
||||
|
||||
#include "json_struct.h"
|
||||
|
||||
namespace JS {
|
||||
|
||||
enum DiffFlags : unsigned char
|
||||
{
|
||||
None,
|
||||
FuzzyFloatComparison
|
||||
};
|
||||
|
||||
enum DiffType : int
|
||||
{
|
||||
NoDiff, // Type and value are equal
|
||||
ValueDiff, // Value has changed
|
||||
TypeDiff, // Type has changed
|
||||
NewMember, // New member in JSON object
|
||||
NewArrayItem, // New item in JSON array
|
||||
MissingMembers, // JSON object is missing one or more members
|
||||
MissingArrayItems, // JSON array is missing one or more items
|
||||
RootItemDiff, // The root items are different
|
||||
ErroneousRootItem // The root item is not Type::ObjectStart or Type::ArrayStart
|
||||
};
|
||||
|
||||
enum DiffError : unsigned char
|
||||
{
|
||||
NoError,
|
||||
NoTokens,
|
||||
EmptyString
|
||||
};
|
||||
|
||||
struct DiffOptions
|
||||
{
|
||||
DiffOptions()
|
||||
{}
|
||||
DiffOptions(DiffFlags flags, double fuzzyEpsilon)
|
||||
: flags(flags)
|
||||
, fuzzyEpsilon(fuzzyEpsilon)
|
||||
{}
|
||||
DiffFlags flags = DiffFlags::FuzzyFloatComparison;
|
||||
double fuzzyEpsilon = 1e-6; // Used if (flags | FuzzyFloatComparison == true)
|
||||
};
|
||||
|
||||
namespace Internal
|
||||
{
|
||||
namespace Diff
|
||||
{
|
||||
inline bool isComplexValue(const Token &token)
|
||||
{
|
||||
return (token.value_type == Type::ObjectStart) || (token.value_type == Type::ArrayStart);
|
||||
}
|
||||
|
||||
struct MissingTokens
|
||||
{
|
||||
Token token;
|
||||
std::vector<Token> missingTokens;
|
||||
|
||||
bool operator ==(const Token& t) const
|
||||
{
|
||||
return (token.name.data == t.name.data) && (token.value.data == t.value.data);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
struct DiffTokens
|
||||
{
|
||||
DiffTokens()
|
||||
{}
|
||||
|
||||
explicit DiffTokens(const char* json, size_t size)
|
||||
{
|
||||
reset(json, size);
|
||||
}
|
||||
|
||||
void reset(const char* json, size_t size)
|
||||
{
|
||||
clear();
|
||||
tokens.data.reserve(50);
|
||||
generateTokens(json, size);
|
||||
diffs.resize(tokens.data.size(), DiffType::NoDiff);
|
||||
meta = metaForTokens(tokens);
|
||||
}
|
||||
|
||||
void invalidate()
|
||||
{
|
||||
missingMembers.clear();
|
||||
diffs.clear();
|
||||
error = DiffError::NoError;
|
||||
diff_count = 0;
|
||||
diffs.resize(tokens.data.size(), DiffType::NoDiff);
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
tokens.data.clear();
|
||||
missingMembers.clear();
|
||||
diffs.clear();
|
||||
meta.clear();
|
||||
error = DiffError::NoError;
|
||||
diff_count = 0;
|
||||
}
|
||||
|
||||
void generateTokens(const char* json, size_t size)
|
||||
{
|
||||
if (size == 0)
|
||||
{
|
||||
error = DiffError::EmptyString;
|
||||
return;
|
||||
}
|
||||
|
||||
Tokenizer tokenizer;
|
||||
tokenizer.addData(json, size);
|
||||
Token token;
|
||||
Error e = Error::NoError;
|
||||
while (e == Error::NoError)
|
||||
{
|
||||
e = tokenizer.nextToken(token);
|
||||
if (e == Error::NoError)
|
||||
tokens.data.emplace_back(token);
|
||||
}
|
||||
if (e == Error::NeedMoreData)
|
||||
error = DiffError::NoError;
|
||||
if (tokens.data.size() == 0)
|
||||
error = DiffError::NoTokens;
|
||||
}
|
||||
|
||||
void skip(size_t *pos) const
|
||||
{
|
||||
assert(*pos < size());
|
||||
if (Internal::Diff::isComplexValue(tokens.data[*pos]))
|
||||
{
|
||||
for (const auto &m : meta)
|
||||
{
|
||||
if (m.position == *pos)
|
||||
{
|
||||
*pos += m.size;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
(*pos)++; // Skip strings, numbers, bools, nulls
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int childCount(size_t pos) const
|
||||
{
|
||||
assert(pos < size());
|
||||
assert(Internal::Diff::isComplexValue(tokens.data[pos]));
|
||||
size_t metaPos;
|
||||
if (getMetaPos(pos, &metaPos))
|
||||
return meta[metaPos].children;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void set(size_t pos, DiffType diff)
|
||||
{
|
||||
assert(pos < tokens.data.size());
|
||||
diffs[pos] = diff;
|
||||
if (diff != DiffType::NoDiff)
|
||||
diff_count++;
|
||||
}
|
||||
|
||||
void setStateForEntireToken(const size_t startPos, DiffType diffType)
|
||||
{
|
||||
assert(startPos < size());
|
||||
set(startPos, diffType);
|
||||
const Token &token = tokens.data[startPos];
|
||||
|
||||
if (token.value_type == Type::ObjectStart || token.value_type == Type::ArrayStart)
|
||||
{
|
||||
size_t pos = startPos + 1;
|
||||
while (true)
|
||||
{
|
||||
const Token ¤tToken = tokens.data[pos];
|
||||
if (currentToken.value_type == Type::ObjectStart || currentToken.value_type == Type::ArrayStart)
|
||||
{
|
||||
setStateForEntireToken(pos, diffType);
|
||||
skip(&pos);
|
||||
}
|
||||
else if (currentToken.value_type == Type::ObjectEnd || currentToken.value_type == Type::ArrayEnd)
|
||||
{
|
||||
set(pos, diffType);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
set(pos, diffType);
|
||||
skip(&pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool getMetaPos(size_t pos, size_t *outPos) const
|
||||
{
|
||||
bool set = false;
|
||||
for (size_t i = 0; i < meta.size(); i++)
|
||||
{
|
||||
if (meta[i].position == pos)
|
||||
{
|
||||
*outPos = i;
|
||||
set = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
void addMissingMembers(const size_t startPos, const DiffTokens& baseTokens, const size_t basePos)
|
||||
{
|
||||
assert(startPos < size());
|
||||
assert(tokens.data[startPos].value_type == JS::Type::ObjectStart);
|
||||
const Token &token = baseTokens.tokens.data[basePos];
|
||||
addMissingToken(startPos, token);
|
||||
|
||||
if (token.value_type == Type::ObjectStart || token.value_type == Type::ArrayStart)
|
||||
{
|
||||
size_t pos = basePos + 1;
|
||||
while (true)
|
||||
{
|
||||
const Token &missingToken = baseTokens.tokens.data[pos];
|
||||
if (missingToken.value_type == Type::ObjectStart || missingToken.value_type == Type::ArrayStart)
|
||||
{
|
||||
addMissingMembers(startPos, baseTokens, pos);
|
||||
baseTokens.skip(&pos);
|
||||
}
|
||||
else if (missingToken.value_type == Type::ObjectEnd || missingToken.value_type == Type::ArrayEnd)
|
||||
{
|
||||
addMissingToken(startPos, missingToken);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
addMissingToken(startPos, missingToken);
|
||||
baseTokens.skip(&pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void addMissingToken(const size_t pos, const Token& missingMember)
|
||||
{
|
||||
assert(pos < tokens.data.size());
|
||||
const Token &objectMissingMember = tokens.data[pos];
|
||||
assert(objectMissingMember.value_type == Type::ObjectStart);
|
||||
|
||||
std::vector<Token>* existing = nullptr;
|
||||
for (auto &m : missingMembers)
|
||||
{
|
||||
if (m == objectMissingMember)
|
||||
{
|
||||
existing = &m.missingTokens;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (existing)
|
||||
{
|
||||
existing->emplace_back(missingMember);
|
||||
}
|
||||
else
|
||||
{
|
||||
Internal::Diff::MissingTokens m;
|
||||
m.token = objectMissingMember;
|
||||
m.missingTokens.reserve(10);
|
||||
m.missingTokens.emplace_back(missingMember);
|
||||
missingMembers.emplace_back(m);
|
||||
}
|
||||
|
||||
set(pos, DiffType::MissingMembers);
|
||||
}
|
||||
|
||||
void addMissingArrayItems(const size_t startPos, const DiffTokens& baseTokens, const size_t basePos)
|
||||
{
|
||||
assert(startPos < size());
|
||||
assert(tokens.data[startPos].value_type == JS::Type::ArrayStart);
|
||||
const Token &token = baseTokens.tokens.data[basePos];
|
||||
addMissingArrayToken(startPos, token);
|
||||
|
||||
if (token.value_type == Type::ObjectStart || token.value_type == Type::ArrayStart)
|
||||
{
|
||||
size_t pos = basePos + 1;
|
||||
while (true)
|
||||
{
|
||||
const Token &missingToken = baseTokens.tokens.data[pos];
|
||||
if (missingToken.value_type == Type::ObjectStart || missingToken.value_type == Type::ArrayStart)
|
||||
{
|
||||
addMissingArrayItems(startPos, baseTokens, pos);
|
||||
baseTokens.skip(&pos);
|
||||
}
|
||||
else if (missingToken.value_type == Type::ObjectEnd || missingToken.value_type == Type::ArrayEnd)
|
||||
{
|
||||
addMissingArrayToken(startPos, missingToken);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
addMissingArrayToken(startPos, missingToken);
|
||||
baseTokens.skip(&pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void addMissingArrayToken(const size_t pos, const Token& missingItem)
|
||||
{
|
||||
assert(pos < tokens.data.size());
|
||||
const Token& arrayMissingItem = tokens.data[pos];
|
||||
assert(arrayMissingItem.value_type == Type::ArrayStart);
|
||||
|
||||
std::vector<Token>* existing = nullptr;
|
||||
for (auto &m : missingArrayItems)
|
||||
{
|
||||
if (m == arrayMissingItem)
|
||||
{
|
||||
existing = &m.missingTokens;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (existing)
|
||||
{
|
||||
existing->emplace_back(missingItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
Internal::Diff::MissingTokens m;
|
||||
m.token = arrayMissingItem;
|
||||
m.missingTokens.reserve(10);
|
||||
m.missingTokens.emplace_back(missingItem);
|
||||
missingArrayItems.emplace_back(m);
|
||||
}
|
||||
|
||||
set(pos, DiffType::MissingArrayItems);
|
||||
}
|
||||
|
||||
size_t size() const
|
||||
{
|
||||
assert(tokens.data.size() == diffs.size());
|
||||
return tokens.data.size();
|
||||
}
|
||||
|
||||
const std::vector<Token>* getMissingTokens(const Token &token, const std::vector<Internal::Diff::MissingTokens>& missingTokens) const
|
||||
{
|
||||
const std::vector<Token>* missing = nullptr;
|
||||
for (auto const& m : missingTokens)
|
||||
{
|
||||
if (m == token)
|
||||
{
|
||||
missing = &m.missingTokens;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return missing;
|
||||
}
|
||||
|
||||
const std::vector<Token>* getMissingMembers(const Token &token) const
|
||||
{
|
||||
return getMissingTokens(token, missingMembers);
|
||||
}
|
||||
|
||||
const std::vector<Token>* getMissingArrayItems(const Token &token) const
|
||||
{
|
||||
return getMissingTokens(token, missingArrayItems);
|
||||
}
|
||||
|
||||
JsonTokens tokens;
|
||||
std::vector<Internal::Diff::MissingTokens> missingMembers;
|
||||
std::vector<Internal::Diff::MissingTokens> missingArrayItems;
|
||||
std::vector<DiffType> diffs; // Equal length to tokens.data array, having diffs in the same order
|
||||
std::vector<JsonMeta> meta;
|
||||
DiffError error;
|
||||
size_t diff_count = 0;
|
||||
};
|
||||
|
||||
namespace Internal
|
||||
{
|
||||
namespace Diff
|
||||
{
|
||||
void diffObjects(const DiffTokens &base, const size_t basePos, DiffTokens &diff, const size_t diffPos, const DiffOptions &options);
|
||||
void diffArrays(const DiffTokens &base, const size_t basePos, DiffTokens &diff, const size_t diffPos, const DiffOptions &options);
|
||||
|
||||
inline bool isSameMember(const Token &base, const Token &diff)
|
||||
{
|
||||
return (base.name_type == diff.name_type)
|
||||
&& (base.name.size == diff.name.size)
|
||||
&& (strncmp(base.name.data, diff.name.data, base.name.size) == 0);
|
||||
}
|
||||
|
||||
inline bool isSameValueType(const Token &base, const Token &diff)
|
||||
{
|
||||
return base.value_type == diff.value_type;
|
||||
}
|
||||
|
||||
inline bool stringValuesEqual(const DataRef &base, const DataRef &diff)
|
||||
{
|
||||
return (base.size == diff.size) && (strncmp(base.data, diff.data, base.size) == 0);
|
||||
}
|
||||
|
||||
inline bool fuzzyEquals(double d1, double d2, double epsilon)
|
||||
{
|
||||
double diff = d2 - d1;
|
||||
return diff > 0 ? (diff <= epsilon) : (-diff <= epsilon);
|
||||
}
|
||||
|
||||
inline void diffStringValues(const Token &baseToken, const Token &diffToken, DiffTokens &diff, const size_t diffPos)
|
||||
{
|
||||
if (stringValuesEqual(baseToken.value, diffToken.value))
|
||||
diff.set(diffPos, DiffType::NoDiff);
|
||||
else
|
||||
diff.set(diffPos, DiffType::ValueDiff);
|
||||
}
|
||||
|
||||
inline void diffNumberValues(const Token &baseToken, const Token &diffToken, DiffTokens &diff, const size_t diffPos, const DiffOptions &options)
|
||||
{
|
||||
double baseValue = std::stod(std::string(baseToken.value.data, baseToken.value.size));
|
||||
double diffValue = std::stod(std::string(diffToken.value.data, diffToken.value.size));
|
||||
|
||||
if (options.flags & DiffFlags::FuzzyFloatComparison)
|
||||
{
|
||||
if (fuzzyEquals(baseValue, diffValue, options.fuzzyEpsilon))
|
||||
diff.set(diffPos, DiffType::NoDiff);
|
||||
else
|
||||
diff.set(diffPos, DiffType::ValueDiff);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (baseValue == diffValue)
|
||||
diff.set(diffPos, DiffType::NoDiff);
|
||||
else
|
||||
diff.set(diffPos, DiffType::ValueDiff);
|
||||
}
|
||||
}
|
||||
|
||||
inline void diffBooleanValues(const Token &baseToken, const Token &diffToken, DiffTokens &diff, const size_t diffPos)
|
||||
{
|
||||
bool baseBool = false;
|
||||
bool diffBool = false;
|
||||
ParseContext dummyContext;
|
||||
|
||||
dummyContext.token = baseToken;
|
||||
TypeHandler<bool>::to(baseBool, dummyContext);
|
||||
assert(dummyContext.error == JS::Error::NoError);
|
||||
|
||||
dummyContext.token = diffToken;
|
||||
TypeHandler<bool>::to(diffBool, dummyContext);
|
||||
assert(dummyContext.error == JS::Error::NoError);
|
||||
|
||||
if (baseBool ^ diffBool)
|
||||
diff.set(diffPos, DiffType::ValueDiff);
|
||||
else
|
||||
diff.set(diffPos, DiffType::NoDiff);
|
||||
}
|
||||
|
||||
inline void diffNullValues(const Token &baseToken, const Token &diffToken, DiffTokens &diff, const size_t diffPos)
|
||||
{
|
||||
if ((baseToken.value_type == Type::Null) && (diffToken.value_type == Type::Null))
|
||||
diff.set(diffPos, DiffType::NoDiff);
|
||||
else
|
||||
diff.set(diffPos, DiffType::TypeDiff);
|
||||
}
|
||||
|
||||
inline void diffObjectMember(const DiffTokens &base, const size_t basePos, DiffTokens &diff, const size_t diffPos, const DiffOptions &options)
|
||||
{
|
||||
auto const &baseToken = base.tokens.data[basePos];
|
||||
auto const &diffToken = diff.tokens.data[diffPos];
|
||||
assert(isSameMember(baseToken, diffToken));
|
||||
assert(isSameValueType(baseToken, diffToken));
|
||||
|
||||
if (baseToken.value_type == Type::String)
|
||||
diffStringValues(baseToken, diffToken, diff, diffPos);
|
||||
else if (baseToken.value_type == Type::Number)
|
||||
diffNumberValues(baseToken, diffToken, diff, diffPos, options);
|
||||
else if (baseToken.value_type == Type::Bool)
|
||||
diffBooleanValues(baseToken, diffToken, diff, diffPos);
|
||||
else if (baseToken.value_type == Type::Null)
|
||||
diffNullValues(baseToken, diffToken, diff, diffPos);
|
||||
else if (baseToken.value_type == Type::ObjectStart)
|
||||
diffObjects(base, basePos, diff, diffPos, options);
|
||||
else if (baseToken.value_type == Type::ArrayStart)
|
||||
diffArrays(base, basePos, diff, diffPos, options);
|
||||
}
|
||||
|
||||
inline void setStateForEntireToken(DiffTokens &diffTokens, const size_t startPos, DiffType diffType)
|
||||
{
|
||||
assert(startPos < diffTokens.size());
|
||||
diffTokens.set(startPos, diffType);
|
||||
const Token &token = diffTokens.tokens.data[startPos];
|
||||
|
||||
if (token.value_type == Type::ObjectStart || token.value_type == Type::ArrayStart)
|
||||
{
|
||||
size_t pos = startPos + 1;
|
||||
while (true)
|
||||
{
|
||||
const Token ¤tToken = diffTokens.tokens.data[pos];
|
||||
if (currentToken.value_type == Type::ObjectStart || currentToken.value_type == Type::ArrayStart)
|
||||
{
|
||||
setStateForEntireToken(diffTokens, pos, diffType);
|
||||
diffTokens.skip(&pos);
|
||||
}
|
||||
else if (currentToken.value_type == Type::ObjectEnd || currentToken.value_type == Type::ArrayEnd)
|
||||
{
|
||||
diffTokens.set(pos, diffType);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
diffTokens.set(pos, diffType);
|
||||
diffTokens.skip(&pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void diffObjects(const DiffTokens &base, const size_t basePos, DiffTokens &diff, const size_t diffPos, const DiffOptions &options)
|
||||
{
|
||||
assert(base.tokens.data[basePos].value_type == Type::ObjectStart);
|
||||
assert(diff.tokens.data[diffPos].value_type == Type::ObjectStart);
|
||||
assert(basePos < base.tokens.data.size());
|
||||
assert(diffPos < diff.tokens.data.size());
|
||||
|
||||
size_t bChildCount = base.childCount(basePos);
|
||||
size_t dChildCount = diff.childCount(diffPos);
|
||||
if (bChildCount == 0 && dChildCount == 0)
|
||||
return;
|
||||
|
||||
size_t bPos = basePos + 1;
|
||||
size_t dPos = diffPos + 1;
|
||||
|
||||
// Diff members that exist in both objects and find members that are in base but not in diff.
|
||||
while (true)
|
||||
{
|
||||
const Token &baseToken = base.tokens.data[bPos];
|
||||
if (baseToken.value_type == Type::ObjectEnd)
|
||||
break;
|
||||
|
||||
dPos = diffPos + 1;
|
||||
while (true)
|
||||
{
|
||||
const Token &diffToken = diff.tokens.data[dPos];
|
||||
if (diffToken.value_type == Type::ObjectEnd)
|
||||
{
|
||||
// Did not find baseToken in diff: missing member.
|
||||
diff.addMissingMembers(diffPos, base, bPos);
|
||||
base.skip(&bPos);
|
||||
diff.skip(&dPos);
|
||||
break;
|
||||
}
|
||||
|
||||
if (isSameMember(baseToken, diffToken))
|
||||
{
|
||||
if (isSameValueType(baseToken, diffToken))
|
||||
diffObjectMember(base, bPos, diff, dPos, options);
|
||||
else
|
||||
setStateForEntireToken(diff, dPos, DiffType::TypeDiff);
|
||||
base.skip(&bPos);
|
||||
break;
|
||||
}
|
||||
|
||||
diff.skip(&dPos);
|
||||
}
|
||||
}
|
||||
|
||||
// Find members that are in diff but not in base.
|
||||
bPos = basePos + 1;
|
||||
dPos = diffPos + 1;
|
||||
while (true)
|
||||
{
|
||||
const Token &diffToken = diff.tokens.data[dPos];
|
||||
if (diffToken.value_type == Type::ObjectEnd)
|
||||
break;
|
||||
|
||||
bPos = basePos + 1;
|
||||
while (true)
|
||||
{
|
||||
const Token &baseToken = base.tokens.data[bPos];
|
||||
if (baseToken.value_type == Type::ObjectEnd)
|
||||
{
|
||||
// Did not find diffToken in base: new member.
|
||||
setStateForEntireToken(diff, dPos, DiffType::NewMember);
|
||||
diff.skip(&dPos);
|
||||
break;
|
||||
}
|
||||
|
||||
if (isSameMember(diffToken, baseToken))
|
||||
{
|
||||
diff.skip(&dPos);
|
||||
break;
|
||||
}
|
||||
|
||||
base.skip(&bPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void diffArrays(const DiffTokens &base, const size_t basePos, DiffTokens &diff, const size_t diffPos, const DiffOptions &options)
|
||||
{
|
||||
assert(base.tokens.data[basePos].value_type == Type::ArrayStart);
|
||||
assert(diff.tokens.data[diffPos].value_type == Type::ArrayStart);
|
||||
|
||||
size_t bChildCount = base.childCount(basePos);
|
||||
size_t dChildCount = diff.childCount(diffPos);
|
||||
if (bChildCount == 0 && dChildCount == 0)
|
||||
return;
|
||||
|
||||
size_t bPos = basePos + 1;
|
||||
size_t dPos = diffPos + 1;
|
||||
bool arrayDiffDone = false;
|
||||
|
||||
while (!arrayDiffDone)
|
||||
{
|
||||
const Token &baseToken = base.tokens.data[bPos];
|
||||
const Token &diffToken = diff.tokens.data[dPos];
|
||||
if (baseToken.value_type == diffToken.value_type)
|
||||
{
|
||||
switch (baseToken.value_type)
|
||||
{
|
||||
case Type::ArrayEnd:
|
||||
arrayDiffDone = true;
|
||||
continue;
|
||||
case Type::ObjectStart:
|
||||
diffObjects(base, bPos, diff, dPos, options);
|
||||
break;
|
||||
case Type::ArrayStart:
|
||||
diffArrays(base, bPos, diff, dPos, options);
|
||||
break;
|
||||
case Type::String:
|
||||
diffStringValues(baseToken, diffToken, diff, dPos);
|
||||
break;
|
||||
case Type::Number:
|
||||
diffNumberValues(baseToken, diffToken, diff, dPos, options);
|
||||
break;
|
||||
case Type::Bool:
|
||||
diffBooleanValues(baseToken, diffToken, diff, dPos);
|
||||
break;
|
||||
case Type::Null:
|
||||
diffNullValues(baseToken, diffToken, diff, dPos);
|
||||
break;
|
||||
default:
|
||||
assert(false); // Not implemented, this is an error!
|
||||
break;
|
||||
}
|
||||
|
||||
base.skip(&bPos);
|
||||
diff.skip(&dPos);
|
||||
}
|
||||
else
|
||||
{
|
||||
// New items in array.
|
||||
if (baseToken.value_type == Type::ArrayEnd)
|
||||
{
|
||||
int arrayEndCount = 0;
|
||||
while (arrayEndCount >= 0)
|
||||
{
|
||||
diff.set(dPos++, DiffType::NewArrayItem);
|
||||
const Token& dToken = diff.tokens.data[dPos];
|
||||
if (dToken.value_type == Type::ArrayStart)
|
||||
arrayEndCount++;
|
||||
else if (dToken.value_type == Type::ArrayEnd)
|
||||
arrayEndCount--;
|
||||
}
|
||||
arrayDiffDone = true;
|
||||
}
|
||||
// Check for missing items in array.
|
||||
else if (diffToken.value_type == Type::ArrayEnd)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
const Token bToken = base.tokens.data[bPos];
|
||||
if (bToken.value_type == JS::Type::ArrayEnd)
|
||||
break;
|
||||
diff.addMissingArrayItems(diffPos, base, bPos);
|
||||
base.skip(&bPos);
|
||||
}
|
||||
arrayDiffDone = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
diff.set(dPos, DiffType::TypeDiff);
|
||||
base.skip(&bPos);
|
||||
diff.skip(&dPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Note: This function implicitly assumes that the base tokens and the diff tokens represent correct JSON.
|
||||
inline void diff(const DiffTokens &base, DiffTokens &diff, const DiffOptions &options = {})
|
||||
{
|
||||
if (base.tokens.data.empty() && diff.tokens.data.empty())
|
||||
{
|
||||
// Nothing to do, the diff will be reported as successful.
|
||||
}
|
||||
else if (base.tokens.data.empty() && diff.tokens.data.size())
|
||||
{
|
||||
if (diff.tokens.data[0].value_type == Type::ObjectStart)
|
||||
diff.setStateForEntireToken(0, DiffType::NewMember);
|
||||
else if (diff.tokens.data[0].value_type == Type::ArrayStart)
|
||||
diff.setStateForEntireToken(0, DiffType::NewArrayItem);
|
||||
else
|
||||
setStateForEntireToken(diff, 0, DiffType::ErroneousRootItem);
|
||||
}
|
||||
else if (base.tokens.data.size() && diff.tokens.data.empty())
|
||||
{
|
||||
if (diff.tokens.data[0].value_type == Type::ObjectStart)
|
||||
diff.addMissingMembers(0, base, 0);
|
||||
else if (diff.tokens.data[0].value_type == Type::ArrayStart)
|
||||
diff.addMissingArrayItems(0, base, 0);
|
||||
else
|
||||
setStateForEntireToken(diff, 0, DiffType::ErroneousRootItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
diff.diff_count = 0;
|
||||
const Type& baseType = base.tokens.data[0].value_type;
|
||||
const Type& diffType = diff.tokens.data[0].value_type;
|
||||
if (baseType == diffType)
|
||||
{
|
||||
if (baseType == Type::ObjectStart)
|
||||
diffObjects(base, 0, diff, 0, options);
|
||||
else if (baseType == Type::ArrayStart)
|
||||
diffArrays(base, 0, diff, 0, options);
|
||||
else
|
||||
setStateForEntireToken(diff, 0, DiffType::ErroneousRootItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
setStateForEntireToken(diff, 0, DiffType::RootItemDiff);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct DiffContext
|
||||
{
|
||||
explicit DiffContext(const DiffOptions &options = {})
|
||||
: base()
|
||||
, options(options)
|
||||
{}
|
||||
|
||||
explicit DiffContext(const char* baseJson, size_t baseSize, const DiffOptions &options = {})
|
||||
: base(baseJson, baseSize)
|
||||
, options(options)
|
||||
{
|
||||
error = base.error;
|
||||
}
|
||||
|
||||
explicit DiffContext(const char* baseJson, const DiffOptions &options = {})
|
||||
: base(baseJson, strlen(baseJson))
|
||||
, options(options)
|
||||
{
|
||||
error = base.error;
|
||||
}
|
||||
|
||||
template <size_t SIZE>
|
||||
explicit DiffContext(const char (&baseJson)[SIZE], const DiffOptions &options = {})
|
||||
: DiffContext(baseJson, SIZE, options)
|
||||
{}
|
||||
|
||||
explicit DiffContext(const std::string &baseJson, const DiffOptions &options = {})
|
||||
: DiffContext(baseJson.c_str(), baseJson.size(), options)
|
||||
{}
|
||||
|
||||
void clear(const DiffOptions &opt = {})
|
||||
{
|
||||
base.clear();
|
||||
diffs.clear();
|
||||
options = opt;
|
||||
error = DiffError::NoError;
|
||||
}
|
||||
|
||||
void reset(const char* baseJson, size_t baseSize, const DiffOptions &opt = {})
|
||||
{
|
||||
base.reset(baseJson, baseSize);
|
||||
options = opt;
|
||||
diffs.clear();
|
||||
error = DiffError::NoError;
|
||||
}
|
||||
|
||||
void reset(const std::string &baseJson, const DiffOptions &opt = {})
|
||||
{
|
||||
reset(baseJson.c_str(), baseJson.size(), opt);
|
||||
}
|
||||
|
||||
void changeBase(const size_t pos)
|
||||
{
|
||||
assert(pos < diffs.size());
|
||||
DiffTokens tmp = diffs[pos];
|
||||
diffs[pos] = base;
|
||||
base = tmp;
|
||||
invalidate(this->options);
|
||||
}
|
||||
|
||||
void invalidate(const DiffOptions &opt)
|
||||
{
|
||||
options = opt;
|
||||
base.invalidate();
|
||||
for (auto &diffTokens : diffs)
|
||||
{
|
||||
diffTokens.invalidate();
|
||||
diff(diffTokens);
|
||||
}
|
||||
}
|
||||
|
||||
void invalidate()
|
||||
{
|
||||
invalidate(options);
|
||||
}
|
||||
|
||||
size_t diff(const char* json, size_t size)
|
||||
{
|
||||
DiffTokens diffTokens(json, size);
|
||||
error = diffTokens.error;
|
||||
if (error != DiffError::NoError)
|
||||
return size_t(-1);
|
||||
diff(diffTokens);
|
||||
diffs.emplace_back(diffTokens);
|
||||
return diffs.size() - 1;
|
||||
}
|
||||
|
||||
size_t diff(const std::string &json)
|
||||
{
|
||||
return diff(json.c_str(), json.size());
|
||||
}
|
||||
|
||||
template <size_t SIZE>
|
||||
size_t diff(const char (&json)[SIZE])
|
||||
{
|
||||
return diff(json, SIZE);
|
||||
}
|
||||
|
||||
void diff(DiffTokens &diffTokens)
|
||||
{
|
||||
Internal::Diff::diff(base, diffTokens, options);
|
||||
}
|
||||
|
||||
DiffTokens base;
|
||||
std::vector<DiffTokens> diffs;
|
||||
DiffError error = DiffError::NoError;
|
||||
DiffOptions options;
|
||||
};
|
||||
|
||||
} //Namespace
|
||||
#endif //JSON_STRUCT_DIFF_H
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#include "LGUIelement.h"
|
||||
#include "LGUIElement.h"
|
||||
|
||||
struct _CreateButton : public _CreateElement
|
||||
{
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#include "LGUIelement.h"
|
||||
#include "LGUIElement.h"
|
||||
|
||||
class LGUICheckBox :
|
||||
public LGUIElement
|
||||
|
||||
@ -1,15 +1,17 @@
|
||||
#pragma once
|
||||
#include "LGUIelement.h"
|
||||
#include "LGUIElement.h"
|
||||
|
||||
class LGUICommandButton :
|
||||
public LGUIButton
|
||||
{
|
||||
public LGUIButton {
|
||||
public:
|
||||
LGUI_API LGUICommandButton(const char *p_Factory, LGUIElement *p_pParent, const char *p_Name);
|
||||
|
||||
LGUI_API ~LGUICommandButton(void);
|
||||
|
||||
// LGUI_API class LSTypeDefinition *GetLSType();
|
||||
|
||||
LGUI_API bool FromXML(class XMLNode *pXML, class XMLNode *pTemplate = 0);
|
||||
|
||||
LGUI_API bool IsTypeOf(char *TestFactory);
|
||||
|
||||
LGUI_API bool OnLMouseUp(POINT2I &pt);
|
||||
@ -19,5 +21,4 @@ public:
|
||||
char *Command;
|
||||
char *Console;
|
||||
// --------------------
|
||||
|
||||
};
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#include "LGUIelement.h"
|
||||
#include "LGUIElement.h"
|
||||
|
||||
class LGUICommandCheckBox :
|
||||
public LGUICheckBox
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#include "LGUItextentry.h"
|
||||
#include "LGUITextEntry.h"
|
||||
|
||||
class LGUICommandEntry :
|
||||
public LGUITextEntry
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#include "LGUIelement.h"
|
||||
#include "LGUIElement.h"
|
||||
|
||||
class LGUIConsoleSelector
|
||||
{
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#include "LGUIelement.h"
|
||||
#include "LGUIElement.h"
|
||||
|
||||
class LGUIHudElement :
|
||||
public LGUIElement
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#include "LGUIelement.h"
|
||||
#include "LGUIElement.h"
|
||||
|
||||
class LGUIScreen :
|
||||
public LGUIElement
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#include "LGUIelement.h"
|
||||
#include "LGUIElement.h"
|
||||
|
||||
struct _CreateSlider : public _CreateElement
|
||||
{
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#include "LGUIelement.h"
|
||||
#include "LGUIElement.h"
|
||||
|
||||
enum eTextAlign
|
||||
{
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#include "LGUIelement.h"
|
||||
#include "LGUIElement.h"
|
||||
|
||||
class CTextEditLine
|
||||
{
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#include "LGUIelement.h"
|
||||
#include "LGUIElement.h"
|
||||
|
||||
struct _CreateTextEntry : public _CreateElement
|
||||
{
|
||||
|
||||
110
src/Api/ForWho.h
Normal file
110
src/Api/ForWho.h
Normal file
@ -0,0 +1,110 @@
|
||||
#ifndef FORWHO_H
|
||||
#define FORWHO_H
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <ranges>
|
||||
|
||||
#include "isxeq2/ExtensionTLOs.h"
|
||||
|
||||
inline bool IsForMe(const std::string &forWho);
|
||||
|
||||
inline bool IsForMe(const std::string &command, const std::string ¶meter);
|
||||
|
||||
inline bool IsForMe(const std::string &command, const std::string ¶meter) {
|
||||
string commandLower(command);
|
||||
string parameterLower(parameter);
|
||||
string me = ExtensionTLOs::Me().Name();
|
||||
string className = ExtensionTLOs::Me().Class();
|
||||
string subClassName = ExtensionTLOs::Me().SubClass();
|
||||
string archetypeName = ExtensionTLOs::Me().Archetype();
|
||||
vector<string> groupMembers;
|
||||
vector<string> raidMembers;
|
||||
|
||||
for (int idx = 0; idx <= ExtensionTLOs::Me().GroupCount(); ++idx) {
|
||||
string name = ExtensionTLOs::Me().GroupMemberByIndex(idx).Name();
|
||||
ranges::transform(name, name.begin(), ::tolower);
|
||||
groupMembers.push_back(name);
|
||||
}
|
||||
|
||||
for (int idx = 1; idx <= 24; idx++) {
|
||||
// I don't know how to tell if it's valid or not, not sure what NULL will look like
|
||||
auto name = ExtensionTLOs::Me().RaidMemberByIndex(idx).Name();
|
||||
ranges::transform(name, name.begin(), ::tolower);
|
||||
raidMembers.push_back(name);
|
||||
}
|
||||
|
||||
ranges::transform(commandLower, commandLower.begin(), ::tolower);
|
||||
ranges::transform(parameterLower, parameterLower.begin(), ::tolower);
|
||||
ranges::transform(me, me.begin(), ::tolower);
|
||||
ranges::transform(className, className.begin(), ::tolower);
|
||||
ranges::transform(subClassName, subClassName.begin(), ::tolower);
|
||||
ranges::transform(archetypeName, archetypeName.begin(), ::tolower);
|
||||
|
||||
if (commandLower == "igw") {
|
||||
return ranges::find(groupMembers, parameterLower) != groupMembers.end();
|
||||
}
|
||||
|
||||
if (commandLower == "igwbn") {
|
||||
auto view = groupMembers | std::views::drop(1);
|
||||
return ranges::find(view, parameterLower) == groupMembers.end();
|
||||
}
|
||||
|
||||
if (commandLower == "irw") {
|
||||
return ranges::find(raidMembers, parameterLower) != raidMembers.end();
|
||||
}
|
||||
|
||||
if (commandLower == "irwbn") {
|
||||
auto view = raidMembers | std::views::drop(1);
|
||||
return ranges::find(view, parameterLower) == raidMembers.end();
|
||||
}
|
||||
|
||||
if (commandLower == "not") {
|
||||
return !IsForMe(parameterLower);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool IsForMe(const std::string &forWho) {
|
||||
string forWhoLower(forWho);
|
||||
string me = ExtensionTLOs::Me().Name();
|
||||
string className = ExtensionTLOs::Me().Class();
|
||||
string subClassName = ExtensionTLOs::Me().SubClass();
|
||||
string archetypeName = ExtensionTLOs::Me().Archetype();
|
||||
ranges::transform(forWhoLower, forWhoLower.begin(), ::tolower);
|
||||
ranges::transform(me, me.begin(), ::tolower);
|
||||
ranges::transform(className, className.begin(), ::tolower);
|
||||
ranges::transform(subClassName, subClassName.begin(), ::tolower);
|
||||
ranges::transform(archetypeName, archetypeName.begin(), ::tolower);
|
||||
|
||||
if (forWhoLower == "all" || forWhoLower == me) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (forWhoLower == className || forWhoLower == subClassName || forWhoLower == archetypeName) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (forWhoLower == "melee" && (archetypeName == "fighter" || archetypeName == "scout")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (forWhoLower == "caster" && (archetypeName == "mage" || archetypeName == "priest")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (const auto colonIndex = forWhoLower.find(':'); colonIndex != std::string::npos) {
|
||||
const auto forWhoCommand = forWhoLower.substr(0, colonIndex);
|
||||
const auto forWhoParameter = forWhoLower.substr(colonIndex + 1);
|
||||
|
||||
return IsForMe(forWhoCommand, forWhoParameter);
|
||||
}
|
||||
|
||||
if (forWhoLower.starts_with("not")) {
|
||||
return !IsForMe(forWhoLower.substr(3));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif //FORWHO_H
|
||||
16
src/Api/MrBotApi.cpp
Normal file
16
src/Api/MrBotApi.cpp
Normal file
@ -0,0 +1,16 @@
|
||||
//
|
||||
// Created by marob on 1/2/2024.
|
||||
//
|
||||
|
||||
#include "MrBotApi.h"
|
||||
|
||||
void MrBotApi::AcceptReward(const string &forWho, const u_short selection) const {
|
||||
if (!IsForMe(forWho)) return;
|
||||
if (selection < 1) return;
|
||||
}
|
||||
|
||||
void MrBotApi::ActorClick(const string &forWho, const string &actorName, bool exactMatch) const {
|
||||
if (!IsForMe(forWho)) return;
|
||||
if (actorName.empty()) return;
|
||||
}
|
||||
|
||||
21
src/Api/MrBotApi.h
Normal file
21
src/Api/MrBotApi.h
Normal file
@ -0,0 +1,21 @@
|
||||
//
|
||||
// Created by marob on 1/2/2024.
|
||||
//
|
||||
|
||||
#ifndef MRBOTAPI_H
|
||||
#define MRBOTAPI_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "ForWho.h"
|
||||
|
||||
|
||||
class MrBotApi {
|
||||
public:
|
||||
void AcceptReward(const string &forWho, const u_short selection) const;
|
||||
|
||||
void ActorClick(const string &forWho, const string &actorName, bool exactMatch) const;
|
||||
};
|
||||
|
||||
|
||||
#endif //MRBOTAPI_H
|
||||
@ -5,7 +5,8 @@
|
||||
#include <vector>
|
||||
|
||||
//#include <nlohmann/json.hpp>
|
||||
#include <picojson/picojson.h>
|
||||
//#include <picojson/picojson.h>
|
||||
#include <json_struct/json_struct.h>
|
||||
|
||||
using namespace std;
|
||||
//using json = nlohmann::json;
|
||||
@ -77,86 +78,11 @@ struct ExportedAbility {
|
||||
unsigned long TypeFlags;
|
||||
unsigned short RequirementsFlags;
|
||||
|
||||
picojson::value ToJson() const {
|
||||
picojson::object jsonValue;
|
||||
|
||||
jsonValue["Id"] = picojson::value(static_cast<double>(Id));
|
||||
jsonValue["Name"] = picojson::value(Name);
|
||||
jsonValue["Description"] = picojson::value(Description);
|
||||
jsonValue["Tier"] = picojson::value(Tier);
|
||||
jsonValue["Level"] = picojson::value(static_cast<double>(Level));
|
||||
jsonValue["HealthCost"] = picojson::value(static_cast<double>(HealthCost));
|
||||
jsonValue["PowerCost"] = picojson::value(static_cast<double>(PowerCost));
|
||||
jsonValue["DissonanceCost"] = picojson::value(static_cast<double>(DissonanceCost));
|
||||
jsonValue["SavageryCost"] = picojson::value(static_cast<double>(SavageryCost));
|
||||
jsonValue["ConcentrationCost"] = picojson::value(static_cast<double>(ConcentrationCost));
|
||||
jsonValue["MainIconID"] = picojson::value(static_cast<double>(MainIconID));
|
||||
jsonValue["HOIconID"] = picojson::value(static_cast<double>(HOIconID));
|
||||
jsonValue["CastingTime"] = picojson::value(static_cast<double>(CastingTime));
|
||||
jsonValue["RecoveryTime"] = picojson::value(static_cast<double>(RecoveryTime));
|
||||
jsonValue["RecastTime"] = picojson::value(static_cast<double>(RecastTime));
|
||||
jsonValue["MaxDuration"] = picojson::value(static_cast<double>(MaxDuration));
|
||||
jsonValue["NumClasses"] = picojson::value(static_cast<double>(NumClasses));
|
||||
jsonValue["NumEffects"] = picojson::value(static_cast<double>(NumEffects));
|
||||
jsonValue["BackdropIconID"] = picojson::value(static_cast<double>(BackdropIconID));
|
||||
jsonValue["HealthCostPerTick"] = picojson::value(static_cast<double>(HealthCostPerTick));
|
||||
jsonValue["PowerCostPerTick"] = picojson::value(static_cast<double>(PowerCostPerTick));
|
||||
jsonValue["DissonanceCostPerTick"] = picojson::value(static_cast<double>(DissonanceCostPerTick));
|
||||
jsonValue["SavageryCostPerTick"] = picojson::value(static_cast<double>(SavageryCostPerTick));
|
||||
jsonValue["MaxAOETargets"] = picojson::value(static_cast<double>(MaxAOETargets));
|
||||
jsonValue["DoesNotExpire"] = picojson::value(static_cast<bool>(DoesNotExpire));
|
||||
jsonValue["GroupRestricted"] = picojson::value(static_cast<bool>(GroupRestricted));
|
||||
jsonValue["AllowRaid"] = picojson::value(static_cast<bool>(AllowRaid));
|
||||
jsonValue["IsBeneficial"] = picojson::value(static_cast<bool>(IsBeneficial));
|
||||
jsonValue["EffectRadius"] = picojson::value(EffectRadius);
|
||||
jsonValue["TargetType"] = picojson::value(static_cast<double>(TargetType));
|
||||
jsonValue["SpellBookType"] = picojson::value(static_cast<double>(SpellBookType));
|
||||
jsonValue["MinRange"] = picojson::value(MinRange);
|
||||
jsonValue["MaxRange"] = picojson::value(MaxRange);
|
||||
|
||||
|
||||
//jsonValue
|
||||
// j["Id"] = Id;
|
||||
// j["Name"] = Name;
|
||||
// j["Description"] = Description;
|
||||
// j["Tier"] = Tier;
|
||||
// j["Level"] = Level;
|
||||
// j["HealthCost"] = HealthCost;
|
||||
// j["PowerCost"] = PowerCost;
|
||||
// j["DissonanceCost"] = DissonanceCost;
|
||||
// j["SavageryCost"] = SavageryCost;
|
||||
// j["ConcentrationCost"] = ConcentrationCost;
|
||||
// j["MainIconID"] = MainIconID;
|
||||
// j["HOIconID"] = HOIconID;
|
||||
// j["CastingTime"] = CastingTime;
|
||||
// j["RecoveryTime"] = RecoveryTime;
|
||||
// j["RecastTime"] = RecastTime;
|
||||
// j["MaxDuration"] = MaxDuration;
|
||||
// j["NumClasses"] = NumClasses;
|
||||
// j["NumEffects"] = NumEffects;
|
||||
// j["BackdropIconID"] = BackdropIconID;
|
||||
// j["HealthCostPerTick"] = HealthCostPerTick;
|
||||
// j["PowerCostPerTick"] = PowerCostPerTick;
|
||||
// j["DissonanceCostPerTick"] = DissonanceCostPerTick;
|
||||
// j["SavageryCostPerTick"] = SavageryCostPerTick;
|
||||
// j["MaxAOETargets"] = MaxAOETargets;
|
||||
// j["DoesNotExpire"] = DoesNotExpire;
|
||||
// j["GroupRestricted"] = GroupRestricted;
|
||||
// j["AllowRaid"] = AllowRaid;
|
||||
// j["IsBeneficial"] = IsBeneficial;
|
||||
// j["EffectRadius"] = EffectRadius;
|
||||
// j["TargetType"] = TargetType;
|
||||
// j["SpellBookType"] = SpellBookType;
|
||||
// j["MinRange"] = MinRange;
|
||||
// j["MaxRange"] = MaxRange;
|
||||
// j["Damage"] = Damage;
|
||||
// j["Effects"] = Effects;
|
||||
// j["TypeFlags"] = TypeFlags;
|
||||
// j["RequirementsFlags"] = RequirementsFlags;
|
||||
|
||||
|
||||
return picojson::value(jsonValue);
|
||||
}
|
||||
JS_OBJ(Id, Name, Description, Tier, Level, HealthCost, PowerCost, DissonanceCost, SavageryCost, ConcentrationCost,
|
||||
MainIconID, HOIconID, CastingTime, RecoveryTime, RecastTime, MaxDuration, NumClasses, NumEffects,
|
||||
BackdropIconID, HealthCostPerTick, PowerCostPerTick, DissonanceCostPerTick, SavageryCostPerTick,
|
||||
MaxAOETargets, DoesNotExpire, GroupRestricted, AllowRaid, IsBeneficial, EffectRadius, TargetType,
|
||||
SpellBookType, MinRange, MaxRange, Damage, Effects, TypeFlags, RequirementsFlags);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
#include <fstream>
|
||||
#include <future>
|
||||
#include <thread>
|
||||
#include <picojson/picojson.h>
|
||||
#include<json_struct/json_struct.h>
|
||||
|
||||
#include "ISXMr.h"
|
||||
#include "ExportCommand.h"
|
||||
@ -13,7 +13,6 @@
|
||||
#include "isxeq2/ExtensionTLOs.h"
|
||||
|
||||
using namespace std;
|
||||
//using json = nlohmann::json;
|
||||
|
||||
AbilityInfo GetAbilityInfo(const int idx) {
|
||||
const auto ability = ExtensionTLOs::Me().Ability(idx);
|
||||
@ -28,7 +27,7 @@ void ExportCommand::Execute() {
|
||||
try {
|
||||
log << "Exporting abilities" << endl;
|
||||
const auto numAbilities = ExtensionTLOs::Me().NumAbilities();
|
||||
auto abilityList = map<string, picojson::value>{};
|
||||
auto abilityList = map<string, vector<ExportedAbility> >{};
|
||||
for (int i = 1; i <= numAbilities && !IsStopRequested(); ++i) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
||||
while (!ExtensionTLOs::Me().Ability(i).IsAbilityInfoAvailable() && !IsStopRequested()) {
|
||||
@ -41,13 +40,15 @@ void ExportCommand::Execute() {
|
||||
}
|
||||
const auto exportedAbility = ExtensionTLOs::Me().Ability(i).ToExportedAbility();
|
||||
log << "Exporting " << exportedAbility.Name << " (" << i << "/" << numAbilities << ")" << endl;
|
||||
|
||||
// ReSharper disable once CppTooWideScopeInitStatement
|
||||
const auto abilityLineName = StripTrailingRomanNumerals(exportedAbility.Name);
|
||||
if (const auto abilityLine = abilityList[abilityLineName]; !abilityLine.is<picojson::array>()) {
|
||||
picojson::array entry({exportedAbility.ToJson()});
|
||||
abilityList[abilityLineName] = picojson::value(picojson::array({exportedAbility.ToJson()}));
|
||||
} else {
|
||||
abilityList[abilityLineName].get<picojson::array>().push_back(exportedAbility.ToJson());
|
||||
}
|
||||
abilityList[abilityLineName].push_back(exportedAbility);
|
||||
// if (abilityList.contains(abilityLineName)) {
|
||||
//
|
||||
// } else {
|
||||
// abilityList[abilityLineName] = vector<ExportedAbility>{exportedAbility};
|
||||
// }
|
||||
}
|
||||
|
||||
constexpr size_t innerspacePathBufferLength = 255;
|
||||
@ -71,8 +72,9 @@ void ExportCommand::Execute() {
|
||||
}
|
||||
|
||||
if (std::ofstream file(fullPath); file) {
|
||||
picojson::value abilities(abilityList);
|
||||
file << abilities << endl;
|
||||
std::string pretty_json = JS::serializeStruct(abilityList);
|
||||
//picojson::value abilities(abilityList);
|
||||
file << pretty_json << endl;
|
||||
} else {
|
||||
loge << "Unknown error writing export to disk" << endl;
|
||||
}
|
||||
|
||||
@ -1,30 +1,33 @@
|
||||
//
|
||||
// Created by marob on 12/27/2023.
|
||||
//
|
||||
|
||||
#include "Ability.h"
|
||||
#include "ExtensionTLOs.h"
|
||||
|
||||
#include <memory>
|
||||
#include <regex>
|
||||
|
||||
|
||||
u_long Ability::Id() const {
|
||||
return {static_cast<u_long>(this->lsObject->GetMember("ID").Int64)};
|
||||
const auto id = this->lsObject->GetMember("ID");
|
||||
return id.has_value() ? id->Int64 : 0;
|
||||
}
|
||||
|
||||
bool Ability::IsReady() const {
|
||||
return this->lsObject->GetMember("IsReady").Int;
|
||||
const auto isReady = this->lsObject->GetMember("IsReady");
|
||||
return isReady.has_value() ? isReady->Int : false;
|
||||
}
|
||||
|
||||
float Ability::TimeUntilReady() const {
|
||||
return this->lsObject->GetMember("TimeUntilReady").Float;
|
||||
const auto timeUntilReady = this->lsObject->GetMember("TimeUntilReady");
|
||||
return timeUntilReady.has_value() ? timeUntilReady->Float : 0.0f;
|
||||
}
|
||||
|
||||
bool Ability::IsQueued() const {
|
||||
return this->lsObject->GetMember("IsQueued").Int;
|
||||
const auto isQueued = this->lsObject->GetMember("IsQueued");
|
||||
return isQueued.has_value() ? isQueued->Int : false;
|
||||
}
|
||||
|
||||
bool Ability::IsAbilityInfoAvailable() const {
|
||||
return this->lsObject->GetMember("IsAbilityInfoAvailable").Int;
|
||||
const auto isAbilityInfoAvailable = this->lsObject->GetMember("IsAbilityInfoAvailable");
|
||||
return isAbilityInfoAvailable.has_value() ? isAbilityInfoAvailable->Int : false;
|
||||
}
|
||||
|
||||
AbilityInfo Ability::GetAbilityInfo() const {
|
||||
@ -37,7 +40,8 @@ ExportedAbility Ability::ToExportedAbility() const {
|
||||
exportedAbility.Name = this->GetAbilityInfo().Name();
|
||||
exportedAbility.Description = this->GetAbilityInfo().Description();
|
||||
exportedAbility.Tier = this->GetAbilityInfo().Tier();
|
||||
//exportedAbility.Level = this->GetAbilityInfo().Level();
|
||||
//logd << "SubClass: " << ExtensionTLOs::Me().SubClass() << endl;
|
||||
exportedAbility.Level = this->GetAbilityInfo().ClassByName(ExtensionTLOs::Me().SubClass()).Level();
|
||||
exportedAbility.HealthCost = this->GetAbilityInfo().HealthCost();
|
||||
exportedAbility.PowerCost = this->GetAbilityInfo().PowerCost();
|
||||
exportedAbility.DissonanceCost = this->GetAbilityInfo().DissonanceCost();
|
||||
@ -67,9 +71,32 @@ ExportedAbility Ability::ToExportedAbility() const {
|
||||
exportedAbility.MinRange = this->GetAbilityInfo().MinRange();
|
||||
exportedAbility.MaxRange = this->GetAbilityInfo().MaxRange();
|
||||
|
||||
for (int idx = 1; idx < this->GetAbilityInfo().NumEffects(); ++idx) {
|
||||
exportedAbility.Effects.push_back(this->GetAbilityInfo().EffectByIndex(idx).Description());
|
||||
}
|
||||
|
||||
if (RequiresStealth(exportedAbility.Effects)) {
|
||||
exportedAbility.RequirementsFlags |= Stealth;
|
||||
}
|
||||
|
||||
if (RequiresFlanking(exportedAbility.Effects)) {
|
||||
exportedAbility.RequirementsFlags |= Flanking;
|
||||
}
|
||||
|
||||
if (RequiresNonEpic(exportedAbility.Effects)) {
|
||||
exportedAbility.RequirementsFlags |= NoEpic;
|
||||
}
|
||||
|
||||
if (IsStun(exportedAbility.Effects)) {
|
||||
exportedAbility.TypeFlags |= Stun;
|
||||
}
|
||||
|
||||
if (IsInterrupt(exportedAbility.Effects)) {
|
||||
exportedAbility.TypeFlags |= Interrupt;
|
||||
}
|
||||
|
||||
|
||||
return exportedAbility;
|
||||
|
||||
}
|
||||
|
||||
void Ability::Use() const {
|
||||
@ -79,3 +106,38 @@ void Ability::Use() const {
|
||||
void Ability::Examine() const {
|
||||
this->lsObject->CallMethod("Examine");
|
||||
}
|
||||
|
||||
bool Ability::RequiresStealth(const vector<string> &effects) {
|
||||
const std::regex stealthRegex(
|
||||
"(I need to be stealthed!|You must be (in stealth|sneaking) to use this(!| ability.))");
|
||||
|
||||
return std::ranges::any_of(
|
||||
effects, [&stealthRegex](const string &effect) {
|
||||
return std::regex_search(effect, stealthRegex);
|
||||
});
|
||||
}
|
||||
|
||||
bool Ability::RequiresFlanking(const vector<string> &effects) {
|
||||
return std::ranges::any_of(effects, [](const string &effect) {
|
||||
return effect == "Must be flanking or behind";
|
||||
});
|
||||
}
|
||||
|
||||
bool Ability::RequiresNonEpic(const vector<string> &effects) {
|
||||
return std::ranges::any_of(effects, [](const string &effect) {
|
||||
return effect == "Does not affect Epic targets";
|
||||
});
|
||||
}
|
||||
|
||||
bool Ability::IsInterrupt(const vector<string> &effects) {
|
||||
return std::ranges::any_of(effects, [](const string &effect) {
|
||||
return effect == "Interrupts target";
|
||||
});
|
||||
}
|
||||
|
||||
bool Ability::IsStun(const vector<string> &effects) {
|
||||
return std::ranges::any_of(effects, [](const string &effect) {
|
||||
return effect == "Stuns target";
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -1,7 +1,3 @@
|
||||
//
|
||||
// Created by marob on 12/27/2023.
|
||||
//
|
||||
|
||||
#ifndef ABILITY_H
|
||||
#define ABILITY_H
|
||||
|
||||
@ -44,6 +40,16 @@ public:
|
||||
|
||||
private:
|
||||
const shared_ptr<LSObject> lsObject;
|
||||
|
||||
static bool RequiresStealth(const vector<string> &effects);
|
||||
|
||||
static bool RequiresFlanking(const vector<string> &effects);
|
||||
|
||||
static bool RequiresNonEpic(const vector<string> &effects);
|
||||
|
||||
static bool IsInterrupt(const vector<string> &effects);
|
||||
|
||||
static bool IsStun(const vector<string> &effects);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -14,15 +14,26 @@ class LSObject;
|
||||
class AbilityEffect {
|
||||
public:
|
||||
explicit AbilityEffect(const std::shared_ptr<LSObject> &obj) {
|
||||
percentSuccess = obj->GetMember("PercentSuccess").Int;
|
||||
indentation = obj->GetMember("Indentation").Int;
|
||||
description = obj->GetMember("Description").CharPtr;
|
||||
const auto optPercentSuccess = obj->GetMember("PercentSuccess");
|
||||
const auto optIndentation = obj->GetMember("Indentation");
|
||||
const auto optDescription = obj->GetMember("Description");
|
||||
percentSuccess = optPercentSuccess.has_value() ? optPercentSuccess->Int : 0;
|
||||
indentation = optIndentation.has_value() ? optIndentation->Int : 0;
|
||||
description = optDescription.has_value() ? optDescription->CharPtr : "";
|
||||
}
|
||||
|
||||
int PercentSuccess() const;
|
||||
int Indentation() const;
|
||||
int PercentSuccess() const {
|
||||
return percentSuccess;
|
||||
}
|
||||
|
||||
int Indentation() const {
|
||||
return indentation;
|
||||
}
|
||||
|
||||
std::string Description() const {
|
||||
return description;
|
||||
}
|
||||
|
||||
std::string Description() const;
|
||||
private:
|
||||
int percentSuccess;
|
||||
int indentation;
|
||||
@ -30,5 +41,4 @@ private:
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif //ABILITYEFFECT_H
|
||||
|
||||
@ -2,63 +2,78 @@
|
||||
|
||||
|
||||
string AbilityInfo::Name() const {
|
||||
return this->lsObject->GetMember("Name").CharPtr;
|
||||
const auto optName = this->lsObject->GetMember("Name");
|
||||
return optName.has_value() ? optName->CharPtr : string();
|
||||
}
|
||||
|
||||
string AbilityInfo::Description() const {
|
||||
return this->lsObject->GetMember("Description").CharPtr;
|
||||
const auto optDescription = this->lsObject->GetMember("Description");
|
||||
return optDescription.has_value() ? optDescription->CharPtr : string();
|
||||
}
|
||||
|
||||
string AbilityInfo::Tier() const {
|
||||
return this->lsObject->GetMember("Tier").CharPtr;
|
||||
const auto optTier = this->lsObject->GetMember("Tier");
|
||||
return optTier.has_value() ? optTier->CharPtr : string();
|
||||
}
|
||||
|
||||
int AbilityInfo::HealthCost() const {
|
||||
return this->lsObject->GetMember("HealthCost").Int;
|
||||
const auto optHealthCost = this->lsObject->GetMember("HealthCost");
|
||||
return optHealthCost.has_value() ? optHealthCost->Int : 0;
|
||||
}
|
||||
|
||||
int AbilityInfo::PowerCost() const {
|
||||
return this->lsObject->GetMember("PowerCost").Int;
|
||||
const auto optPowerCost = this->lsObject->GetMember("PowerCost");
|
||||
return optPowerCost.has_value() ? optPowerCost->Int : 0;
|
||||
}
|
||||
|
||||
int AbilityInfo::DissonanceCost() const {
|
||||
return this->lsObject->GetMember("DissonanceCost").Int;
|
||||
const auto optDissonanceCost = this->lsObject->GetMember("DissonanceCost");
|
||||
return optDissonanceCost.has_value() ? optDissonanceCost->Int : 0;
|
||||
}
|
||||
|
||||
int AbilityInfo::SavageryCost() const {
|
||||
return this->lsObject->GetMember("SavageryCost").Int;
|
||||
const auto optSavageryCost = this->lsObject->GetMember("SavageryCost");
|
||||
return optSavageryCost.has_value() ? optSavageryCost->Int : 0;
|
||||
}
|
||||
|
||||
int AbilityInfo::ConcentrationCost() const {
|
||||
return this->lsObject->GetMember("ConcentrationCost").Int;
|
||||
const auto optConcentrationCost = this->lsObject->GetMember("ConcentrationCost");
|
||||
return optConcentrationCost.has_value() ? optConcentrationCost->Int : 0;
|
||||
}
|
||||
|
||||
int AbilityInfo::MainIconID() const {
|
||||
return this->lsObject->GetMember("MainIconID").Int;
|
||||
const auto result = this->lsObject->GetMember("MainIconID");
|
||||
return result.has_value() ? result->Int : 0;
|
||||
}
|
||||
|
||||
int AbilityInfo::HOIconID() const {
|
||||
return this->lsObject->GetMember("HOIconID").Int;
|
||||
const auto result = this->lsObject->GetMember("HOIconID");
|
||||
return result.has_value() ? result->Int : 0;
|
||||
}
|
||||
|
||||
float AbilityInfo::CastingTime() const {
|
||||
return this->lsObject->GetMember("CastingTime").Float;
|
||||
const auto result = this->lsObject->GetMember("CastingTime");
|
||||
return result.has_value() ? result->Float : 0.0f;
|
||||
}
|
||||
|
||||
float AbilityInfo::RecoveryTime() const {
|
||||
return this->lsObject->GetMember("RecoveryTime").Float;
|
||||
const auto result = this->lsObject->GetMember("RecoveryTime");
|
||||
return result.has_value() ? result->Float : 0.0f;
|
||||
}
|
||||
|
||||
float AbilityInfo::RecastTime() const {
|
||||
return this->lsObject->GetMember("RecastTime").Float;
|
||||
const auto result = this->lsObject->GetMember("RecastTime");
|
||||
return result.has_value() ? result->Float : 0.0f;
|
||||
}
|
||||
|
||||
float AbilityInfo::MaxDuration() const {
|
||||
return this->lsObject->GetMember("MaxDuration").Float;
|
||||
const auto result = this->lsObject->GetMember("MaxDuration");
|
||||
return result.has_value() ? result->Float : 0.0f;
|
||||
}
|
||||
|
||||
int AbilityInfo::NumClasses() const {
|
||||
return this->lsObject->GetMember("NumClasses").Int;
|
||||
const auto result = this->lsObject->GetMember("NumClasses");
|
||||
return result.has_value() ? result->Int : 0;
|
||||
}
|
||||
|
||||
CharacterClass AbilityInfo::ClassByIndex(const int num) const {
|
||||
@ -69,71 +84,92 @@ CharacterClass AbilityInfo::ClassByName(const string &name) const {
|
||||
return CharacterClass(make_shared<LSObject>(LSObject(this->lsObject->GetMember("Class", name))));
|
||||
}
|
||||
|
||||
AbilityEffect AbilityInfo::EffectByIndex(const int num) const {
|
||||
return AbilityEffect(make_shared<LSObject>(LSObject(this->lsObject->GetMember("Effect", num))));
|
||||
}
|
||||
|
||||
int AbilityInfo::NumEffects() const {
|
||||
return this->lsObject->GetMember("NumEffects").Int;
|
||||
const auto result = this->lsObject->GetMember("NumEffects");
|
||||
return result.has_value() ? result->Int : 0;
|
||||
}
|
||||
|
||||
int AbilityInfo::BackDropIconID() const {
|
||||
return this->lsObject->GetMember("BackDropIconID").Int;
|
||||
const auto result = this->lsObject->GetMember("BackDropIconID");
|
||||
return result.has_value() ? result->Int : 0;
|
||||
}
|
||||
|
||||
int AbilityInfo::HealthCostPerTick() const {
|
||||
return this->lsObject->GetMember("HealthCostPerTick").Int;
|
||||
const auto result = this->lsObject->GetMember("HealthCostPerTick");
|
||||
return result.has_value() ? result->Int : 0;
|
||||
}
|
||||
|
||||
int AbilityInfo::PowerCostPerTick() const {
|
||||
return this->lsObject->GetMember("PowerCostPerTick").Int;
|
||||
const auto result = this->lsObject->GetMember("PowerCostPerTick");
|
||||
return result.has_value() ? result->Int : 0;
|
||||
}
|
||||
|
||||
int AbilityInfo::DissonanceCostPerTick() const {
|
||||
return this->lsObject->GetMember("DissonanceCostPerTick").Int;
|
||||
const auto result = this->lsObject->GetMember("DissonanceCostPerTick");
|
||||
return result.has_value() ? result->Int : 0;
|
||||
}
|
||||
|
||||
int AbilityInfo::SavageryCostPerTick() const {
|
||||
return this->lsObject->GetMember("SavageryCostPerTick").Int;
|
||||
const auto result = this->lsObject->GetMember("SavageryCostPerTick");
|
||||
return result.has_value() ? result->Int : 0;
|
||||
}
|
||||
|
||||
int AbilityInfo::MaxAOETargets() const {
|
||||
return this->lsObject->GetMember("MaxAOETargets").Int;
|
||||
const auto result = this->lsObject->GetMember("MaxAOETargets");
|
||||
return result.has_value() ? result->Int : 0;
|
||||
}
|
||||
|
||||
bool AbilityInfo::DoesNotExpire() const {
|
||||
return this->lsObject->GetMember("DoesNotExpire").Int;
|
||||
const auto result = this->lsObject->GetMember("DoesNotExpire");
|
||||
return result.has_value() ? result->Int : false;
|
||||
}
|
||||
|
||||
bool AbilityInfo::GroupRestricted() const {
|
||||
return this->lsObject->GetMember("GroupRestricted").Int;
|
||||
const auto result = this->lsObject->GetMember("GroupRestricted");
|
||||
return result.has_value() ? result->Int : false;
|
||||
}
|
||||
|
||||
bool AbilityInfo::AllowRaid() const {
|
||||
return this->lsObject->GetMember("AllowRaid").Int;
|
||||
const auto result = this->lsObject->GetMember("AllowRaid");
|
||||
return result.has_value() ? result->Int : false;
|
||||
}
|
||||
|
||||
bool AbilityInfo::IsBeneficial() const {
|
||||
return this->lsObject->GetMember("IsBeneficial").Int;
|
||||
const auto result = this->lsObject->GetMember("IsBeneficial");
|
||||
return result.has_value() ? result->Int : false;
|
||||
}
|
||||
|
||||
float AbilityInfo::EffectRadius() const {
|
||||
return this->lsObject->GetMember("EffectRadius").Float;
|
||||
const auto result = this->lsObject->GetMember("EffectRadius");
|
||||
return result.has_value() ? result->Float : 0.0f;
|
||||
}
|
||||
|
||||
int AbilityInfo::TargetType() const {
|
||||
return this->lsObject->GetMember("TargetType").Int;
|
||||
const auto result = this->lsObject->GetMember("TargetType");
|
||||
return result.has_value() ? result->Int : 0;
|
||||
}
|
||||
|
||||
int AbilityInfo::SpellBookType() const {
|
||||
return this->lsObject->GetMember("SpellBookType").Int;
|
||||
const auto result = this->lsObject->GetMember("SpellBookType");
|
||||
return result.has_value() ? result->Int : 0;
|
||||
}
|
||||
|
||||
float AbilityInfo::MinRange() const {
|
||||
return this->lsObject->GetMember("MinRange").Float;
|
||||
const auto result = this->lsObject->GetMember("MinRange");
|
||||
return result.has_value() ? result->Float : 0.0f;
|
||||
}
|
||||
|
||||
float AbilityInfo::MaxRange() const {
|
||||
return this->lsObject->GetMember("MaxRange").Float;
|
||||
const auto result = this->lsObject->GetMember("MaxRange");
|
||||
return result.has_value() ? result->Float : 0.0f;
|
||||
}
|
||||
|
||||
string AbilityInfo::ToLink() const {
|
||||
return this->lsObject->GetMember("ToLink").CharPtr;
|
||||
const auto result = this->lsObject->GetMember("ToLink");
|
||||
return result.has_value() ? result->CharPtr : string();
|
||||
}
|
||||
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
#define ABILITYINFO_H
|
||||
#include <memory>
|
||||
|
||||
#include "AbilityEffect.h"
|
||||
#include "CharacterClass.h"
|
||||
#include "LSObject.h"
|
||||
#include "BotSettings/ExportedAbility.h"
|
||||
@ -46,6 +47,8 @@ public:
|
||||
|
||||
CharacterClass ClassByName(const string &name) const;
|
||||
|
||||
AbilityEffect EffectByIndex(const int num) const;
|
||||
|
||||
int NumEffects() const;
|
||||
|
||||
int BackDropIconID() const;
|
||||
|
||||
@ -1,394 +1,682 @@
|
||||
//
|
||||
// Created by marob on 12/20/2023.
|
||||
//
|
||||
|
||||
#include "Actor.h"
|
||||
|
||||
|
||||
u_long Actor::Id() const {
|
||||
return static_cast<u_long>(this->lsObject->GetMember("ID").Int64);
|
||||
if (const auto id = this->lsObject->GetMember("ID"); id.has_value()) {
|
||||
return id->Int64;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string Actor::Name() const {
|
||||
return this->lsObject->GetMember("Name").CharPtr;
|
||||
if (const auto name = this->lsObject->GetMember("Name"); name.has_value()) {
|
||||
return name->CharPtr;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string Actor::LastName() const {
|
||||
return this->lsObject->GetMember("LastName").CharPtr;
|
||||
if (const auto lastName = this->lsObject->GetMember("LastName"); lastName.has_value()) {
|
||||
return lastName->CharPtr;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
int Actor::HealthPercentage() const {
|
||||
return this->lsObject->GetMember("Health").Int;
|
||||
if (const auto healthPercentage = this->lsObject->GetMember("Health"); healthPercentage.has_value()) {
|
||||
return healthPercentage->Int;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
int Actor::PowerPercentage() const {
|
||||
return this->lsObject->GetMember("Power").Int;
|
||||
if (const auto powerPercentage = this->lsObject->GetMember("Power"); powerPercentage.has_value()) {
|
||||
return powerPercentage->Int;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
int Actor::Level() const {
|
||||
return this->lsObject->GetMember("Level").Int;
|
||||
if (const auto level = this->lsObject->GetMember("Level"); level.has_value()) {
|
||||
return level->Int;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
int Actor::EffectiveLevel() const {
|
||||
return this->lsObject->GetMember("EffectiveLevel").Int;
|
||||
if (const auto effectiveLevel = this->lsObject->GetMember("EffectiveLevel"); effectiveLevel.has_value()) {
|
||||
return effectiveLevel->Int;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
u_int Actor::TintFlags() const {
|
||||
return this->lsObject->GetMember("TintFlags").Int;
|
||||
if (const auto tintFlags = this->lsObject->GetMember("TintFlags"); tintFlags.has_value()) {
|
||||
return tintFlags->Int;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string Actor::VisualVariant() const {
|
||||
return {this->lsObject->GetMember("VisualVariant").CharPtr};
|
||||
if (const auto visualVariant = this->lsObject->GetMember("VisualVariant"); visualVariant.has_value()) {
|
||||
return visualVariant->CharPtr;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string Actor::Mood() const {
|
||||
return {this->lsObject->GetMember("Mood").CharPtr};
|
||||
if (const auto mood = this->lsObject->GetMember("Mood"); mood.has_value()) {
|
||||
return mood->CharPtr;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string Actor::CurrentAnimation() const {
|
||||
return {this->lsObject->GetMember("CurrentAnimation").CharPtr};
|
||||
if (const auto currentAnimation = this->lsObject->GetMember("CurrentAnimation"); currentAnimation.has_value()) {
|
||||
return currentAnimation->CharPtr;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string Actor::Overlay() const {
|
||||
return {this->lsObject->GetMember("Overlay").CharPtr};
|
||||
if (const auto overlay = this->lsObject->GetMember("Overlay"); overlay.has_value()) {
|
||||
return overlay->CharPtr;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string Actor::Aura() const {
|
||||
return {this->lsObject->GetMember("Aura").CharPtr};
|
||||
if (const auto aura = this->lsObject->GetMember("Aura"); aura.has_value()) {
|
||||
return aura->CharPtr;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string Actor::Guild() const {
|
||||
return {this->lsObject->GetMember("Guild").CharPtr};
|
||||
if (const auto guild = this->lsObject->GetMember("Guild"); guild.has_value()) {
|
||||
return guild->CharPtr;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string Actor::Type() const {
|
||||
return {this->lsObject->GetMember("Type").CharPtr};
|
||||
if (const auto type = this->lsObject->GetMember("Type"); type.has_value()) {
|
||||
return type->CharPtr;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string Actor::SuffixTitle() const {
|
||||
return {this->lsObject->GetMember("SuffixTitle").CharPtr};
|
||||
if (const auto suffixTitle = this->lsObject->GetMember("SuffixTitle"); suffixTitle.has_value()) {
|
||||
return suffixTitle->CharPtr;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string Actor::ConColor() const {
|
||||
return {this->lsObject->GetMember("ConColor").CharPtr};
|
||||
if (const auto conColor = this->lsObject->GetMember("ConColor"); conColor.has_value()) {
|
||||
return conColor->CharPtr;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string Actor::RawConColor() const {
|
||||
// TODO: Modify to accept a parameter & pass in the string 'raw'
|
||||
return {this->lsObject->GetMember("RawConColor").CharPtr};
|
||||
if (const auto rawConColor = this->lsObject->GetMember("RawConColor"); rawConColor.has_value()) {
|
||||
return rawConColor->CharPtr;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string Actor::FactionStanding() const {
|
||||
return {this->lsObject->GetMember("FactionStanding").CharPtr};
|
||||
if (const auto factionStanding = this->lsObject->GetMember("FactionStanding"); factionStanding.has_value()) {
|
||||
return factionStanding->CharPtr;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
int Actor::Faction() const {
|
||||
return this->lsObject->GetMember("Faction").Int;
|
||||
if (const auto faction = this->lsObject->GetMember("Faction"); faction.has_value()) {
|
||||
return faction->Int;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
Actor Actor::Target() const {
|
||||
return Actor(make_shared<LSObject>(LSObject(this->lsObject->GetMember("Target"))));
|
||||
if (const auto target = this->lsObject->GetMember("Target"); target.has_value()) {
|
||||
return Actor(make_shared<LSObject>(LSObject(target.value())));
|
||||
}
|
||||
return Actor(make_shared<LSObject>(nullopt));
|
||||
}
|
||||
|
||||
Actor Actor::Pet() const {
|
||||
return Actor(make_shared<LSObject>(LSObject(this->lsObject->GetMember("Pet"))));
|
||||
if (const auto pet = this->lsObject->GetMember("Pet"); pet.has_value()) {
|
||||
return Actor(make_shared<LSObject>(LSObject(pet.value())));
|
||||
}
|
||||
return Actor(make_shared<LSObject>(nullopt));
|
||||
}
|
||||
|
||||
int Actor::ThreatToPet() const {
|
||||
return this->lsObject->GetMember("ThreatToPet").Int;
|
||||
if (const auto threatToPet = this->lsObject->GetMember("ThreatToPet"); threatToPet.has_value()) {
|
||||
return threatToPet->Int;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
int Actor::ThreatToMe() const {
|
||||
return this->lsObject->GetMember("ThreatToMe").Int;
|
||||
if (const auto threatToMe = this->lsObject->GetMember("ThreatToMe"); threatToMe.has_value()) {
|
||||
return threatToMe->Int;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
int Actor::ThreatToNext() const {
|
||||
return this->lsObject->GetMember("ThreatToNext").Int;
|
||||
if (const auto threatToNext = this->lsObject->GetMember("ThreatToNext"); threatToNext.has_value()) {
|
||||
return threatToNext->Int;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
float Actor::Distance() const {
|
||||
return this->lsObject->GetMember("Distance").Float;
|
||||
if (const auto distance = this->lsObject->GetMember("Distance"); distance.has_value()) {
|
||||
return distance->Float;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
float Actor::Distance2d() const {
|
||||
return this->lsObject->GetMember("Distance2D").Float;
|
||||
if (const auto distance2d = this->lsObject->GetMember("Distance2D"); distance2d.has_value()) {
|
||||
return distance2d->Float;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
float Actor::X() const {
|
||||
return this->lsObject->GetMember("X").Float;
|
||||
if (const auto x = this->lsObject->GetMember("X"); x.has_value()) {
|
||||
return x->Float;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
float Actor::Y() const {
|
||||
return this->lsObject->GetMember("Y").Float;
|
||||
if (const auto y = this->lsObject->GetMember("Y"); y.has_value()) {
|
||||
return y->Float;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
float Actor::Z() const {
|
||||
return this->lsObject->GetMember("Z").Float;
|
||||
if (const auto z = this->lsObject->GetMember("Z"); z.has_value()) {
|
||||
return z->Float;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string Actor::Race() const {
|
||||
return {this->lsObject->GetMember("Race").CharPtr};
|
||||
if (const auto race = this->lsObject->GetMember("Race"); race.has_value()) {
|
||||
return race->CharPtr;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string Actor::Class() const {
|
||||
return {this->lsObject->GetMember("Class").CharPtr};
|
||||
if (const auto cls = this->lsObject->GetMember("Class"); cls.has_value()) {
|
||||
return cls->CharPtr;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string Actor::Gender() const {
|
||||
return {this->lsObject->GetMember("Gender").CharPtr};
|
||||
if (const auto gender = this->lsObject->GetMember("Gender"); gender.has_value()) {
|
||||
return gender->CharPtr;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
Point3f Actor::Location() const {
|
||||
return Point3f(make_shared<LSObject>(LSObject(this->lsObject->GetMember("Location"))));
|
||||
if (const auto location = this->lsObject->GetMember("Location"); location.has_value()) {
|
||||
return Point3f(make_shared<LSObject>(LSObject(location.value())));
|
||||
}
|
||||
return Point3f(make_shared<LSObject>(nullopt));
|
||||
}
|
||||
|
||||
float Actor::Heading() const {
|
||||
return this->lsObject->GetMember("Heading").Float;
|
||||
if (const auto heading = this->lsObject->GetMember("Heading"); heading.has_value()) {
|
||||
return heading->Float;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
string Actor::HeadingToAsString() const {
|
||||
return this->lsObject->GetMember("HeadingTo", "AsString").CharPtr;
|
||||
if (const auto headingTo = this->lsObject->GetMember("HeadingTo"); headingTo.has_value()) {
|
||||
return headingTo->CharPtr;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
Point3f Actor::Velocity() const {
|
||||
return Point3f(make_shared<LSObject>(LSObject(this->lsObject->GetMember("Velocity"))));
|
||||
if (const auto velocity = this->lsObject->GetMember("Velocity"); velocity.has_value()) {
|
||||
return Point3f(make_shared<LSObject>(LSObject(velocity.value())));
|
||||
}
|
||||
return Point3f(make_shared<LSObject>(LSObject(nullopt)));
|
||||
}
|
||||
|
||||
bool Actor::CheckCollision() const {
|
||||
return this->lsObject->GetMember("CheckCollision").Int;
|
||||
if (const auto checkCollision = this->lsObject->GetMember("CheckCollision"); checkCollision.has_value()) {
|
||||
return checkCollision->Int;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Actor::CheckCollision(const float toX, const float toY, const float toZ) const {
|
||||
return this->lsObject->GetMember("CheckCollision", toX, toY, toZ).Int;
|
||||
if (const auto checkCollision = this->lsObject->GetMember("CheckCollision", toX, toY, toZ); checkCollision.
|
||||
has_value()) {
|
||||
return checkCollision->Int;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
float Actor::TargetRingRadius() const {
|
||||
return this->lsObject->GetMember("TargetRingRadius").Float;
|
||||
if (const auto targetRingRadius = this->lsObject->GetMember("TargetRingRadius"); targetRingRadius.has_value()) {
|
||||
return targetRingRadius->Float;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
float Actor::CollisionRadius() const {
|
||||
return this->lsObject->GetMember("CollisionRadius").Float;
|
||||
if (const auto collisionRadius = this->lsObject->GetMember("CollisionRadius"); collisionRadius.has_value()) {
|
||||
return collisionRadius->Float;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
float Actor::CollisionScale() const {
|
||||
return this->lsObject->GetMember("CollisionScale").Float;
|
||||
if (const auto collisionScale = this->lsObject->GetMember("CollisionScale"); collisionScale.has_value()) {
|
||||
return collisionScale->Float;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
u_long Actor::WhoFollowingId() const {
|
||||
return this->lsObject->GetMember("WhoFollowingID").Int64;
|
||||
if (const auto whoFollowingId = this->lsObject->GetMember("WhoFollowing"); whoFollowingId.has_value()) {
|
||||
return whoFollowingId->Int64;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
string Actor::WhoFollowingName() const {
|
||||
return this->lsObject->GetMember("WhoFollowing").CharPtr;
|
||||
if (const auto whoFollowingName = this->lsObject->GetMember("WhoFollowing"); whoFollowingName.has_value()) {
|
||||
return whoFollowingName->CharPtr;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
float Actor::Speed() const {
|
||||
return this->lsObject->GetMember("Speed").Float;
|
||||
if (const auto speed = this->lsObject->GetMember("Speed"); speed.has_value()) {
|
||||
return speed->Float;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
float Actor::SwimmingSpeedModifier() const {
|
||||
return this->lsObject->GetMember("SwimmingSpeedMod").Float;
|
||||
if (const auto swimmingSpeedModifier = this->lsObject->GetMember("SwimmingSpeedMod"); swimmingSpeedModifier.
|
||||
has_value()) {
|
||||
return swimmingSpeedModifier->Float;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
bool Actor::InMyGroup() const {
|
||||
return this->lsObject->GetMember("InMyGroup").Int;
|
||||
if (const auto inMyGroup = this->lsObject->GetMember("InMyGroup"); inMyGroup.has_value()) {
|
||||
return inMyGroup->Int;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Actor::Interactable() const {
|
||||
return this->lsObject->GetMember("Interactable").Int;
|
||||
if (const auto interactable = this->lsObject->GetMember("Interactable"); interactable.has_value()) {
|
||||
return interactable->Int;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Actor::OnFlyingMount() const {
|
||||
return this->lsObject->GetMember("OnFlyingMount").Int;
|
||||
if (const auto onFlyingMount = this->lsObject->GetMember("OnFlyingMount"); onFlyingMount.has_value()) {
|
||||
return onFlyingMount->Int;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Actor::FlyingUsingMount() const {
|
||||
return this->lsObject->GetMember("FlyingUsingMount").Int;
|
||||
if (const auto flyingUsingMount = this->lsObject->GetMember("FlyingUsingMount"); flyingUsingMount.has_value()) {
|
||||
return flyingUsingMount->Int;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Actor::IsChest() const {
|
||||
return this->lsObject->GetMember("IsChest").Int;
|
||||
if (const auto isChest = this->lsObject->GetMember("IsChest"); isChest.has_value()) {
|
||||
return isChest->Int;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Actor::IsBanker() const {
|
||||
return this->lsObject->GetMember("IsBanker").Int;
|
||||
if (const auto isBanker = this->lsObject->GetMember("IsBanker"); isBanker.has_value()) {
|
||||
return isBanker->Int;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Actor::IsMerchant() const {
|
||||
return this->lsObject->GetMember("IsMerchant").Int;
|
||||
if (const auto isMerchant = this->lsObject->GetMember("IsMerchant"); isMerchant.has_value()) {
|
||||
return isMerchant->Int;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Actor::IsAPet() const {
|
||||
return this->lsObject->GetMember("IsAPet").Int;
|
||||
if (const auto isAPet = this->lsObject->GetMember("IsAPet"); isAPet.has_value()) {
|
||||
return isAPet->Int;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Actor::IsMyPet() const {
|
||||
return this->lsObject->GetMember("IsMyPet").Int;
|
||||
if (const auto isMyPet = this->lsObject->GetMember("IsMyPet"); isMyPet.has_value()) {
|
||||
return isMyPet->Int;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Actor::IsAfk() const {
|
||||
return this->lsObject->GetMember("IsAFK").Int;
|
||||
if (const auto isAfk = this->lsObject->GetMember("IsAFK"); isAfk.has_value()) {
|
||||
return isAfk->Int;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Actor::IsLfw() const {
|
||||
return this->lsObject->GetMember("IsLFW").Int;
|
||||
if (const auto isLfw = this->lsObject->GetMember("IsLFW"); isLfw.has_value()) {
|
||||
return isLfw->Int;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Actor::IsLfg() const {
|
||||
return this->lsObject->GetMember("IsLFG").Int;
|
||||
if (const auto isLfg = this->lsObject->GetMember("IsLFG"); isLfg.has_value()) {
|
||||
return isLfg->Int;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Actor::IsLinkdead() const {
|
||||
return this->lsObject->GetMember("IsLinkdead").Int;
|
||||
if (const auto isLinkdead = this->lsObject->GetMember("IsLinkdead"); isLinkdead.has_value()) {
|
||||
return isLinkdead->Int;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Actor::IsCamping() const {
|
||||
return this->lsObject->GetMember("IsCamping").Int;
|
||||
if (const auto isCamping = this->lsObject->GetMember("IsCamping"); isCamping.has_value()) {
|
||||
return isCamping->Int;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Actor::IsLocked() const {
|
||||
return this->lsObject->GetMember("IsLocked").Int;
|
||||
if (const auto isLocked = this->lsObject->GetMember("IsLocked"); isLocked.has_value()) {
|
||||
return isLocked->Int;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Actor::IsAggro() const {
|
||||
return this->lsObject->GetMember("IsAggro").Int;
|
||||
if (const auto isAggro = this->lsObject->GetMember("IsAggro"); isAggro.has_value()) {
|
||||
return isAggro->Int;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Actor::IsSolo() const {
|
||||
return this->lsObject->GetMember("IsSolo").Int;
|
||||
if (const auto isSolo = this->lsObject->GetMember("IsSolo"); isSolo.has_value()) {
|
||||
return isSolo->Int;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Actor::IsHeroic() const {
|
||||
return this->lsObject->GetMember("IsHeroic").Int;
|
||||
if (const auto isHeroic = this->lsObject->GetMember("IsHeroic"); isHeroic.has_value()) {
|
||||
return isHeroic->Int;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Actor::IsEpic() const {
|
||||
return this->lsObject->GetMember("IsEpic").Int;
|
||||
if (const auto isEpic = this->lsObject->GetMember("IsEpic"); isEpic.has_value()) {
|
||||
return isEpic->Int;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Actor::IsNamed() const {
|
||||
return this->lsObject->GetMember("IsNamed").Int;
|
||||
if (const auto isNamed = this->lsObject->GetMember("IsNamed"); isNamed.has_value()) {
|
||||
return isNamed->Int;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Actor::IsSwimming() const {
|
||||
return this->lsObject->GetMember("IsSwimming").Int;
|
||||
if (const auto isSwimming = this->lsObject->GetMember("IsSwimming"); isSwimming.has_value()) {
|
||||
return isSwimming->Int;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Actor::IsEncounterBroken() const {
|
||||
return this->lsObject->GetMember("IsEncounterBroken").Int;
|
||||
if (const auto isEncounterBroken = this->lsObject->GetMember("IsEncounterBroken"); isEncounterBroken.has_value()) {
|
||||
isEncounterBroken->Int;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Actor::IsInvisible() const {
|
||||
return this->lsObject->GetMember("IsInvisible").Int;
|
||||
if (const auto isInvisible = this->lsObject->GetMember("IsInvisible"); isInvisible.has_value()) {
|
||||
return isInvisible->Int;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Actor::IsClimbing() const {
|
||||
return this->lsObject->GetMember("IsClimbing").Int;
|
||||
if (const auto isClimbing = this->lsObject->GetMember("IsClimbing"); isClimbing.has_value()) {
|
||||
return isClimbing->Int;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Actor::IsJumping() const {
|
||||
return this->lsObject->GetMember("IsJumping").Int;
|
||||
if (const auto isJumping = this->lsObject->GetMember("IsJumping"); isJumping.has_value()) {
|
||||
return isJumping->Int;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Actor::IsFalling() const {
|
||||
return this->lsObject->GetMember("IsFalling").Int;
|
||||
if (const auto isFalling = this->lsObject->GetMember("IsFalling"); isFalling.has_value()) {
|
||||
return isFalling->Int;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Actor::IsFD() const {
|
||||
return this->lsObject->GetMember("IsFD").Int;
|
||||
if (const auto isFD = this->lsObject->GetMember("IsFD"); isFD.has_value()) {
|
||||
return isFD->Int;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Actor::IsDead() const {
|
||||
return this->lsObject->GetMember("IsDead").Int;
|
||||
if (const auto isDead = this->lsObject->GetMember("IsDead"); isDead.has_value()) {
|
||||
return isDead->Int;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Actor::IsRooted() const {
|
||||
return this->lsObject->GetMember("IsRooted").Int;
|
||||
if (const auto isRooted = this->lsObject->GetMember("IsRooted"); isRooted.has_value()) {
|
||||
return isRooted->Int;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Actor::CanTurn() const {
|
||||
return this->lsObject->GetMember("CanTurn").Int;
|
||||
if (const auto canTurn = this->lsObject->GetMember("CanTurn"); canTurn.has_value()) {
|
||||
return canTurn->Int;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Actor::InCombatMode() const {
|
||||
return this->lsObject->GetMember("InCombatMode").Int;
|
||||
if (const auto inCombatMode = this->lsObject->GetMember("InCombatMode"); inCombatMode.has_value()) {
|
||||
return inCombatMode->Int;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Actor::IsCrouching() const {
|
||||
return this->lsObject->GetMember("IsCrouching").Int;
|
||||
if (const auto isCrouching = this->lsObject->GetMember("IsCrouching"); isCrouching.has_value()) {
|
||||
return isCrouching->Int;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Actor::IsSitting() const {
|
||||
return this->lsObject->GetMember("IsSitting").Int;
|
||||
if (const auto isSitting = this->lsObject->GetMember("IsSitting"); isSitting.has_value()) {
|
||||
return isSitting->Int;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Actor::OnCarpet() const {
|
||||
return this->lsObject->GetMember("OnCarpet").Int;
|
||||
if (const auto onCarpet = this->lsObject->GetMember("OnCarpet"); onCarpet.has_value()) {
|
||||
return onCarpet->Int;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Actor::OnHorse() const {
|
||||
return this->lsObject->GetMember("OnHorse").Int;
|
||||
if (const auto onHorse = this->lsObject->GetMember("OnHorse"); onHorse.has_value()) {
|
||||
return onHorse->Int;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Actor::ONGriphon() const {
|
||||
return this->lsObject->GetMember("OnGriphon").Int;
|
||||
if (const auto onGriphon = this->lsObject->GetMember("OnGriphon"); onGriphon.has_value()) {
|
||||
return onGriphon->Int;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Actor::IsRunning() const {
|
||||
return this->lsObject->GetMember("IsRunning").Int;
|
||||
if (const auto isRunning = this->lsObject->GetMember("IsRunning"); isRunning.has_value()) {
|
||||
return isRunning->Int;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Actor::IsWalking() const {
|
||||
return this->lsObject->GetMember("IsWalking").Int;
|
||||
if (const auto isWalking = this->lsObject->GetMember("IsWalking"); isWalking.has_value()) {
|
||||
return isWalking->Int;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Actor::IsSprinting() const {
|
||||
return this->lsObject->GetMember("IsSprinting").Int;
|
||||
if (const auto isSprinting = this->lsObject->GetMember("IsSprinting"); isSprinting.has_value()) {
|
||||
return isSprinting->Int;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Actor::IsBackingUp() const {
|
||||
return this->lsObject->GetMember("IsBackingUp").Int;
|
||||
if (const auto isBackingUp = this->lsObject->GetMember("IsBackingUp"); isBackingUp.has_value()) {
|
||||
return isBackingUp->Int;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Actor::IsStrafingLeft() const {
|
||||
return this->lsObject->GetMember("IsStrafingLeft").Int;
|
||||
if (const auto isStrafingLeft = this->lsObject->GetMember("IsStrafingLeft"); isStrafingLeft.has_value()) {
|
||||
return isStrafingLeft->Int;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Actor::IsStrafingRight() const {
|
||||
return this->lsObject->GetMember("IsStrafingRight").Int;
|
||||
if (const auto isStrafingRight = this->lsObject->GetMember("IsStrafingRight"); isStrafingRight.has_value()) {
|
||||
return isStrafingRight->Int;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Actor::IsIdle() const {
|
||||
return this->lsObject->GetMember("IsIdle").Int;
|
||||
if (const auto isIdle = this->lsObject->GetMember("IsIdle"); isIdle.has_value()) {
|
||||
return isIdle->Int;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int Actor::EncounterSize() const {
|
||||
return this->lsObject->GetMember("EncounterSize").Int;
|
||||
if (const auto encounterSize = this->lsObject->GetMember("EncounterSize"); encounterSize.has_value()) {
|
||||
return encounterSize->Int;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
int Actor::Difficulty() const {
|
||||
return this->lsObject->GetMember("Difficulty").Int;
|
||||
if (const auto difficulty = this->lsObject->GetMember("Difficulty"); difficulty.has_value()) {
|
||||
return difficulty->Int;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
int Actor::IsInSameEncounter(const u_long id) const {
|
||||
return this->lsObject->GetMember("IsInSameEncounter", id).Int;
|
||||
if (const auto isInSameEncounter = this->lsObject->GetMember("IsInSameEncounter", id); isInSameEncounter.
|
||||
has_value()) {
|
||||
return isInSameEncounter->Int;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
int Actor::RaidSize() const {
|
||||
return this->lsObject->GetMember("RaidSize").Int;
|
||||
if (const auto raidSize = this->lsObject->GetMember("RaidSize"); raidSize.has_value()) {
|
||||
return raidSize->Int;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
string Actor::TagTargetNumber() const {
|
||||
return this->lsObject->GetMember("TagTargetNumber").CharPtr;
|
||||
if (const auto tagTargetNumber = this->lsObject->GetMember("TagTargetNumber"); tagTargetNumber.has_value()) {
|
||||
return tagTargetNumber->CharPtr;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
string Actor::TagTargetIcon() const {
|
||||
return this->lsObject->GetMember("TagTargetIcon").CharPtr;
|
||||
if (const auto tagTargetIcon = this->lsObject->GetMember("TagTargetIcon"); tagTargetIcon.has_value()) {
|
||||
return tagTargetIcon->CharPtr;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
int Actor::EffectCount() const {
|
||||
return this->lsObject->GetMember("EffectCount").Int;
|
||||
if (const auto effectCount = this->lsObject->GetMember("EffectCount"); effectCount.has_value()) {
|
||||
return effectCount->Int;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
void Actor::DoubleClick() const {
|
||||
|
||||
@ -14,107 +14,189 @@ public:
|
||||
|
||||
// General
|
||||
u_long Id() const;
|
||||
|
||||
std::string Name() const;
|
||||
|
||||
std::string LastName() const;
|
||||
|
||||
int HealthPercentage() const;
|
||||
|
||||
int PowerPercentage() const;
|
||||
|
||||
int Level() const;
|
||||
|
||||
int EffectiveLevel() const;
|
||||
|
||||
u_int TintFlags() const;
|
||||
|
||||
std::string VisualVariant() const;
|
||||
|
||||
std::string Mood() const;
|
||||
|
||||
std::string CurrentAnimation() const;
|
||||
|
||||
std::string Overlay() const;
|
||||
|
||||
std::string Aura() const;
|
||||
|
||||
std::string Gender() const;
|
||||
|
||||
std::string Race() const;
|
||||
|
||||
std::string Class() const;
|
||||
|
||||
std::string Guild() const;
|
||||
|
||||
std::string Type() const;
|
||||
|
||||
std::string SuffixTitle() const;
|
||||
|
||||
std::string ConColor() const;
|
||||
|
||||
std::string RawConColor() const;
|
||||
|
||||
std::string FactionStanding() const;
|
||||
|
||||
int Faction() const;
|
||||
|
||||
Actor Target() const;
|
||||
|
||||
Actor Pet() const;
|
||||
|
||||
// Threat
|
||||
int ThreatToPet() const;
|
||||
|
||||
int ThreatToMe() const;
|
||||
|
||||
int ThreatToNext() const;
|
||||
|
||||
// Location
|
||||
float Distance() const; // Note: This is the distance using three dimensions, which is what the EQ2 client primarily uses for determining ability ranges, etc.
|
||||
float Distance() const;
|
||||
|
||||
// Note: This is the distance using three dimensions, which is what the EQ2 client primarily uses for determining ability ranges, etc.
|
||||
float Distance2d() const;
|
||||
|
||||
float X() const;
|
||||
|
||||
float Y() const;
|
||||
|
||||
float Z() const;
|
||||
|
||||
Point3f Location() const;
|
||||
|
||||
float Heading() const;
|
||||
|
||||
string HeadingToAsString() const;
|
||||
|
||||
Point3f Velocity() const;
|
||||
|
||||
bool CheckCollision() const;
|
||||
|
||||
bool CheckCollision(const float toX, const float toY, const float toZ) const;
|
||||
|
||||
float TargetRingRadius() const;
|
||||
|
||||
float CollisionRadius() const;
|
||||
|
||||
float CollisionScale() const;
|
||||
|
||||
u_long WhoFollowingId() const;
|
||||
|
||||
string WhoFollowingName() const;
|
||||
|
||||
float Speed() const;
|
||||
|
||||
float SwimmingSpeedModifier() const;
|
||||
|
||||
// Booleans
|
||||
bool InMyGroup() const;
|
||||
|
||||
bool Interactable() const;
|
||||
|
||||
bool OnFlyingMount() const;
|
||||
|
||||
bool FlyingUsingMount() const;
|
||||
|
||||
bool IsChest() const;
|
||||
|
||||
bool IsBanker() const;
|
||||
|
||||
bool IsMerchant() const;
|
||||
|
||||
bool IsAPet() const;
|
||||
|
||||
bool IsMyPet() const;
|
||||
|
||||
bool IsAfk() const;
|
||||
|
||||
bool IsLfw() const;
|
||||
|
||||
bool IsLfg() const;
|
||||
|
||||
bool IsLinkdead() const;
|
||||
|
||||
bool IsCamping() const;
|
||||
|
||||
bool IsLocked() const;
|
||||
|
||||
bool IsAggro() const;
|
||||
|
||||
bool IsSolo() const;
|
||||
|
||||
bool IsHeroic() const;
|
||||
|
||||
bool IsEpic() const;
|
||||
|
||||
bool IsNamed() const;
|
||||
|
||||
bool IsSwimming() const;
|
||||
|
||||
bool IsEncounterBroken() const;
|
||||
|
||||
bool IsInvisible() const;
|
||||
|
||||
bool IsClimbing() const;
|
||||
|
||||
bool IsJumping() const;
|
||||
|
||||
bool IsFalling() const;
|
||||
|
||||
bool IsFD() const;
|
||||
|
||||
bool IsDead() const;
|
||||
|
||||
bool IsRooted() const;
|
||||
|
||||
bool CanTurn() const;
|
||||
|
||||
// The following members are mutually exclusive.
|
||||
bool InCombatMode() const;
|
||||
|
||||
bool IsCrouching() const;
|
||||
|
||||
bool IsSitting() const;
|
||||
|
||||
// The following members are mutually exclusive.
|
||||
bool OnCarpet() const;
|
||||
|
||||
bool OnHorse() const;
|
||||
|
||||
bool ONGriphon() const;
|
||||
|
||||
// The following members are mutually exclusive.
|
||||
bool IsRunning() const;
|
||||
|
||||
bool IsWalking() const;
|
||||
|
||||
bool IsSprinting() const;
|
||||
|
||||
// The following members are mutually exclusive.
|
||||
bool IsBackingUp() const;
|
||||
|
||||
bool IsStrafingLeft() const;
|
||||
|
||||
bool IsStrafingRight() const;
|
||||
|
||||
bool IsIdle() const;
|
||||
|
||||
// Encounter Information
|
||||
@ -122,10 +204,14 @@ public:
|
||||
|
||||
/// \brief Returns the encounter difficulty as a range of -3 to 3. (-3 = three down arrows, 0 = no arrows, 3 = three up arrows)
|
||||
int Difficulty() const;
|
||||
|
||||
/// \brief Given another actor's ID#, returns TRUE if this actor is in the same encounter.
|
||||
int IsInSameEncounter(const u_long id) const;
|
||||
|
||||
int RaidSize() const;
|
||||
|
||||
string TagTargetNumber() const;
|
||||
|
||||
string TagTargetIcon() const;
|
||||
|
||||
// Effects
|
||||
@ -136,20 +222,22 @@ public:
|
||||
|
||||
// Methods
|
||||
void DoubleClick() const;
|
||||
void WaypointTo() const;
|
||||
void DoFace() const;
|
||||
void DoTarget() const;
|
||||
void AddLocation(const string ¬es) const;
|
||||
void DeleteLocation() const;
|
||||
void RequesteffectsInfo() const;
|
||||
|
||||
void WaypointTo() const;
|
||||
|
||||
void DoFace() const;
|
||||
|
||||
void DoTarget() const;
|
||||
|
||||
void AddLocation(const string ¬es) const;
|
||||
|
||||
void DeleteLocation() const;
|
||||
|
||||
void RequesteffectsInfo() const;
|
||||
|
||||
protected:
|
||||
const shared_ptr<LSObject> lsObject;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif //ACTOR_H
|
||||
|
||||
@ -1,23 +1,38 @@
|
||||
#include "Character.h"
|
||||
|
||||
std::string Character::Archetype() const {
|
||||
return this->lsObject->GetMember("Archetype").CharPtr;
|
||||
const auto res = this->lsObject->GetMember("Archetype");
|
||||
return res.has_value()
|
||||
? res->CharPtr
|
||||
: string();
|
||||
}
|
||||
|
||||
std::string Character::SubClass() const {
|
||||
return this->lsObject->GetMember("SubClass").CharPtr;
|
||||
const auto res = this->lsObject->GetMember("SubClass");
|
||||
return res.has_value()
|
||||
? res->CharPtr
|
||||
: string();
|
||||
}
|
||||
|
||||
std::string Character::TradeskillArchtype() const {
|
||||
return this->lsObject->GetMember("TSArchetype").CharPtr;
|
||||
const auto res = this->lsObject->GetMember("TSArchetype");
|
||||
return res.has_value()
|
||||
? res->CharPtr
|
||||
: string();
|
||||
}
|
||||
|
||||
std::string Character::TradeskillClass() const {
|
||||
return this->lsObject->GetMember("TSClass").CharPtr;
|
||||
const auto res = this->lsObject->GetMember("TSClass");
|
||||
return res.has_value()
|
||||
? res->CharPtr
|
||||
: string();
|
||||
}
|
||||
|
||||
std::string Character::TradeskillSubClass() const {
|
||||
return this->lsObject->GetMember("TSSubClass").CharPtr;
|
||||
const auto res = this->lsObject->GetMember("TSSubClass");
|
||||
return res.has_value()
|
||||
? res->CharPtr
|
||||
: string();
|
||||
}
|
||||
|
||||
Actor Character::CursorActor() const {
|
||||
@ -25,59 +40,209 @@ Actor Character::CursorActor() const {
|
||||
}
|
||||
|
||||
bool Character::IsMoving() const {
|
||||
return this->lsObject->GetMember("IsMoving").Int;
|
||||
const auto res = this->lsObject->GetMember("IsMoving");
|
||||
return res.has_value()
|
||||
? res->Int
|
||||
: false;
|
||||
}
|
||||
|
||||
bool Character::InGameWorld() const {
|
||||
return this->lsObject->GetMember("InGameWorld").Int;
|
||||
const auto res = this->lsObject->GetMember("InGameWorld");
|
||||
return res.has_value()
|
||||
? res->Int
|
||||
: false;
|
||||
}
|
||||
|
||||
bool Character::AtCharSelect() const {
|
||||
return this->lsObject->GetMember("AtCharSelect").Int;
|
||||
const auto res = this->lsObject->GetMember("AtCharSelect");
|
||||
return res.has_value()
|
||||
? res->Int
|
||||
: false;
|
||||
}
|
||||
|
||||
float Character::WaterDepth() const {
|
||||
return this->lsObject->GetMember("WaterDepth").Float;
|
||||
const auto res = this->lsObject->GetMember("WaterDepth");
|
||||
return res.has_value()
|
||||
? res->Float
|
||||
: false;
|
||||
}
|
||||
|
||||
float Character::HeadingTo(const float toX, const float toY, const float toZ) const {
|
||||
return this->lsObject->GetMember("HeadingTo", toX, toY, toZ).Float;
|
||||
const auto res = this->lsObject->GetMember("HeadingTo", toX, toY, toZ);
|
||||
return res.has_value() ? res->Float : 0.0f;
|
||||
}
|
||||
|
||||
string Character::HeadingToAsString(const float toX, const float toY, const float toZ) const {
|
||||
return this->lsObject->GetMember("HeadingTo", toX, toY, toZ, "AsString").CharPtr;
|
||||
const auto res = this->lsObject->GetMember("HeadingTo", toX, toY, toZ, "AsString");
|
||||
return res.has_value() ? res->CharPtr : string();
|
||||
}
|
||||
|
||||
int Character::VeteranBonus() const {
|
||||
return this->lsObject->GetMember("VeteranBonus").Int;
|
||||
const auto res = this->lsObject->GetMember("VeteranBonus");
|
||||
return res.has_value()
|
||||
? res->Int
|
||||
: 0;
|
||||
}
|
||||
|
||||
int Character::Level() const {
|
||||
return this->lsObject->GetMember("Level").Int;
|
||||
const auto res = this->lsObject->GetMember("Level");
|
||||
return res.has_value()
|
||||
? res->Int
|
||||
: 0;
|
||||
}
|
||||
|
||||
int Character::EffectiveLevel() const {
|
||||
return this->lsObject->GetMember("EffectiveLevel").Int;
|
||||
const auto res = this->lsObject->GetMember("EffectiveLevel");
|
||||
return res.has_value()
|
||||
? res->Int
|
||||
: 0;
|
||||
}
|
||||
|
||||
int Character::TradeskillLevel() const {
|
||||
return this->lsObject->GetMember("TSLevel").Int;
|
||||
const auto res = this->lsObject->GetMember("TSLevel");
|
||||
return res.has_value()
|
||||
? res->Int
|
||||
: 0;
|
||||
}
|
||||
|
||||
int Character::APExperience() const {
|
||||
return this->lsObject->GetMember("APExp").Int;
|
||||
const auto res = this->lsObject->GetMember("APExp");
|
||||
return res.has_value()
|
||||
? res->Int
|
||||
: 0;
|
||||
}
|
||||
|
||||
int Character::TotalEarnedAPs() const {
|
||||
return this->lsObject->GetMember("TotalEarnedAPs").Int;
|
||||
const auto res = this->lsObject->GetMember("TotalEarnedAPs");
|
||||
return res.has_value()
|
||||
? res->Int
|
||||
: 0;
|
||||
}
|
||||
|
||||
int Character::MaxAPs() const {
|
||||
return this->lsObject->GetMember("MaxAPs").Int;
|
||||
const auto res = this->lsObject->GetMember("MaxAPs");
|
||||
return res.has_value()
|
||||
? res->Int
|
||||
: 0;
|
||||
}
|
||||
|
||||
u_long Character::Copper() const {
|
||||
const auto res = this->lsObject->GetMember("Copper");
|
||||
return res.has_value()
|
||||
? res->Int64
|
||||
: 0;
|
||||
}
|
||||
|
||||
u_long Character::Silver() const {
|
||||
const auto res = this->lsObject->GetMember("Silver");
|
||||
return res.has_value()
|
||||
? res->Int64
|
||||
: 0;
|
||||
}
|
||||
|
||||
u_long Character::Gold() const {
|
||||
const auto res = this->lsObject->GetMember("Gold");
|
||||
return res.has_value()
|
||||
? res->Int64
|
||||
: 0;
|
||||
}
|
||||
|
||||
u_long Character::Platinum() const {
|
||||
const auto res = this->lsObject->GetMember("Platinum");
|
||||
return res.has_value()
|
||||
? res->Int64
|
||||
: 0;
|
||||
}
|
||||
|
||||
bool Character::IsGroupLeader() const {
|
||||
const auto res = this->lsObject->GetMember("IsGroupLeader");
|
||||
return res.has_value()
|
||||
? res->Int
|
||||
: 0;
|
||||
}
|
||||
|
||||
bool Character::Grouped() const {
|
||||
const auto res = this->lsObject->GetMember("Grouped");
|
||||
return res.has_value()
|
||||
? res->Int
|
||||
: 0;
|
||||
}
|
||||
|
||||
int Character::GroupCount() const {
|
||||
const auto res = this->lsObject->GetMember("GroupCount");
|
||||
return res.has_value()
|
||||
? res->Int
|
||||
: 0;
|
||||
}
|
||||
|
||||
GroupMember Character::GroupMemberByIndex(const int index) const {
|
||||
if (index <= 0 || index >= 7) {
|
||||
throw std::invalid_argument("index must be between 1 and 6");
|
||||
}
|
||||
return GroupMember(make_shared<LSObject>(LSObject(this->lsObject->GetMember("GroupMember", index))));
|
||||
}
|
||||
|
||||
GroupMember Character::GroupMemberByName(const string &name) const {
|
||||
return GroupMember(make_shared<LSObject>(LSObject(this->lsObject->GetMember("GroupMember", name))));
|
||||
}
|
||||
|
||||
GroupMember Character::GroupMemberById(const u_long id) const {
|
||||
return GroupMember(make_shared<LSObject>(LSObject(this->lsObject->GetMember("GroupMember", "id", id))));
|
||||
}
|
||||
|
||||
int Character::RaidCount() const {
|
||||
const auto res = this->lsObject->GetMember("RaidCount");
|
||||
return res.has_value()
|
||||
? res->Int
|
||||
: 0;
|
||||
}
|
||||
|
||||
int Character::RaidGroupNumber() const {
|
||||
const auto res = this->lsObject->GetMember("RaidGroupNumber");
|
||||
return res.has_value()
|
||||
? res->Int
|
||||
: 0;
|
||||
}
|
||||
|
||||
int Character::Raid() const {
|
||||
const auto res = this->lsObject->GetMember("Raid");
|
||||
return res.has_value()
|
||||
? res->Int
|
||||
: 0;
|
||||
}
|
||||
|
||||
GroupMember Character::RaidMemberByIndex(const int index) const {
|
||||
if (index <= 0 || index >= 25) {
|
||||
throw std::invalid_argument("index must be between 1 and 24");
|
||||
}
|
||||
|
||||
return GroupMember(make_shared<LSObject>(LSObject(this->lsObject->GetMember("Raid", index))));
|
||||
}
|
||||
|
||||
GroupMember Character::RaidMemberByName(const string &name) const {
|
||||
return GroupMember(make_shared<LSObject>(LSObject(this->lsObject->GetMember("Raid", name))));
|
||||
}
|
||||
|
||||
GroupMember Character::RaidMemberById(const u_long id) const {
|
||||
return GroupMember(make_shared<LSObject>(LSObject(this->lsObject->GetMember("Raid", "id", id))));
|
||||
}
|
||||
|
||||
GroupMember Character::RaidMemberByGroupAndIndex(const int group, const int index) const {
|
||||
if (group <= 0 || group >= 5) {
|
||||
throw std::invalid_argument("group must be between 1 and 4");
|
||||
}
|
||||
|
||||
if (index <= 0 || index >= 7) {
|
||||
throw std::invalid_argument("index must be between 1 and 6");
|
||||
}
|
||||
return GroupMember(make_shared<LSObject>(LSObject(this->lsObject->GetMember("Raid", group, index))));
|
||||
}
|
||||
|
||||
int Character::NumAbilities() const {
|
||||
return this->lsObject->GetMember("NumAbilities").Int;
|
||||
const auto res = this->lsObject->GetMember("NumAbilities");
|
||||
return res.has_value()
|
||||
? res->Int
|
||||
: 0;
|
||||
}
|
||||
|
||||
Ability Character::Ability(const int index) const {
|
||||
|
||||
@ -6,42 +6,98 @@
|
||||
#include "Ability.h"
|
||||
#include "LSObject.h"
|
||||
#include "Actor.h"
|
||||
#include "GroupMember.h"
|
||||
|
||||
class Character : public Actor {
|
||||
public:
|
||||
explicit Character(const shared_ptr<LSObject> &obj) : Actor(obj) { }
|
||||
explicit Character(const shared_ptr<LSObject> &obj) : Actor(obj) {
|
||||
}
|
||||
|
||||
std::string Archetype() const;
|
||||
|
||||
std::string SubClass() const;
|
||||
|
||||
std::string TradeskillArchtype() const;
|
||||
|
||||
std::string TradeskillClass() const;
|
||||
|
||||
std::string TradeskillSubClass() const;
|
||||
|
||||
Actor CursorActor() const;
|
||||
|
||||
// GameData
|
||||
|
||||
// Location
|
||||
bool IsMoving() const;
|
||||
|
||||
bool InGameWorld() const;
|
||||
|
||||
bool AtCharSelect() const;
|
||||
|
||||
float WaterDepth() const;
|
||||
|
||||
float HeadingTo(float toX, float toY, float toZ) const;
|
||||
|
||||
string HeadingToAsString(float toX, float toY, float toZ) const;
|
||||
|
||||
// Experience/Level
|
||||
int VeteranBonus() const;
|
||||
|
||||
int Level() const;
|
||||
|
||||
int EffectiveLevel() const;
|
||||
|
||||
int TradeskillLevel() const;
|
||||
|
||||
int APExperience() const;
|
||||
|
||||
int TotalEarnedAPs() const;
|
||||
|
||||
int MaxAPs() const;
|
||||
|
||||
|
||||
// Money
|
||||
u_long Copper() const;
|
||||
|
||||
u_long Silver() const;
|
||||
|
||||
u_long Gold() const;
|
||||
|
||||
u_long Platinum() const;
|
||||
|
||||
// Group information
|
||||
bool IsGroupLeader() const;
|
||||
|
||||
bool Grouped() const;
|
||||
|
||||
int GroupCount() const;
|
||||
|
||||
GroupMember GroupMemberByIndex(const int index) const;
|
||||
|
||||
GroupMember GroupMemberByName(const string &name) const;
|
||||
|
||||
GroupMember GroupMemberById(const u_long id) const;
|
||||
|
||||
// Raid Information
|
||||
int RaidCount() const;
|
||||
|
||||
int RaidGroupNumber() const;
|
||||
|
||||
int Raid() const;
|
||||
|
||||
GroupMember RaidMemberByIndex(const int index) const;
|
||||
|
||||
GroupMember RaidMemberByName(const string &name) const;
|
||||
|
||||
GroupMember RaidMemberById(const u_long id) const;
|
||||
|
||||
GroupMember RaidMemberByGroupAndIndex(const int group, const int index) const;
|
||||
|
||||
// Abilities & Recipes
|
||||
int NumAbilities() const;
|
||||
|
||||
Ability Ability(int index) const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif //CHARACTER_H
|
||||
|
||||
@ -1,6 +1,3 @@
|
||||
//
|
||||
// Created by marob on 12/27/2023.
|
||||
//
|
||||
|
||||
#ifndef CLASS_H
|
||||
#define CLASS_H
|
||||
@ -10,23 +7,25 @@
|
||||
class CharacterClass {
|
||||
public:
|
||||
explicit CharacterClass(const shared_ptr<LSObject> &obj) {
|
||||
name = obj->GetMember("Name").CharPtr;
|
||||
level = obj->GetMember("Level").Int;
|
||||
const auto optName = obj->GetMember("Name");
|
||||
const auto optLevel = obj->GetMember("Level");
|
||||
|
||||
name = optName.has_value() ? optName->CharPtr : string();
|
||||
level = optLevel.has_value() ? optLevel->Int : 0;
|
||||
}
|
||||
|
||||
string Name() const {
|
||||
return this->name;
|
||||
}
|
||||
|
||||
int Level() const {
|
||||
return this->level;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
string name;
|
||||
int level;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif //CLASS_H
|
||||
|
||||
@ -1,10 +1,7 @@
|
||||
//
|
||||
// Created by marob on 12/28/2023.
|
||||
//
|
||||
|
||||
#ifndef EQ2_H
|
||||
#define EQ2_H
|
||||
#include <memory>
|
||||
#include <ISXDK.h>
|
||||
|
||||
#include "LSObject.h"
|
||||
|
||||
@ -18,9 +15,18 @@ public:
|
||||
}
|
||||
|
||||
string ServerName() const {
|
||||
return this->lsObject->GetMember("ServerName").CharPtr;
|
||||
const auto serverName = this->lsObject->GetMember("ServerName");
|
||||
return serverName.has_value() ? serverName->CharPtr : string();
|
||||
}
|
||||
|
||||
|
||||
// static vector<Actor> QueryActors(const string &query) {
|
||||
// vector<Actor> actors;
|
||||
// char *args[] = {const_cast<char *>(query.c_str())};
|
||||
//
|
||||
// return actors;
|
||||
// }
|
||||
|
||||
private:
|
||||
const shared_ptr<LSObject> lsObject;
|
||||
};
|
||||
|
||||
103
src/isxeq2/GroupMember.cpp
Normal file
103
src/isxeq2/GroupMember.cpp
Normal file
@ -0,0 +1,103 @@
|
||||
//
|
||||
// Created by marob on 1/2/2024.
|
||||
//
|
||||
|
||||
#include "GroupMember.h"
|
||||
|
||||
std::string GroupMember::ZoneName() const {
|
||||
if (const auto zoneName = this->lsObject->GetMember("ZoneName"); zoneName.has_value()) {
|
||||
return zoneName->CharPtr;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
u_long GroupMember::PetId() const {
|
||||
if (const auto petId = this->lsObject->GetMember("PetID"); petId.has_value()) {
|
||||
return petId->Int64;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
int GroupMember::RaidGroupNumber() const {
|
||||
if (const auto raidGroupNumber = this->lsObject->GetMember("RaidGroupNumber"); raidGroupNumber.has_value()) {
|
||||
return raidGroupNumber->Int;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
int GroupMember::RaidRole() const {
|
||||
if (const auto raidRole = this->lsObject->GetMember("RaidRole"); raidRole.has_value()) {
|
||||
return raidRole->Int;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
int GroupMember::HitPoints() const {
|
||||
if (const auto hitPoints = this->lsObject->GetMember("HitPoints"); hitPoints.has_value()) {
|
||||
return hitPoints->Int64;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
int GroupMember::MaxHitPoints() const {
|
||||
if (const auto maxHitPoints = this->lsObject->GetMember("MaxHitPoints"); maxHitPoints.has_value()) {
|
||||
return maxHitPoints->Int64;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
int GroupMember::CurrentPower() const {
|
||||
if (const auto currentPower = this->lsObject->GetMember("CurrentPower"); currentPower.has_value()) {
|
||||
return currentPower->Int64;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
bool GroupMember::InZone() const {
|
||||
if (const auto inZone = this->lsObject->GetMember("InZone"); inZone.has_value()) {
|
||||
return inZone->Int;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GroupMember::IsAfflicted() const {
|
||||
if (const auto isAfflicted = this->lsObject->GetMember("IsAfflicted"); isAfflicted.has_value()) {
|
||||
return isAfflicted->Int;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int GroupMember::Noxious() const {
|
||||
if (const auto noxious = this->lsObject->GetMember("Noxious"); noxious.has_value()) {
|
||||
return noxious->Int;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
int GroupMember::Trauma() const {
|
||||
if (const auto trauma = this->lsObject->GetMember("Trauma"); trauma.has_value()) {
|
||||
return trauma->Int;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
int GroupMember::Elemental() const {
|
||||
if (const auto elemental = this->lsObject->GetMember("Elemental"); elemental.has_value()) {
|
||||
return elemental->Int;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
int GroupMember::Arcane() const {
|
||||
if (const auto arcane = this->lsObject->GetMember("Arcane"); arcane.has_value()) {
|
||||
return arcane->Int;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
int GroupMember::Cursed() const {
|
||||
if (const auto cursed = this->lsObject->GetMember("Cursed"); cursed.has_value()) {
|
||||
return cursed->Int;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
47
src/isxeq2/GroupMember.h
Normal file
47
src/isxeq2/GroupMember.h
Normal file
@ -0,0 +1,47 @@
|
||||
//
|
||||
// Created by marob on 1/2/2024.
|
||||
//
|
||||
|
||||
#ifndef GROUPMEMBER_H
|
||||
#define GROUPMEMBER_H
|
||||
#include "Actor.h"
|
||||
|
||||
|
||||
class GroupMember : public Actor {
|
||||
public:
|
||||
explicit GroupMember(const shared_ptr<LSObject> &obj) : Actor(obj) {
|
||||
}
|
||||
|
||||
std::string ZoneName() const;
|
||||
|
||||
u_long PetId() const;
|
||||
|
||||
int RaidGroupNumber() const;
|
||||
|
||||
int RaidRole() const;
|
||||
|
||||
int HitPoints() const;
|
||||
|
||||
int MaxHitPoints() const;
|
||||
|
||||
int CurrentPower() const;
|
||||
|
||||
bool InZone() const;
|
||||
|
||||
bool IsAfflicted() const;
|
||||
|
||||
int Noxious() const;
|
||||
|
||||
int Trauma() const;
|
||||
|
||||
int Elemental() const;
|
||||
|
||||
int Arcane() const;
|
||||
|
||||
int Cursed() const;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
|
||||
#endif //GROUPMEMBER_H
|
||||
@ -1,14 +1,12 @@
|
||||
//
|
||||
// Created by marob on 12/20/2023.
|
||||
//
|
||||
|
||||
#ifndef LSOBJECT_H
|
||||
#define LSOBJECT_H
|
||||
#include <ISXDK.h>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
|
||||
#include "ISXMr.h"
|
||||
#include "Logger.h"
|
||||
|
||||
template<typename T>
|
||||
std::string toString(const T &value) {
|
||||
@ -19,12 +17,21 @@ std::string toString(const T &value) {
|
||||
|
||||
class LSObject {
|
||||
public:
|
||||
explicit LSObject(const LSOBJECT &obj) : lsObject(obj) {
|
||||
explicit LSObject(const optional<LSOBJECT> &obj) : lsObject(obj) {
|
||||
}
|
||||
|
||||
~LSObject() {
|
||||
if (this->lsObject.has_value()) {
|
||||
this->lsObject.value().Type->FreeVariable(this->lsObject.value().GetObjectData());
|
||||
this->lsObject.reset();
|
||||
}
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
LSOBJECT GetMember(const std::string &memberName, Args... args) {
|
||||
LSOBJECT response;
|
||||
optional<LSOBJECT> GetMember(const std::string &memberName, Args... args) {
|
||||
if (!this->lsObject.has_value()) {
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
// Use a fold expression to convert each argument to a string
|
||||
const std::vector<std::string> arguments = {toString(args)...};
|
||||
@ -36,20 +43,34 @@ public:
|
||||
argv.push_back(const_cast<char *>(arg.c_str()));
|
||||
}
|
||||
|
||||
this->lsObject.Type->GetMemberEx(
|
||||
this->lsObject.GetObjectData(),
|
||||
try {
|
||||
LSOBJECT response;
|
||||
|
||||
if (const auto result = this->lsObject->Type->GetMemberEx(
|
||||
this->lsObject->GetObjectData(),
|
||||
const_cast<char *>(memberName.c_str()),
|
||||
argc,
|
||||
argv.data(),
|
||||
response
|
||||
);
|
||||
|
||||
); !result) {
|
||||
logd << "GetMemberEx failed on member " << memberName
|
||||
<< " for type " << this->lsObject->Type->GetName()
|
||||
<< endl;
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
} catch (...) {
|
||||
loge << "GetMemberEx failed" << endl;
|
||||
}
|
||||
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void CallMethod(const std::string &methodName, Args... args) {
|
||||
LSOBJECT response;
|
||||
if (!this->lsObject.has_value()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Use a fold expression to convert each argument to a string
|
||||
const std::vector<std::string> arguments = {toString(args)...};
|
||||
@ -61,15 +82,19 @@ public:
|
||||
argv.push_back(const_cast<char *>(arg.c_str()));
|
||||
}
|
||||
|
||||
this->lsObject.Type->GetMethodEx(
|
||||
this->lsObject.GetObjectData(),
|
||||
this->lsObject->Type->GetMethodEx(
|
||||
this->lsObject->GetObjectData(),
|
||||
const_cast<char *>(methodName.c_str()),
|
||||
argc,
|
||||
argv.data());
|
||||
}
|
||||
|
||||
bool IsValid() const {
|
||||
return this->lsObject.has_value();
|
||||
}
|
||||
|
||||
private:
|
||||
LSOBJECT lsObject;
|
||||
optional<LSOBJECT> lsObject;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -9,12 +9,13 @@
|
||||
class Point3f {
|
||||
public:
|
||||
explicit Point3f(const shared_ptr<LSObject> &obj) {
|
||||
x = *obj->GetMember("X").Float64Ptr;
|
||||
y = *obj->GetMember("Y").Float64Ptr;
|
||||
z = *obj->GetMember("Z").Float64Ptr;
|
||||
x = *obj->GetMember("X")->Float64Ptr;
|
||||
y = *obj->GetMember("Y")->Float64Ptr;
|
||||
z = *obj->GetMember("Z")->Float64Ptr;
|
||||
}
|
||||
|
||||
explicit Point3f(const float x, const float y, const float z) : x(x), y(y), z(z) { }
|
||||
explicit Point3f(const float x, const float y, const float z) : x(x), y(y), z(z) {
|
||||
}
|
||||
|
||||
float X() const { return this->x; }
|
||||
float Y() const { return this->y; }
|
||||
@ -23,14 +24,15 @@ public:
|
||||
void setX(const float x) {
|
||||
this->x = x;
|
||||
}
|
||||
|
||||
void setY(const float y) {
|
||||
this->y = y;
|
||||
}
|
||||
|
||||
void setZ(const float z) {
|
||||
this->z = z;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
float x;
|
||||
float y;
|
||||
@ -38,5 +40,4 @@ private:
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif //POINT3F_H
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user