Fixed emote visual state ids for classic/DoF client
Fix #154 - emotes will work cross clients since visual state ids can vary
This commit is contained in:
parent
e8bf4be00f
commit
745185ecde
4 changed files with 206 additions and 12 deletions
57
DB/updates/fixed_emotes_table.sql
Normal file
57
DB/updates/fixed_emotes_table.sql
Normal file
File diff suppressed because one or more lines are too long
|
@ -17,6 +17,7 @@
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with EQ2Emulator. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "../common/Log.h"
|
||||
#include <map>
|
||||
|
||||
using namespace std;
|
||||
|
@ -47,7 +48,6 @@ private:
|
|||
int id;
|
||||
string name;
|
||||
};
|
||||
|
||||
class Emote{
|
||||
public:
|
||||
Emote(char* in_name, int in_visual_state, char* in_message, char* in_targeted_message){
|
||||
|
@ -74,6 +74,97 @@ private:
|
|||
string message;
|
||||
string targeted_message;
|
||||
};
|
||||
class VersionRange {
|
||||
public:
|
||||
VersionRange(int32 in_min_version, int32 in_max_version)
|
||||
{
|
||||
min_version = in_min_version;
|
||||
max_version = in_max_version;
|
||||
}
|
||||
int32 GetMinVersion() { return min_version; }
|
||||
int32 GetMaxVersion() { return max_version; }
|
||||
private:
|
||||
int32 min_version;
|
||||
int32 max_version;
|
||||
};
|
||||
|
||||
class EmoteVersionRange {
|
||||
public:
|
||||
EmoteVersionRange(char* in_name)
|
||||
{
|
||||
name = string(in_name);
|
||||
}
|
||||
|
||||
~EmoteVersionRange()
|
||||
{
|
||||
map<VersionRange*, Emote*>::iterator itr;
|
||||
for (itr = version_map.begin(); itr != version_map.end(); itr++)
|
||||
{
|
||||
VersionRange* range = itr->first;
|
||||
Emote* emote = itr->second;
|
||||
delete range;
|
||||
delete emote;
|
||||
}
|
||||
|
||||
version_map.clear();
|
||||
}
|
||||
|
||||
void AddVersionRange(int32 min_version, int32 max_version,
|
||||
char* in_name, int in_visual_state, char* in_message, char* in_targeted_message)
|
||||
{
|
||||
map<VersionRange*, Emote*>::iterator itr = FindVersionRange(min_version, max_version);
|
||||
if (itr != version_map.end())
|
||||
{
|
||||
VersionRange* range = itr->first;
|
||||
LogWrite(WORLD__ERROR, 0, "Emotes Table Error: Duplicate emote mapping of %s with range min %u max %u, Existing found with range min %u max %u\n", name.c_str(), min_version, max_version, range->GetMinVersion(), range->GetMaxVersion());
|
||||
return;
|
||||
}
|
||||
|
||||
version_map.insert(make_pair(new VersionRange(min_version, max_version), new Emote(in_name, in_visual_state, in_message, in_targeted_message)));
|
||||
}
|
||||
|
||||
map<VersionRange*, Emote*>::iterator FindVersionRange(int32 min_version, int32 max_version)
|
||||
{
|
||||
map<VersionRange*, Emote*>::iterator itr;
|
||||
for (itr = version_map.begin(); itr != version_map.end(); itr++)
|
||||
{
|
||||
VersionRange* range = itr->first;
|
||||
// if min and max version are both in range
|
||||
if (range->GetMinVersion() <= min_version && max_version <= range->GetMaxVersion())
|
||||
return itr;
|
||||
// if the min version is in range, but max range is 0
|
||||
else if (range->GetMinVersion() <= min_version && range->GetMaxVersion() == 0)
|
||||
return itr;
|
||||
// if min version is 0 and max_version has a cap
|
||||
else if (range->GetMinVersion() == 0 && max_version <= range->GetMaxVersion())
|
||||
return itr;
|
||||
}
|
||||
|
||||
return version_map.end();
|
||||
}
|
||||
|
||||
map<VersionRange*, Emote*>::iterator FindEmoteVersion(int32 version)
|
||||
{
|
||||
map<VersionRange*, Emote*>::iterator itr;
|
||||
for (itr = version_map.begin(); itr != version_map.end(); itr++)
|
||||
{
|
||||
VersionRange* range = itr->first;
|
||||
// if min and max version are both in range
|
||||
if (version >= range->GetMinVersion() && (range->GetMaxVersion() == 0 || version <= range->GetMaxVersion()))
|
||||
return itr;
|
||||
}
|
||||
|
||||
return version_map.end();
|
||||
}
|
||||
|
||||
const char* GetName() { return name.c_str(); }
|
||||
string GetNameString() { return name; }
|
||||
|
||||
map<VersionRange*, Emote*>::iterator GetRangeEnd() { return version_map.end(); }
|
||||
private:
|
||||
map<VersionRange*, Emote*> version_map;
|
||||
string name;
|
||||
};
|
||||
|
||||
class VisualStates
|
||||
{
|
||||
|
@ -88,7 +179,7 @@ public:
|
|||
}
|
||||
|
||||
void ClearEmotes(){
|
||||
map<string, Emote*>::iterator map_list;
|
||||
map<string, EmoteVersionRange*>::iterator map_list;
|
||||
for(map_list = emoteMap.begin(); map_list != emoteMap.end(); map_list++ )
|
||||
safe_delete(map_list->second);
|
||||
emoteMap.clear();
|
||||
|
@ -111,17 +202,33 @@ public:
|
|||
return 0;
|
||||
}
|
||||
|
||||
void InsertEmote(Emote* emote){
|
||||
emoteMap[emote->GetNameString()] = emote;
|
||||
void InsertEmoteRange(EmoteVersionRange* emote) {
|
||||
emoteMap[emote->GetName()] = emote;
|
||||
}
|
||||
|
||||
Emote* FindEmote(string var){
|
||||
if(emoteMap.count(var) > 0)
|
||||
EmoteVersionRange* FindEmoteRange(string var) {
|
||||
if (emoteMap.count(var) > 0)
|
||||
{
|
||||
return emoteMap[var];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Emote* FindEmote(string var, int32 version){
|
||||
if (emoteMap.count(var) > 0)
|
||||
{
|
||||
map<VersionRange*,Emote*>::iterator itr = emoteMap[var]->FindEmoteVersion(version);
|
||||
|
||||
if (itr != emoteMap[var]->GetRangeEnd())
|
||||
{
|
||||
Emote* emote = itr->second;
|
||||
return emote;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
private:
|
||||
map<string,VisualState*> visualStateMap;
|
||||
map<string,Emote*> emoteMap;
|
||||
map<string,EmoteVersionRange*> emoteMap;
|
||||
};
|
||||
|
||||
|
|
|
@ -429,11 +429,17 @@ void WorldDatabase::LoadVisualStates()
|
|||
LogWrite(WORLD__DEBUG, 3, "World", "--Loaded %u visual states", total);
|
||||
|
||||
total = 0;
|
||||
result = query2.RunQuery2(Q_SELECT, "SELECT name, visual_state_id, message, targeted_message FROM emotes");
|
||||
result = query2.RunQuery2(Q_SELECT, "SELECT name, visual_state_id, message, targeted_message, min_version_range, max_version_range FROM emotes");
|
||||
while(result && (row = mysql_fetch_row(result)))
|
||||
{
|
||||
Emote* emote = new Emote(row[0], atoi(row[1]), row[2], row[3]);
|
||||
visual_states.InsertEmote(emote);
|
||||
EmoteVersionRange* range = 0;
|
||||
if ((range = visual_states.FindEmoteRange(string(row[0]))) == NULL)
|
||||
{
|
||||
range = new EmoteVersionRange(row[0]);
|
||||
visual_states.InsertEmoteRange(range);
|
||||
}
|
||||
|
||||
range->AddVersionRange(atoul(row[4]),atoul(row[5]), row[0], atoi(row[1]), row[2], row[3]);
|
||||
total++;
|
||||
LogWrite(WORLD__DEBUG, 5, "World", "---Loading emote state: '%s' (%i)", row[1], atoi(row[0]));
|
||||
}
|
||||
|
|
|
@ -5661,20 +5661,44 @@ void ZoneServer::HandleEmote(Client* originator, string name) {
|
|||
}
|
||||
|
||||
Client* client = 0;
|
||||
Emote* emote = visual_states.FindEmote(name);
|
||||
if(!emote){
|
||||
Emote* origEmote = visual_states.FindEmote(name, originator->GetVersion());
|
||||
if(!origEmote){
|
||||
originator->Message(CHANNEL_COLOR_YELLOW, "Unable to find emote '%s'. If this should be a valid emote be sure to submit a /bug report.", name.c_str());
|
||||
return;
|
||||
}
|
||||
Emote* emote = origEmote;
|
||||
|
||||
PacketStruct* packet = 0;
|
||||
char* emoteResponse = 0;
|
||||
vector<Client*>::iterator client_itr;
|
||||
|
||||
int32 cur_client_version = originator->GetVersion();
|
||||
map<int32, Emote*> emote_version_range;
|
||||
MClientList.readlock(__FUNCTION__, __LINE__);
|
||||
for (client_itr = clients.begin(); client_itr != clients.end(); client_itr++) {
|
||||
client = *client_itr;
|
||||
if(!client || (client && client->GetPlayer()->IsIgnored(originator->GetPlayer()->GetName())))
|
||||
continue;
|
||||
|
||||
// establish appropriate emote for the version used by the client
|
||||
if (client->GetVersion() != originator->GetVersion())
|
||||
{
|
||||
map<int32, Emote*>::iterator rangeitr = emote_version_range.find(client->GetVersion());
|
||||
if (rangeitr == emote_version_range.end())
|
||||
{
|
||||
Emote* tmp_new_emote = visual_states.FindEmote(name, client->GetVersion());
|
||||
if (tmp_new_emote)
|
||||
{
|
||||
emote_version_range.insert(make_pair(client->GetVersion(), tmp_new_emote));
|
||||
emote = tmp_new_emote;
|
||||
} // else its missing just use the current clients default
|
||||
}
|
||||
else // we have an existing emote already cached
|
||||
emote = rangeitr->second;
|
||||
}
|
||||
else // since the client and originator client match use the original emote
|
||||
emote = origEmote;
|
||||
|
||||
packet = configReader.getStruct("WS_CannedEmote", client->GetVersion());
|
||||
if(packet){
|
||||
packet->setDataByName("spawn_id" , client->GetPlayer()->GetIDWithPlayerSpawn(originator->GetPlayer()));
|
||||
|
|
Loading…
Add table
Reference in a new issue