mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-11 12:41:30 +00:00
[Horses] Convert Horses to Repositories (#3965)
* [Horses] Convert Horses to Repositories # Notes - Convert `BuildHorseType()` to repositories. - Removed unused code, parameters, and member variables in horses. * Update horse.cpp
This commit is contained in:
parent
11e2a252e5
commit
b9f997015a
210
zone/horse.cpp
210
zone/horse.cpp
@ -21,169 +21,155 @@
|
||||
#include "../common/linked_list.h"
|
||||
#include "../common/strings.h"
|
||||
|
||||
#include "../common/repositories/horses_repository.h"
|
||||
|
||||
#include "client.h"
|
||||
#include "entity.h"
|
||||
#include "horse.h"
|
||||
#include "mob.h"
|
||||
#include "string_ids.h"
|
||||
|
||||
std::map<uint16, const NPCType *> Horse::horse_types;
|
||||
LinkedList<NPCType *> horses_auto_delete;
|
||||
|
||||
Horse::Horse(Client *_owner, uint16 spell_id, const glm::vec4& position)
|
||||
: NPC(GetHorseType(spell_id), nullptr, position, GravityBehavior::Water)
|
||||
Horse::Horse(
|
||||
Client *c,
|
||||
uint16 spell_id,
|
||||
const glm::vec4& position
|
||||
) : NPC(
|
||||
GetHorseType(spell_id),
|
||||
nullptr,
|
||||
position,
|
||||
GravityBehavior::Water
|
||||
)
|
||||
{
|
||||
//give the horse its proper name.
|
||||
strn0cpy(name, _owner->GetCleanName(), 55);
|
||||
strcat(name,"`s_Mount00");
|
||||
strn0cpy(name, fmt::format("{}`s_Mount00", c->GetCleanName()).c_str(), sizeof(name));
|
||||
|
||||
is_horse = true;
|
||||
|
||||
owner = _owner;
|
||||
owner = c;
|
||||
}
|
||||
|
||||
void Horse::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) {
|
||||
NPC::FillSpawnStruct(ns, ForWho);
|
||||
void Horse::FillSpawnStruct(NewSpawn_Struct* ns, Mob* m) {
|
||||
NPC::FillSpawnStruct(ns, m);
|
||||
|
||||
// ns->spawn.texture = NPCTypedata->mount_color;
|
||||
ns->spawn.petOwnerId = 0;
|
||||
|
||||
//dunno why we do these, they should allready be set right.
|
||||
ns->spawn.runspeed = NPCTypedata->runspeed;
|
||||
ns->spawn.runspeed = NPCTypedata->runspeed;
|
||||
}
|
||||
|
||||
bool Horse::IsHorseSpell(uint16 spell_id) {
|
||||
//written in terms of a function which does a ton more work
|
||||
//than we need to to figure out if this is a horse spell.
|
||||
//the logic is that people calling this function will post
|
||||
//likely immediately summon the horse, so we need the extra anyways.
|
||||
return(GetHorseType(spell_id) != nullptr);
|
||||
bool Horse::IsHorseSpell(uint16 spell_id)
|
||||
{
|
||||
return GetHorseType(spell_id);
|
||||
}
|
||||
|
||||
const NPCType *Horse::GetHorseType(uint16 spell_id) {
|
||||
if(horse_types.count(spell_id) == 1)
|
||||
return(horse_types[spell_id]);
|
||||
//cache invalid spell IDs as nullptr entries
|
||||
const NPCType *ret;
|
||||
horse_types[spell_id] = ret = BuildHorseType(spell_id);
|
||||
return(ret);
|
||||
const NPCType *Horse::GetHorseType(uint16 spell_id)
|
||||
{
|
||||
if (horse_types.count(spell_id)) {
|
||||
return horse_types[spell_id];
|
||||
}
|
||||
|
||||
const NPCType* n;
|
||||
|
||||
horse_types[spell_id] = n = BuildHorseType(spell_id);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
const NPCType *Horse::BuildHorseType(uint16 spell_id) {
|
||||
const NPCType *Horse::BuildHorseType(uint16 spell_id)
|
||||
{
|
||||
const auto& l = HorsesRepository::GetWhere(
|
||||
content_db,
|
||||
fmt::format(
|
||||
"`filename` = '{}'",
|
||||
Strings::Escape(spells[spell_id].teleport_zone)
|
||||
)
|
||||
);
|
||||
|
||||
const char* fileName = spells[spell_id].teleport_zone;
|
||||
|
||||
std::string query = StringFormat("SELECT race, gender, texture, mountspeed FROM horses WHERE filename = '%s'", fileName);
|
||||
auto results = content_db.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
if (l.empty()) {
|
||||
LogError("No Database entry for mount: [{}], check the horses table.", spells[spell_id].teleport_zone);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (results.RowCount() != 1) {
|
||||
LogError("No Database entry for mount: [{}], check the horses table", fileName);
|
||||
return nullptr;
|
||||
}
|
||||
auto n = new NPCType;
|
||||
|
||||
auto row = results.begin();
|
||||
memset(n, 0, sizeof(NPCType));
|
||||
|
||||
auto npc_type = new NPCType;
|
||||
memset(npc_type, 0, sizeof(NPCType));
|
||||
strcpy(npc_type->name, "Unclaimed_Mount"); // this should never get used
|
||||
strn0cpy(n->name, "Unclaimed_Mount", sizeof(n->name));
|
||||
|
||||
strcpy(npc_type->special_abilities, "19,1^20,1^24,1");
|
||||
npc_type->current_hp = 1;
|
||||
npc_type->max_hp = 1;
|
||||
npc_type->race = Strings::ToInt(row[0]);
|
||||
npc_type->gender = Strings::ToInt(row[1]); // Drogmor's are female horses. Yuck.
|
||||
npc_type->class_ = 1;
|
||||
npc_type->deity = 1;
|
||||
npc_type->level = 1;
|
||||
npc_type->npc_id = 0;
|
||||
npc_type->loottable_id = 0;
|
||||
npc_type->texture = Strings::ToInt(row[2]); // mount color
|
||||
npc_type->helmtexture = Strings::ToInt(row[2]); // mount color
|
||||
npc_type->runspeed = Strings::ToFloat(row[3]);
|
||||
strn0cpy(n->special_abilities, "19,1^20,1^24,1", sizeof(n->special_abilities));
|
||||
|
||||
npc_type->light = 0;
|
||||
npc_type->STR = 75;
|
||||
npc_type->STA = 75;
|
||||
npc_type->DEX = 75;
|
||||
npc_type->AGI = 75;
|
||||
npc_type->INT = 75;
|
||||
npc_type->WIS = 75;
|
||||
npc_type->CHA = 75;
|
||||
horses_auto_delete.Insert(npc_type);
|
||||
auto e = l.front();
|
||||
|
||||
return npc_type;
|
||||
n->current_hp = 1;
|
||||
n->max_hp = 1;
|
||||
n->race = e.race;
|
||||
n->gender = e.gender;
|
||||
n->class_ = Class::Warrior;
|
||||
n->deity = 1;
|
||||
n->level = 1;
|
||||
n->npc_id = 0;
|
||||
n->loottable_id = 0;
|
||||
n->texture = e.texture;
|
||||
n->helmtexture = e.texture;
|
||||
n->runspeed = e.mountspeed;
|
||||
n->light = 0;
|
||||
n->STR = 75;
|
||||
n->STA = 75;
|
||||
n->DEX = 75;
|
||||
n->AGI = 75;
|
||||
n->INT = 75;
|
||||
n->WIS = 75;
|
||||
n->CHA = 75;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
void Client::SummonHorse(uint16 spell_id) {
|
||||
if (GetHorseId() != 0) {
|
||||
Message(Chat::Red,"You already have a Horse. Get off, Fatbutt!");
|
||||
return;
|
||||
}
|
||||
if(!Horse::IsHorseSpell(spell_id)) {
|
||||
LogError("[{}] tried to summon an unknown horse, spell id [{}]", GetName(), spell_id);
|
||||
void Client::SummonHorse(uint16 spell_id)
|
||||
{
|
||||
if (GetHorseId()) {
|
||||
MessageString(Chat::Red, ALREADY_ON_A_MOUNT);
|
||||
return;
|
||||
}
|
||||
|
||||
// No Horse, lets get them one.
|
||||
if (!Horse::IsHorseSpell(spell_id)) {
|
||||
LogError("[{}] tried to summon an unknown horse, spell_id [{}].", GetName(), spell_id);
|
||||
return;
|
||||
}
|
||||
|
||||
auto horse = new Horse(this, spell_id, GetPosition());
|
||||
|
||||
//we want to manage the spawn packet ourself.
|
||||
//another reason is we dont want quests executing on it.
|
||||
entity_list.AddNPC(horse, false);
|
||||
|
||||
// Okay, lets say they have a horse now.
|
||||
Horse* h = new Horse(this, spell_id, GetPosition());
|
||||
|
||||
entity_list.AddNPC(h, false);
|
||||
|
||||
EQApplicationPacket outapp;
|
||||
horse->CreateHorseSpawnPacket(&outapp, GetName(), GetID());
|
||||
/* // Doodman: Kludged in here instead of adding a field to PCType. FIXME!
|
||||
NewSpawn_Struct* ns=(NewSpawn_Struct*)outapp->pBuffer;
|
||||
ns->spawn.texture=mount_color;
|
||||
ns->spawn.pet_owner_id=0;
|
||||
ns->spawn.walkspeed=npc_type->walkspeed;
|
||||
ns->spawn.runspeed=npc_type->runspeed;
|
||||
*/
|
||||
entity_list.QueueClients(horse, &outapp);
|
||||
|
||||
h->CreateHorseSpawnPacket(&outapp);
|
||||
|
||||
uint16 tmpID = horse->GetID();
|
||||
SetHorseId(tmpID);
|
||||
entity_list.QueueClients(h, &outapp);
|
||||
|
||||
SetHorseId(h->GetID());
|
||||
BuffFadeBySitModifier();
|
||||
|
||||
}
|
||||
|
||||
void Client::SetHorseId(uint16 horseid_in) {
|
||||
//if its the same, do nothing
|
||||
if(horseId == horseid_in)
|
||||
void Client::SetHorseId(uint16 in_horse_id)
|
||||
{
|
||||
if (horseId == in_horse_id) {
|
||||
return;
|
||||
|
||||
//otherwise it changed.
|
||||
//if we have a horse, get rid of it no matter what.
|
||||
if(horseId) {
|
||||
Mob *horse = entity_list.GetMob(horseId);
|
||||
if(horse != nullptr)
|
||||
horse->Depop();
|
||||
}
|
||||
|
||||
//now we take whatever they gave us.
|
||||
horseId = horseid_in;
|
||||
if (horseId) {
|
||||
Mob* h = entity_list.GetMob(horseId);
|
||||
if (h) {
|
||||
h->Depop();
|
||||
}
|
||||
}
|
||||
|
||||
horseId = in_horse_id;
|
||||
}
|
||||
|
||||
void Mob::CreateHorseSpawnPacket(EQApplicationPacket* app, const char* ownername, uint16 ownerid, Mob* ForWho) {
|
||||
void Mob::CreateHorseSpawnPacket(EQApplicationPacket* app, Mob* m) {
|
||||
app->SetOpcode(OP_NewSpawn);
|
||||
safe_delete_array(app->pBuffer);
|
||||
app->pBuffer = new uchar[sizeof(NewSpawn_Struct)];
|
||||
app->size = sizeof(NewSpawn_Struct);
|
||||
memset(app->pBuffer, 0, sizeof(NewSpawn_Struct));
|
||||
NewSpawn_Struct* ns = (NewSpawn_Struct*)app->pBuffer;
|
||||
FillSpawnStruct(ns, ForWho);
|
||||
|
||||
#if (EQDEBUG >= 11)
|
||||
printf("Horse Spawn Packet - Owner: %s\n", ownername);
|
||||
DumpPacket(app);
|
||||
#endif
|
||||
auto* ns = (NewSpawn_Struct*) app->pBuffer;
|
||||
FillSpawnStruct(ns, m);
|
||||
}
|
||||
|
||||
|
||||
14
zone/horse.h
14
zone/horse.h
@ -29,19 +29,17 @@ struct NewSpawn_Struct;
|
||||
|
||||
class Horse : public NPC {
|
||||
public:
|
||||
Horse(Client *owner, uint16 spell_id, const glm::vec4& position);
|
||||
Horse(Client* c, uint16 spell_id, const glm::vec4& position);
|
||||
|
||||
virtual void FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho);
|
||||
virtual void FillSpawnStruct(NewSpawn_Struct* ns, Mob* m);
|
||||
|
||||
static bool IsHorseSpell(uint16 spell_id);
|
||||
protected:
|
||||
uint8 mount_color;
|
||||
Client *owner;
|
||||
Client* owner;
|
||||
|
||||
//generate npc type records for horses
|
||||
static std::map<uint16, const NPCType *> horse_types;
|
||||
static const NPCType *GetHorseType(uint16 spell_id);
|
||||
static const NPCType *BuildHorseType(uint16 spell_id);
|
||||
static std::map<uint16, const NPCType*> horse_types;
|
||||
static const NPCType* GetHorseType(uint16 spell_id);
|
||||
static const NPCType* BuildHorseType(uint16 spell_id);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -821,7 +821,7 @@ public:
|
||||
|
||||
//Other Packet
|
||||
void CreateDespawnPacket(EQApplicationPacket* app, bool Decay);
|
||||
void CreateHorseSpawnPacket(EQApplicationPacket* app, const char* ownername, uint16 ownerid, Mob* ForWho = 0);
|
||||
void CreateHorseSpawnPacket(EQApplicationPacket* app, Mob* m = nullptr);
|
||||
void CreateSpawnPacket(EQApplicationPacket* app, Mob* ForWho = 0);
|
||||
static void CreateSpawnPacket(EQApplicationPacket* app, NewSpawn_Struct* ns);
|
||||
virtual void FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho);
|
||||
|
||||
@ -55,6 +55,7 @@
|
||||
#define MISS_NOTE 180 //You miss a note, bringing your song to a close!
|
||||
#define CANNOT_USE_ITEM 181 //Your race, class, or deity cannot use this item.
|
||||
#define ITEM_OUT_OF_CHARGES 182 //Item is out of charges.
|
||||
#define ALREADY_ON_A_MOUNT 189 //You are already on a mount.
|
||||
#define TARGET_NO_MANA 191 //Your target has no mana to affect
|
||||
#define TARGET_GROUP_MEMBER 196 //You must first target a group member.
|
||||
#define SPELL_TOO_POWERFUL 197 //Your spell is too powerful for your intended target.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user