- Fix #453 PlayFlavor re-design
PlayFlavorID(NPC, type, id, index, Player, language) Set Player to 'nil' to send to all clients, specifying a Player will make it send ONLY to that player New command /reload voiceovers added - versioning updated to 0.9.4-aquarii - Fix #454 Support for SendShowBook to have language, items field 'book_language' added - Some debug log cleanup
This commit is contained in:
parent
17eb8e0d23
commit
0e00165195
22 changed files with 338 additions and 18 deletions
1
DB/updates/jul22_items_book_language.sql
Normal file
1
DB/updates/jul22_items_book_language.sql
Normal file
|
@ -0,0 +1 @@
|
|||
alter table items add column book_language tinyint(3) unsigned default 0;
|
13
DB/updates/voiceovers_table_july23_2022.sql
Normal file
13
DB/updates/voiceovers_table_july23_2022.sql
Normal file
|
@ -0,0 +1,13 @@
|
|||
insert into commands set type=1,command='reload',subcommand='voiceovers',required_status=100,handler=532;
|
||||
CREATE TABLE `voiceovers` (
|
||||
`type_id` tinyint(3) unsigned NOT NULL default 0,
|
||||
`id` int(10) unsigned NOT NULL default 0,
|
||||
`indexed` smallint(5) unsigned NOT NULL default 0,
|
||||
`mp3_string` text not null default '',
|
||||
`text_string` text not null default '',
|
||||
`emote_string` text not null default '',
|
||||
`key1` int(10) unsigned NOT NULL default 0,
|
||||
`key2` int(10) unsigned NOT NULL default 0,
|
||||
`garbled` tinyint(3) unsigned NOT NULL default 0,
|
||||
`garble_link_id` tinyint(3) unsigned NOT NULL default 0
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
|
@ -756,7 +756,7 @@ void Commands::Command_Bot_Help(Client* client, Seperator* sep) {
|
|||
details += "18\tSarnak\n";
|
||||
details += "19\tVampire\n";
|
||||
details += "20\tAerakyn\n";
|
||||
client->SendShowBook(client->GetPlayer(), title, 1, details);
|
||||
client->SendShowBook(client->GetPlayer(), title, 0, 1, details);
|
||||
return;
|
||||
}
|
||||
else if (strncasecmp("class", sep->arg[0], 5) == 0) {
|
||||
|
@ -811,7 +811,7 @@ void Commands::Command_Bot_Help(Client* client, Seperator* sep) {
|
|||
details3 += "43\tSHAPER\n";
|
||||
details3 += "44\tCHANNELER\n";
|
||||
|
||||
client->SendShowBook(client->GetPlayer(), title, 3, details, details2, details3);
|
||||
client->SendShowBook(client->GetPlayer(), title, 0, 3, details, details2, details3);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1833,6 +1833,7 @@ void Commands::Process(int32 index, EQ2_16BitString* command_parms, Client* clie
|
|||
client->SimpleMessage(CHANNEL_COLOR_YELLOW, "/reload rules");
|
||||
client->SimpleMessage(CHANNEL_COLOR_YELLOW, "/reload transporters");
|
||||
client->SimpleMessage(CHANNEL_COLOR_YELLOW, "/reload startabilities");
|
||||
client->SimpleMessage(CHANNEL_COLOR_YELLOW, "/reload voiceovers");
|
||||
break;
|
||||
}
|
||||
case COMMAND_RELOADSTRUCTS: {
|
||||
|
@ -1946,6 +1947,13 @@ void Commands::Process(int32 index, EQ2_16BitString* command_parms, Client* clie
|
|||
client->SimpleMessage(CHANNEL_COLOR_YELLOW, "Done!");
|
||||
break;
|
||||
}
|
||||
case COMMAND_RELOAD_VOICEOVERS: {
|
||||
client->SimpleMessage(CHANNEL_COLOR_YELLOW, "Reloading Voiceovers...");
|
||||
world.PurgeVoiceOvers();
|
||||
world.LoadVoiceOvers();
|
||||
client->SimpleMessage(CHANNEL_COLOR_YELLOW, "Done!");
|
||||
break;
|
||||
}
|
||||
case COMMAND_READ: {
|
||||
if (sep && sep->arg[1][0] && sep->IsNumber(1)) {
|
||||
if (strcmp(sep->arg[0], "read") == 0) {
|
||||
|
@ -1953,7 +1961,7 @@ void Commands::Process(int32 index, EQ2_16BitString* command_parms, Client* clie
|
|||
Item* item = client->GetPlayer()->item_list.GetItemFromIndex(item_index);
|
||||
if (item) {
|
||||
Spawn* spawn = cmdTarget;
|
||||
client->SendShowBook(client->GetPlayer(), item->name, item->book_pages);
|
||||
client->SendShowBook(client->GetPlayer(), item->name, item->book_language, item->book_pages);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -3867,7 +3875,7 @@ void Commands::Process(int32 index, EQ2_16BitString* command_parms, Client* clie
|
|||
client->GetCurrentZone()->SendAllSpawnsForVisChange(client, false);
|
||||
client->Message(CHANNEL_COLOR_RED, "Adding spawn group tag \"%s\" with tag icon %u.", (value == 1) ? "on" : "off", tag_icon);
|
||||
}
|
||||
else if(strncasecmp(sep->arg[1], "race", 5) == 0){
|
||||
else if(strncasecmp(sep->arg[1], "race", 4 == 0)){
|
||||
if(!value) {
|
||||
client->SimpleMessage(CHANNEL_COLOR_RED, "Need to supply a valid race id.");
|
||||
break;
|
||||
|
@ -4742,7 +4750,7 @@ void Commands::Process(int32 index, EQ2_16BitString* command_parms, Client* clie
|
|||
}
|
||||
|
||||
string title = string(spawn->GetName()) + "(" + to_string(spawn->GetDatabaseID()) + ")";
|
||||
client->SendShowBook(client->GetPlayer(), title, 4, details, details2, details3, details4);
|
||||
client->SendShowBook(client->GetPlayer(), title, 0, 4, details, details2, details3, details4);
|
||||
}
|
||||
else {
|
||||
client->SimpleMessage(CHANNEL_COLOR_YELLOW, "Syntax: /spawn details (radius)");
|
||||
|
|
|
@ -932,6 +932,8 @@ private:
|
|||
#define COMMAND_CANCEL_EFFECT 530
|
||||
#define COMMAND_CUREPLAYER 531
|
||||
|
||||
#define COMMAND_RELOAD_VOICEOVERS 532
|
||||
|
||||
|
||||
#define GET_AA_XML 750
|
||||
#define ADD_AA 751
|
||||
|
|
|
@ -897,6 +897,7 @@ Item::Item(){
|
|||
no_sale = false;
|
||||
created = std::time(nullptr);
|
||||
effect_type = NO_EFFECT_TYPE;
|
||||
book_language = 0;
|
||||
}
|
||||
|
||||
Item::Item(Item* in_item){
|
||||
|
@ -917,6 +918,7 @@ Item::Item(Item* in_item){
|
|||
created = in_item->created;
|
||||
grouped_char_ids.insert(in_item->grouped_char_ids.begin(), in_item->grouped_char_ids.end());
|
||||
effect_type = in_item->effect_type;
|
||||
book_language = in_item->book_language;
|
||||
}
|
||||
|
||||
Item::~Item(){
|
||||
|
@ -1140,6 +1142,7 @@ void Item::SetItem(Item* old_item){
|
|||
slot_data = old_item->slot_data;
|
||||
spell_id = old_item->spell_id;
|
||||
spell_tier = old_item->spell_tier;
|
||||
book_language = old_item->book_language;
|
||||
}
|
||||
|
||||
bool Item::CheckArchetypeAdvSubclass(int8 adventure_class, map<int8, int16>* adv_class_levels) {
|
||||
|
|
|
@ -951,6 +951,7 @@ public:
|
|||
ItemEffectType effect_type;
|
||||
bool crafted;
|
||||
bool tinkered;
|
||||
int8 book_language;
|
||||
|
||||
void AddEffect(string effect, int8 percentage, int8 subbulletflag);
|
||||
void AddBookPage(int8 page, string page_text,int8 valign, int8 halign);
|
||||
|
|
|
@ -224,6 +224,7 @@ void WorldDatabase::LoadDataFromRow(DatabaseResult* result, Item* item)
|
|||
|
||||
item->crafted = result->GetInt8Str("crafted");
|
||||
item->tinkered = result->GetInt8Str("tinkered");
|
||||
item->book_language = result->GetInt8Str("book_language");
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -188,6 +188,33 @@ int EQ2Emu_lua_PlayFlavor(lua_State* state) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int EQ2Emu_lua_PlayFlavorID(lua_State* state) {
|
||||
if (!lua_interface)
|
||||
return 0;
|
||||
Spawn* spawn = lua_interface->GetSpawn(state);
|
||||
|
||||
int8 type = lua_interface->GetInt8Value(state, 2);
|
||||
int32 id = lua_interface->GetInt32Value(state, 3);
|
||||
int16 index = lua_interface->GetInt16Value(state, 4);
|
||||
Spawn* player = lua_interface->GetSpawn(state, 5);
|
||||
int8 language = lua_interface->GetInt8Value(state, 6);
|
||||
lua_interface->ResetFunctionStack(state);
|
||||
if (spawn) {
|
||||
Client* client = 0;
|
||||
if (player && player->IsPlayer())
|
||||
client = spawn->GetZone()->GetClientBySpawn(player);
|
||||
if (client) {
|
||||
VoiceOverStruct non_garble, garble;
|
||||
bool garble_success = false;
|
||||
bool success = world.FindVoiceOver(type, id, index, &non_garble, &garble_success, &garble);
|
||||
client->SendPlayFlavor(spawn, language, &non_garble, &garble, success, garble_success);
|
||||
}
|
||||
else
|
||||
spawn->GetZone()->PlayFlavorID(spawn, type, id, index, language);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int EQ2Emu_lua_PlaySound(lua_State* state) {
|
||||
if (!lua_interface)
|
||||
return 0;
|
||||
|
|
|
@ -194,6 +194,7 @@ int EQ2Emu_lua_GetCharacterID(lua_State* state);
|
|||
int EQ2Emu_lua_MovementLoopAdd(lua_State* state);
|
||||
int EQ2Emu_lua_GetCurrentZoneSafeLocation(lua_State* state);
|
||||
int EQ2Emu_lua_PlayFlavor(lua_State* state);
|
||||
int EQ2Emu_lua_PlayFlavorID(lua_State* state);
|
||||
int EQ2Emu_lua_PlaySound(lua_State* state);
|
||||
int EQ2Emu_lua_PlayVoice(lua_State* state);
|
||||
int EQ2Emu_lua_PlayAnimation(lua_State* state);
|
||||
|
|
|
@ -1057,6 +1057,7 @@ void LuaInterface::RegisterFunctions(lua_State* state) {
|
|||
lua_register(state, "GetSpawnByGroupID", EQ2Emu_lua_GetSpawnByGroupID);
|
||||
lua_register(state, "GetSpawnByLocationID", EQ2Emu_lua_GetSpawnByLocationID);
|
||||
lua_register(state, "PlayFlavor", EQ2Emu_lua_PlayFlavor);
|
||||
lua_register(state, "PlayFlavorID", EQ2Emu_lua_PlayFlavorID);
|
||||
lua_register(state, "PlaySound", EQ2Emu_lua_PlaySound);
|
||||
lua_register(state, "PlayVoice", EQ2Emu_lua_PlayVoice);
|
||||
lua_register(state, "PlayAnimation", EQ2Emu_lua_PlayAnimation);
|
||||
|
|
|
@ -132,6 +132,7 @@ World::~World(){
|
|||
tov_itemstat_conversion.clear();
|
||||
|
||||
PurgeStartingLists();
|
||||
PurgeVoiceOvers();
|
||||
|
||||
map<std::string, RegionMapRange*>::iterator itr3;
|
||||
for (itr3 = region_maps.begin(); itr3 != region_maps.end(); itr3++)
|
||||
|
@ -170,6 +171,7 @@ void World::init(){
|
|||
LogWrite(WORLD__DEBUG, 1, "World", "-Load `visual states` complete!");
|
||||
|
||||
LoadStartingLists();
|
||||
LoadVoiceOvers();
|
||||
|
||||
LogWrite(WORLD__DEBUG, 1, "World", "-Setting system parameters...");
|
||||
Variable* var = variables.FindVariable("gametime");
|
||||
|
@ -2411,7 +2413,18 @@ void World::PurgeStartingLists()
|
|||
safe_delete(tmpMap);
|
||||
}
|
||||
starting_spells.clear();
|
||||
|
||||
|
||||
for(int type=0;type<3;type++) {
|
||||
multimap<int32, multimap<int16, VoiceOverStruct>*>::iterator vos_itr;
|
||||
|
||||
for (vos_itr = voiceover_map[type].begin(); vos_itr != voiceover_map[type].end(); vos_itr++)
|
||||
{
|
||||
multimap<int16, VoiceOverStruct>* tmpMap = vos_itr->second;
|
||||
safe_delete(tmpMap);
|
||||
}
|
||||
voiceover_map[type].clear();
|
||||
}
|
||||
MStartingLists.releasewritelock();
|
||||
}
|
||||
|
||||
|
@ -2611,3 +2624,146 @@ void World::SendTimeUpdate()
|
|||
{
|
||||
zone_list.SendTimeUpdate();
|
||||
}
|
||||
|
||||
void World::LoadVoiceOvers()
|
||||
{
|
||||
LogWrite(WORLD__DEBUG, 1, "World", "-Loading `voiceovers`...");
|
||||
database.LoadVoiceOvers(this);
|
||||
}
|
||||
|
||||
|
||||
void World::PurgeVoiceOvers()
|
||||
{
|
||||
MVoiceOvers.writelock();
|
||||
for(int type=0;type<MAX_VOICEOVER_TYPE+1;type++) {
|
||||
multimap<int32, multimap<int16, VoiceOverStruct>*>::iterator vos_itr;
|
||||
|
||||
for (vos_itr = voiceover_map[type].begin(); vos_itr != voiceover_map[type].end(); vos_itr++)
|
||||
{
|
||||
multimap<int16, VoiceOverStruct>* tmpMap = vos_itr->second;
|
||||
safe_delete(tmpMap);
|
||||
}
|
||||
voiceover_map[type].clear();
|
||||
}
|
||||
MVoiceOvers.releasewritelock();
|
||||
}
|
||||
|
||||
|
||||
bool World::FindVoiceOver(int8 type, int32 id, int16 index, VoiceOverStruct* struct_, bool* find_garbled, VoiceOverStruct* garble_struct_) {
|
||||
// if we complete both requirements, based on struct_ and garble_struct_ being passed when required by ptr not being null
|
||||
bool succeed = false;
|
||||
if(type > MAX_VOICEOVER_TYPE) {
|
||||
LogWrite(WORLD__ERROR, 0, "World", "Voice over %u out of range, max voiceover type is %u...", type, MAX_VOICEOVER_TYPE);
|
||||
return succeed;
|
||||
}
|
||||
|
||||
MVoiceOvers.readlock();
|
||||
multimap<int32, multimap<int16, VoiceOverStruct>*>::iterator itr = voiceover_map[type].find(id);
|
||||
if(itr != voiceover_map[type].end()) {
|
||||
std::pair<VOMapIterator, VOMapIterator> result = itr->second->equal_range(index);
|
||||
int count = std::distance(result.first, result.second);
|
||||
bool tries_attempt = true; // abort out the while loop
|
||||
bool non_garble_found = false;
|
||||
int rand = 0; // use to randomize the voiceover selection
|
||||
int pos = 0;
|
||||
int tries = 0;
|
||||
bool has_ungarbled = false;
|
||||
bool has_garbled = false;
|
||||
int8 garble_link_id = 0; // used to match ungarbled to garbled when the link id is set in the DB
|
||||
while(tries_attempt) {
|
||||
pos = 0;
|
||||
rand = MakeRandomInt(0, count);
|
||||
if ( tries == 3 || non_garble_found || (find_garbled && (*find_garbled)))
|
||||
rand = 0; // override, too many tries, or we otherwise found one garbled/ungarbled lets try to link it
|
||||
for (VOMapIterator it = result.first; it != result.second; it++) {
|
||||
if(!it->second.is_garbled) {
|
||||
has_ungarbled = true;
|
||||
}
|
||||
else {
|
||||
has_garbled = true;
|
||||
}
|
||||
pos++;
|
||||
|
||||
// if there is only 1 entry in the voiceover list we aren't going to bother skipping
|
||||
if(count > 1 && pos < rand) {
|
||||
continue;
|
||||
}
|
||||
if(!it->second.is_garbled && (garble_link_id == 0 || it->second.garble_link_id == garble_link_id)) {
|
||||
garble_link_id = it->second.garble_link_id;
|
||||
non_garble_found = true;
|
||||
if(struct_) {
|
||||
CopyVoiceOver(struct_, &it->second);
|
||||
}
|
||||
|
||||
if(!find_garbled || ((*find_garbled))) {
|
||||
if(find_garbled)
|
||||
*find_garbled = true;
|
||||
tries_attempt = false;
|
||||
succeed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(find_garbled && !(*find_garbled) && it->second.is_garbled && (garble_link_id == 0 || it->second.garble_link_id == garble_link_id)) {
|
||||
*find_garbled = true;
|
||||
garble_link_id = it->second.garble_link_id;
|
||||
if(garble_struct_) {
|
||||
CopyVoiceOver(garble_struct_, &it->second);
|
||||
if(!struct_ || non_garble_found) {
|
||||
tries_attempt = false;
|
||||
succeed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
tries++;
|
||||
if(!tries_attempt || (tries > 0 && !has_ungarbled && (!find_garbled || *find_garbled == true || !has_garbled)) || tries > 3)
|
||||
break;
|
||||
}
|
||||
}
|
||||
MVoiceOvers.releasereadlock();
|
||||
|
||||
return succeed;
|
||||
}
|
||||
|
||||
void World::AddVoiceOver(int8 type, int32 id, int16 index, VoiceOverStruct* struct_) {
|
||||
if(type > MAX_VOICEOVER_TYPE) {
|
||||
LogWrite(WORLD__ERROR, 0, "World", "Voice over %u out of range, max voiceover type is %u...", type, MAX_VOICEOVER_TYPE);
|
||||
return;
|
||||
}
|
||||
|
||||
VoiceOverStruct tmpStruct;
|
||||
tmpStruct.mp3_string = std::string(struct_->mp3_string);
|
||||
tmpStruct.text_string = std::string(struct_->text_string);
|
||||
tmpStruct.emote_string = std::string(struct_->emote_string);
|
||||
tmpStruct.key1 = struct_->key1;
|
||||
tmpStruct.key2 = struct_->key2;
|
||||
tmpStruct.is_garbled = struct_->is_garbled;
|
||||
|
||||
MVoiceOvers.writelock();
|
||||
if(!voiceover_map[type].count(id))
|
||||
{
|
||||
multimap<int16, VoiceOverStruct>* vo_struct = new multimap<int16, VoiceOverStruct>();
|
||||
vo_struct->insert(make_pair(index, tmpStruct));
|
||||
voiceover_map[type].insert(make_pair(id, vo_struct));
|
||||
}
|
||||
else
|
||||
{
|
||||
multimap<int32, multimap<int16, VoiceOverStruct>*>::const_iterator itr = voiceover_map[type].find(id);
|
||||
itr->second->insert(make_pair(index, tmpStruct));
|
||||
}
|
||||
MVoiceOvers.releasewritelock();
|
||||
}
|
||||
|
||||
void World::CopyVoiceOver(VoiceOverStruct* struct1, VoiceOverStruct* struct2) {
|
||||
if(!struct1 || !struct2)
|
||||
return;
|
||||
|
||||
struct1->mp3_string = std::string(struct2->mp3_string);
|
||||
struct1->text_string = std::string(struct2->text_string);
|
||||
struct1->emote_string = std::string(struct2->emote_string);
|
||||
struct1->key1 = struct2->key1;
|
||||
struct1->key2 = struct2->key2;
|
||||
struct1->is_garbled = struct2->is_garbled;
|
||||
struct1->garble_link_id = struct2->garble_link_id;
|
||||
}
|
||||
|
|
|
@ -398,6 +398,17 @@ struct StartingSpell
|
|||
int32 knowledge_slot;
|
||||
};
|
||||
|
||||
#define MAX_VOICEOVER_TYPE 2
|
||||
struct VoiceOverStruct{
|
||||
string mp3_string;
|
||||
string text_string;
|
||||
string emote_string;
|
||||
int32 key1;
|
||||
int32 key2;
|
||||
bool is_garbled;
|
||||
int8 garble_link_id;
|
||||
};
|
||||
|
||||
class ZoneList {
|
||||
public:
|
||||
ZoneList();
|
||||
|
@ -642,10 +653,17 @@ public:
|
|||
// just in case we roll over a time as to not send bad times to clients (days before hours, hours before minutes as examples)
|
||||
Mutex MWorldTime;
|
||||
|
||||
|
||||
|
||||
void LoadVoiceOvers();
|
||||
void PurgeVoiceOvers();
|
||||
typedef std::multimap<int16, VoiceOverStruct>::iterator VOMapIterator;
|
||||
bool FindVoiceOver(int8 type, int32 id, int16 index, VoiceOverStruct* struct_ = nullptr, bool* find_garbled = nullptr, VoiceOverStruct* garble_struct_ = nullptr);
|
||||
void AddVoiceOver(int8 type, int32 id, int16 index, VoiceOverStruct* struct_);
|
||||
void CopyVoiceOver(VoiceOverStruct* struct1, VoiceOverStruct* struct2);
|
||||
Mutex MVoiceOvers;
|
||||
|
||||
static sint64 newValue;
|
||||
private:
|
||||
multimap<int32, multimap<int16, VoiceOverStruct>*> voiceover_map[3];
|
||||
int32 suppressed_warning = 0;
|
||||
map<string, int32> reloading_subsystems;
|
||||
//void RemovePlayerFromGroup(PlayerGroup* group, GroupMemberInfo* info, bool erase = true);
|
||||
|
|
|
@ -7416,6 +7416,42 @@ void WorldDatabase::LoadStartingSkills(World* world)
|
|||
}
|
||||
|
||||
|
||||
void WorldDatabase::LoadVoiceOvers(World* world)
|
||||
{
|
||||
int32 total = 0;
|
||||
Query query;
|
||||
MYSQL_ROW row;
|
||||
MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT type_id, id, indexed, mp3_string, text_string, emote_string, key1, key2, garbled, garble_link_id FROM voiceovers");
|
||||
|
||||
if (result)
|
||||
{
|
||||
if (mysql_num_rows(result) > 0)
|
||||
{
|
||||
Skill* skill = 0;
|
||||
|
||||
while (result && (row = mysql_fetch_row(result)))
|
||||
{
|
||||
|
||||
VoiceOverStruct vos;
|
||||
vos.mp3_string = std::string(row[3]);
|
||||
vos.text_string = std::string(row[4]);
|
||||
vos.emote_string = std::string(row[5]);
|
||||
vos.key1 = atoul(row[6]);
|
||||
vos.key2 = atoul(row[7]);
|
||||
vos.is_garbled = atoul(row[8]);
|
||||
vos.garble_link_id = atoul(row[9]);
|
||||
int8 type = atoul(row[0]);
|
||||
int32 id = atoul(row[1]);
|
||||
int16 index = atoul(row[2]);
|
||||
world->AddVoiceOver(type, id, index, &vos);
|
||||
total++;
|
||||
}
|
||||
}
|
||||
}
|
||||
LogWrite(WORLD__DEBUG, 3, "World", "--Loaded %u Voiceover(s)", total);
|
||||
}
|
||||
|
||||
|
||||
void WorldDatabase::LoadStartingSpells(World* world)
|
||||
{
|
||||
world->MStartingLists.writelock();
|
||||
|
|
|
@ -604,6 +604,7 @@ public:
|
|||
|
||||
void LoadStartingSkills(World* world);
|
||||
void LoadStartingSpells(World* world);
|
||||
void LoadVoiceOvers(World* world);
|
||||
|
||||
int32 CreateSpiritShard(const char* name, int32 level, int8 race, int8 gender, int8 adventure_class,
|
||||
int16 model_type, int16 soga_model_type, int16 hair_type, int16 hair_face_type, int16 wing_type,
|
||||
|
|
|
@ -64,7 +64,6 @@ std::string RegionMapV1::TestFile(std::string testFile)
|
|||
string tmpScript("RegionScripts/");
|
||||
tmpScript.append(mZoneNameLower);
|
||||
tmpScript.append("/" + tmpStr + ".lua");
|
||||
printf("File to test : %s\n",tmpScript.c_str());
|
||||
std::ifstream f(tmpScript.c_str());
|
||||
return f.good() ? tmpScript : string("");
|
||||
}
|
||||
|
|
|
@ -10530,7 +10530,7 @@ void Client::SendFlightAutoMount(int32 path_id, int16 mount_id, int8 mount_red_c
|
|||
((Entity*)GetPlayer())->SetMount(mount_id, mount_red_color, mount_green_color, mount_blue_color);
|
||||
}
|
||||
|
||||
void Client::SendShowBook(Spawn* sender, string title, int8 num_pages, ...)
|
||||
void Client::SendShowBook(Spawn* sender, string title, int8 language, int8 num_pages, ...)
|
||||
{
|
||||
if (!sender)
|
||||
{
|
||||
|
@ -10547,7 +10547,9 @@ void Client::SendShowBook(Spawn* sender, string title, int8 num_pages, ...)
|
|||
packet->setDataByName("book_title", title.c_str());
|
||||
packet->setDataByName("book_type", "simple");
|
||||
packet->setDataByName("unknown2", 1);
|
||||
|
||||
if(language > 0 && !GetPlayer()->HasLanguage(language))
|
||||
packet->setDataByName("language", language);
|
||||
|
||||
if (GetVersion() > 546)
|
||||
packet->setDataByName("unknown5", 1, 4);
|
||||
|
||||
|
@ -10596,7 +10598,7 @@ void Client::SendShowBook(Spawn* sender, string title, int8 num_pages, ...)
|
|||
safe_delete(packet);
|
||||
}
|
||||
|
||||
void Client::SendShowBook(Spawn* sender, string title, vector<Item::BookPage*> pages)
|
||||
void Client::SendShowBook(Spawn* sender, string title, int8 language, vector<Item::BookPage*> pages)
|
||||
{
|
||||
if (!sender)
|
||||
{
|
||||
|
@ -10613,6 +10615,9 @@ void Client::SendShowBook(Spawn* sender, string title, vector<Item::BookPage*> p
|
|||
packet->setDataByName("book_title", title.c_str());
|
||||
packet->setDataByName("book_type", "simple");
|
||||
packet->setDataByName("unknown2", 1);
|
||||
|
||||
if(language > 0 && !GetPlayer()->HasLanguage(language))
|
||||
packet->setDataByName("language", language);
|
||||
|
||||
if (GetVersion() > 546)
|
||||
packet->setDataByName("unknown5", 1, 4);
|
||||
|
@ -11018,4 +11023,22 @@ bool Client::UseItem(Item* item, Spawn* target) {
|
|||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Client::SendPlayFlavor(Spawn* spawn, int8 language, VoiceOverStruct* non_garble,
|
||||
VoiceOverStruct* garble, bool success, bool garble_success) {
|
||||
VoiceOverStruct* resStruct = nullptr;
|
||||
|
||||
if(language == 0 || GetPlayer()->HasLanguage(language)) {
|
||||
if(success) {
|
||||
resStruct = non_garble;
|
||||
}
|
||||
}
|
||||
else if(garble_success) {
|
||||
resStruct = garble;
|
||||
}
|
||||
|
||||
if(resStruct) {
|
||||
GetPlayer()->GetZone()->PlayFlavor(this, spawn, resStruct->mp3_string.c_str(), resStruct->text_string.c_str(), resStruct->emote_string.c_str(), resStruct->key1, resStruct->key2, language);
|
||||
}
|
||||
}
|
|
@ -32,6 +32,7 @@ using namespace std;
|
|||
#define CLIENT_TIMEOUT 60000
|
||||
struct TransportDestination;
|
||||
struct ConversationOption;
|
||||
struct VoiceOverStruct;
|
||||
|
||||
#define MAIL_SEND_RESULT_SUCCESS 0
|
||||
#define MAIL_SEND_RESULT_UNKNOWN_PLAYER 1
|
||||
|
@ -446,8 +447,8 @@ public:
|
|||
|
||||
void SendFlightAutoMount(int32 path_id, int16 mount_id = 0, int8 mount_red_color = 0xFF, int8 mount_green_color = 0xFF, int8 mount_blue_color=0xFF);
|
||||
|
||||
void SendShowBook(Spawn* sender, string title, int8 num_pages, ...);
|
||||
void SendShowBook(Spawn* sender, string title, vector<Item::BookPage*> pages);
|
||||
void SendShowBook(Spawn* sender, string title, int8 language, int8 num_pages, ...);
|
||||
void SendShowBook(Spawn* sender, string title, int8 language, vector<Item::BookPage*> pages);
|
||||
|
||||
void SetTemporaryTransportID(int32 id) { temporary_transport_id = id; }
|
||||
int32 GetTemporaryTransportID() { return temporary_transport_id; }
|
||||
|
@ -540,6 +541,8 @@ public:
|
|||
}
|
||||
|
||||
bool UseItem(Item* item, Spawn* target = nullptr);
|
||||
|
||||
void SendPlayFlavor(Spawn* spawn, int8 language, VoiceOverStruct* non_garble, VoiceOverStruct* garble, bool success = false, bool garble_success = false);
|
||||
private:
|
||||
void SavePlayerImages();
|
||||
void SkillChanged(Skill* skill, int16 previous_value, int16 new_value);
|
||||
|
|
|
@ -3654,6 +3654,29 @@ void ZoneServer::PlayFlavor(Spawn* spawn, const char* mp3, const char* text, con
|
|||
MClientList.releasereadlock(__FUNCTION__, __LINE__);
|
||||
}
|
||||
|
||||
void ZoneServer::PlayFlavorID(Spawn* spawn, int8 type, int32 id, int16 index, int8 language){
|
||||
if(!spawn)
|
||||
return;
|
||||
|
||||
Client* client = 0;
|
||||
vector<Client*>::iterator client_itr;
|
||||
|
||||
VoiceOverStruct non_garble, garble;
|
||||
bool garble_success = false;
|
||||
bool success = world.FindVoiceOver(type, id, index, &non_garble, &garble_success, &garble);
|
||||
|
||||
VoiceOverStruct* resStruct = nullptr;
|
||||
MClientList.readlock(__FUNCTION__, __LINE__);
|
||||
for (client_itr = clients.begin(); client_itr != clients.end(); client_itr++) {
|
||||
client = *client_itr;
|
||||
if(!client || !client->IsReadyForUpdates() || !client->GetPlayer()->WasSentSpawn(spawn->GetID()) || client->GetPlayer()->GetDistance(spawn) > 30)
|
||||
continue;
|
||||
|
||||
client->SendPlayFlavor(spawn, language, &non_garble, &garble, success, garble_success);
|
||||
}
|
||||
MClientList.releasereadlock(__FUNCTION__, __LINE__);
|
||||
}
|
||||
|
||||
void ZoneServer::PlayVoice(Spawn* spawn, const char* mp3, int32 key1, int32 key2){
|
||||
if(!spawn || !mp3)
|
||||
return;
|
||||
|
|
|
@ -450,6 +450,7 @@ public:
|
|||
void PlayFlavor(Client* client, Spawn* spawn, const char* mp3, const char* text, const char* emote, int32 key1, int32 key2, int8 language);
|
||||
void PlayVoice(Client* client, Spawn* spawn, const char* mp3, int32 key1, int32 key2);
|
||||
void PlayFlavor(Spawn* spawn, const char* mp3, const char* text, const char* emote, int32 key1, int32 key2, int8 language);
|
||||
void PlayFlavorID(Spawn* spawn, int8 type, int32 id, int16 index, int8 language);
|
||||
void PlayVoice(Spawn* spawn, const char* mp3, int32 key1, int32 key2);
|
||||
void SendThreatPacket(Spawn* caster, Spawn* target, int32 threat_amt, const char* spell_name);
|
||||
void KillSpawnByDistance(Spawn* spawn, float max_distance, bool include_players = false, bool send_packet = false);
|
||||
|
|
|
@ -38,11 +38,11 @@
|
|||
#endif
|
||||
|
||||
#if defined(LOGIN)
|
||||
#define CURRENT_VERSION "0.9.4-geminorum"
|
||||
#define CURRENT_VERSION "0.9.4-aquarii"
|
||||
#elif defined(WORLD)
|
||||
#define CURRENT_VERSION "0.9.4-geminorum"
|
||||
#define CURRENT_VERSION "0.9.4-aquarii"
|
||||
#else
|
||||
#define CURRENT_VERSION "0.9.4-geminorum"
|
||||
#define CURRENT_VERSION "0.9.4-aquarii"
|
||||
#endif
|
||||
|
||||
#define COMPILE_DATE __DATE__
|
||||
|
|
|
@ -9876,7 +9876,8 @@ to zero and treated like placeholders." />
|
|||
<Struct Name="WS_EqShowBook" ClientVersion="546" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqShowBookCmd" >
|
||||
<Data ElementName="spawn_id" Type="int32" Size="1" />
|
||||
<Data ElementName="book_title" Type="EQ2_16Bit_String" Size="1" />
|
||||
<Data ElementName="unknown" Type="int16" Size="1" />
|
||||
<Data ElementName="language" Type="int8" Size="1" />
|
||||
<Data ElementName="unknown1" Type="int8" Size="1" />
|
||||
<Data ElementName="book_type" Type="EQ2_16Bit_String" Size="1" />
|
||||
<Data ElementName="unknown2" Type="int16" Size="1" />
|
||||
<Data ElementName="num_pages" Type="int8" Size="1" />
|
||||
|
@ -9891,7 +9892,8 @@ to zero and treated like placeholders." />
|
|||
<Struct Name="WS_EqShowBook" ClientVersion="1096" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqShowBookCmd" >
|
||||
<Data ElementName="spawn_id" Type="int32" Size="1" />
|
||||
<Data ElementName="book_title" Type="EQ2_16Bit_String" Size="1" />
|
||||
<Data ElementName="unknown" Type="int16" Size="1" />
|
||||
<Data ElementName="language" Type="int8" Size="1" />
|
||||
<Data ElementName="unknown1" Type="int8" Size="1" />
|
||||
<Data ElementName="book_type" Type="EQ2_16Bit_String" Size="1" />
|
||||
<Data ElementName="unknown2" Type="int8" Size="1" />
|
||||
<Data ElementName="unknown3" Type="int16" Size="1" />
|
||||
|
|
Loading…
Reference in a new issue