mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-23 04:52:29 +00:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2434bab697 | |||
| 7a5a755033 |
@@ -1,35 +1,3 @@
|
||||
## [22.45.1] 2/29/2024
|
||||
|
||||
### Character Creation
|
||||
|
||||
* Improved Random Name Generator ([#4081](https://github.com/EQEmu/Server/pull/4081)) @catapultam-habeo 2024-02-27
|
||||
|
||||
### Code
|
||||
|
||||
* Fix Server Rules Documentation Generation ([#4125](https://github.com/EQEmu/Server/pull/4125)) @Kinglykrab 2024-02-26
|
||||
* Remove unnecessary stoptimer logs ([#4128](https://github.com/EQEmu/Server/pull/4128)) @Kinglykrab 2024-02-28
|
||||
|
||||
### Commands
|
||||
|
||||
* Add `#forage` command ([#4133](https://github.com/EQEmu/Server/pull/4133)) @joligario 2024-02-29
|
||||
|
||||
### Crash
|
||||
|
||||
* Fix crash issue during database dump ([#4127](https://github.com/EQEmu/Server/pull/4127)) @Akkadius 2024-02-29
|
||||
|
||||
### Crash Fix
|
||||
|
||||
* D20 crash if mitigation average resulted in 0 ([#4131](https://github.com/EQEmu/Server/pull/4131)) @nytmyr 2024-02-29
|
||||
|
||||
### Fixes
|
||||
|
||||
* Fix forage returning first result from table ([#4130](https://github.com/EQEmu/Server/pull/4130)) @nytmyr 2024-02-29
|
||||
* Who /all displays incorrect guild name ([#4123](https://github.com/EQEmu/Server/pull/4123)) @neckkola 2024-02-25
|
||||
|
||||
### Quest API
|
||||
|
||||
* Add Pet Owner Methods to Perl/Lua ([#4115](https://github.com/EQEmu/Server/pull/4115)) @Kinglykrab 2024-02-25
|
||||
|
||||
## [22.45.0] 2/24/2024
|
||||
|
||||
### Beacon
|
||||
|
||||
@@ -575,12 +575,7 @@ void DatabaseDumpService::RemoveSqlBackup()
|
||||
{
|
||||
std::string file = fmt::format("{}.sql", GetDumpFileNameWithPath());
|
||||
if (File::Exists(file)) {
|
||||
try {
|
||||
std::filesystem::remove(file);
|
||||
}
|
||||
catch (std::exception &e) {
|
||||
LogError("std::filesystem::remove err [{}]", e.what());
|
||||
}
|
||||
std::filesystem::remove(file);
|
||||
}
|
||||
|
||||
RemoveCredentialsFile();
|
||||
|
||||
+4
-3
@@ -48,10 +48,10 @@ RULE_BOOL(Character, DeathKeepLevel, false, "Players can not drop below 0% exper
|
||||
RULE_BOOL(Character, UseDeathExpLossMult, false, "Setting to control whether DeathExpLossMultiplier or the code default is used: (Level x Level / 18.0) x 12000")
|
||||
RULE_BOOL(Character, UseOldRaceRezEffects, false, "Older clients had ID 757 for races with high starting STR, but it doesn't seem used anymore")
|
||||
RULE_INT(Character, CorpseDecayTime, 604800000, "Time after which the corpse decays (milliseconds) DEFAULT: 604800000 (7 Days)")
|
||||
RULE_INT(Character, EmptyCorpseDecayTime, 10800000, "Time after which an empty corpse decays (milliseconds) DEFAULT: 10800000 (3 Hours)")
|
||||
RULE_INT( Character, EmptyCorpseDecayTime, 10800000, "Time after which an empty corpse decays (milliseconds) DEFAULT: 10800000 (3 Hours)")
|
||||
RULE_INT(Character, CorpseResTime, 10800000, "Time after which the corpse can no longer be resurrected (milliseconds) DEFAULT: 10800000 (3 Hours)")
|
||||
RULE_INT(Character, DuelCorpseResTime, 600000, "Time before cant res corpse after a duel (milliseconds) DEFAULT: 600000 (10 Minutes)")
|
||||
RULE_INT(Character, CorpseOwnerOnlineTime, 30000, "How often corpse will check if its owner is online DEFAULT: 30000 (30 Seconds)")
|
||||
RULE_INT( Character, DuelCorpseResTime, 600000, "Time before cant res corpse after a duel (milliseconds) DEFAULT: 600000 (10 Minutes)")
|
||||
RULE_INT( Character, CorpseOwnerOnlineTime, 30000, "How often corpse will check if its owner is online DEFAULT: 30000 (30 Seconds)")
|
||||
RULE_BOOL(Character, LeaveCorpses, true, "Setting whether you leave a corpse behind")
|
||||
RULE_BOOL(Character, LeaveNakedCorpses, false, "Setting whether you leave a corpse without items")
|
||||
RULE_INT(Character, MaxDraggedCorpses, 2, "Maximum number of corpses you can drag at once")
|
||||
@@ -495,6 +495,7 @@ RULE_BOOL(Spells, EvacClearCharmPet, false, "Enable to have evac in zone clear c
|
||||
RULE_BOOL(Spells, ManaTapsRequireNPCMana, false, "Enabling will require target to have mana to tap. Default off as many npc's are caster class with 0 mana and need fixed.")
|
||||
RULE_INT(Spells, HarmTouchCritRatio, 200, "Harmtouch crit bonus, on top of BaseCritRatio")
|
||||
RULE_BOOL(Spells, UseClassicSpellFocus, false, "Enabling will tell the server to handle random focus damage as classic spell imports lack the limit values.")
|
||||
RULE_BOOL(Spells, ManaTapsOnAnyClass, false, "Enabling this will allow you to cast mana taps on any class, this will bypass ManaTapsRequireNPCMana rule.")
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(Combat)
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@
|
||||
|
||||
// Build variables
|
||||
// these get injected during the build pipeline
|
||||
#define CURRENT_VERSION "22.45.1-dev" // always append -dev to the current version for custom-builds
|
||||
#define CURRENT_VERSION "22.45.0-dev" // always append -dev to the current version for custom-builds
|
||||
#define LOGIN_VERSION "0.8.0"
|
||||
#define COMPILE_DATE __DATE__
|
||||
#define COMPILE_TIME __TIME__
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "eqemu-server",
|
||||
"version": "22.45.1",
|
||||
"version": "22.45.0",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/EQEmu/Server.git"
|
||||
|
||||
+65
-49
@@ -599,63 +599,79 @@ bool Client::HandleNameApprovalPacket(const EQApplicationPacket *app)
|
||||
}
|
||||
|
||||
bool Client::HandleGenerateRandomNamePacket(const EQApplicationPacket *app) {
|
||||
char newName[17] = {0};
|
||||
bool unique = false;
|
||||
|
||||
while (!unique) {
|
||||
std::string cons = "bcdfghjklmnpqrstvwxyz";
|
||||
std::string vows = "aeou";
|
||||
std::string allVows = "aeiou";
|
||||
std::vector<std::string> endPhon = {"a", "e", "i", "o", "u", "os", "as", "us", "is", "y", "an", "en", "in", "on", "un"};
|
||||
|
||||
std::random_device rd;
|
||||
std::mt19937 gen(rd());
|
||||
|
||||
std::uniform_int_distribution<int> lenDist(5, 10);
|
||||
std::uniform_int_distribution<int> firstCharDist(0, 1);
|
||||
std::uniform_int_distribution<int> consDist(0, cons.size() - 1);
|
||||
std::uniform_int_distribution<int> vowDist(0, vows.size() - 1);
|
||||
std::uniform_int_distribution<int> allVowDist(0, allVows.size() - 1);
|
||||
std::uniform_int_distribution<int> endPhonDist(0, endPhon.size() - 1);
|
||||
|
||||
int len = 0;
|
||||
memset(newName, 0, sizeof(newName));
|
||||
|
||||
if (firstCharDist(gen) == 0) {
|
||||
newName[len++] = vows[vowDist(gen)];
|
||||
newName[len++] = cons[consDist(gen)];
|
||||
} else {
|
||||
newName[len++] = cons[consDist(gen)];
|
||||
newName[len++] = allVows[allVowDist(gen)];
|
||||
}
|
||||
|
||||
newName[0] = toupper(newName[0]);
|
||||
|
||||
while (len < lenDist(gen) - 1) {
|
||||
if (len % 2 == 0) {
|
||||
newName[len++] = cons[consDist(gen)];
|
||||
} else {
|
||||
newName[len++] = allVows[allVowDist(gen)];
|
||||
// creates up to a 10 char name
|
||||
char vowels[18]="aeiouyaeiouaeioe";
|
||||
char cons[48]="bcdfghjklmnpqrstvwxzybcdgklmnprstvwbcdgkpstrkd";
|
||||
char rndname[17]="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
|
||||
char paircons[33]="ngrkndstshthphsktrdrbrgrfrclcr";
|
||||
int rndnum=emu_random.Int(0, 75),n=1;
|
||||
bool dlc=false;
|
||||
bool vwl=false;
|
||||
bool dbl=false;
|
||||
if (rndnum>63)
|
||||
{ // rndnum is 0 - 75 where 64-75 is cons pair, 17-63 is cons, 0-16 is vowel
|
||||
rndnum=(rndnum-61)*2; // name can't start with "ng" "nd" or "rk"
|
||||
rndname[0]=paircons[rndnum];
|
||||
rndname[1]=paircons[rndnum+1];
|
||||
n=2;
|
||||
}
|
||||
else if (rndnum>16)
|
||||
{
|
||||
rndnum-=17;
|
||||
rndname[0]=cons[rndnum];
|
||||
}
|
||||
else
|
||||
{
|
||||
rndname[0]=vowels[rndnum];
|
||||
vwl=true;
|
||||
}
|
||||
int namlen=emu_random.Int(5, 10);
|
||||
for (int i=n;i<namlen;i++)
|
||||
{
|
||||
dlc=false;
|
||||
if (vwl) //last char was a vowel
|
||||
{ // so pick a cons or cons pair
|
||||
rndnum=emu_random.Int(0, 62);
|
||||
if (rndnum>46)
|
||||
{ // pick a cons pair
|
||||
if (i>namlen-3) // last 2 chars in name?
|
||||
{ // name can only end in cons pair "rk" "st" "sh" "th" "ph" "sk" "nd" or "ng"
|
||||
rndnum=emu_random.Int(0, 7)*2;
|
||||
}
|
||||
else
|
||||
{ // pick any from the set
|
||||
rndnum=(rndnum-47)*2;
|
||||
}
|
||||
rndname[i]=paircons[rndnum];
|
||||
rndname[i+1]=paircons[rndnum+1];
|
||||
dlc=true; // flag keeps second letter from being doubled below
|
||||
i+=1;
|
||||
}
|
||||
else
|
||||
{ // select a single cons
|
||||
rndname[i]=cons[rndnum];
|
||||
}
|
||||
}
|
||||
|
||||
std::string end = endPhon[endPhonDist(gen)];
|
||||
for (char c : end) {
|
||||
if (len < 10) newName[len++] = c;
|
||||
else
|
||||
{ // select a vowel
|
||||
rndname[i]=vowels[emu_random.Int(0, 16)];
|
||||
}
|
||||
|
||||
if (database.CheckNameFilter(newName)) {
|
||||
std::string query = StringFormat("SELECT `name` FROM `character_data` WHERE `name` = '%s'", newName);
|
||||
auto res = database.QueryDatabase(query);
|
||||
if (res.Success() && res.RowCount() == 0) {
|
||||
unique = true;
|
||||
vwl=!vwl;
|
||||
if (!dbl && !dlc)
|
||||
{ // one chance at double letters in name
|
||||
if (!emu_random.Int(0, i+9)) // chances decrease towards end of name
|
||||
{
|
||||
rndname[i+1]=rndname[i];
|
||||
dbl=true;
|
||||
i+=1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rndname[0]=toupper(rndname[0]);
|
||||
NameGeneration_Struct* ngs = (NameGeneration_Struct*)app->pBuffer;
|
||||
memset(ngs->name, 0, 64);
|
||||
strcpy(ngs->name, newName);
|
||||
memset(ngs->name,0,64);
|
||||
strcpy(ngs->name,rndname);
|
||||
|
||||
QueuePacket(app);
|
||||
return true;
|
||||
|
||||
+1
-11
@@ -230,23 +230,13 @@ void WorldGuildManager::ProcessZonePacket(ServerPacket *pack) {
|
||||
case ServerOP_GuildChannel:
|
||||
case ServerOP_GuildURL:
|
||||
case ServerOP_GuildMemberRemove:
|
||||
case ServerOP_GuildMemberAdd:
|
||||
case ServerOP_GuildSendGuildList:
|
||||
case ServerOP_GuildMembersList:
|
||||
{
|
||||
zoneserver_list.SendPacketToBootedZones(pack);
|
||||
break;
|
||||
}
|
||||
case ServerOP_GuildMemberAdd:
|
||||
{
|
||||
auto in = (ServerOP_GuildMessage_Struct *)pack->pBuffer;
|
||||
auto guild = GetGuildByGuildID(in->guild_id);
|
||||
if (!guild) {
|
||||
BaseGuildManager::RefreshGuild(in->guild_id);
|
||||
}
|
||||
|
||||
zoneserver_list.SendPacketToBootedZones(pack);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
LogGuilds("Unknown packet {:#04x} received from zone??", pack->opcode);
|
||||
break;
|
||||
|
||||
+1
-1
@@ -1005,7 +1005,7 @@ double Mob::RollD20(int offense, int mitigation)
|
||||
auto atk_roll = zone->random.Roll0(offense + 5);
|
||||
auto def_roll = zone->random.Roll0(mitigation + 5);
|
||||
|
||||
int avg = std::max(1, (offense + mitigation + 10) / 2);
|
||||
int avg = (offense + mitigation + 10) / 2;
|
||||
int index = std::max(0, (atk_roll - def_roll) + (avg / 2));
|
||||
|
||||
index = EQ::Clamp((index * 20) / avg, 0, 19);
|
||||
|
||||
@@ -133,7 +133,6 @@ int command_init(void)
|
||||
command_add("find", "Search command used to find various things", AccountStatus::Guide, command_find) ||
|
||||
command_add("fixmob", "[race|gender|texture|helm|face|hair|haircolor|beard|beardcolor|heritage|tattoo|detail] [next|prev] - Manipulate appearance of your target", AccountStatus::QuestTroupe, command_fixmob) ||
|
||||
command_add("flagedit", "Edit zone flags on your target. Use #flagedit help for more info.", AccountStatus::GMAdmin, command_flagedit) ||
|
||||
command_add("forage", "Forage an item", AccountStatus::QuestTroupe, command_forage) ||
|
||||
command_add("gearup", "Developer tool to quickly equip yourself or your target", AccountStatus::GMMgmt, command_gearup) ||
|
||||
command_add("giveitem", "[itemid] [charges] - Summon an item onto your target's cursor. Charges are optional.", AccountStatus::GMMgmt, command_giveitem) ||
|
||||
command_add("givemoney", "[Platinum] [Gold] [Silver] [Copper] - Gives specified amount of money to you or your player target", AccountStatus::GMMgmt, command_givemoney) ||
|
||||
@@ -825,7 +824,6 @@ void command_bot(Client *c, const Seperator *sep)
|
||||
#include "gm_commands/find.cpp"
|
||||
#include "gm_commands/fixmob.cpp"
|
||||
#include "gm_commands/flagedit.cpp"
|
||||
#include "gm_commands/forage.cpp"
|
||||
#include "gm_commands/gearup.cpp"
|
||||
#include "gm_commands/giveitem.cpp"
|
||||
#include "gm_commands/givemoney.cpp"
|
||||
|
||||
@@ -85,7 +85,6 @@ void command_feature(Client *c, const Seperator *sep);
|
||||
void command_find(Client *c, const Seperator *sep);
|
||||
void command_fixmob(Client *c, const Seperator *sep);
|
||||
void command_flagedit(Client *c, const Seperator *sep);
|
||||
void command_forage(Client* c, const Seperator* sep);
|
||||
void command_gearup(Client *c, const Seperator *sep);
|
||||
void command_giveitem(Client *c, const Seperator *sep);
|
||||
void command_givemoney(Client *c, const Seperator *sep);
|
||||
|
||||
+1
-1
@@ -89,7 +89,7 @@ uint32 ZoneDatabase::LoadForage(uint32 zone_id, uint8 skill_level)
|
||||
}
|
||||
|
||||
forage_items[count] = e.Itemid;
|
||||
forage_chances[count] = e.chance + current_chance;
|
||||
forage_chances[count] = e.chance;
|
||||
|
||||
current_chance = forage_chances[count];
|
||||
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_forage(Client *c, const Seperator *sep)
|
||||
{
|
||||
c->ForageItem(true);
|
||||
}
|
||||
@@ -752,7 +752,11 @@ void QuestManager::stoptimer(const std::string& timer_name)
|
||||
);
|
||||
|
||||
for (auto e = QTimerList.begin(); e != QTimerList.end(); ++e) {
|
||||
LogInfo("Current [{}] Timer [{}]", e->name, timer_name);
|
||||
|
||||
if (e->mob && e->mob == owner && e->name == timer_name) {
|
||||
LogInfo("Matched [{}] Timer [{}]", e->name, timer_name);
|
||||
|
||||
if (has_stop_event) {
|
||||
if (owner->IsClient()) {
|
||||
parse->EventPlayer(EVENT_TIMER_STOP, owner->CastToClient(), timer_name, 0);
|
||||
|
||||
+1
-10
@@ -223,16 +223,7 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot,
|
||||
|
||||
// check to see if target is a caster mob before performing a mana tap
|
||||
if(GetTarget() && IsManaTapSpell(spell_id)) {
|
||||
if (
|
||||
GetTarget()->GetCasterClass() == 'N' &&
|
||||
(
|
||||
!RuleB(Spells, ManaTapsRequireNPCMana) ||
|
||||
(
|
||||
RuleB(Spells, ManaTapsRequireNPCMana) &&
|
||||
GetTarget()->GetMana() == 0
|
||||
)
|
||||
)
|
||||
) {
|
||||
if (!RuleB(Spells, ManaTapsOnAnyClass) && GetTarget()->GetCasterClass() != 'N' && RuleB(Spells, ManaTapsRequireNPCMana) && GetTarget()->GetMana() == 0) {
|
||||
InterruptSpell(TARGET_NO_MANA, 0x121, spell_id);
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user