[Languages] Cleanup language constants, use repositories (#3838)

* [Languages] Cleanup languages constants

# Notes
- Cleanup formatting and logic where necessary.
- Cleaned up constants to use a namespace with `constexpr` instead.
- Changed `LoadCharacterLanguages` to use a repository instead.

* Lua GroupMessage uint8/language_id

* Lua More uint8/language_id
This commit is contained in:
Alex King 2024-01-06 23:17:10 -05:00 committed by GitHub
parent 43c4b13978
commit 122fe398b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
34 changed files with 393 additions and 393 deletions

View File

@ -561,7 +561,6 @@ SET(common_headers
item_fieldlist.h
item_instance.h
json_config.h
languages.h
light_source.h
linked_list.h
loottable.h

View File

@ -22,7 +22,6 @@
#include "data_verification.h"
#include "eqemu_logsys.h"
#include "eqemu_logsys_log_aliases.h"
#include "languages.h"
#include "rulesys.h"
int16 EQ::invtype::GetInvTypeSize(int16 inv_type) {
@ -159,45 +158,45 @@ int EQ::constants::ConvertStanceTypeToIndex(StanceType stance_type) {
return 0;
}
const std::map<int, std::string>& EQ::constants::GetLanguageMap()
const std::map<uint8, std::string>& EQ::constants::GetLanguageMap()
{
static const std::map<int, std::string> language_map = {
{ LANG_COMMON_TONGUE, "Common Tongue" },
{ LANG_BARBARIAN, "Barbarian" },
{ LANG_ERUDIAN, "Erudian" },
{ LANG_ELVISH, "Elvish" },
{ LANG_DARK_ELVISH, "Dark Elvish" },
{ LANG_DWARVISH, "Dwarvish" },
{ LANG_TROLL, "Troll" },
{ LANG_OGRE, "Ogre" },
{ LANG_GNOMISH, "Gnomish" },
{ LANG_HALFLING, "Halfling" },
{ LANG_THIEVES_CANT, "Thieves Cant" },
{ LANG_OLD_ERUDIAN, "Old Erudian" },
{ LANG_ELDER_ELVISH, "Elder Elvish" },
{ LANG_FROGLOK, "Froglok" },
{ LANG_GOBLIN, "Goblin" },
{ LANG_GNOLL, "Gnoll" },
{ LANG_COMBINE_TONGUE, "Combine Tongue" },
{ LANG_ELDER_TEIRDAL, "Elder Teirdal" },
{ LANG_LIZARDMAN, "Lizardman" },
{ LANG_ORCISH, "Orcish" },
{ LANG_FAERIE, "Faerie" },
{ LANG_DRAGON, "Dragon" },
{ LANG_ELDER_DRAGON, "Elder Dragon" },
{ LANG_DARK_SPEECH, "Dark Speech" },
{ LANG_VAH_SHIR, "Vah Shir" },
{ LANG_ALARAN, "Alaran" },
{ LANG_HADAL, "Hadal" },
{ LANG_UNKNOWN, "Unknown" }
static const std::map<uint8, std::string> language_map = {
{ Language::CommonTongue, "Common Tongue" },
{ Language::Barbarian, "Barbarian" },
{ Language::Erudian, "Erudian" },
{ Language::Elvish, "Elvish" },
{ Language::DarkElvish, "Dark Elvish" },
{ Language::Dwarvish, "Dwarvish" },
{ Language::Troll, "Troll" },
{ Language::Ogre, "Ogre" },
{ Language::Gnomish, "Gnomish" },
{ Language::Halfling, "Halfling" },
{ Language::ThievesCant, "Thieves Cant" },
{ Language::OldErudian, "Old Erudian" },
{ Language::ElderElvish, "Elder Elvish" },
{ Language::Froglok, "Froglok" },
{ Language::Goblin, "Goblin" },
{ Language::Gnoll, "Gnoll" },
{ Language::CombineTongue, "Combine Tongue" },
{ Language::ElderTeirDal, "Elder Teir'Dal" },
{ Language::Lizardman, "Lizardman" },
{ Language::Orcish, "Orcish" },
{ Language::Faerie, "Faerie" },
{ Language::Dragon, "Dragon" },
{ Language::ElderDragon, "Elder Dragon" },
{ Language::DarkSpeech, "Dark Speech" },
{ Language::VahShir, "Vah Shir" },
{ Language::Alaran, "Alaran" },
{ Language::Hadal, "Hadal" },
{ Language::Unknown27, "Unknown" }
};
return language_map;
}
std::string EQ::constants::GetLanguageName(int language_id)
std::string EQ::constants::GetLanguageName(uint8 language_id)
{
if (!EQ::ValueWithin(language_id, LANG_COMMON_TONGUE, LANG_UNKNOWN)) {
if (!EQ::ValueWithin(language_id, Language::CommonTongue, Language::Unknown27)) {
return std::string();
}

View File

@ -358,8 +358,8 @@ namespace EQ
const char *GetStanceName(StanceType stance_type);
int ConvertStanceTypeToIndex(StanceType stance_type);
extern const std::map<int, std::string>& GetLanguageMap();
std::string GetLanguageName(int language_id);
extern const std::map<uint8, std::string>& GetLanguageMap();
std::string GetLanguageName(uint8 language_id);
extern const std::map<uint32, std::string>& GetLDoNThemeMap();
std::string GetLDoNThemeName(uint32 theme_id);

View File

@ -686,6 +686,38 @@ namespace Zones {
constexpr uint16 APPRENTICE = 999; // Designer Apprentice
}
namespace Language {
constexpr uint8 CommonTongue = 0;
constexpr uint8 Barbarian = 1;
constexpr uint8 Erudian = 2;
constexpr uint8 Elvish = 3;
constexpr uint8 DarkElvish = 4;
constexpr uint8 Dwarvish = 5;
constexpr uint8 Troll = 6;
constexpr uint8 Ogre = 7;
constexpr uint8 Gnomish = 8;
constexpr uint8 Halfling = 9;
constexpr uint8 ThievesCant = 10;
constexpr uint8 OldErudian = 11;
constexpr uint8 ElderElvish = 12;
constexpr uint8 Froglok = 13;
constexpr uint8 Goblin = 14;
constexpr uint8 Gnoll = 15;
constexpr uint8 CombineTongue = 16;
constexpr uint8 ElderTeirDal = 17;
constexpr uint8 Lizardman = 18;
constexpr uint8 Orcish = 19;
constexpr uint8 Faerie = 20;
constexpr uint8 Dragon = 21;
constexpr uint8 ElderDragon = 22;
constexpr uint8 DarkSpeech = 23;
constexpr uint8 VahShir = 24;
constexpr uint8 Alaran = 25;
constexpr uint8 Hadal = 26;
constexpr uint8 Unknown27 = 27;
constexpr uint8 MaxValue = 100;
}
typedef enum {
FilterNone = 0,

View File

@ -1,54 +0,0 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2002 EQEMu Development Team (http://eqemulator.org)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef LANGUAGES_H
#define LANGUAGES_H
#include "../common/types.h"
#define LANG_COMMON_TONGUE 0
#define LANG_BARBARIAN 1
#define LANG_ERUDIAN 2
#define LANG_ELVISH 3
#define LANG_DARK_ELVISH 4
#define LANG_DWARVISH 5
#define LANG_TROLL 6
#define LANG_OGRE 7
#define LANG_GNOMISH 8
#define LANG_HALFLING 9
#define LANG_THIEVES_CANT 10
#define LANG_OLD_ERUDIAN 11
#define LANG_ELDER_ELVISH 12
#define LANG_FROGLOK 13
#define LANG_GOBLIN 14
#define LANG_GNOLL 15
#define LANG_COMBINE_TONGUE 16
#define LANG_ELDER_TEIRDAL 17
#define LANG_LIZARDMAN 18
#define LANG_ORCISH 19
#define LANG_FAERIE 20
#define LANG_DRAGON 21
#define LANG_ELDER_DRAGON 22
#define LANG_DARK_SPEECH 23
#define LANG_VAH_SHIR 24
#define LANG_ALARAN 25
#define LANG_HADAL 26
#define LANG_UNKNOWN 27
#define MAX_LANGUAGE_SKILL 100
#endif

View File

@ -28,7 +28,6 @@
#include "../common/inventory_profile.h"
#include "../common/races.h"
#include "../common/classes.h"
#include "../common/languages.h"
#include "../common/skills.h"
#include "../common/extprofile.h"
#include "../common/strings.h"
@ -2181,115 +2180,101 @@ void Client::SetRaceStartingSkills( PlayerProfile_Struct *pp )
void Client::SetRacialLanguages( PlayerProfile_Struct *pp )
{
switch( pp->race )
{
case BARBARIAN:
{
pp->languages[LANG_COMMON_TONGUE] = 100;
pp->languages[LANG_BARBARIAN] = 100;
switch (pp->race) {
case Race::Human: {
pp->languages[Language::CommonTongue] = Language::MaxValue;
break;
}
case DARK_ELF:
{
pp->languages[LANG_COMMON_TONGUE] = 100;
pp->languages[LANG_DARK_ELVISH] = 100;
pp->languages[LANG_DARK_SPEECH] = 100;
pp->languages[LANG_ELDER_ELVISH] = 100;
pp->languages[LANG_ELVISH] = 25;
case Race::Barbarian: {
pp->languages[Language::CommonTongue] = Language::MaxValue;
pp->languages[Language::Barbarian] = Language::MaxValue;
break;
}
case DWARF:
{
pp->languages[LANG_COMMON_TONGUE] = 100;
pp->languages[LANG_DWARVISH] = 100;
pp->languages[LANG_GNOMISH] = 25;
case Race::Erudite: {
pp->languages[Language::CommonTongue] = Language::MaxValue;
pp->languages[Language::Erudian] = Language::MaxValue;
break;
}
case ERUDITE:
{
pp->languages[LANG_COMMON_TONGUE] = 100;
pp->languages[LANG_ERUDIAN] = 100;
case Race::WoodElf: {
pp->languages[Language::CommonTongue] = Language::MaxValue;
pp->languages[Language::Elvish] = Language::MaxValue;
break;
}
case FROGLOK:
{
pp->languages[LANG_COMMON_TONGUE] = 100;
pp->languages[LANG_FROGLOK] = 100;
pp->languages[LANG_TROLL] = 25;
case Race::HighElf: {
pp->languages[Language::CommonTongue] = Language::MaxValue;
pp->languages[Language::DarkElvish] = 25;
pp->languages[Language::ElderElvish] = 25;
pp->languages[Language::Elvish] = Language::MaxValue;
break;
}
case GNOME:
{
pp->languages[LANG_COMMON_TONGUE] = 100;
pp->languages[LANG_DWARVISH] = 25;
pp->languages[LANG_GNOMISH] = 100;
case Race::DarkElf: {
pp->languages[Language::CommonTongue] = Language::MaxValue;
pp->languages[Language::DarkElvish] = Language::MaxValue;
pp->languages[Language::DarkSpeech] = Language::MaxValue;
pp->languages[Language::ElderElvish] = Language::MaxValue;
pp->languages[Language::Elvish] = 25;
break;
}
case HALF_ELF:
{
pp->languages[LANG_COMMON_TONGUE] = 100;
pp->languages[LANG_ELVISH] = 100;
case Race::HalfElf: {
pp->languages[Language::CommonTongue] = Language::MaxValue;
pp->languages[Language::Elvish] = Language::MaxValue;
break;
}
case HALFLING:
{
pp->languages[LANG_COMMON_TONGUE] = 100;
pp->languages[LANG_HALFLING] = 100;
case Race::Dwarf: {
pp->languages[Language::CommonTongue] = Language::MaxValue;
pp->languages[Language::Dwarvish] = Language::MaxValue;
pp->languages[Language::Gnomish] = 25;
break;
}
case HIGH_ELF:
{
pp->languages[LANG_COMMON_TONGUE] = 100;
pp->languages[LANG_DARK_ELVISH] = 25;
pp->languages[LANG_ELDER_ELVISH] = 25;
pp->languages[LANG_ELVISH] = 100;
case Race::Troll: {
pp->languages[Language::CommonTongue] = RuleI(Character, TrollCommonTongue);
pp->languages[Language::DarkSpeech] = Language::MaxValue;
pp->languages[Language::Troll] = Language::MaxValue;
break;
}
case HUMAN:
{
pp->languages[LANG_COMMON_TONGUE] = 100;
case Race::Ogre: {
pp->languages[Language::CommonTongue] = RuleI(Character, OgreCommonTongue);
pp->languages[Language::DarkSpeech] = Language::MaxValue;
pp->languages[Language::Ogre] = Language::MaxValue;
break;
}
case IKSAR:
{
pp->languages[LANG_COMMON_TONGUE] = RuleI(Character, IksarCommonTongue);
pp->languages[LANG_DARK_SPEECH] = 100;
pp->languages[LANG_LIZARDMAN] = 100;
case Race::Halfling: {
pp->languages[Language::CommonTongue] = Language::MaxValue;
pp->languages[Language::Halfling] = Language::MaxValue;
break;
}
case OGRE:
{
pp->languages[LANG_COMMON_TONGUE] = RuleI(Character, OgreCommonTongue);
pp->languages[LANG_DARK_SPEECH] = 100;
pp->languages[LANG_OGRE] = 100;
case Race::Gnome: {
pp->languages[Language::CommonTongue] = Language::MaxValue;
pp->languages[Language::Dwarvish] = 25;
pp->languages[Language::Gnomish] = Language::MaxValue;
break;
}
case TROLL:
{
pp->languages[LANG_COMMON_TONGUE] = RuleI(Character, TrollCommonTongue);
pp->languages[LANG_DARK_SPEECH] = 100;
pp->languages[LANG_TROLL] = 100;
case Race::Iksar: {
pp->languages[Language::CommonTongue] = RuleI(Character, IksarCommonTongue);
pp->languages[Language::DarkSpeech] = Language::MaxValue;
pp->languages[Language::Lizardman] = Language::MaxValue;
break;
}
case WOOD_ELF:
{
pp->languages[LANG_COMMON_TONGUE] = 100;
pp->languages[LANG_ELVISH] = 100;
case Race::VahShir: {
pp->languages[Language::CommonTongue] = Language::MaxValue;
pp->languages[Language::CombineTongue] = Language::MaxValue;
pp->languages[Language::Erudian] = 25;
pp->languages[Language::VahShir] = Language::MaxValue;
break;
}
case VAHSHIR:
{
pp->languages[LANG_COMMON_TONGUE] = 100;
pp->languages[LANG_COMBINE_TONGUE] = 100;
pp->languages[LANG_ERUDIAN] = 25;
pp->languages[LANG_VAH_SHIR] = 100;
case Race::Froglok: {
pp->languages[Language::CommonTongue] = Language::MaxValue;
pp->languages[Language::Froglok] = Language::MaxValue;
pp->languages[Language::Troll] = 25;
break;
}
case DRAKKIN:
{
pp->languages[LANG_COMMON_TONGUE] = 100;
pp->languages[LANG_ELDER_DRAGON] = 100;
pp->languages[LANG_DRAGON] = 100;
case Race::Drakkin: {
pp->languages[Language::CommonTongue] = Language::MaxValue;
pp->languages[Language::ElderDragon] = Language::MaxValue;
pp->languages[Language::Dragon] = Language::MaxValue;
break;
}
default: {
break;
}
}
@ -2298,12 +2283,12 @@ void Client::SetRacialLanguages( PlayerProfile_Struct *pp )
void Client::SetClassLanguages(PlayerProfile_Struct *pp)
{
// we only need to handle one class, but custom server might want to do more
switch(pp->class_) {
case Class::Rogue:
pp->languages[LANG_THIEVES_CANT] = 100;
break;
default:
break;
switch (pp->class_) {
case Class::Rogue:
pp->languages[Language::ThievesCant] = Language::MaxValue;
break;
default:
break;
}
}

View File

@ -7894,7 +7894,7 @@ void Bot::BotGroupSay(Mob *speaker, const char *msg, ...) {
if (speaker->HasGroup()) {
Group *g = speaker->GetGroup();
if (g)
g->GroupMessage(speaker->CastToMob(), 0, 100, buf);
g->GroupMessage(speaker->CastToMob(), Language::CommonTongue, Language::MaxValue, buf);
} else
speaker->Say("%s", buf);
}

View File

@ -367,7 +367,7 @@ bool Bot::BotCastSlow(Mob* tar, uint8 botLevel, uint8 botClass, BotSpell& botSpe
if (casted_spell && GetClass() != Class::Bard) {
if (raid) {
const auto msg = fmt::format("Attempting to slow {}.", tar->GetCleanName());
raid->RaidSay(msg.c_str(), GetCleanName(), 0, 100);
raid->RaidSay(msg.c_str(), GetCleanName(), Language::CommonTongue, Language::MaxValue);
} else {
BotGroupSay(
this,
@ -1159,7 +1159,7 @@ bool Bot::BotCastHeal(Mob* tar, uint8 botLevel, uint8 botClass, BotSpell& botSpe
} else if (IsRaidGrouped()) {
uint32 r_group = raid->GetGroup(GetName());
const auto msg = fmt::format("Casting {}.", spells[botSpell.SpellId].name);
raid->RaidGroupSay(msg.c_str(), GetCleanName(), 0, 100);
raid->RaidGroupSay(msg.c_str(), GetCleanName(), Language::CommonTongue, Language::MaxValue);
std::vector<RaidMember> raid_group_members = raid->GetRaidGroupMembers(r_group);
for (const auto& rgm : raid_group_members) {
if (rgm.member && !rgm.member->qglobal) {

View File

@ -915,15 +915,19 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
// Garble the message based on drunkness
if (GetIntoxication() > 0 && !(RuleB(Chat, ServerWideOOC) && chan_num == ChatChannel_OOC) && !GetGM()) {
GarbleMessage(message, (int)(GetIntoxication() / 3));
language = 0; // No need for language when drunk
lang_skill = 100;
language = Language::CommonTongue; // No need for language when drunk
lang_skill = Language::MaxValue;
}
// some channels don't use languages
if (chan_num == ChatChannel_OOC || chan_num == ChatChannel_GMSAY || chan_num == ChatChannel_Broadcast || chan_num == ChatChannel_Petition)
{
language = 0;
lang_skill = 100;
if (
chan_num == ChatChannel_OOC ||
chan_num == ChatChannel_GMSAY ||
chan_num == ChatChannel_Broadcast ||
chan_num == ChatChannel_Petition
) {
language = Language::CommonTongue;
lang_skill = Language::MaxValue;
}
// Censor the message
@ -1274,69 +1278,88 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
}
}
void Client::ChannelMessageSend(const char* from, const char* to, uint8 chan_num, uint8 language, uint8 lang_skill, const char* message, ...) {
if ((chan_num==11 && !(GetGM())) || (chan_num==10 && Admin() < AccountStatus::QuestTroupe)) // dont need to send /pr & /petition to everybody
void Client::ChannelMessageSend(
const char *from,
const char *to,
uint8 channel_id,
uint8 language_id,
uint8 language_skill,
const char *message,
...
)
{
if (
(channel_id == ChatChannel_Petition && Admin() < AccountStatus::QuestTroupe) ||
(channel_id == ChatChannel_GMSAY && !GetGM())
) {
return;
}
va_list argptr;
char buffer[4096];
char message_sender[64];
char buffer[4096];
char message_sender[64];
va_start(argptr, message);
vsnprintf(buffer, 4096, message, argptr);
va_end(argptr);
EQApplicationPacket app(OP_ChannelMessage, sizeof(ChannelMessage_Struct)+strlen(buffer)+1);
ChannelMessage_Struct* cm = (ChannelMessage_Struct*)app.pBuffer;
EQApplicationPacket app(OP_ChannelMessage, sizeof(ChannelMessage_Struct) + strlen(buffer) + 1);
if (from == 0)
auto* cm = (ChannelMessage_Struct *) app.pBuffer;
if (from == 0) {
strcpy(cm->sender, "ZServer");
else if (from[0] == 0)
} else if (from[0] == 0) {
strcpy(cm->sender, "ZServer");
else {
} else {
CleanMobName(from, message_sender);
strcpy(cm->sender, message_sender);
}
if (to != 0)
if (to != 0) {
strcpy((char *) cm->targetname, to);
else if (chan_num == ChatChannel_Tell)
} else if (channel_id == ChatChannel_Tell) {
strcpy(cm->targetname, m_pp.name);
else
} else {
cm->targetname[0] = 0;
uint8 ListenerSkill;
if (language < MAX_PP_LANGUAGE) {
ListenerSkill = m_pp.languages[language];
if (ListenerSkill < 24) {
cm->language = (MAX_PP_LANGUAGE - 1); // in an unknown tongue
}
else {
cm->language = language;
}
}
else {
ListenerSkill = m_pp.languages[0];
cm->language = 0;
uint8 listener_skill;
const bool is_valid_language = EQ::ValueWithin(language_id, Language::CommonTongue, Language::Unknown27);
if (is_valid_language) {
listener_skill = m_pp.languages[language_id];
cm->language = listener_skill < 24 ? Language::Unknown27 : language_id;
} else {
listener_skill = m_pp.languages[Language::CommonTongue];
cm->language = Language::CommonTongue;
}
// set effective language skill = lower of sender and receiver skills
int32 EffSkill = (lang_skill < ListenerSkill ? lang_skill : ListenerSkill);
if (EffSkill > 100) // maximum language skill is 100
EffSkill = 100;
cm->skill_in_language = EffSkill;
uint8 effective_skill = (language_skill < listener_skill ? language_skill : listener_skill);
if (effective_skill > Language::MaxValue) {
effective_skill = Language::MaxValue;
}
cm->chan_num = chan_num;
cm->skill_in_language = effective_skill;
cm->chan_num = channel_id;
strcpy(&cm->message[0], buffer);
QueuePacket(&app);
bool senderCanTrainSelf = RuleB(Client, SelfLanguageLearning);
bool weAreNotSender = strcmp(GetCleanName(), cm->sender);
const bool can_train_self = RuleB(Client, SelfLanguageLearning);
const bool is_not_sender = strcmp(GetCleanName(), cm->sender);
if (senderCanTrainSelf || weAreNotSender) {
if ((chan_num == ChatChannel_Group) && (ListenerSkill < 100)) { // group message in unmastered language, check for skill up
if (language < MAX_PP_LANGUAGE && m_pp.languages[language] <= lang_skill)
CheckLanguageSkillIncrease(language, lang_skill);
if (can_train_self || is_not_sender) {
if (
channel_id == ChatChannel_Group &&
listener_skill < Language::MaxValue
) { // group message in non-mastered language, check for skill up
if (is_valid_language && m_pp.languages[language_id] <= language_skill) {
CheckLanguageSkillIncrease(language_id, language_skill);
}
}
}
}
@ -1637,26 +1660,30 @@ void Client::SetSkill(EQ::skills::SkillType skillid, uint16 value) {
safe_delete(outapp);
}
void Client::IncreaseLanguageSkill(int skill_id, int value) {
void Client::IncreaseLanguageSkill(uint8 language_id, uint8 increase)
{
if (!EQ::ValueWithin(language_id, Language::CommonTongue, Language::Unknown27)) {
return;
}
if (skill_id >= MAX_PP_LANGUAGE)
return; //Invalid lang id
m_pp.languages[language_id] += increase;
m_pp.languages[skill_id] += value;
if (m_pp.languages[language_id] > Language::MaxValue) {
m_pp.languages[language_id] = Language::MaxValue;
}
if (m_pp.languages[skill_id] > 100) //Lang skill above max
m_pp.languages[skill_id] = 100;
database.SaveCharacterLanguage(CharacterID(), skill_id, m_pp.languages[skill_id]);
database.SaveCharacterLanguage(CharacterID(), language_id, m_pp.languages[language_id]);
auto outapp = new EQApplicationPacket(OP_SkillUpdate, sizeof(SkillUpdate_Struct));
SkillUpdate_Struct* skill = (SkillUpdate_Struct*)outapp->pBuffer;
skill->skillId = 100 + skill_id;
skill->value = m_pp.languages[skill_id];
auto* s = (SkillUpdate_Struct*) outapp->pBuffer;
s->skillId = 100 + language_id;
s->value = m_pp.languages[language_id];
QueuePacket(outapp);
safe_delete(outapp);
MessageString( Chat::Skills, LANG_SKILL_IMPROVED ); //Notify client
MessageString(Chat::Skills, LANG_SKILL_IMPROVED);
}
void Client::AddSkill(EQ::skills::SkillType skillid, uint16 value) {
@ -2272,9 +2299,9 @@ void Client::ReadBook(BookRequest_Struct *book) {
memcpy(out->booktext, booktxt2.c_str(), length);
if (book_language > 0 && book_language < MAX_PP_LANGUAGE) {
if (m_pp.languages[book_language] < 100) {
GarbleMessage(out->booktext, (100 - m_pp.languages[book_language]));
if (EQ::ValueWithin(book_language, Language::CommonTongue, Language::Unknown27)) {
if (m_pp.languages[book_language] < Language::MaxValue) {
GarbleMessage(out->booktext, (Language::MaxValue - m_pp.languages[book_language]));
}
}
@ -2673,38 +2700,43 @@ bool Client::CheckIncreaseSkill(EQ::skills::SkillType skillid, Mob *against_who,
return false;
}
void Client::CheckLanguageSkillIncrease(uint8 langid, uint8 TeacherSkill) {
if (IsDead() || IsUnconscious())
void Client::CheckLanguageSkillIncrease(uint8 language_id, uint8 teacher_skill) {
if (IsDead() || IsUnconscious()) {
return;
if (IsAIControlled())
}
if (IsAIControlled()) {
return;
if (langid >= MAX_PP_LANGUAGE)
return; // do nothing if langid is an invalid language
}
int LangSkill = m_pp.languages[langid]; // get current language skill
if (!EQ::ValueWithin(language_id, Language::CommonTongue, Language::Unknown27)) {
return;
}
if (LangSkill < 100) { // if the language isn't already maxed
int32 Chance = 5 + ((TeacherSkill - LangSkill)/10); // greater chance to learn if teacher's skill is much higher than yours
Chance = (Chance * RuleI(Character, SkillUpModifier)/100);
const uint8 language_skill = m_pp.languages[language_id]; // get current language skill
if(zone->random.Real(0,100) < Chance) { // if they make the roll
IncreaseLanguageSkill(langid); // increase the language skill by 1
if (language_skill < Language::MaxValue) { // if the language isn't already maxed
int chance = 5 + ((teacher_skill - language_skill) / 10); // greater chance to learn if teacher's skill is much higher than yours
chance = (chance * RuleI(Character, SkillUpModifier) / 100);
if (zone->random.Real(0, 100) < chance) { // if they make the roll
IncreaseLanguageSkill(language_id);
if (parse->PlayerHasQuestSub(EVENT_LANGUAGE_SKILL_UP)) {
const auto& export_string = fmt::format(
const auto &export_string = fmt::format(
"{} {} {}",
langid,
LangSkill + 1,
100
language_id,
language_skill + 1,
Language::MaxValue
);
parse->EventPlayer(EVENT_LANGUAGE_SKILL_UP, this, export_string, 0);
}
LogSkills("Language [{}] at value [{}] successfully gain with [{}] % chance", langid, LangSkill, Chance);
LogSkills("Language [{}] at value [{}] successfully gain with [{}] % chance", language_id, language_skill, chance);
} else {
LogSkills("Language [{}] at value [{}] failed to gain with [{}] % chance", language_id, language_skill, chance);
}
else
LogSkills("Language [{}] at value [{}] failed to gain with [{}] % chance", langid, LangSkill, Chance);
}
}
@ -3566,25 +3598,30 @@ void Client::SetHideMe(bool flag)
UpdateWho();
}
void Client::SetLanguageSkill(int langid, int value)
void Client::SetLanguageSkill(uint8 language_id, uint8 language_skill)
{
if (langid >= MAX_PP_LANGUAGE)
return; //Invalid Language
if (!EQ::ValueWithin(language_id, Language::CommonTongue, Language::Unknown27)) {
return;
}
if (value > 100)
value = 100; //Max lang value
if (language_skill > Language::MaxValue) {
language_skill = Language::MaxValue;
}
m_pp.languages[langid] = value;
database.SaveCharacterLanguage(CharacterID(), langid, value);
m_pp.languages[language_id] = language_skill;
database.SaveCharacterLanguage(CharacterID(), language_id, language_skill);
auto outapp = new EQApplicationPacket(OP_SkillUpdate, sizeof(SkillUpdate_Struct));
SkillUpdate_Struct* skill = (SkillUpdate_Struct*)outapp->pBuffer;
skill->skillId = 100 + langid;
skill->value = m_pp.languages[langid];
auto* s = (SkillUpdate_Struct*) outapp->pBuffer;
s->skillId = 100 + language_id;
s->value = m_pp.languages[language_id];
QueuePacket(outapp);
safe_delete(outapp);
MessageString( Chat::Skills, LANG_SKILL_IMPROVED ); //Notify the client
MessageString(Chat::Skills, LANG_SKILL_IMPROVED);
}
void Client::LinkDead()
@ -10546,9 +10583,9 @@ void Client::ReadBookByName(std::string book_name, uint8 book_type)
memcpy(out->booktext, book_text.c_str(), length);
if (book_language > 0 && book_language < MAX_PP_LANGUAGE) {
if (m_pp.languages[book_language] < 100) {
GarbleMessage(out->booktext, (100 - m_pp.languages[book_language]));
if (EQ::ValueWithin(book_language, Language::CommonTongue, Language::Unknown27)) {
if (m_pp.languages[book_language] < Language::MaxValue) {
GarbleMessage(out->booktext, (Language::MaxValue - m_pp.languages[book_language]));
}
}

View File

@ -335,7 +335,7 @@ public:
void QueuePacket(const EQApplicationPacket* app, bool ack_req = true, CLIENT_CONN_STATUS = CLIENT_CONNECTINGALL, eqFilterType filter=FilterNone);
void FastQueuePacket(EQApplicationPacket** app, bool ack_req = true, CLIENT_CONN_STATUS = CLIENT_CONNECTINGALL);
void ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_skill, const char* orig_message, const char* targetname = nullptr, bool is_silent = false);
void ChannelMessageSend(const char* from, const char* to, uint8 chan_num, uint8 language, uint8 lang_skill, const char* message, ...);
void ChannelMessageSend(const char* from, const char* to, uint8 channel_id, uint8 language_id, uint8 language_skill, const char* message, ...);
void Message(uint32 type, const char* message, ...);
void FilteredMessage(Mob *sender, uint32 type, eqFilterType filter, const char* message, ...);
void VoiceMacroReceived(uint32 Type, char *Target, uint32 MacroNumber);
@ -452,7 +452,7 @@ public:
void SendSingleTraderItem(uint32 char_id, int uniqueid);
void BulkSendMerchantInventory(int merchant_id, int npcid);
inline uint8 GetLanguageSkill(uint16 n) const { return m_pp.languages[n]; }
inline uint8 GetLanguageSkill(uint8 language_id) const { return m_pp.languages[language_id]; }
void SendPickPocketResponse(Mob *from, uint32 amt, int type, const EQ::ItemData* item = nullptr);
@ -767,7 +767,7 @@ public:
void SetSkillPoints(int inp) { m_pp.points = inp;}
void IncreaseSkill(int skill_id, int value = 1) { if (skill_id <= EQ::skills::HIGHEST_SKILL) { m_pp.skills[skill_id] += value; } }
void IncreaseLanguageSkill(int skill_id, int value = 1);
void IncreaseLanguageSkill(uint8 language_id, uint8 increase = 1);
virtual uint16 GetSkill(EQ::skills::SkillType skill_id) const { if (skill_id <= EQ::skills::HIGHEST_SKILL) { return(itembonuses.skillmod[skill_id] > 0 ? (itembonuses.skillmodmax[skill_id] > 0 ? std::min(m_pp.skills[skill_id] + itembonuses.skillmodmax[skill_id], m_pp.skills[skill_id] * (100 + itembonuses.skillmod[skill_id]) / 100) : m_pp.skills[skill_id] * (100 + itembonuses.skillmod[skill_id]) / 100) : m_pp.skills[skill_id]); } return 0; }
uint32 GetRawSkill(EQ::skills::SkillType skill_id) const { if (skill_id <= EQ::skills::HIGHEST_SKILL) { return(m_pp.skills[skill_id]); } return 0; }
bool HasSkill(EQ::skills::SkillType skill_id) const;
@ -777,8 +777,8 @@ public:
void CheckSpecializeIncrease(uint16 spell_id);
void CheckSongSkillIncrease(uint16 spell_id);
bool CheckIncreaseSkill(EQ::skills::SkillType skillid, Mob *against_who, int chancemodi = 0);
void CheckLanguageSkillIncrease(uint8 langid, uint8 TeacherSkill);
void SetLanguageSkill(int langid, int value);
void CheckLanguageSkillIncrease(uint8 language_id, uint8 teacher_skill);
void SetLanguageSkill(uint8 language_id, uint8 language_skill);
void SetHoTT(uint32 mobid);
void ShowSkillsWindow();

View File

@ -4505,23 +4505,24 @@ void Client::Handle_OP_CastSpell(const EQApplicationPacket *app)
void Client::Handle_OP_ChannelMessage(const EQApplicationPacket *app)
{
ChannelMessage_Struct* cm = (ChannelMessage_Struct*)app->pBuffer;
auto* cm = (ChannelMessage_Struct*) app->pBuffer;
if (app->size < sizeof(ChannelMessage_Struct)) {
std::cout << "Wrong size " << app->size << ", should be " << sizeof(ChannelMessage_Struct) << "+ on 0x" << std::hex << std::setfill('0') << std::setw(4) << app->GetOpcode() << std::dec << std::endl;
return;
}
if (IsAIControlled() && !GetGM()) {
Message(Chat::Red, "You try to speak but cant move your mouth!");
LogDebug("Size mismatch in OP_ChannelMessage expected [{}] got [{}]", sizeof(ChannelMessage_Struct), app->size);
return;
}
uint8 skill_in_language = 100;
if (cm->language < MAX_PP_LANGUAGE)
{
skill_in_language = m_pp.languages[cm->language];
if (IsAIControlled() && !GetGM()) {
Message(Chat::Red, "You try to speak but can't move your mouth!");
return;
}
ChannelMessageReceived(cm->chan_num, cm->language, skill_in_language, cm->message, cm->targetname);
uint8 language_skill = Language::MaxValue;
if (EQ::ValueWithin(cm->language, Language::CommonTongue, Language::Unknown27)) {
language_skill = m_pp.languages[cm->language];
}
ChannelMessageReceived(cm->chan_num, cm->language, language_skill, cm->message, cm->targetname);
return;
}
@ -8862,7 +8863,7 @@ void Client::Handle_OP_ItemLinkClick(const EQApplicationPacket *app)
Message(Chat::LightGray, "You say, '%s'", response.c_str());
}
ChannelMessageReceived(ChatChannel_Say, 0, 100, response.c_str(), nullptr, true);
ChannelMessageReceived(ChatChannel_Say, Language::CommonTongue, Language::MaxValue, response.c_str(), nullptr, true);
return;
}
@ -11573,7 +11574,7 @@ void Client::Handle_OP_PopupResponse(const EQApplicationPacket *app)
if (EntityVariableExists(DIAWIND_RESPONSE_ONE_KEY)) {
response = GetEntityVariable(DIAWIND_RESPONSE_ONE_KEY);
if (!response.empty()) {
ChannelMessageReceived(ChatChannel_Say, 0, 100, response.c_str(), nullptr, true);
ChannelMessageReceived(ChatChannel_Say, Language::CommonTongue, Language::MaxValue, response.c_str(), nullptr, true);
}
}
break;
@ -11582,7 +11583,7 @@ void Client::Handle_OP_PopupResponse(const EQApplicationPacket *app)
if (EntityVariableExists(DIAWIND_RESPONSE_TWO_KEY)) {
response = GetEntityVariable(DIAWIND_RESPONSE_TWO_KEY);
if (!response.empty()) {
ChannelMessageReceived(ChatChannel_Say, 0, 100, response.c_str(), nullptr, true);
ChannelMessageReceived(ChatChannel_Say, Language::CommonTongue, Language::MaxValue, response.c_str(), nullptr, true);
}
}
break;

View File

@ -93,13 +93,13 @@ void Perl__say(const char* message)
// we currently default to these
opts.speak_mode = Journal::SpeakMode::Say;
opts.journal_mode = Journal::Mode::Log2;
opts.language = 0;
opts.language = Language::CommonTongue;
opts.message_type = Chat::NPCQuestSay;
quest_manager.say(message, opts);
}
void Perl__say(const char* message, int language_id)
void Perl__say(const char* message, uint8 language_id)
{
Journal::Options opts;
opts.speak_mode = Journal::SpeakMode::Say;
@ -110,7 +110,7 @@ void Perl__say(const char* message, int language_id)
quest_manager.say(message, opts);
}
void Perl__say(const char* message, int language_id, int message_type)
void Perl__say(const char* message, uint8 language_id, int message_type)
{
Journal::Options opts;
opts.speak_mode = Journal::SpeakMode::Say;
@ -121,7 +121,7 @@ void Perl__say(const char* message, int language_id, int message_type)
quest_manager.say(message, opts);
}
void Perl__say(const char* message, int language_id, int message_type, int speak_mode)
void Perl__say(const char* message, uint8 language_id, int message_type, int speak_mode)
{
Journal::Options opts;
opts.speak_mode = static_cast<Journal::SpeakMode>(speak_mode);
@ -132,7 +132,7 @@ void Perl__say(const char* message, int language_id, int message_type, int speak
quest_manager.say(message, opts);
}
void Perl__say(const char* message, int language_id, int message_type, int speak_mode, int journal_mode)
void Perl__say(const char* message, uint8 language_id, int message_type, int speak_mode, int journal_mode)
{
Journal::Options opts;
opts.speak_mode = static_cast<Journal::SpeakMode>(speak_mode);
@ -674,9 +674,9 @@ void Perl__addskill(int skill_id, int value)
quest_manager.addskill(skill_id, value);
}
void Perl__setlanguage(int skill_id, int value)
void Perl__setlanguage(uint8 language_id, uint8 language_skill)
{
quest_manager.setlanguage(skill_id, value);
quest_manager.setlanguage(language_id, language_skill);
}
void Perl__setskill(int skill_id, int value)
@ -4713,7 +4713,7 @@ std::string Perl__getfactionname(int faction_id)
return quest_manager.getfactionname(faction_id);
}
std::string Perl__getlanguagename(int language_id)
std::string Perl__getlanguagename(uint8 language_id)
{
return quest_manager.getlanguagename(language_id);
}
@ -6532,10 +6532,10 @@ void perl_register_quest()
package.add("safemove", &Perl__safemove);
package.add("save", &Perl__save);
package.add("say", (void(*)(const char*))&Perl__say);
package.add("say", (void(*)(const char*, int))&Perl__say);
package.add("say", (void(*)(const char*, int, int))&Perl__say);
package.add("say", (void(*)(const char*, int, int, int))&Perl__say);
package.add("say", (void(*)(const char*, int, int, int, int))&Perl__say);
package.add("say", (void(*)(const char*, uint8))&Perl__say);
package.add("say", (void(*)(const char*, uint8, int))&Perl__say);
package.add("say", (void(*)(const char*, uint8, int, int))&Perl__say);
package.add("say", (void(*)(const char*, uint8, int, int, int))&Perl__say);
package.add("saylink", (std::string(*)(const char*))&Perl__saylink);
package.add("saylink", (std::string(*)(const char*, bool))&Perl__saylink);
package.add("saylink", (std::string(*)(const char*, bool, const char*))&Perl__saylink);

View File

@ -1282,7 +1282,7 @@ uint16 EntityList::GetFreeID()
// if no language skill is specified, sent with 100 skill
void EntityList::ChannelMessage(Mob *from, uint8 chan_num, uint8 language, const char *message, ...)
{
ChannelMessage(from, chan_num, language, 100, message);
ChannelMessage(from, chan_num, language, Language::MaxValue, message);
}
void EntityList::ChannelMessage(Mob *from, uint8 chan_num, uint8 language,
@ -4588,7 +4588,7 @@ void EntityList::GroupMessage(uint32 gid, const char *from, const char *message)
g = it->second->GetGroup();
if (g) {
if (g->GetID() == gid)
it->second->ChannelMessageSend(from, it->second->GetName(), ChatChannel_Group, 0, 100, message);
it->second->ChannelMessageSend(from, it->second->GetName(), ChatChannel_Group, Language::CommonTongue, Language::MaxValue, message);
}
}
++it;

View File

@ -13,7 +13,7 @@ void command_chat(Client *c, const Seperator *sep)
auto channel_id = static_cast<uint8>(Strings::ToUnsignedInt(sep->arg[1]));
std::string message = sep->argplus[2];
if (!worldserver.SendChannelMessage(0, 0, channel_id, 0, 0, 100, message.c_str())) {
if (!worldserver.SendChannelMessage(0, 0, channel_id, 0, Language::CommonTongue, Language::MaxValue, message.c_str())) {
c->Message(Chat::White, "World server is disconnected.");
}
}

View File

@ -1,11 +1,10 @@
#include "../../client.h"
#include "../../common/languages.h"
void FindLanguage(Client *c, const Seperator *sep)
{
if (sep->IsNumber(2)) {
const auto language_id = Strings::ToInt(sep->arg[2]);
if (EQ::ValueWithin(language_id, LANG_COMMON_TONGUE, LANG_UNKNOWN)) {
if (EQ::ValueWithin(language_id, Language::CommonTongue, Language::Unknown27)) {
c->Message(
Chat::White,
fmt::format(

View File

@ -1,43 +1,42 @@
#include "../../client.h"
#include "../../../common/languages.h"
#include "../../../common/data_verification.h"
void SetLanguage(Client *c, const Seperator *sep)
{
const auto arguments = sep->argnum;
const int arguments = sep->argnum;
if (arguments < 3 || !sep->IsNumber(2) || !sep->IsNumber(3)) {
c->Message(Chat::White, "Usage: #set language [Language ID] [Language Value]");
c->Message(Chat::White, "Usage: #set language [Language ID] [Language Skill]");
c->Message(Chat::White, "Language ID = 0 to 27");
c->Message(Chat::White, "Language Value = 0 to 100");
c->Message(Chat::White, "Language Skill = 0 to 100");
return;
}
auto t = c;
Client* t = c;
if (c->GetTarget() && c->GetTarget()->IsClient()) {
t = c->GetTarget()->CastToClient();
}
const int language_id = Strings::ToInt(sep->arg[2]);
const int language_value = Strings::ToInt(sep->arg[3]);
const uint8 language_id = Strings::ToInt(sep->arg[2]);
const uint8 language_skill = Strings::ToInt(sep->arg[3]);
if (
!EQ::ValueWithin(language_id, LANG_COMMON_TONGUE, LANG_UNKNOWN) ||
!EQ::ValueWithin(language_value, 0, MAX_LANGUAGE_SKILL)
!EQ::ValueWithin(language_id, Language::CommonTongue, Language::Unknown27) ||
!EQ::ValueWithin(language_skill, 0, Language::MaxValue)
) {
c->Message(Chat::White, "Usage: #set language [Language ID] [Language Value]");
c->Message(Chat::White, "Usage: #set language [Language ID] [Language Skill]");
c->Message(Chat::White, "Language ID = 0 to 27");
c->Message(Chat::White, "Language Value = 0 to 100");
c->Message(Chat::White, "Language Skill = 0 to 100");
return;
}
LogInfo(
"Set language request from [{}], Target: [{}] Language ID: [{}] Language Value: [{}]",
"Set language request from [{}], Target: [{}] Language ID: [{}] Language Skill: [{}]",
c->GetCleanName(),
c->GetTargetDescription(t),
language_id,
language_value
language_skill
);
t->SetLanguageSkill(language_id, language_value);
t->SetLanguageSkill(language_id, language_skill);
if (c != t) {
c->Message(
@ -46,7 +45,7 @@ void SetLanguage(Client *c, const Seperator *sep)
"Set {} ({}) to {} for {}.",
EQ::constants::GetLanguageName(language_id),
language_id,
language_value,
language_skill,
c->GetTargetDescription(t)
).c_str()
);

View File

@ -494,14 +494,14 @@ void Lua_Client::IncreaseSkill(int skill_id, int value) {
self->IncreaseSkill(skill_id, value);
}
void Lua_Client::IncreaseLanguageSkill(int skill_id) {
void Lua_Client::IncreaseLanguageSkill(uint8 language_id) {
Lua_Safe_Call_Void();
self->IncreaseLanguageSkill(skill_id);
self->IncreaseLanguageSkill(language_id);
}
void Lua_Client::IncreaseLanguageSkill(int skill_id, int value) {
void Lua_Client::IncreaseLanguageSkill(uint8 language_id, uint8 increase) {
Lua_Safe_Call_Void();
self->IncreaseLanguageSkill(skill_id, value);
self->IncreaseLanguageSkill(language_id, increase);
}
int Lua_Client::GetRawSkill(int skill_id) {
@ -544,9 +544,9 @@ void Lua_Client::CheckIncreaseSkill(int skill_id, Lua_Mob target, int chance_mod
self->CheckIncreaseSkill(static_cast<EQ::skills::SkillType>(skill_id), target, chance_mod);
}
void Lua_Client::SetLanguageSkill(int language, int value) {
void Lua_Client::SetLanguageSkill(uint8 language_id, uint8 language_skill) {
Lua_Safe_Call_Void();
self->SetLanguageSkill(language, value);
self->SetLanguageSkill(language_id, language_skill);
}
int Lua_Client::MaxSkill(int skill_id) {
@ -3523,8 +3523,8 @@ luabind::scope lua_register_client() {
.def("Hungry", (bool(Lua_Client::*)(void))&Lua_Client::Hungry)
.def("InZone", (bool(Lua_Client::*)(void))&Lua_Client::InZone)
.def("IncStats", (void(Lua_Client::*)(int,int))&Lua_Client::IncStats)
.def("IncreaseLanguageSkill", (void(Lua_Client::*)(int))&Lua_Client::IncreaseLanguageSkill)
.def("IncreaseLanguageSkill", (void(Lua_Client::*)(int,int))&Lua_Client::IncreaseLanguageSkill)
.def("IncreaseLanguageSkill", (void(Lua_Client::*)(uint8))&Lua_Client::IncreaseLanguageSkill)
.def("IncreaseLanguageSkill", (void(Lua_Client::*)(uint8,uint8))&Lua_Client::IncreaseLanguageSkill)
.def("IncreaseSkill", (void(Lua_Client::*)(int))&Lua_Client::IncreaseSkill)
.def("IncreaseSkill", (void(Lua_Client::*)(int,int))&Lua_Client::IncreaseSkill)
.def("IncrementAA", (void(Lua_Client::*)(int))&Lua_Client::IncrementAA)

View File

@ -165,8 +165,8 @@ public:
void SetSkillPoints(int skill);
void IncreaseSkill(int skill_id);
void IncreaseSkill(int skill_id, int value);
void IncreaseLanguageSkill(int skill_id);
void IncreaseLanguageSkill(int skill_id, int value);
void IncreaseLanguageSkill(uint8 language_id);
void IncreaseLanguageSkill(uint8 language_id, uint8 increase);
int GetRawSkill(int skill_id);
bool HasSkill(int skill_id);
bool CanHaveSkill(int skill_id);
@ -175,7 +175,7 @@ public:
void CheckSpecializeIncrease(int spell_id);
void CheckIncreaseSkill(int skill_id, Lua_Mob target);
void CheckIncreaseSkill(int skill_id, Lua_Mob target, int chance_mod);
void SetLanguageSkill(int language, int value);
void SetLanguageSkill(uint8 language_id, uint8 language_skill);
int MaxSkill(int skill_id);
bool IsMedding();
int GetDuelTarget();

View File

@ -570,9 +570,9 @@ void Lua_EntityList::SignalAllClients(int signal_id) {
self->SignalAllClients(signal_id);
}
void Lua_EntityList::ChannelMessage(Lua_Mob from, int channel_num, int language, const char *message) {
void Lua_EntityList::ChannelMessage(Lua_Mob from, int channel_num, uint8 language_id, const char *message) {
Lua_Safe_Call_Void();
self->ChannelMessage(from, channel_num, language, message);
self->ChannelMessage(from, channel_num, language_id, message);
}
Lua_Mob Lua_EntityList::GetRandomMob() {
@ -686,7 +686,7 @@ luabind::scope lua_register_entity_list() {
.property("null", &Lua_EntityList::Null)
.property("valid", &Lua_EntityList::Valid)
.def("CanAddHateForMob", (bool(Lua_EntityList::*)(Lua_Mob))&Lua_EntityList::CanAddHateForMob)
.def("ChannelMessage", (void(Lua_EntityList::*)(Lua_Mob, int, int, const char*))&Lua_EntityList::ChannelMessage)
.def("ChannelMessage", (void(Lua_EntityList::*)(Lua_Mob, int, uint8, const char*))&Lua_EntityList::ChannelMessage)
.def("ClearClientPetitionQueue", (void(Lua_EntityList::*)(void))&Lua_EntityList::ClearClientPetitionQueue)
.def("ClearFeignAggro", (void(Lua_EntityList::*)(Lua_Mob))&Lua_EntityList::ClearFeignAggro)
.def("DeleteNPCCorpses", (uint32(Lua_EntityList::*)(void))&Lua_EntityList::DeleteNPCCorpses)

View File

@ -122,7 +122,7 @@ public:
Lua_Doors_List GetDoorsList();
Lua_Spawn_List GetSpawnList();
void SignalAllClients(int signal_id);
void ChannelMessage(Lua_Mob from, int channel_num, int language, const char *message);
void ChannelMessage(Lua_Mob from, int channel_num, uint8 language, const char *message);
Lua_Bot GetBotByID(uint32 bot_id);
Lua_Bot GetBotByName(std::string bot_name);
Lua_Client GetBotOwnerByBotEntityID(uint32 entity_id);

View File

@ -3789,7 +3789,7 @@ std::string lua_get_faction_name(int faction_id) {
return quest_manager.getfactionname(faction_id);
}
std::string lua_get_language_name(int language_id) {
std::string lua_get_language_name(uint8 language_id) {
return quest_manager.getlanguagename(language_id);
}

View File

@ -39,12 +39,12 @@ void Lua_Group::SplitExp(uint64 exp, Lua_Mob other) {
void Lua_Group::GroupMessage(Lua_Mob sender, const char* message) {
Lua_Safe_Call_Void();
self->GroupMessage(sender, 0, 100, message);
self->GroupMessage(sender, Language::CommonTongue, Language::MaxValue, message);
}
void Lua_Group::GroupMessage(Lua_Mob sender, int language, const char* message) {
void Lua_Group::GroupMessage(Lua_Mob sender, uint8 language, const char* message) {
Lua_Safe_Call_Void();
self->GroupMessage(sender, language, 100, message);
self->GroupMessage(sender, language, Language::MaxValue, message);
}
uint32 Lua_Group::GetTotalGroupDamage(Lua_Mob other) {
@ -158,7 +158,7 @@ luabind::scope lua_register_group() {
.def("GetTotalGroupDamage", (uint32(Lua_Group::*)(Lua_Mob))&Lua_Group::GetTotalGroupDamage)
.def("GroupCount", (int(Lua_Group::*)(void))&Lua_Group::GroupCount)
.def("GroupMessage", (void(Lua_Group::*)(Lua_Mob,const char*))&Lua_Group::GroupMessage)
.def("GroupMessage", (void(Lua_Group::*)(Lua_Mob,int,const char*))&Lua_Group::GroupMessage)
.def("GroupMessage", (void(Lua_Group::*)(Lua_Mob,uint8,const char*))&Lua_Group::GroupMessage)
.def("IsGroupMember", (bool(Lua_Group::*)(const char*))&Lua_Group::IsGroupMember)
.def("IsGroupMember", (bool(Lua_Group::*)(Lua_Mob))&Lua_Group::IsGroupMember)
.def("IsLeader", (bool(Lua_Group::*)(const char*))&Lua_Group::IsLeader)

View File

@ -33,7 +33,7 @@ public:
void CastGroupSpell(Lua_Mob caster, int spell_id);
void SplitExp(uint64 exp, Lua_Mob other);
void GroupMessage(Lua_Mob sender, const char* message);
void GroupMessage(Lua_Mob sender, int language, const char* message);
void GroupMessage(Lua_Mob sender, uint8 language_id, const char* message);
uint32 GetTotalGroupDamage(Lua_Mob other);
void SplitMoney(uint32 copper, uint32 silver, uint32 gold, uint32 platinum);
void SplitMoney(uint32 copper, uint32 silver, uint32 gold, uint32 platinum, Lua_Client splitter);

View File

@ -3,7 +3,6 @@
#include <luabind/luabind.hpp>
#include <luabind/object.hpp>
#include "../common/languages.h"
#include "masterentity.h"
#include "lua_iteminst.h"
#include "lua_item.h"
@ -309,13 +308,13 @@ std::string Lua_ItemInst::GetName() {
void Lua_ItemInst::ItemSay(const char* text) // @categories Inventory and Items
{
Lua_Safe_Call_Void();
quest_manager.GetInitiator()->ChannelMessageSend(self->GetItem()->Name, 0, ChatChannel_Say, LANG_COMMON_TONGUE, MAX_LANGUAGE_SKILL, text);
quest_manager.GetInitiator()->ChannelMessageSend(self->GetItem()->Name, 0, ChatChannel_Say, Language::CommonTongue, Language::MaxValue, text);
}
void Lua_ItemInst::ItemSay(const char* text, uint8 language_id) // @categories Inventory and Items
{
Lua_Safe_Call_Void();
quest_manager.GetInitiator()->ChannelMessageSend(self->GetItem()->Name, 0, ChatChannel_Say, language_id, MAX_LANGUAGE_SKILL, text);
quest_manager.GetInitiator()->ChannelMessageSend(self->GetItem()->Name, 0, ChatChannel_Say, language_id, Language::MaxValue, text);
}
luabind::scope lua_register_iteminst() {

View File

@ -788,9 +788,9 @@ void Lua_Mob::Say(const char *message) {
self->Say(message);
}
void Lua_Mob::Say(const char* message, int language) {
void Lua_Mob::Say(const char* message, uint8 language_id) {
Lua_Safe_Call_Void();
entity_list.ChannelMessage(self, ChatChannel_Say, language, message); // these run through the client channels and probably shouldn't for NPCs, but oh well
entity_list.ChannelMessage(self, ChatChannel_Say, language_id, message); // these run through the client channels and probably shouldn't for NPCs, but oh well
}
void Lua_Mob::QuestSay(Lua_Client client, const char *message) {
@ -798,7 +798,7 @@ void Lua_Mob::QuestSay(Lua_Client client, const char *message) {
Journal::Options journal_opts;
journal_opts.speak_mode = Journal::SpeakMode::Say;
journal_opts.journal_mode = RuleB(NPC, EnableNPCQuestJournal) ? Journal::Mode::Log2 : Journal::Mode::None;
journal_opts.language = 0;
journal_opts.language = Language::CommonTongue;
journal_opts.message_type = Chat::NPCQuestSay;
journal_opts.target_spawn_id = 0;
self->QuestJournalledSay(client, message, journal_opts);
@ -811,7 +811,7 @@ void Lua_Mob::QuestSay(Lua_Client client, const char *message, luabind::adl::obj
// defaults
journal_opts.speak_mode = Journal::SpeakMode::Say;
journal_opts.journal_mode = Journal::Mode::Log2;
journal_opts.language = 0;
journal_opts.language = Language::CommonTongue;
journal_opts.message_type = Chat::NPCQuestSay;
journal_opts.target_spawn_id = 0;
@ -861,9 +861,9 @@ void Lua_Mob::Shout(const char *message) {
self->Shout(message);
}
void Lua_Mob::Shout(const char* message, int language) {
void Lua_Mob::Shout(const char* message, uint8 language_id) {
Lua_Safe_Call_Void();
entity_list.ChannelMessage(self, ChatChannel_Shout, language, message);
entity_list.ChannelMessage(self, ChatChannel_Shout, language_id, message);
}
void Lua_Mob::Emote(const char *message) {
@ -3638,7 +3638,7 @@ luabind::scope lua_register_mob() {
.def("ResumeTimer", &Lua_Mob::ResumeTimer)
.def("RunTo", (void(Lua_Mob::*)(double, double, double))&Lua_Mob::RunTo)
.def("Say", (void(Lua_Mob::*)(const char*))& Lua_Mob::Say)
.def("Say", (void(Lua_Mob::*)(const char*, int))& Lua_Mob::Say)
.def("Say", (void(Lua_Mob::*)(const char*, uint8))& Lua_Mob::Say)
.def("SeeHide", (bool(Lua_Mob::*)(void))&Lua_Mob::SeeHide)
.def("SeeImprovedHide", (bool(Lua_Mob::*)(bool))&Lua_Mob::SeeImprovedHide)
.def("SeeInvisible", (uint8(Lua_Mob::*)(void))&Lua_Mob::SeeInvisible)
@ -3705,7 +3705,7 @@ luabind::scope lua_register_mob() {
.def("StopAllTimers", &Lua_Mob::StopAllTimers)
.def("StopTimer", &Lua_Mob::StopTimer)
.def("Shout", (void(Lua_Mob::*)(const char*))& Lua_Mob::Shout)
.def("Shout", (void(Lua_Mob::*)(const char*, int))& Lua_Mob::Shout)
.def("Shout", (void(Lua_Mob::*)(const char*, uint8))& Lua_Mob::Shout)
.def("Signal", (void(Lua_Mob::*)(int))&Lua_Mob::Signal)
.def("SpellEffect", &Lua_Mob::SpellEffect)
.def("SpellFinished", (bool(Lua_Mob::*)(int,Lua_Mob))&Lua_Mob::SpellFinished)

View File

@ -186,11 +186,11 @@ public:
void Message(uint32 type, const char *message);
void MessageString(uint32 type, uint32 string_id, uint32 distance);
void Say(const char *message);
void Say(const char* message, int language);
void Say(const char* message, uint8 language_id);
void QuestSay(Lua_Client client, const char *message);
void QuestSay(Lua_Client client, const char *message, luabind::adl::object opts);
void Shout(const char *message);
void Shout(const char* message, int language);
void Shout(const char* message, uint8 language_id);
void Emote(const char *message);
void InterruptSpell();
void InterruptSpell(int spell_id);

View File

@ -3546,7 +3546,7 @@ void Merc::MercGroupSay(Mob *speaker, const char *msg, ...)
Group *g = speaker->GetGroup();
if(g)
g->GroupMessage(speaker->CastToMob(), 0, 100, buf);
g->GroupMessage(speaker->CastToMob(), Language::CommonTongue, Language::MaxValue, buf);
}
}

View File

@ -464,14 +464,14 @@ void Perl_Client_IncreaseSkill(Client* self, int skill_id, int value) // @catego
self->IncreaseSkill(skill_id, value);
}
void Perl_Client_IncreaseLanguageSkill(Client* self, int skill_id) // @categories Skills and Recipes
void Perl_Client_IncreaseLanguageSkill(Client* self, uint8 language_id) // @categories Skills and Recipes
{
self->IncreaseLanguageSkill(skill_id);
self->IncreaseLanguageSkill(language_id);
}
void Perl_Client_IncreaseLanguageSkill(Client* self, int skill_id, int value) // @categories Skills and Recipes
void Perl_Client_IncreaseLanguageSkill(Client* self, uint8 language_id, uint8 increase) // @categories Skills and Recipes
{
self->IncreaseLanguageSkill(skill_id, value);
self->IncreaseLanguageSkill(language_id, increase);
}
uint32_t Perl_Client_GetRawSkill(Client* self, int skill_id) // @categories Skills and Recipes
@ -514,9 +514,9 @@ bool Perl_Client_CheckIncreaseSkill(Client* self, int skill_id, int chance_modif
return self->CheckIncreaseSkill(static_cast<EQ::skills::SkillType>(skill_id), nullptr, chance_modifier);
}
void Perl_Client_SetLanguageSkill(Client* self, int language_id, int value) // @categories Account and Character, Skills and Recipes, Stats and Attributes
void Perl_Client_SetLanguageSkill(Client* self, uint8 language_id, uint8 language_skill) // @categories Account and Character, Skills and Recipes, Stats and Attributes
{
self->SetLanguageSkill(language_id, value);
self->SetLanguageSkill(language_id, language_skill);
}
int Perl_Client_MaxSkill(Client* self, uint16 skill_id) // @categories Skills and Recipes
@ -1591,7 +1591,7 @@ void Perl_Client_SilentMessage(Client* self, const char* message) // @categories
if (self->GetTarget()->CastToNPC()->IsMoving() &&
!self->GetTarget()->CastToNPC()->IsOnHatelist(self->GetTarget()))
self->GetTarget()->CastToNPC()->PauseWandering(RuleI(NPC, SayPauseTimeInSec));
self->ChannelMessageReceived(ChatChannel_Say, 0, 100, message, nullptr, true);
self->ChannelMessageReceived(ChatChannel_Say, Language::CommonTongue, Language::MaxValue, message, nullptr, true);
}
}
}
@ -3334,8 +3334,8 @@ void perl_register_client()
package.add("Hungry", &Perl_Client_Hungry);
package.add("InZone", &Perl_Client_InZone);
package.add("IncStats", &Perl_Client_IncStats);
package.add("IncreaseLanguageSkill", (void(*)(Client*, int))&Perl_Client_IncreaseLanguageSkill);
package.add("IncreaseLanguageSkill", (void(*)(Client*, int, int))&Perl_Client_IncreaseLanguageSkill);
package.add("IncreaseLanguageSkill", (void(*)(Client*, uint8))&Perl_Client_IncreaseLanguageSkill);
package.add("IncreaseLanguageSkill", (void(*)(Client*, uint8, uint8))&Perl_Client_IncreaseLanguageSkill);
package.add("IncreaseSkill", (void(*)(Client*, int))&Perl_Client_IncreaseSkill);
package.add("IncreaseSkill", (void(*)(Client*, int, int))&Perl_Client_IncreaseSkill);
package.add("IncrementAA", &Perl_Client_IncrementAA);

View File

@ -35,16 +35,16 @@ void Perl_Group_SplitExp(Group* self, uint32_t exp, Mob* other) // @categories A
void Perl_Group_GroupMessage(Group* self, Mob* sender, const char* message) // @categories Script Utility, Group
{
// if no language is specificed, send it in common
self->GroupMessage(sender, 0, 100, message);
self->GroupMessage(sender, Language::CommonTongue, Language::MaxValue, message);
}
void Perl_Group_GroupMessage(Group* self, Mob* sender, uint8_t language, const char* message) // @categories Script Utility, Group
{
if (!EQ::ValueWithin(language, 0, (MAX_PP_LANGUAGE - 1))) {
language = 0;
if (!EQ::ValueWithin(language, Language::CommonTongue, Language::Unknown27)) {
language = Language::CommonTongue;
}
self->GroupMessage(sender, language, 100, message);
self->GroupMessage(sender, language, Language::MaxValue, message);
}
uint32_t Perl_Group_GetTotalGroupDamage(Group* self, Mob* other) // @categories Script Utility, Group

View File

@ -1,5 +1,4 @@
#include "../common/features.h"
#include "../common/languages.h"
#include "client.h"
#ifdef EMBPERL_XS_CLASSES
@ -21,12 +20,12 @@ void Perl_QuestItem_SetScale(EQ::ItemInstance* self, float scale_multiplier) //
void Perl_QuestItem_ItemSay(EQ::ItemInstance* self, const char* text) // @categories Inventory and Items
{
quest_manager.GetInitiator()->ChannelMessageSend(self->GetItem()->Name, 0, ChatChannel_Say, LANG_COMMON_TONGUE, MAX_LANGUAGE_SKILL, text);
quest_manager.GetInitiator()->ChannelMessageSend(self->GetItem()->Name, 0, ChatChannel_Say, Language::CommonTongue, Language::MaxValue, text);
}
void Perl_QuestItem_ItemSay(EQ::ItemInstance* self, const char* text, uint8 language_id) // @categories Inventory and Items
{
quest_manager.GetInitiator()->ChannelMessageSend(self->GetItem()->Name, 0, ChatChannel_Say, language_id, MAX_LANGUAGE_SKILL, text);
quest_manager.GetInitiator()->ChannelMessageSend(self->GetItem()->Name, 0, ChatChannel_Say, language_id, Language::MaxValue, text);
}
bool Perl_QuestItem_IsType(EQ::ItemInstance* self, int type) // @categories Inventory and Items

View File

@ -1081,7 +1081,7 @@ std::string QuestManager::getfactionname(int faction_id) {
return content_db.GetFactionName(faction_id);
}
std::string QuestManager::getlanguagename(int language_id) {
std::string QuestManager::getlanguagename(uint8 language_id) {
return EQ::constants::GetLanguageName(language_id);
}
@ -1331,14 +1331,14 @@ void QuestManager::addskill(int skill_id, int value) {
initiator->AddSkill((EQ::skills::SkillType) skill_id, value);
}
void QuestManager::setlanguage(int skill_id, int value) {
void QuestManager::setlanguage(uint8 language_id, uint8 language_skill) {
QuestManagerCurrentQuestVars();
if (!initiator) {
return;
}
initiator->SetLanguageSkill(skill_id, value);
initiator->SetLanguageSkill(language_id, language_skill);
}
void QuestManager::setskill(int skill_id, int value) {

View File

@ -120,7 +120,7 @@ public:
std::string getskillname(int skill_id);
std::string getldonthemename(uint32 theme_id);
std::string getfactionname(int faction_id);
std::string getlanguagename(int language_id);
std::string getlanguagename(uint8 language_id);
std::string getbodytypename(uint32 bodytype_id);
std::string getconsiderlevelname(uint8 consider_level);
void safemove();
@ -142,7 +142,7 @@ public:
void movegrp(int zoneid, float x, float y, float z);
void doanim(int animation_id, int animation_speed = 0, bool ackreq = true, eqFilterType filter = FilterNone);
void addskill(int skill_id, int value);
void setlanguage(int skill_id, int value);
void setlanguage(uint8 language_id, uint8 language_skill);
void setskill(int skill_id, int value);
void setallskill(int value);
void attack(const char *client_name);

View File

@ -232,7 +232,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
client->MessageString(Chat::EchoTell, TOLD_NOT_ONLINE, scm->to);
else // normal tell echo "You told Soanso, 'something'"
// tell echo doesn't use language, so it looks normal to you even if nobody can understand your tells
client->ChannelMessageSend(scm->from, scm->to, scm->chan_num, 0, 100, scm->message);
client->ChannelMessageSend(scm->from, scm->to, scm->chan_num, Language::CommonTongue, Language::MaxValue, scm->message);
}
else if (scm->chan_num == ChatChannel_Tell) {
client->ChannelMessageSend(scm->from, scm->to, scm->chan_num, scm->language, scm->lang_skill, scm->message);

View File

@ -20,6 +20,7 @@
#include "../common/repositories/character_pet_inventory_repository.h"
#include "../common/repositories/character_pet_info_repository.h"
#include "../common/repositories/character_buffs_repository.h"
#include "../common/repositories/character_languages_repository.h"
#include "../common/repositories/criteria/content_filter_criteria.h"
#include "../common/repositories/spawn2_disabled_repository.h"
@ -804,23 +805,27 @@ bool ZoneDatabase::LoadCharacterSpellBook(uint32 character_id, PlayerProfile_Str
return true;
}
bool ZoneDatabase::LoadCharacterLanguages(uint32 character_id, PlayerProfile_Struct* pp){
std::string query = StringFormat(
"SELECT "
"lang_id, "
"`value` "
"FROM "
"`character_languages` "
"WHERE `id` = %u ORDER BY `lang_id`", character_id);
auto results = database.QueryDatabase(query); int i = 0;
/* Initialize Languages */
for (i = 0; i < MAX_PP_LANGUAGE; ++i)
pp->languages[i] = 0;
bool ZoneDatabase::LoadCharacterLanguages(uint32 character_id, PlayerProfile_Struct* pp)
{
const auto& l = CharacterLanguagesRepository::GetWhere(
database,
fmt::format(
"`id` = {} ORDER BY `lang_id`",
character_id
)
);
for (auto& row = results.begin(); row != results.end(); ++row) {
i = Strings::ToInt(row[0]);
if (i < MAX_PP_LANGUAGE){
pp->languages[i] = Strings::ToInt(row[1]);
if (l.empty()) {
return false;
}
for (int i = 0; i < MAX_PP_LANGUAGE; ++i) { // Initialize Languages
pp->languages[i] = 0;
}
for (const auto& e : l) {
if (EQ::ValueWithin(e.lang_id, Language::CommonTongue, Language::Unknown27)) {
pp->languages[e.lang_id] = e.value;
}
}