Item Transformation now works!

This commit is contained in:
Natedog2012 2014-11-26 13:57:18 -08:00 committed by Michael Cook (mackal)
parent ee7f88d247
commit daec5bde66
16 changed files with 166 additions and 8 deletions

View File

@ -1412,6 +1412,8 @@ ItemInst::ItemInst(const Item_Struct* item, int16 charges) {
m_scaledItem = nullptr;
m_evolveInfo = nullptr;
m_scaling = false;
m_ornamenticon = 0;
m_ornamentidfile = 0;
}
ItemInst::ItemInst(SharedDatabase *db, uint32 item_id, int16 charges) {
@ -1434,6 +1436,8 @@ ItemInst::ItemInst(SharedDatabase *db, uint32 item_id, int16 charges) {
m_scaledItem = nullptr;
m_evolveInfo = nullptr;
m_scaling = false;
m_ornamenticon = 0;
m_ornamentidfile = 0;
}
ItemInst::ItemInst(ItemInstTypes use_type) {
@ -1451,6 +1455,8 @@ ItemInst::ItemInst(ItemInstTypes use_type) {
m_scaledItem = nullptr;
m_evolveInfo = nullptr;
m_scaling = false;
m_ornamenticon = 0;
m_ornamentidfile = 0;
}
// Make a copy of an ItemInst object
@ -1501,6 +1507,8 @@ ItemInst::ItemInst(const ItemInst& copy)
m_evolveInfo = nullptr;
m_scaling = copy.m_scaling;
m_ornamenticon = copy.m_ornamenticon;
m_ornamentidfile = copy.m_ornamentidfile;
}
// Clean up container contents
@ -1789,6 +1797,54 @@ ItemInst* ItemInst::GetOrnamentationAug(int ornamentationAugtype) const
return nullptr;
}
bool ItemInst::CanTransform(const Item_Struct *ItemToTry, const Item_Struct *Container, bool AllowAll) {
if (!ItemToTry || !Container) return false;
if (ItemToTry->ItemType == ItemTypeArrow || strnlen(Container->CharmFile, 30) == 0)
return false;
if (AllowAll && Container->CharmFile != "ITEMTRANSFIGSHIELD" && Container->CharmFile != "ITEMTransfigBow") {
switch (ItemToTry->ItemType) {
case 0:
case 1:
case 2:
case 3:
case 4:
case 35:
case 45:
return true;
}
}
static std::map<std::string, int> types = {
{ "ITEMTransfig1HP", 2 },
{ "ITEMTransfig1HS", 0 },
{ "ITEMTransfig2HB", 4 },
{ "ITEMTransfig2HP", 35 },
{ "ITEMTransfig2HS", 1 },
{ "ITEMTransfigBlunt", 3 },
{ "ITEMTransfigBow", 5 },
{ "ITEMTransfigHTH", 45 },
{ "ITEMTRANSFIGSHIELD", 8 },
{ "ITEMTransfigSlashing", 0 }
};
auto i = types.find(Container->CharmFile);
if (i != types.end() && i->second == ItemToTry->ItemType)
return true;
static std::map<std::string, int> typestwo = {
{ "ITEMTransfigBlunt", 4 },
{ "ITEMTransfigSlashing", 1 }
};
i = typestwo.find(Container->CharmFile);
if (i != typestwo.end() && i->second == ItemToTry->ItemType)
return true;
return false;
}
uint32 ItemInst::GetAugmentItemID(uint8 slot) const
{
uint32 id = NO_ITEM;

View File

@ -330,6 +330,7 @@ public:
ItemInst* RemoveAugment(uint8 index);
bool IsAugmented();
ItemInst* GetOrnamentationAug(int ornamentationAugtype) const;
static bool CanTransform(const Item_Struct *ItemToTry, const Item_Struct *Container, bool AllowAll = false);
// Has attack/delay?
bool IsWeapon() const;
@ -392,6 +393,10 @@ public:
void SetActivated(bool activated) { m_activated = activated; }
int8 GetEvolveLvl() const { return m_evolveLvl; }
void SetScaling(bool v) { m_scaling = v; }
uint32 GetOrnamentationIcon() const { return m_ornamenticon; }
void SetOrnamentIcon(uint32 ornament_icon) { m_ornamenticon = ornament_icon; }
uint32 GetOrnamentationIDFile() const { return m_ornamentidfile; }
void SetOrnamentationIDFile(uint32 ornament_idfile) { m_ornamentidfile = ornament_idfile; }
void Initialize(SharedDatabase *db = nullptr);
void ScaleItem();
@ -436,6 +441,8 @@ protected:
Item_Struct* m_scaledItem;
EvolveInfo* m_evolveInfo;
bool m_scaling;
uint32 m_ornamenticon;
uint32 m_ornamentidfile;
//
// Items inside of this item (augs or contents);

View File

@ -4888,6 +4888,16 @@ namespace RoF
//Icon
ornaIcon = aug_weap->Icon;
}
else if (inst->GetOrnamentationIDFile() && inst->GetOrnamentationIcon()) {
char tmp[30]; memset(tmp, 0x0, 30); sprintf(tmp, "IT%d", inst->GetOrnamentationIDFile());
//Mainhand
ss.write(tmp, strlen(tmp));
ss.write((const char*)&null_term, sizeof(uint8));
//Offhand
ss.write(tmp, strlen(tmp));
ss.write((const char*)&null_term, sizeof(uint8));
ornaIcon = inst->GetOrnamentationIcon();
}
else {
ss.write((const char*)&null_term, sizeof(uint8)); //no mh
ss.write((const char*)&null_term, sizeof(uint8));//no of

View File

@ -3664,6 +3664,12 @@ namespace Underfoot
ss.write((const char*)&null_term, sizeof(uint8));
ornaIcon = aug_weap->Icon;
}
else if (inst->GetOrnamentationIDFile() && inst->GetOrnamentationIcon()) {
char tmp[30]; memset(tmp, 0x0, 30); sprintf(tmp, "IT%d", inst->GetOrnamentationIDFile());
ss.write(tmp, strlen(tmp));
ss.write((const char*)&null_term, sizeof(uint8));
ornaIcon = inst->GetOrnamentationIcon();
}
else {
ss.write((const char*)&null_term, sizeof(uint8)); //no idfile
}

