mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-13 06:21:28 +00:00
Merge branch 'luamod'
This commit is contained in:
commit
0a8b21d4ab
2
.gitignore
vendored
2
.gitignore
vendored
@ -33,5 +33,7 @@ Build_32/
|
||||
build_32/
|
||||
Build_64/
|
||||
build_64/
|
||||
x64/
|
||||
x86/
|
||||
log/
|
||||
logs/
|
||||
|
||||
@ -13,12 +13,6 @@
|
||||
#EQEMU_LOG_LEVEL_QUEST
|
||||
#EQEMU_LOG_LEVEL_COMMANDS
|
||||
#EQEMU_LOG_LEVEL_CRASH
|
||||
#EQEMU_STREAM_SEND_RATE
|
||||
#EQEMU_STREAM_DECAY_RATE
|
||||
#EQEMU_STREAM_RETRANSMIT_TIMEOUT_MUL
|
||||
#EQEMU_STREAM_RETRANSMIT_TIMEOUT_MAX
|
||||
#EQEMU_STREAM_AVERAGE_DELTA_MAX
|
||||
#EQEMU_STREAM_RETRANSMIT_ACKED_PACKETS
|
||||
#EQEMU_DEPOP_INVALIDATES_CACHE
|
||||
#EQEMU_ENABLE_BOTS
|
||||
#EQEMU_DISABLE_LOGSYS
|
||||
@ -237,14 +231,6 @@ SET(EQEMU_LOG_LEVEL_CRASH 3 CACHE STRING "EQEmu logging level for [Crash]:
|
||||
|
||||
MARK_AS_ADVANCED(EQEMU_LOG_LEVEL_STATUS EQEMU_LOG_LEVEL_NORMAL EQEMU_LOG_LEVEL_ERROR EQEMU_LOG_LEVEL_DEBUG EQEMU_LOG_LEVEL_QUEST EQEMU_LOG_LEVEL_COMMANDS EQEMU_LOG_LEVEL_CRASH)
|
||||
|
||||
SET(EQEMU_STREAM_SEND_RATE 1048576 CACHE STRING "Advanced: Base amount of data stream can send before throttle.")
|
||||
SET(EQEMU_STREAM_DECAY_RATE 78642 CACHE STRING "Advanced: Base amount of data stream recovers per tic.")
|
||||
SET(EQEMU_STREAM_RETRANSMIT_TIMEOUT_MUL 3.0 CACHE STRING "Advanced: Multiplier on retransmit timeout.")
|
||||
SET(EQEMU_STREAM_RETRANSMIT_TIMEOUT_MAX 5000 CACHE STRING "Advanced: Max in ms for retransmit timeout timer.")
|
||||
SET(EQEMU_STREAM_AVERAGE_DELTA_MAX 2500 CACHE STRING "Advanced: The maximum average delta in ms allowed.")
|
||||
SET(EQEMU_STREAM_RETRANSMIT_ACKED_PACKETS TRUE CACHE BOOL "Advanced: Whether or not acked packets can be retransmitted")
|
||||
MARK_AS_ADVANCED(EQEMU_STREAM_SEND_RATE EQEMU_STREAM_DECAY_RATE EQEMU_STREAM_RETRANSMIT_TIMEOUT_MUL EQEMU_STREAM_RETRANSMIT_TIMEOUT_MAX EQEMU_STREAM_AVERAGE_DELTA_MAX EQEMU_STREAM_RETRANSMIT_ACKED_PACKETS)
|
||||
|
||||
#NPC Types Cache Behavior
|
||||
OPTION(EQEMU_DEPOP_INVALIDATES_CACHE "#repop invalidates the npc_types cache (will cause a larger database hit on #repop but is more convienent)." ON)
|
||||
|
||||
@ -306,11 +292,6 @@ ADD_DEFINITIONS(-DEQDEBUG=${EQEMU_DEBUG_LEVEL})
|
||||
ADD_DEFINITIONS(-DINVERSEXY)
|
||||
ADD_DEFINITIONS(-DFIELD_ITEMS)
|
||||
ADD_DEFINITIONS(-DMAP_DIR="${EQEMU_MAP_DIR}")
|
||||
ADD_DEFINITIONS(-DRATEBASE=${EQEMU_STREAM_SEND_RATE})
|
||||
ADD_DEFINITIONS(-DDECAYBASE=${EQEMU_STREAM_DECAY_RATE})
|
||||
ADD_DEFINITIONS(-DRETRANSMIT_TIMEOUT_MULT=${EQEMU_STREAM_RETRANSMIT_TIMEOUT_MUL})
|
||||
ADD_DEFINITIONS(-DRETRANSMIT_TIMEOUT_MAX=${EQEMU_STREAM_RETRANSMIT_TIMEOUT_MAX})
|
||||
ADD_DEFINITIONS(-DAVERAGE_DELTA_MAX=${EQEMU_STREAM_AVERAGE_DELTA_MAX})
|
||||
ADD_DEFINITIONS(-DLOG_LEVEL_STATUS=${EQEMU_LOG_LEVEL_STATUS})
|
||||
ADD_DEFINITIONS(-DLOG_LEVEL_NORMAL=${EQEMU_LOG_LEVEL_NORMAL})
|
||||
ADD_DEFINITIONS(-DLOG_LEVEL_ERROR=${EQEMU_LOG_LEVEL_ERROR})
|
||||
@ -320,12 +301,6 @@ ADD_DEFINITIONS(-DLOG_LEVEL_COMMANDS=${EQEMU_LOG_LEVEL_COMMANDS})
|
||||
ADD_DEFINITIONS(-DLOG_LEVEL_CRASH=${EQEMU_LOG_LEVEL_CRASH})
|
||||
ADD_DEFINITIONS(-DGLM_FORCE_RADIANS)
|
||||
|
||||
IF(EQEMU_STREAM_RETRANSMIT_ACKED_PACKETS)
|
||||
ADD_DEFINITIONS(-DRETRANSMIT_ACKED_PACKETS=true)
|
||||
ELSE(EQEMU_STREAM_RETRANSMIT_ACKED_PACKETS)
|
||||
ADD_DEFINITIONS(-DRETRANSMIT_ACKED_PACKETS=false)
|
||||
ENDIF(EQEMU_STREAM_RETRANSMIT_ACKED_PACKETS)
|
||||
|
||||
#Find everything we need
|
||||
FIND_PACKAGE(ZLIB REQUIRED)
|
||||
FIND_PACKAGE(MySQL REQUIRED)
|
||||
|
||||
@ -103,6 +103,7 @@ SET(common_sources
|
||||
tinyxml/tinyxml.cpp
|
||||
tinyxml/tinyxmlerror.cpp
|
||||
tinyxml/tinyxmlparser.cpp
|
||||
util/directory.cpp
|
||||
util/uuid.cpp
|
||||
)
|
||||
|
||||
@ -257,6 +258,7 @@ SET(common_headers
|
||||
tinyxml/tinystr.h
|
||||
tinyxml/tinyxml.h
|
||||
util/memory_stream.h
|
||||
util/directory.h
|
||||
util/uuid.h
|
||||
)
|
||||
|
||||
@ -366,6 +368,8 @@ SOURCE_GROUP(TinyXML FILES
|
||||
|
||||
SOURCE_GROUP(Util FILES
|
||||
util/memory_stream.h
|
||||
util/directory.cpp
|
||||
util/directory.h
|
||||
util/uuid.cpp
|
||||
util/uuid.h
|
||||
)
|
||||
|
||||
@ -25,6 +25,23 @@ void EQ::Net::ConsoleServer::RegisterLogin(ConsoleServerLoginCallback fn)
|
||||
m_login = fn;
|
||||
}
|
||||
|
||||
EQ::Net::ConsoleServerConnection *EQ::Net::ConsoleServer::FindByAccountName(const std::string &acct_name) {
|
||||
for (auto &iter : m_connections) {
|
||||
if (iter.second->UserName().compare(acct_name) == 0) {
|
||||
return iter.second.get();
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
void EQ::Net::ConsoleServer::SendChannelMessage(const ServerChannelMessage_Struct* scm, std::function<void(void)> onTell) {
|
||||
for (auto &iter : m_connections) {
|
||||
iter.second->SendChannelMessage(scm, onTell);
|
||||
}
|
||||
}
|
||||
|
||||
void EQ::Net::ConsoleServer::ConnectionDisconnected(ConsoleServerConnection *c)
|
||||
{
|
||||
auto iter = m_connections.find(c->GetUUID());
|
||||
|
||||
@ -25,7 +25,8 @@ namespace EQ
|
||||
|
||||
void RegisterCall(const std::string& command, int status_required, const std::string& help_definition, ConsoleServerCallback fn);
|
||||
void RegisterLogin(ConsoleServerLoginCallback fn);
|
||||
|
||||
ConsoleServerConnection *FindByAccountName(const std::string &acct_name);
|
||||
void SendChannelMessage(const ServerChannelMessage_Struct* scm, std::function<void(void)> onTell);
|
||||
private:
|
||||
void ConnectionDisconnected(ConsoleServerConnection *c);
|
||||
void ProcessCommand(ConsoleServerConnection *c, const std::string& cmd);
|
||||
|
||||
@ -2,6 +2,8 @@
|
||||
#include "../common/util/uuid.h"
|
||||
#include "../common/net/packet.h"
|
||||
#include "../common/eqemu_logsys.h"
|
||||
#include "../common/servertalk.h"
|
||||
#include "../common/rulesys.h"
|
||||
|
||||
EQ::Net::ConsoleServerConnection::ConsoleServerConnection(ConsoleServer *parent, std::shared_ptr<TCPConnection> connection)
|
||||
{
|
||||
@ -107,6 +109,53 @@ void EQ::Net::ConsoleServerConnection::QueueMessage(const std::string &msg)
|
||||
}
|
||||
}
|
||||
|
||||
bool EQ::Net::ConsoleServerConnection::SendChannelMessage(const ServerChannelMessage_Struct* scm, std::function<void(void)> onTell) {
|
||||
if (!m_accept_messages) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (scm->chan_num) {
|
||||
if (RuleB(Chat, ServerWideAuction)) {
|
||||
case 4: {
|
||||
QueueMessage(fmt::format("{0} auctions, '{1}'", scm->from, scm->message));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (RuleB(Chat, ServerWideOOC)) {
|
||||
case 5: {
|
||||
QueueMessage(fmt::format("{0} says ooc, '{1}'", scm->from, scm->message));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
case 6: {
|
||||
QueueMessage(fmt::format("{0} BROADCASTS, '{1}'", scm->from, scm->message));
|
||||
break;
|
||||
}
|
||||
|
||||
case 7: {
|
||||
QueueMessage(fmt::format("[{0}] tells you, '{1}'", scm->from, scm->message));
|
||||
if (onTell) {
|
||||
onTell();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 11: {
|
||||
QueueMessage(fmt::format("{0} GMSAYS, '{1}'", scm->from, scm->message));
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void EQ::Net::ConsoleServerConnection::OnRead(TCPConnection *c, const unsigned char *data, size_t sz)
|
||||
{
|
||||
for (size_t i = 0; i < sz; ++i) {
|
||||
|
||||
@ -4,6 +4,8 @@
|
||||
#include <memory>
|
||||
#include <map>
|
||||
|
||||
struct ServerChannelMessage_Struct;
|
||||
|
||||
namespace EQ
|
||||
{
|
||||
namespace Net
|
||||
@ -42,6 +44,7 @@ namespace EQ
|
||||
bool AcceptMessages() const { return m_accept_messages; }
|
||||
void SetAcceptMessages(bool v) { m_accept_messages = v; }
|
||||
void QueueMessage(const std::string &msg);
|
||||
bool SendChannelMessage(const ServerChannelMessage_Struct* scm, std::function<void(void)> onTell);
|
||||
private:
|
||||
void OnRead(TCPConnection* c, const unsigned char* data, size_t sz);
|
||||
void OnDisconnect(TCPConnection* c);
|
||||
|
||||
@ -277,7 +277,7 @@ EQ::Net::DaybreakConnection::DaybreakConnection(DaybreakConnectionManager *owner
|
||||
m_encode_passes[1] = owner->m_options.encode_passes[1];
|
||||
m_hold_time = Clock::now();
|
||||
m_buffered_packets_length = 0;
|
||||
m_rolling_ping = 500;
|
||||
m_rolling_ping = 900;
|
||||
m_resend_delay = (m_rolling_ping * m_owner->m_options.resend_delay_factor) + m_owner->m_options.resend_delay_ms;
|
||||
m_combined.reset(new char[512]);
|
||||
m_combined[0] = 0;
|
||||
@ -300,7 +300,7 @@ EQ::Net::DaybreakConnection::DaybreakConnection(DaybreakConnectionManager *owner
|
||||
m_crc_bytes = 0;
|
||||
m_hold_time = Clock::now();
|
||||
m_buffered_packets_length = 0;
|
||||
m_rolling_ping = 500;
|
||||
m_rolling_ping = 900;
|
||||
m_resend_delay = (m_rolling_ping * m_owner->m_options.resend_delay_factor) + m_owner->m_options.resend_delay_ms;
|
||||
m_combined.reset(new char[512]);
|
||||
m_combined[0] = 0;
|
||||
@ -1026,7 +1026,7 @@ void EQ::Net::DaybreakConnection::ProcessResend(int stream)
|
||||
InternalBufferedSend(entry.second.packet);
|
||||
entry.second.last_sent = now;
|
||||
entry.second.times_resent++;
|
||||
m_rolling_ping += 100;
|
||||
m_rolling_ping += 300;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -1040,7 +1040,7 @@ void EQ::Net::DaybreakConnection::ProcessResend(int stream)
|
||||
InternalBufferedSend(entry.second.packet);
|
||||
entry.second.last_sent = now;
|
||||
entry.second.times_resent++;
|
||||
m_rolling_ping += 100;
|
||||
m_rolling_ping += 300;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <queue>
|
||||
#include <list>
|
||||
|
||||
@ -155,13 +156,13 @@ namespace EQ
|
||||
|
||||
uint16_t sequence_in;
|
||||
uint16_t sequence_out;
|
||||
std::map<uint16_t, Packet*> packet_queue;
|
||||
std::unordered_map<uint16_t, Packet*> packet_queue;
|
||||
|
||||
DynamicPacket fragment_packet;
|
||||
uint32_t fragment_current_bytes;
|
||||
uint32_t fragment_total_bytes;
|
||||
|
||||
std::map<uint16_t, DaybreakSentPacket> sent_packets;
|
||||
std::unordered_map<uint16_t, DaybreakSentPacket> sent_packets;
|
||||
};
|
||||
|
||||
DaybreakStream m_streams[4];
|
||||
@ -205,10 +206,10 @@ namespace EQ
|
||||
DaybreakConnectionManagerOptions() {
|
||||
max_connection_count = 0;
|
||||
keepalive_delay_ms = 9000;
|
||||
resend_delay_ms = 150;
|
||||
resend_delay_ms = 300;
|
||||
resend_delay_factor = 1.5;
|
||||
resend_delay_min = 150;
|
||||
resend_delay_max = 1000;
|
||||
resend_delay_min = 350;
|
||||
resend_delay_max = 8000;
|
||||
connect_delay_ms = 500;
|
||||
stale_connection_ms = 90000;
|
||||
connect_stale_ms = 5000;
|
||||
@ -282,4 +283,4 @@ namespace EQ
|
||||
friend class DaybreakConnection;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
49
common/util/directory.cpp
Normal file
49
common/util/directory.cpp
Normal file
@ -0,0 +1,49 @@
|
||||
#include "directory.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "win_dirent.h"
|
||||
#else
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
|
||||
struct EQ::Directory::impl {
|
||||
DIR *m_dir;
|
||||
};
|
||||
|
||||
EQ::Directory::Directory(const std::string &path)
|
||||
{
|
||||
m_impl = new impl;
|
||||
m_impl->m_dir = opendir(path.c_str());
|
||||
}
|
||||
|
||||
EQ::Directory::~Directory()
|
||||
{
|
||||
if (m_impl->m_dir) {
|
||||
closedir(m_impl->m_dir);
|
||||
}
|
||||
|
||||
delete m_impl;
|
||||
}
|
||||
|
||||
bool EQ::Directory::Exists()
|
||||
{
|
||||
return m_impl->m_dir != nullptr;
|
||||
}
|
||||
|
||||
void EQ::Directory::GetFiles(std::vector<std::string>& files)
|
||||
{
|
||||
if (m_impl->m_dir) {
|
||||
struct dirent *ent;
|
||||
while ((ent = readdir(m_impl->m_dir)) != nullptr) {
|
||||
switch (ent->d_type) {
|
||||
case DT_REG:
|
||||
files.push_back(ent->d_name);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rewinddir(m_impl->m_dir);
|
||||
}
|
||||
}
|
||||
19
common/util/directory.h
Normal file
19
common/util/directory.h
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace EQ {
|
||||
class Directory
|
||||
{
|
||||
public:
|
||||
Directory(const std::string &path);
|
||||
~Directory();
|
||||
|
||||
bool Exists();
|
||||
void GetFiles(std::vector<std::string> &files);
|
||||
private:
|
||||
struct impl;
|
||||
impl *m_impl;
|
||||
};
|
||||
}
|
||||
928
common/util/win_dirent.h
Normal file
928
common/util/win_dirent.h
Normal file
@ -0,0 +1,928 @@
|
||||
/*
|
||||
* Dirent interface for Microsoft Visual Studio
|
||||
* Version 1.21
|
||||
*
|
||||
* Copyright (C) 2006-2012 Toni Ronkko
|
||||
* This file is part of dirent. Dirent may be freely distributed
|
||||
* under the MIT license. For all details and documentation, see
|
||||
* https://github.com/tronkko/dirent
|
||||
*/
|
||||
#ifndef DIRENT_H
|
||||
#define DIRENT_H
|
||||
|
||||
/*
|
||||
* Include windows.h without Windows Sockets 1.1 to prevent conflicts with
|
||||
* Windows Sockets 2.0.
|
||||
*/
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <windows.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <wchar.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <malloc.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
|
||||
/* Indicates that d_type field is available in dirent structure */
|
||||
#define _DIRENT_HAVE_D_TYPE
|
||||
|
||||
/* Indicates that d_namlen field is available in dirent structure */
|
||||
#define _DIRENT_HAVE_D_NAMLEN
|
||||
|
||||
/* Entries missing from MSVC 6.0 */
|
||||
#if !defined(FILE_ATTRIBUTE_DEVICE)
|
||||
# define FILE_ATTRIBUTE_DEVICE 0x40
|
||||
#endif
|
||||
|
||||
/* File type and permission flags for stat(), general mask */
|
||||
#if !defined(S_IFMT)
|
||||
# define S_IFMT _S_IFMT
|
||||
#endif
|
||||
|
||||
/* Directory bit */
|
||||
#if !defined(S_IFDIR)
|
||||
# define S_IFDIR _S_IFDIR
|
||||
#endif
|
||||
|
||||
/* Character device bit */
|
||||
#if !defined(S_IFCHR)
|
||||
# define S_IFCHR _S_IFCHR
|
||||
#endif
|
||||
|
||||
/* Pipe bit */
|
||||
#if !defined(S_IFFIFO)
|
||||
# define S_IFFIFO _S_IFFIFO
|
||||
#endif
|
||||
|
||||
/* Regular file bit */
|
||||
#if !defined(S_IFREG)
|
||||
# define S_IFREG _S_IFREG
|
||||
#endif
|
||||
|
||||
/* Read permission */
|
||||
#if !defined(S_IREAD)
|
||||
# define S_IREAD _S_IREAD
|
||||
#endif
|
||||
|
||||
/* Write permission */
|
||||
#if !defined(S_IWRITE)
|
||||
# define S_IWRITE _S_IWRITE
|
||||
#endif
|
||||
|
||||
/* Execute permission */
|
||||
#if !defined(S_IEXEC)
|
||||
# define S_IEXEC _S_IEXEC
|
||||
#endif
|
||||
|
||||
/* Pipe */
|
||||
#if !defined(S_IFIFO)
|
||||
# define S_IFIFO _S_IFIFO
|
||||
#endif
|
||||
|
||||
/* Block device */
|
||||
#if !defined(S_IFBLK)
|
||||
# define S_IFBLK 0
|
||||
#endif
|
||||
|
||||
/* Link */
|
||||
#if !defined(S_IFLNK)
|
||||
# define S_IFLNK 0
|
||||
#endif
|
||||
|
||||
/* Socket */
|
||||
#if !defined(S_IFSOCK)
|
||||
# define S_IFSOCK 0
|
||||
#endif
|
||||
|
||||
/* Read user permission */
|
||||
#if !defined(S_IRUSR)
|
||||
# define S_IRUSR S_IREAD
|
||||
#endif
|
||||
|
||||
/* Write user permission */
|
||||
#if !defined(S_IWUSR)
|
||||
# define S_IWUSR S_IWRITE
|
||||
#endif
|
||||
|
||||
/* Execute user permission */
|
||||
#if !defined(S_IXUSR)
|
||||
# define S_IXUSR 0
|
||||
#endif
|
||||
|
||||
/* Read group permission */
|
||||
#if !defined(S_IRGRP)
|
||||
# define S_IRGRP 0
|
||||
#endif
|
||||
|
||||
/* Write group permission */
|
||||
#if !defined(S_IWGRP)
|
||||
# define S_IWGRP 0
|
||||
#endif
|
||||
|
||||
/* Execute group permission */
|
||||
#if !defined(S_IXGRP)
|
||||
# define S_IXGRP 0
|
||||
#endif
|
||||
|
||||
/* Read others permission */
|
||||
#if !defined(S_IROTH)
|
||||
# define S_IROTH 0
|
||||
#endif
|
||||
|
||||
/* Write others permission */
|
||||
#if !defined(S_IWOTH)
|
||||
# define S_IWOTH 0
|
||||
#endif
|
||||
|
||||
/* Execute others permission */
|
||||
#if !defined(S_IXOTH)
|
||||
# define S_IXOTH 0
|
||||
#endif
|
||||
|
||||
/* Maximum length of file name */
|
||||
#if !defined(PATH_MAX)
|
||||
# define PATH_MAX MAX_PATH
|
||||
#endif
|
||||
#if !defined(FILENAME_MAX)
|
||||
# define FILENAME_MAX MAX_PATH
|
||||
#endif
|
||||
#if !defined(NAME_MAX)
|
||||
# define NAME_MAX FILENAME_MAX
|
||||
#endif
|
||||
|
||||
/* File type flags for d_type */
|
||||
#define DT_UNKNOWN 0
|
||||
#define DT_REG S_IFREG
|
||||
#define DT_DIR S_IFDIR
|
||||
#define DT_FIFO S_IFIFO
|
||||
#define DT_SOCK S_IFSOCK
|
||||
#define DT_CHR S_IFCHR
|
||||
#define DT_BLK S_IFBLK
|
||||
#define DT_LNK S_IFLNK
|
||||
|
||||
/* Macros for converting between st_mode and d_type */
|
||||
#define IFTODT(mode) ((mode) & S_IFMT)
|
||||
#define DTTOIF(type) (type)
|
||||
|
||||
/*
|
||||
* File type macros. Note that block devices, sockets and links cannot be
|
||||
* distinguished on Windows and the macros S_ISBLK, S_ISSOCK and S_ISLNK are
|
||||
* only defined for compatibility. These macros should always return false
|
||||
* on Windows.
|
||||
*/
|
||||
#if !defined(S_ISFIFO)
|
||||
# define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
|
||||
#endif
|
||||
#if !defined(S_ISDIR)
|
||||
# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
|
||||
#endif
|
||||
#if !defined(S_ISREG)
|
||||
# define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
|
||||
#endif
|
||||
#if !defined(S_ISLNK)
|
||||
# define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
|
||||
#endif
|
||||
#if !defined(S_ISSOCK)
|
||||
# define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
|
||||
#endif
|
||||
#if !defined(S_ISCHR)
|
||||
# define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
|
||||
#endif
|
||||
#if !defined(S_ISBLK)
|
||||
# define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
|
||||
#endif
|
||||
|
||||
/* Return the exact length of d_namlen without zero terminator */
|
||||
#define _D_EXACT_NAMLEN(p) ((p)->d_namlen)
|
||||
|
||||
/* Return number of bytes needed to store d_namlen */
|
||||
#define _D_ALLOC_NAMLEN(p) (PATH_MAX)
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* Wide-character version */
|
||||
struct _wdirent {
|
||||
/* Always zero */
|
||||
long d_ino;
|
||||
|
||||
/* Structure size */
|
||||
unsigned short d_reclen;
|
||||
|
||||
/* Length of name without \0 */
|
||||
size_t d_namlen;
|
||||
|
||||
/* File type */
|
||||
int d_type;
|
||||
|
||||
/* File name */
|
||||
wchar_t d_name[PATH_MAX];
|
||||
};
|
||||
typedef struct _wdirent _wdirent;
|
||||
|
||||
struct _WDIR {
|
||||
/* Current directory entry */
|
||||
struct _wdirent ent;
|
||||
|
||||
/* Private file data */
|
||||
WIN32_FIND_DATAW data;
|
||||
|
||||
/* True if data is valid */
|
||||
int cached;
|
||||
|
||||
/* Win32 search handle */
|
||||
HANDLE handle;
|
||||
|
||||
/* Initial directory name */
|
||||
wchar_t *patt;
|
||||
};
|
||||
typedef struct _WDIR _WDIR;
|
||||
|
||||
static _WDIR *_wopendir (const wchar_t *dirname);
|
||||
static struct _wdirent *_wreaddir (_WDIR *dirp);
|
||||
static int _wclosedir (_WDIR *dirp);
|
||||
static void _wrewinddir (_WDIR* dirp);
|
||||
|
||||
|
||||
/* For compatibility with Symbian */
|
||||
#define wdirent _wdirent
|
||||
#define WDIR _WDIR
|
||||
#define wopendir _wopendir
|
||||
#define wreaddir _wreaddir
|
||||
#define wclosedir _wclosedir
|
||||
#define wrewinddir _wrewinddir
|
||||
|
||||
|
||||
/* Multi-byte character versions */
|
||||
struct dirent {
|
||||
/* Always zero */
|
||||
long d_ino;
|
||||
|
||||
/* Structure size */
|
||||
unsigned short d_reclen;
|
||||
|
||||
/* Length of name without \0 */
|
||||
size_t d_namlen;
|
||||
|
||||
/* File type */
|
||||
int d_type;
|
||||
|
||||
/* File name */
|
||||
char d_name[PATH_MAX];
|
||||
};
|
||||
typedef struct dirent dirent;
|
||||
|
||||
struct DIR {
|
||||
struct dirent ent;
|
||||
struct _WDIR *wdirp;
|
||||
};
|
||||
typedef struct DIR DIR;
|
||||
|
||||
static DIR *opendir (const char *dirname);
|
||||
static struct dirent *readdir (DIR *dirp);
|
||||
static int closedir (DIR *dirp);
|
||||
static void rewinddir (DIR* dirp);
|
||||
|
||||
|
||||
/* Internal utility functions */
|
||||
static WIN32_FIND_DATAW *dirent_first (_WDIR *dirp);
|
||||
static WIN32_FIND_DATAW *dirent_next (_WDIR *dirp);
|
||||
|
||||
static int dirent_mbstowcs_s(
|
||||
size_t *pReturnValue,
|
||||
wchar_t *wcstr,
|
||||
size_t sizeInWords,
|
||||
const char *mbstr,
|
||||
size_t count);
|
||||
|
||||
static int dirent_wcstombs_s(
|
||||
size_t *pReturnValue,
|
||||
char *mbstr,
|
||||
size_t sizeInBytes,
|
||||
const wchar_t *wcstr,
|
||||
size_t count);
|
||||
|
||||
static void dirent_set_errno (int error);
|
||||
|
||||
/*
|
||||
* Open directory stream DIRNAME for read and return a pointer to the
|
||||
* internal working area that is used to retrieve individual directory
|
||||
* entries.
|
||||
*/
|
||||
static _WDIR*
|
||||
_wopendir(
|
||||
const wchar_t *dirname)
|
||||
{
|
||||
_WDIR *dirp = NULL;
|
||||
int error;
|
||||
|
||||
/* Must have directory name */
|
||||
if (dirname == NULL || dirname[0] == '\0') {
|
||||
dirent_set_errno (ENOENT);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Allocate new _WDIR structure */
|
||||
dirp = (_WDIR*) malloc (sizeof (struct _WDIR));
|
||||
if (dirp != NULL) {
|
||||
DWORD n;
|
||||
|
||||
/* Reset _WDIR structure */
|
||||
dirp->handle = INVALID_HANDLE_VALUE;
|
||||
dirp->patt = NULL;
|
||||
dirp->cached = 0;
|
||||
|
||||
/* Compute the length of full path plus zero terminator
|
||||
*
|
||||
* Note that on WinRT there's no way to convert relative paths
|
||||
* into absolute paths, so just assume its an absolute path.
|
||||
*/
|
||||
# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
|
||||
n = wcslen(dirname);
|
||||
# else
|
||||
n = GetFullPathNameW (dirname, 0, NULL, NULL);
|
||||
# endif
|
||||
|
||||
/* Allocate room for absolute directory name and search pattern */
|
||||
dirp->patt = (wchar_t*) malloc (sizeof (wchar_t) * n + 16);
|
||||
if (dirp->patt) {
|
||||
|
||||
/*
|
||||
* Convert relative directory name to an absolute one. This
|
||||
* allows rewinddir() to function correctly even when current
|
||||
* working directory is changed between opendir() and rewinddir().
|
||||
*
|
||||
* Note that on WinRT there's no way to convert relative paths
|
||||
* into absolute paths, so just assume its an absolute path.
|
||||
*/
|
||||
# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
|
||||
wcsncpy_s(dirp->patt, n+1, dirname, n);
|
||||
# else
|
||||
n = GetFullPathNameW (dirname, n, dirp->patt, NULL);
|
||||
# endif
|
||||
if (n > 0) {
|
||||
wchar_t *p;
|
||||
|
||||
/* Append search pattern \* to the directory name */
|
||||
p = dirp->patt + n;
|
||||
if (dirp->patt < p) {
|
||||
switch (p[-1]) {
|
||||
case '\\':
|
||||
case '/':
|
||||
case ':':
|
||||
/* Directory ends in path separator, e.g. c:\temp\ */
|
||||
/*NOP*/;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Directory name doesn't end in path separator */
|
||||
*p++ = '\\';
|
||||
}
|
||||
}
|
||||
*p++ = '*';
|
||||
*p = '\0';
|
||||
|
||||
/* Open directory stream and retrieve the first entry */
|
||||
if (dirent_first (dirp)) {
|
||||
/* Directory stream opened successfully */
|
||||
error = 0;
|
||||
} else {
|
||||
/* Cannot retrieve first entry */
|
||||
error = 1;
|
||||
dirent_set_errno (ENOENT);
|
||||
}
|
||||
|
||||
} else {
|
||||
/* Cannot retrieve full path name */
|
||||
dirent_set_errno (ENOENT);
|
||||
error = 1;
|
||||
}
|
||||
|
||||
} else {
|
||||
/* Cannot allocate memory for search pattern */
|
||||
error = 1;
|
||||
}
|
||||
|
||||
} else {
|
||||
/* Cannot allocate _WDIR structure */
|
||||
error = 1;
|
||||
}
|
||||
|
||||
/* Clean up in case of error */
|
||||
if (error && dirp) {
|
||||
_wclosedir (dirp);
|
||||
dirp = NULL;
|
||||
}
|
||||
|
||||
return dirp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read next directory entry. The directory entry is returned in dirent
|
||||
* structure in the d_name field. Individual directory entries returned by
|
||||
* this function include regular files, sub-directories, pseudo-directories
|
||||
* "." and ".." as well as volume labels, hidden files and system files.
|
||||
*/
|
||||
static struct _wdirent*
|
||||
_wreaddir(
|
||||
_WDIR *dirp)
|
||||
{
|
||||
WIN32_FIND_DATAW *datap;
|
||||
struct _wdirent *entp;
|
||||
|
||||
/* Read next directory entry */
|
||||
datap = dirent_next (dirp);
|
||||
if (datap) {
|
||||
size_t n;
|
||||
DWORD attr;
|
||||
|
||||
/* Pointer to directory entry to return */
|
||||
entp = &dirp->ent;
|
||||
|
||||
/*
|
||||
* Copy file name as wide-character string. If the file name is too
|
||||
* long to fit in to the destination buffer, then truncate file name
|
||||
* to PATH_MAX characters and zero-terminate the buffer.
|
||||
*/
|
||||
n = 0;
|
||||
while (n + 1 < PATH_MAX && datap->cFileName[n] != 0) {
|
||||
entp->d_name[n] = datap->cFileName[n];
|
||||
n++;
|
||||
}
|
||||
dirp->ent.d_name[n] = 0;
|
||||
|
||||
/* Length of file name excluding zero terminator */
|
||||
entp->d_namlen = n;
|
||||
|
||||
/* File type */
|
||||
attr = datap->dwFileAttributes;
|
||||
if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
|
||||
entp->d_type = DT_CHR;
|
||||
} else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
|
||||
entp->d_type = DT_DIR;
|
||||
} else {
|
||||
entp->d_type = DT_REG;
|
||||
}
|
||||
|
||||
/* Reset dummy fields */
|
||||
entp->d_ino = 0;
|
||||
entp->d_reclen = sizeof (struct _wdirent);
|
||||
|
||||
} else {
|
||||
|
||||
/* Last directory entry read */
|
||||
entp = NULL;
|
||||
|
||||
}
|
||||
|
||||
return entp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Close directory stream opened by opendir() function. This invalidates the
|
||||
* DIR structure as well as any directory entry read previously by
|
||||
* _wreaddir().
|
||||
*/
|
||||
static int
|
||||
_wclosedir(
|
||||
_WDIR *dirp)
|
||||
{
|
||||
int ok;
|
||||
if (dirp) {
|
||||
|
||||
/* Release search handle */
|
||||
if (dirp->handle != INVALID_HANDLE_VALUE) {
|
||||
FindClose (dirp->handle);
|
||||
dirp->handle = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
/* Release search pattern */
|
||||
if (dirp->patt) {
|
||||
free (dirp->patt);
|
||||
dirp->patt = NULL;
|
||||
}
|
||||
|
||||
/* Release directory structure */
|
||||
free (dirp);
|
||||
ok = /*success*/0;
|
||||
|
||||
} else {
|
||||
/* Invalid directory stream */
|
||||
dirent_set_errno (EBADF);
|
||||
ok = /*failure*/-1;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
/*
|
||||
* Rewind directory stream such that _wreaddir() returns the very first
|
||||
* file name again.
|
||||
*/
|
||||
static void
|
||||
_wrewinddir(
|
||||
_WDIR* dirp)
|
||||
{
|
||||
if (dirp) {
|
||||
/* Release existing search handle */
|
||||
if (dirp->handle != INVALID_HANDLE_VALUE) {
|
||||
FindClose (dirp->handle);
|
||||
}
|
||||
|
||||
/* Open new search handle */
|
||||
dirent_first (dirp);
|
||||
}
|
||||
}
|
||||
|
||||
/* Get first directory entry (internal) */
|
||||
static WIN32_FIND_DATAW*
|
||||
dirent_first(
|
||||
_WDIR *dirp)
|
||||
{
|
||||
WIN32_FIND_DATAW *datap;
|
||||
|
||||
/* Open directory and retrieve the first entry */
|
||||
dirp->handle = FindFirstFileExW(
|
||||
dirp->patt, FindExInfoStandard, &dirp->data,
|
||||
FindExSearchNameMatch, NULL, 0);
|
||||
if (dirp->handle != INVALID_HANDLE_VALUE) {
|
||||
|
||||
/* a directory entry is now waiting in memory */
|
||||
datap = &dirp->data;
|
||||
dirp->cached = 1;
|
||||
|
||||
} else {
|
||||
|
||||
/* Failed to re-open directory: no directory entry in memory */
|
||||
dirp->cached = 0;
|
||||
datap = NULL;
|
||||
|
||||
}
|
||||
return datap;
|
||||
}
|
||||
|
||||
/* Get next directory entry (internal) */
|
||||
static WIN32_FIND_DATAW*
|
||||
dirent_next(
|
||||
_WDIR *dirp)
|
||||
{
|
||||
WIN32_FIND_DATAW *p;
|
||||
|
||||
/* Get next directory entry */
|
||||
if (dirp->cached != 0) {
|
||||
|
||||
/* A valid directory entry already in memory */
|
||||
p = &dirp->data;
|
||||
dirp->cached = 0;
|
||||
|
||||
} else if (dirp->handle != INVALID_HANDLE_VALUE) {
|
||||
|
||||
/* Get the next directory entry from stream */
|
||||
if (FindNextFileW (dirp->handle, &dirp->data) != FALSE) {
|
||||
/* Got a file */
|
||||
p = &dirp->data;
|
||||
} else {
|
||||
/* The very last entry has been processed or an error occured */
|
||||
FindClose (dirp->handle);
|
||||
dirp->handle = INVALID_HANDLE_VALUE;
|
||||
p = NULL;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/* End of directory stream reached */
|
||||
p = NULL;
|
||||
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
* Open directory stream using plain old C-string.
|
||||
*/
|
||||
static DIR*
|
||||
opendir(
|
||||
const char *dirname)
|
||||
{
|
||||
struct DIR *dirp;
|
||||
int error;
|
||||
|
||||
/* Must have directory name */
|
||||
if (dirname == NULL || dirname[0] == '\0') {
|
||||
dirent_set_errno (ENOENT);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Allocate memory for DIR structure */
|
||||
dirp = (DIR*) malloc (sizeof (struct DIR));
|
||||
if (dirp) {
|
||||
wchar_t wname[PATH_MAX];
|
||||
size_t n;
|
||||
|
||||
/* Convert directory name to wide-character string */
|
||||
error = dirent_mbstowcs_s (&n, wname, PATH_MAX, dirname, PATH_MAX);
|
||||
if (!error) {
|
||||
|
||||
/* Open directory stream using wide-character name */
|
||||
dirp->wdirp = _wopendir (wname);
|
||||
if (dirp->wdirp) {
|
||||
/* Directory stream opened */
|
||||
error = 0;
|
||||
} else {
|
||||
/* Failed to open directory stream */
|
||||
error = 1;
|
||||
}
|
||||
|
||||
} else {
|
||||
/*
|
||||
* Cannot convert file name to wide-character string. This
|
||||
* occurs if the string contains invalid multi-byte sequences or
|
||||
* the output buffer is too small to contain the resulting
|
||||
* string.
|
||||
*/
|
||||
error = 1;
|
||||
}
|
||||
|
||||
} else {
|
||||
/* Cannot allocate DIR structure */
|
||||
error = 1;
|
||||
}
|
||||
|
||||
/* Clean up in case of error */
|
||||
if (error && dirp) {
|
||||
free (dirp);
|
||||
dirp = NULL;
|
||||
}
|
||||
|
||||
return dirp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read next directory entry.
|
||||
*
|
||||
* When working with text consoles, please note that file names returned by
|
||||
* readdir() are represented in the default ANSI code page while any output to
|
||||
* console is typically formatted on another code page. Thus, non-ASCII
|
||||
* characters in file names will not usually display correctly on console. The
|
||||
* problem can be fixed in two ways: (1) change the character set of console
|
||||
* to 1252 using chcp utility and use Lucida Console font, or (2) use
|
||||
* _cprintf function when writing to console. The _cprinf() will re-encode
|
||||
* ANSI strings to the console code page so many non-ASCII characters will
|
||||
* display correcly.
|
||||
*/
|
||||
static struct dirent*
|
||||
readdir(
|
||||
DIR *dirp)
|
||||
{
|
||||
WIN32_FIND_DATAW *datap;
|
||||
struct dirent *entp;
|
||||
|
||||
/* Read next directory entry */
|
||||
datap = dirent_next (dirp->wdirp);
|
||||
if (datap) {
|
||||
size_t n;
|
||||
int error;
|
||||
|
||||
/* Attempt to convert file name to multi-byte string */
|
||||
error = dirent_wcstombs_s(
|
||||
&n, dirp->ent.d_name, PATH_MAX, datap->cFileName, PATH_MAX);
|
||||
|
||||
/*
|
||||
* If the file name cannot be represented by a multi-byte string,
|
||||
* then attempt to use old 8+3 file name. This allows traditional
|
||||
* Unix-code to access some file names despite of unicode
|
||||
* characters, although file names may seem unfamiliar to the user.
|
||||
*
|
||||
* Be ware that the code below cannot come up with a short file
|
||||
* name unless the file system provides one. At least
|
||||
* VirtualBox shared folders fail to do this.
|
||||
*/
|
||||
if (error && datap->cAlternateFileName[0] != '\0') {
|
||||
error = dirent_wcstombs_s(
|
||||
&n, dirp->ent.d_name, PATH_MAX,
|
||||
datap->cAlternateFileName, PATH_MAX);
|
||||
}
|
||||
|
||||
if (!error) {
|
||||
DWORD attr;
|
||||
|
||||
/* Initialize directory entry for return */
|
||||
entp = &dirp->ent;
|
||||
|
||||
/* Length of file name excluding zero terminator */
|
||||
entp->d_namlen = n - 1;
|
||||
|
||||
/* File attributes */
|
||||
attr = datap->dwFileAttributes;
|
||||
if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
|
||||
entp->d_type = DT_CHR;
|
||||
} else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
|
||||
entp->d_type = DT_DIR;
|
||||
} else {
|
||||
entp->d_type = DT_REG;
|
||||
}
|
||||
|
||||
/* Reset dummy fields */
|
||||
entp->d_ino = 0;
|
||||
entp->d_reclen = sizeof (struct dirent);
|
||||
|
||||
} else {
|
||||
/*
|
||||
* Cannot convert file name to multi-byte string so construct
|
||||
* an errornous directory entry and return that. Note that
|
||||
* we cannot return NULL as that would stop the processing
|
||||
* of directory entries completely.
|
||||
*/
|
||||
entp = &dirp->ent;
|
||||
entp->d_name[0] = '?';
|
||||
entp->d_name[1] = '\0';
|
||||
entp->d_namlen = 1;
|
||||
entp->d_type = DT_UNKNOWN;
|
||||
entp->d_ino = 0;
|
||||
entp->d_reclen = 0;
|
||||
}
|
||||
|
||||
} else {
|
||||
/* No more directory entries */
|
||||
entp = NULL;
|
||||
}
|
||||
|
||||
return entp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Close directory stream.
|
||||
*/
|
||||
static int
|
||||
closedir(
|
||||
DIR *dirp)
|
||||
{
|
||||
int ok;
|
||||
if (dirp) {
|
||||
|
||||
/* Close wide-character directory stream */
|
||||
ok = _wclosedir (dirp->wdirp);
|
||||
dirp->wdirp = NULL;
|
||||
|
||||
/* Release multi-byte character version */
|
||||
free (dirp);
|
||||
|
||||
} else {
|
||||
|
||||
/* Invalid directory stream */
|
||||
dirent_set_errno (EBADF);
|
||||
ok = /*failure*/-1;
|
||||
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
/*
|
||||
* Rewind directory stream to beginning.
|
||||
*/
|
||||
static void
|
||||
rewinddir(
|
||||
DIR* dirp)
|
||||
{
|
||||
/* Rewind wide-character string directory stream */
|
||||
_wrewinddir (dirp->wdirp);
|
||||
}
|
||||
|
||||
/* Convert multi-byte string to wide character string */
|
||||
static int
|
||||
dirent_mbstowcs_s(
|
||||
size_t *pReturnValue,
|
||||
wchar_t *wcstr,
|
||||
size_t sizeInWords,
|
||||
const char *mbstr,
|
||||
size_t count)
|
||||
{
|
||||
int error;
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1400
|
||||
|
||||
/* Microsoft Visual Studio 2005 or later */
|
||||
error = mbstowcs_s (pReturnValue, wcstr, sizeInWords, mbstr, count);
|
||||
|
||||
#else
|
||||
|
||||
/* Older Visual Studio or non-Microsoft compiler */
|
||||
size_t n;
|
||||
|
||||
/* Convert to wide-character string (or count characters) */
|
||||
n = mbstowcs (wcstr, mbstr, sizeInWords);
|
||||
if (!wcstr || n < count) {
|
||||
|
||||
/* Zero-terminate output buffer */
|
||||
if (wcstr && sizeInWords) {
|
||||
if (n >= sizeInWords) {
|
||||
n = sizeInWords - 1;
|
||||
}
|
||||
wcstr[n] = 0;
|
||||
}
|
||||
|
||||
/* Length of resuting multi-byte string WITH zero terminator */
|
||||
if (pReturnValue) {
|
||||
*pReturnValue = n + 1;
|
||||
}
|
||||
|
||||
/* Success */
|
||||
error = 0;
|
||||
|
||||
} else {
|
||||
|
||||
/* Could not convert string */
|
||||
error = 1;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/* Convert wide-character string to multi-byte string */
|
||||
static int
|
||||
dirent_wcstombs_s(
|
||||
size_t *pReturnValue,
|
||||
char *mbstr,
|
||||
size_t sizeInBytes, /* max size of mbstr */
|
||||
const wchar_t *wcstr,
|
||||
size_t count)
|
||||
{
|
||||
int error;
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1400
|
||||
|
||||
/* Microsoft Visual Studio 2005 or later */
|
||||
error = wcstombs_s (pReturnValue, mbstr, sizeInBytes, wcstr, count);
|
||||
|
||||
#else
|
||||
|
||||
/* Older Visual Studio or non-Microsoft compiler */
|
||||
size_t n;
|
||||
|
||||
/* Convert to multi-byte string (or count the number of bytes needed) */
|
||||
n = wcstombs (mbstr, wcstr, sizeInBytes);
|
||||
if (!mbstr || n < count) {
|
||||
|
||||
/* Zero-terminate output buffer */
|
||||
if (mbstr && sizeInBytes) {
|
||||
if (n >= sizeInBytes) {
|
||||
n = sizeInBytes - 1;
|
||||
}
|
||||
mbstr[n] = '\0';
|
||||
}
|
||||
|
||||
/* Length of resulting multi-bytes string WITH zero-terminator */
|
||||
if (pReturnValue) {
|
||||
*pReturnValue = n + 1;
|
||||
}
|
||||
|
||||
/* Success */
|
||||
error = 0;
|
||||
|
||||
} else {
|
||||
|
||||
/* Cannot convert string */
|
||||
error = 1;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/* Set errno variable */
|
||||
static void
|
||||
dirent_set_errno(
|
||||
int error)
|
||||
{
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1400
|
||||
|
||||
/* Microsoft Visual Studio 2005 and later */
|
||||
_set_errno (error);
|
||||
|
||||
#else
|
||||
|
||||
/* Non-Microsoft compiler or older Microsoft compiler */
|
||||
errno = error;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /*DIRENT_H*/
|
||||
159
utils/mods/classic_wow_experience.lua
Normal file
159
utils/mods/classic_wow_experience.lua
Normal file
@ -0,0 +1,159 @@
|
||||
--Mod file to demo changing the experience tables
|
||||
--In this case I used some old wow tables (roughly it's not 100%)
|
||||
|
||||
function GetRequiredAAExperience(e)
|
||||
e.level = 51;
|
||||
return GetEXPForLevel(e);
|
||||
end
|
||||
|
||||
function GetExperienceForKill(e)
|
||||
local ML = e.other:GetLevel();
|
||||
local CL = e.self:GetLevel();
|
||||
|
||||
if(ML > CL) then
|
||||
local lmod = (ML - CL) * 0.05;
|
||||
if(lmod > 1.0) then
|
||||
lmod = 1.0;
|
||||
end
|
||||
e.ReturnValue = BaseXP(ML) * (1 + lmod);
|
||||
elseif(ML < CL) then
|
||||
local lmod = (CL - ML) * 0.05;
|
||||
if(lmod > 1.0) then
|
||||
lmod = 1.0;
|
||||
end
|
||||
e.ReturnValue = BaseXP(ML) * (1 - lmod);
|
||||
else
|
||||
e.ReturnValue = BaseXP(ML);
|
||||
end
|
||||
|
||||
e.IgnoreDefault = true;
|
||||
return e;
|
||||
end
|
||||
|
||||
function BaseXP(L)
|
||||
local base = L * 5;
|
||||
|
||||
if(L < 60) then
|
||||
base = base + 45;
|
||||
elseif(L < 70) then
|
||||
base = base + 235;
|
||||
elseif(L < 80) then
|
||||
base = base + 580;
|
||||
else
|
||||
base = base + 1875;
|
||||
end
|
||||
|
||||
return base;
|
||||
end
|
||||
|
||||
function GetEXPForLevel(e)
|
||||
local exp_table = {
|
||||
0,
|
||||
400,
|
||||
900,
|
||||
1400,
|
||||
2100,
|
||||
2800,
|
||||
3600,
|
||||
4500,
|
||||
5400,
|
||||
6500,
|
||||
7600,
|
||||
8700,
|
||||
9800,
|
||||
11000,
|
||||
12300,
|
||||
13600,
|
||||
15000,
|
||||
16400,
|
||||
17800,
|
||||
19300,
|
||||
20800,
|
||||
22400,
|
||||
24000,
|
||||
25500,
|
||||
27200,
|
||||
28900,
|
||||
30500,
|
||||
32200,
|
||||
33900,
|
||||
36300,
|
||||
38800,
|
||||
41600,
|
||||
44600,
|
||||
48000,
|
||||
51400,
|
||||
55000,
|
||||
58700,
|
||||
62400,
|
||||
66200,
|
||||
70200,
|
||||
74300,
|
||||
78500,
|
||||
82800,
|
||||
87100,
|
||||
91600,
|
||||
96300,
|
||||
101000,
|
||||
105800,
|
||||
110700,
|
||||
115700,
|
||||
120900,
|
||||
126100,
|
||||
131500,
|
||||
137000,
|
||||
142500,
|
||||
148200,
|
||||
154000,
|
||||
159900,
|
||||
165800,
|
||||
172000,
|
||||
290000,
|
||||
317000,
|
||||
349000,
|
||||
386000,
|
||||
428000,
|
||||
475000,
|
||||
527000,
|
||||
585000,
|
||||
648000,
|
||||
717000,
|
||||
1523800,
|
||||
1539000,
|
||||
1555700,
|
||||
1571800,
|
||||
1587900,
|
||||
1604200,
|
||||
1620700,
|
||||
1637400,
|
||||
1653900,
|
||||
1670800,
|
||||
1670800,
|
||||
1670800,
|
||||
2121500,
|
||||
2669000,
|
||||
3469000,
|
||||
4583000,
|
||||
13000000,
|
||||
15080000,
|
||||
22600000,
|
||||
27300000,
|
||||
32800000
|
||||
};
|
||||
|
||||
if(e.level < 1) then
|
||||
e.ReturnValue = 0;
|
||||
e.IgnoreDefault = true;
|
||||
return e;
|
||||
end
|
||||
|
||||
if(e.level > 91) then
|
||||
e.ReturnValue = exp_table[91];
|
||||
e.IgnoreDefault = true;
|
||||
return e;
|
||||
end
|
||||
|
||||
e.ReturnValue = exp_table[e.level];
|
||||
e.IgnoreDefault = true;
|
||||
return e;
|
||||
end
|
||||
752
utils/mods/legacy_combat.lua
Normal file
752
utils/mods/legacy_combat.lua
Normal file
@ -0,0 +1,752 @@
|
||||
MonkACBonusWeight = RuleI.Get(Rule.MonkACBonusWeight);
|
||||
NPCACFactor = RuleR.Get(Rule.NPCACFactor);
|
||||
OldACSoftcapRules = RuleB.Get(Rule.OldACSoftcapRules);
|
||||
ClothACSoftcap = RuleI.Get(Rule.ClothACSoftcap);
|
||||
LeatherACSoftcap = RuleI.Get(Rule.LeatherACSoftcap);
|
||||
MonkACSoftcap = RuleI.Get(Rule.MonkACSoftcap);
|
||||
ChainACSoftcap = RuleI.Get(Rule.ChainACSoftcap);
|
||||
PlateACSoftcap = RuleI.Get(Rule.PlateACSoftcap);
|
||||
|
||||
AAMitigationACFactor = RuleR.Get(Rule.AAMitigationACFactor);
|
||||
WarriorACSoftcapReturn = RuleR.Get(Rule.WarriorACSoftcapReturn);
|
||||
KnightACSoftcapReturn = RuleR.Get(Rule.KnightACSoftcapReturn);
|
||||
LowPlateChainACSoftcapReturn = RuleR.Get(Rule.LowPlateChainACSoftcapReturn);
|
||||
LowChainLeatherACSoftcapReturn = RuleR.Get(Rule.LowChainLeatherACSoftcapReturn);
|
||||
CasterACSoftcapReturn = RuleR.Get(Rule.CasterACSoftcapReturn);
|
||||
MiscACSoftcapReturn = RuleR.Get(Rule.MiscACSoftcapReturn);
|
||||
WarACSoftcapReturn = RuleR.Get(Rule.WarACSoftcapReturn);
|
||||
ClrRngMnkBrdACSoftcapReturn = RuleR.Get(Rule.ClrRngMnkBrdACSoftcapReturn);
|
||||
PalShdACSoftcapReturn = RuleR.Get(Rule.PalShdACSoftcapReturn);
|
||||
DruNecWizEncMagACSoftcapReturn = RuleR.Get(Rule.DruNecWizEncMagACSoftcapReturn);
|
||||
RogShmBstBerACSoftcapReturn = RuleR.Get(Rule.RogShmBstBerACSoftcapReturn);
|
||||
SoftcapFactor = RuleR.Get(Rule.SoftcapFactor);
|
||||
ACthac0Factor = RuleR.Get(Rule.ACthac0Factor);
|
||||
ACthac20Factor = RuleR.Get(Rule.ACthac20Factor);
|
||||
|
||||
MeleeBaseCritChance = 0.0;
|
||||
ClientBaseCritChance = 0.0;
|
||||
BerserkBaseCritChance = 6.0;
|
||||
WarBerBaseCritChance = 3.0;
|
||||
RogueCritThrowingChance = 25;
|
||||
RogueDeadlyStrikeChance = 80;
|
||||
RogueDeadlyStrikeMod = 2;
|
||||
|
||||
BaseHitChance = RuleR.Get(Rule.BaseHitChance);
|
||||
NPCBonusHitChance = RuleR.Get(Rule.NPCBonusHitChance);
|
||||
HitFalloffMinor = RuleR.Get(Rule.HitFalloffMinor);
|
||||
HitFalloffModerate = RuleR.Get(Rule.HitFalloffModerate);
|
||||
HitFalloffMajor = RuleR.Get(Rule.HitFalloffMajor);
|
||||
HitBonusPerLevel = RuleR.Get(Rule.HitBonusPerLevel);
|
||||
AgiHitFactor = RuleR.Get(Rule.AgiHitFactor);
|
||||
WeaponSkillFalloff = RuleR.Get(Rule.WeaponSkillFalloff);
|
||||
ArcheryHitPenalty = RuleR.Get(Rule.ArcheryHitPenalty);
|
||||
UseOldDamageIntervalRules = RuleB.Get(Rule.UseOldDamageIntervalRules);
|
||||
|
||||
function MeleeMitigation(e)
|
||||
e.IgnoreDefault = true;
|
||||
|
||||
if e.hit.damage_done < 0 or e.hit.base_damage == 0 then
|
||||
return e;
|
||||
end
|
||||
|
||||
e.hit.damage_done = 2 * e.hit.base_damage * GetDamageTable(e.other, e.hit.skill) / 100;
|
||||
e.hit = DoMeleeMitigation(e.self, e.other, e.hit, e.opts);
|
||||
return e;
|
||||
end
|
||||
|
||||
function CheckHitChance(e)
|
||||
e.IgnoreDefault = true;
|
||||
|
||||
local other = e.other;
|
||||
local attacker = other;
|
||||
local self = e.self;
|
||||
local defender = self;
|
||||
local chancetohit = BaseHitChance;
|
||||
local chance_mod = 0;
|
||||
|
||||
if(e.opts ~= nil) then
|
||||
chance_mod = e.opts.hit_chance;
|
||||
end
|
||||
|
||||
if(attacker:IsNPC() and not attacker:IsPet()) then
|
||||
chancetohit = chancetohit + NPCBonusHitChance;
|
||||
end
|
||||
|
||||
local pvpmode = false;
|
||||
if(self:IsClient() and other:IsClient()) then
|
||||
pvpmode = true;
|
||||
end
|
||||
|
||||
if (chance_mod >= 10000) then
|
||||
e.ReturnValue = true;
|
||||
return e;
|
||||
end
|
||||
|
||||
local avoidanceBonus = 0;
|
||||
local hitBonus = 0;
|
||||
|
||||
local attacker_level = attacker:GetLevel();
|
||||
if(attacker_level < 1) then
|
||||
attacker_level = 1;
|
||||
end
|
||||
|
||||
local defender_level = defender:GetLevel();
|
||||
if(defender_level < 1) then
|
||||
defender_level = 1;
|
||||
end
|
||||
|
||||
local level_difference = attacker_level - defender_level;
|
||||
local range = defender_level;
|
||||
range = ((range / 4) + 3);
|
||||
|
||||
if(level_difference < 0) then
|
||||
if(level_difference >= -range) then
|
||||
chancetohit = chancetohit + ((level_difference / range) * HitFalloffMinor);
|
||||
elseif (level_difference >= -(range+3.0)) then
|
||||
chancetohit = chancetohit - HitFalloffMinor;
|
||||
chancetohit = chancetohit + (((level_difference + range) / 3.0) * HitFalloffModerate);
|
||||
else
|
||||
chancetohit = chancetohit - (HitFalloffMinor + HitFalloffModerate);
|
||||
chancetohit = chancetohit + (((level_difference + range + 3.0) / 12.0) * HitFalloffMajor);
|
||||
end
|
||||
else
|
||||
chancetohit = chancetohit + (HitBonusPerLevel * level_difference);
|
||||
end
|
||||
|
||||
chancetohit = chancetohit - (defender:GetAGI() * AgiHitFactor);
|
||||
|
||||
if(attacker:IsClient()) then
|
||||
chancetohit = chancetohit - (WeaponSkillFalloff * (attacker:CastToClient():MaxSkill(e.hit.skill) - attacker:GetSkill(e.hit.skill)));
|
||||
end
|
||||
|
||||
if(defender:IsClient()) then
|
||||
chancetohit = chancetohit + (WeaponSkillFalloff * (defender:CastToClient():MaxSkill(Skill.Defense) - defender:GetSkill(Skill.Defense)));
|
||||
end
|
||||
|
||||
local attacker_spellbonuses = attacker:GetSpellBonuses();
|
||||
local attacker_itembonuses = attacker:GetItemBonuses();
|
||||
local attacker_aabonuses = attacker:GetAABonuses();
|
||||
local defender_spellbonuses = defender:GetSpellBonuses();
|
||||
local defender_itembonuses = defender:GetItemBonuses();
|
||||
local defender_aabonuses = defender:GetAABonuses();
|
||||
|
||||
if(attacker_spellbonuses:MeleeSkillCheckSkill() == e.hit.skill or attacker_spellbonuses:MeleeSkillCheckSkill() == 255) then
|
||||
chancetohit = chancetohit + attacker_spellbonuses:MeleeSkillCheck();
|
||||
end
|
||||
|
||||
if(attacker_itembonuses:MeleeSkillCheckSkill() == e.hit.skill or attacker_itembonuses:MeleeSkillCheckSkill() == 255) then
|
||||
chancetohit = chancetohit + attacker_itembonuses:MeleeSkillCheck();
|
||||
end
|
||||
|
||||
avoidanceBonus = defender_spellbonuses:AvoidMeleeChanceEffect() +
|
||||
defender_itembonuses:AvoidMeleeChanceEffect() +
|
||||
defender_aabonuses:AvoidMeleeChanceEffect() +
|
||||
(defender_itembonuses:AvoidMeleeChance() / 10.0);
|
||||
|
||||
local owner = Mob();
|
||||
if (defender:IsPet()) then
|
||||
owner = defender:GetOwner();
|
||||
elseif (defender:IsNPC() and defender:CastToNPC():GetSwarmOwner()) then
|
||||
local entity_list = eq.get_entity_list();
|
||||
owner = entity_list:GetMobID(defender:CastToNPC():GetSwarmOwner());
|
||||
end
|
||||
|
||||
if (owner.valid) then
|
||||
avoidanceBonus = avoidanceBonus + owner:GetAABonuses():PetAvoidance() + owner:GetSpellBonuses():PetAvoidance() + owner:GetItemBonuses():PetAvoidance();
|
||||
end
|
||||
|
||||
if(defender:IsNPC()) then
|
||||
avoidanceBonus = avoidanceBonus + (defender:CastToNPC():GetAvoidanceRating() / 10.0);
|
||||
end
|
||||
|
||||
hitBonus = hitBonus + attacker_itembonuses:HitChanceEffect(e.hit.skill) +
|
||||
attacker_spellbonuses:HitChanceEffect(e.hit.skill) +
|
||||
attacker_aabonuses:HitChanceEffect(e.hit.skill) +
|
||||
attacker_itembonuses:HitChanceEffect(Skill.HIGHEST_SKILL + 1) +
|
||||
attacker_spellbonuses:HitChanceEffect(Skill.HIGHEST_SKILL + 1) +
|
||||
attacker_aabonuses:HitChanceEffect(Skill.HIGHEST_SKILL + 1);
|
||||
|
||||
hitBonus = hitBonus + (attacker_itembonuses:Accuracy(Skill.HIGHEST_SKILL + 1) +
|
||||
attacker_spellbonuses:Accuracy(Skill.HIGHEST_SKILL + 1) +
|
||||
attacker_aabonuses:Accuracy(Skill.HIGHEST_SKILL + 1) +
|
||||
attacker_aabonuses:Accuracy(e.hit.skill) +
|
||||
attacker_itembonuses:HitChance()) / 15.0;
|
||||
|
||||
hitBonus = hitBonus + chance_mod;
|
||||
|
||||
if(attacker:IsNPC()) then
|
||||
hitBonus = hitBonus + (attacker:CastToNPC():GetAccuracyRating() / 10.0);
|
||||
end
|
||||
|
||||
if (e.hit.skill == Skill.Archery) then
|
||||
hitBonus = hitBonus - (hitBonus * ArcheryHitPenalty);
|
||||
end
|
||||
|
||||
chancetohit = chancetohit + ((chancetohit * (hitBonus - avoidanceBonus)) / 100.0);
|
||||
|
||||
if(chancetohit > 1000 or chancetohit < -1000) then
|
||||
elseif(chancetohit > 95) then
|
||||
chancetohit = 95;
|
||||
elseif(chancetohit < 5) then
|
||||
chancetohit = 5;
|
||||
end
|
||||
|
||||
local tohit_roll = Random.Real(0, 100);
|
||||
if(tohit_roll <= chancetohit) then
|
||||
e.ReturnValue = true;
|
||||
else
|
||||
e.ReturnValue = false;
|
||||
end
|
||||
|
||||
return e;
|
||||
end
|
||||
|
||||
function TryCriticalHit(e)
|
||||
e.IgnoreDefault = true;
|
||||
|
||||
local self = e.self;
|
||||
local defender = e.other;
|
||||
|
||||
if(e.hit.damage_done < 1 or defender.null) then
|
||||
return e;
|
||||
end
|
||||
|
||||
if ((self:IsPet() and self:GetOwner():IsClient()) or (self:IsNPC() and self:CastToNPC():GetSwarmOwner() ~= 0)) then
|
||||
e.hit = TryPetCriticalHit(self, defender, e.hit);
|
||||
return e;
|
||||
end
|
||||
|
||||
if (self:IsPet() and self:GetOwner().valid and self:GetOwner():IsBot()) then
|
||||
e.hit = TryPetCriticalHit(self, defender, e.hit);
|
||||
return e;
|
||||
end
|
||||
|
||||
local critChance = 0.0;
|
||||
local IsBerskerSPA = false;
|
||||
local aabonuses = self:GetAABonuses();
|
||||
local itembonuses = self:GetItemBonuses();
|
||||
local spellbonuses = self:GetSpellBonuses();
|
||||
local entity_list = eq.get_entity_list();
|
||||
|
||||
if (defender:GetBodyType() == BT.Undead or defender:GetBodyType() == BT.SummonedUndead or defender:GetBodyType() == BT.Vampire) then
|
||||
local SlayRateBonus = aabonuses:SlayUndead(0) + itembonuses:SlayUndead(0) + spellbonuses:SlayUndead(0);
|
||||
if (SlayRateBonus > 0) then
|
||||
local slayChance = SlayRateBonus / 10000.0;
|
||||
if (Random.RollReal(slayChance)) then
|
||||
local SlayDmgBonus = aabonuses:SlayUndead(1) + itembonuses:SlayUndead(1) + spellbonuses:SlayUndead(1);
|
||||
e.hit.damage_done = (e.hit.damage_done * SlayDmgBonus * 2.25) / 100;
|
||||
|
||||
if (self:GetGender() == 1) then
|
||||
entity_list:FilteredMessageClose(self, false, 200, MT.CritMelee, Filter.MeleeCrits, string.format('%s\'s holy blade cleanses her target! (%d)', self:GetCleanName(), e.hit.damage_done));
|
||||
else
|
||||
entity_list:FilteredMessageClose(self, false, 200, MT.CritMelee, Filter.MeleeCrits, string.format('%s\'s holy blade cleanses his target! (%d)', self:GetCleanName(), e.hit.damage_done));
|
||||
end
|
||||
|
||||
return e;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
critChance = critChance + MeleeBaseCritChance;
|
||||
|
||||
if (self:IsClient()) then
|
||||
critChance = critChance + ClientBaseCritChance;
|
||||
|
||||
if (spellbonuses:BerserkSPA() or itembonuses:BerserkSPA() or aabonuses:BerserkSPA()) then
|
||||
IsBerskerSPA = true;
|
||||
end
|
||||
|
||||
if (((self:GetClass() == Class.WARRIOR or self:GetClass() == Class.BERSERKER) and self:GetLevel() >= 12) or IsBerskerSPA) then
|
||||
if (self:IsBerserk() or IsBerskerSPA) then
|
||||
critChance = critChance + BerserkBaseCritChance;
|
||||
else
|
||||
critChance = critChance + WarBerBaseCritChance;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local deadlyChance = 0;
|
||||
local deadlyMod = 0;
|
||||
if (e.hit.skill == Skill.Archery and self:GetClass() == Class.RANGER and self:GetSkill(Skill.Archery) >= 65) then
|
||||
critChance = critChance + 6;
|
||||
end
|
||||
|
||||
if (e.hit.skill == Skill.Throwing and self:GetClass() == Class.ROGUE and self:GetSkill(Skill.Throwing) >= 65) then
|
||||
critChance = critChance + RogueCritThrowingChance;
|
||||
deadlyChance = RogueDeadlyStrikeChance;
|
||||
deadlyMod = RogueDeadlyStrikeMod;
|
||||
end
|
||||
|
||||
local CritChanceBonus = GetCriticalChanceBonus(self, e.hit.skill);
|
||||
|
||||
if (CritChanceBonus > 0 or critChance > 0) then
|
||||
if (self:GetDEX() <= 255) then
|
||||
critChance = critChance + (self:GetDEX() / 125.0);
|
||||
elseif (self:GetDEX() > 255) then
|
||||
critChance = critChance + ((self:GetDEX() - 255) / 500.0) + 2.0;
|
||||
end
|
||||
critChance = critChance + (critChance * CritChanceBonus / 100.0);
|
||||
end
|
||||
|
||||
if(opts ~= nil) then
|
||||
critChance = critChance * opts.crit_percent;
|
||||
critChance = critChance + opts.crit_flat;
|
||||
end
|
||||
|
||||
if(critChance > 0) then
|
||||
|
||||
critChance = critChance / 100;
|
||||
|
||||
if(Random.RollReal(critChance)) then
|
||||
local critMod = 200;
|
||||
local crip_success = false;
|
||||
local CripplingBlowChance = GetCrippBlowChance(self);
|
||||
|
||||
if (CripplingBlowChance > 0 or (self:IsBerserk() or IsBerskerSPA)) then
|
||||
if (not self:IsBerserk() and not IsBerskerSPA) then
|
||||
critChance = critChance * (CripplingBlowChance / 100.0);
|
||||
end
|
||||
|
||||
if ((self:IsBerserk() or IsBerskerSPA) or Random.RollReal(critChance)) then
|
||||
critMod = 400;
|
||||
crip_success = true;
|
||||
end
|
||||
end
|
||||
|
||||
critMod = critMod + GetCritDmgMod(self, e.hit.skill) * 2;
|
||||
e.hit.damage_done = e.hit.damage_done * critMod / 100;
|
||||
|
||||
local deadlySuccess = false;
|
||||
if (deadlyChance > 0 and Random.RollReal(deadlyChance / 100.0)) then
|
||||
if (self:BehindMob(defender, self:GetX(), self:GetY())) then
|
||||
e.hit.damage_done = e.hit.damage_done * deadlyMod;
|
||||
deadlySuccess = true;
|
||||
end
|
||||
end
|
||||
|
||||
if (crip_success) then
|
||||
entity_list:FilteredMessageClose(self, false, 200, MT.CritMelee, Filter.MeleeCrits, string.format('%s lands a Crippling Blow! (%d)', self:GetCleanName(), e.hit.damage_done));
|
||||
if (defender:GetLevel() <= 55 and not defender:GetSpecialAbility(SpecialAbility.unstunable)) then
|
||||
defender:Emote("staggers.");
|
||||
defender:Stun(0);
|
||||
end
|
||||
elseif (deadlySuccess) then
|
||||
entity_list:FilteredMessageClose(self, false, 200, MT.CritMelee, Filter.MeleeCrits, string.format('%s scores a Deadly Strike! (%d)', self:GetCleanName(), e.hit.damage_done));
|
||||
else
|
||||
entity_list:FilteredMessageClose(self, false, 200, MT.CritMelee, Filter.MeleeCrits, string.format('%s scores a critical hit! (%d)', self:GetCleanName(), e.hit.damage_done));
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return e;
|
||||
end
|
||||
|
||||
function TryPetCriticalHit(self, defender, hit)
|
||||
if(hit.damage_done < 1) then
|
||||
return hit;
|
||||
end
|
||||
|
||||
local owner = Mob();
|
||||
local critChance = MeleeBaseCritChance;
|
||||
local critMod = 163;
|
||||
|
||||
if (self:IsPet()) then
|
||||
owner = self:GetOwner();
|
||||
elseif (self:IsNPC() and self:CastToNPC():GetSwarmOwner()) then
|
||||
local entity_list = eq.get_entity_list();
|
||||
owner = entity_list:GetMobID(self:CastToNPC():GetSwarmOwner());
|
||||
else
|
||||
return hit;
|
||||
end
|
||||
|
||||
if (owner.null) then
|
||||
return hit;
|
||||
end
|
||||
|
||||
local CritPetChance = owner:GetAABonuses():PetCriticalHit() + owner:GetItemBonuses():PetCriticalHit() + owner:GetSpellBonuses():PetCriticalHit();
|
||||
local CritChanceBonus = GetCriticalChanceBonus(self, hit.skill);
|
||||
|
||||
if (CritPetChance or critChance) then
|
||||
critChance = critChance + CritPetChance;
|
||||
critChance = critChance + (critChance * CritChanceBonus / 100.0);
|
||||
end
|
||||
|
||||
if(critChance > 0) then
|
||||
critChance = critChance / 100;
|
||||
|
||||
if(Random.RollReal(critChance)) then
|
||||
local entity_list = eq.get_entity_list();
|
||||
critMod = critMod + GetCritDmgMob(self, hit.skill) * 2;
|
||||
hit.damage_done = (hit.damage_done * critMod) / 100;
|
||||
entity_list:FilteredMessageClose(this, false, 200,
|
||||
MT.CritMelee, Filter.MeleeCrits, string.format('%s scores a critical hit! (%d)',
|
||||
self:GetCleanName(), hit.damage_done));
|
||||
end
|
||||
end
|
||||
|
||||
return hit;
|
||||
end
|
||||
|
||||
function GetCriticalChanceBonus(self, skill)
|
||||
|
||||
local critical_chance = 0;
|
||||
|
||||
local aabonuses = self:GetAABonuses();
|
||||
local itembonuses = self:GetItemBonuses();
|
||||
local spellbonuses = self:GetSpellBonuses();
|
||||
|
||||
critical_chance = critical_chance + itembonuses:CriticalHitChance(Skill.HIGHEST_SKILL + 1);
|
||||
critical_chance = critical_chance + spellbonuses:CriticalHitChance(Skill.HIGHEST_SKILL + 1);
|
||||
critical_chance = critical_chance + aabonuses:CriticalHitChance(Skill.HIGHEST_SKILL + 1);
|
||||
critical_chance = critical_chance + itembonuses:CriticalHitChance(skill);
|
||||
critical_chance = critical_chance + spellbonuses:CriticalHitChance(skill);
|
||||
critical_chance = critical_chance + aabonuses:CriticalHitChance(skill);
|
||||
|
||||
return critical_chance;
|
||||
end
|
||||
|
||||
function GetCritDmgMod(self, skill)
|
||||
local critDmg_mod = 0;
|
||||
|
||||
local aabonuses = self:GetAABonuses();
|
||||
local itembonuses = self:GetItemBonuses();
|
||||
local spellbonuses = self:GetSpellBonuses();
|
||||
|
||||
critDmg_mod = critDmg_mod + itembonuses:CritDmgMod(Skill.HIGHEST_SKILL + 1);
|
||||
critDmg_mod = critDmg_mod + spellbonuses:CritDmgMod(Skill.HIGHEST_SKILL + 1);
|
||||
critDmg_mod = critDmg_mod + aabonuses:CritDmgMod(Skill.HIGHEST_SKILL + 1);
|
||||
critDmg_mod = critDmg_mod + itembonuses:CritDmgMod(skill);
|
||||
critDmg_mod = critDmg_mod + spellbonuses:CritDmgMod(skill);
|
||||
critDmg_mod = critDmg_mod + aabonuses:CritDmgMod(skill);
|
||||
|
||||
return critDmg_mod;
|
||||
end
|
||||
|
||||
function GetCrippBlowChance(self)
|
||||
local aabonuses = self:GetAABonuses();
|
||||
local itembonuses = self:GetItemBonuses();
|
||||
local spellbonuses = self:GetSpellBonuses();
|
||||
local crip_chance = itembonuses:CrippBlowChance() + spellbonuses:CrippBlowChance() + aabonuses:CrippBlowChance();
|
||||
|
||||
if(crip_chance < 0) then
|
||||
crip_chance = 0;
|
||||
end
|
||||
|
||||
return crip_chance;
|
||||
end
|
||||
|
||||
function DoMeleeMitigation(defender, attacker, hit, opts)
|
||||
if hit.damage_done <= 0 then
|
||||
return hit;
|
||||
end
|
||||
|
||||
local aabonuses = defender:GetAABonuses();
|
||||
local itembonuses = defender:GetItemBonuses();
|
||||
local spellbonuses = defender:GetSpellBonuses();
|
||||
|
||||
local aa_mit = (aabonuses:CombatStability() + itembonuses:CombatStability() + spellbonuses:CombatStability()) / 100.0;
|
||||
local softcap = (defender:GetSkill(15) + defender:GetLevel()) * SoftcapFactor * (1.0 + aa_mit);
|
||||
local mitigation_rating = 0.0;
|
||||
local attack_rating = 0.0;
|
||||
local shield_ac = 0;
|
||||
local armor = 0;
|
||||
local weight = 0.0;
|
||||
local monkweight = MonkACBonusWeight;
|
||||
|
||||
if defender:IsClient() then
|
||||
armor, shield_ac = GetRawACNoShield(defender);
|
||||
weight = defender:CastToClient():CalcCurrentWeight() / 10;
|
||||
elseif defender:IsNPC() then
|
||||
armor = defender:CastToNPC():GetRawAC();
|
||||
local PetACBonus = 0;
|
||||
|
||||
if not defender:IsPet() then
|
||||
armor = armor / NPCACFactor;
|
||||
end
|
||||
|
||||
local owner = Mob();
|
||||
if defender:IsPet() then
|
||||
owner = defender:GetOwner();
|
||||
elseif defender:CastToNPC():GetSwarmOwner() ~= 0 then
|
||||
local entity_list = eq.get_entity_list();
|
||||
owner = entity_list:GetMobID(defender:CastToNPC():GetSwarmOwner());
|
||||
end
|
||||
|
||||
if owner.valid then
|
||||
PetACBonus = owner:GetAABonuses():PetMeleeMitigation() + owner:GetItemBonuses():PetMeleeMitigation() + owner:GetSpellBonuses():PetMeleeMitigation();
|
||||
end
|
||||
|
||||
armor = armor + defender:GetSpellBonuses():AC() + defender:GetItemBonuses():AC() + PetACBonus + 1;
|
||||
end
|
||||
|
||||
if (opts ~= nil) then
|
||||
armor = armor * (1.0 - opts.armor_pen_percent);
|
||||
armor = armor - opts.armor_pen_flat;
|
||||
end
|
||||
|
||||
local defender_class = defender:GetClass();
|
||||
if OldACSoftcapRules then
|
||||
if defender_class == Class.WIZARD or defender_class == Class.MAGICIAN or defender_class == Class.NECROMANCER or defender_class == Class.ENCHANTER then
|
||||
softcap = ClothACSoftcap;
|
||||
elseif defender_class == Class.MONK and weight <= monkweight then
|
||||
softcap = MonkACSoftcap;
|
||||
elseif defender_class == Class.DRUID or defender_class == Class.BEASTLORD or defender_class == Class.MONK then
|
||||
softcap = LeatherACSoftcap;
|
||||
elseif defender_class == Class.SHAMAN or defender_class == Class.ROGUE or defender_class == Class.BERSERKER or defender_class == Class.RANGER then
|
||||
softcap = ChainACSoftcap;
|
||||
else
|
||||
softcap = PlateACSoftcap;
|
||||
end
|
||||
end
|
||||
|
||||
softcap = softcap + shield_ac;
|
||||
armor = armor + shield_ac;
|
||||
|
||||
if OldACSoftcapRules then
|
||||
softcap = softcap + (softcap * (aa_mit * AAMitigationACFactor));
|
||||
end
|
||||
|
||||
if armor > softcap then
|
||||
local softcap_armor = armor - softcap;
|
||||
if OldACSoftcapRules then
|
||||
if defender_class == Class.WARRIOR then
|
||||
softcap_armor = softcap_armor * WarriorACSoftcapReturn;
|
||||
elseif defender_class == Class.SHADOWKNIGHT or defender_class == Class.PALADIN or (defender_class == Class.MONK and weight <= monkweight) then
|
||||
softcap_armor = softcap_armor * KnightACSoftcapReturn;
|
||||
elseif defender_class == Class.CLERIC or defender_class == Class.BARD or defender_class == Class.BERSERKER or defender_class == Class.ROGUE or defender_class == Class.SHAMAN or defender_class == Class.MONK then
|
||||
softcap_armor = softcap_armor * LowPlateChainACSoftcapReturn;
|
||||
elseif defender_class == Class.RANGER or defender_class == Class.BEASTLORD then
|
||||
softcap_armor = softcap_armor * LowChainLeatherACSoftcapReturn;
|
||||
elseif defender_class == Class.WIZARD or defender_class == Class.MAGICIAN or defender_class == Class.NECROMANCER or defender_class == Class.ENCHANTER or defender_class == Class.DRUID then
|
||||
softcap_armor = softcap_armor * CasterACSoftcapReturn;
|
||||
else
|
||||
softcap_armor = softcap_armor * MiscACSoftcapReturn;
|
||||
end
|
||||
else
|
||||
if defender_class == Class.WARRIOR then
|
||||
softcap_armor = softcap_armor * WarACSoftcapReturn;
|
||||
elseif defender_class == Class.PALADIN or defender_class == Class.SHADOWKNIGHT then
|
||||
softcap_armor = softcap_armor * PalShdACSoftcapReturn;
|
||||
elseif defender_class == Class.CLERIC or defender_class == Class.RANGER or defender_class == Class.MONK or defender_class == Class.BARD then
|
||||
softcap_armor = softcap_armor * ClrRngMnkBrdACSoftcapReturn;
|
||||
elseif defender_class == Class.DRUID or defender_class == Class.NECROMANCER or defender_class == Class.WIZARD or defender_class == Class.ENCHANTER or defender_class == Class.MAGICIAN then
|
||||
softcap_armor = softcap_armor * DruNecWizEncMagACSoftcapReturn;
|
||||
elseif defender_class == Class.ROGUE or defender_class == Class.SHAMAN or defender_class == Class.BEASTLORD or defender_class == Class.BERSERKER then
|
||||
softcap_armor = softcap_armor * RogShmBstBerACSoftcapReturn;
|
||||
else
|
||||
softcap_armor = softcap_armor * MiscACSoftcapReturn;
|
||||
end
|
||||
end
|
||||
|
||||
armor = softcap + softcap_armor;
|
||||
end
|
||||
|
||||
local mitigation_rating;
|
||||
if defender_class == Class.WIZARD or defender_class == Class.MAGICIAN or defender_class == Class.NECROMANCER or defender_class == Class.ENCHANTER then
|
||||
mitigation_rating = ((defender:GetSkill(Skill.Defense) + defender:GetItemBonuses():HeroicAGI() / 10) / 4.0) + armor + 1;
|
||||
else
|
||||
mitigation_rating = ((defender:GetSkill(Skill.Defense) + defender:GetItemBonuses():HeroicAGI() / 10) / 3.0) + (armor * 1.333333) + 1;
|
||||
end
|
||||
|
||||
mitigation_rating = mitigation_rating * 0.847;
|
||||
|
||||
local attack_rating;
|
||||
if attacker:IsClient() then
|
||||
attack_rating = (attacker:CastToClient():CalcATK() + ((attacker:GetSTR() - 66) * 0.9) + (attacker:GetSkill(Skill.Offense)*1.345));
|
||||
else
|
||||
attack_rating = (attacker:GetATK() + (attacker:GetSkill(Skill.Offense)*1.345) + ((attacker:GetSTR() - 66) * 0.9));
|
||||
end
|
||||
|
||||
hit.damage_done = GetMeleeMitDmg(defender, attacker, hit.damage_done, hit.min_damage, mitigation_rating, attack_rating);
|
||||
|
||||
if hit.damage_done < 0 then
|
||||
hit.damage_done = 0;
|
||||
end
|
||||
|
||||
return hit;
|
||||
end
|
||||
|
||||
function GetMeleeMitDmg(defender, attacker, damage, min_damage, mitigation_rating, attack_rating)
|
||||
if defender:IsClient() then
|
||||
return ClientGetMeleeMitDmg(defender, attacker, damage, min_damage, mitigation_rating, attack_rating);
|
||||
else
|
||||
return MobGetMeleeMitDmg(defender, attacker, damage, min_damage, mitigation_rating, attack_rating);
|
||||
end
|
||||
end
|
||||
|
||||
function ClientGetMeleeMitDmg(defender, attacker, damage, min_damage, mitigation_rating, attack_rating)
|
||||
if (not attacker:IsNPC() or UseOldDamageIntervalRules) then
|
||||
return MobGetMeleeMitDmg(defender, attacker, damage, min_damage, mitigation_rating, attack_rating);
|
||||
end
|
||||
|
||||
local d = 10;
|
||||
local dmg_interval = (damage - min_damage) / 19.0;
|
||||
local dmg_bonus = min_damage - dmg_interval;
|
||||
local spellMeleeMit = (defender:GetSpellBonuses():MeleeMitigationEffect() + defender:GetItemBonuses():MeleeMitigationEffect() + defender:GetAABonuses():MeleeMitigationEffect()) / 100.0;
|
||||
if (defender:GetClass() == Class.WARRIOR) then
|
||||
spellMeleeMit = spellMeleeMit - 0.05;
|
||||
end
|
||||
|
||||
dmg_bonus = dmg_bonus - (dmg_bonus * (defender:GetItemBonuses():MeleeMitigation() / 100.0));
|
||||
dmg_interval = dmg_interval + (dmg_interval * spellMeleeMit);
|
||||
|
||||
local mit_roll = Random.Real(0, mitigation_rating);
|
||||
local atk_roll = Random.Real(0, attack_rating);
|
||||
|
||||
if (atk_roll > mit_roll) then
|
||||
local a_diff = atk_roll - mit_roll;
|
||||
local thac0 = attack_rating * ACthac0Factor;
|
||||
local thac0cap = attacker:GetLevel() * 9 + 20;
|
||||
if (thac0 > thac0cap) then
|
||||
thac0 = thac0cap;
|
||||
end
|
||||
|
||||
d = d + (10 * (a_diff / thac0));
|
||||
elseif (mit_roll > atk_roll) then
|
||||
local m_diff = mit_roll - atk_roll;
|
||||
local thac20 = mitigation_rating * ACthac20Factor;
|
||||
local thac20cap = defender:GetLevel() * 9 + 20;
|
||||
if (thac20 > thac20cap) then
|
||||
thac20 = thac20cap;
|
||||
end
|
||||
|
||||
d = d - (10 * (m_diff / thac20));
|
||||
end
|
||||
|
||||
if (d < 1) then
|
||||
d = 1;
|
||||
elseif (d > 20) then
|
||||
d = 20;
|
||||
end
|
||||
|
||||
return math.floor(dmg_bonus + dmg_interval * d);
|
||||
end
|
||||
|
||||
function MobGetMeleeMitDmg(defender, attacker, damage, min_damage, mitigation_rating, attack_rating)
|
||||
local d = 10.0;
|
||||
local mit_roll = Random.Real(0, mitigation_rating);
|
||||
local atk_roll = Random.Real(0, attack_rating);
|
||||
|
||||
if (atk_roll > mit_roll) then
|
||||
local a_diff = atk_roll - mit_roll;
|
||||
local thac0 = attack_rating * ACthac0Factor;
|
||||
local thac0cap = attacker:GetLevel() * 9 + 20;
|
||||
if (thac0 > thac0cap) then
|
||||
thac0 = thac0cap;
|
||||
end
|
||||
|
||||
d = d - (10.0 * (a_diff / thac0));
|
||||
elseif (mit_roll > atk_roll) then
|
||||
local m_diff = mit_roll - atk_roll;
|
||||
local thac20 = mitigation_rating * ACthac20Factor;
|
||||
local thac20cap = defender:GetLevel() * 9 + 20;
|
||||
if (thac20 > thac20cap) then
|
||||
thac20 = thac20cap;
|
||||
end
|
||||
|
||||
d = d + (10.0 * (m_diff / thac20));
|
||||
end
|
||||
|
||||
if (d < 0.0) then
|
||||
d = 0.0;
|
||||
elseif (d > 20.0) then
|
||||
d = 20.0;
|
||||
end
|
||||
|
||||
local interval = (damage - min_damage) / 20.0;
|
||||
damage = damage - (math.floor(d) * interval);
|
||||
damage = damage - (min_damage * defender:GetItemBonuses():MeleeMitigation() / 100);
|
||||
damage = damage + (damage * (defender:GetSpellBonuses():MeleeMitigationEffect() + defender:GetItemBonuses():MeleeMitigationEffect() + defender:GetAABonuses():MeleeMitigationEffect()) / 100);
|
||||
|
||||
return damage;
|
||||
end
|
||||
|
||||
function GetRawACNoShield(self)
|
||||
self = self:CastToClient();
|
||||
|
||||
local ac = self:GetItemBonuses():AC() + self:GetSpellBonuses():AC() + self:GetAABonuses():AC();
|
||||
local shield_ac = 0;
|
||||
local inst = self:GetInventory():GetItem(Slot.Secondary);
|
||||
|
||||
if inst.valid then
|
||||
if inst:GetItem():ItemType() == 8 then
|
||||
shield_ac = inst:GetItem():AC();
|
||||
|
||||
for i = 1, 6 do
|
||||
local augment = inst:GetAugment(i - 1);
|
||||
if augment.valid then
|
||||
shield_ac = shield_ac + augment:GetItem():AC();
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ac = ac - shield_ac;
|
||||
return ac, shield_ac;
|
||||
end
|
||||
|
||||
function GetDamageTable(attacker, skill)
|
||||
if not attacker:IsClient() then
|
||||
return 100;
|
||||
end
|
||||
|
||||
if attacker:GetLevel() <= 51 then
|
||||
local ret_table = 0;
|
||||
local str_over_75 = 0;
|
||||
if attacker:GetSTR() > 75 then
|
||||
str_over_75 = attacker:GetSTR() - 75;
|
||||
end
|
||||
|
||||
if str_over_75 > 255 then
|
||||
ret_table = (attacker:GetSkill(skill) + 255) / 2;
|
||||
else
|
||||
ret_table = (attacker:GetSkill(skill) + str_over_75) / 2;
|
||||
end
|
||||
|
||||
if ret_table < 100 then
|
||||
return 100;
|
||||
end
|
||||
|
||||
return ret_table;
|
||||
elseif attacker:GetLevel() >= 90 then
|
||||
if attacker:GetClass() == 7 then
|
||||
return 379;
|
||||
else
|
||||
return 345;
|
||||
end
|
||||
else
|
||||
local dmg_table = { 275, 275, 275, 275, 275, 280, 280, 280, 280, 285, 285, 285, 290, 290, 295, 295, 300, 300, 300, 305, 305, 305, 310, 310, 315, 315, 320, 320, 320, 325, 325, 325, 330, 330, 335, 335, 340, 340, 340 };
|
||||
|
||||
if attacker:GetClass() == 7 then
|
||||
local monkDamageTableBonus = 20;
|
||||
return (dmg_table[GetLevel() - 50] * (100 + monkDamageTableBonus) / 100);
|
||||
else
|
||||
return dmg_table[attacker:GetLevel() - 50];
|
||||
end
|
||||
end
|
||||
return 100;
|
||||
end
|
||||
|
||||
function ApplyDamageTable(e)
|
||||
e.IgnoreDefault = true;
|
||||
return e;
|
||||
end
|
||||
|
||||
function CommonOutgoingHitSuccess(e)
|
||||
e = ApplyMeleeDamageBonus(e);
|
||||
e.hit.damage_done = e.hit.damage_done + (e.hit.damage_done * e.other:GetSkillDmgTaken(e.hit.skill) / 100) + (e.self:GetSkillDmgAmt(e.hit.skill) + e.other:GetFcDamageAmtIncoming(e.self, 0, true, e.hit.skill));
|
||||
e = TryCriticalHit(e);
|
||||
e.self:CheckNumHitsRemaining(5, -1, 65535);
|
||||
e.IgnoreDefault = true;
|
||||
return e;
|
||||
end
|
||||
|
||||
function ApplyMeleeDamageBonus(e)
|
||||
local dmgbonusmod = e.self:GetMeleeDamageMod_SE(e.hit.skill);
|
||||
if (opts) then
|
||||
dmgbonusmod = dmgbonusmod + e.opts.melee_damage_bonus_flat;
|
||||
end
|
||||
|
||||
e.hit.damage_done = e.hit.damage_done + (e.hit.damage_done * dmgbonusmod / 100);
|
||||
return e;
|
||||
end
|
||||
1
utils/mods/load_order.txt
Normal file
1
utils/mods/load_order.txt
Normal file
@ -0,0 +1 @@
|
||||
legacy_combat.lua
|
||||
@ -392,12 +392,12 @@ int main(int argc, char** argv) {
|
||||
server_connection->Listen(server_opts);
|
||||
Log(Logs::General, Logs::World_Server, "Server (TCP) listener started.");
|
||||
|
||||
server_connection->OnConnectionIdentified("Zone", [](std::shared_ptr<EQ::Net::ServertalkServerConnection> connection) {
|
||||
server_connection->OnConnectionIdentified("Zone", [&console](std::shared_ptr<EQ::Net::ServertalkServerConnection> connection) {
|
||||
LogF(Logs::General, Logs::World_Server, "New Zone Server connection from {2} at {0}:{1}",
|
||||
connection->Handle()->RemoteIP(), connection->Handle()->RemotePort(), connection->GetUUID());
|
||||
|
||||
numzones++;
|
||||
zoneserver_list.Add(new ZoneServer(connection));
|
||||
zoneserver_list.Add(new ZoneServer(connection, console.get()));
|
||||
});
|
||||
|
||||
server_connection->OnConnectionRemoved("Zone", [](std::shared_ptr<EQ::Net::ServertalkServerConnection> connection) {
|
||||
|
||||
@ -46,7 +46,7 @@ extern UCSConnection UCSLink;
|
||||
extern QueryServConnection QSLink;
|
||||
void CatchSignal(int sig_num);
|
||||
|
||||
ZoneServer::ZoneServer(std::shared_ptr<EQ::Net::ServertalkServerConnection> connection)
|
||||
ZoneServer::ZoneServer(std::shared_ptr<EQ::Net::ServertalkServerConnection> connection, EQ::Net::ConsoleServer *console)
|
||||
: tcpc(connection), zone_boot_timer(5000) {
|
||||
|
||||
/* Set Process tracking variable defaults */
|
||||
@ -73,6 +73,8 @@ ZoneServer::ZoneServer(std::shared_ptr<EQ::Net::ServertalkServerConnection> conn
|
||||
zone_boot_timer.Disable();
|
||||
}
|
||||
}));
|
||||
|
||||
this->console = console;
|
||||
}
|
||||
|
||||
ZoneServer::~ZoneServer() {
|
||||
@ -412,6 +414,27 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) {
|
||||
break;
|
||||
}
|
||||
if (scm->chan_num == 7 || scm->chan_num == 14) {
|
||||
if (scm->deliverto[0] == '*') {
|
||||
|
||||
if (console) {
|
||||
auto con = console->FindByAccountName(&scm->deliverto[1]);
|
||||
if (((!con) || (!con->SendChannelMessage(scm, [&scm]() {
|
||||
auto pack = new ServerPacket(ServerOP_ChannelMessage,
|
||||
sizeof(ServerChannelMessage_Struct) + strlen(scm->message) + 1);
|
||||
memcpy(pack->pBuffer, scm, pack->size);
|
||||
ServerChannelMessage_Struct* scm2 = (ServerChannelMessage_Struct*)pack->pBuffer;
|
||||
strcpy(scm2->deliverto, scm2->from);
|
||||
scm2->noreply = true;
|
||||
client_list.SendPacket(scm->from, pack);
|
||||
safe_delete(pack);
|
||||
}))) && (!scm->noreply))
|
||||
{
|
||||
zoneserver_list.SendEmoteMessage(scm->from, 0, 0, 0, "%s is not online at this time.", scm->to);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
ClientListEntry* cle = client_list.FindCharacter(scm->deliverto);
|
||||
if (cle == 0 || cle->Online() < CLE_Status_Zoning ||
|
||||
(cle->TellsOff() && ((cle->Anon() == 1 && scm->fromadmin < cle->Admin()) || scm->fromadmin < 80))) {
|
||||
@ -462,6 +485,20 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) {
|
||||
cle->Server()->SendPacket(pack);
|
||||
}
|
||||
else {
|
||||
if (scm->chan_num == 5 || scm->chan_num == 6 || scm->chan_num == 11) {
|
||||
if (console) {
|
||||
console->SendChannelMessage(scm, [&scm]() {
|
||||
auto pack = new ServerPacket(ServerOP_ChannelMessage,
|
||||
sizeof(ServerChannelMessage_Struct) + strlen(scm->message) + 1);
|
||||
memcpy(pack->pBuffer, scm, pack->size);
|
||||
ServerChannelMessage_Struct* scm2 = (ServerChannelMessage_Struct*)pack->pBuffer;
|
||||
strcpy(scm2->deliverto, scm2->from);
|
||||
scm2->noreply = true;
|
||||
client_list.SendPacket(scm->from, pack);
|
||||
safe_delete(pack);
|
||||
});
|
||||
}
|
||||
}
|
||||
zoneserver_list.SendPacket(pack);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
#include "../net/servertalk_server.h"
|
||||
#include "../event/timer.h"
|
||||
#include "../timer.h"
|
||||
#include "console.h"
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
|
||||
@ -31,7 +32,7 @@ class ServerPacket;
|
||||
|
||||
class ZoneServer : public WorldTCPConnection {
|
||||
public:
|
||||
ZoneServer(std::shared_ptr<EQ::Net::ServertalkServerConnection> connection);
|
||||
ZoneServer(std::shared_ptr<EQ::Net::ServertalkServerConnection> connection, EQ::Net::ConsoleServer *console);
|
||||
~ZoneServer();
|
||||
virtual inline bool IsZoneServer() { return true; }
|
||||
|
||||
@ -97,6 +98,7 @@ private:
|
||||
uint32 zone_os_process_id;
|
||||
std::string launcher_name; //the launcher which started us
|
||||
std::string launched_name; //the name of the zone we launched.
|
||||
EQ::Net::ConsoleServer *console;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -51,6 +51,7 @@ SET(zone_sources
|
||||
lua_item.cpp
|
||||
lua_iteminst.cpp
|
||||
lua_mob.cpp
|
||||
lua_mod.cpp
|
||||
lua_npc.cpp
|
||||
lua_object.cpp
|
||||
lua_packet.cpp
|
||||
@ -59,6 +60,7 @@ SET(zone_sources
|
||||
lua_raid.cpp
|
||||
lua_spawn.cpp
|
||||
lua_spell.cpp
|
||||
lua_stat_bonuses.cpp
|
||||
embperl.cpp
|
||||
embxs.cpp
|
||||
entity.cpp
|
||||
@ -173,6 +175,7 @@ SET(zone_headers
|
||||
lua_item.h
|
||||
lua_iteminst.h
|
||||
lua_mob.h
|
||||
lua_mod.h
|
||||
lua_npc.h
|
||||
lua_object.h
|
||||
lua_packet.h
|
||||
@ -182,6 +185,7 @@ SET(zone_headers
|
||||
lua_raid.h
|
||||
lua_spawn.h
|
||||
lua_spell.h
|
||||
lua_stat_bonuses.h
|
||||
map.h
|
||||
masterentity.h
|
||||
maxskill.h
|
||||
|
||||
@ -916,7 +916,7 @@ void Client::SendAlternateAdvancementRank(int aa_id, int level) {
|
||||
void Client::SendAlternateAdvancementStats() {
|
||||
auto outapp = new EQApplicationPacket(OP_AAExpUpdate, sizeof(AltAdvStats_Struct));
|
||||
AltAdvStats_Struct *aps = (AltAdvStats_Struct *)outapp->pBuffer;
|
||||
aps->experience = (uint32)(((float)330.0f * (float)m_pp.expAA) / (float)max_AAXP);
|
||||
aps->experience = (uint32)(((float)330.0f * (float)m_pp.expAA) / (float)GetRequiredAAExperience());
|
||||
aps->unspent = m_pp.aapoints;
|
||||
aps->percentage = m_epp.perAA;
|
||||
QueuePacket(outapp);
|
||||
|
||||
@ -31,6 +31,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#include "water_map.h"
|
||||
#include "worldserver.h"
|
||||
#include "zone.h"
|
||||
#include "lua_parser.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
@ -52,8 +53,9 @@ extern WorldServer worldserver;
|
||||
extern EntityList entity_list;
|
||||
extern Zone* zone;
|
||||
|
||||
bool Mob::AttackAnimation(EQEmu::skills::SkillType &skillinuse, int Hand, const EQEmu::ItemInstance* weapon)
|
||||
EQEmu::skills::SkillType Mob::AttackAnimation(int Hand, const EQEmu::ItemInstance* weapon)
|
||||
{
|
||||
EQEmu::skills::SkillType skillinuse = EQEmu::skills::Skill1HBlunt;
|
||||
// Determine animation
|
||||
int type = 0;
|
||||
if (weapon && weapon->IsClassCommon()) {
|
||||
@ -137,7 +139,7 @@ bool Mob::AttackAnimation(EQEmu::skills::SkillType &skillinuse, int Hand, const
|
||||
type = animDualWield;
|
||||
|
||||
DoAnim(type, 0, false);
|
||||
return true;
|
||||
return skillinuse;
|
||||
}
|
||||
|
||||
int Mob::compute_tohit(EQEmu::skills::SkillType skillinuse)
|
||||
@ -271,6 +273,16 @@ int Mob::GetTotalDefense()
|
||||
// and does other mitigation checks. 'this' is the mob being attacked.
|
||||
bool Mob::CheckHitChance(Mob* other, DamageHitInfo &hit)
|
||||
{
|
||||
#ifdef LUA_EQEMU
|
||||
bool lua_ret = false;
|
||||
bool ignoreDefault = false;
|
||||
lua_ret = LuaParser::Instance()->CheckHitChance(this, other, hit, ignoreDefault);
|
||||
|
||||
if(ignoreDefault) {
|
||||
return lua_ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
Mob *attacker = other;
|
||||
Mob *defender = this;
|
||||
Log(Logs::Detail, Logs::Attack, "CheckHitChance(%s) attacked by %s", defender->GetName(), attacker->GetName());
|
||||
@ -301,6 +313,16 @@ bool Mob::CheckHitChance(Mob* other, DamageHitInfo &hit)
|
||||
|
||||
bool Mob::AvoidDamage(Mob *other, DamageHitInfo &hit)
|
||||
{
|
||||
#ifdef LUA_EQEMU
|
||||
bool lua_ret = false;
|
||||
bool ignoreDefault = false;
|
||||
lua_ret = LuaParser::Instance()->AvoidDamage(this, other, hit, ignoreDefault);
|
||||
|
||||
if (ignoreDefault) {
|
||||
return lua_ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* called when a mob is attacked, does the checks to see if it's a hit
|
||||
* and does other mitigation checks. 'this' is the mob being attacked.
|
||||
*
|
||||
@ -871,6 +893,15 @@ double Mob::RollD20(int offense, int mitigation)
|
||||
|
||||
void Mob::MeleeMitigation(Mob *attacker, DamageHitInfo &hit, ExtraAttackOptions *opts)
|
||||
{
|
||||
#ifdef LUA_EQEMU
|
||||
bool ignoreDefault = false;
|
||||
LuaParser::Instance()->MeleeMitigation(this, attacker, hit, opts, ignoreDefault);
|
||||
|
||||
if (ignoreDefault) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (hit.damage_done < 0 || hit.base_damage == 0)
|
||||
return;
|
||||
|
||||
@ -1237,6 +1268,7 @@ void Mob::DoAttack(Mob *other, DamageHitInfo &hit, ExtraAttackOptions *opts)
|
||||
return;
|
||||
Log(Logs::Detail, Logs::Combat, "%s::DoAttack vs %s base %d min %d offense %d tohit %d skill %d", GetName(),
|
||||
other->GetName(), hit.base_damage, hit.min_damage, hit.offense, hit.tohit, hit.skill);
|
||||
|
||||
// check to see if we hit..
|
||||
if (other->AvoidDamage(this, hit)) {
|
||||
int strike_through = itembonuses.StrikeThrough + spellbonuses.StrikeThrough + aabonuses.StrikeThrough;
|
||||
@ -1331,7 +1363,7 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
|
||||
DamageHitInfo my_hit;
|
||||
// calculate attack_skill and skillinuse depending on hand and weapon
|
||||
// also send Packet to near clients
|
||||
AttackAnimation(my_hit.skill, Hand, weapon);
|
||||
my_hit.skill = AttackAnimation(Hand, weapon);
|
||||
Log(Logs::Detail, Logs::Combat, "Attacking with %s in slot %d using skill %d", weapon ? weapon->GetItem()->Name : "Fist", Hand, my_hit.skill);
|
||||
|
||||
// Now figure out damage
|
||||
@ -1892,7 +1924,7 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
|
||||
//do attack animation regardless of whether or not we can hit below
|
||||
int16 charges = 0;
|
||||
EQEmu::ItemInstance weapon_inst(weapon, charges);
|
||||
AttackAnimation(my_hit.skill, Hand, &weapon_inst);
|
||||
my_hit.skill = AttackAnimation(Hand, &weapon_inst);
|
||||
|
||||
//basically "if not immune" then do the attack
|
||||
if (weapon_damage > 0) {
|
||||
@ -2190,7 +2222,7 @@ bool NPC::Death(Mob* killer_mob, int32 damage, uint16 spell, EQEmu::skills::Skil
|
||||
Group *kg = entity_list.GetGroupByClient(give_exp_client);
|
||||
Raid *kr = entity_list.GetRaidByClient(give_exp_client);
|
||||
|
||||
int32 finalxp = EXP_FORMULA;
|
||||
int32 finalxp = give_exp_client->GetExperienceForKill(this);
|
||||
finalxp = give_exp_client->mod_client_xp(finalxp, this);
|
||||
|
||||
if (kr) {
|
||||
@ -2801,6 +2833,8 @@ uint8 Mob::GetWeaponDamageBonus(const EQEmu::ItemData *weapon, bool offhand)
|
||||
}
|
||||
return damage_bonus;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Mob::GetHandToHandDamage(void)
|
||||
@ -4064,7 +4098,7 @@ void Mob::TryPetCriticalHit(Mob *defender, DamageHitInfo &hit)
|
||||
|
||||
if (critChance > 0) {
|
||||
if (zone->random.Roll(critChance)) {
|
||||
critMod += GetCritDmgMob(hit.skill);
|
||||
critMod += GetCritDmgMod(hit.skill);
|
||||
hit.damage_done += 5;
|
||||
hit.damage_done = (hit.damage_done * critMod) / 100;
|
||||
|
||||
@ -4085,6 +4119,15 @@ void Mob::TryPetCriticalHit(Mob *defender, DamageHitInfo &hit)
|
||||
|
||||
void Mob::TryCriticalHit(Mob *defender, DamageHitInfo &hit, ExtraAttackOptions *opts)
|
||||
{
|
||||
#ifdef LUA_EQEMU
|
||||
bool ignoreDefault = false;
|
||||
LuaParser::Instance()->TryCriticalHit(this, defender, hit, opts, ignoreDefault);
|
||||
|
||||
if (ignoreDefault) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (hit.damage_done < 1 || !defender)
|
||||
return;
|
||||
|
||||
@ -4193,7 +4236,11 @@ void Mob::TryCriticalHit(Mob *defender, DamageHitInfo &hit, ExtraAttackOptions *
|
||||
// step 2: calculate damage
|
||||
hit.damage_done = std::max(hit.damage_done, hit.base_damage) + 5;
|
||||
int og_damage = hit.damage_done;
|
||||
int crit_mod = 170 + GetCritDmgMob(hit.skill);
|
||||
int crit_mod = 170 + GetCritDmgMod(hit.skill);
|
||||
if (crit_mod < 100) {
|
||||
crit_mod = 100;
|
||||
}
|
||||
|
||||
hit.damage_done = hit.damage_done * crit_mod / 100;
|
||||
Log(Logs::Detail, Logs::Combat,
|
||||
"Crit success roll %d dex chance %d og dmg %d crit_mod %d new dmg %d", roll, dex_bonus,
|
||||
@ -4254,7 +4301,7 @@ void Mob::TryCriticalHit(Mob *defender, DamageHitInfo &hit, ExtraAttackOptions *
|
||||
// Crippling blows also have a chance to stun
|
||||
// Kayen: Crippling Blow would cause a chance to interrupt for npcs < 55, with a
|
||||
// staggers message.
|
||||
if (defender->GetLevel() <= 55 && !defender->GetSpecialAbility(IMMUNE_STUN)) {
|
||||
if (defender->GetLevel() <= 55 && !defender->GetSpecialAbility(UNSTUNABLE)) {
|
||||
defender->Emote("staggers.");
|
||||
defender->Stun(2000);
|
||||
}
|
||||
@ -4535,6 +4582,15 @@ const DamageTable &Mob::GetDamageTable() const
|
||||
|
||||
void Mob::ApplyDamageTable(DamageHitInfo &hit)
|
||||
{
|
||||
#ifdef LUA_EQEMU
|
||||
bool ignoreDefault = false;
|
||||
LuaParser::Instance()->ApplyDamageTable(this, hit, ignoreDefault);
|
||||
|
||||
if (ignoreDefault) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// someone may want to add this to custom servers, can remove this if that's the case
|
||||
if (!IsClient()
|
||||
#ifdef BOTS
|
||||
@ -4870,6 +4926,15 @@ void Mob::CommonOutgoingHitSuccess(Mob* defender, DamageHitInfo &hit, ExtraAttac
|
||||
if (!defender)
|
||||
return;
|
||||
|
||||
#ifdef LUA_EQEMU
|
||||
bool ignoreDefault = false;
|
||||
LuaParser::Instance()->CommonOutgoingHitSuccess(this, defender, hit, opts, ignoreDefault);
|
||||
|
||||
if (ignoreDefault) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// BER weren't parsing the halving
|
||||
if (hit.skill == EQEmu::skills::SkillArchery ||
|
||||
(hit.skill == EQEmu::skills::SkillThrowing && GetClass() != BERSERKER))
|
||||
|
||||
@ -1084,9 +1084,9 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
|
||||
break;
|
||||
// base1 = effect value, base2 = skill restrictions(-1 for all)
|
||||
if (base2 == ALL_SKILLS)
|
||||
newbon->CritDmgMob[EQEmu::skills::HIGHEST_SKILL + 1] += base1;
|
||||
newbon->CritDmgMod[EQEmu::skills::HIGHEST_SKILL + 1] += base1;
|
||||
else
|
||||
newbon->CritDmgMob[base2] += base1;
|
||||
newbon->CritDmgMod[base2] += base1;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2441,9 +2441,9 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
|
||||
if (base2 > EQEmu::skills::HIGHEST_SKILL)
|
||||
break;
|
||||
if(base2 == ALL_SKILLS)
|
||||
new_bonus->CritDmgMob[EQEmu::skills::HIGHEST_SKILL + 1] += effect_value;
|
||||
new_bonus->CritDmgMod[EQEmu::skills::HIGHEST_SKILL + 1] += effect_value;
|
||||
else
|
||||
new_bonus->CritDmgMob[base2] += effect_value;
|
||||
new_bonus->CritDmgMod[base2] += effect_value;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -4203,9 +4203,9 @@ void Mob::NegateSpellsBonuses(uint16 spell_id)
|
||||
{
|
||||
for (int e = 0; e < EQEmu::skills::HIGHEST_SKILL + 1; e++)
|
||||
{
|
||||
spellbonuses.CritDmgMob[e] = effect_value;
|
||||
aabonuses.CritDmgMob[e] = effect_value;
|
||||
itembonuses.CritDmgMob[e] = effect_value;
|
||||
spellbonuses.CritDmgMod[e] = effect_value;
|
||||
aabonuses.CritDmgMod[e] = effect_value;
|
||||
itembonuses.CritDmgMod[e] = effect_value;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
#include "object.h"
|
||||
#include "doors.h"
|
||||
#include "quest_parser_collection.h"
|
||||
#include "lua_parser.h"
|
||||
#include "../common/string_util.h"
|
||||
#include "../common/say_link.h"
|
||||
|
||||
@ -3856,7 +3857,7 @@ void Bot::AddToHateList(Mob* other, uint32 hate, int32 damage, bool iYellForHelp
|
||||
Mob::AddToHateList(other, hate, damage, iYellForHelp, bFrenzy, iBuffTic, pet_command);
|
||||
}
|
||||
|
||||
bool Bot::Attack(Mob* other, int Hand, bool FromRiposte, bool IsStrikethrough, bool IsFromSpell, ExtraAttackOptions *opts) {
|
||||
bool Bot::Attack(Mob* other, int Hand, bool FromRiposte, bool IsStrikethrough, bool IsFromSpell, ExtraAttackOptions *opts) {
|
||||
if (!other) {
|
||||
SetTarget(nullptr);
|
||||
Log(Logs::General, Logs::Error, "A null Mob object was passed to Bot::Attack for evaluation!");
|
||||
@ -3919,7 +3920,7 @@ bool Bot::Attack(Mob* other, int Hand, bool FromRiposte, bool IsStrikethrough, b
|
||||
// calculate attack_skill and skillinuse depending on hand and weapon
|
||||
// also send Packet to near clients
|
||||
DamageHitInfo my_hit;
|
||||
AttackAnimation(my_hit.skill, Hand, weapon);
|
||||
my_hit.skill = AttackAnimation(Hand, weapon);
|
||||
Log(Logs::Detail, Logs::Combat, "Attacking with %s in slot %d using skill %d", weapon?weapon->GetItem()->Name:"Fist", Hand, my_hit.skill);
|
||||
|
||||
// Now figure out damage
|
||||
|
||||
@ -1255,6 +1255,37 @@ void Client::Message(uint32 type, const char* message, ...) {
|
||||
safe_delete_array(buffer);
|
||||
}
|
||||
|
||||
void Client::FilteredMessage(Mob *sender, uint32 type, eqFilterType filter, const char* message, ...) {
|
||||
if (!FilteredMessageCheck(sender, filter))
|
||||
return;
|
||||
|
||||
va_list argptr;
|
||||
auto buffer = new char[4096];
|
||||
va_start(argptr, message);
|
||||
vsnprintf(buffer, 4096, message, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
size_t len = strlen(buffer);
|
||||
|
||||
//client dosent like our packet all the time unless
|
||||
//we make it really big, then it seems to not care that
|
||||
//our header is malformed.
|
||||
//len = 4096 - sizeof(SpecialMesg_Struct);
|
||||
|
||||
uint32 len_packet = sizeof(SpecialMesg_Struct) + len;
|
||||
auto app = new EQApplicationPacket(OP_SpecialMesg, len_packet);
|
||||
SpecialMesg_Struct* sm = (SpecialMesg_Struct*)app->pBuffer;
|
||||
sm->header[0] = 0x00; // Header used for #emote style messages..
|
||||
sm->header[1] = 0x00; // Play around with these to see other types
|
||||
sm->header[2] = 0x00;
|
||||
sm->msg_type = type;
|
||||
memcpy(sm->message, buffer, len + 1);
|
||||
|
||||
FastQueuePacket(&app);
|
||||
|
||||
safe_delete_array(buffer);
|
||||
}
|
||||
|
||||
void Client::QuestJournalledMessage(const char *npcname, const char* message) {
|
||||
|
||||
// npcnames longer than 60 characters crash the client when they log back in
|
||||
|
||||
@ -308,6 +308,7 @@ public:
|
||||
void ChannelMessageSend(const char* from, const char* to, uint8 chan_num, uint8 language, const char* message, ...);
|
||||
void ChannelMessageSend(const char* from, const char* to, uint8 chan_num, uint8 language, uint8 lang_skill, const char* message, ...);
|
||||
void Message(uint32 type, const char* message, ...);
|
||||
void FilteredMessage(Mob *sender, uint32 type, eqFilterType filter, const char* message, ...);
|
||||
void QuestJournalledMessage(const char *npcname, const char* message);
|
||||
void VoiceMacroReceived(uint32 Type, char *Target, uint32 MacroNumber);
|
||||
void SendSound();
|
||||
@ -570,6 +571,7 @@ public:
|
||||
void AddCrystals(uint32 Radiant, uint32 Ebon);
|
||||
void SendCrystalCounts();
|
||||
|
||||
uint32 GetExperienceForKill(Mob *against);
|
||||
void AddEXP(uint32 in_add_exp, uint8 conlevel = 0xFF, bool resexp = false);
|
||||
uint32 CalcEXP(uint8 conlevel = 0xFF);
|
||||
void SetEXP(uint32 set_exp, uint32 set_aaxp, bool resexp=false);
|
||||
@ -795,12 +797,12 @@ public:
|
||||
void AddAAPoints(uint32 points) { m_pp.aapoints += points; SendAlternateAdvancementStats(); }
|
||||
int GetAAPoints() { return m_pp.aapoints; }
|
||||
int GetSpentAA() { return m_pp.aapoints_spent; }
|
||||
uint32 GetRequiredAAExperience();
|
||||
|
||||
//old AA methods that we still use
|
||||
void ResetAA();
|
||||
void RefundAA();
|
||||
void SendClearAA();
|
||||
inline uint32 GetMaxAAXP(void) const { return max_AAXP; }
|
||||
inline uint32 GetAAXP() const { return m_pp.expAA; }
|
||||
inline uint32 GetAAPercent() const { return m_epp.perAA; }
|
||||
int16 CalcAAFocus(focusType type, const AA::Rank &rank, uint16 spell_id);
|
||||
@ -1261,6 +1263,8 @@ public:
|
||||
|
||||
void CheckRegionTypeChanges();
|
||||
|
||||
int32 CalcATK();
|
||||
|
||||
protected:
|
||||
friend class Mob;
|
||||
void CalcItemBonuses(StatBonuses* newbon);
|
||||
@ -1320,7 +1324,6 @@ private:
|
||||
|
||||
void HandleTraderPriceUpdate(const EQApplicationPacket *app);
|
||||
|
||||
int32 CalcATK();
|
||||
int32 CalcItemATKCap();
|
||||
int32 CalcHaste();
|
||||
|
||||
@ -1491,7 +1494,6 @@ private:
|
||||
|
||||
uint32 tribute_master_id;
|
||||
|
||||
uint32 max_AAXP;
|
||||
bool npcflag;
|
||||
uint8 npclevel;
|
||||
bool feigned;
|
||||
|
||||
@ -1355,8 +1355,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
||||
|
||||
/* Set Total Seconds Played */
|
||||
TotalSecondsPlayed = m_pp.timePlayedMin * 60;
|
||||
/* Set Max AA XP */
|
||||
max_AAXP = RuleI(AA, ExpPerPoint);
|
||||
|
||||
/* If we can maintain intoxication across zones, check for it */
|
||||
if (!RuleB(Character, MaintainIntoxicationAcrossZones))
|
||||
m_pp.intoxication = 0;
|
||||
|
||||
@ -408,7 +408,7 @@ struct StatBonuses {
|
||||
uint32 SpellTriggers[MAX_SPELL_TRIGGER]; // Innate/Spell/Item Spells that trigger when you cast
|
||||
uint32 SpellOnKill[MAX_SPELL_TRIGGER*3]; // Chance to proc after killing a mob
|
||||
uint32 SpellOnDeath[MAX_SPELL_TRIGGER*2]; // Chance to have effect cast when you die
|
||||
int32 CritDmgMob[EQEmu::skills::HIGHEST_SKILL + 2]; // All Skills + -1
|
||||
int32 CritDmgMod[EQEmu::skills::HIGHEST_SKILL + 2]; // All Skills + -1
|
||||
int32 SkillReuseTime[EQEmu::skills::HIGHEST_SKILL + 1]; // Reduces skill timers
|
||||
int32 SkillDamageAmount[EQEmu::skills::HIGHEST_SKILL + 2]; // All Skills + -1
|
||||
int32 TwoHandBluntBlock; // chance to block when wielding two hand blunt weapon
|
||||
|
||||
@ -2135,6 +2135,25 @@ void EntityList::MessageClose(Mob* sender, bool skipsender, float dist, uint32 t
|
||||
}
|
||||
}
|
||||
|
||||
void EntityList::FilteredMessageClose(Mob *sender, bool skipsender, float dist, uint32 type, eqFilterType filter, const char *message, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
char buffer[4096];
|
||||
|
||||
va_start(argptr, message);
|
||||
vsnprintf(buffer, 4095, message, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
float dist2 = dist * dist;
|
||||
|
||||
auto it = client_list.begin();
|
||||
while (it != client_list.end()) {
|
||||
if (DistanceSquared(it->second->GetPosition(), sender->GetPosition()) <= dist2 && (!skipsender || it->second != sender))
|
||||
it->second->FilteredMessage(sender, type, filter, buffer);
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
void EntityList::RemoveAllMobs()
|
||||
{
|
||||
auto it = mob_list.begin();
|
||||
|
||||
@ -79,6 +79,7 @@ public:
|
||||
virtual bool IsTrap() const { return false; }
|
||||
virtual bool IsBeacon() const { return false; }
|
||||
virtual bool IsEncounter() const { return false; }
|
||||
virtual bool IsBot() const { return false; }
|
||||
|
||||
virtual bool Process() { return false; }
|
||||
virtual bool Save() { return true; }
|
||||
@ -113,7 +114,6 @@ public:
|
||||
bool CheckCoordLosNoZLeaps(float cur_x, float cur_y, float cur_z, float trg_x, float trg_y, float trg_z, float perwalk=1);
|
||||
|
||||
#ifdef BOTS
|
||||
virtual bool IsBot() const { return false; }
|
||||
Bot* CastToBot();
|
||||
#endif
|
||||
|
||||
@ -315,6 +315,7 @@ public:
|
||||
void Message(uint32 to_guilddbid, uint32 type, const char* message, ...);
|
||||
void MessageStatus(uint32 to_guilddbid, int to_minstatus, uint32 type, const char* message, ...);
|
||||
void MessageClose(Mob* sender, bool skipsender, float dist, uint32 type, const char* message, ...);
|
||||
void FilteredMessageClose(Mob* sender, bool skipsender, float dist, uint32 type, eqFilterType filter, const char* message, ...);
|
||||
void Message_StringID(Mob *sender, bool skipsender, uint32 type, uint32 string_id, const char* message1=0,const char* message2=0,const char* message3=0,const char* message4=0,const char* message5=0,const char* message6=0,const char* message7=0,const char* message8=0,const char* message9=0);
|
||||
void FilteredMessage_StringID(Mob *sender, bool skipsender, uint32 type, eqFilterType filter, uint32 string_id, const char* message1=0,const char* message2=0,const char* message3=0,const char* message4=0,const char* message5=0,const char* message6=0,const char* message7=0,const char* message8=0,const char* message9=0);
|
||||
void MessageClose_StringID(Mob *sender, bool skipsender, float dist, uint32 type, uint32 string_id, const char* message1=0,const char* message2=0,const char* message3=0,const char* message4=0,const char* message5=0,const char* message6=0,const char* message7=0,const char* message8=0,const char* message9=0);
|
||||
|
||||
66
zone/exp.cpp
66
zone/exp.cpp
@ -28,6 +28,7 @@
|
||||
|
||||
#include "queryserv.h"
|
||||
#include "quest_parser_collection.h"
|
||||
#include "lua_parser.h"
|
||||
#include "string_ids.h"
|
||||
|
||||
#ifdef BOTS
|
||||
@ -153,6 +154,26 @@ uint32 Client::CalcEXP(uint8 conlevel) {
|
||||
return in_add_exp;
|
||||
}
|
||||
|
||||
uint32 Client::GetExperienceForKill(Mob *against)
|
||||
{
|
||||
#ifdef LUA_EQEMU
|
||||
uint32 lua_ret = 0;
|
||||
bool ignoreDefault = false;
|
||||
lua_ret = LuaParser::Instance()->GetExperienceForKill(this, against, ignoreDefault);
|
||||
|
||||
if (ignoreDefault) {
|
||||
return lua_ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (against && against->IsNPC()) {
|
||||
uint32 level = (uint32)against->GetLevel();
|
||||
return EXP_FORMULA;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Client::AddEXP(uint32 in_add_exp, uint8 conlevel, bool resexp) {
|
||||
|
||||
this->EVENT_ITEM_ScriptStopReturn();
|
||||
@ -339,8 +360,8 @@ void Client::AddEXP(uint32 in_add_exp, uint8 conlevel, bool resexp) {
|
||||
|
||||
void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) {
|
||||
Log(Logs::Detail, Logs::None, "Attempting to Set Exp for %s (XP: %u, AAXP: %u, Rez: %s)", this->GetCleanName(), set_exp, set_aaxp, isrezzexp ? "true" : "false");
|
||||
//max_AAXP = GetEXPForLevel(52) - GetEXPForLevel(51); //GetEXPForLevel() doesn't depend on class/race, just level, so it shouldn't change between Clients
|
||||
max_AAXP = RuleI(AA, ExpPerPoint); //this may be redundant since we're doing this in Client::FinishConnState2()
|
||||
|
||||
auto max_AAXP = GetRequiredAAExperience();
|
||||
if (max_AAXP == 0 || GetEXPForLevel(GetLevel()) == 0xFFFFFFFF) {
|
||||
Message(13, "Error in Client::SetEXP. EXP not set.");
|
||||
return; // Must be invalid class/race
|
||||
@ -377,19 +398,23 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) {
|
||||
}
|
||||
|
||||
if (isrezzexp) {
|
||||
if (RuleI(Character, ShowExpValues) > 0) Message(MT_Experience, "You regain %s experience from resurrection. %s", exp_amount_message.c_str(), exp_percent_message.c_str());
|
||||
if (RuleI(Character, ShowExpValues) > 0)
|
||||
Message(MT_Experience, "You regain %s experience from resurrection. %s", exp_amount_message.c_str(), exp_percent_message.c_str());
|
||||
else Message_StringID(MT_Experience, REZ_REGAIN);
|
||||
} else {
|
||||
if (membercount > 1) {
|
||||
if (RuleI(Character, ShowExpValues) > 0) Message(MT_Experience, "You have gained %s party experience! %s", exp_amount_message.c_str(), exp_percent_message.c_str());
|
||||
if (RuleI(Character, ShowExpValues) > 0)
|
||||
Message(MT_Experience, "You have gained %s party experience! %s", exp_amount_message.c_str(), exp_percent_message.c_str());
|
||||
else Message_StringID(MT_Experience, GAIN_GROUPXP);
|
||||
}
|
||||
else if (IsRaidGrouped()) {
|
||||
if (RuleI(Character, ShowExpValues) > 0) Message(MT_Experience, "You have gained %s raid experience! %s", exp_amount_message.c_str(), exp_percent_message.c_str());
|
||||
if (RuleI(Character, ShowExpValues) > 0)
|
||||
Message(MT_Experience, "You have gained %s raid experience! %s", exp_amount_message.c_str(), exp_percent_message.c_str());
|
||||
else Message_StringID(MT_Experience, GAIN_RAIDEXP);
|
||||
}
|
||||
else {
|
||||
if (RuleI(Character, ShowExpValues) > 0) Message(MT_Experience, "You have gained %s experience! %s", exp_amount_message.c_str(), exp_percent_message.c_str());
|
||||
if (RuleI(Character, ShowExpValues) > 0)
|
||||
Message(MT_Experience, "You have gained %s experience! %s", exp_amount_message.c_str(), exp_percent_message.c_str());
|
||||
else Message_StringID(MT_Experience, GAIN_XP);
|
||||
}
|
||||
}
|
||||
@ -460,14 +485,13 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) {
|
||||
|
||||
//add in how many points we had
|
||||
m_pp.aapoints += last_unspentAA;
|
||||
//set_aaxp = m_pp.expAA % max_AAXP;
|
||||
|
||||
//figure out how many points were actually gained
|
||||
/*uint32 gained = m_pp.aapoints - last_unspentAA;*/ //unused
|
||||
|
||||
//Message(15, "You have gained %d skill points!!", m_pp.aapoints - last_unspentAA);
|
||||
char val1[20]={0};
|
||||
Message_StringID(MT_Experience, GAIN_ABILITY_POINT,ConvertArray(m_pp.aapoints, val1),m_pp.aapoints == 1 ? "" : "(s)"); //You have gained an ability point! You now have %1 ability point%2.
|
||||
Message_StringID(MT_Experience, GAIN_ABILITY_POINT, ConvertArray(m_pp.aapoints, val1),m_pp.aapoints == 1 ? "" : "(s)"); //You have gained an ability point! You now have %1 ability point%2.
|
||||
|
||||
/* QS: PlayerLogAARate */
|
||||
if (RuleB(QueryServ, PlayerLogAARate)){
|
||||
@ -571,8 +595,7 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) {
|
||||
char val1[20]={0};
|
||||
char val2[20]={0};
|
||||
char val3[20]={0};
|
||||
Message_StringID(MT_Experience, GM_GAINXP,ConvertArray(set_aaxp,val1),ConvertArray(set_exp,val2),ConvertArray(GetEXPForLevel(GetLevel()+1),val3)); //[GM] You have gained %1 AXP and %2 EXP (%3).
|
||||
//Message(15, "[GM] You now have %d / %d EXP and %d / %d AA exp.", set_exp, GetEXPForLevel(GetLevel()+1), set_aaxp, max_AAXP);
|
||||
Message_StringID(MT_Experience, GM_GAINXP, ConvertArray(set_aaxp,val1),ConvertArray(set_exp,val2),ConvertArray(GetEXPForLevel(GetLevel()+1),val3)); //[GM] You have gained %1 AXP and %2 EXP (%3).
|
||||
}
|
||||
}
|
||||
|
||||
@ -664,6 +687,15 @@ void Client::SetLevel(uint8 set_level, bool command)
|
||||
// Add: You can set the values you want now, client will be always sync :) - Merkur
|
||||
uint32 Client::GetEXPForLevel(uint16 check_level)
|
||||
{
|
||||
#ifdef LUA_EQEMU
|
||||
uint32 lua_ret = 0;
|
||||
bool ignoreDefault = false;
|
||||
lua_ret = LuaParser::Instance()->GetEXPForLevel(this, check_level, ignoreDefault);
|
||||
|
||||
if (ignoreDefault) {
|
||||
return lua_ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
uint16 check_levelm1 = check_level-1;
|
||||
float mod;
|
||||
@ -933,3 +965,17 @@ uint32 Client::GetCharMaxLevelFromQGlobal() {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 Client::GetRequiredAAExperience() {
|
||||
#ifdef LUA_EQEMU
|
||||
uint32 lua_ret = 0;
|
||||
bool ignoreDefault = false;
|
||||
lua_ret = LuaParser::Instance()->GetRequiredAAExperience(this, ignoreDefault);
|
||||
|
||||
if (ignoreDefault) {
|
||||
return lua_ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
return RuleI(AA, ExpPerPoint);
|
||||
}
|
||||
|
||||
@ -1172,6 +1172,11 @@ uint64 Lua_Client::GetAllMoney() {
|
||||
return self->GetAllMoney();
|
||||
}
|
||||
|
||||
uint32 Lua_Client::GetMoney(uint8 type, uint8 subtype) {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetMoney(type, subtype);
|
||||
}
|
||||
|
||||
void Lua_Client::OpenLFGuildWindow() {
|
||||
Lua_Safe_Call_Void();
|
||||
self->OpenLFGuildWindow();
|
||||
@ -1414,9 +1419,25 @@ void Lua_Client::QuestReward(Lua_Mob target, luabind::adl::object reward) {
|
||||
self->QuestReward(target, copper, silver, gold, platinum, itemid, exp, faction);
|
||||
}
|
||||
|
||||
uint32 Lua_Client::GetMoney(uint8 type, uint8 subtype) {
|
||||
bool Lua_Client::IsDead() {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->IsDead();
|
||||
}
|
||||
|
||||
int Lua_Client::CalcCurrentWeight() {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetMoney(type, subtype);
|
||||
return self->CalcCurrentWeight();
|
||||
}
|
||||
|
||||
int Lua_Client::CalcATK() {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->CalcATK();
|
||||
}
|
||||
|
||||
void Lua_Client::FilteredMessage(Mob *sender, uint32 type, int filter, const char *message)
|
||||
{
|
||||
Lua_Safe_Call_Void();
|
||||
self->FilteredMessage(sender, type, (eqFilterType)filter, message);
|
||||
}
|
||||
|
||||
luabind::scope lua_register_client() {
|
||||
@ -1653,6 +1674,7 @@ luabind::scope lua_register_client() {
|
||||
.def("GetAggroCount", (int(Lua_Client::*)(void))&Lua_Client::GetAggroCount)
|
||||
.def("GetCarriedMoney", (uint64(Lua_Client::*)(void))&Lua_Client::GetCarriedMoney)
|
||||
.def("GetAllMoney", (uint64(Lua_Client::*)(void))&Lua_Client::GetAllMoney)
|
||||
.def("GetMoney", (uint32(Lua_Client::*)(uint8, uint8))&Lua_Client::GetMoney)
|
||||
.def("OpenLFGuildWindow", (void(Lua_Client::*)(void))&Lua_Client::OpenLFGuildWindow)
|
||||
.def("Signal", (void(Lua_Client::*)(uint32))&Lua_Client::Signal)
|
||||
.def("AddAlternateCurrencyValue", (void(Lua_Client::*)(uint32,int))&Lua_Client::AddAlternateCurrencyValue)
|
||||
@ -1687,7 +1709,10 @@ luabind::scope lua_register_client() {
|
||||
.def("QuestReward", (void(Lua_Client::*)(Lua_Mob, uint32, uint32, uint32, uint32, uint32, uint32))&Lua_Client::QuestReward)
|
||||
.def("QuestReward", (void(Lua_Client::*)(Lua_Mob, uint32, uint32, uint32, uint32, uint32, uint32, bool))&Lua_Client::QuestReward)
|
||||
.def("QuestReward", (void(Lua_Client::*)(Lua_Mob, luabind::adl::object))&Lua_Client::QuestReward)
|
||||
.def("GetMoney", (uint32(Lua_Client::*)(uint8, uint8))&Lua_Client::GetMoney);
|
||||
.def("IsDead", &Lua_Client::IsDead)
|
||||
.def("CalcCurrentWeight", &Lua_Client::CalcCurrentWeight)
|
||||
.def("CalcATK", &Lua_Client::CalcATK)
|
||||
.def("FilteredMessage", &Lua_Client::FilteredMessage);
|
||||
}
|
||||
|
||||
luabind::scope lua_register_inventory_where() {
|
||||
|
||||
@ -297,6 +297,10 @@ public:
|
||||
void QuestReward(Lua_Mob target, uint32 copper, uint32 silver, uint32 gold, uint32 platinum, uint32 itemid, uint32 exp);
|
||||
void QuestReward(Lua_Mob target, uint32 copper, uint32 silver, uint32 gold, uint32 platinum, uint32 itemid, uint32 exp, bool faction);
|
||||
void QuestReward(Lua_Mob target, luabind::adl::object reward);
|
||||
bool IsDead();
|
||||
int CalcCurrentWeight();
|
||||
int CalcATK();
|
||||
void FilteredMessage(Mob *sender, uint32 type, int filter, const char* message);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -67,6 +67,16 @@ bool Lua_Entity::IsBeacon() {
|
||||
return self->IsBeacon();
|
||||
}
|
||||
|
||||
bool Lua_Entity::IsEncounter() {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->IsEncounter();
|
||||
}
|
||||
|
||||
bool Lua_Entity::IsBot() {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->IsBot();
|
||||
}
|
||||
|
||||
int Lua_Entity::GetID() {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->GetID();
|
||||
@ -124,6 +134,8 @@ luabind::scope lua_register_entity() {
|
||||
.def("IsDoor", &Lua_Entity::IsDoor)
|
||||
.def("IsTrap", &Lua_Entity::IsTrap)
|
||||
.def("IsBeacon", &Lua_Entity::IsBeacon)
|
||||
.def("IsEncounter", &Lua_Entity::IsEncounter)
|
||||
.def("IsBot", &Lua_Entity::IsBot)
|
||||
.def("GetID", &Lua_Entity::GetID)
|
||||
.def("CastToClient", &Lua_Entity::CastToClient)
|
||||
.def("CastToNPC", &Lua_Entity::CastToNPC)
|
||||
|
||||
@ -44,6 +44,8 @@ public:
|
||||
bool IsDoor();
|
||||
bool IsTrap();
|
||||
bool IsBeacon();
|
||||
bool IsEncounter();
|
||||
bool IsBot();
|
||||
int GetID();
|
||||
|
||||
Lua_Client CastToClient();
|
||||
|
||||
@ -210,6 +210,12 @@ void Lua_EntityList::MessageClose(Lua_Mob sender, bool skip_sender, float dist,
|
||||
self->MessageClose(sender, skip_sender, dist, type, message);
|
||||
}
|
||||
|
||||
void Lua_EntityList::FilteredMessageClose(Lua_Mob sender, bool skip_sender, float dist, uint32 type, int filter, const char *message)
|
||||
{
|
||||
Lua_Safe_Call_Void();
|
||||
self->FilteredMessageClose(sender, skip_sender, dist, type, (eqFilterType)filter, message);
|
||||
}
|
||||
|
||||
void Lua_EntityList::RemoveFromTargets(Lua_Mob mob) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->RemoveFromTargets(mob);
|
||||
@ -450,16 +456,17 @@ luabind::scope lua_register_entity_list() {
|
||||
.def("GetSpawnByID", (Lua_Spawn(Lua_EntityList::*)(uint32))&Lua_EntityList::GetSpawnByID)
|
||||
.def("ClearClientPetitionQueue", (void(Lua_EntityList::*)(void))&Lua_EntityList::ClearClientPetitionQueue)
|
||||
.def("CanAddHateForMob", (bool(Lua_EntityList::*)(Lua_Mob))&Lua_EntityList::CanAddHateForMob)
|
||||
.def("Message", (void(Lua_EntityList::*)(uint32,uint32,const char*))&Lua_EntityList::Message)
|
||||
.def("MessageStatus", (void(Lua_EntityList::*)(uint32,uint32,uint32,const char*))&Lua_EntityList::MessageStatus)
|
||||
.def("MessageClose", (void(Lua_EntityList::*)(Lua_Mob,bool,float,uint32,const char*))&Lua_EntityList::MessageClose)
|
||||
.def("Message", (void(Lua_EntityList::*)(uint32, uint32, const char*))&Lua_EntityList::Message)
|
||||
.def("MessageStatus", (void(Lua_EntityList::*)(uint32, uint32, uint32, const char*))&Lua_EntityList::MessageStatus)
|
||||
.def("MessageClose", (void(Lua_EntityList::*)(Lua_Mob, bool, float, uint32, const char*))&Lua_EntityList::MessageClose)
|
||||
.def("FilteredMessageClose", &Lua_EntityList::FilteredMessageClose)
|
||||
.def("RemoveFromTargets", (void(Lua_EntityList::*)(Lua_Mob))&Lua_EntityList::RemoveFromTargets)
|
||||
.def("RemoveFromTargets", (void(Lua_EntityList::*)(Lua_Mob,bool))&Lua_EntityList::RemoveFromTargets)
|
||||
.def("ReplaceWithTarget", (void(Lua_EntityList::*)(Lua_Mob,Lua_Mob))&Lua_EntityList::ReplaceWithTarget)
|
||||
.def("RemoveFromTargets", (void(Lua_EntityList::*)(Lua_Mob, bool))&Lua_EntityList::RemoveFromTargets)
|
||||
.def("ReplaceWithTarget", (void(Lua_EntityList::*)(Lua_Mob, Lua_Mob))&Lua_EntityList::ReplaceWithTarget)
|
||||
.def("OpenDoorsNear", (void(Lua_EntityList::*)(Lua_NPC))&Lua_EntityList::OpenDoorsNear)
|
||||
.def("MakeNameUnique", (std::string(Lua_EntityList::*)(const char*))&Lua_EntityList::MakeNameUnique)
|
||||
.def("RemoveNumbers", (std::string(Lua_EntityList::*)(const char*))&Lua_EntityList::RemoveNumbers)
|
||||
.def("SignalMobsByNPCID", (void(Lua_EntityList::*)(uint32,int))&Lua_EntityList::SignalMobsByNPCID)
|
||||
.def("SignalMobsByNPCID", (void(Lua_EntityList::*)(uint32, int))&Lua_EntityList::SignalMobsByNPCID)
|
||||
.def("DeleteNPCCorpses", (int(Lua_EntityList::*)(void))&Lua_EntityList::DeleteNPCCorpses)
|
||||
.def("DeletePlayerCorpses", (int(Lua_EntityList::*)(void))&Lua_EntityList::DeletePlayerCorpses)
|
||||
.def("HalveAggro", (void(Lua_EntityList::*)(Lua_Mob))&Lua_EntityList::HalveAggro)
|
||||
@ -467,10 +474,10 @@ luabind::scope lua_register_entity_list() {
|
||||
.def("ClearFeignAggro", (void(Lua_EntityList::*)(Lua_Mob))&Lua_EntityList::ClearFeignAggro)
|
||||
.def("Fighting", (bool(Lua_EntityList::*)(Lua_Mob))&Lua_EntityList::Fighting)
|
||||
.def("RemoveFromHateLists", (void(Lua_EntityList::*)(Lua_Mob))&Lua_EntityList::RemoveFromHateLists)
|
||||
.def("RemoveFromHateLists", (void(Lua_EntityList::*)(Lua_Mob,bool))&Lua_EntityList::RemoveFromHateLists)
|
||||
.def("MessageGroup", (void(Lua_EntityList::*)(Lua_Mob,bool,uint32,const char*))&Lua_EntityList::MessageGroup)
|
||||
.def("GetRandomClient", (Lua_Client(Lua_EntityList::*)(float,float,float,float))&Lua_EntityList::GetRandomClient)
|
||||
.def("GetRandomClient", (Lua_Client(Lua_EntityList::*)(float,float,float,float,Lua_Client))&Lua_EntityList::GetRandomClient)
|
||||
.def("RemoveFromHateLists", (void(Lua_EntityList::*)(Lua_Mob, bool))&Lua_EntityList::RemoveFromHateLists)
|
||||
.def("MessageGroup", (void(Lua_EntityList::*)(Lua_Mob, bool, uint32, const char*))&Lua_EntityList::MessageGroup)
|
||||
.def("GetRandomClient", (Lua_Client(Lua_EntityList::*)(float, float, float, float))&Lua_EntityList::GetRandomClient)
|
||||
.def("GetRandomClient", (Lua_Client(Lua_EntityList::*)(float, float, float, float, Lua_Client))&Lua_EntityList::GetRandomClient)
|
||||
.def("GetMobList", (Lua_Mob_List(Lua_EntityList::*)(void))&Lua_EntityList::GetMobList)
|
||||
.def("GetClientList", (Lua_Client_List(Lua_EntityList::*)(void))&Lua_EntityList::GetClientList)
|
||||
.def("GetNPCList", (Lua_NPC_List(Lua_EntityList::*)(void))&Lua_EntityList::GetNPCList)
|
||||
@ -479,7 +486,7 @@ luabind::scope lua_register_entity_list() {
|
||||
.def("GetDoorsList", (Lua_Doors_List(Lua_EntityList::*)(void))&Lua_EntityList::GetDoorsList)
|
||||
.def("GetSpawnList", (Lua_Spawn_List(Lua_EntityList::*)(void))&Lua_EntityList::GetSpawnList)
|
||||
.def("SignalAllClients", (void(Lua_EntityList::*)(int))&Lua_EntityList::SignalAllClients)
|
||||
.def("ChannelMessage", (void(Lua_EntityList::*)(Lua_Mob,int,int,const char*))&Lua_EntityList::ChannelMessage);
|
||||
.def("ChannelMessage", (void(Lua_EntityList::*)(Lua_Mob, int, int, const char*))&Lua_EntityList::ChannelMessage);
|
||||
}
|
||||
|
||||
luabind::scope lua_register_mob_list() {
|
||||
|
||||
@ -80,6 +80,7 @@ public:
|
||||
void Message(uint32 guild_dbid, uint32 type, const char *message);
|
||||
void MessageStatus(uint32 guild_dbid, int min_status, uint32 type, const char *message);
|
||||
void MessageClose(Lua_Mob sender, bool skip_sender, float dist, uint32 type, const char *message);
|
||||
void FilteredMessageClose(Lua_Mob sender, bool skip_sender, float dist, uint32 type, int filter, const char *message);
|
||||
void RemoveFromTargets(Lua_Mob mob);
|
||||
void RemoveFromTargets(Lua_Mob mob, bool RemoveFromXTargets);
|
||||
void ReplaceWithTarget(Lua_Mob target, Lua_Mob new_target);
|
||||
|
||||
@ -7,6 +7,10 @@
|
||||
#include <list>
|
||||
#include <map>
|
||||
|
||||
#include "../common/timer.h"
|
||||
#include "../common/eqemu_logsys.h"
|
||||
#include "../common/classes.h"
|
||||
#include "../common/rulesys.h"
|
||||
#include "lua_parser.h"
|
||||
#include "lua_item.h"
|
||||
#include "lua_iteminst.h"
|
||||
@ -16,8 +20,6 @@
|
||||
#include "quest_parser_collection.h"
|
||||
#include "questmgr.h"
|
||||
#include "qglobals.h"
|
||||
#include "../common/timer.h"
|
||||
#include "../common/eqemu_logsys.h"
|
||||
#include "encounter.h"
|
||||
#include "lua_encounter.h"
|
||||
|
||||
@ -27,6 +29,12 @@ struct Slots { };
|
||||
struct Materials { };
|
||||
struct ClientVersions { };
|
||||
struct Appearances { };
|
||||
struct Classes { };
|
||||
struct Skills { };
|
||||
struct BodyTypes { };
|
||||
struct Filters { };
|
||||
struct MessageTypes { };
|
||||
struct Rule { };
|
||||
|
||||
struct lua_registered_event {
|
||||
std::string encounter_name;
|
||||
@ -1462,6 +1470,39 @@ void lua_create_npc(luabind::adl::object table, float x, float y, float z, float
|
||||
npc->GiveNPCTypeData(npc_type);
|
||||
entity_list.AddNPC(npc);
|
||||
}
|
||||
|
||||
int random_int(int low, int high) {
|
||||
return zone->random.Int(low, high);
|
||||
}
|
||||
|
||||
double random_real(double low, double high) {
|
||||
return zone->random.Real(low, high);
|
||||
}
|
||||
|
||||
bool random_roll_int(int required) {
|
||||
return zone->random.Roll(required);
|
||||
}
|
||||
|
||||
bool random_roll_real(double required) {
|
||||
return zone->random.Roll(required);
|
||||
}
|
||||
|
||||
int random_roll0(int max) {
|
||||
return zone->random.Roll0(max);
|
||||
}
|
||||
|
||||
int get_rulei(int rule) {
|
||||
return RuleManager::Instance()->GetIntRule((RuleManager::IntType)rule);
|
||||
}
|
||||
|
||||
float get_ruler(int rule) {
|
||||
return RuleManager::Instance()->GetRealRule((RuleManager::RealType)rule);
|
||||
}
|
||||
|
||||
bool get_ruleb(int rule) {
|
||||
return RuleManager::Instance()->GetBoolRule((RuleManager::BoolType)rule);
|
||||
}
|
||||
|
||||
luabind::scope lua_register_general() {
|
||||
return luabind::namespace_("eq")
|
||||
[
|
||||
@ -1663,6 +1704,18 @@ luabind::scope lua_register_general() {
|
||||
];
|
||||
}
|
||||
|
||||
luabind::scope lua_register_random() {
|
||||
return luabind::namespace_("Random")
|
||||
[
|
||||
luabind::def("Int", &random_int),
|
||||
luabind::def("Real", &random_real),
|
||||
luabind::def("Roll", &random_roll_int),
|
||||
luabind::def("RollReal", &random_roll_real),
|
||||
luabind::def("Roll0", &random_roll0)
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
luabind::scope lua_register_events() {
|
||||
return luabind::class_<Events>("Event")
|
||||
.enum_("constants")
|
||||
@ -1863,4 +1916,355 @@ luabind::scope lua_register_appearance() {
|
||||
];
|
||||
}
|
||||
|
||||
luabind::scope lua_register_classes() {
|
||||
return luabind::class_<Classes>("Class")
|
||||
.enum_("constants")
|
||||
[
|
||||
luabind::value("WARRIOR", WARRIOR),
|
||||
luabind::value("CLERIC", CLERIC),
|
||||
luabind::value("PALADIN", PALADIN),
|
||||
luabind::value("RANGER", RANGER),
|
||||
luabind::value("SHADOWKNIGHT", SHADOWKNIGHT),
|
||||
luabind::value("DRUID", DRUID),
|
||||
luabind::value("MONK", MONK),
|
||||
luabind::value("BARD", BARD),
|
||||
luabind::value("ROGUE", ROGUE),
|
||||
luabind::value("SHAMAN", SHAMAN),
|
||||
luabind::value("NECROMANCER", NECROMANCER),
|
||||
luabind::value("WIZARD", WIZARD),
|
||||
luabind::value("MAGICIAN", MAGICIAN),
|
||||
luabind::value("ENCHANTER", ENCHANTER),
|
||||
luabind::value("BEASTLORD", BEASTLORD),
|
||||
luabind::value("BERSERKER", BERSERKER),
|
||||
luabind::value("WARRIORGM", WARRIORGM),
|
||||
luabind::value("CLERICGM", CLERICGM),
|
||||
luabind::value("PALADINGM", PALADINGM),
|
||||
luabind::value("RANGERGM", RANGERGM),
|
||||
luabind::value("SHADOWKNIGHTGM", SHADOWKNIGHTGM),
|
||||
luabind::value("DRUIDGM", DRUIDGM),
|
||||
luabind::value("MONKGM", MONKGM),
|
||||
luabind::value("BARDGM", BARDGM),
|
||||
luabind::value("ROGUEGM", ROGUEGM),
|
||||
luabind::value("SHAMANGM", SHAMANGM),
|
||||
luabind::value("NECROMANCERGM", NECROMANCERGM),
|
||||
luabind::value("WIZARDGM", WIZARDGM),
|
||||
luabind::value("MAGICIANGM", MAGICIANGM),
|
||||
luabind::value("ENCHANTERGM", ENCHANTERGM),
|
||||
luabind::value("BEASTLORDGM", BEASTLORDGM),
|
||||
luabind::value("BERSERKERGM", BERSERKERGM),
|
||||
luabind::value("BANKER", BANKER),
|
||||
luabind::value("MERCHANT", MERCHANT),
|
||||
luabind::value("DISCORD_MERCHANT", DISCORD_MERCHANT),
|
||||
luabind::value("ADVENTURERECRUITER", ADVENTURERECRUITER),
|
||||
luabind::value("ADVENTUREMERCHANT", ADVENTUREMERCHANT),
|
||||
luabind::value("LDON_TREASURE", LDON_TREASURE),
|
||||
luabind::value("CORPSE_CLASS", CORPSE_CLASS),
|
||||
luabind::value("TRIBUTE_MASTER", TRIBUTE_MASTER),
|
||||
luabind::value("GUILD_TRIBUTE_MASTER", GUILD_TRIBUTE_MASTER),
|
||||
luabind::value("NORRATHS_KEEPERS_MERCHANT", NORRATHS_KEEPERS_MERCHANT),
|
||||
luabind::value("DARK_REIGN_MERCHANT", DARK_REIGN_MERCHANT),
|
||||
luabind::value("FELLOWSHIP_MASTER", FELLOWSHIP_MASTER),
|
||||
luabind::value("ALT_CURRENCY_MERCHANT", ALT_CURRENCY_MERCHANT),
|
||||
luabind::value("MERCERNARY_MASTER", MERCERNARY_MASTER)
|
||||
];
|
||||
}
|
||||
|
||||
luabind::scope lua_register_skills() {
|
||||
return luabind::class_<Skills>("Skill")
|
||||
.enum_("constants")
|
||||
[
|
||||
luabind::value("1HBlunt", EQEmu::skills::Skill1HBlunt),
|
||||
luabind::value("1HSlashing", EQEmu::skills::Skill1HSlashing),
|
||||
luabind::value("2HBlunt", EQEmu::skills::Skill2HBlunt),
|
||||
luabind::value("2HSlashing", EQEmu::skills::Skill2HSlashing),
|
||||
luabind::value("Abjuration", EQEmu::skills::SkillAbjuration),
|
||||
luabind::value("Alteration", EQEmu::skills::SkillAlteration),
|
||||
luabind::value("ApplyPoison", EQEmu::skills::SkillApplyPoison),
|
||||
luabind::value("Archery", EQEmu::skills::SkillArchery),
|
||||
luabind::value("Backstab", EQEmu::skills::SkillBackstab),
|
||||
luabind::value("BindWound", EQEmu::skills::SkillBindWound),
|
||||
luabind::value("Bash", EQEmu::skills::SkillBash),
|
||||
luabind::value("Block", EQEmu::skills::SkillBlock),
|
||||
luabind::value("BrassInstruments", EQEmu::skills::SkillBrassInstruments),
|
||||
luabind::value("Channeling", EQEmu::skills::SkillChanneling),
|
||||
luabind::value("Conjuration", EQEmu::skills::SkillConjuration),
|
||||
luabind::value("Defense", EQEmu::skills::SkillDefense),
|
||||
luabind::value("Disarm", EQEmu::skills::SkillDisarm),
|
||||
luabind::value("DisarmTraps", EQEmu::skills::SkillDisarmTraps),
|
||||
luabind::value("Divination", EQEmu::skills::SkillDivination),
|
||||
luabind::value("Dodge", EQEmu::skills::SkillDodge),
|
||||
luabind::value("DoubleAttack", EQEmu::skills::SkillDoubleAttack),
|
||||
luabind::value("DragonPunch", EQEmu::skills::SkillDragonPunch),
|
||||
luabind::value("TailRake", EQEmu::skills::SkillTailRake),
|
||||
luabind::value("DualWield", EQEmu::skills::SkillDualWield),
|
||||
luabind::value("EagleStrike", EQEmu::skills::SkillEagleStrike),
|
||||
luabind::value("Evocation", EQEmu::skills::SkillEvocation),
|
||||
luabind::value("FeignDeath", EQEmu::skills::SkillFeignDeath),
|
||||
luabind::value("FlyingKick", EQEmu::skills::SkillFlyingKick),
|
||||
luabind::value("Forage", EQEmu::skills::SkillForage),
|
||||
luabind::value("HandtoHand", EQEmu::skills::SkillHandtoHand),
|
||||
luabind::value("Hide", EQEmu::skills::SkillHide),
|
||||
luabind::value("Kick", EQEmu::skills::SkillKick),
|
||||
luabind::value("Meditate", EQEmu::skills::SkillMeditate),
|
||||
luabind::value("Mend", EQEmu::skills::SkillMend),
|
||||
luabind::value("Offense", EQEmu::skills::SkillOffense),
|
||||
luabind::value("Parry", EQEmu::skills::SkillParry),
|
||||
luabind::value("PickLock", EQEmu::skills::SkillPickLock),
|
||||
luabind::value("1HPiercing", EQEmu::skills::Skill1HPiercing),
|
||||
luabind::value("Riposte", EQEmu::skills::SkillRiposte),
|
||||
luabind::value("RoundKick", EQEmu::skills::SkillRoundKick),
|
||||
luabind::value("SafeFall", EQEmu::skills::SkillSafeFall),
|
||||
luabind::value("SenseHeading", EQEmu::skills::SkillSenseHeading),
|
||||
luabind::value("Singing", EQEmu::skills::SkillSinging),
|
||||
luabind::value("Sneak", EQEmu::skills::SkillSneak),
|
||||
luabind::value("SpecializeAbjure", EQEmu::skills::SkillSpecializeAbjure),
|
||||
luabind::value("SpecializeAlteration", EQEmu::skills::SkillSpecializeAlteration),
|
||||
luabind::value("SpecializeConjuration", EQEmu::skills::SkillSpecializeConjuration),
|
||||
luabind::value("SpecializeDivination", EQEmu::skills::SkillSpecializeDivination),
|
||||
luabind::value("SpecializeEvocation", EQEmu::skills::SkillSpecializeEvocation),
|
||||
luabind::value("PickPockets", EQEmu::skills::SkillPickPockets),
|
||||
luabind::value("StringedInstruments", EQEmu::skills::SkillStringedInstruments),
|
||||
luabind::value("Swimming", EQEmu::skills::SkillSwimming),
|
||||
luabind::value("Throwing", EQEmu::skills::SkillThrowing),
|
||||
luabind::value("TigerClaw", EQEmu::skills::SkillTigerClaw),
|
||||
luabind::value("Tracking", EQEmu::skills::SkillTracking),
|
||||
luabind::value("WindInstruments", EQEmu::skills::SkillWindInstruments),
|
||||
luabind::value("Fishing", EQEmu::skills::SkillFishing),
|
||||
luabind::value("MakePoison", EQEmu::skills::SkillMakePoison),
|
||||
luabind::value("Tinkering", EQEmu::skills::SkillTinkering),
|
||||
luabind::value("Research", EQEmu::skills::SkillResearch),
|
||||
luabind::value("Alchemy", EQEmu::skills::SkillAlchemy),
|
||||
luabind::value("Baking", EQEmu::skills::SkillBaking),
|
||||
luabind::value("Tailoring", EQEmu::skills::SkillTailoring),
|
||||
luabind::value("SenseTraps", EQEmu::skills::SkillSenseTraps),
|
||||
luabind::value("Blacksmithing", EQEmu::skills::SkillBlacksmithing),
|
||||
luabind::value("Fletching", EQEmu::skills::SkillFletching),
|
||||
luabind::value("Brewing", EQEmu::skills::SkillBrewing),
|
||||
luabind::value("AlcoholTolerance", EQEmu::skills::SkillAlcoholTolerance),
|
||||
luabind::value("Begging", EQEmu::skills::SkillBegging),
|
||||
luabind::value("JewelryMaking", EQEmu::skills::SkillJewelryMaking),
|
||||
luabind::value("Pottery", EQEmu::skills::SkillPottery),
|
||||
luabind::value("PercussionInstruments", EQEmu::skills::SkillPercussionInstruments),
|
||||
luabind::value("Intimidation", EQEmu::skills::SkillIntimidation),
|
||||
luabind::value("Berserking", EQEmu::skills::SkillBerserking),
|
||||
luabind::value("Taunt", EQEmu::skills::SkillTaunt),
|
||||
luabind::value("Frenzy", EQEmu::skills::SkillFrenzy),
|
||||
luabind::value("RemoveTraps", EQEmu::skills::SkillRemoveTraps),
|
||||
luabind::value("TripleAttack", EQEmu::skills::SkillTripleAttack),
|
||||
luabind::value("2HPiercing", EQEmu::skills::Skill2HPiercing),
|
||||
luabind::value("HIGHEST_SKILL", EQEmu::skills::HIGHEST_SKILL)
|
||||
];
|
||||
}
|
||||
|
||||
luabind::scope lua_register_bodytypes() {
|
||||
return luabind::class_<BodyTypes>("BT")
|
||||
.enum_("constants")
|
||||
[
|
||||
luabind::value("Humanoid", 1),
|
||||
luabind::value("Lycanthrope", 2),
|
||||
luabind::value("Undead", 3),
|
||||
luabind::value("Giant", 4),
|
||||
luabind::value("Construct", 5),
|
||||
luabind::value("Extraplanar", 6),
|
||||
luabind::value("Magical", 7),
|
||||
luabind::value("SummonedUndead", 8),
|
||||
luabind::value("RaidGiant", 9),
|
||||
luabind::value("NoTarget", 11),
|
||||
luabind::value("Vampire", 12),
|
||||
luabind::value("Atenha_Ra", 13),
|
||||
luabind::value("Greater_Akheva", 14),
|
||||
luabind::value("Khati_Sha", 15),
|
||||
luabind::value("Seru", 16),
|
||||
luabind::value("Draz_Nurakk", 18),
|
||||
luabind::value("Zek", 19),
|
||||
luabind::value("Luggald", 20),
|
||||
luabind::value("Animal", 21),
|
||||
luabind::value("Insect", 22),
|
||||
luabind::value("Monster", 23),
|
||||
luabind::value("Summoned", 24),
|
||||
luabind::value("Plant", 25),
|
||||
luabind::value("Dragon", 26),
|
||||
luabind::value("Summoned2", 27),
|
||||
luabind::value("Summoned3", 28),
|
||||
luabind::value("VeliousDragon", 30),
|
||||
luabind::value("Dragon3", 32),
|
||||
luabind::value("Boxes", 33),
|
||||
luabind::value("Muramite", 34),
|
||||
luabind::value("NoTarget2", 60),
|
||||
luabind::value("SwarmPet", 63),
|
||||
luabind::value("InvisMan", 66),
|
||||
luabind::value("Special", 67)
|
||||
];
|
||||
}
|
||||
|
||||
luabind::scope lua_register_filters() {
|
||||
return luabind::class_<Filters>("Filter")
|
||||
.enum_("constants")
|
||||
[
|
||||
luabind::value("None", FilterNone),
|
||||
luabind::value("GuildChat", FilterGuildChat),
|
||||
luabind::value("Socials", FilterSocials),
|
||||
luabind::value("GroupChat", FilterGroupChat),
|
||||
luabind::value("Shouts", FilterShouts),
|
||||
luabind::value("Auctions", FilterAuctions),
|
||||
luabind::value("OOC", FilterOOC),
|
||||
luabind::value("BadWords", FilterBadWords),
|
||||
luabind::value("PCSpells", FilterPCSpells),
|
||||
luabind::value("NPCSpells", FilterNPCSpells),
|
||||
luabind::value("BardSongs", FilterBardSongs),
|
||||
luabind::value("SpellCrits", FilterSpellCrits),
|
||||
luabind::value("MeleeCrits", FilterMeleeCrits),
|
||||
luabind::value("SpellDamage", FilterSpellDamage),
|
||||
luabind::value("MyMisses", FilterMyMisses),
|
||||
luabind::value("OthersMiss", FilterOthersMiss),
|
||||
luabind::value("OthersHit", FilterOthersHit),
|
||||
luabind::value("MissedMe", FilterMissedMe),
|
||||
luabind::value("DamageShields", FilterDamageShields),
|
||||
luabind::value("DOT", FilterDOT),
|
||||
luabind::value("PetHits", FilterPetHits),
|
||||
luabind::value("PetMisses", FilterPetMisses),
|
||||
luabind::value("FocusEffects", FilterFocusEffects),
|
||||
luabind::value("PetSpells", FilterPetSpells),
|
||||
luabind::value("HealOverTime", FilterHealOverTime),
|
||||
luabind::value("Unknown25", FilterUnknown25),
|
||||
luabind::value("Unknown26", FilterUnknown26),
|
||||
luabind::value("Unknown27", FilterUnknown27),
|
||||
luabind::value("Unknown28", FilterUnknown28)
|
||||
];
|
||||
}
|
||||
|
||||
luabind::scope lua_register_message_types() {
|
||||
return luabind::class_<MessageTypes>("MT")
|
||||
.enum_("constants")
|
||||
[
|
||||
luabind::value("Say", MT_Say),
|
||||
luabind::value("Tell", MT_Tell),
|
||||
luabind::value("Group", MT_Group),
|
||||
luabind::value("Guild", MT_Guild),
|
||||
luabind::value("OOC", MT_OOC),
|
||||
luabind::value("Auction", MT_Auction),
|
||||
luabind::value("Shout", MT_Shout),
|
||||
luabind::value("Emote", MT_Emote),
|
||||
luabind::value("Spells", MT_Spells),
|
||||
luabind::value("YouHitOther", MT_YouHitOther),
|
||||
luabind::value("OtherHitsYou", MT_OtherHitsYou),
|
||||
luabind::value("YouMissOther", MT_YouMissOther),
|
||||
luabind::value("OtherMissesYou", MT_OtherMissesYou),
|
||||
luabind::value("Broadcasts", MT_Broadcasts),
|
||||
luabind::value("Skills", MT_Skills),
|
||||
luabind::value("Disciplines", MT_Disciplines),
|
||||
luabind::value("Unused1", MT_Unused1),
|
||||
luabind::value("DefaultText", MT_DefaultText),
|
||||
luabind::value("Unused2", MT_Unused2),
|
||||
luabind::value("MerchantOffer", MT_MerchantOffer),
|
||||
luabind::value("MerchantBuySell", MT_MerchantBuySell),
|
||||
luabind::value("YourDeath", MT_YourDeath),
|
||||
luabind::value("OtherDeath", MT_OtherDeath),
|
||||
luabind::value("OtherHits", MT_OtherHits),
|
||||
luabind::value("OtherMisses", MT_OtherMisses),
|
||||
luabind::value("Who", MT_Who),
|
||||
luabind::value("YellForHelp", MT_YellForHelp),
|
||||
luabind::value("NonMelee", MT_NonMelee),
|
||||
luabind::value("WornOff", MT_WornOff),
|
||||
luabind::value("MoneySplit", MT_MoneySplit),
|
||||
luabind::value("LootMessages", MT_LootMessages),
|
||||
luabind::value("DiceRoll", MT_DiceRoll),
|
||||
luabind::value("OtherSpells", MT_OtherSpells),
|
||||
luabind::value("SpellFailure", MT_SpellFailure),
|
||||
luabind::value("Chat", MT_Chat),
|
||||
luabind::value("Channel1", MT_Channel1),
|
||||
luabind::value("Channel2", MT_Channel2),
|
||||
luabind::value("Channel3", MT_Channel3),
|
||||
luabind::value("Channel4", MT_Channel4),
|
||||
luabind::value("Channel5", MT_Channel5),
|
||||
luabind::value("Channel6", MT_Channel6),
|
||||
luabind::value("Channel7", MT_Channel7),
|
||||
luabind::value("Channel8", MT_Channel8),
|
||||
luabind::value("Channel9", MT_Channel9),
|
||||
luabind::value("Channel10", MT_Channel10),
|
||||
luabind::value("CritMelee", MT_CritMelee),
|
||||
luabind::value("SpellCrits", MT_SpellCrits),
|
||||
luabind::value("TooFarAway", MT_TooFarAway),
|
||||
luabind::value("NPCRampage", MT_NPCRampage),
|
||||
luabind::value("NPCFlurry", MT_NPCFlurry),
|
||||
luabind::value("NPCEnrage", MT_NPCEnrage),
|
||||
luabind::value("SayEcho", MT_SayEcho),
|
||||
luabind::value("TellEcho", MT_TellEcho),
|
||||
luabind::value("GroupEcho", MT_GroupEcho),
|
||||
luabind::value("GuildEcho", MT_GuildEcho),
|
||||
luabind::value("OOCEcho", MT_OOCEcho),
|
||||
luabind::value("AuctionEcho", MT_AuctionEcho),
|
||||
luabind::value("ShoutECho", MT_ShoutECho),
|
||||
luabind::value("EmoteEcho", MT_EmoteEcho),
|
||||
luabind::value("Chat1Echo", MT_Chat1Echo),
|
||||
luabind::value("Chat2Echo", MT_Chat2Echo),
|
||||
luabind::value("Chat3Echo", MT_Chat3Echo),
|
||||
luabind::value("Chat4Echo", MT_Chat4Echo),
|
||||
luabind::value("Chat5Echo", MT_Chat5Echo),
|
||||
luabind::value("Chat6Echo", MT_Chat6Echo),
|
||||
luabind::value("Chat7Echo", MT_Chat7Echo),
|
||||
luabind::value("Chat8Echo", MT_Chat8Echo),
|
||||
luabind::value("Chat9Echo", MT_Chat9Echo),
|
||||
luabind::value("Chat10Echo", MT_Chat10Echo),
|
||||
luabind::value("DoTDamage", MT_DoTDamage),
|
||||
luabind::value("ItemLink", MT_ItemLink),
|
||||
luabind::value("RaidSay", MT_RaidSay),
|
||||
luabind::value("MyPet", MT_MyPet),
|
||||
luabind::value("DS", MT_DS),
|
||||
luabind::value("Leadership", MT_Leadership),
|
||||
luabind::value("PetFlurry", MT_PetFlurry),
|
||||
luabind::value("PetCrit", MT_PetCrit),
|
||||
luabind::value("FocusEffect", MT_FocusEffect),
|
||||
luabind::value("Experience", MT_Experience),
|
||||
luabind::value("System", MT_System),
|
||||
luabind::value("PetSpell", MT_PetSpell),
|
||||
luabind::value("PetResponse", MT_PetResponse),
|
||||
luabind::value("ItemSpeech", MT_ItemSpeech),
|
||||
luabind::value("StrikeThrough", MT_StrikeThrough),
|
||||
luabind::value("Stun", MT_Stun)
|
||||
];
|
||||
}
|
||||
|
||||
luabind::scope lua_register_rules_const() {
|
||||
return luabind::class_<Rule>("Rule")
|
||||
.enum_("constants")
|
||||
[
|
||||
#define RULE_INT(cat, rule, default_value) \
|
||||
luabind::value(#rule, RuleManager::Int__##rule),
|
||||
#include "../common/ruletypes.h"
|
||||
luabind::value("_IntRuleCount", RuleManager::_IntRuleCount),
|
||||
#undef RULE_INT
|
||||
#define RULE_REAL(cat, rule, default_value) \
|
||||
luabind::value(#rule, RuleManager::Real__##rule),
|
||||
#include "../common/ruletypes.h"
|
||||
luabind::value("_RealRuleCount", RuleManager::_RealRuleCount),
|
||||
#undef RULE_REAL
|
||||
#define RULE_BOOL(cat, rule, default_value) \
|
||||
luabind::value(#rule, RuleManager::Bool__##rule),
|
||||
#include "../common/ruletypes.h"
|
||||
luabind::value("_BoolRuleCount", RuleManager::_BoolRuleCount)
|
||||
];
|
||||
}
|
||||
|
||||
luabind::scope lua_register_rulei() {
|
||||
return luabind::namespace_("RuleI")
|
||||
[
|
||||
luabind::def("Get", &get_rulei)
|
||||
];
|
||||
}
|
||||
|
||||
luabind::scope lua_register_ruler() {
|
||||
return luabind::namespace_("RuleR")
|
||||
[
|
||||
luabind::def("Get", &get_ruler)
|
||||
];
|
||||
}
|
||||
|
||||
luabind::scope lua_register_ruleb() {
|
||||
return luabind::namespace_("RuleB")
|
||||
[
|
||||
luabind::def("Get", &get_ruleb)
|
||||
];
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -3,12 +3,22 @@
|
||||
#ifdef LUA_EQEMU
|
||||
|
||||
luabind::scope lua_register_general();
|
||||
luabind::scope lua_register_random();
|
||||
luabind::scope lua_register_events();
|
||||
luabind::scope lua_register_faction();
|
||||
luabind::scope lua_register_slot();
|
||||
luabind::scope lua_register_material();
|
||||
luabind::scope lua_register_client_version();
|
||||
luabind::scope lua_register_appearance();
|
||||
luabind::scope lua_register_classes();
|
||||
luabind::scope lua_register_skills();
|
||||
luabind::scope lua_register_bodytypes();
|
||||
luabind::scope lua_register_filters();
|
||||
luabind::scope lua_register_message_types();
|
||||
luabind::scope lua_register_rules_const();
|
||||
luabind::scope lua_register_rulei();
|
||||
luabind::scope lua_register_ruler();
|
||||
luabind::scope lua_register_ruleb();
|
||||
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
115
zone/lua_mob.cpp
115
zone/lua_mob.cpp
@ -10,6 +10,7 @@
|
||||
#include "lua_mob.h"
|
||||
#include "lua_hate_list.h"
|
||||
#include "lua_client.h"
|
||||
#include "lua_stat_bonuses.h"
|
||||
|
||||
struct SpecialAbilities { };
|
||||
|
||||
@ -1725,6 +1726,18 @@ int Lua_Mob::GetSkillDmgTaken(int skill) {
|
||||
return self->GetSkillDmgTaken(static_cast<EQEmu::skills::SkillType>(skill));
|
||||
}
|
||||
|
||||
int Lua_Mob::GetFcDamageAmtIncoming(Lua_Mob caster, uint32 spell_id, bool use_skill, uint16 skill)
|
||||
{
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetFcDamageAmtIncoming(caster, spell_id, use_skill, skill);
|
||||
}
|
||||
|
||||
int Lua_Mob::GetSkillDmgAmt(uint16 skill)
|
||||
{
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetSkillDmgAmt(skill);
|
||||
}
|
||||
|
||||
void Lua_Mob::SetAllowBeneficial(bool value) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->SetAllowBeneficial(value);
|
||||
@ -1985,6 +1998,89 @@ int32 Lua_Mob::GetMeleeMitigation() {
|
||||
return self->GetMeleeMitigation();
|
||||
}
|
||||
|
||||
int Lua_Mob::GetWeaponDamageBonus(Lua_Item weapon, bool offhand) {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetWeaponDamageBonus(weapon, offhand);
|
||||
}
|
||||
|
||||
Lua_StatBonuses Lua_Mob::GetItemBonuses()
|
||||
{
|
||||
Lua_Safe_Call_Class(Lua_StatBonuses);
|
||||
return self->GetItemBonusesPtr();
|
||||
}
|
||||
|
||||
Lua_StatBonuses Lua_Mob::GetSpellBonuses()
|
||||
{
|
||||
Lua_Safe_Call_Class(Lua_StatBonuses);
|
||||
return self->GetSpellBonusesPtr();
|
||||
}
|
||||
|
||||
Lua_StatBonuses Lua_Mob::GetAABonuses()
|
||||
{
|
||||
Lua_Safe_Call_Class(Lua_StatBonuses);
|
||||
return self->GetAABonusesPtr();
|
||||
}
|
||||
|
||||
int16 Lua_Mob::GetMeleeDamageMod_SE(uint16 skill)
|
||||
{
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetMeleeDamageMod_SE(skill);
|
||||
}
|
||||
|
||||
int16 Lua_Mob::GetMeleeMinDamageMod_SE(uint16 skill)
|
||||
{
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetMeleeMinDamageMod_SE(skill);
|
||||
}
|
||||
|
||||
bool Lua_Mob::IsAttackAllowed(Lua_Mob target, bool isSpellAttack) {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->IsAttackAllowed(target, isSpellAttack);
|
||||
}
|
||||
|
||||
bool Lua_Mob::IsCasting() {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->IsCasting();
|
||||
}
|
||||
|
||||
int Lua_Mob::AttackAnimation(int Hand, Lua_ItemInst weapon) {
|
||||
Lua_Safe_Call_Int();
|
||||
return (int)self->AttackAnimation(Hand, weapon);
|
||||
}
|
||||
|
||||
int Lua_Mob::GetWeaponDamage(Lua_Mob against, Lua_ItemInst weapon) {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetWeaponDamage(against, weapon);
|
||||
}
|
||||
|
||||
bool Lua_Mob::IsBerserk() {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->IsBerserk();
|
||||
}
|
||||
|
||||
bool Lua_Mob::TryFinishingBlow(Lua_Mob defender, int &damage) {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->TryFinishingBlow(defender, damage);
|
||||
}
|
||||
|
||||
int Lua_Mob::GetBodyType()
|
||||
{
|
||||
Lua_Safe_Call_Int();
|
||||
return (int)self->GetBodyType();
|
||||
}
|
||||
|
||||
int Lua_Mob::GetOrigBodyType()
|
||||
{
|
||||
Lua_Safe_Call_Int();
|
||||
return (int)self->GetOrigBodyType();
|
||||
}
|
||||
|
||||
void Lua_Mob::CheckNumHitsRemaining(int type, int32 buff_slot, uint16 spell_id)
|
||||
{
|
||||
Lua_Safe_Call_Void();
|
||||
self->CheckNumHitsRemaining((NumHit)type, buff_slot, spell_id);
|
||||
}
|
||||
|
||||
luabind::scope lua_register_mob() {
|
||||
return luabind::class_<Lua_Mob, Lua_Entity>("Mob")
|
||||
.def(luabind::constructor<>())
|
||||
@ -2281,6 +2377,8 @@ luabind::scope lua_register_mob() {
|
||||
.def("ModSkillDmgTaken", (void(Lua_Mob::*)(int,int))&Lua_Mob::ModSkillDmgTaken)
|
||||
.def("GetModSkillDmgTaken", (int(Lua_Mob::*)(int))&Lua_Mob::GetModSkillDmgTaken)
|
||||
.def("GetSkillDmgTaken", (int(Lua_Mob::*)(int))&Lua_Mob::GetSkillDmgTaken)
|
||||
.def("GetFcDamageAmtIncoming", &Lua_Mob::GetFcDamageAmtIncoming)
|
||||
.def("GetSkillDmgAmt", (int(Lua_Mob::*)(int))&Lua_Mob::GetSkillDmgAmt)
|
||||
.def("SetAllowBeneficial", (void(Lua_Mob::*)(bool))&Lua_Mob::SetAllowBeneficial)
|
||||
.def("GetAllowBeneficial", (bool(Lua_Mob::*)(void))&Lua_Mob::GetAllowBeneficial)
|
||||
.def("IsBeneficialAllowed", (bool(Lua_Mob::*)(Lua_Mob))&Lua_Mob::IsBeneficialAllowed)
|
||||
@ -2330,7 +2428,22 @@ luabind::scope lua_register_mob() {
|
||||
.def("HasPet", (bool(Lua_Mob::*)(void))&Lua_Mob::HasPet)
|
||||
.def("IsSilenced", (bool(Lua_Mob::*)(void))&Lua_Mob::IsSilenced)
|
||||
.def("IsAmnesiad", (bool(Lua_Mob::*)(void))&Lua_Mob::IsAmnesiad)
|
||||
.def("GetMeleeMitigation", (int32(Lua_Mob::*)(void))&Lua_Mob::GetMeleeMitigation);
|
||||
.def("GetMeleeMitigation", (int32(Lua_Mob::*)(void))&Lua_Mob::GetMeleeMitigation)
|
||||
.def("GetWeaponDamageBonus", &Lua_Mob::GetWeaponDamageBonus)
|
||||
.def("GetItemBonuses", &Lua_Mob::GetItemBonuses)
|
||||
.def("GetSpellBonuses", &Lua_Mob::GetSpellBonuses)
|
||||
.def("GetAABonuses", &Lua_Mob::GetAABonuses)
|
||||
.def("GetMeleeDamageMod_SE", &Lua_Mob::GetMeleeDamageMod_SE)
|
||||
.def("GetMeleeMinDamageMod_SE", &Lua_Mob::GetMeleeMinDamageMod_SE)
|
||||
.def("IsAttackAllowed", &Lua_Mob::IsAttackAllowed)
|
||||
.def("IsCasting", &Lua_Mob::IsCasting)
|
||||
.def("AttackAnimation", &Lua_Mob::AttackAnimation)
|
||||
.def("GetWeaponDamage", &Lua_Mob::GetWeaponDamage)
|
||||
.def("IsBerserk", &Lua_Mob::IsBerserk)
|
||||
.def("TryFinishingBlow", &Lua_Mob::TryFinishingBlow)
|
||||
.def("GetBodyType", &Lua_Mob::GetBodyType)
|
||||
.def("GetOrigBodyType", &Lua_Mob::GetOrigBodyType)
|
||||
.def("CheckNumHitsRemaining", &Lua_Mob::CheckNumHitsRemaining);
|
||||
}
|
||||
|
||||
luabind::scope lua_register_special_abilities() {
|
||||
|
||||
@ -8,6 +8,7 @@ class Mob;
|
||||
struct Lua_HateList;
|
||||
class Lua_Item;
|
||||
class Lua_ItemInst;
|
||||
class Lua_StatBonuses;
|
||||
|
||||
namespace luabind {
|
||||
struct scope;
|
||||
@ -330,6 +331,8 @@ public:
|
||||
void ModSkillDmgTaken(int skill, int value);
|
||||
int GetModSkillDmgTaken(int skill);
|
||||
int GetSkillDmgTaken(int skill);
|
||||
int GetFcDamageAmtIncoming(Lua_Mob caster, uint32 spell_id, bool use_skill, uint16 skill);
|
||||
int GetSkillDmgAmt(uint16 skill);
|
||||
void SetAllowBeneficial(bool value);
|
||||
bool GetAllowBeneficial();
|
||||
bool IsBeneficialAllowed(Lua_Mob target);
|
||||
@ -340,7 +343,6 @@ public:
|
||||
void SetFlurryChance(int value);
|
||||
int GetFlurryChance();
|
||||
int GetSkill(int skill_id);
|
||||
void CalcBonuses();
|
||||
int GetSpecialAbility(int ability);
|
||||
int GetSpecialAbilityParam(int ability, int param);
|
||||
void SetSpecialAbility(int ability, int level);
|
||||
@ -381,6 +383,21 @@ public:
|
||||
bool IsSilenced();
|
||||
bool IsAmnesiad();
|
||||
int32 GetMeleeMitigation();
|
||||
int GetWeaponDamageBonus(Lua_Item weapon, bool offhand);
|
||||
Lua_StatBonuses GetItemBonuses();
|
||||
Lua_StatBonuses GetSpellBonuses();
|
||||
Lua_StatBonuses GetAABonuses();
|
||||
int16 GetMeleeDamageMod_SE(uint16 skill);
|
||||
int16 GetMeleeMinDamageMod_SE(uint16 skill);
|
||||
bool IsAttackAllowed(Lua_Mob target, bool isSpellAttack);
|
||||
bool IsCasting();
|
||||
int AttackAnimation(int Hand, Lua_ItemInst weapon);
|
||||
int GetWeaponDamage(Lua_Mob against, Lua_ItemInst weapon);
|
||||
bool IsBerserk();
|
||||
bool TryFinishingBlow(Lua_Mob defender, int &damage);
|
||||
int GetBodyType();
|
||||
int GetOrigBodyType();
|
||||
void CheckNumHitsRemaining(int type, int32 buff_slot, uint16 spell_id);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
631
zone/lua_mod.cpp
Normal file
631
zone/lua_mod.cpp
Normal file
@ -0,0 +1,631 @@
|
||||
#include "lua.hpp"
|
||||
#include <luabind/luabind.hpp>
|
||||
#include <luabind/object.hpp>
|
||||
|
||||
#include "../common/spdat.h"
|
||||
#include "masterentity.h"
|
||||
#include "questmgr.h"
|
||||
#include "zone.h"
|
||||
#include "zone_config.h"
|
||||
|
||||
#include "lua_parser.h"
|
||||
#include "lua_mod.h"
|
||||
#include "lua_bit.h"
|
||||
#include "lua_entity.h"
|
||||
#include "lua_item.h"
|
||||
#include "lua_iteminst.h"
|
||||
#include "lua_mob.h"
|
||||
#include "lua_hate_list.h"
|
||||
#include "lua_client.h"
|
||||
#include "lua_inventory.h"
|
||||
#include "lua_npc.h"
|
||||
#include "lua_spell.h"
|
||||
#include "lua_entity_list.h"
|
||||
#include "lua_group.h"
|
||||
#include "lua_raid.h"
|
||||
#include "lua_corpse.h"
|
||||
#include "lua_object.h"
|
||||
#include "lua_door.h"
|
||||
#include "lua_spawn.h"
|
||||
#include "lua_packet.h"
|
||||
#include "lua_general.h"
|
||||
#include "lua_encounter.h"
|
||||
#include "lua_stat_bonuses.h"
|
||||
|
||||
void LuaMod::Init()
|
||||
{
|
||||
m_has_melee_mitigation = parser_->HasFunction("MeleeMitigation", package_name_);
|
||||
m_has_apply_damage_table = parser_->HasFunction("ApplyDamageTable", package_name_);
|
||||
m_has_avoid_damage = parser_->HasFunction("AvoidDamage", package_name_);
|
||||
m_has_check_hit_chance = parser_->HasFunction("CheckHitChance", package_name_);
|
||||
m_has_try_critical_hit = parser_->HasFunction("TryCriticalHit", package_name_);
|
||||
m_has_get_required_aa_experience = parser_->HasFunction("GetRequiredAAExperience", package_name_);
|
||||
m_has_get_exp_for_level = parser_->HasFunction("GetEXPForLevel", package_name_);
|
||||
m_has_get_experience_for_kill = parser_->HasFunction("GetExperienceForKill", package_name_);
|
||||
m_has_common_outgoing_hit_success = parser_->HasFunction("CommonOutgoingHitSuccess", package_name_);
|
||||
}
|
||||
|
||||
void PutDamageHitInfo(lua_State *L, luabind::adl::object &e, DamageHitInfo &hit) {
|
||||
luabind::adl::object lua_hit = luabind::newtable(L);
|
||||
lua_hit["base_damage"] = hit.base_damage;
|
||||
lua_hit["min_damage"] = hit.min_damage;
|
||||
lua_hit["damage_done"] = hit.damage_done;
|
||||
lua_hit["offense"] = hit.offense;
|
||||
lua_hit["tohit"] = hit.tohit;
|
||||
lua_hit["hand"] = hit.hand;
|
||||
lua_hit["skill"] = (int)hit.skill;
|
||||
e["hit"] = lua_hit;
|
||||
}
|
||||
|
||||
void GetDamageHitInfo(luabind::adl::object &ret, DamageHitInfo &hit) {
|
||||
auto luaHitTable = ret["hit"];
|
||||
if (luabind::type(luaHitTable) == LUA_TTABLE) {
|
||||
auto base_damage = luaHitTable["base_damage"];
|
||||
auto min_damage = luaHitTable["min_damage"];
|
||||
auto damage_done = luaHitTable["damage_done"];
|
||||
auto offense = luaHitTable["offense"];
|
||||
auto tohit = luaHitTable["tohit"];
|
||||
auto hand = luaHitTable["hand"];
|
||||
auto skill = luaHitTable["skill"];
|
||||
|
||||
if (luabind::type(base_damage) == LUA_TNUMBER) {
|
||||
hit.base_damage = luabind::object_cast<int>(base_damage);
|
||||
}
|
||||
|
||||
if (luabind::type(min_damage) == LUA_TNUMBER) {
|
||||
hit.min_damage = luabind::object_cast<int>(min_damage);
|
||||
}
|
||||
|
||||
if (luabind::type(damage_done) == LUA_TNUMBER) {
|
||||
hit.damage_done = luabind::object_cast<int>(damage_done);
|
||||
}
|
||||
|
||||
if (luabind::type(offense) == LUA_TNUMBER) {
|
||||
hit.offense = luabind::object_cast<int>(offense);
|
||||
}
|
||||
|
||||
if (luabind::type(tohit) == LUA_TNUMBER) {
|
||||
hit.tohit = luabind::object_cast<int>(tohit);
|
||||
}
|
||||
|
||||
if (luabind::type(hand) == LUA_TNUMBER) {
|
||||
hit.hand = luabind::object_cast<int>(hand);
|
||||
}
|
||||
|
||||
if (luabind::type(skill) == LUA_TNUMBER) {
|
||||
hit.skill = (EQEmu::skills::SkillType)luabind::object_cast<int>(skill);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PutExtraAttackOptions(lua_State *L, luabind::adl::object &e, ExtraAttackOptions *opts) {
|
||||
if (opts) {
|
||||
luabind::adl::object lua_opts = luabind::newtable(L);
|
||||
lua_opts["damage_percent"] = opts->damage_percent;
|
||||
lua_opts["damage_flat"] = opts->damage_flat;
|
||||
lua_opts["armor_pen_percent"] = opts->armor_pen_percent;
|
||||
lua_opts["armor_pen_flat"] = opts->armor_pen_flat;
|
||||
lua_opts["crit_percent"] = opts->crit_percent;
|
||||
lua_opts["crit_flat"] = opts->crit_flat;
|
||||
lua_opts["hate_percent"] = opts->hate_percent;
|
||||
lua_opts["hate_flat"] = opts->hate_flat;
|
||||
lua_opts["hit_chance"] = opts->hit_chance;
|
||||
lua_opts["melee_damage_bonus_flat"] = opts->melee_damage_bonus_flat;
|
||||
lua_opts["skilldmgtaken_bonus_flat"] = opts->skilldmgtaken_bonus_flat;
|
||||
e["opts"] = lua_opts;
|
||||
}
|
||||
}
|
||||
|
||||
void GetExtraAttackOptions(luabind::adl::object &ret, ExtraAttackOptions *opts) {
|
||||
if (opts) {
|
||||
auto luaOptsTable = ret["opts"];
|
||||
if (luabind::type(luaOptsTable) == LUA_TTABLE) {
|
||||
auto damage_percent = luaOptsTable["damage_percent"];
|
||||
auto damage_flat = luaOptsTable["damage_flat"];
|
||||
auto armor_pen_percent = luaOptsTable["armor_pen_percent"];
|
||||
auto armor_pen_flat = luaOptsTable["armor_pen_flat"];
|
||||
auto crit_percent = luaOptsTable["crit_percent"];
|
||||
auto crit_flat = luaOptsTable["crit_flat"];
|
||||
auto hate_percent = luaOptsTable["hate_percent"];
|
||||
auto hate_flat = luaOptsTable["hate_flat"];
|
||||
auto hit_chance = luaOptsTable["hit_chance"];
|
||||
auto melee_damage_bonus_flat = luaOptsTable["melee_damage_bonus_flat"];
|
||||
auto skilldmgtaken_bonus_flat = luaOptsTable["skilldmgtaken_bonus_flat"];
|
||||
|
||||
if (luabind::type(damage_percent) == LUA_TNUMBER) {
|
||||
opts->damage_percent = luabind::object_cast<float>(damage_percent);
|
||||
}
|
||||
|
||||
if (luabind::type(damage_flat) == LUA_TNUMBER) {
|
||||
opts->damage_flat = luabind::object_cast<int>(damage_flat);
|
||||
}
|
||||
|
||||
if (luabind::type(armor_pen_percent) == LUA_TNUMBER) {
|
||||
opts->armor_pen_percent = luabind::object_cast<float>(armor_pen_percent);
|
||||
}
|
||||
|
||||
if (luabind::type(armor_pen_flat) == LUA_TNUMBER) {
|
||||
opts->armor_pen_flat = luabind::object_cast<int>(armor_pen_flat);
|
||||
}
|
||||
|
||||
if (luabind::type(crit_percent) == LUA_TNUMBER) {
|
||||
opts->crit_percent = luabind::object_cast<float>(crit_percent);
|
||||
}
|
||||
|
||||
if (luabind::type(crit_flat) == LUA_TNUMBER) {
|
||||
opts->crit_flat = luabind::object_cast<float>(crit_flat);
|
||||
}
|
||||
|
||||
if (luabind::type(hate_percent) == LUA_TNUMBER) {
|
||||
opts->hate_percent = luabind::object_cast<float>(hate_percent);
|
||||
}
|
||||
|
||||
if (luabind::type(hate_flat) == LUA_TNUMBER) {
|
||||
opts->hate_flat = luabind::object_cast<int>(hate_flat);
|
||||
}
|
||||
|
||||
if (luabind::type(hit_chance) == LUA_TNUMBER) {
|
||||
opts->hit_chance = luabind::object_cast<int>(hit_chance);
|
||||
}
|
||||
|
||||
if (luabind::type(melee_damage_bonus_flat) == LUA_TNUMBER) {
|
||||
opts->melee_damage_bonus_flat = luabind::object_cast<int>(melee_damage_bonus_flat);
|
||||
}
|
||||
|
||||
if (luabind::type(skilldmgtaken_bonus_flat) == LUA_TNUMBER) {
|
||||
opts->skilldmgtaken_bonus_flat = luabind::object_cast<int>(skilldmgtaken_bonus_flat);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LuaMod::MeleeMitigation(Mob *self, Mob *attacker, DamageHitInfo &hit, ExtraAttackOptions *opts, bool &ignoreDefault) {
|
||||
int start = lua_gettop(L);
|
||||
|
||||
try {
|
||||
if (!m_has_melee_mitigation) {
|
||||
return;
|
||||
}
|
||||
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, package_name_.c_str());
|
||||
lua_getfield(L, -1, "MeleeMitigation");
|
||||
|
||||
Lua_Mob l_self(self);
|
||||
Lua_Mob l_other(attacker);
|
||||
luabind::adl::object e = luabind::newtable(L);
|
||||
e["self"] = l_self;
|
||||
e["other"] = l_other;
|
||||
|
||||
PutDamageHitInfo(L, e, hit);
|
||||
PutExtraAttackOptions(L, e, opts);
|
||||
|
||||
e.push(L);
|
||||
|
||||
if (lua_pcall(L, 1, 1, 0)) {
|
||||
std::string error = lua_tostring(L, -1);
|
||||
parser_->AddError(error);
|
||||
lua_pop(L, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (lua_type(L, -1) == LUA_TTABLE) {
|
||||
luabind::adl::object ret(luabind::from_stack(L, -1));
|
||||
auto IgnoreDefaultObj = ret["IgnoreDefault"];
|
||||
if (luabind::type(IgnoreDefaultObj) == LUA_TBOOLEAN) {
|
||||
ignoreDefault = ignoreDefault || luabind::object_cast<bool>(IgnoreDefaultObj);
|
||||
}
|
||||
|
||||
GetDamageHitInfo(ret, hit);
|
||||
GetExtraAttackOptions(ret, opts);
|
||||
}
|
||||
}
|
||||
catch (std::exception &ex) {
|
||||
parser_->AddError(ex.what());
|
||||
}
|
||||
|
||||
int end = lua_gettop(L);
|
||||
int n = end - start;
|
||||
if (n > 0) {
|
||||
lua_pop(L, n);
|
||||
}
|
||||
}
|
||||
|
||||
void LuaMod::ApplyDamageTable(Mob *self, DamageHitInfo &hit, bool &ignoreDefault) {
|
||||
int start = lua_gettop(L);
|
||||
|
||||
try {
|
||||
if (!m_has_apply_damage_table) {
|
||||
return;
|
||||
}
|
||||
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, package_name_.c_str());
|
||||
lua_getfield(L, -1, "ApplyDamageTable");
|
||||
|
||||
Lua_Mob l_self(self);
|
||||
luabind::adl::object e = luabind::newtable(L);
|
||||
e["self"] = l_self;
|
||||
|
||||
PutDamageHitInfo(L, e, hit);
|
||||
e.push(L);
|
||||
|
||||
if (lua_pcall(L, 1, 1, 0)) {
|
||||
std::string error = lua_tostring(L, -1);
|
||||
parser_->AddError(error);
|
||||
lua_pop(L, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (lua_type(L, -1) == LUA_TTABLE) {
|
||||
luabind::adl::object ret(luabind::from_stack(L, -1));
|
||||
auto IgnoreDefaultObj = ret["IgnoreDefault"];
|
||||
if (luabind::type(IgnoreDefaultObj) == LUA_TBOOLEAN) {
|
||||
ignoreDefault = ignoreDefault || luabind::object_cast<bool>(IgnoreDefaultObj);
|
||||
}
|
||||
|
||||
GetDamageHitInfo(ret, hit);
|
||||
}
|
||||
}
|
||||
catch (std::exception &ex) {
|
||||
parser_->AddError(ex.what());
|
||||
}
|
||||
|
||||
int end = lua_gettop(L);
|
||||
int n = end - start;
|
||||
if (n > 0) {
|
||||
lua_pop(L, n);
|
||||
}
|
||||
}
|
||||
|
||||
void LuaMod::AvoidDamage(Mob *self, Mob *other, DamageHitInfo &hit, bool &returnValue, bool &ignoreDefault) {
|
||||
int start = lua_gettop(L);
|
||||
|
||||
try {
|
||||
if (!m_has_avoid_damage) {
|
||||
return;
|
||||
}
|
||||
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, package_name_.c_str());
|
||||
lua_getfield(L, -1, "AvoidDamage");
|
||||
|
||||
Lua_Mob l_self(self);
|
||||
Lua_Mob l_other(other);
|
||||
luabind::adl::object e = luabind::newtable(L);
|
||||
e["self"] = l_self;
|
||||
e["other"] = l_other;
|
||||
|
||||
PutDamageHitInfo(L, e, hit);
|
||||
e.push(L);
|
||||
|
||||
if (lua_pcall(L, 1, 1, 0)) {
|
||||
std::string error = lua_tostring(L, -1);
|
||||
parser_->AddError(error);
|
||||
lua_pop(L, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (lua_type(L, -1) == LUA_TTABLE) {
|
||||
luabind::adl::object ret(luabind::from_stack(L, -1));
|
||||
auto IgnoreDefaultObj = ret["IgnoreDefault"];
|
||||
if (luabind::type(IgnoreDefaultObj) == LUA_TBOOLEAN) {
|
||||
ignoreDefault = ignoreDefault || luabind::object_cast<bool>(IgnoreDefaultObj);
|
||||
}
|
||||
|
||||
auto returnValueObj = ret["ReturnValue"];
|
||||
if (luabind::type(returnValueObj) == LUA_TBOOLEAN) {
|
||||
returnValue = luabind::object_cast<bool>(returnValueObj);
|
||||
}
|
||||
|
||||
GetDamageHitInfo(ret, hit);
|
||||
}
|
||||
}
|
||||
catch (std::exception &ex) {
|
||||
parser_->AddError(ex.what());
|
||||
}
|
||||
|
||||
int end = lua_gettop(L);
|
||||
int n = end - start;
|
||||
if (n > 0) {
|
||||
lua_pop(L, n);
|
||||
}
|
||||
}
|
||||
|
||||
void LuaMod::CheckHitChance(Mob *self, Mob* other, DamageHitInfo &hit, bool &returnValue, bool &ignoreDefault) {
|
||||
int start = lua_gettop(L);
|
||||
|
||||
try {
|
||||
if (!m_has_check_hit_chance) {
|
||||
return;
|
||||
}
|
||||
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, package_name_.c_str());
|
||||
lua_getfield(L, -1, "CheckHitChance");
|
||||
|
||||
Lua_Mob l_self(self);
|
||||
Lua_Mob l_other(other);
|
||||
luabind::adl::object e = luabind::newtable(L);
|
||||
e["self"] = l_self;
|
||||
e["other"] = l_other;
|
||||
|
||||
PutDamageHitInfo(L, e, hit);
|
||||
e.push(L);
|
||||
|
||||
if (lua_pcall(L, 1, 1, 0)) {
|
||||
std::string error = lua_tostring(L, -1);
|
||||
parser_->AddError(error);
|
||||
lua_pop(L, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (lua_type(L, -1) == LUA_TTABLE) {
|
||||
luabind::adl::object ret(luabind::from_stack(L, -1));
|
||||
auto IgnoreDefaultObj = ret["IgnoreDefault"];
|
||||
if (luabind::type(IgnoreDefaultObj) == LUA_TBOOLEAN) {
|
||||
ignoreDefault = ignoreDefault || luabind::object_cast<bool>(IgnoreDefaultObj);
|
||||
}
|
||||
|
||||
auto returnValueObj = ret["ReturnValue"];
|
||||
if (luabind::type(returnValueObj) == LUA_TBOOLEAN) {
|
||||
returnValue = luabind::object_cast<bool>(returnValueObj);
|
||||
}
|
||||
|
||||
GetDamageHitInfo(ret, hit);
|
||||
}
|
||||
}
|
||||
catch (std::exception &ex) {
|
||||
parser_->AddError(ex.what());
|
||||
}
|
||||
|
||||
int end = lua_gettop(L);
|
||||
int n = end - start;
|
||||
if (n > 0) {
|
||||
lua_pop(L, n);
|
||||
}
|
||||
}
|
||||
|
||||
void LuaMod::CommonOutgoingHitSuccess(Mob *self, Mob *other, DamageHitInfo &hit, ExtraAttackOptions *opts, bool &ignoreDefault)
|
||||
{
|
||||
int start = lua_gettop(L);
|
||||
|
||||
try {
|
||||
if (!m_has_common_outgoing_hit_success) {
|
||||
return;
|
||||
}
|
||||
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, package_name_.c_str());
|
||||
lua_getfield(L, -1, "CommonOutgoingHitSuccess");
|
||||
|
||||
Lua_Mob l_self(self);
|
||||
Lua_Mob l_other(other);
|
||||
luabind::adl::object e = luabind::newtable(L);
|
||||
e["self"] = l_self;
|
||||
e["other"] = l_other;
|
||||
|
||||
PutDamageHitInfo(L, e, hit);
|
||||
PutExtraAttackOptions(L, e, opts);
|
||||
e.push(L);
|
||||
|
||||
if (lua_pcall(L, 1, 1, 0)) {
|
||||
std::string error = lua_tostring(L, -1);
|
||||
parser_->AddError(error);
|
||||
lua_pop(L, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (lua_type(L, -1) == LUA_TTABLE) {
|
||||
luabind::adl::object ret(luabind::from_stack(L, -1));
|
||||
auto IgnoreDefaultObj = ret["IgnoreDefault"];
|
||||
if (luabind::type(IgnoreDefaultObj) == LUA_TBOOLEAN) {
|
||||
ignoreDefault = ignoreDefault || luabind::object_cast<bool>(IgnoreDefaultObj);
|
||||
}
|
||||
|
||||
GetDamageHitInfo(ret, hit);
|
||||
GetExtraAttackOptions(ret, opts);
|
||||
}
|
||||
}
|
||||
catch (std::exception &ex) {
|
||||
parser_->AddError(ex.what());
|
||||
}
|
||||
|
||||
int end = lua_gettop(L);
|
||||
int n = end - start;
|
||||
if (n > 0) {
|
||||
lua_pop(L, n);
|
||||
}
|
||||
}
|
||||
|
||||
void LuaMod::TryCriticalHit(Mob *self, Mob *defender, DamageHitInfo &hit, ExtraAttackOptions *opts, bool &ignoreDefault) {
|
||||
int start = lua_gettop(L);
|
||||
|
||||
try {
|
||||
if (!m_has_try_critical_hit) {
|
||||
return;
|
||||
}
|
||||
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, package_name_.c_str());
|
||||
lua_getfield(L, -1, "TryCriticalHit");
|
||||
|
||||
Lua_Mob l_self(self);
|
||||
Lua_Mob l_other(defender);
|
||||
luabind::adl::object e = luabind::newtable(L);
|
||||
e["self"] = l_self;
|
||||
e["other"] = l_other;
|
||||
|
||||
PutDamageHitInfo(L, e, hit);
|
||||
PutExtraAttackOptions(L, e, opts);
|
||||
e.push(L);
|
||||
|
||||
if (lua_pcall(L, 1, 1, 0)) {
|
||||
std::string error = lua_tostring(L, -1);
|
||||
parser_->AddError(error);
|
||||
lua_pop(L, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (lua_type(L, -1) == LUA_TTABLE) {
|
||||
luabind::adl::object ret(luabind::from_stack(L, -1));
|
||||
auto IgnoreDefaultObj = ret["IgnoreDefault"];
|
||||
if (luabind::type(IgnoreDefaultObj) == LUA_TBOOLEAN) {
|
||||
ignoreDefault = ignoreDefault || luabind::object_cast<bool>(IgnoreDefaultObj);
|
||||
}
|
||||
|
||||
GetDamageHitInfo(ret, hit);
|
||||
GetExtraAttackOptions(ret, opts);
|
||||
}
|
||||
}
|
||||
catch (std::exception &ex) {
|
||||
parser_->AddError(ex.what());
|
||||
}
|
||||
|
||||
int end = lua_gettop(L);
|
||||
int n = end - start;
|
||||
if (n > 0) {
|
||||
lua_pop(L, n);
|
||||
}
|
||||
}
|
||||
|
||||
void LuaMod::GetRequiredAAExperience(Client *self, uint32 &returnValue, bool &ignoreDefault)
|
||||
{
|
||||
int start = lua_gettop(L);
|
||||
|
||||
try {
|
||||
if (!m_has_get_required_aa_experience) {
|
||||
return;
|
||||
}
|
||||
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, package_name_.c_str());
|
||||
lua_getfield(L, -1, "GetRequiredAAExperience");
|
||||
|
||||
Lua_Client l_self(self);
|
||||
luabind::adl::object e = luabind::newtable(L);
|
||||
e["self"] = l_self;
|
||||
e.push(L);
|
||||
|
||||
if (lua_pcall(L, 1, 1, 0)) {
|
||||
std::string error = lua_tostring(L, -1);
|
||||
parser_->AddError(error);
|
||||
lua_pop(L, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (lua_type(L, -1) == LUA_TTABLE) {
|
||||
luabind::adl::object ret(luabind::from_stack(L, -1));
|
||||
auto IgnoreDefaultObj = ret["IgnoreDefault"];
|
||||
if (luabind::type(IgnoreDefaultObj) == LUA_TBOOLEAN) {
|
||||
ignoreDefault = ignoreDefault || luabind::object_cast<bool>(IgnoreDefaultObj);
|
||||
}
|
||||
|
||||
auto returnValueObj = ret["ReturnValue"];
|
||||
if (luabind::type(returnValueObj) == LUA_TNUMBER) {
|
||||
returnValue = luabind::object_cast<uint32>(returnValueObj);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (std::exception &ex) {
|
||||
parser_->AddError(ex.what());
|
||||
}
|
||||
|
||||
int end = lua_gettop(L);
|
||||
int n = end - start;
|
||||
if (n > 0) {
|
||||
lua_pop(L, n);
|
||||
}
|
||||
}
|
||||
|
||||
void LuaMod::GetEXPForLevel(Client *self, uint16 level, uint32 &returnValue, bool &ignoreDefault) {
|
||||
int start = lua_gettop(L);
|
||||
|
||||
try {
|
||||
if (!m_has_get_exp_for_level) {
|
||||
return;
|
||||
}
|
||||
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, package_name_.c_str());
|
||||
lua_getfield(L, -1, "GetEXPForLevel");
|
||||
|
||||
Lua_Client l_self(self);
|
||||
luabind::adl::object e = luabind::newtable(L);
|
||||
e["self"] = l_self;
|
||||
e["level"] = level;
|
||||
e.push(L);
|
||||
|
||||
if (lua_pcall(L, 1, 1, 0)) {
|
||||
std::string error = lua_tostring(L, -1);
|
||||
parser_->AddError(error);
|
||||
lua_pop(L, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (lua_type(L, -1) == LUA_TTABLE) {
|
||||
luabind::adl::object ret(luabind::from_stack(L, -1));
|
||||
auto IgnoreDefaultObj = ret["IgnoreDefault"];
|
||||
if (luabind::type(IgnoreDefaultObj) == LUA_TBOOLEAN) {
|
||||
ignoreDefault = ignoreDefault || luabind::object_cast<bool>(IgnoreDefaultObj);
|
||||
}
|
||||
|
||||
auto returnValueObj = ret["ReturnValue"];
|
||||
if (luabind::type(returnValueObj) == LUA_TNUMBER) {
|
||||
returnValue = luabind::object_cast<uint32>(returnValueObj);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (std::exception &ex) {
|
||||
parser_->AddError(ex.what());
|
||||
}
|
||||
|
||||
int end = lua_gettop(L);
|
||||
int n = end - start;
|
||||
if (n > 0) {
|
||||
lua_pop(L, n);
|
||||
}
|
||||
}
|
||||
|
||||
void LuaMod::GetExperienceForKill(Client *self, Mob *against, uint32 &returnValue, bool &ignoreDefault)
|
||||
{
|
||||
int start = lua_gettop(L);
|
||||
uint32 retval = 0;
|
||||
|
||||
try {
|
||||
if (!m_has_get_experience_for_kill) {
|
||||
return;
|
||||
}
|
||||
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, package_name_.c_str());
|
||||
lua_getfield(L, -1, "GetExperienceForKill");
|
||||
|
||||
Lua_Client l_self(self);
|
||||
Lua_Mob l_other(against);
|
||||
luabind::adl::object e = luabind::newtable(L);
|
||||
e["self"] = l_self;
|
||||
e["other"] = l_other;
|
||||
e.push(L);
|
||||
|
||||
if (lua_pcall(L, 1, 1, 0)) {
|
||||
std::string error = lua_tostring(L, -1);
|
||||
parser_->AddError(error);
|
||||
lua_pop(L, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (lua_type(L, -1) == LUA_TTABLE) {
|
||||
luabind::adl::object ret(luabind::from_stack(L, -1));
|
||||
auto IgnoreDefaultObj = ret["IgnoreDefault"];
|
||||
if (luabind::type(IgnoreDefaultObj) == LUA_TBOOLEAN) {
|
||||
ignoreDefault = ignoreDefault || luabind::object_cast<bool>(IgnoreDefaultObj);
|
||||
}
|
||||
|
||||
auto returnValueObj = ret["ReturnValue"];
|
||||
if (luabind::type(returnValueObj) == LUA_TNUMBER) {
|
||||
returnValue = luabind::object_cast<uint32>(returnValueObj);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (std::exception &ex) {
|
||||
parser_->AddError(ex.what());
|
||||
}
|
||||
|
||||
int end = lua_gettop(L);
|
||||
int n = end - start;
|
||||
if (n > 0) {
|
||||
lua_pop(L, n);
|
||||
}
|
||||
}
|
||||
43
zone/lua_mod.h
Normal file
43
zone/lua_mod.h
Normal file
@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
struct lua_State;
|
||||
|
||||
class LuaParser;
|
||||
class LuaMod
|
||||
{
|
||||
public:
|
||||
LuaMod(lua_State *ls, LuaParser *lp, const std::string &package_name) {
|
||||
L = ls;
|
||||
parser_ = lp;
|
||||
package_name_ = package_name;
|
||||
Init();
|
||||
}
|
||||
~LuaMod() { }
|
||||
void Init();
|
||||
|
||||
void MeleeMitigation(Mob *self, Mob *attacker, DamageHitInfo &hit, ExtraAttackOptions *opts, bool &ignoreDefault);
|
||||
void ApplyDamageTable(Mob *self, DamageHitInfo &hit, bool &ignoreDefault);
|
||||
void AvoidDamage(Mob *self, Mob *other, DamageHitInfo &hit, bool &returnValue, bool &ignoreDefault);
|
||||
void CheckHitChance(Mob *self, Mob* other, DamageHitInfo &hit, bool &returnValue, bool &ignoreDefault);
|
||||
void CommonOutgoingHitSuccess(Mob *self, Mob* other, DamageHitInfo &hit, ExtraAttackOptions *opts, bool &ignoreDefault);
|
||||
void TryCriticalHit(Mob *self, Mob *defender, DamageHitInfo &hit, ExtraAttackOptions *opts, bool &ignoreDefault);
|
||||
void GetRequiredAAExperience(Client *self, uint32 &returnValue, bool &ignoreDefault);
|
||||
void GetEXPForLevel(Client *self, uint16 level, uint32 &returnValue, bool &ignoreDefault);
|
||||
void GetExperienceForKill(Client *self, Mob *against, uint32 &returnValue, bool &ignoreDefault);
|
||||
private:
|
||||
LuaParser *parser_;
|
||||
lua_State *L;
|
||||
std::string package_name_;
|
||||
|
||||
bool m_has_melee_mitigation;
|
||||
bool m_has_apply_damage_table;
|
||||
bool m_has_avoid_damage;
|
||||
bool m_has_check_hit_chance;
|
||||
bool m_has_common_outgoing_hit_success;
|
||||
bool m_has_try_critical_hit;
|
||||
bool m_has_get_required_aa_experience;
|
||||
bool m_has_get_exp_for_level;
|
||||
bool m_has_get_experience_for_kill;
|
||||
};
|
||||
@ -498,6 +498,17 @@ uint8 Lua_NPC::GetMerchantProbability() {
|
||||
return self->GetMerchantProbability();
|
||||
}
|
||||
|
||||
int Lua_NPC::GetRawAC() {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetRawAC();
|
||||
}
|
||||
|
||||
int Lua_NPC::GetAvoidanceRating()
|
||||
{
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetAvoidanceRating();
|
||||
}
|
||||
|
||||
luabind::scope lua_register_npc() {
|
||||
return luabind::class_<Lua_NPC, Lua_Mob>("NPC")
|
||||
.def(luabind::constructor<>())
|
||||
@ -598,7 +609,9 @@ luabind::scope lua_register_npc() {
|
||||
.def("MerchantOpenShop", (void(Lua_NPC::*)(void))&Lua_NPC::MerchantOpenShop)
|
||||
.def("MerchantCloseShop", (void(Lua_NPC::*)(void))&Lua_NPC::MerchantCloseShop)
|
||||
.def("SetMerchantProbability", (void(Lua_NPC::*)(void))&Lua_NPC::SetMerchantProbability)
|
||||
.def("GetMerchantProbability", (uint8(Lua_NPC::*)(void))&Lua_NPC::GetMerchantProbability);
|
||||
.def("GetMerchantProbability", (uint8(Lua_NPC::*)(void))&Lua_NPC::GetMerchantProbability)
|
||||
.def("GetRawAC", (int(Lua_NPC::*)(void))&Lua_NPC::GetRawAC)
|
||||
.def("GetAvoidanceRating", &Lua_NPC::GetAvoidanceRating);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -125,6 +125,8 @@ public:
|
||||
void MerchantCloseShop();
|
||||
void SetMerchantProbability(uint8 amt);
|
||||
uint8 GetMerchantProbability();
|
||||
int GetRawAC();
|
||||
int GetAvoidanceRating();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -10,8 +10,13 @@
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#include "masterentity.h"
|
||||
#include "../common/spdat.h"
|
||||
#include "masterentity.h"
|
||||
#include "questmgr.h"
|
||||
#include "zone.h"
|
||||
#include "zone_config.h"
|
||||
|
||||
#include "lua_parser.h"
|
||||
#include "lua_bit.h"
|
||||
#include "lua_entity.h"
|
||||
#include "lua_item.h"
|
||||
@ -31,11 +36,8 @@
|
||||
#include "lua_spawn.h"
|
||||
#include "lua_packet.h"
|
||||
#include "lua_general.h"
|
||||
#include "questmgr.h"
|
||||
#include "zone.h"
|
||||
#include "zone_config.h"
|
||||
#include "lua_parser.h"
|
||||
#include "lua_encounter.h"
|
||||
#include "lua_stat_bonuses.h"
|
||||
|
||||
const char *LuaEvents[_LargestEventID] = {
|
||||
"event_say",
|
||||
@ -799,12 +801,14 @@ void LuaParser::Init() {
|
||||
void LuaParser::ReloadQuests() {
|
||||
loaded_.clear();
|
||||
errors_.clear();
|
||||
mods_.clear();
|
||||
lua_encounter_events_registered.clear();
|
||||
lua_encounters_loaded.clear();
|
||||
|
||||
for (auto encounter : lua_encounters) {
|
||||
encounter.second->Depop();
|
||||
}
|
||||
|
||||
lua_encounters.clear();
|
||||
// so the Depop function above depends on the Process being called again so ...
|
||||
// And there is situations where it wouldn't be :P
|
||||
@ -817,6 +821,8 @@ void LuaParser::ReloadQuests() {
|
||||
L = luaL_newstate();
|
||||
luaL_openlibs(L);
|
||||
|
||||
auto top = lua_gettop(L);
|
||||
|
||||
if(luaopen_bit(L) != 1) {
|
||||
std::string error = lua_tostring(L, -1);
|
||||
AddError(error);
|
||||
@ -830,7 +836,7 @@ void LuaParser::ReloadQuests() {
|
||||
#ifdef SANITIZE_LUA_LIBS
|
||||
//io
|
||||
lua_pushnil(L);
|
||||
lua_setglobal(L, "io");
|
||||
//lua_setglobal(L, "io");
|
||||
|
||||
//some os/debug are okay some are not
|
||||
lua_getglobal(L, "os");
|
||||
@ -933,24 +939,48 @@ void LuaParser::ReloadQuests() {
|
||||
std::string error = lua_tostring(L, -1);
|
||||
AddError(error);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
else {
|
||||
zone_script = Config->QuestDir;
|
||||
zone_script += "/";
|
||||
zone_script += zone->GetShortName();
|
||||
zone_script += "/script_init.lua";
|
||||
f = fopen(zone_script.c_str(), "r");
|
||||
if (f) {
|
||||
fclose(f);
|
||||
|
||||
zone_script = Config->QuestDir;
|
||||
zone_script += "/";
|
||||
zone_script += zone->GetShortName();
|
||||
zone_script += "/script_init.lua";
|
||||
f = fopen(zone_script.c_str(), "r");
|
||||
if(f) {
|
||||
fclose(f);
|
||||
|
||||
if(luaL_dofile(L, zone_script.c_str())) {
|
||||
std::string error = lua_tostring(L, -1);
|
||||
AddError(error);
|
||||
if (luaL_dofile(L, zone_script.c_str())) {
|
||||
std::string error = lua_tostring(L, -1);
|
||||
AddError(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FILE *load_order = fopen("mods/load_order.txt", "r");
|
||||
if (load_order) {
|
||||
char file_name[256] = { 0 };
|
||||
while (fgets(file_name, 256, load_order) != nullptr) {
|
||||
for (int i = 0; i < 256; ++i) {
|
||||
auto c = file_name[i];
|
||||
if (c == '\n' || c == '\r' || c == ' ') {
|
||||
file_name[i] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LoadScript("mods/" + std::string(file_name), file_name);
|
||||
mods_.push_back(LuaMod(L, this, file_name));
|
||||
}
|
||||
|
||||
fclose(load_order);
|
||||
}
|
||||
|
||||
auto end = lua_gettop(L);
|
||||
int n = end - top;
|
||||
if (n > 0) {
|
||||
lua_pop(L, n);
|
||||
}
|
||||
}
|
||||
|
||||
void LuaParser::LoadScript(std::string filename, std::string package_name) {
|
||||
@ -959,6 +989,7 @@ void LuaParser::LoadScript(std::string filename, std::string package_name) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto top = lua_gettop(L);
|
||||
if(luaL_loadfile(L, filename.c_str())) {
|
||||
std::string error = lua_tostring(L, -1);
|
||||
AddError(error);
|
||||
@ -986,14 +1017,20 @@ void LuaParser::LoadScript(std::string filename, std::string package_name) {
|
||||
std::string error = lua_tostring(L, -1);
|
||||
AddError(error);
|
||||
lua_pop(L, 1);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
loaded_[package_name] = true;
|
||||
}
|
||||
|
||||
loaded_[package_name] = true;
|
||||
auto end = lua_gettop(L);
|
||||
int n = end - top;
|
||||
if (n > 0) {
|
||||
lua_pop(L, n);
|
||||
}
|
||||
}
|
||||
|
||||
bool LuaParser::HasFunction(std::string subname, std::string package_name) {
|
||||
std::transform(subname.begin(), subname.end(), subname.begin(), ::tolower);
|
||||
//std::transform(subname.begin(), subname.end(), subname.begin(), ::tolower);
|
||||
|
||||
auto iter = loaded_.find(package_name);
|
||||
if(iter == loaded_.end()) {
|
||||
@ -1020,12 +1057,18 @@ void LuaParser::MapFunctions(lua_State *L) {
|
||||
luabind::module(L)
|
||||
[
|
||||
lua_register_general(),
|
||||
lua_register_random(),
|
||||
lua_register_events(),
|
||||
lua_register_faction(),
|
||||
lua_register_slot(),
|
||||
lua_register_material(),
|
||||
lua_register_client_version(),
|
||||
lua_register_appearance(),
|
||||
lua_register_classes(),
|
||||
lua_register_skills(),
|
||||
lua_register_bodytypes(),
|
||||
lua_register_filters(),
|
||||
lua_register_message_types(),
|
||||
lua_register_entity(),
|
||||
lua_register_encounter(),
|
||||
lua_register_mob(),
|
||||
@ -1054,7 +1097,12 @@ void LuaParser::MapFunctions(lua_State *L) {
|
||||
lua_register_door(),
|
||||
lua_register_object(),
|
||||
lua_register_packet(),
|
||||
lua_register_packet_opcodes()
|
||||
lua_register_packet_opcodes(),
|
||||
lua_register_stat_bonuses(),
|
||||
lua_register_rules_const(),
|
||||
lua_register_rulei(),
|
||||
lua_register_ruler(),
|
||||
lua_register_ruleb()
|
||||
];
|
||||
|
||||
} catch(std::exception &ex) {
|
||||
@ -1251,3 +1299,76 @@ QuestEventID LuaParser::ConvertLuaEvent(QuestEventID evt) {
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void LuaParser::MeleeMitigation(Mob *self, Mob *attacker, DamageHitInfo &hit, ExtraAttackOptions *opts, bool &ignoreDefault)
|
||||
{
|
||||
for (auto &mod : mods_) {
|
||||
mod.MeleeMitigation(self, attacker, hit, opts, ignoreDefault);
|
||||
}
|
||||
}
|
||||
|
||||
void LuaParser::ApplyDamageTable(Mob *self, DamageHitInfo &hit, bool &ignoreDefault)
|
||||
{
|
||||
for (auto &mod : mods_) {
|
||||
mod.ApplyDamageTable(self, hit, ignoreDefault);
|
||||
}
|
||||
}
|
||||
|
||||
bool LuaParser::AvoidDamage(Mob *self, Mob *other, DamageHitInfo &hit, bool & ignoreDefault)
|
||||
{
|
||||
bool retval = false;
|
||||
for (auto &mod : mods_) {
|
||||
mod.AvoidDamage(self, other, hit, retval, ignoreDefault);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
bool LuaParser::CheckHitChance(Mob *self, Mob *other, DamageHitInfo &hit, bool &ignoreDefault)
|
||||
{
|
||||
bool retval = false;
|
||||
for (auto &mod : mods_) {
|
||||
mod.CheckHitChance(self, other, hit, retval, ignoreDefault);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
void LuaParser::TryCriticalHit(Mob *self, Mob *defender, DamageHitInfo &hit, ExtraAttackOptions *opts, bool &ignoreDefault)
|
||||
{
|
||||
for (auto &mod : mods_) {
|
||||
mod.TryCriticalHit(self, defender, hit, opts, ignoreDefault);
|
||||
}
|
||||
}
|
||||
|
||||
void LuaParser::CommonOutgoingHitSuccess(Mob *self, Mob *other, DamageHitInfo &hit, ExtraAttackOptions *opts, bool &ignoreDefault)
|
||||
{
|
||||
for (auto &mod : mods_) {
|
||||
mod.CommonOutgoingHitSuccess(self, other, hit, opts, ignoreDefault);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 LuaParser::GetRequiredAAExperience(Client *self, bool &ignoreDefault)
|
||||
{
|
||||
uint32 retval = 0;
|
||||
for (auto &mod : mods_) {
|
||||
mod.GetRequiredAAExperience(self, retval, ignoreDefault);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
uint32 LuaParser::GetEXPForLevel(Client *self, uint16 level, bool &ignoreDefault)
|
||||
{
|
||||
uint32 retval = 0;
|
||||
for (auto &mod : mods_) {
|
||||
mod.GetEXPForLevel(self, level, retval, ignoreDefault);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
uint32 LuaParser::GetExperienceForKill(Client *self, Mob *against, bool &ignoreDefault)
|
||||
{
|
||||
uint32 retval = 0;
|
||||
for (auto &mod : mods_) {
|
||||
mod.GetExperienceForKill(self, against, retval, ignoreDefault);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -7,8 +7,10 @@
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <exception>
|
||||
|
||||
#include "zone_config.h"
|
||||
#include "lua_mod.h"
|
||||
|
||||
extern const ZoneConfig *Config;
|
||||
|
||||
@ -32,7 +34,6 @@ namespace luabind {
|
||||
|
||||
class LuaParser : public QuestInterface {
|
||||
public:
|
||||
LuaParser();
|
||||
~LuaParser();
|
||||
|
||||
virtual int EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||
@ -81,7 +82,29 @@ public:
|
||||
virtual int DispatchEventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data,
|
||||
std::vector<EQEmu::Any> *extra_pointers);
|
||||
|
||||
static LuaParser* Instance() {
|
||||
static LuaParser inst;
|
||||
return &inst;
|
||||
}
|
||||
|
||||
bool HasFunction(std::string function, std::string package_name);
|
||||
|
||||
//Mod Extensions
|
||||
void MeleeMitigation(Mob *self, Mob *attacker, DamageHitInfo &hit, ExtraAttackOptions *opts, bool &ignoreDefault);
|
||||
void ApplyDamageTable(Mob *self, DamageHitInfo &hit, bool &ignoreDefault);
|
||||
bool AvoidDamage(Mob *self, Mob *other, DamageHitInfo &hit, bool &ignoreDefault);
|
||||
bool CheckHitChance(Mob *self, Mob* other, DamageHitInfo &hit, bool &ignoreDefault);
|
||||
void TryCriticalHit(Mob *self, Mob *defender, DamageHitInfo &hit, ExtraAttackOptions *opts, bool &ignoreDefault);
|
||||
void CommonOutgoingHitSuccess(Mob *self, Mob* other, DamageHitInfo &hit, ExtraAttackOptions *opts, bool &ignoreDefault);
|
||||
uint32 GetRequiredAAExperience(Client *self, bool &ignoreDefault);
|
||||
uint32 GetEXPForLevel(Client *self, uint16 level, bool &ignoreDefault);
|
||||
uint32 GetExperienceForKill(Client *self, Mob *against, bool &ignoreDefault);
|
||||
|
||||
private:
|
||||
LuaParser();
|
||||
LuaParser(const LuaParser&);
|
||||
LuaParser& operator=(const LuaParser&);
|
||||
|
||||
int _EventNPC(std::string package_name, QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||
std::vector<EQEmu::Any> *extra_pointers, luabind::adl::object *l_func = nullptr);
|
||||
int _EventPlayer(std::string package_name, QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
||||
@ -94,13 +117,12 @@ private:
|
||||
std::vector<EQEmu::Any> *extra_pointers);
|
||||
|
||||
void LoadScript(std::string filename, std::string package_name);
|
||||
bool HasFunction(std::string function, std::string package_name);
|
||||
void ClearStates();
|
||||
void MapFunctions(lua_State *L);
|
||||
QuestEventID ConvertLuaEvent(QuestEventID evt);
|
||||
|
||||
std::map<std::string, std::string> vars_;
|
||||
std::map<std::string, bool> loaded_;
|
||||
std::vector<LuaMod> mods_;
|
||||
lua_State *L;
|
||||
|
||||
NPCArgumentHandler NPCArgumentDispatch[_LargestEventID];
|
||||
|
||||
@ -2,13 +2,21 @@
|
||||
#define EQEMU_LUA_PTR_H
|
||||
#ifdef LUA_EQEMU
|
||||
|
||||
//TODO: Remove the error checking by a flag since this adds significant overhead to each c call
|
||||
#ifndef EQEMU_UNSAFE_LUA
|
||||
#define Lua_Safe_Call_Void() if(!d_) { return; } NativeType *self = reinterpret_cast<NativeType*>(d_)
|
||||
#define Lua_Safe_Call_Bool() if(!d_) { return false; } NativeType *self = reinterpret_cast<NativeType*>(d_)
|
||||
#define Lua_Safe_Call_Int() if(!d_) { return 0; } NativeType *self = reinterpret_cast<NativeType*>(d_)
|
||||
#define Lua_Safe_Call_Real() if(!d_) { return 0.0; } NativeType *self = reinterpret_cast<NativeType*>(d_)
|
||||
#define Lua_Safe_Call_String() if(!d_) { return ""; } NativeType *self = reinterpret_cast<NativeType*>(d_)
|
||||
#define Lua_Safe_Call_Class(type) if(!d_) { return type(); } NativeType *self = reinterpret_cast<NativeType*>(d_)
|
||||
#else
|
||||
#define Lua_Safe_Call_Void() NativeType *self = reinterpret_cast<NativeType*>(d_)
|
||||
#define Lua_Safe_Call_Bool() NativeType *self = reinterpret_cast<NativeType*>(d_)
|
||||
#define Lua_Safe_Call_Int() NativeType *self = reinterpret_cast<NativeType*>(d_)
|
||||
#define Lua_Safe_Call_Real() NativeType *self = reinterpret_cast<NativeType*>(d_)
|
||||
#define Lua_Safe_Call_String() NativeType *self = reinterpret_cast<NativeType*>(d_)
|
||||
#define Lua_Safe_Call_Class(type) NativeType *self = reinterpret_cast<NativeType*>(d_)
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
class Lua_Ptr
|
||||
|
||||
1539
zone/lua_stat_bonuses.cpp
Normal file
1539
zone/lua_stat_bonuses.cpp
Normal file
File diff suppressed because it is too large
Load Diff
285
zone/lua_stat_bonuses.h
Normal file
285
zone/lua_stat_bonuses.h
Normal file
@ -0,0 +1,285 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef LUA_EQEMU
|
||||
|
||||
#include "lua_ptr.h"
|
||||
#include "common.h"
|
||||
|
||||
struct StatBonuses;
|
||||
|
||||
namespace luabind {
|
||||
struct scope;
|
||||
}
|
||||
|
||||
luabind::scope lua_register_stat_bonuses();
|
||||
|
||||
class Lua_StatBonuses : public Lua_Ptr<StatBonuses>
|
||||
{
|
||||
typedef StatBonuses NativeType;
|
||||
public:
|
||||
Lua_StatBonuses() : Lua_Ptr(nullptr) { }
|
||||
Lua_StatBonuses(StatBonuses *d) : Lua_Ptr(d) { }
|
||||
virtual ~Lua_StatBonuses() { }
|
||||
|
||||
operator StatBonuses*() {
|
||||
return reinterpret_cast<StatBonuses*>(GetLuaPtrData());
|
||||
}
|
||||
|
||||
int32 GetAC() const;
|
||||
int32 GetHP() const;
|
||||
int32 GetHPRegen() const;
|
||||
int32 GetMaxHP() const;
|
||||
int32 GetManaRegen() const;
|
||||
int32 GetEnduranceRegen() const;
|
||||
int32 GetMana() const;
|
||||
int32 GetEndurance() const;
|
||||
int32 GetATK() const;
|
||||
int32 GetSTR() const;
|
||||
int32 GetSTRCapMod() const;
|
||||
int32 GetHeroicSTR() const;
|
||||
int32 GetSTA() const;
|
||||
int32 GetSTACapMod() const;
|
||||
int32 GetHeroicSTA() const;
|
||||
int32 GetDEX() const;
|
||||
int32 GetDEXCapMod() const;
|
||||
int32 GetHeroicDEX() const;
|
||||
int32 GetAGI() const;
|
||||
int32 GetAGICapMod() const;
|
||||
int32 GetHeroicAGI() const;
|
||||
int32 GetINT() const;
|
||||
int32 GetINTCapMod() const;
|
||||
int32 GetHeroicINT() const;
|
||||
int32 GetWIS() const;
|
||||
int32 GetWISCapMod() const;
|
||||
int32 GetHeroicWIS() const;
|
||||
int32 GetCHA() const;
|
||||
int32 GetCHACapMod() const;
|
||||
int32 GetHeroicCHA() const;
|
||||
int32 GetMR() const;
|
||||
int32 GetMRCapMod() const;
|
||||
int32 GetHeroicMR() const;
|
||||
int32 GetFR() const;
|
||||
int32 GetFRCapMod() const;
|
||||
int32 GetHeroicFR() const;
|
||||
int32 GetCR() const;
|
||||
int32 GetCRCapMod() const;
|
||||
int32 GetHeroicCR() const;
|
||||
int32 GetPR() const;
|
||||
int32 GetPRCapMod() const;
|
||||
int32 GetHeroicPR() const;
|
||||
int32 GetDR() const;
|
||||
int32 GetDRCapMod() const;
|
||||
int32 GetHeroicDR() const;
|
||||
int32 GetCorrup() const;
|
||||
int32 GetCorrupCapMod() const;
|
||||
int32 GetHeroicCorrup() const;
|
||||
uint16 GetDamageShieldSpellID() const;
|
||||
int GetDamageShield() const;
|
||||
int GetDamageShieldType() const;
|
||||
int GetSpellDamageShield() const;
|
||||
int GetSpellShield() const;
|
||||
int GetReverseDamageShield() const;
|
||||
uint16 GetReverseDamageShieldSpellID() const;
|
||||
int GetReverseDamageShieldType() const;
|
||||
int Getmovementspeed() const;
|
||||
int32 Gethaste() const;
|
||||
int32 Gethastetype2() const;
|
||||
int32 Gethastetype3() const;
|
||||
int32 Getinhibitmelee() const;
|
||||
float GetAggroRange() const;
|
||||
float GetAssistRange() const;
|
||||
int32 Getskillmod(int idx) const;
|
||||
int32 Getskillmodmax(int idx) const;
|
||||
int Geteffective_casting_level() const;
|
||||
int Getreflect_chance() const;
|
||||
uint32 GetsingingMod() const;
|
||||
uint32 GetAmplification() const;
|
||||
uint32 GetbrassMod() const;
|
||||
uint32 GetpercussionMod() const;
|
||||
uint32 GetwindMod() const;
|
||||
uint32 GetstringedMod() const;
|
||||
uint32 GetsongModCap() const;
|
||||
int8 Gethatemod() const;
|
||||
int32 GetEnduranceReduction() const;
|
||||
int32 GetStrikeThrough() const;
|
||||
int32 GetMeleeMitigation() const;
|
||||
int32 GetMeleeMitigationEffect() const;
|
||||
int32 GetCriticalHitChance(int idx) const;
|
||||
int32 GetCriticalSpellChance() const;
|
||||
int32 GetSpellCritDmgIncrease() const;
|
||||
int32 GetSpellCritDmgIncNoStack() const;
|
||||
int32 GetDotCritDmgIncrease() const;
|
||||
int32 GetCriticalHealChance() const;
|
||||
int32 GetCriticalHealOverTime() const;
|
||||
int32 GetCriticalDoTChance() const;
|
||||
int32 GetCrippBlowChance() const;
|
||||
int32 GetAvoidMeleeChance() const;
|
||||
int32 GetAvoidMeleeChanceEffect() const;
|
||||
int32 GetRiposteChance() const;
|
||||
int32 GetDodgeChance() const;
|
||||
int32 GetParryChance() const;
|
||||
int32 GetDualWieldChance() const;
|
||||
int32 GetDoubleAttackChance() const;
|
||||
int32 GetTripleAttackChance() const;
|
||||
int32 GetDoubleRangedAttack() const;
|
||||
int32 GetResistSpellChance() const;
|
||||
int32 GetResistFearChance() const;
|
||||
bool GetFearless() const;
|
||||
bool GetIsFeared() const;
|
||||
bool GetIsBlind() const;
|
||||
int32 GetStunResist() const;
|
||||
int32 GetMeleeSkillCheck() const;
|
||||
uint8 GetMeleeSkillCheckSkill() const;
|
||||
int32 GetHitChance() const;
|
||||
int32 GetHitChanceEffect(int idx) const;
|
||||
int32 GetDamageModifier(int idx) const;
|
||||
int32 GetDamageModifier2(int idx) const;
|
||||
int32 GetMinDamageModifier(int idx) const;
|
||||
int32 GetProcChance() const;
|
||||
int32 GetProcChanceSPA() const;
|
||||
int32 GetExtraAttackChance() const;
|
||||
int32 GetDoTShielding() const;
|
||||
int32 GetFlurryChance() const;
|
||||
int32 GetHundredHands() const;
|
||||
int32 GetMeleeLifetap() const;
|
||||
int32 GetVampirism() const;
|
||||
int32 GetHealRate() const;
|
||||
int32 GetMaxHPChange() const;
|
||||
int32 GetHealAmt() const;
|
||||
int32 GetSpellDmg() const;
|
||||
int32 GetClairvoyance() const;
|
||||
int32 GetDSMitigation() const;
|
||||
int32 GetDSMitigationOffHand() const;
|
||||
int32 GetTwoHandBluntBlock() const;
|
||||
uint32 GetItemManaRegenCap() const;
|
||||
int32 GetGravityEffect() const;
|
||||
bool GetAntiGate() const;
|
||||
bool GetMagicWeapon() const;
|
||||
int32 GetIncreaseBlockChance() const;
|
||||
uint32 GetPersistantCasting() const;
|
||||
int GetXPRateMod() const;
|
||||
bool GetBlockNextSpell() const;
|
||||
bool GetImmuneToFlee() const;
|
||||
uint32 GetVoiceGraft() const;
|
||||
int32 GetSpellProcChance() const;
|
||||
int32 GetCharmBreakChance() const;
|
||||
int32 GetSongRange() const;
|
||||
uint32 GetHPToManaConvert() const;
|
||||
bool GetNegateEffects() const;
|
||||
bool GetTriggerMeleeThreshold() const;
|
||||
bool GetTriggerSpellThreshold() const;
|
||||
int32 GetShieldBlock() const;
|
||||
int32 GetBlockBehind() const;
|
||||
bool GetCriticalRegenDecay() const;
|
||||
bool GetCriticalHealDecay() const;
|
||||
bool GetCriticalDotDecay() const;
|
||||
bool GetDivineAura() const;
|
||||
bool GetDistanceRemoval() const;
|
||||
int32 GetFrenziedDevastation() const;
|
||||
bool GetNegateIfCombat() const;
|
||||
int8 GetScreech() const;
|
||||
int32 GetAlterNPCLevel() const;
|
||||
bool GetBerserkSPA() const;
|
||||
int32 GetMetabolism() const;
|
||||
bool GetSanctuary() const;
|
||||
int32 GetFactionModPct() const;
|
||||
uint32 GetPC_Pet_Flurry() const;
|
||||
int8 GetPackrat() const;
|
||||
uint8 GetBuffSlotIncrease() const;
|
||||
uint32 GetDelayDeath() const;
|
||||
int8 GetBaseMovementSpeed() const;
|
||||
uint8 GetIncreaseRunSpeedCap() const;
|
||||
int32 GetDoubleSpecialAttack() const;
|
||||
uint8 GetFrontalStunResist() const;
|
||||
int32 GetBindWound() const;
|
||||
int32 GetMaxBindWound() const;
|
||||
int32 GetChannelChanceSpells() const;
|
||||
int32 GetChannelChanceItems() const;
|
||||
uint8 GetSeeInvis() const;
|
||||
uint8 GetTripleBackstab() const;
|
||||
bool GetFrontalBackstabMinDmg() const;
|
||||
uint8 GetFrontalBackstabChance() const;
|
||||
uint8 GetConsumeProjectile() const;
|
||||
uint8 GetForageAdditionalItems() const;
|
||||
uint8 GetSalvageChance() const;
|
||||
uint32 GetArcheryDamageModifier() const;
|
||||
bool GetSecondaryDmgInc() const;
|
||||
uint32 GetGiveDoubleAttack() const;
|
||||
int32 GetPetCriticalHit() const;
|
||||
int32 GetPetAvoidance() const;
|
||||
int32 GetCombatStability() const;
|
||||
int32 GetDoubleRiposte() const;
|
||||
int32 GetAmbidexterity() const;
|
||||
int32 GetPetMaxHP() const;
|
||||
int32 GetPetFlurry() const;
|
||||
uint8 GetMasteryofPast() const;
|
||||
bool GetGivePetGroupTarget() const;
|
||||
int32 GetRootBreakChance() const;
|
||||
int32 GetUnfailingDivinity() const;
|
||||
int32 GetItemHPRegenCap() const;
|
||||
int32 GetOffhandRiposteFail() const;
|
||||
int32 GetItemATKCap() const;
|
||||
int32 GetShieldEquipDmgMod() const;
|
||||
bool GetTriggerOnValueAmount() const;
|
||||
int8 GetStunBashChance() const;
|
||||
int8 GetIncreaseChanceMemwipe() const;
|
||||
int8 GetCriticalMend() const;
|
||||
int32 GetImprovedReclaimEnergy() const;
|
||||
int32 GetPetMeleeMitigation() const;
|
||||
bool GetIllusionPersistence() const;
|
||||
uint16 Getextra_xtargets() const;
|
||||
bool GetShroudofStealth() const;
|
||||
uint16 GetReduceFallDamage() const;
|
||||
uint8 GetTradeSkillMastery() const;
|
||||
int16 GetNoBreakAESneak() const;
|
||||
int16 GetFeignedCastOnChance() const;
|
||||
int32 GetDivineSaveChance(int idx) const;
|
||||
uint32 GetDeathSave(int idx) const;
|
||||
int32 GetAccuracy(int idx) const;
|
||||
int16 GetSkillDmgTaken(int idx) const;
|
||||
uint32 GetSpellTriggers(int idx) const;
|
||||
uint32 GetSpellOnKill(int idx) const;
|
||||
uint32 GetSpellOnDeath(int idx) const;
|
||||
int32 GetCritDmgMod(int idx) const;
|
||||
int32 GetSkillReuseTime(int idx) const;
|
||||
int32 GetSkillDamageAmount(int idx) const;
|
||||
int GetHPPercCap(int idx) const;
|
||||
int GetManaPercCap(int idx) const;
|
||||
int GetEndPercCap(int idx) const;
|
||||
uint8 GetFocusEffects(int idx) const;
|
||||
int16 GetFocusEffectsWorn(int idx) const;
|
||||
int32 GetSkillDamageAmount2(int idx) const;
|
||||
uint32 GetNegateAttacks(int idx) const;
|
||||
uint32 GetMitigateMeleeRune(int idx) const;
|
||||
uint32 GetMeleeThresholdGuard(int idx) const;
|
||||
uint32 GetSpellThresholdGuard(int idx) const;
|
||||
uint32 GetMitigateSpellRune(int idx) const;
|
||||
uint32 GetMitigateDotRune(int idx) const;
|
||||
uint32 GetManaAbsorbPercentDamage(int idx) const;
|
||||
int32 GetImprovedTaunt(int idx) const;
|
||||
int8 GetRoot(int idx) const;
|
||||
uint32 GetAbsorbMagicAtt(int idx) const;
|
||||
uint32 GetMeleeRune(int idx) const;
|
||||
int32 GetAStacker(int idx) const;
|
||||
int32 GetBStacker(int idx) const;
|
||||
int32 GetCStacker(int idx) const;
|
||||
int32 GetDStacker(int idx) const;
|
||||
bool GetLimitToSkill(int idx) const;
|
||||
uint32 GetSkillProc(int idx) const;
|
||||
uint32 GetSkillProcSuccess(int idx) const;
|
||||
uint32 GetPC_Pet_Rampage(int idx) const;
|
||||
int32 GetSkillAttackProc(int idx) const;
|
||||
int32 GetSlayUndead(int idx) const;
|
||||
int32 GetGiveDoubleRiposte(int idx) const;
|
||||
uint32 GetRaiseSkillCap(int idx) const;
|
||||
int32 GetSEResist(int idx) const;
|
||||
int32 GetFinishingBlow(int idx) const;
|
||||
uint32 GetFinishingBlowLvl(int idx) const;
|
||||
uint32 GetHeadShot(int idx) const;
|
||||
uint8 GetHSLevel(int idx) const;
|
||||
uint32 GetAssassinate(int idx) const;
|
||||
uint8 GetAssassinateLevel(int idx) const;
|
||||
int32 GetReduceTradeskillFail(int idx) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -4677,16 +4677,13 @@ bool Mob::TrySpellOnDeath()
|
||||
//in death because the heal will not register before the script kills you.
|
||||
}
|
||||
|
||||
int16 Mob::GetCritDmgMob(uint16 skill)
|
||||
int16 Mob::GetCritDmgMod(uint16 skill)
|
||||
{
|
||||
int critDmg_mod = 0;
|
||||
|
||||
// All skill dmg mod + Skill specific
|
||||
critDmg_mod += itembonuses.CritDmgMob[EQEmu::skills::HIGHEST_SKILL + 1] + spellbonuses.CritDmgMob[EQEmu::skills::HIGHEST_SKILL + 1] + aabonuses.CritDmgMob[EQEmu::skills::HIGHEST_SKILL + 1] +
|
||||
itembonuses.CritDmgMob[skill] + spellbonuses.CritDmgMob[skill] + aabonuses.CritDmgMob[skill];
|
||||
|
||||
if(critDmg_mod < -100)
|
||||
critDmg_mod = -100;
|
||||
critDmg_mod += itembonuses.CritDmgMod[EQEmu::skills::HIGHEST_SKILL + 1] + spellbonuses.CritDmgMod[EQEmu::skills::HIGHEST_SKILL + 1] + aabonuses.CritDmgMod[EQEmu::skills::HIGHEST_SKILL + 1] +
|
||||
itembonuses.CritDmgMod[skill] + spellbonuses.CritDmgMod[skill] + aabonuses.CritDmgMod[skill];
|
||||
|
||||
return critDmg_mod;
|
||||
}
|
||||
|
||||
11
zone/mob.h
11
zone/mob.h
@ -233,7 +233,7 @@ public:
|
||||
inline bool SeeImprovedHide() const { return see_improved_hide; }
|
||||
bool IsInvisible(Mob* other = 0) const;
|
||||
void SetInvisible(uint8 state);
|
||||
bool AttackAnimation(EQEmu::skills::SkillType &skillinuse, int Hand, const EQEmu::ItemInstance* weapon);
|
||||
EQEmu::skills::SkillType AttackAnimation(int Hand, const EQEmu::ItemInstance* weapon);
|
||||
|
||||
//Song
|
||||
bool UseBardSpellLogic(uint16 spell_id = 0xffff, int slot = -1);
|
||||
@ -446,6 +446,9 @@ public:
|
||||
inline StatBonuses GetItemBonuses() const { return itembonuses; }
|
||||
inline StatBonuses GetSpellBonuses() const { return spellbonuses; }
|
||||
inline StatBonuses GetAABonuses() const { return aabonuses; }
|
||||
inline StatBonuses* GetItemBonusesPtr() { return &itembonuses; }
|
||||
inline StatBonuses* GetSpellBonusesPtr() { return &spellbonuses; }
|
||||
inline StatBonuses* GetAABonusesPtr() { return &aabonuses; }
|
||||
inline virtual int32 GetMaxSTR() const { return GetSTR(); }
|
||||
inline virtual int32 GetMaxSTA() const { return GetSTA(); }
|
||||
inline virtual int32 GetMaxDEX() const { return GetDEX(); }
|
||||
@ -694,7 +697,7 @@ public:
|
||||
void CastOnCure(uint32 spell_id);
|
||||
void CastOnNumHitFade(uint32 spell_id);
|
||||
void SlowMitigation(Mob* caster);
|
||||
int16 GetCritDmgMob(uint16 skill);
|
||||
int16 GetCritDmgMod(uint16 skill);
|
||||
int16 GetMeleeDamageMod_SE(uint16 skill);
|
||||
int16 GetMeleeMinDamageMod_SE(uint16 skill);
|
||||
int16 GetCrippBlowChance();
|
||||
@ -1060,6 +1063,8 @@ public:
|
||||
void AddAssistCap() { ++npc_assist_cap; }
|
||||
void DelAssistCap() { --npc_assist_cap; }
|
||||
void ResetAssistCap() { npc_assist_cap = 0; }
|
||||
int GetWeaponDamage(Mob *against, const EQEmu::ItemData *weapon_item);
|
||||
int GetWeaponDamage(Mob *against, const EQEmu::ItemInstance *weapon_item, uint32 *hate = nullptr);
|
||||
|
||||
// Bots HealRotation methods
|
||||
#ifdef BOTS
|
||||
@ -1209,8 +1214,6 @@ protected:
|
||||
virtual float GetDefensiveProcChances(float &ProcBonus, float &ProcChance, uint16 hand = EQEmu::inventory::slotPrimary, Mob *on = nullptr);
|
||||
virtual float GetSkillProcChances(uint16 ReuseTime, uint16 hand = 0); // hand = MainCharm?
|
||||
uint16 GetWeaponSpeedbyHand(uint16 hand);
|
||||
int GetWeaponDamage(Mob *against, const EQEmu::ItemData *weapon_item);
|
||||
int GetWeaponDamage(Mob *against, const EQEmu::ItemInstance *weapon_item, uint32 *hate = nullptr);
|
||||
#ifdef BOTS
|
||||
virtual
|
||||
#endif
|
||||
|
||||
@ -391,8 +391,7 @@ int main(int argc, char** argv) {
|
||||
|
||||
parse = new QuestParserCollection();
|
||||
#ifdef LUA_EQEMU
|
||||
auto lua_parser = new LuaParser();
|
||||
parse->RegisterQuestInterface(lua_parser, "lua");
|
||||
parse->RegisterQuestInterface(LuaParser::Instance(), "lua");
|
||||
#endif
|
||||
|
||||
#ifdef EMBPERL
|
||||
@ -565,10 +564,6 @@ int main(int argc, char** argv) {
|
||||
safe_delete(perl_parser);
|
||||
#endif
|
||||
|
||||
#ifdef LUA_EQEMU
|
||||
safe_delete(lua_parser);
|
||||
#endif
|
||||
|
||||
safe_delete(Config);
|
||||
|
||||
if (zone != 0)
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
#include "entity.h"
|
||||
#include "mob.h"
|
||||
#include "string_ids.h"
|
||||
#include "lua_parser.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@ -758,7 +759,6 @@ void Mob::DoArcheryAttackDmg(Mob *other, const EQEmu::ItemInstance *RangeWeapon,
|
||||
uint16 weapon_damage, int16 chance_mod, int16 focus, int ReuseTime, uint32 range_id,
|
||||
uint32 ammo_id, const EQEmu::ItemData *AmmoItem, int AmmoSlot, float speed)
|
||||
{
|
||||
|
||||
if ((other == nullptr ||
|
||||
((IsClient() && CastToClient()->dead) || (other->IsClient() && other->CastToClient()->dead)) ||
|
||||
HasDied() || (!IsAttackAllowed(other)) || (other->GetInvul() || other->GetSpecialAbility(IMMUNE_MELEE)))) {
|
||||
|
||||
@ -596,8 +596,7 @@ int32 Client::GetMeleeDamage(Mob* other, bool GetMinDamage)
|
||||
}
|
||||
}
|
||||
|
||||
EQEmu::skills::SkillType skillinuse;
|
||||
AttackAnimation(skillinuse, Hand, weapon);
|
||||
EQEmu::skills::SkillType skillinuse = AttackAnimation(Hand, weapon);
|
||||
|
||||
int damage = 0;
|
||||
uint8 mylevel = GetLevel() ? GetLevel() : 1;
|
||||
@ -665,16 +664,16 @@ void Mob::Tune_FindAccuaryByHitChance(Mob* defender, Mob *attacker, float hit_ch
|
||||
weapon = attacker->CastToClient()->GetInv().GetItem(EQEmu::inventory::slotPrimary);
|
||||
|
||||
if(weapon && weapon->IsWeapon()){
|
||||
attacker->CastToClient()->AttackAnimation(skillinuse, EQEmu::inventory::slotPrimary, weapon);
|
||||
skillinuse = attacker->CastToClient()->AttackAnimation(EQEmu::inventory::slotPrimary, weapon);
|
||||
}
|
||||
else {
|
||||
weapon = attacker->CastToClient()->GetInv().GetItem(EQEmu::inventory::slotSecondary);
|
||||
if (weapon && weapon->IsWeapon())
|
||||
attacker->CastToClient()->AttackAnimation(skillinuse, EQEmu::inventory::slotSecondary, weapon);
|
||||
skillinuse = attacker->CastToClient()->AttackAnimation(EQEmu::inventory::slotSecondary, weapon);
|
||||
else {
|
||||
weapon = attacker->CastToClient()->GetInv().GetItem(EQEmu::inventory::slotRange);
|
||||
if (weapon && weapon->IsWeapon())
|
||||
attacker->CastToClient()->AttackAnimation(skillinuse, EQEmu::inventory::slotRange, weapon);
|
||||
skillinuse = attacker->CastToClient()->AttackAnimation(EQEmu::inventory::slotRange, weapon);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -745,16 +744,16 @@ void Mob::Tune_FindAvoidanceByHitChance(Mob* defender, Mob *attacker, float hit_
|
||||
weapon = attacker->CastToClient()->GetInv().GetItem(EQEmu::inventory::slotPrimary);
|
||||
|
||||
if(weapon && weapon->IsWeapon()){
|
||||
attacker->CastToClient()->AttackAnimation(skillinuse, EQEmu::inventory::slotPrimary, weapon);
|
||||
skillinuse = attacker->CastToClient()->AttackAnimation(EQEmu::inventory::slotPrimary, weapon);
|
||||
}
|
||||
else {
|
||||
weapon = attacker->CastToClient()->GetInv().GetItem(EQEmu::inventory::slotSecondary);
|
||||
if (weapon && weapon->IsWeapon())
|
||||
attacker->CastToClient()->AttackAnimation(skillinuse, EQEmu::inventory::slotSecondary, weapon);
|
||||
skillinuse = attacker->CastToClient()->AttackAnimation(EQEmu::inventory::slotSecondary, weapon);
|
||||
else {
|
||||
weapon = attacker->CastToClient()->GetInv().GetItem(EQEmu::inventory::slotRange);
|
||||
if (weapon && weapon->IsWeapon())
|
||||
attacker->CastToClient()->AttackAnimation(skillinuse, EQEmu::inventory::slotRange, weapon);
|
||||
skillinuse = attacker->CastToClient()->AttackAnimation(EQEmu::inventory::slotRange, weapon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user