mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-13 06:21:28 +00:00
[Feature] Enable spawn attribute for NPCTintID (#4871)
* Add scripting for NPCTintIndex * AddNPCTintID Add NPCTintID to spawn logic * Update base_npc_types_repository.h * Correct version.h
This commit is contained in:
parent
1221e88d92
commit
20da490bda
@ -7087,6 +7087,18 @@ CREATE INDEX `idx_expire_at` ON `instance_list` (`expire_at`);
|
|||||||
)",
|
)",
|
||||||
.content_schema_update = false
|
.content_schema_update = false
|
||||||
},
|
},
|
||||||
|
ManifestEntry{
|
||||||
|
.version = 9322,
|
||||||
|
.description = "2025_04_24_add_npc_tint_id.sql",
|
||||||
|
.check = "SHOW COLUMNS FROM `npc_types` LIKE 'npc_tint_id'",
|
||||||
|
.condition = "empty",
|
||||||
|
.match = "",
|
||||||
|
.sql = R"(
|
||||||
|
ALTER TABLE `npc_types`
|
||||||
|
ADD COLUMN `npc_tint_id` SMALLINT UNSIGNED NULL DEFAULT '0' AFTER `multiquest_enabled`;
|
||||||
|
)",
|
||||||
|
.content_schema_update = true
|
||||||
|
}
|
||||||
// -- template; copy/paste this when you need to create a new entry
|
// -- template; copy/paste this when you need to create a new entry
|
||||||
// ManifestEntry{
|
// ManifestEntry{
|
||||||
// .version = 9228,
|
// .version = 9228,
|
||||||
|
|||||||
@ -325,6 +325,7 @@ union
|
|||||||
bool trader;
|
bool trader;
|
||||||
bool buyer;
|
bool buyer;
|
||||||
bool untargetable;
|
bool untargetable;
|
||||||
|
uint32 npc_tint_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PlayerState_Struct {
|
struct PlayerState_Struct {
|
||||||
|
|||||||
@ -4839,13 +4839,13 @@ namespace RoF2
|
|||||||
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->petOwnerId);
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->petOwnerId);
|
||||||
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // FindBits MQ2 name
|
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // FindBits MQ2 name
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->PlayerState);
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->PlayerState);
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // NpcTintIndex
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->npc_tint_id); // NpcTintIndex
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // PrimaryTintIndex
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // PrimaryTintIndex
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // SecondaryTintIndex
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // SecondaryTintIndex
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0xffffffff); // These do something with OP_WeaponEquip1
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0xffffffff); // These do something with OP_WeaponEquip1
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0xffffffff); // ^
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0xffffffff); // ^
|
||||||
|
|
||||||
if ((emu->NPC == 0) || (emu->race <= Race::Gnome) || (emu->race == Race::Iksar) ||
|
if ((emu->NPC == 0) || (emu->race <= Race::Gnome) || (emu->race == Race::Iksar) ||
|
||||||
(emu->race == Race::VahShir) || (emu->race == Race::Froglok2) || (emu->race == Race::Drakkin)
|
(emu->race == Race::VahShir) || (emu->race == Race::Froglok2) || (emu->race == Race::Drakkin)
|
||||||
|
|||||||
@ -149,6 +149,7 @@ public:
|
|||||||
uint8_t keeps_sold_items;
|
uint8_t keeps_sold_items;
|
||||||
uint8_t is_parcel_merchant;
|
uint8_t is_parcel_merchant;
|
||||||
uint8_t multiquest_enabled;
|
uint8_t multiquest_enabled;
|
||||||
|
uint16_t npc_tint_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::string PrimaryKey()
|
static std::string PrimaryKey()
|
||||||
@ -289,6 +290,7 @@ public:
|
|||||||
"keeps_sold_items",
|
"keeps_sold_items",
|
||||||
"is_parcel_merchant",
|
"is_parcel_merchant",
|
||||||
"multiquest_enabled",
|
"multiquest_enabled",
|
||||||
|
"npc_tint_id",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -425,6 +427,7 @@ public:
|
|||||||
"keeps_sold_items",
|
"keeps_sold_items",
|
||||||
"is_parcel_merchant",
|
"is_parcel_merchant",
|
||||||
"multiquest_enabled",
|
"multiquest_enabled",
|
||||||
|
"npc_tint_id",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -595,6 +598,7 @@ public:
|
|||||||
e.keeps_sold_items = 1;
|
e.keeps_sold_items = 1;
|
||||||
e.is_parcel_merchant = 0;
|
e.is_parcel_merchant = 0;
|
||||||
e.multiquest_enabled = 0;
|
e.multiquest_enabled = 0;
|
||||||
|
e.npc_tint_id = 0;
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
@ -761,6 +765,7 @@ public:
|
|||||||
e.keeps_sold_items = row[127] ? static_cast<uint8_t>(strtoul(row[127], nullptr, 10)) : 1;
|
e.keeps_sold_items = row[127] ? static_cast<uint8_t>(strtoul(row[127], nullptr, 10)) : 1;
|
||||||
e.is_parcel_merchant = row[128] ? static_cast<uint8_t>(strtoul(row[128], nullptr, 10)) : 0;
|
e.is_parcel_merchant = row[128] ? static_cast<uint8_t>(strtoul(row[128], nullptr, 10)) : 0;
|
||||||
e.multiquest_enabled = row[129] ? static_cast<uint8_t>(strtoul(row[129], nullptr, 10)) : 0;
|
e.multiquest_enabled = row[129] ? static_cast<uint8_t>(strtoul(row[129], nullptr, 10)) : 0;
|
||||||
|
e.npc_tint_id = row[130] ? static_cast<uint16_t>(strtoul(row[130], nullptr, 10)) : 0;
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
@ -923,6 +928,7 @@ public:
|
|||||||
v.push_back(columns[127] + " = " + std::to_string(e.keeps_sold_items));
|
v.push_back(columns[127] + " = " + std::to_string(e.keeps_sold_items));
|
||||||
v.push_back(columns[128] + " = " + std::to_string(e.is_parcel_merchant));
|
v.push_back(columns[128] + " = " + std::to_string(e.is_parcel_merchant));
|
||||||
v.push_back(columns[129] + " = " + std::to_string(e.multiquest_enabled));
|
v.push_back(columns[129] + " = " + std::to_string(e.multiquest_enabled));
|
||||||
|
v.push_back(columns[130] + " = " + std::to_string(e.npc_tint_id));
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@ -1074,6 +1080,7 @@ public:
|
|||||||
v.push_back(std::to_string(e.keeps_sold_items));
|
v.push_back(std::to_string(e.keeps_sold_items));
|
||||||
v.push_back(std::to_string(e.is_parcel_merchant));
|
v.push_back(std::to_string(e.is_parcel_merchant));
|
||||||
v.push_back(std::to_string(e.multiquest_enabled));
|
v.push_back(std::to_string(e.multiquest_enabled));
|
||||||
|
v.push_back(std::to_string(e.npc_tint_id));
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@ -1233,6 +1240,7 @@ public:
|
|||||||
v.push_back(std::to_string(e.keeps_sold_items));
|
v.push_back(std::to_string(e.keeps_sold_items));
|
||||||
v.push_back(std::to_string(e.is_parcel_merchant));
|
v.push_back(std::to_string(e.is_parcel_merchant));
|
||||||
v.push_back(std::to_string(e.multiquest_enabled));
|
v.push_back(std::to_string(e.multiquest_enabled));
|
||||||
|
v.push_back(std::to_string(e.npc_tint_id));
|
||||||
|
|
||||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
}
|
}
|
||||||
@ -1396,6 +1404,7 @@ public:
|
|||||||
e.keeps_sold_items = row[127] ? static_cast<uint8_t>(strtoul(row[127], nullptr, 10)) : 1;
|
e.keeps_sold_items = row[127] ? static_cast<uint8_t>(strtoul(row[127], nullptr, 10)) : 1;
|
||||||
e.is_parcel_merchant = row[128] ? static_cast<uint8_t>(strtoul(row[128], nullptr, 10)) : 0;
|
e.is_parcel_merchant = row[128] ? static_cast<uint8_t>(strtoul(row[128], nullptr, 10)) : 0;
|
||||||
e.multiquest_enabled = row[129] ? static_cast<uint8_t>(strtoul(row[129], nullptr, 10)) : 0;
|
e.multiquest_enabled = row[129] ? static_cast<uint8_t>(strtoul(row[129], nullptr, 10)) : 0;
|
||||||
|
e.npc_tint_id = row[130] ? static_cast<uint16_t>(strtoul(row[130], nullptr, 10)) : 0;
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
@ -1550,6 +1559,7 @@ public:
|
|||||||
e.keeps_sold_items = row[127] ? static_cast<uint8_t>(strtoul(row[127], nullptr, 10)) : 1;
|
e.keeps_sold_items = row[127] ? static_cast<uint8_t>(strtoul(row[127], nullptr, 10)) : 1;
|
||||||
e.is_parcel_merchant = row[128] ? static_cast<uint8_t>(strtoul(row[128], nullptr, 10)) : 0;
|
e.is_parcel_merchant = row[128] ? static_cast<uint8_t>(strtoul(row[128], nullptr, 10)) : 0;
|
||||||
e.multiquest_enabled = row[129] ? static_cast<uint8_t>(strtoul(row[129], nullptr, 10)) : 0;
|
e.multiquest_enabled = row[129] ? static_cast<uint8_t>(strtoul(row[129], nullptr, 10)) : 0;
|
||||||
|
e.npc_tint_id = row[130] ? static_cast<uint16_t>(strtoul(row[130], nullptr, 10)) : 0;
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
@ -1754,6 +1764,7 @@ public:
|
|||||||
v.push_back(std::to_string(e.keeps_sold_items));
|
v.push_back(std::to_string(e.keeps_sold_items));
|
||||||
v.push_back(std::to_string(e.is_parcel_merchant));
|
v.push_back(std::to_string(e.is_parcel_merchant));
|
||||||
v.push_back(std::to_string(e.multiquest_enabled));
|
v.push_back(std::to_string(e.multiquest_enabled));
|
||||||
|
v.push_back(std::to_string(e.npc_tint_id));
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@ -1906,6 +1917,7 @@ public:
|
|||||||
v.push_back(std::to_string(e.keeps_sold_items));
|
v.push_back(std::to_string(e.keeps_sold_items));
|
||||||
v.push_back(std::to_string(e.is_parcel_merchant));
|
v.push_back(std::to_string(e.is_parcel_merchant));
|
||||||
v.push_back(std::to_string(e.multiquest_enabled));
|
v.push_back(std::to_string(e.multiquest_enabled));
|
||||||
|
v.push_back(std::to_string(e.npc_tint_id));
|
||||||
|
|
||||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -42,7 +42,7 @@
|
|||||||
* Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
* Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define CURRENT_BINARY_DATABASE_VERSION 9321
|
#define CURRENT_BINARY_DATABASE_VERSION 9322
|
||||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9054
|
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9054
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -1693,6 +1693,24 @@ void command_npcedit(Client *c, const Seperator *sep)
|
|||||||
c->Message(Chat::White, "Usage: #npcedit set_grid [Grid ID] - Sets an NPC's Grid ID");
|
c->Message(Chat::White, "Usage: #npcedit set_grid [Grid ID] - Sets an NPC's Grid ID");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
} else if (!strcasecmp(sep->arg[1], "npc_tint_id")) {
|
||||||
|
if (sep->IsNumber(2)) {
|
||||||
|
const uint32 npc_tint_id = (Strings::ToUnsignedInt(sep->arg[2]));
|
||||||
|
|
||||||
|
n.npc_tint_id = npc_tint_id;
|
||||||
|
|
||||||
|
d = fmt::format(
|
||||||
|
"Set NPCTintID {} for {}",
|
||||||
|
npc_tint_id,
|
||||||
|
npc_id_string
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
c->Message(
|
||||||
|
Chat::White,
|
||||||
|
"Usage: #npcedit npc_tint_id [id] - Sets an NPC's NPCTintID [0 - 78 for RoF2]"
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
SendNPCEditSubCommands(c);
|
SendNPCEditSubCommands(c);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -945,6 +945,12 @@ bool Lua_NPC::IsResumedFromZoneSuspend()
|
|||||||
return self->IsResumedFromZoneSuspend();
|
return self->IsResumedFromZoneSuspend();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Lua_NPC::SetNPCTintIndex(uint32 id)
|
||||||
|
{
|
||||||
|
Lua_Safe_Call_Void();
|
||||||
|
self->SendAppearancePacket(AppearanceType::NPCTintIndex, id);
|
||||||
|
}
|
||||||
|
|
||||||
luabind::scope lua_register_npc() {
|
luabind::scope lua_register_npc() {
|
||||||
return luabind::class_<Lua_NPC, Lua_Mob>("NPC")
|
return luabind::class_<Lua_NPC, Lua_Mob>("NPC")
|
||||||
.def(luabind::constructor<>())
|
.def(luabind::constructor<>())
|
||||||
@ -1091,6 +1097,7 @@ luabind::scope lua_register_npc() {
|
|||||||
.def("SetLDoNTrapType", (void(Lua_NPC::*)(uint8))&Lua_NPC::SetLDoNTrapType)
|
.def("SetLDoNTrapType", (void(Lua_NPC::*)(uint8))&Lua_NPC::SetLDoNTrapType)
|
||||||
.def("SetNPCAggro", (void(Lua_NPC::*)(bool))&Lua_NPC::SetNPCAggro)
|
.def("SetNPCAggro", (void(Lua_NPC::*)(bool))&Lua_NPC::SetNPCAggro)
|
||||||
.def("SetNPCFactionID", (void(Lua_NPC::*)(int))&Lua_NPC::SetNPCFactionID)
|
.def("SetNPCFactionID", (void(Lua_NPC::*)(int))&Lua_NPC::SetNPCFactionID)
|
||||||
|
.def("SetNPCTintIndex", &Lua_NPC::SetNPCTintIndex)
|
||||||
.def("SetPetSpellID", (void(Lua_NPC::*)(int))&Lua_NPC::SetPetSpellID)
|
.def("SetPetSpellID", (void(Lua_NPC::*)(int))&Lua_NPC::SetPetSpellID)
|
||||||
.def("SetPlatinum", (void(Lua_NPC::*)(uint32))&Lua_NPC::SetPlatinum)
|
.def("SetPlatinum", (void(Lua_NPC::*)(uint32))&Lua_NPC::SetPlatinum)
|
||||||
.def("SetPrimSkill", (void(Lua_NPC::*)(int))&Lua_NPC::SetPrimSkill)
|
.def("SetPrimSkill", (void(Lua_NPC::*)(int))&Lua_NPC::SetPrimSkill)
|
||||||
|
|||||||
@ -199,6 +199,8 @@ public:
|
|||||||
void ReturnHandinItems(Lua_Client c);
|
void ReturnHandinItems(Lua_Client c);
|
||||||
Lua_Spawn GetSpawn(lua_State* L);
|
Lua_Spawn GetSpawn(lua_State* L);
|
||||||
bool IsResumedFromZoneSuspend();
|
bool IsResumedFromZoneSuspend();
|
||||||
|
void SetNPCTintIndex(uint32 id);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
39
zone/mob.cpp
39
zone/mob.cpp
@ -101,7 +101,8 @@ Mob::Mob(
|
|||||||
bool in_always_aggro,
|
bool in_always_aggro,
|
||||||
int32 in_heroic_strikethrough,
|
int32 in_heroic_strikethrough,
|
||||||
bool in_keeps_sold_items,
|
bool in_keeps_sold_items,
|
||||||
int64 in_hp_regen_per_second
|
int64 in_hp_regen_per_second,
|
||||||
|
uint32 npc_tint_id
|
||||||
) :
|
) :
|
||||||
attack_timer(2000),
|
attack_timer(2000),
|
||||||
attack_dw_timer(2000),
|
attack_dw_timer(2000),
|
||||||
@ -289,6 +290,7 @@ Mob::Mob(
|
|||||||
always_aggro = in_always_aggro;
|
always_aggro = in_always_aggro;
|
||||||
heroic_strikethrough = in_heroic_strikethrough;
|
heroic_strikethrough = in_heroic_strikethrough;
|
||||||
keeps_sold_items = in_keeps_sold_items;
|
keeps_sold_items = in_keeps_sold_items;
|
||||||
|
m_npc_tint_id = npc_tint_id;
|
||||||
|
|
||||||
InitializeBuffSlots();
|
InitializeBuffSlots();
|
||||||
|
|
||||||
@ -1285,23 +1287,24 @@ void Mob::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho)
|
|||||||
strn0cpy(ns->spawn.lastName, lastname, sizeof(ns->spawn.lastName));
|
strn0cpy(ns->spawn.lastName, lastname, sizeof(ns->spawn.lastName));
|
||||||
}
|
}
|
||||||
|
|
||||||
ns->spawn.heading = FloatToEQ12(m_Position.w);
|
ns->spawn.heading = FloatToEQ12(m_Position.w);
|
||||||
ns->spawn.x = FloatToEQ19(m_Position.x);//((int32)x_pos)<<3;
|
ns->spawn.x = FloatToEQ19(m_Position.x); //((int32)x_pos)<<3;
|
||||||
ns->spawn.y = FloatToEQ19(m_Position.y);//((int32)y_pos)<<3;
|
ns->spawn.y = FloatToEQ19(m_Position.y); //((int32)y_pos)<<3;
|
||||||
ns->spawn.z = FloatToEQ19(m_Position.z);//((int32)z_pos)<<3;
|
ns->spawn.z = FloatToEQ19(m_Position.z); //((int32)z_pos)<<3;
|
||||||
ns->spawn.spawnId = GetID();
|
ns->spawn.spawnId = GetID();
|
||||||
ns->spawn.curHp = static_cast<uint8>(GetHPRatio());
|
ns->spawn.curHp = static_cast<uint8>(GetHPRatio());
|
||||||
ns->spawn.max_hp = 100; //this field needs a better name
|
ns->spawn.max_hp = 100; // this field needs a better name
|
||||||
ns->spawn.race = (use_model) ? use_model : race;
|
ns->spawn.race = (use_model) ? use_model : race;
|
||||||
ns->spawn.runspeed = runspeed;
|
ns->spawn.runspeed = runspeed;
|
||||||
ns->spawn.walkspeed = walkspeed;
|
ns->spawn.walkspeed = walkspeed;
|
||||||
ns->spawn.class_ = class_;
|
ns->spawn.class_ = class_;
|
||||||
ns->spawn.gender = gender;
|
ns->spawn.gender = gender;
|
||||||
ns->spawn.level = level;
|
ns->spawn.level = level;
|
||||||
ns->spawn.PlayerState = GetPlayerState();
|
ns->spawn.PlayerState = GetPlayerState();
|
||||||
ns->spawn.deity = deity;
|
ns->spawn.deity = deity;
|
||||||
ns->spawn.animation = 0;
|
ns->spawn.animation = 0;
|
||||||
ns->spawn.findable = findable?1:0;
|
ns->spawn.findable = findable ? 1 : 0;
|
||||||
|
ns->spawn.npc_tint_id = GetNpcTintId();
|
||||||
|
|
||||||
UpdateActiveLight();
|
UpdateActiveLight();
|
||||||
ns->spawn.light = m_Light.Type[EQ::lightsource::LightActive];
|
ns->spawn.light = m_Light.Type[EQ::lightsource::LightActive];
|
||||||
|
|||||||
@ -192,7 +192,8 @@ public:
|
|||||||
bool in_always_aggros_foes,
|
bool in_always_aggros_foes,
|
||||||
int32 in_heroic_strikethrough,
|
int32 in_heroic_strikethrough,
|
||||||
bool keeps_sold_items,
|
bool keeps_sold_items,
|
||||||
int64 in_hp_regen_per_second = 0
|
int64 in_hp_regen_per_second = 0,
|
||||||
|
uint32 npc_tint_id = 0
|
||||||
);
|
);
|
||||||
virtual ~Mob();
|
virtual ~Mob();
|
||||||
|
|
||||||
@ -1066,6 +1067,7 @@ public:
|
|||||||
void SendWearChangeAndLighting(int8 last_texture);
|
void SendWearChangeAndLighting(int8 last_texture);
|
||||||
inline uint8 GetActiveLightType() { return m_Light.Type[EQ::lightsource::LightActive]; }
|
inline uint8 GetActiveLightType() { return m_Light.Type[EQ::lightsource::LightActive]; }
|
||||||
bool UpdateActiveLight(); // returns true if change, false if no change
|
bool UpdateActiveLight(); // returns true if change, false if no change
|
||||||
|
uint32 GetNpcTintId() { return m_npc_tint_id; }
|
||||||
|
|
||||||
EQ::LightSourceProfile* GetLightProfile() { return &m_Light; }
|
EQ::LightSourceProfile* GetLightProfile() { return &m_Light; }
|
||||||
|
|
||||||
@ -1597,6 +1599,7 @@ protected:
|
|||||||
bool rare_spawn;
|
bool rare_spawn;
|
||||||
int32 heroic_strikethrough;
|
int32 heroic_strikethrough;
|
||||||
bool keeps_sold_items;
|
bool keeps_sold_items;
|
||||||
|
uint32 m_npc_tint_id;
|
||||||
|
|
||||||
uint32 m_PlayerState;
|
uint32 m_PlayerState;
|
||||||
uint32 GetPlayerState() { return m_PlayerState; }
|
uint32 GetPlayerState() { return m_PlayerState; }
|
||||||
|
|||||||
22
zone/npc.cpp
22
zone/npc.cpp
@ -128,7 +128,8 @@ NPC::NPC(const NPCType *npc_type_data, Spawn2 *in_respawn, const glm::vec4 &posi
|
|||||||
npc_type_data->always_aggro,
|
npc_type_data->always_aggro,
|
||||||
npc_type_data->heroic_strikethrough,
|
npc_type_data->heroic_strikethrough,
|
||||||
npc_type_data->keeps_sold_items,
|
npc_type_data->keeps_sold_items,
|
||||||
npc_type_data->hp_regen_per_second
|
npc_type_data->hp_regen_per_second,
|
||||||
|
npc_type_data->m_npc_tint_id
|
||||||
),
|
),
|
||||||
attacked_timer(CombatEventTimer_expire),
|
attacked_timer(CombatEventTimer_expire),
|
||||||
swarm_timer(100),
|
swarm_timer(100),
|
||||||
@ -451,6 +452,7 @@ NPC::NPC(const NPCType *npc_type_data, Spawn2 *in_respawn, const glm::vec4 &posi
|
|||||||
raid_target = npc_type_data->raid_target;
|
raid_target = npc_type_data->raid_target;
|
||||||
ignore_despawn = npc_type_data->ignore_despawn;
|
ignore_despawn = npc_type_data->ignore_despawn;
|
||||||
m_targetable = !npc_type_data->untargetable;
|
m_targetable = !npc_type_data->untargetable;
|
||||||
|
m_npc_tint_id = npc_type_data->m_npc_tint_id;
|
||||||
|
|
||||||
npc_scale_manager->ScaleNPC(this);
|
npc_scale_manager->ScaleNPC(this);
|
||||||
|
|
||||||
@ -1256,10 +1258,11 @@ uint32 ZoneDatabase::CreateNewNPCCommand(
|
|||||||
e.Avoidance = n->GetAvoidanceRating();
|
e.Avoidance = n->GetAvoidanceRating();
|
||||||
e.heroic_strikethrough = n->GetHeroicStrikethrough();
|
e.heroic_strikethrough = n->GetHeroicStrikethrough();
|
||||||
|
|
||||||
e.see_hide = n->SeeHide();
|
e.see_hide = n->SeeHide();
|
||||||
e.see_improved_hide = n->SeeImprovedHide();
|
e.see_improved_hide = n->SeeImprovedHide();
|
||||||
e.see_invis = n->SeeInvisible();
|
e.see_invis = n->SeeInvisible();
|
||||||
e.see_invis_undead = n->SeeInvisibleUndead();
|
e.see_invis_undead = n->SeeInvisibleUndead();
|
||||||
|
e.npc_tint_id = n->GetNpcTintId();
|
||||||
|
|
||||||
|
|
||||||
e = NpcTypesRepository::InsertOne(*this, e);
|
e = NpcTypesRepository::InsertOne(*this, e);
|
||||||
@ -1399,6 +1402,7 @@ uint32 ZoneDatabase::UpdateNPCTypeAppearance(Client* c, NPC* n)
|
|||||||
e.loottable_id = n->GetLoottableID();
|
e.loottable_id = n->GetLoottableID();
|
||||||
e.merchant_id = n->MerchantType;
|
e.merchant_id = n->MerchantType;
|
||||||
e.face = n->GetLuclinFace();
|
e.face = n->GetLuclinFace();
|
||||||
|
e.npc_tint_id = n->GetNpcTintId();
|
||||||
|
|
||||||
const int updated = NpcTypesRepository::UpdateOne(*this, e);
|
const int updated = NpcTypesRepository::UpdateOne(*this, e);
|
||||||
|
|
||||||
@ -1539,6 +1543,7 @@ uint32 ZoneDatabase::AddNPCTypes(
|
|||||||
e.runspeed = n->GetRunspeed();
|
e.runspeed = n->GetRunspeed();
|
||||||
e.prim_melee_type = static_cast<uint8_t>(EQ::skills::SkillHandtoHand);
|
e.prim_melee_type = static_cast<uint8_t>(EQ::skills::SkillHandtoHand);
|
||||||
e.sec_melee_type = static_cast<uint8_t>(EQ::skills::SkillHandtoHand);
|
e.sec_melee_type = static_cast<uint8_t>(EQ::skills::SkillHandtoHand);
|
||||||
|
e.npc_tint_id = n->GetNpcTintId();
|
||||||
|
|
||||||
e = NpcTypesRepository::InsertOne(*this, e);
|
e = NpcTypesRepository::InsertOne(*this, e);
|
||||||
|
|
||||||
@ -2169,9 +2174,10 @@ void NPC::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho)
|
|||||||
PetOnSpawn(ns);
|
PetOnSpawn(ns);
|
||||||
ns->spawn.is_npc = 1;
|
ns->spawn.is_npc = 1;
|
||||||
UpdateActiveLight();
|
UpdateActiveLight();
|
||||||
ns->spawn.light = GetActiveLightType();
|
ns->spawn.light = GetActiveLightType();
|
||||||
ns->spawn.show_name = NPCTypedata->show_name;
|
ns->spawn.show_name = NPCTypedata->show_name;
|
||||||
ns->spawn.trader = false;
|
ns->spawn.trader = false;
|
||||||
|
ns->spawn.npc_tint_id = GetNpcTintId();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NPC::PetOnSpawn(NewSpawn_Struct* ns)
|
void NPC::PetOnSpawn(NewSpawn_Struct* ns)
|
||||||
|
|||||||
@ -885,6 +885,11 @@ Spawn2* Perl_NPC_GetSpawn(NPC* self)
|
|||||||
return self->GetSpawn();
|
return self->GetSpawn();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Perl_NPC_SetNPCTintIndex(NPC* self, uint32 id)
|
||||||
|
{
|
||||||
|
return self->SendAppearancePacket(AppearanceType::NPCTintIndex, id);
|
||||||
|
}
|
||||||
|
|
||||||
void perl_register_npc()
|
void perl_register_npc()
|
||||||
{
|
{
|
||||||
perl::interpreter perl(PERL_GET_THX);
|
perl::interpreter perl(PERL_GET_THX);
|
||||||
@ -1034,6 +1039,7 @@ void perl_register_npc()
|
|||||||
package.add("SetGold", &Perl_NPC_SetGold);
|
package.add("SetGold", &Perl_NPC_SetGold);
|
||||||
package.add("SetGrid", &Perl_NPC_SetGrid);
|
package.add("SetGrid", &Perl_NPC_SetGrid);
|
||||||
package.add("SetNPCFactionID", &Perl_NPC_SetNPCFactionID);
|
package.add("SetNPCFactionID", &Perl_NPC_SetNPCFactionID);
|
||||||
|
package.add("SetNPCTintIndex", &Perl_NPC_SetNPCTintIndex);
|
||||||
package.add("SetPetSpellID", &Perl_NPC_SetPetSpellID);
|
package.add("SetPetSpellID", &Perl_NPC_SetPetSpellID);
|
||||||
package.add("SetPlatinum", &Perl_NPC_SetPlatinum);
|
package.add("SetPlatinum", &Perl_NPC_SetPlatinum);
|
||||||
package.add("SetPrimSkill", &Perl_NPC_SetPrimSkill);
|
package.add("SetPrimSkill", &Perl_NPC_SetPrimSkill);
|
||||||
|
|||||||
@ -1732,6 +1732,7 @@ const NPCType *ZoneDatabase::LoadNPCTypesData(uint32 npc_type_id, bool bulk_load
|
|||||||
t->attack_count = n.attack_count;
|
t->attack_count = n.attack_count;
|
||||||
t->is_parcel_merchant = n.is_parcel_merchant ? true : false;
|
t->is_parcel_merchant = n.is_parcel_merchant ? true : false;
|
||||||
t->greed = n.greed;
|
t->greed = n.greed;
|
||||||
|
t->m_npc_tint_id = n.npc_tint_id;
|
||||||
|
|
||||||
if (!n.special_abilities.empty()) {
|
if (!n.special_abilities.empty()) {
|
||||||
strn0cpy(t->special_abilities, n.special_abilities.c_str(), 512);
|
strn0cpy(t->special_abilities, n.special_abilities.c_str(), 512);
|
||||||
|
|||||||
@ -157,6 +157,7 @@ struct NPCType
|
|||||||
bool is_parcel_merchant;
|
bool is_parcel_merchant;
|
||||||
uint8 greed;
|
uint8 greed;
|
||||||
bool multiquest_enabled;
|
bool multiquest_enabled;
|
||||||
|
uint32 m_npc_tint_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user