diff --git a/changelog.txt b/changelog.txt index 30cdf9ba7..2dca36203 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,9 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 03/29/2015 == +Secrets: Identified the Target Ring fields for RoF/RoF2. +Secrets: Added a perl accessor for the last target ring position received from the client. Usage: $client->GetTargetRingX(), $client->GetTargetRingY(), $client->GetTargetRingZ() + == 03/12/2015 == Akkadius: [eqemu_update.pl V7] Add Option 9) LUA Modules - Download latest LUA Modules (Required for Lua) diff --git a/common/patches/rof.cpp b/common/patches/rof.cpp index 0495935b1..81865d12b 100644 --- a/common/patches/rof.cpp +++ b/common/patches/rof.cpp @@ -4236,6 +4236,10 @@ namespace RoF //IN(inventoryslot); IN(target_id); + IN(y_pos); + IN(x_pos); + IN(z_pos); + FINISH_DIRECT_DECODE(); } diff --git a/common/patches/rof2.cpp b/common/patches/rof2.cpp index 9e0bd9c8a..f51ee685c 100644 --- a/common/patches/rof2.cpp +++ b/common/patches/rof2.cpp @@ -4380,6 +4380,9 @@ namespace RoF2 emu->inventoryslot = RoF2ToServerSlot(eq->inventoryslot); //IN(inventoryslot); IN(target_id); + IN(y_pos); + IN(x_pos); + IN(z_pos); FINISH_DIRECT_DECODE(); } diff --git a/common/patches/rof2_structs.h b/common/patches/rof2_structs.h index 79da918b9..033e0ed9a 100644 --- a/common/patches/rof2_structs.h +++ b/common/patches/rof2_structs.h @@ -658,7 +658,10 @@ struct CastSpell_Struct /*04*/ uint32 spell_id; /*08*/ ItemSlotStruct inventoryslot; // slot for clicky item, Seen unknown of 131 = normal cast /*20*/ uint32 target_id; -/*24*/ uint32 cs_unknown[5]; +/*24*/ uint32 cs_unknown[2]; +/*32*/ float y_pos; +/*36*/ float x_pos; +/*40*/ float z_pos; /*44*/ }; diff --git a/common/patches/rof_structs.h b/common/patches/rof_structs.h index a623c7cf4..456c7b1a9 100644 --- a/common/patches/rof_structs.h +++ b/common/patches/rof_structs.h @@ -647,7 +647,10 @@ struct CastSpell_Struct /*04*/ uint32 spell_id; /*08*/ ItemSlotStruct inventoryslot; // slot for clicky item, Seen unknown of 131 = normal cast /*20*/ uint32 target_id; -/*24*/ uint32 cs_unknown[5]; +/*24*/ uint32 cs_unknown[2]; +/*32*/ float y_pos; +/*36*/ float x_pos; +/*40*/ float z_pos; /*44*/ }; diff --git a/zone/beacon.cpp b/zone/beacon.cpp index 5a952dc9d..0df02b201 100644 --- a/zone/beacon.cpp +++ b/zone/beacon.cpp @@ -54,7 +54,7 @@ Beacon::Beacon(Mob *at_mob, int lifetime) :Mob ( nullptr, nullptr, 0, 0, 0, INVISIBLE_MAN, 0, BT_NoTarget, 0, 0, 0, 0, 0, at_mob->GetPosition(), 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ), remove_timer(lifetime), spell_timer(0) diff --git a/zone/client.cpp b/zone/client.cpp index 3d0a8d75a..677884171 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -107,8 +107,12 @@ Client::Client(EQStreamInterface* ieqs) 0, 0, // qglobal 0, // maxlevel - 0 // scalerate - + 0, // scalerate + 0, + 0, + 0, + 0, + 0 ), //these must be listed in the order they appear in client.h position_timer(250), diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 21ab1c7cf..07e9876ca 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -2604,7 +2604,7 @@ void Client::Handle_OP_AltCurrencyReclaim(const EQApplicationPacket *app) ++iter; } - if (item_id == 0 || reclaim->count == 0) { + if (item_id == 0) { return; } @@ -2624,6 +2624,9 @@ void Client::Handle_OP_AltCurrencyReclaim(const EQApplicationPacket *app) /* Cursor to Item storage */ else { uint32 max_currency = GetAlternateCurrencyValue(reclaim->currency_id); + + if(max_currency == 0 || reclaim->count == 0) + return; /* If you input more than you have currency wise, just give the max of the currency you currently have */ if (reclaim->count > max_currency) { diff --git a/zone/corpse.cpp b/zone/corpse.cpp index 551f49a1b..fad65aa3a 100644 --- a/zone/corpse.cpp +++ b/zone/corpse.cpp @@ -152,7 +152,7 @@ Corpse::Corpse(NPC* in_npc, ItemList* in_itemlist, uint32 in_npctypeid, const NP in_npc->GetDeity(),in_npc->GetLevel(),in_npc->GetNPCTypeID(),in_npc->GetSize(),0, in_npc->GetPosition(), in_npc->GetInnateLightType(), in_npc->GetTexture(),in_npc->GetHelmTexture(), 0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0xff,0,0,0,0,0,0,0,0,0), + 0,0,0,0,0,0,0,0,0,0,0,0xff,0,0,0,0,0,0,0,0,0,0,0,0,0,0), corpse_decay_timer(in_decaytime), corpse_rez_timer(0), corpse_delay_timer(RuleI(NPC, CorpseUnlockTimer)), @@ -253,7 +253,12 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob ( 0, // int32 in_mana_regen, 0, // uint8 in_qglobal, 0, // uint8 in_maxlevel, - 0 // uint32 in_scalerate + 0, // uint32 in_scalerate + 0, // uint8 in_armtexture, + 0, // uint8 in_bracertexture, + 0, // uint8 in_handtexture, + 0, // uint8 in_legtexture, + 0 // uint8 in_feettexture, ), corpse_decay_timer(RuleI(Character, CorpseDecayTimeMS)), corpse_rez_timer(RuleI(Character, CorpseResTimeMS)), @@ -478,6 +483,11 @@ in_helmtexture, 0, 0, 0, +0, +0, +0, +0, +0, 0), corpse_decay_timer(RuleI(Character, CorpseDecayTimeMS)), corpse_rez_timer(RuleI(Character, CorpseResTimeMS)), diff --git a/zone/mob.cpp b/zone/mob.cpp index f21ed3d6e..9e9bcbd5d 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -83,7 +83,12 @@ Mob::Mob(const char* in_name, int32 in_mana_regen, uint8 in_qglobal, uint8 in_maxlevel, - uint32 in_scalerate + uint32 in_scalerate, + uint8 in_armtexture, + uint8 in_bracertexture, + uint8 in_handtexture, + uint8 in_legtexture, + uint8 in_feettexture ) : attack_timer(2000), attack_dw_timer(2000), @@ -158,6 +163,13 @@ Mob::Mob(const char* in_name, texture = in_texture; helmtexture = in_helmtexture; + armtexture = in_armtexture; + bracertexture = in_bracertexture; + handtexture = in_handtexture; + legtexture = in_legtexture; + feettexture = in_feettexture; + multitexture = (armtexture || bracertexture || handtexture || legtexture || feettexture); + haircolor = in_haircolor; beardcolor = in_beardcolor; eyecolor1 = in_eyecolor1; @@ -930,7 +942,7 @@ void Mob::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) ns->spawn.drakkin_heritage = drakkin_heritage; ns->spawn.drakkin_tattoo = drakkin_tattoo; ns->spawn.drakkin_details = drakkin_details; - ns->spawn.equip_chest2 = GetHerosForgeModel(1) != 0 ? 0xff : texture; + ns->spawn.equip_chest2 = GetHerosForgeModel(1) != 0 || multitexture? 0xff : texture; // ns->spawn.invis2 = 0xff;//this used to be labeled beard.. if its not FF it will turn mob invis diff --git a/zone/mob.h b/zone/mob.h index f35857823..22f9cb5f1 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -112,7 +112,12 @@ public: int32 in_mana_regen, uint8 in_qglobal, uint8 in_maxlevel, - uint32 in_scalerate + uint32 in_scalerate, + uint8 in_armtexture, + uint8 in_bracertexture, + uint8 in_handtexture, + uint8 in_legtexture, + uint8 in_feettexture ); virtual ~Mob(); @@ -971,6 +976,12 @@ protected: uint16 entity_id_being_looted; //the id of the entity being looted, 0 if not looting. uint8 texture; uint8 helmtexture; + uint8 armtexture; + uint8 bracertexture; + uint8 handtexture; + uint8 legtexture; + uint8 feettexture; + bool multitexture; int AC; int32 ATK; diff --git a/zone/npc.cpp b/zone/npc.cpp index 22fb5f188..4e69657cd 100644 --- a/zone/npc.cpp +++ b/zone/npc.cpp @@ -103,7 +103,12 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, const glm::vec4& position, int if d->mana_regen, d->qglobal, d->maxlevel, - d->scalerate ), + d->scalerate, + d->armtexture, + d->bracertexture, + d->handtexture, + d->legtexture, + d->feettexture), attacked_timer(CombatEventTimer_expire), swarm_timer(100), classattack_timer(1000), @@ -1308,6 +1313,16 @@ int32 NPC::GetEquipmentMaterial(uint8 material_slot) const return helmtexture; case MaterialChest: return texture; + case MaterialArms: + return armtexture; + case MaterialWrist: + return bracertexture; + case MaterialHands: + return handtexture; + case MaterialLegs: + return legtexture; + case MaterialFeet: + return feettexture; case MaterialPrimary: return d_melee_texture1; case MaterialSecondary: diff --git a/zone/perl_client.cpp b/zone/perl_client.cpp index d399d7665..a885922e9 100644 --- a/zone/perl_client.cpp +++ b/zone/perl_client.cpp @@ -6110,6 +6110,84 @@ XS(XS_Client_SendSpellAnim) XSRETURN_EMPTY; } +XS(XS_Client_GetTargetRingX); /* prototype to pass -Wmissing-prototypes */ +XS(XS_Client_GetTargetRingX) +{ + dXSARGS; + if (items != 1) + Perl_croak(aTHX_ "Usage: Client::GetTargetRingX(THIS)"); + { + Client * THIS; + float RETVAL; + dXSTARG; + + if (sv_derived_from(ST(0), "Client")) { + IV tmp = SvIV((SV*)SvRV(ST(0))); + THIS = INT2PTR(Client *,tmp); + } + else + Perl_croak(aTHX_ "THIS is not of type Client"); + if(THIS == nullptr) + Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); + + RETVAL = THIS->GetTargetRingX(); + XSprePUSH; PUSHn((double)RETVAL); + } + XSRETURN(1); +} + +XS(XS_Client_GetTargetRingY); /* prototype to pass -Wmissing-prototypes */ +XS(XS_Client_GetTargetRingY) +{ + dXSARGS; + if (items != 1) + Perl_croak(aTHX_ "Usage: Client::GetTargetRingY(THIS)"); + { + Client * THIS; + float RETVAL; + dXSTARG; + + if (sv_derived_from(ST(0), "Client")) { + IV tmp = SvIV((SV*)SvRV(ST(0))); + THIS = INT2PTR(Client *,tmp); + } + else + Perl_croak(aTHX_ "THIS is not of type Client"); + if(THIS == nullptr) + Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); + + RETVAL = THIS->GetTargetRingY(); + XSprePUSH; PUSHn((double)RETVAL); + } + XSRETURN(1); +} + +XS(XS_Client_GetTargetRingZ); /* prototype to pass -Wmissing-prototypes */ +XS(XS_Client_GetTargetRingZ) +{ + dXSARGS; + if (items != 1) + Perl_croak(aTHX_ "Usage: Client::GetTargetRingZ(THIS)"); + { + Client * THIS; + float RETVAL; + dXSTARG; + + if (sv_derived_from(ST(0), "Client")) { + IV tmp = SvIV((SV*)SvRV(ST(0))); + THIS = INT2PTR(Client *,tmp); + } + else + Perl_croak(aTHX_ "THIS is not of type Client"); + if(THIS == nullptr) + Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); + + RETVAL = THIS->GetTargetRingZ(); + XSprePUSH; PUSHn((double)RETVAL); + } + XSRETURN(1); +} + #ifdef __cplusplus extern "C" #endif @@ -6351,6 +6429,9 @@ XS(boot_Client) newXSproto(strcpy(buf, "SendMarqueeMessage"), XS_Client_SendMarqueeMessage, file, "$$$$$$$"); newXSproto(strcpy(buf, "SendColoredText"), XS_Client_SendColoredText, file, "$$$"); newXSproto(strcpy(buf, "SendSpellAnim"), XS_Client_SendSpellAnim, file, "$$$"); + newXSproto(strcpy(buf, "GetTargetRingX"), XS_Client_GetTargetRingX, file, "$$"); + newXSproto(strcpy(buf, "GetTargetRingY"), XS_Client_GetTargetRingY, file, "$$"); + newXSproto(strcpy(buf, "GetTargetRingZ"), XS_Client_GetTargetRingZ, file, "$$"); XSRETURN_YES; } diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index 21ba36e0a..b159fbabc 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -5253,7 +5253,7 @@ uint16 Client::GetSympatheticFocusEffect(focusType type, uint16 spell_id) { if (IsValidSpell(proc_spellid)){ - ProcChance = GetSympatheticProcChances(spell_id, GetSympatheticSpellProcRate(spell_id)); + ProcChance = GetSympatheticProcChances(spell_id, GetSympatheticSpellProcRate(proc_spellid)); if(zone->random.Roll(ProcChance)) SympatheticProcList.push_back(proc_spellid); } diff --git a/zone/trading.cpp b/zone/trading.cpp index b6c869b61..df8d159b1 100644 --- a/zone/trading.cpp +++ b/zone/trading.cpp @@ -1626,23 +1626,10 @@ void Client::BuyTraderItem(TraderBuy_Struct* tbs, Client* Trader, const EQApplic return; } - ReturnTraderReq(app, outtbs->Quantity, ItemID); - - outtbs->TraderID = this->GetID(); - outtbs->Action = BazaarBuyItem; - strn0cpy(outtbs->ItemName, BuyItem->GetItem()->Name, 64); - - int TraderSlot = 0; - - if(BuyItem->IsStackable()) - SendTraderItem(BuyItem->GetItem()->ID, outtbs->Quantity); - else - SendTraderItem(BuyItem->GetItem()->ID, BuyItem->GetCharges()); - // This cannot overflow assuming MAX_TRANSACTION_VALUE, checked above, is the default of 2000000000 uint32 TotalCost = tbs->Price * outtbs->Quantity; - if (Trader->GetClientVersion() >= ClientVersion::RoF) + if(Trader->GetClientVersion() >= ClientVersion::RoF) { // RoF+ uses individual item price where older clients use total price outtbs->Price = tbs->Price; @@ -1673,6 +1660,19 @@ void Client::BuyTraderItem(TraderBuy_Struct* tbs, Client* Trader, const EQApplic Log.Out(Logs::Detail, Logs::Trading, "Trader Received: %d Platinum, %d Gold, %d Silver, %d Copper", platinum, gold, silver, copper); + ReturnTraderReq(app, outtbs->Quantity, ItemID); + + outtbs->TraderID = this->GetID(); + outtbs->Action = BazaarBuyItem; + strn0cpy(outtbs->ItemName, BuyItem->GetItem()->Name, 64); + + int TraderSlot = 0; + + if(BuyItem->IsStackable()) + SendTraderItem(BuyItem->GetItem()->ID, outtbs->Quantity); + else + SendTraderItem(BuyItem->GetItem()->ID, BuyItem->GetCharges()); + TraderSlot = Trader->FindTraderItem(tbs->ItemID, outtbs->Quantity); if(RuleB(Bazaar, AuditTrail)) diff --git a/zone/zonedb.cpp b/zone/zonedb.cpp index 685fbd3ca..1fab4aff2 100644 --- a/zone/zonedb.cpp +++ b/zone/zonedb.cpp @@ -1904,7 +1904,12 @@ const NPCType* ZoneDatabase::LoadNPCTypesData(uint32 npc_type_id, bool bulk_load "npc_types.no_target_hotkey, " "npc_types.raid_target, " "npc_types.attack_delay, " - "npc_types.light " + "npc_types.light, " + "npc_types.armtexture, " + "npc_types.bracertexture, " + "npc_types.handtexture, " + "npc_types.legtexture, " + "npc_types.feettexture " "FROM npc_types %s", where_condition.c_str() ); @@ -2074,6 +2079,12 @@ const NPCType* ZoneDatabase::LoadNPCTypesData(uint32 npc_type_id, bool bulk_load temp_npctype_data->attack_delay = atoi(row[90]); temp_npctype_data->light = (atoi(row[91]) & 0x0F); + temp_npctype_data->armtexture = atoi(row[92]); + temp_npctype_data->bracertexture = atoi(row[93]); + temp_npctype_data->handtexture = atoi(row[94]); + temp_npctype_data->legtexture = atoi(row[95]); + temp_npctype_data->feettexture = atoi(row[96]); + // If NPC with duplicate NPC id already in table, // free item we attempted to add. if (zone->npctable.find(temp_npctype_data->npc_id) != zone->npctable.end()) { diff --git a/zone/zonedump.h b/zone/zonedump.h index dc13300e3..e69692339 100644 --- a/zone/zonedump.h +++ b/zone/zonedump.h @@ -127,6 +127,11 @@ struct NPCType bool no_target_hotkey; bool raid_target; uint8 probability; + uint8 armtexture; + uint8 bracertexture; + uint8 handtexture; + uint8 legtexture; + uint8 feettexture; }; namespace player_lootitem {