View File

@ -586,6 +586,8 @@ RULE_CATEGORY( Inventory )
RULE_BOOL ( Inventory, EnforceAugmentRestriction, true) // Forces augment slot restrictions
RULE_BOOL ( Inventory, EnforceAugmentUsability, true) // Forces augmented item usability
RULE_BOOL ( Inventory, EnforceAugmentWear, true) // Forces augment wear slot validation
RULE_BOOL ( Inventory, DeleteTransformationMold, true) //False if you want mold to last forever
RULE_BOOL ( Inventory, AllowAnyWeaponTransformation, false) //Weapons can use any weapon transformation
RULE_CATEGORY_END()
RULE_CATEGORY( Client )

View File

@ -199,14 +199,14 @@ bool SharedDatabase::UpdateInventorySlot(uint32 char_id, const ItemInst* inst, i
// Update/Insert item
std::string query = StringFormat("REPLACE INTO inventory "
"(charid, slotid, itemid, charges, instnodrop, custom_data, color, "
"augslot1, augslot2, augslot3, augslot4, augslot5) "
"augslot1, augslot2, augslot3, augslot4, augslot5, ornamenticon, ornamentidfile) "
"VALUES( %lu, %lu, %lu, %lu, %lu, '%s', %lu, "
"%lu, %lu, %lu, %lu, %lu)",
"%lu, %lu, %lu, %lu, %lu, %lu, %lu)",
(unsigned long)char_id, (unsigned long)slot_id, (unsigned long)inst->GetItem()->ID,
(unsigned long)charges, (unsigned long)(inst->IsInstNoDrop()? 1: 0),
inst->GetCustomDataString().c_str(), (unsigned long)inst->GetColor(),
(unsigned long)augslot[0], (unsigned long)augslot[1], (unsigned long)augslot[2],
(unsigned long)augslot[3],(unsigned long)augslot[4]);
(unsigned long)augslot[3],(unsigned long)augslot[4], (unsigned long)inst->GetOrnamentationIcon(), (unsigned long)inst->GetOrnamentationIDFile());
auto results = QueryDatabase(query);
// Save bag contents, if slot supports bag contents
@ -488,7 +488,7 @@ bool SharedDatabase::GetSharedBank(uint32 id, Inventory* inv, bool is_charid) {
bool SharedDatabase::GetInventory(uint32 char_id, Inventory* inv) {
// Retrieve character inventory
std::string query = StringFormat("SELECT slotid, itemid, charges, color, augslot1, "
"augslot2, augslot3, augslot4, augslot5, instnodrop, custom_data "
"augslot2, augslot3, augslot4, augslot5, instnodrop, custom_data, ornamenticon, ornamentidfile "
"FROM inventory WHERE charid = %i ORDER BY slotid", char_id);
auto results = QueryDatabase(query);
if (!results.Success()) {
@ -513,6 +513,9 @@ bool SharedDatabase::GetInventory(uint32 char_id, Inventory* inv) {
bool instnodrop = (row[9] && (uint16)atoi(row[9]))? true: false;
uint32 ornament_icon = (uint32)atoul(row[11]);
uint32 ornament_idfile = (uint32)atoul(row[12]);
const Item_Struct* item = GetItem(item_id);
if (!item) {
@ -549,6 +552,11 @@ bool SharedDatabase::GetInventory(uint32 char_id, Inventory* inv) {
value.push_back(v);
}
}
if (ornament_icon > 0)
inst->SetOrnamentIcon(ornament_icon);
if (ornament_idfile > 0)
inst->SetOrnamentationIDFile(ornament_idfile);
if (instnodrop || (((slot_id >= EmuConstants::EQUIPMENT_BEGIN && slot_id <= EmuConstants::EQUIPMENT_END) || slot_id == MainPowerSource) && inst->GetItem()->Attuneable))
inst->SetInstNoDrop(true);
@ -591,7 +599,7 @@ bool SharedDatabase::GetInventory(uint32 char_id, Inventory* inv) {
bool SharedDatabase::GetInventory(uint32 account_id, char* name, Inventory* inv) {
// Retrieve character inventory
std::string query = StringFormat("SELECT slotid, itemid, charges, color, augslot1, "
"augslot2, augslot3, augslot4, augslot5, instnodrop, custom_data "
"augslot2, augslot3, augslot4, augslot5, instnodrop, custom_data, ornamenticon, ornamentidfile "
"FROM inventory INNER JOIN character_data ch "
"ON ch.id = charid WHERE ch.name = '%s' AND ch.account_id = %i ORDER BY slotid",
name, account_id);
@ -617,6 +625,9 @@ bool SharedDatabase::GetInventory(uint32 account_id, char* name, Inventory* inv)
aug[4] = (uint32)atoi(row[8]);
bool instnodrop = (row[9] && (uint16)atoi(row[9])) ? true : false;
uint32 ornament_icon = (uint32)atoul(row[11]);
uint32 ornament_idfile = (uint32)atoul(row[12]);
const Item_Struct* item = GetItem(item_id);
int16 put_slot_id = INVALID_INDEX;
if(!item)
@ -651,6 +662,12 @@ bool SharedDatabase::GetInventory(uint32 account_id, char* name, Inventory* inv)
}
}
if (ornament_icon > 0)
inst->SetOrnamentIcon(ornament_icon);
if (ornament_idfile > 0)
inst->SetOrnamentationIDFile(ornament_idfile);
if (color > 0)
inst->SetColor(color);

View File

@ -0,0 +1,3 @@
--Optional Transformation Rules
INSERT INTO `rule_values` VALUES (1, 'Inventory:DeleteTransformationMold', 'true', 'false to keep transformation mold forever');
INSERT INTO `rule_values` VALUES (1, 'Inventory:AllowAnyWeaponTransformation', 'false', 'True allows any MELEE weapon to use the other melee type transformatios');

View File

@ -0,0 +1,4 @@
--Inventory table update
ALTER TABLE `inventory`
ADD COLUMN `ornamenticon` INT(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `custom_data`,
ADD COLUMN `ornamentidfile` INT(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `ornamenticon`;

View File

@ -197,6 +197,9 @@ void WorldDatabase::GetCharSelectInfo(uint32 account_id, CharacterSelect_Struct*
if (item->GetOrnamentationAug(ornamentationAugtype)) {
idfile = atoi(&item->GetOrnamentationAug(ornamentationAugtype)->GetItem()->IDFile[2]);
}
else if (item->GetOrnamentationIcon() && item->GetOrnamentationIDFile()) {
idfile = item->GetOrnamentationIDFile();
}
else {
idfile = atoi(&item->GetItem()->IDFile[2]);
}

View File

@ -1889,6 +1889,9 @@ void Client::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho)
if (strlen(item->IDFile) > 2)
ns->spawn.equipment[MaterialPrimary] = atoi(&item->IDFile[2]);
}
else if (inst->GetOrnamentationIcon() && inst->GetOrnamentationIDFile()) {
ns->spawn.equipment[MaterialPrimary] = inst->GetOrnamentationIDFile();
}
else {
item = inst->GetItem();
if (strlen(item->IDFile) > 2)
@ -1901,6 +1904,9 @@ void Client::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho)
if (strlen(item->IDFile) > 2)
ns->spawn.equipment[MaterialSecondary] = atoi(&item->IDFile[2]);
}
else if (inst->GetOrnamentationIcon() && inst->GetOrnamentationIDFile()) {
ns->spawn.equipment[MaterialSecondary] = inst->GetOrnamentationIDFile();
}
else {
item = inst->GetItem();
if (strlen(item->IDFile) > 2)
@ -2766,6 +2772,9 @@ void Client::SetMaterial(int16 in_slot, uint32 item_id) {
item = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem();
m_pp.item_material[MaterialPrimary] = atoi(item->IDFile + 2);
}
else if (inst && inst->GetOrnamentationIcon() && inst->GetOrnamentationIDFile()) {
m_pp.item_material[MaterialPrimary] = inst->GetOrnamentationIDFile();
}
else {
m_pp.item_material[MaterialPrimary] = atoi(item->IDFile + 2);
}
@ -2776,6 +2785,9 @@ void Client::SetMaterial(int16 in_slot, uint32 item_id) {
item = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem();
m_pp.item_material[MaterialSecondary] = atoi(item->IDFile + 2);
}
else if (inst && inst->GetOrnamentationIcon() && inst->GetOrnamentationIDFile()) {
m_pp.item_material[MaterialSecondary] = inst->GetOrnamentationIDFile();
}
else {
m_pp.item_material[MaterialSecondary] = atoi(item->IDFile + 2);
}
@ -5832,7 +5844,11 @@ void Client::ProcessInspectRequest(Client* requestee, Client* requester) {
const Item_Struct *aug_weap = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem();
strcpy(insr->itemnames[L], item->Name);
insr->itemicons[L] = aug_weap->Icon;
}
}
else if (inst->GetOrnamentationIcon() && inst->GetOrnamentationIDFile()) {
strcpy(insr->itemnames[L], item->Name);
insr->itemicons[L] = inst->GetOrnamentationIcon();
}
else {
strcpy(insr->itemnames[L], item->Name);
insr->itemicons[L] = item->Icon;

View File

@ -810,7 +810,7 @@ public:
void QSSwapItemAuditor(MoveItem_Struct* move_in, bool postaction_call = false);
void PutLootInInventory(int16 slot_id, const ItemInst &inst, ServerLootItem_Struct** bag_item_data = 0);
bool AutoPutLootInInventory(ItemInst& inst, bool try_worn = false, bool try_cursor = true, ServerLootItem_Struct** bag_item_data = 0);
bool SummonItem(uint32 item_id, int16 charges = -1, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, bool attuned = false, uint16 to_slot = MainCursor);
bool SummonItem(uint32 item_id, int16 charges = -1, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, bool attuned = false, uint16 to_slot = MainCursor, uint32 ornament_icon = 0, uint32 ornament_idfile = 0);
void SetStats(uint8 type,int16 set_val);
void IncStats(uint8 type,int16 increase_val);
void DropItem(int16 slot_id);

View File

@ -8031,6 +8031,10 @@ void Client::Handle_OP_InspectAnswer(const EQApplicationPacket *app)
strcpy(insr->itemnames[L], item->Name);
insr->itemicons[L] = aug_weap->Icon;
}
else if (inst->GetOrnamentationIcon() && inst->GetOrnamentationIDFile()) {
strcpy(insr->itemnames[L], item->Name);
insr->itemicons[L] = inst->GetOrnamentationIcon();
}
else {
strcpy(insr->itemnames[L], item->Name);
insr->itemicons[L] = item->Icon;

View File

@ -199,7 +199,7 @@ bool Client::CheckLoreConflict(const Item_Struct* item) {
return (m_inv.HasItemByLoreGroup(item->LoreGroup, ~invWhereSharedBank) != INVALID_INDEX);
}
bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, bool attuned, uint16 to_slot) {
bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, bool attuned, uint16 to_slot, uint32 ornament_icon, uint32 ornament_idfile) {
this->EVENT_ITEM_ScriptStopReturn();
// TODO: update calling methods and script apis to handle a failure return
@ -557,6 +557,11 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2,
// attune item
if(attuned && inst->GetItem()->Attuneable)
inst->SetInstNoDrop(true);
if(ornament_icon > 0 && ornament_idfile > 0) {
inst->SetOrnamentIcon(ornament_icon);
inst->SetOrnamentationIDFile(ornament_idfile);
}
// check to see if item is usable in requested slot
if(enforceusable && (((to_slot >= MainCharm) && (to_slot <= MainAmmo)) || (to_slot == MainPowerSource))) {

View File

@ -2455,6 +2455,9 @@ int32 Mob::GetEquipmentMaterial(uint8 material_slot) const
item = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem();
return atoi(&item->IDFile[2]);
}
else if (inst->GetOrnamentationIcon() && inst->GetOrnamentationIDFile()) {
return inst->GetOrnamentationIDFile();
}
else {
if (strlen(item->IDFile) > 2)
return atoi(&item->IDFile[2]);

View File

@ -296,6 +296,8 @@
#define GUILD_BANK_FULL 6098 // There is no more room in the Guild Bank.
#define GUILD_BANK_TRANSFERRED 6100 // '%1' transferred to Guild Bank from Deposits.
#define GUILD_BANK_EMPTY_HANDS 6108 // You must empty your hands to withdraw from the Guild Bank.
#define TRANSFORM_FAILED 6326 //This mold cannot be applied to your %1.
#define TRANSFORM_COMPLETE 6327 //You have successfully transformed your %1.
#define GENERIC_STRING 6688 //%1 (used to any basic message)
#define SENTINEL_TRIG_YOU 6724 //You have triggered your sentinel.
#define SENTINEL_TRIG_OTHER 6725 //%1 has triggered your sentinel.

View File

@ -283,6 +283,26 @@ void Object::HandleCombine(Client* user, const NewCombine_Struct* in_combine, Ob
}
container = inst;
if (container->GetItem()->BagType == BagTypeTransformationmold) {
const ItemInst* inst = container->GetItem(0);
bool AllowAll = RuleB(Inventory, AllowAnyWeaponTransformation);
if (inst && ItemInst::CanTransform(inst->GetItem(), container->GetItem(), AllowAll)) {
const Item_Struct* new_weapon = inst->GetItem();
user->DeleteItemInInventory(Inventory::CalcSlotId(in_combine->container_slot, 0), 0, true);
container->Clear();
user->SummonItem(new_weapon->ID, inst->GetCharges(), inst->GetAugmentItemID(0), inst->GetAugmentItemID(1), inst->GetAugmentItemID(2), inst->GetAugmentItemID(3), inst->GetAugmentItemID(4), inst->IsInstNoDrop(), MainCursor, container->GetItem()->Icon, atoi(container->GetItem()->IDFile + 2));
user->Message_StringID(4, TRANSFORM_COMPLETE, inst->GetItem()->Name);
if (RuleB(Inventory, DeleteTransformationMold))
user->DeleteItemInInventory(in_combine->container_slot, 0, true);
}
else if (inst) {
user->Message_StringID(4, TRANSFORM_FAILED, inst->GetItem()->Name);
}
EQApplicationPacket* outapp = new EQApplicationPacket(OP_TradeSkillCombine, 0);
user->QueuePacket(outapp);
safe_delete(outapp);
return;
}
DBTradeskillRecipe_Struct spec;
if (!database.GetTradeRecipe(container, c_type, some_id, user->CharacterID(), &spec)) {