PDA

View Full Version : Mercenaries


Pages : [1] 2

trevius
04-02-2012, 07:56 AM
Since EQ is now F2P, I spent some time collecting data from Live for Mercenaries. There does not seem to be too many packets related to Mercs. Below is what I have figured out for mercenary packet structures. Hopefully I can get time to test some of this and maybe implement some basic handling for these packets, but I figured it would be good to post in case I don't get time to do that soon.

Mercenary Packet Structures:


// Currently unused, but may be good to have
enum MercStance
{
MercPassive = 1,
MercBalanced = 2,
MercEfficient = 3,
MercReactive = 4,
MercAggressive = 5,
MercAssist = 6,
MercBurn = 7,
MercEfficient = 8,
MercBurnAE = 9
};

// [OPCode: 0x27ac] On Live as of April 2 2012 [Server->Client]
struct MercenarySellList_Struct {
int32 MercTypeCount; // Seen 2 - Iterations of MercCategory_Struct
MercCategory_Struct Categories[0]; // From dbstr_us.txt - Apprentice (330000100), Journeyman (330000200), Master (330000300)
int32 MercCount; // Seen 24 - Iterations of MercCategory_Struct
MercenaryInfo_Struct Mercs[0]; // Data for individual mercenaries in the Merchant List
};

struct MercCategory_Struct {
int32 Category; // From dbstr_us.txt - Apprentice (330000100), Journeyman (330000200), Master (330000300)
};

// Used for Mercenary Merchant Lists and for Hired Mercenary Info Updates
struct MercenaryInfo_Struct {
int32 MercID; // ID unique to each type of mercenary (probably a DB id) - (if 1, do not send MercData_Struct - No merc hired)
MercData_Struct MercData[0]; // Data for individual mercenaries - Not populated if no merc is hired
};

struct MercData_Struct {
/*0000*/ int32 MercType; // From dbstr_us.txt - Apprentice (330000100), Journeyman (330000200), Master (330000300)
/*0004*/ int32 MercDesc; // From dbstr_us.txt - 330020105^23^Race: Guktan<br>Type: Healer<br>Confidence: High<br>Proficiency: Apprentice, Tier V...
/*0008*/ int32 PurchaseCost; // Purchase Cost (in gold)
/*0012*/ int32 UpkeepCost; // Upkeep Cost (in gold)
/*0016*/ int32 Status; // Required Account Status (Free = 0, Silver = 1, Gold = 2) at merchants - Seen 0 (suspended) or 1 (unsuspended) on hired mercs ?
/*0020*/ int32 AltCurrencyCost; // Alternate Currency Purchase Cost? (all seen costs show N/A Bayle Mark) - Seen 0
/*0024*/ int32 AltCurrencyUpkeep; // Alternate Currency Upkeep Cost? (all seen costs show 1 Bayle Mark) - Seen 1
/*0028*/ int32 AltCurrencyType; // Alternate Currency Type? - 19^17^Bayle Mark^0 - Seen 19
/*0032*/ int8 MercUnk01; // Unknown (always see 0)
/*0036*/ sint32 TimeLeft; // Unknown (always see -1 at merchant) - Seen 900000 (15 minutes in ms for newly hired merc)
/*0040*/ int32 MerchantSlot; // Merchant Slot? Increments, but not always by 1 - May be for Merc Window Options (Seen 5, 36, 1 for active mercs)?
/*0044*/ int32 MercUnk02; // Unknown (always see 1)
/*0048*/ int32 StanceCount; // Iterations of MercStance_Struct - Normally 2 to 4 seen
/*0052*/ int32 MercUnk03; // Unknown (always 0 at merchant) - Seen on active merc: 93 a4 03 77, b8 ed 2f 26, 88 d5 8b c3, and 93 a4 ad 77
/*0056*/ int8 MercUnk04; // Seen 1
/*0060*/ char[0] MercName; // Null Terminated Mercenary Name (00 at merchants)
/*0000*/ MercStance_Struct Stances[0]; // From dbstr_us.txt - 1^24^Passive^0, 2^24^Balanced^0, etc (1 to 9 as of April 2012)
};

// There appears to be extra data sent in this part of the struct sometimes that is unknown (normally 0, 1, or 2)
struct MercStance_Struct {
int32 Stance; // From dbstr_us.txt - 1^24^Passive^0, 2^24^Balanced^0, etc (1 to 9 as of April 2012)
};

// [OPCode: 0x6537] On Live as of April 2 2012 [Server->Client]
// Size 12 and sent on Zone-In if no mercenary is currently hired and when merc is dismissed
// Size varies if mercenary is hired or if browsing Mercenary Merchant
struct MercDataUpdate_Struct {
/*0000*/ sint32 MercStatus; // Seen 0 with merc and -1 with no merc hired
/*0004*/ int32 HiredCount; // Seen 1 with 1 merc hired and 0 with no merc hired
/*0008*/ MercenaryInfo_Struct MercData[0]; // Data for individual mercenaries in the Merchant List
};

// [OPCode: 0x495d] On Live as of April 2 2012 [Server->Client] [Size: 20]
// Sent on Zone-In, or after Dismissing, Suspending or Unsuspending Mercs
struct MercenaryUpdate_Struct {
/*0000*/ int32 MercEntityID; // Seen 0 (no merc spawned) or 615843841 and 22779137
/*0004*/ int32 UpdateInterval; // Seen 900000 - Matches from 0x6537 packet (15 minutes in ms?)
/*0008*/ int32 MercUnk01; // Seen 180000 - 3 minutes in milleseconds?
/*0012*/ int32 MercState; // Seen 5 (normal) or 1 (suspended)
/*0016*/ int32 SuspendedTime; // Seen 0 (not suspended) or c9 c2 64 4f (suspended on Sat Mar 17 11:58:49 2012) - Unix Timestamp
/*0020*/
};

// [OPCode: 0x1a79] On Live as of April 2 2012 [Client->Server] [Size: 1] - Requesting to suspend or unsuspend merc
struct SuspendMercenary_Struct {
/*0000*/ int8 SuspendMerc; // Seen 30 (48) for suspending or unsuspending
/*0001*/
};

// [OPCode: 0x2528] On Live as of April 2 2012 [Server->Client] [Size: 4] - Response to suspend merc with timestamp
struct SuspendMercenary_Struct {
/*0000*/ int32 SuspendTime; // Unix Timestamp - Seen a9 11 78 4f
/*0004*/
};

// MercCommand field is possibly related to MerchantSlot field in MercData_Struct (seen same values)
// [OPCode: 0x4c6c] On Live as of April 2 2012 [Client->Server] [Size: 8] - Response to suspend merc with timestamp
struct MercCommand_Struct {
/*0000*/ int32 MercCommand; // Seen 0 (zone in with no merc or suspended), 1 (dismiss merc), 5 (normal state), 36 (zone in with merc)
/*0004*/ int32 Option; // Seen -1 (zone in with no merc), 0 (setting to passive stance), 1 (normal or setting to balanced stance)
/*0008*/
};


These are the opcodes that appear to be directly Mercenary related:

0x6537 Server->Client - Some kinda merc info update. Much smaller with no merc
0x0327 Client->Server - Labelled OP_MercenaryDataResponse in EQExtractor2 (size 0)
0x2ef8 Client->Server - Request dismiss merc (size 0)
0x495d Server->Client - Some merc status update from server - Maybe response to 0x4c6c
0x1a79 Client->Server - Requesting to suspend merc
0x2528 Server->Client - Response to suspend merc
0x4c6c Client->Server - Some kind of merc status change request from client - Examples:
24 00 00 00 01 00 00 00 - Zoning in
01 00 00 00 01 00 00 00 - Dismiss merc
05 00 00 00 01 00 00 00 - Right after purchasing merc
05 00 00 00 00 00 00 00 - Setting merc to passive
05 00 00 00 01 00 00 00 - Setting merc back to balanced
00 00 00 00 ff ff ff ff - Zoning in with no merc
01 00 00 00 01 00 00 00 - Right after previous update of zoning in with no merc

Using Mercenary Merchant:

0x4dd9 Client->Server - Right clicking merchant request
0x27ac Server->Client - Merc merchant response
0x3887 Server->Client - After merchant response
0x5e78 Client->Server - Request to view merc info while browsing merchant?
90 01 00 00 01 00 00 00 46 22 00 00 00 6e e4 03
0x5e78 Server->Client - Server response to 0x5e78
06 00 00 00
0x528f Server->Client - Seen after purchasing merc and when camping
0x6942 Server->Client - Response after purchasing merc - Purchase approval response?

I have a ton more data than I am showing here, but I don't want to post it all until I can organize it a bit more. I will post the rest of the structs for the above lists when I have time. At least the more complex structs should be in pretty good shape from the ones I posted above. The rest are all really small (16 bytes or less).

Secrets
04-02-2012, 10:29 PM
*snip*

This is actually going to help me a lot, I had mercenaries figured out to the point where I could actually have the window up, but I wasn't going off of live packet collects. I'll look into finding out what some of those unknowns are for you.

bad_captain
04-02-2012, 10:53 PM
Trev, I have a lot of this worked out for SoD and UF, with the help of Derision. We are able to display the info in the merc merchant's window, and can spawn an npc that uses the merc window, changing stances, etc. I spent a lot of time getting all of the data (I generated quite a few hundred inserts for a basic db structure for mercs for types, subtypes, stances, handling different clients, and started on inventory and spells) for the freely available mercs before free to play which further restricted to just apprentice mercs (was apprentice t1-5 and journeymen 1-2).

If you plan on working on mercs, I can send all of it to you, or if you are just getting the info out there, I can use anything you have. I was trying to get to mercs within a few weeks. I've been really busy lately though.

Things have changed recently with the ability to have multiple mercs and such, but the basics should still be the same. I am on live trying to lvl up my toons to have a full group with mercs so I can continue to get spells cast as well as screenshots of equipment, etc. Let me know if there's anything you need.

trevius
04-03-2012, 12:51 AM
Most of the data I have is related to what I already posted. Just the basic purchasing and usage packets and structs from Live. It sounds like you guys are a lot further along than I am lol. I only really worked on it for 1 day though. I didn't know anyone else was working on it. With your recent implementation of stances, I figured it would make it that much easier to add in a merc system.

I am a bit interested in the DB work you have done for them. I didn't think it would take hundreds of entries for it. I was figuring on 1 entry per merc subtype in a new merc table that just points to an NPC ID in the npc_types table. I haven't really played Live since 2005 until now (since it went free), so I am still really new to mercs. I guess there would be a lot of variations for merc races, and multiple types and subtypes.

I am not really too concerned with the DB entries, as I would probably just add somewhat customized entries anyway. I was more looking to get some basic functionality implemented that could be built upon. It sounds like you guys have already made it that far and are working on finishing stuff off.

I am no where near as skilled as Derision or you when it comes to that type of thing, so I will leave it up to the 2 of you :)

Maybe I can help you guys out if there is something you still need done. I am better with dissecting packets than I am with coding normally. I have quite a few characters in the 50 to 67 range, if there is something I can get with them that would be useful.

I can post the rest of the smaller structs later tonight (I still have to make them) if they would be useful. I also plan to write a script to help with opcode work a bit hopefully.

You should join the dev IRC channel. It might be easier to discuss and share info there. PM me if you don't know the channel name.

trevius
09-20-2012, 06:39 AM
Bad_captain, did you ever get anywhere with this? I am curious how close this was to being functional. Even if it is only partly functional, it might be good to get it on the SVN so the rest can be completed as time permits. I could probably put some more work in on it, but didn't want to double any efforts that have already been made.

Noport
09-20-2012, 08:06 AM
i'll post the newer opcodes real soon

Listing of hired mercenaries
OP_MercenaryList=0x5a0a

bad_captain
09-21-2012, 12:53 AM
Sorry I dropped the ball on this one. I have meant to get back to this, but keep finding stuff to fix in bots, and with school just starting back up, I've been pretty busy. I'm in the middle of a bot AA rewrite, then I plan on getting back to this. I know I was slowed down working on all of the packet encoding/decoding, which I know you are adept at. If I can't get something going by next weekend (hopefully I will have time to at least get it somewhat respectable), I'll shoot you a diff or something.

I have been trying to level up on live to get some better logs/collects, but it's been slow going. I've been getting screenshots though, as weapons appear to change every 5 levels (not that I think we can get all equipment correct, but it's at least a start).

Noport
09-21-2012, 04:34 AM
Bad_captain go grab my post of newer opcode and please update as needed thank you.
http://www.eqemulator.org/forums/showthread.php?t=35640&page=2

trevius
10-12-2012, 06:15 AM
I went through and refined, corrected, and added to the previous list of Mercenary related packet structures that I had posted. Each includes the opcode used on Live as well as the opcode name used on EQEmu currently where I could find them. I added notes for each struct to explain the packet a bit.

This should compile find on windows now, and should work for the initial changes to get mercs to be purchaseable and spawning at least. These structs are the ones used on Live as of April 12 2012, so these would go in eq_packet_structs.h. I will go through the SoD and UF clients and add the structs for those patch files as well in the next post.

Right now, there are still a couple of struct issues remaining due to how the variable sized packets for the Mercenary Data has variable sized arrays within it. To prevent it from breaking anything, I just hard set the variable sized structs that are inside the already variable sized structs. This only effects a few fields, but it is something that will need to be corrected to make these packets work exactly like they do on Live. For example, the MercName, MercTypes,and Stances fields are all hard set to values that should make them functional enough for now, but ideally those should all be able to vary in size. I am not really sure of the best way to do this and still allow the data to be sent to patch .cpp files so they can be encoded accordingly for each client.

// Used by MercenaryListEntry_Struct
struct MercenaryStance_Struct {
/*0000*/ int32 StanceIndex; // Index of this stance (sometimes reverse reverse order - 3, 2, 1, 0 for 4 stances etc)
/*0004*/ int32 Stance; // From dbstr_us.txt - 1^24^Passive^0, 2^24^Balanced^0, etc (1 to 9 as of April 2012)
};

// Used by MercenaryMerchantList_Struct
struct MercenaryListEntry_Struct {
/*0000*/ int32 MercID; // ID unique to each type of mercenary (probably a DB id)
/*0004*/ int32 MercType; // From dbstr_us.txt - Apprentice (330000100), Journeyman (330000200), Master (330000300)
/*0008*/ int32 MercSubType; // From dbstr_us.txt - 330020105^23^Race: Guktan<br>Type: Healer<br>Confidence: High<br>Proficiency: Apprentice, Tier V...
/*0012*/ int32 PurchaseCost; // Purchase Cost (in gold)
/*0016*/ int32 UpkeepCost; // Upkeep Cost (in gold)
/*0020*/ int32 Status; // Required Account Status (Free = 0, Silver = 1, Gold = 2) at merchants - Seen 0 (suspended) or 1 (unsuspended) on hired mercs ?
/*0024*/ int32 AltCurrencyCost; // Alternate Currency Purchase Cost? (all seen costs show N/A Bayle Mark) - Seen 0
/*0028*/ int32 AltCurrencyUpkeep; // Alternate Currency Upkeep Cost? (all seen costs show 1 Bayle Mark) - Seen 1
/*0032*/ int32 AltCurrencyType; // Alternate Currency Type? - 19^17^Bayle Mark^0 - Seen 19
/*0036*/ int8 MercUnk01; // Unknown (always see 0)
/*0037*/ sint32 TimeLeft; // Unknown (always see -1 at merchant) - Seen 900000 (15 minutes in ms for newly hired merc)
/*0041*/ int32 MerchantSlot; // Merchant Slot? Increments, but not always by 1 - May be for Merc Window Options (Seen 5, 36, 1 for active mercs)?
/*0045*/ int32 MercUnk02; // Unknown (normally see 1, but sometimes 2 or 0)
/*0049*/ int32 StanceCount; // Iterations of MercenaryStance_Struct - Normally 2 to 4 seen
/*0053*/ int32 MercUnk03; // Unknown (always 0 at merchant) - Seen on active merc: 93 a4 03 77, b8 ed 2f 26, 88 d5 8b c3, and 93 a4 ad 77
/*0057*/ int8 MercUnk04; // Seen 1
/*0058*/ char MercName[1]; // Null Terminated Mercenary Name (00 at merchants)
/*0000*/ MercenaryStance_Struct Stances[2]; // Count Varies, but hard set to 2 for now - From dbstr_us.txt - 1^24^Passive^0, 2^24^Balanced^0, etc (1 to 9 as of April 2012)
};

// [OPCode: 0x27ac OP_MercenaryDataResponse] On Live as of April 2 2012 [Server->Client]
// Opcode should be renamed to something like OP_MercenaryMerchantShopResponse since the Data Response packet is different
// Sent by the server when browsing the Mercenary Merchant
struct MercenaryMerchantList_Struct {
/*0000*/ int32 MercTypeCount; // Number of Merc Types to follow
/*0004*/ int32 MercTypes[3]; // Count varies, but hard set to 3 for now - From dbstr_us.txt - Apprentice (330000100), Journeyman (330000200), Master (330000300)
/*0016*/ int32 MercCount; // Number of MercenaryInfo_Struct to follow
/*0020*/ MercenaryListEntry_Struct Mercs[0]; // Data for individual mercenaries in the Merchant List
};

// [OPCode: 0x4dd9 OP_MercenaryDataRequest] On Live as of April 2 2012 [Client->Server]
// Opcode should be renamed to something like OP_MercenaryMerchantShopRequest since the Data Request packet is different
// Right clicking merchant - shop request
struct MercenaryMerchantShopRequest_Struct {
/*0000*/ int32 MercMerchantID; // Entity ID of the Mercenary Merchant
/*0004*/
};

// Used by MercenaryDataUpdate_Struct
struct MercenaryData_Struct {
/*0000*/ int32 MercID; // ID unique to each type of mercenary (probably a DB id) - (if 1, do not send MercenaryData_Struct - No merc hired)
/*0004*/ int32 MercType; // From dbstr_us.txt - Apprentice (330000100), Journeyman (330000200), Master (330000300)
/*0008*/ int32 MercSubType; // From dbstr_us.txt - 330020105^23^Race: Guktan<br>Type: Healer<br>Confidence: High<br>Proficiency: Apprentice, Tier V...
/*0012*/ int32 PurchaseCost; // Purchase Cost (in gold)
/*0016*/ int32 UpkeepCost; // Upkeep Cost (in gold)
/*0020*/ int32 Status; // Required Account Status (Free = 0, Silver = 1, Gold = 2) at merchants - Seen 0 (suspended) or 1 (unsuspended) on hired mercs ?
/*0024*/ int32 AltCurrencyCost; // Alternate Currency Purchase Cost? (all seen costs show N/A Bayle Mark) - Seen 0
/*0028*/ int32 AltCurrencyUpkeep; // Alternate Currency Upkeep Cost? (all seen costs show 1 Bayle Mark) - Seen 1
/*0032*/ int32 AltCurrencyType; // Alternate Currency Type? - 19^17^Bayle Mark^0 - Seen 19
/*0036*/ int8 MercUnk01; // Unknown (always see 0)
/*0037*/ sint32 TimeLeft; // Unknown (always see -1 at merchant) - Seen 900000 (15 minutes in ms for newly hired merc)
/*0041*/ int32 MerchantSlot; // Merchant Slot? Increments, but not always by 1 - May be for Merc Window Options (Seen 5, 36, 1 for active mercs)?
/*0045*/ int32 MercUnk02; // Unknown (normally see 1, but sometimes 2 or 0)
/*0049*/ int32 StanceCount; // Iterations of MercenaryStance_Struct - Normally 2 to 4 seen
/*0053*/ int32 MercUnk03; // Unknown (always 0 at merchant) - Seen on active merc: 93 a4 03 77, b8 ed 2f 26, 88 d5 8b c3, and 93 a4 ad 77
/*0057*/ int8 MercUnk04; // Seen 1
/*0058*/ char MercName[1]; // Null Terminated Mercenary Name (00 at merchants)
/*0000*/ MercenaryStance_Struct Stances[2]; // Count Varies, but hard set to 2 for now - From dbstr_us.txt - 1^24^Passive^0, 2^24^Balanced^0, etc (1 to 9 as of April 2012)
/*0000*/ int32 MercUnk05; // Seen 1 - Extra Merc Data field that differs from MercenaryListEntry_Struct
// MercUnk05 may be a field that is at the end of the packet only, even if multiple mercs are listed (haven't seen examples of multiple mercs owned at once)
};

// [OPCode: 0x6537] On Live as of April 2 2012 [Server->Client]
// Should be named OP_MercenaryDataResponse, but the current opcode using that name should be renamed first
// Size varies if mercenary is hired or if browsing Mercenary Merchant
// This may also be the response for Client->Server 0x0327 (size 0) packet On Live as of April 2 2012
struct MercenaryDataUpdate_Struct {
/*0000*/ sint32 MercStatus; // Seen 0 with merc and -1 with no merc hired
/*0004*/ int32 MercCount; // Seen 1 with 1 merc hired and 0 with no merc hired
/*0008*/ MercenaryData_Struct MercData[0]; // Data for individual mercenaries in the Merchant List
};

// [OPCode: 0x6537] On Live as of April 2 2012 [Server->Client]
// Size 12 and sent on Zone-In if no mercenary is currently hired and when merc is dismissed
// (Same packet as MercAssign_Struct?)
struct NoMercenaryHired_Struct {
/*0000*/ sint32 MercStatus; // Seen -1 with no merc hired
/*0004*/ int32 MercCount; // Seen 0 with no merc hired
/*0008*/ int32 MercID; // Seen 1 when no merc is hired - ID unique to each type of mercenary
/*0012*/
};

// OP_MercenaryAssign (Same packet as NoMercenaryHired_Struct?)
struct MercenaryAssign_Struct {
/*0000*/ int32 MercEntityID; // Seen 0 (no merc spawned) or 615843841 and 22779137
/*0004*/ int32 MercUnk01; //
/*0008*/ int32 MercUnk02; //
/*0012*/
};

// [OPCode: 0x495d OP_MercenaryTimer] On Live as of April 2 2012 [Server->Client] [Size: 20]
// Sent on Zone-In, or after Dismissing, Suspending, or Unsuspending Mercs
struct MercenaryStatus_Struct {
/*0000*/ int32 MercEntityID; // Seen 0 (no merc spawned) or 615843841 and 22779137
/*0004*/ int32 UpdateInterval; // Seen 900000 - Matches from 0x6537 packet (15 minutes in ms?)
/*0008*/ int32 MercUnk01; // Seen 180000 - 3 minutes in milleseconds? Maybe next update interval?
/*0012*/ int32 MercState; // Seen 5 (normal) or 1 (suspended)
/*0016*/ int32 SuspendedTime; // Seen 0 (not suspended) or c9 c2 64 4f (suspended on Sat Mar 17 11:58:49 2012) - Unix Timestamp
/*0020*/
};

// [OPCode: 0x4c6c] On Live as of April 2 2012 [Client->Server] [Size: 8]
// Sent from the client when using the Mercenary Window
struct MercenaryCommand_Struct {
/*0000*/ int32 MercCommand; // Seen 0 (zone in with no merc or suspended), 1 (dismiss merc), 5 (normal state), 36 (zone in with merc)
/*0004*/ sint32 Option; // Seen -1 (zone in with no merc), 0 (setting to passive stance), 1 (normal or setting to balanced stance)
/*0008*/
};

// [OPCode: 0x1a79] On Live as of April 2 2012 [Client->Server] [Size: 1]
// Requesting to suspend or unsuspend merc
struct SuspendMercenary_Struct {
/*0000*/ int8 SuspendMerc; // Seen 30 (48) for suspending or unsuspending
/*0001*/
};

// [OPCode: 0x2528] On Live as of April 2 2012 [Server->Client] [Size: 4]
// Response to suspend merc with timestamp
struct SuspendMercenaryResponse_Struct {
/*0000*/ int32 SuspendTime; // Unix Timestamp - Seen a9 11 78 4f
/*0004*/
};

// [OPCode: 0x5e78 (OP_MercenaryHire?)] On Live as of April 2 2012
// Sent by client when requesting to view Mercenary info or Hire a Mercenary
struct MercenaryMerchantRequest_Struct {
/*0000*/ int32 MercID; // Seen 399 and 400 for merc ID
/*0004*/ int32 MercUnk01; // Seen 1
/*0008*/ int32 MercMerchantID; // Entity ID for Mercenary Merchant
/*0012*/ int32 MercUnk02; // Seen 65302016 (00 6e e4 03) - (probably actually individual int8 fields)
/*0016*/
};

// [OPCode: 0x5e78 (OP_MercenaryHire?)] On Live as of April 2 2012
// Sent by Server in response to requesting to view Mercenary info or Hire a Mercenary
struct MercenaryMerchantResponse_Struct {
/*0000*/ int32 ResponseType; // Seen 0 for hire response, 6 for info response, and 9 for denied hire request
/*0004*/
};

trevius
10-12-2012, 07:26 AM
Here are the only struct differences for UF and SoD that I know so far based on the packets bad_captain and Derision were generating for each client:

SoD

// Used by MercenaryMerchantList_Struct
struct MercenaryListEntry_Struct {
/*0000*/ int32 MercID; // ID unique to each type of mercenary (probably a DB id)
/*0004*/ int32 MercType; // From dbstr_us.txt - Apprentice (330000100), Journeyman (330000200), Master (330000300)
/*0008*/ int32 MercSubType; // From dbstr_us.txt - 330020105^23^Race: Guktan<br>Type: Healer<br>Confidence: High<br>Proficiency: Apprentice, Tier V...
/*0012*/ int32 PurchaseCost; // Purchase Cost (in gold)
/*0016*/ int32 UpkeepCost; // Upkeep Cost (in gold)
/*0020*/ int32 AltCurrencyCost; // Alternate Currency Purchase Cost? (all seen costs show N/A Bayle Mark) - Seen 0
/*0024*/ int32 AltCurrencyUpkeep; // Alternate Currency Upkeep Cost? (all seen costs show 1 Bayle Mark) - Seen 1
/*0028*/ int32 AltCurrencyType; // Alternate Currency Type? - 19^17^Bayle Mark^0 - Seen 19
/*0032*/ int32 StanceCount; // Iterations of MercenaryStance_Struct - Normally 2 to 4 seen
/*0036*/ sint32 TimeLeft; // Unknown (always see -1 at merchant) - Seen 900000 (15 minutes in ms for newly hired merc)
/*0040*/ MercenaryStance_Struct Stances[2]; // Count Varies, but hard set to 2 for now - From dbstr_us.txt - 1^24^Passive^0, 2^24^Balanced^0, etc (1 to 9 as of April 2012)
};

// Used by MercenaryDataUpdate_Struct
struct MercenaryData_Struct {
/*0000*/ int32 MercID; // ID unique to each type of mercenary (probably a DB id)
/*0004*/ int32 MercType; // From dbstr_us.txt - Apprentice (330000100), Journeyman (330000200), Master (330000300)
/*0008*/ int32 MercSubType; // From dbstr_us.txt - 330020105^23^Race: Guktan<br>Type: Healer<br>Confidence: High<br>Proficiency: Apprentice, Tier V...
/*0012*/ int32 PurchaseCost; // Purchase Cost (in gold)
/*0016*/ int32 UpkeepCost; // Upkeep Cost (in gold)
/*0020*/ int32 AltCurrencyCost; // Alternate Currency Purchase Cost? (all seen costs show N/A Bayle Mark) - Seen 0
/*0024*/ int32 AltCurrencyUpkeep; // Alternate Currency Upkeep Cost? (all seen costs show 1 Bayle Mark) - Seen 1
/*0028*/ int32 AltCurrencyType; // Alternate Currency Type? - 19^17^Bayle Mark^0 - Seen 19
/*0032*/ int32 StanceCount; // Iterations of MercenaryStance_Struct - Normally 2 to 4 seen
/*0036*/ sint32 TimeLeft; // Unknown (always see -1 at merchant) - Seen 900000 (15 minutes in ms for newly hired merc)
/*0040*/ MercenaryStance_Struct Stances[2]; // Count Varies, but hard set to 2 for now - From dbstr_us.txt - 1^24^Passive^0, 2^24^Balanced^0, etc (1 to 9 as of April 2012)
/*0000*/ int32 MercUnk05; // Seen 1 - Extra Merc Data field that differs from MercenaryListEntry_Struct
// MercUnk05 may be a field that is at the end of the packet only, even if multiple mercs are listed (haven't seen examples of multiple mercs owned at once)
};


Underfoot

// Used by MercenaryMerchantList_Struct
struct MercenaryListEntry_Struct {
/*0000*/ int32 MercID; // ID unique to each type of mercenary (probably a DB id)
/*0004*/ int32 MercType; // From dbstr_us.txt - Apprentice (330000100), Journeyman (330000200), Master (330000300)
/*0008*/ int32 MercSubType; // From dbstr_us.txt - 330020105^23^Race: Guktan<br>Type: Healer<br>Confidence: High<br>Proficiency: Apprentice, Tier V...
/*0012*/ int32 PurchaseCost; // Purchase Cost (in gold)
/*0016*/ int32 UpkeepCost; // Upkeep Cost (in gold)
/*0020*/ int32 AltCurrencyCost; // Alternate Currency Purchase Cost? (all seen costs show N/A Bayle Mark) - Seen 0
/*0024*/ int32 AltCurrencyUpkeep; // Alternate Currency Upkeep Cost? (all seen costs show 1 Bayle Mark) - Seen 1
/*0028*/ int32 AltCurrencyType; // Alternate Currency Type? - 19^17^Bayle Mark^0 - Seen 19
/*0032*/ int8 MercUnk01; // Unknown (always see 0)
/*0033*/ sint32 TimeLeft; // Unknown (always see -1 at merchant) - Seen 900000 (15 minutes in ms for newly hired merc)
/*0037*/ int32 MerchantSlot; // Merchant Slot? Increments, but not always by 1 - May be for Merc Window Options (Seen 5, 36, 1 for active mercs)?
/*0041*/ int32 MercUnk02; // Unknown (normally see 1, but sometimes 2 or 0)
/*0045*/ int32 StanceCount; // Iterations of MercenaryStance_Struct - Normally 2 to 4 seen
/*0049*/ int32 MercUnk03; // Unknown (always 0 at merchant) - Seen on active merc: 93 a4 03 77, b8 ed 2f 26, 88 d5 8b c3, and 93 a4 ad 77
/*0053*/ int8 MercUnk04; // Seen 1
/*0054*/ MercenaryStance_Struct Stances[2]; // Count Varies, but hard set to 2 for now - From dbstr_us.txt - 1^24^Passive^0, 2^24^Balanced^0, etc (1 to 9 as of April 2012)
};

// Used by MercenaryDataUpdate_Struct
struct MercenaryData_Struct {
/*0000*/ int32 MercID; // ID unique to each type of mercenary (probably a DB id)
/*0004*/ int32 MercType; // From dbstr_us.txt - Apprentice (330000100), Journeyman (330000200), Master (330000300)
/*0008*/ int32 MercSubType; // From dbstr_us.txt - 330020105^23^Race: Guktan<br>Type: Healer<br>Confidence: High<br>Proficiency: Apprentice, Tier V...
/*0012*/ int32 PurchaseCost; // Purchase Cost (in gold)
/*0016*/ int32 UpkeepCost; // Upkeep Cost (in gold)
/*0020*/ int32 AltCurrencyCost; // Alternate Currency Purchase Cost? (all seen costs show N/A Bayle Mark) - Seen 0
/*0024*/ int32 AltCurrencyUpkeep; // Alternate Currency Upkeep Cost? (all seen costs show 1 Bayle Mark) - Seen 1
/*0028*/ int32 AltCurrencyType; // Alternate Currency Type? - 19^17^Bayle Mark^0 - Seen 19
/*0032*/ int8 MercUnk01; // Unknown (always see 0)
/*0033*/ sint32 TimeLeft; // Unknown (always see -1 at merchant) - Seen 900000 (15 minutes in ms for newly hired merc)
/*0037*/ int32 MerchantSlot; // Merchant Slot? Increments, but not always by 1 - May be for Merc Window Options (Seen 5, 36, 1 for active mercs)?
/*0041*/ int32 MercUnk02; // Unknown (normally see 1, but sometimes 2 or 0)
/*0045*/ int32 StanceCount; // Iterations of MercenaryStance_Struct - Normally 2 to 4 seen
/*0049*/ int32 MercUnk03; // Unknown (always 0 at merchant) - Seen on active merc: 93 a4 03 77, b8 ed 2f 26, 88 d5 8b c3, and 93 a4 ad 77
/*0053*/ int8 MercUnk04; // Seen 1
/*0054*/ MercenaryStance_Struct Stances[2]; // Count Varies, but hard set to 2 for now - From dbstr_us.txt - 1^24^Passive^0, 2^24^Balanced^0, etc (1 to 9 as of April 2012)
/*0000*/ int32 MercUnk05; // Seen 1 - Extra Merc Data field that differs from MercenaryListEntry_Struct
// MercUnk05 may be a field that is at the end of the packet only, even if multiple mercs are listed (haven't seen examples of multiple mercs owned at once)
};


My guess is that most of the smaller packets have not changed much if at all.

Shiny151
10-12-2012, 11:47 AM
Trev; will mercs piggyback off any of the bot code or are they standalone?

trevius
10-12-2012, 08:29 PM
I will leave that type of thing up to the bot dev people like bad_captain. I assume they will get their own merc class that is basically just a copy of the bot class, but tweaked for mercs.

bad_captain
10-12-2012, 10:44 PM
I had a conversation about 2 years ago with Wildcard, who did a lot of the work on bots before me, and he had planned to change bots to be inherited off of mercs when they were finished. After doing a little bit of work on mercs, I'm not sure how easy or beneficial that would be, but I guess we'll see. The one real problem with bots (that won't be an issue with mercs), is the option to build without them, meaning a lot of code has to be rewritten or copied to get bots to work and still compile when they aren't enabled. Mercs should be built into the actual build so that they work a little more seamlessly than bots, even if they are less flexible.

On the other hand, with some changes on the live client, switching between multiple mercs, and editing the dbstring files, I think a lot could be done to merge the two. Incorporating the upkeep system into bots would be a benefit as well.

Once mercs get closer to being viable, I think the decision will have to be made whether to keep bots as is or inherit off of mercs, but unless someone can find other advantages to doing so, I see bots remaining as is.

bad_captain
10-12-2012, 10:53 PM
Note: your comment regarding the first field in the MercenaryMerchantRequest_Struct, is I believe the Merc ID, instead of RequestType.

trevius
10-13-2012, 06:58 AM
Note: your comment regarding the first field in the MercenaryMerchantRequest_Struct, is I believe the Merc ID, instead of RequestType.

Thanks, I corrected that one in the post.

KLS
10-13-2012, 05:45 PM
Going to chime in: I think bots are a clusterfuck and if we're implementing mercs we should implement them as a new system and not shoehorn them into the gap we've made with bots(esp since they don't work 100% the same).

bad_captain
10-13-2012, 08:02 PM
Maybe once Mercs are in, trunk drops support for bots, who are then maintained in the MercsAndBots branch. Seems like an acceptable solution to me.

trevius
10-15-2012, 05:07 AM
Here are some more Mercenary related opcodes for SoD and UF:

SoD

OP_MercenaryDataUpdate=0x0786 #
OP_MercenaryCommand=0x167b #
OP_MercenarySuspendRequest=0x05f1 #
OP_MercenarySuspendResponse=0x57f2 #
OP_MercenaryDataUpdateRequest=0x390c #

Underfoot

OP_MercenaryDataUpdate=0x57f2 #
OP_MercenaryCommand=0x6c36 #
OP_MercenarySuspendRequest=0x3c58 #
OP_MercenarySuspendResponse=0x4b82 #
OP_MercenaryDataUpdateRequest=0x05f1 #

I will try to get some basic packet handling added for these and the code actually supporting them can be added later once more merc stuff is in place.

Also, it looks like OP_MercenaryAssign may actually just be OP_WeaponEquip1 according to the info I can find in my last collects. It is the same size packet and seems like the same struct. If we can verify this, it is one less thing to deal with for merc stuff.

// 0x7404 - OP_MercenaryAssign (Same packet as NoMercenaryHired_Struct?) [Server->Client]
struct MercenaryAssign_Struct {
/*0000*/ int32 MercEntityID; // Seen 0 (no merc spawned) or 615843841 and 22779137
/*0004*/ int32 MercUnk01; //
/*0008*/ int32 MercUnk02; //
/*0012*/
};

[OPCode: 0x7404] OP_WeaponEquip1 [Server->Client] [Size: 12]
000 | a4 59 00 00 01 00 00 00 8a 2b 00 00 | .Y.......+..

[OPCode: 0x7404] OP_WeaponEquip1 [Server->Client] [Size: 12]
000 | a4 59 00 00 00 00 00 00 dd 2a 00 00 | .Y.......*..

trevius
10-15-2012, 07:29 AM
And here are some roughed in packet handling for mercs for client_packet.cpp. These are mostly just hard set with the basic packet responses so they can be corrected later with actual functions supporting them.

ConnectedOpcodes[OP_MercenaryCommand] = &Client::Handle_OP_MercenaryCommand;
ConnectedOpcodes[OP_MercenaryDataUpdateRequest] = &Client::Handle_OP_MercenaryDataUpdateRequest;
ConnectedOpcodes[OP_MercenarySuspendRequest] = &Client::Handle_OP_MercenarySuspendRequest;

void Client::Handle_OP_MercenarySuspendRequest(const EQApplicationPacket *app)
{
if(app->size != sizeof(SuspendMercenary_Struct))
{
LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_MercenarySuspendRequest expected %i got %i", sizeof(SuspendMercenary_Struct), app->size);
DumpPacket(app);
return;
}

SuspendMercenary_Struct* sm = (SuspendMercenary_Struct*) app->pBuffer;
uint32 merc_suspend = sm->SuspendMerc; // Seen 30 for suspending or unsuspending

DumpPacket(app);

// Handle the Command here...
// Check if the merc is suspended and if so, unsuspend, otherwise suspend it


// This response packet includes the timestamp of the suspend request
EQApplicationPacket *outapp = new EQApplicationPacket(OP_MercenarySuspendResponse, sizeof(SuspendMercenaryResponse_Struct));
SuspendMercenaryResponse_Struct* smr = (SuspendMercenaryResponse_Struct*)outapp->pBuffer;
smr->SuspendTime = time(); // Unix Timestamp

DumpPacket(outapp);
FastQueuePacket(&outapp);
}

void Client::Handle_OP_MercenaryCommand(const EQApplicationPacket *app)
{
if(app->size != sizeof(MercenaryCommand_Struct))
{
LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_MercenaryCommand expected %i got %i", sizeof(MercenaryCommand_Struct), app->size);
DumpPacket(app);
return;
}

MercenaryCommand_Struct* mc = (MercenaryCommand_Struct*) app->pBuffer;
uint32 merc_command = mc->MercCommand; // Seen 0 (zone in with no merc or suspended), 1 (dismiss merc), 5 (normal state), 36 (zone in with merc)
sint32 option = mc->Option; // Seen -1 (zone in with no merc), 0 (setting to passive stance), 1 (normal or setting to balanced stance)

DumpPacket(app);

// Handle the Command here...
// Will need a list of what every type of command is supposed to do
// Unsure if there is a server response to this packet
}

void Client::Handle_OP_MercenaryDataUpdateRequest(const EQApplicationPacket *app)
{
// The payload is 0 bytes.
if(app->size != 0)
{
LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_MercenaryDataUpdateRequest expected 0 got %i", app->size);
DumpPacket(app);
return;
}

DumpPacket(app);

// Hard setting some stuff until it can be coded to load properly from the DB
int mercCount = 1;
int stanceCount = 2;
char mercName[32]; // This actually needs to be null terminated
strcpy(mercName, GetRandPetName());

uint32 packetSize = sizeof(MercenaryDataUpdate_Struct) + ( sizeof(MercenaryData_Struct) - 8 + sizeof(MercenaryStance_Struct) * stanceCount ) * mercCount + strlen(mercName);

// This response packet seems to be sent on zoning or camping by client request
// It is populated with owned merc data only
EQApplicationPacket *outapp = new EQApplicationPacket(OP_MercenaryDataUpdate, packetSize);
MercenaryDataUpdate_Struct* mdu = (MercenaryDataUpdate_Struct*)outapp->pBuffer;

mdu->MercStatus = 0;
mdu->MercCount = mercCount;

for(int i = 0; i < mercCount; i++)
{
mdu->Mercs[i].MercID = 400;
mdu->Mercs[i].MercType = 330000100;
mdu->Mercs[i].MercSubType = 330020105;
mdu->Mercs[i].PurchaseCost = 4910;
mdu->Mercs[i].UpkeepCost = 123;
mdu->Mercs[i].Status = 0;
mdu->Mercs[i].AltCurrencyCost = 0;
mdu->Mercs[i].AltCurrencyUpkeep = 1;
mdu->Mercs[i].AltCurrencyType = 19;
mdu->Mercs[i].MercUnk01 = 0;
mdu->Mercs[i].TimeLeft = 900000;
mdu->Mercs[i].MerchantSlot = 1;
mdu->Mercs[i].MercUnk02 = 1;
mdu->Mercs[i].StanceCount = stanceCount;
mdu->Mercs[i].MercUnk03 = 519044964;
mdu->Mercs[i].MercUnk04 = 1;
strcpy(mml->Mercs[i].MercName, mercName);
for (int stanceindex = 0; stanceindex < stanceCount; stanceindex++)
{
mdu->Mercs[i].Stances[stanceindex].StanceIndex = stanceindex;
mdu->Mercs[i].Stances[stanceindex].Stance = stanceindex + 1;
}
mdu->Mercs[i].MercUnk05 = 1;
i++;
}

DumpPacket(outapp);
FastQueuePacket(&outapp);
}


I haven't tested these yet, but the basics should be there and easy to get working. I think this is the last of the handling needed for packets coming from the client. There is still plenty to do to get this stuff actually working as intended though.

trevius
10-16-2012, 06:23 AM
I think it may need some testing, but based on my VoA merc collects, I found a couple more opcodes that appear to be mercenary related:

SoD:
OP_MercenaryDismiss=0x319a #
OP_MercenaryTimerRequest=0x184e #

Underfoot:
OP_MercenaryDismiss=0x0bd0 #
OP_MercenaryTimerRequest=0x0924 #

These are both Client->Server packets, so they will require more handling. I am pretty sure OP_MercenaryDismiss is the right opcode and names based on what I was seeing in UF while watching my log files and dismissing a merc. I am not sure about OP_MercenaryTimerRequest yet, but in my collect from Live, the OP_MercenaryTimer packet comes in right after OP_MercenaryTimerRequest on initial zone in with a merc.

All of these new packets will probably take some playing around with to figure out which are required for what and which may not be required at all (if any).

I will work on some basic handling for these as well, which can be refined later.

trevius
10-16-2012, 06:39 AM
I think this should be the basic handling for those 2 new opcodes:

client_packet.h
void Handle_OP_MercenaryDismiss(const EQApplicationPacket *app);
void Handle_OP_MercenaryTimerRequest(const EQApplicationPacket *app);

client_packet.cpp
ConnectedOpcodes[OP_MercenaryDismiss] = &Client::Handle_OP_MercenaryDismiss;
ConnectedOpcodes[OP_MercenaryTimerRequest] = &Client::Handle_OP_MercenaryTimerRequest;

void Client::Handle_OP_MercenaryDismiss(const EQApplicationPacket *app)
{
// The payload is 0 bytes.
if(app->size != 0)
{
Message(13, "Size mismatch in OP_MercenaryDismiss expected 0 got %i", app->size);
LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_MercenaryDismiss expected 0 got %i", app->size);
DumpPacket(app);
return;
}

DumpPacket(app);

Message(7, "Mercenary Debug: Dismiss Request Recieved.");

// Handle the dismiss here...

// Unsure if there is a server response to this packet

}

void Client::Handle_OP_MercenaryTimerRequest(const EQApplicationPacket *app)
{
// The payload is 0 bytes.
if(app->size != 0)
{
Message(13, "Size mismatch in OP_MercenaryTimerRequest expected 0 got %i", app->size);
LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_MercenaryTimerRequest expected 0 got %i", app->size);
DumpPacket(app);
return;
}

DumpPacket(app);

Message(7, "Mercenary Debug: Timer Request received.");

// To Do: Load Mercenary Timer Data to properly populate this reply packet
// All hard set values for now

// Send Mercenary Status/Timer packet
EQApplicationPacket *outapp = new EQApplicationPacket(OP_MercenaryTimer, sizeof(MercenaryStatus_Struct));
MercenaryStatus_Struct* mss = (MercenaryStatus_Struct*)outapp->pBuffer;
mss->MercEntityID = 1; // Seen 0 (no merc spawned) or 615843841 and 22779137
mss->UpdateInterval = 900000; // Seen 900000 - Matches from 0x6537 packet (15 minutes in ms?)
mss->MercUnk01 = 180000; // Seen 180000 - 3 minutes in milleseconds? Maybe next update interval?
mss->MercState = 5; // Seen 5 (normal) or 1 (suspended)
mss->SuspendedTime = 0; // Seen 0 (not suspended) or c9 c2 64 4f (suspended on Sat Mar 17 11:58:49 2012) - Unix Timestamp

DumpPacket(outapp);
FastQueuePacket(&outapp);
}

trevius
10-17-2012, 05:26 AM
The last commit I did for Rev2234 is causing a zone crash when sending the mercenary merchant list. Simple fix is this:

client_packet.cpp in Client::Handle_OP_MercenaryDataRequest(const EQApplicationPacket *app)

Replace:
packetSize = sizeof(MercenaryMerchantList_Struct) - 12 + mercTypeCount * 4 + ( sizeof(MercenaryListEntry_Struct) - 40 + sizeof(MercenaryStance_Struct) * mercStanceCount ) * mercCount;

With:
packetSize = sizeof(MercenaryMerchantList_Struct) + sizeof(MercenaryListEntry_Struct) * mercCount;

There are 2 spots in that function where this needs to be replaced.

I don't have access to test this right now, but will check it in the morning and commit the fix. Just noting it here for anyone following the merc branch changes.

KLS
10-17-2012, 12:34 PM
See this is why we need automatic packet encoding/decoding even at the application level. =/

bad_captain
10-19-2012, 10:09 AM
I did some spawn work last night. I cleaned up some code in client_packet.cpp and tried to flesh out the hiring / spawning process.

I was able to get the merc when hired added to my group. I had added some code for the merc to follow me, but it doesn't work yet. I didn't get a chance to test it out other than seeing it didn't work.

I added some code for dismiss, but it didn't seem to work either. It may have been an issue with getting the merc owner, as I had a similar issue on spawning I was able to fix. I just ran out of time to test out why.

My plan is to clean up the spawning process a little more, get my merc to follow me, get suspend/unsuspending & dismiss working tonight. A little more work needs to be done before being able to save the merc to the database (definitely not in the player profile).

The merc templates are currently being stored in the zone, so there is duplication. It could be moved to EQSharedMem to eliminate that, but to get it up and running, that's where I put them. The shared memory stuff may be beyond my pay grade, but there's plenty of time before anyone needs to worry about it. I think it's around 150kb per zone if my math is close.

If anyone has a live paid account on EQ that has mercs, I have some things I need to check on that I can't on my account. If anyone is able and willing, I'd appreciate it.

bad_captain
10-19-2012, 11:09 AM
Also, I think I have everything to put the correct stances in. Is there anything else that needs to be done besides modifying the packet size when creating it to account for the extra stances? Besides actually loading the correct stances, of course.. I'm in no hurry to add them, but wanted to check so I knew what changes would be needed. Passive and Balanced are fine for what we need to do yet.

Devincean
10-20-2012, 12:23 AM
I did some spawn work last night. I cleaned up some code in client_packet.cpp and tried to flesh out the hiring / spawning process.

I was able to get the merc when hired added to my group. I had added some code for the merc to follow me, but it doesn't work yet. I didn't get a chance to test it out other than seeing it didn't work.

I added some code for dismiss, but it didn't seem to work either. It may have been an issue with getting the merc owner, as I had a similar issue on spawning I was able to fix. I just ran out of time to test out why.

My plan is to clean up the spawning process a little more, get my merc to follow me, get suspend/unsuspending & dismiss working tonight. A little more work needs to be done before being able to save the merc to the database (definitely not in the player profile).

The merc templates are currently being stored in the zone, so there is duplication. It could be moved to EQSharedMem to eliminate that, but to get it up and running, that's where I put them. The shared memory stuff may be beyond my pay grade, but there's plenty of time before anyone needs to worry about it. I think it's around 150kb per zone if my math is close.

If anyone has a live paid account on EQ that has mercs, I have some things I need to check on that I can't on my account. If anyone is able and willing, I'd appreciate it.

I had mercs on my account even ended up putting in the work and getting high end tier 3 mercs so know all about them. Was also thinking of trying to help you guys out with any packet catching ya need since have guys at all levels and can solo most of the game since my mains on live are 90 druid i dual box with my 90 enchanter each with about 3000aa been awhile since I played well about VOA also have a entire guild city and a couple of houses wanted to see if I could help you guys get that data. If so let me know be glad to reactive my accounts for a month or two if it helps out.

trevius
10-20-2012, 08:04 AM
Also, I think I have everything to put the correct stances in. Is there anything else that needs to be done besides modifying the packet size when creating it to account for the extra stances? Besides actually loading the correct stances, of course.. I'm in no hurry to add them, but wanted to check so I knew what changes would be needed. Passive and Balanced are fine for what we need to do yet.

Nothing special needs to be done to the packets for stances to be added as long as you don't exceed 5 total stances. Right now, due to the variable sized packet issues, I just have it hard coded to globally load 5 stance iterations into the packet. Then, once it is encoded, it only uses the number of iterations that are set in the stance count field. I did the same thing with merc types. I have it currently set to load 3 of them, but only use as many as are set in the merc type counts when the encode happens. Everything else gets discarded and is not populated anyway.

If we need to increase the number of merc types or stances at some point, I think we just have to adjust the related structs in eq_packet_structs.h.

bad_captain
10-20-2012, 10:18 AM
Okay, good to know.

5 stances should be okay, I believe. I'll have to check for any that might have more. Caster has the most - Passive, Balanced, Burn, and BurnAE for sure, maybe Efficient or Aggressive (I don't have them right in front of me). Healers have Passive, Balanced, Efficient and Reactive.

We will need to increase Merc Types, though. While I'm not even sure if they have any Master Mercenaries, there are a few Mercenary Merchants who have 2 races, so they will have at least 4 (6 if you include master).

I was able to get mercs to follow last night, and dismiss and suspend mostly working. Also, I fixed a couple of issues that allow the illusion packet to work (purchasing mercs from Guardian Norerd in PoK who needs to be changed to be a froglok now results in a froglok merc). I still need to add the SQL to fix the mercenary merchants, but i know him and Mercenary Mdjai in Crescent Reach work.

bad_captain
10-20-2012, 04:39 PM
I apparently made a few changes before I committed that I forgot about. One is causing a crash when hiring a merc. To fix this, add the following to the Merc constructor:


p_depop = false;


I'll add it tonight and try to fix another issue when the merc is dismissed. He's dismissed all right, but apparently his group doesn't think so. I'll get it sorted out. Good news though is that it does dismiss him.

bad_captain
10-20-2012, 04:42 PM
I had mercs on my account even ended up putting in the work and getting high end tier 3 mercs so know all about them. Was also thinking of trying to help you guys out with any packet catching ya need since have guys at all levels and can solo most of the game since my mains on live are 90 druid i dual box with my 90 enchanter each with about 3000aa been awhile since I played well about VOA also have a entire guild city and a couple of houses wanted to see if I could help you guys get that data. If so let me know be glad to reactive my accounts for a month or two if it helps out.

Well, I was reminded that the test server has access to the Journeyman mercs, so I was able to get some data that way. I wouldn't want you to do that yet, and only if no one else has easy access to higher tier of mercs. I will be coming up with a list of things to work on, as well as a list of data that's needed. Hopefully this weekend.

Devincean
10-20-2012, 06:20 PM
Ok ya the high tier mercs t3 to t5 are the harder to get usually you have to know someone high enough to run you through the unlock quests or pay someone too run you through the quest and its not cheap from what I use to charge was about half a million plat plus also I made a mistake have the T5 mercs on my guys not the T3 like I said been awhile but just peaked at them yesterday here is the guide i used for the mercs. http://articles.eqresource.com/mercoverview.php

Also just FYI the diffrence between Tier 1 - Tier 4 and Tier 5 mercs is very huge btw the T5 mercs can solo raid targets that are outdoor zones since mercs don't work in closed raid zones example (can't do 2.5 epics with mercs since the Dreadspire Keep: Demi-Plane of Blood (http://everquest.allakhazam.com/db/zone.html?zstrat=310) is indoor raid zone.)

Also some other useful links for mercs sure you could find them yourself but just to help out since information is fairly scattered. These links made coming back and learning how mercs work and what they could do really easy.

Everything about mercs stances/upgrades etc
http://almarsguides.com/eq/general/mercenaries.cfm

Bottom of page has most the race/class combos for mercs
http://everquest.allakhazam.com/wiki/EQ:Mercenaries

Only big things I am not sure how ya would figure out is T5 mercs obviously have AA bonuses the clerics heals amazingly and the tank merc hardly ever take a lot of damage even against raid targets so not sure if there is a way to figure that out also since merc armor auto upgrades as you level up (you can see the armor change per couple levels) not sure what armor and weapons they change to as they level up with you. I guess I could see if I took a alt and power leveled it up at what levels it changes and take pictures of it but not sure how to get the stats of the armor they are wearing or what they are wearing.

trevius
10-22-2012, 03:21 AM
Unless we plan to allow mercs to be given items to equip like Bots (which might be a nice option for custom servers), then the easiest solution would just be to simulate it by changing armor textures and tint. We can also set them to use specific weapon models and attack types right in the npc_types table so we don't have to give them actual weapons. Then their stats just need to be adjusted to whatever we want. Unless they get racial benefits, we could probably save some effort by making a single npc_type entry for each merc and then adjusting the race at the time it is created. Otherwise you are going to end up with thousands of entries to do what could otherwise be done with a small percentage of that.

Also, bad_captain, we will probably need to remove the 2 assign mercenary packets from the hire handling, since those are actually just used for setting weapon models. Those won't be required if we set the weapon models on the npc_type. That, or we can just send normal wearchanges or whatever.

Mercs are looking pretty good so far. Since using them is optional, we could probably merge them into the trunk anytime now even though they are still being worked on. Can probably wait until at least the rest of the packet stuff is worked out I guess.

I will probably leave most of the merc supporting code up to you, since you probably know what is needed better than I due to your experience with Bots. I definitely want to keep helping to make sure all of the packet stuff is worked out though. It looks like we still need to get the timer stuff working, so maybe I will work on that next. I am willing to help with more though, if you want to divvy anything out.

bad_captain
10-22-2012, 09:35 AM
I had planned to write up some stuff over the weekend, but was too busy to get to it. I started to work on stats last night and did give them an inventory, but could take it away just as easily. I would lean towards having it for customization reasons, and it allows for better code reuse from clients. But, I could be convinced otherwise. It would save the hassle of coming up with equipment sets, since they change weapons every 5 levels. They also change weapon types, as I had seen 1hs, 1hp, and 1hb all used by like level 30.

As far as race and npc_types, there is no different between races, and actually, they are all the same race (human?) with an illusion of their actual race. That is already in. I'm not sure I see the need for any entries in npc_types for a couple of reasons. First, everything needed is already in the current merc tables (most everything is dependent on class, proficiency (apprentice, journeyman) and tier). I think its very similar to pet power, which I believe was poorly implemented by having to use different records for each power for each pet. The rest just need to be handled in code based on those factors. Also, I think most fields in the npc_types table are not relevant to mercs (or at least won't vary among them) while there are also additional fields that aren't relevant to npcs but are for mercs.

Once I get a bit of time to write up what's done and what's not, I will have a better idea what can easily be delegated without us tripping over one another. I don't have a problem with others working on it, as another opinion from someone who doesn't work on bots may be beneficial, since I think of how to attack problems like they are bots. A fresh perspective is definitely helpful.

Once a little more work is done to handle the packets and most of the work is done that affects clients ( suspending, hiring, etc), I would feel better about merging. I don't want one of these big changes to mess anyone up. Once most of the work is just getting merc behavior correct, I say go ahead.

Also regarding equipment and stats. We need to decide on a way to scale spell casting as well as melee damage, especially if we choose not to give them an inventory. For journeyman healers, there can be almost a 100% increase in healing on a rank II spell at level 85. We need to determine if that holds true across the board, or if they also receive AA like bonuses that increase with levels (my assumption). I don't think my mercs currently heal for more than the base amount (level in mid 50s) but I would have to look through my logs.

trevius
10-23-2012, 03:42 AM
Yeah, definitely not all fields in npc_types would be relevant for mercs. I was just thinking it would be a nice way for servers to be able to adjust merc stats so they aren't hard coded in the source. If it used npc_types, it would let servers adjust stats and min/max damage etc so you could scale them in any way you want. This would remove the issue of trying to have gear come into play for mercs. I think having a gearing option for mercs might be nice as well to make them more flexible, but it might also be nice to be able to just create them similar to creating a pet. Though, given that mercs can range to any level and there are quite a few variations of mercs, that could mean quite a few npc_types entries to do it that way.

One possibility might be to have it load the base stats, min/max damage, health/mana, regen, weapon models, and so on from the db along with maybe a scaling ratio or something right from the merc_types table with a few new fields. Just like NPCs, they could use the npc_types_tint table to load the armor colors. If material/texture was added to that table as well, it would make it easy to simulate the appearance of any armor set on live for mercs.

The main argument I would have for allowing mercs to use stats over armor sets is that stats are much easier to tweak than armor sets are. It seems pretty clear to me that mercs on Live don't reflect exactly what a character of the same class type (such as warrior compared to merc tank) is capable of. I leveled a trio on Live recently from 1 to 60 and had a tank merc that is able to well out tank my warrior that is fairly well geared for his level now. I don't know if it is just that his mitigation is higher or if he just has a ton more HPs, but he probably tanks 2 or 3 times as well as my warrior does. Unless he is geared far beyond the standard gear for that level, I assume Live uses different base stats and/or formulas for mercs from what player characters use. I am sure there is more solid data out there somewhere from the crazy number crunchers, but I haven't done enough research to find it yet.

It could just be that mercs on Live are wearing the same armor set until they reach the higher levels or maybe only the higher tier mercs. If the set has a recommended level on it, maybe the armor just scales as the merc levels, which makes sense for simplifying the process. If that is the case, armor sets might not be a bad option and then we would just need to adjust the weapons that are used, which is much less work. I am guessing we would have to add support to make sure gear scales to level for recommended level gear that mercs are wearing.

You are probably right that AAs are used to increase spell effects. I don't think it would be hard to get that working for mercs. The other possibility would be if they use focus effects on gear they wear. If using the same armor set as they level as mentioned above, the focus effects wouldn't kick in until they reached the recommended level I think.

I wasn't aware that they are all a single race with an illusion cast on them. That should simplify things a bit as far as DB entries go.

KLS
10-23-2012, 05:55 AM
Just create a mercs table to store stats. A lot of the npc_types info is completely useless to mercs and it sucks having to give up valuable npc type ids.

bad_captain
10-23-2012, 10:30 AM
That seems like a good idea to just maintain it all in a new table. I think it will be important to decide how to scale the stats based on level. Tier also must affect stats since otherwise, why get the highest tier tank, when the lower tier and cheaper one would work almost as well.

With regards to equipment, just for testing, I had planned to give them the defiant gear for their level, with it changing every 20 levels or so. Weapons are a different story, but they are already in with pretty easy to determine effective level ranges. But, that also adds in another level of complexity. But, then we still need to figure out a way to give the mercs bonuses.

Also, Trevius, I think a lot of the merc tank's ability to tank is its regen. I can't remember the exact numbers, but I know at least at lower levels, they would regen more than 10% (I think closer to 15%) of their hps every tick. They could easily tank 3-4 even con mobs at least through level 30-35 or so without a heal.

bad_captain
10-24-2012, 06:13 PM
Below is a first attempt at breaking up the remaining work to be done for mercs. Some of the areas are very broad, but will get refined once work is done on them or in other areas. I have done some work on stats, but until the exact method of giving mercs stats and skills is decided, a lot of the other areas can't be worked on (such as combat). I will try to update this as work is done and further clarify the remaining items to do.

Packets
Merc Merchant List- send correct stances instead of hard coded ones
Merc Hire- check if client has enough coin, deduct purchase cost from client
Timer- send response packet, check if client has enough coin, if so- deduct upkeep from client; if not- dismiss merc
Merc Command- zone, change stance, etc
Remove most if not all of the hard coded values left
Finish extracting packet sending functions

Stats
NPC style stats or equipment based?
Weapons or Max/Min hit?
Stats db table
Skills stored in db table?
if using equipment, need equipment lists
stat scaling based on lvl, proficiency, tier

Spells
Spell & Skill lists per lvl & proficiency

Combat
Melee Attacks
Spell Casting
AI based on proximity
Group Roles
Flee based on confidence & situation

Out of Combat
Buffs
Resurrections

Misc
Save merc to DB

bad_captain
10-24-2012, 10:48 PM
I may be tired and not thinking correctly, but was trying to figure out the upkeep part. I looked at a log I did in December on live, and was watching for when I had my upkeep deducted. Here are the only unknown packets arriving at that time. Note: I was charged the upkeep just before I said 'Upkeep' as shown in the last packet. I was charged 1 platinum, 9 gold. I'm having trouble getting 1 platinum, 9 gold out of that, as well as matching it up with one of the existing structs. Am I missing something?


12/8/2011 9:02:45 PM
[OPCode: 0x7062] OP_ClientUpdate [Client->Server] [Size: 42]
000 | 59 6b 00 00 ce 55 02 00 00 00 b6 24 59 44 b6 2f | Yk...U.....$YD./
016 | a0 42 00 00 a1 c4 00 00 00 00 00 00 00 00 68 cb | .B............h.
032 | 58 40 00 00 00 00 00 78 18 00 | X@.....x..

12/8/2011 9:02:45 PM
[OPCode: 0x528f] OP_Unknown [Server->Client] [Size: 16]
000 | 2d 00 00 00 00 00 00 00 06 00 00 00 05 00 00 00 | -...............

12/8/2011 9:02:45 PM
[OPCode: 0x6537] OP_Unknown [Server->Client] [Size: 4]
000 | 0a 00 00 00 | ....

12/8/2011 9:02:46 PM
[OPCode: 0x2e79] OP_ChannelMessage [Client->Server] [Size: 51]
000 | XX XX XX XX XX XX 00 00 00 00 00 00 00 00 00 00 | MyName..........
016 | 08 00 00 00 00 00 00 00 00 64 00 00 00 75 70 6b | .........d...upk
032 | 65 65 70 00 00 00 00 00 00 00 00 00 00 00 00 00 | eep.............
048 | 00 00 00

lerxst2112
10-24-2012, 11:00 PM
Are there any AA or faction type mods that might change the amount you're charged?

Devincean
10-24-2012, 11:09 PM
Are there any AA or faction type mods that might change the amount you're charged?

no but you can have a marketplace tokenthat gets deducted rather then plat from your character and the amount per upkeep goes up with levels and merc tier type ... possibly the easiest way to see upkeep is to put away and recall your merc since every time you dismiss and recall mercs it charges a upkeep cost.

12/8/2011 9:02:45 PM
[OPCode: 0x7062] OP_ClientUpdate [Client->Server] [Size: 42]
000 | 59 6b 00 00 ce 55 02 00 00 00 b6 24 59 44 b6 2f | Yk...U.....$YD./
016 | a0 42 00 00 a1 c4 00 00 00 00 00 00 00 00 68 cb | .B............h.
032 | 58 40 00 00 00 00 00 78 18 00 | X@.....x..

Could be totally off but this looks like during the upkeep it checks for diffrence currencies first.


12/8/2011 9:02:45 PM
[OPCode: 0x528f] OP_Unknown [Server->Client] [Size: 16]
000 | 2d 00 00 00 00 00 00 00 06 00 00 00 05 00 00 00 | -...............

12/8/2011 9:02:45 PM
[OPCode: 0x6537] OP_Unknown [Server->Client] [Size: 4]
000 | 0a 00 00 00 | ....


Then possibly how much of what to minus plat or token
Mind you thats really just a guess.

bad_captain
10-24-2012, 11:12 PM
I don't think so. The only thing I've found that can change the amount is if you use a mercenary contract instead of purchasing from one of the merchants. The mercenary contract ones are a little cheaper (maybe 2/3 the regular price) for upkeep. There is no purchase price.

I think I just had a duh! moment. When spawned, the client requests the merc data, and the server responds, which includes the purchase price as well as the upkeep cost. The server just needs to tell the client to deduct the upkeep cost. Only issue is if the client levels after the data is sent, then the cost would be greater. I would assume (haven't found evidence in my logs yet, though) that the server would resend the merc data to include the updated costs, since the client is charged the correct amount after leveling. I guess I'll need to do more searching.

Devincean
10-24-2012, 11:17 PM
hey bad_captain was this pre level 50 or post because I know mercs are free no upkeep cost up to a certain level as long as its a Tier 1 or 2 merc

actually just read merc will start costing you 2g every 15 minutes at level 14. so guess the better question is were you 14+

bad_captain
10-25-2012, 12:52 AM
I was around level 20. I was charged 1 plat, 9 gold. I received the message that I was charged, then I said 'upkeep' so I knew where to look. One packet may be the message that I was being charged, but that may be handled client side. I guess I just need to get back in there and get a bunch more packet collects.

Noport
10-25-2012, 06:25 AM
OP_ClientUpdate=0x7062 #
OP_MoneyUpdate=0x528f #
OP_MercenaryDataResponse=0x6537 #
OP_CommonMessage=0x2e79 # You have been Charged for Upkeep


Opcode 0x6537 looks like your 12min timer was rest the opcode converted from hex to dec in ms time
2D65 hex converted to dec 11621 ms timer

chrsschb
10-25-2012, 08:43 AM
I like the idea of being able to control their stats per level / tier in a table like current NPCs, but using that method how would you scale stats for say Level 60 players who are going from Kunark to Velious and eventually into SoL. The level cap stayed 60 that entire time but the content got exponentially harder.

The tier system wouldn't work for this because once a tier is unlocked it's always unlocked. The progression of merc power needs to work similar to the players and not eventually permanently pass the player (especially not by a significant margin like current Live mercs).

bad_captain
10-25-2012, 01:55 PM
Being able to give mercs equipment would help with that, but I think even if mercs have equipment, allowing equipment trades would be a low priority.

I'm more concerned about having to have a record for every level for mercs, for each proficiency, for each tier, for each class. That would be 4 classes, 3 proficiencies including master, 5 tiers, and however many levels each server allows.

Maybe there can just be a tier modifier for each proficiency, with records for certain level ranges. I.E for levels 1-50, you have one record with stats that would max at level 50. In the code, it would scale the stats based on level. Then, another record for lvls 51-65, and so on. That way you could scale based on level, while giving the opportunity to change some parameters at certain levels.

I currently have skills being set to the max for their level based on their class, but I guess that could be put in the database as well.

trevius
10-26-2012, 02:38 AM
I think skills being max for their level is fine. It wouldn't hurt to have the option to be able to set it in the DB, but that shouldn't be something to really worry about at this point.

I think the best way to handle stats would probably just be to do it the long way by having each merc class/proficiency/level in the DB. Even for a server with max level of 80, that is only like 960 entries, which isn't huge in terms of db entries. Most of that could be written, adjusted, and scaled by simple queries fairly quickly using similar formulas to what might be used if we had scaling hard set in the source.

I am sure it could be done by setting a base and then having fields for scaling each field by X amount for levels Y+ or whatever, but having the individual entries allows for the most flexibility by far and shouldn't be too hard to manage.

As far as the upkeep cost packets go, the first one was definitely just an OP_MoneyUpdate, which I broke down here:

12/8/2011 9:02:45 PM
[OPCode: 0x528f] OP_Unknown [Server->Client] [Size: 16]
2d 00 00 00 - 45 Platinum
00 00 00 00 - 0 Gold
06 00 00 00 - 6 Silver
05 00 00 00 - 5 Copper

OP_MoneyUpdate

struct MoneyUpdate_Struct{
sint32 platinum;
sint32 gold;
sint32 silver;
sint32 copper;
};


My guess is that the 45 Plat and change is how much you had on your char after the charge happened. You probably started with 46 Plat 9 gold 6 silver and 5 copper, or something like that before the charge.

So, the charging for mercs should be very simple and is no different than how we already do money updates for just about everything else.

I am not 100% sure about the second packet. Your collect is from a time-frame that I don't have a good opcode reference for, so without the full collect and other merc packet examples, I am not able to verify for sure which packet that is. Since it is 4 bytes and is definitely around the merc related opcodes, I assume it is what we currently refer to as OP_MercenaryHire.

// [OPCode: 0x5e78 (OP_MercenaryHire?)] On Live as of April 2 2012
// Sent by Server in response to requesting to view Mercenary info or Hire a Mercenary
struct MercenaryMerchantResponse_Struct {
/*0000*/ int32 ResponseType; // Seen 0 for hire response, 6 for info response, and 9 for denied hire request
/*0004*/
};

My guess is that ResponseType 10 is just a server response saying you get to keep your merc :) If that is the case, then there is probably another ResponseType for dismissing mercs as well, but we will need to figure out what that is either via collects or by testing with sending different ResponseTypes from 0 to 10 (or so). It could also be that there is a separate packet/opcode for dealing with dismisses or whatever that upkeep packet is, but I would need a more complete collect example to be able to tell for sure.

sorvani
10-26-2012, 09:43 AM
I like the idea of being able to control their stats per level / tier in a table like current NPCs, but using that method how would you scale stats for say Level 60 players who are going from Kunark to Velious and eventually into SoL. The level cap stayed 60 that entire time but the content got exponentially harder.

The tier system wouldn't work for this because once a tier is unlocked it's always unlocked. The progression of merc power needs to work similar to the players and not eventually permanently pass the player (especially not by a significant margin like current Live mercs).

While that would be a nice concept to implement for custom servers, that is not how mercs work on live. It is more important to make sure the design will make them work as they do on live, and then keep/add room for customization where possible for non-legit servers.

chrsschb
10-26-2012, 10:42 AM
While that would be a nice concept to implement for custom servers, that is not how mercs work on live. It is more important to make sure the design will make them work as they do on live, and then keep/add room for customization where possible for non-legit servers.

Which is exactly what I was trying to convey (even if it didn't come out that way). Thanks.

bad_captain
10-26-2012, 01:01 PM
I completely forgot about the money update packet and how it works. I'll see if I can get that MercHire packet to work. I think you are correct, since when upkeep is charged, a check is made to make sure there is enough money to keep the merc. Otherwise, the merc is dismissed. It also sends the message that you have been charged upkeep, but I wasn't sure if it was just a message packet or not.

For stats, I can see a benefit both ways. If rules were used, it would be much simpler to modify stats off of a few base merc records (still have per level, class, at least, probably proficiency as well.). But, you missed tier, so multiply that total by 5. Besides HP, Mana and Maxhit(if used), I'm not sure many stats will have that big of an impact, at least less than skill or spells and their focuses.

I guess for now I'll leave stats how I have them so I can work on other things. I just have base stats, then item, spell, and aa bonuses (which we could rename merc bonuses and would be based on proficiency and tier) . Then we can set the base stats to whatever we decide. I am under the assumption we will be using max and min hits instead of calculating them from weapons. This way, some combat code can be worked on.

trevius
10-29-2012, 03:34 AM
FYI, I haven't given up on doing Merc work. I am just taking a bit of a break before working on more of it. I started reading this "Thinking in C++" book to give me a better understanding of coding before picking back up on it. About halfway done with the book so far. It is a good learning experience and is filling in details for stuff I am familiar with from reading the source, but never really fully understood in depth. Up to this point, almost everything I have learned about coding has been from examples in the EQEmu source. So, it will be nice to understand everything a bit better before picking up on more coding (about time, right?) :)

Hopefully I can finish the book up this week and start back into working on more stuff. The winter is normally a good time for coding anyway, since there are less things to do outside and around the house so there is more free-time for dev work.

joligario
10-29-2012, 07:35 AM
By Bruce Eckel?

trevius
10-29-2012, 07:49 AM
By Bruce Eckel?

Yep, that is the one. Seems pretty good so far for a free one. It assumes the reader is a C programmer, so it isn't really for beginners or anything, but it covers stuff pretty well either way if you have the basic idea of what is going on. Sorry, not trying to derail this thread :)

bad_captain
11-01-2012, 12:48 AM
I just committed some work I've done on mercs. Suspend is mostly working, basic stats are in (#showstats shows the stats we give the merc).

I had the 15 minute timer working at one point, but broke it again, so I need to figure out what happened with that. When the timer was working, I was being charged the upkeep, although the message stating the amount charged was incorrect.

I believe that suspend mostly works, but am unable to test unsuspend, because for some reason, no matter what I send in for suspended time in the suspend response packet, I get either 0 time remaining or 400+ hrs remaining. I'm not going to wait that long. There may be a mixup somewhere with the opcodes, because I get the following message:


[11.01. - 00:01:12] [WORLD__CLIENT_ERR] bad_captain: Received unknown EQApplicationPacket
[11.01. - 00:01:12] [WORLD__CLIENT_ERR] [OpCode OP_MercenaryTimerRequest (0x0924) Size=1]
[11.01. - 00:01:12] [WORLD__CLIENT_ERR] 0000: 30


I don't think the timer is being handled correctly, if at all. I don't get the


Message(7, "Mercenary Debug: Timer Request received.");


message at all, even when I got the 15 minute timer to work.

Another message I get is:


[11.01. - 00:01:18] [WORLD__CLIENT_ERR] bad_captain: Received unknown EQApplicationPacket
[11.01. - 00:01:18] [WORLD__CLIENT_ERR] [OpCode OP_Unknown (0x3401) Size=0]


I'm not sure if that is a relevant opcode or not. I'm using SoD.

Anyway, I just wanted to get the work out there, and hope to look further into the issues I'm having.


Somewhat unrelated, but affecting my debugging of some of these issues, is my inability to get EqExtractor to work for me. It works for captures I did at the end of last year using SoD, as well as ones I did earlier this year on live (in Feb). Now, any capture I do says it is an unsupported client version. I also get an error on the OP_DzChooseZone opcode, as it had a total length of 5, instead of six. I'm wondering if my SoD.conf file is messed up, but even using the default one from the trunk causes the issue. If anyone has any advice, I'd appreciate it. It would certainly help me figure out what's happening with some of these packets being sent and received.

trevius
11-01-2012, 03:22 AM
Yeah, I noticed the 1 byte sized packet for Dismiss on SoD and UF as well, but in my collects from VoA, they are 0 bytes. I am guessing that the case is the same for the Timer Request packet, assuming that is what the packet is for. I am not 100% sure the opcodes are correct for those on SoD and UF compared to what I have for VoA, but the order looks correct as far as I can tell so it should be.

I think we could probably just change the size check to see if it is > 1 instead of != 0 for the Timer Request, which is what I set already for the dismiss request. I have no idea what the 30 (48 in decimal) means, but that is the same thing I was seeing in the dismiss packets in SoD and UF. It may be that the client is sending that because of some mistake elsewhere in the data we are sending in other packets, but that is just a guess at best.

The Unknown 0x3401 opcode is most likely not merc related. I don't see the equivalent opcode being sent in my merc collects for VoA. Also, it is near most of the earlier opcodes, and merc opcodes are much later and all near each other in the order, so it is probably for something else like deleting spawns or something.

Maybe I can get some time to mess with the suspend timer stuff and see if I can get that working.

I haven't messed with the code for it at all yet, but I could probably look into getting the extractor working for Live, and maybe SoD if that is an issue and is needed. Unfortunately, I kinda suck at reading packets that haven't been dumped, cause I don't know the packet header stuff too well yet. I am sure I could figure it out though. I think the collector only requires a minimum amount of correct opcodes and structures to function, so it shouldn't be too hard to get that working. I think one of the main things is to make sure the PP packet struct is correct size. I really don't know why it would error out on any DZ packet sizes, as that seems to be completely irrelevant to identifying client version unless Derision changed the extractor to use that packet for identifying the client instead of the one we use for EQEmu. It would probably take a bit for me to familiarize myself with the code for the extractor, but it would be good stuff to know anyway. I am sure Derision would appreciate help with maintaining it so he isn't the only one doing it.

Noport
11-01-2012, 04:16 AM
you can get cavedude precompiled Version here https://code.google.com/p/projecteqd...e.zip&can=2&q=

says it is an unsupported client version:
keep your opcode files in format of patch_Oct16-2012.Conf
make sure you have a file with the same name as patch_oct16-2012.CS in the same directory.
so you might have to copy and rename *.cs files to match your *.conf file name
if you keep having the same problem download wireshark Version 1.8.2

that is the reason you are receiving unspported client version.


OP_DzChooseZone=0x3c5b

# Mercenary Opcodes:
OP_MercenaryList=0x195c # 0x5a0a
OP_MercenaryHire=0x4dd9
OP_MercenaryDismiss=0x0bd0
OP_MercenaryTimer=0x2ef8
OP_MercenaryTimerRequest=0x0924
OP_MercenaryCommand=0x6c36
OP_MercenaryDataUpdate=0x57f2
OP_MercenaryDataUpdateRequest=0x05f1
OP_MercenaryDataRequest=0x0327
OP_MercenaryDataResponse=0x6537
OP_MercenarySuspendRequest=0x3c58
OP_MercenarySuspendResponse=0x4b82


0x3401 was Op_NewZone in VoA it was changed in Oct 2012
OP_NewZone=0x0d60 # 0x3401

Noport
11-01-2012, 06:24 AM
I have no idea what the 30 (48 in decimal) means:
30 means End if satement or else sub, or if clause
48 means EOF means end of file.

bad_captain
11-01-2012, 11:40 AM
For eqextractor, I think it only needs the size of the pp. I don't think it ever gets there, maybe because of the other issue. When it checks the opcodes, it converts the opcodes to number, with playerprofile being like 245 or whatever. It loops through the opcodes to convert and at that point, it errors because of the Dz opcode. If I make the length 6 by adding a zero at the end (length is the number of characters in the opcode, not packet size. i.e. it's 0x0d6 instead of 0x0d60), it loads, but still doesn't find the correct sized pp. I added a conditional breakpoint to stop when it reached 245 or whatever the player profile one is and it never stopped. I might just use 0x0000 for the one it errors on in case the incorrect opcode causes some other error, then step through manually until I reach the player profile and see why it's not matching the size. It's just strange that it works correctly for collects from last year, but not now. Maybe something is messing up my packets. Who knows.

I'll try the size 1 timer packet and see if that helps.

For the suspend response packet, if I send the time suspended using timer::getcurrenttime, I get 400+ hrs remaining. If I send 30000 (5 minutes), I get the same. If I send the current time + 5 minutes ( in case it's actually when they are available to be unsuspended), I get 0 min 0 sec remaining. This one has me confused for sure. I haven't checked the encoding yet. Maybe there's something there.

trevius
11-05-2012, 05:04 AM
This one has me confused for sure. I haven't checked the encoding yet. Maybe there's something there.

Right now, the only encoding is for OP_MercenaryDataResponse and OP_MercenaryDataUpdate. The rest of the packets seem to not need encodes/decodes so far to my knowledge. There may need to be more encodes/decodes added, but most of the other packets are pretty small and simple, so it is less likely they will need them. It is hard for me to tell for sure without good collects from Live for each client.

Secrets
11-05-2012, 09:10 AM
It's a UNIX timestamp that it uses for mercenary timers. I'm not sure what value Timer::GetCurrentTime returns, but time_t's value should work fine.

PS: I'll be helping with mercenaries soon. I had a lot of experience with the packets before I went crazy. I also have been reverse engineering other games' file formats so I learned a LOT about IDA and game design in general as a result.

I have to get my development environment set up again. Been a while.

trevius
11-05-2012, 10:06 AM
before I went crazy.

I though you were born crazy! <3 Secrets :)

And yeah, it is a unix timestamp. I didn't look much into that function when I stuck that in there. I was just populating fields with data. You may be right that it is returning an undesired result.

Secrets
11-05-2012, 10:11 AM
I though you were born crazy! <3 Secrets :)

And yeah, it is a unix timestamp. I didn't look much into that function when I stuck that in there. I was just populating fields with data. You may be right that it is returning an undesired result.

I'll be committing what I learned from the disassembly soon.

In the meantime, here's a list of valid merc status update IDs. The packet is used on the client and server, whereas the client sends different data than the server packet. It's not just used for hiring as you can see below:

// [OPCode: 0x5e78 (OP_MercenaryHire?)] On Live as of April 2 2012
/*
Valid response IDs:

0 - Hire me! (Assign Merc after sending this.)
1 - Insufficient money message.
2 - Mercenary-To-Hire does not exist in the server's DB.
3 - Mercenary failed to spawn. (this actually tells us the mercenary should spawn BEFORE recieving this packet.)
4 - Mercenaries not allowed in raids.
5 - You already have a mercenary request pending
6 - You must dismiss the mercenary before hiring a new one.
7 - You must dismiss your suspended one before hiring a new one.
8 - Group is full.
9 - Error creating mercenary
10 - Replacing mercenary(?!)
11 - Your mercenary has quit! You ran out of money to pay for your mercenary!
12 - Your mercenary waived an upkeep cost of %d plat, and %d gold and your mercenary upkeep cost timer has been reset to %s. <-- these values are for GM resets of mercenaries and are generated from the client's
mercenary info. NOT from the packet.
13 - Your mercenary is about to be quit due to insufficient funds! <--- Sent before the mercenary quits, unsure of time sent before.
14 - There is no mercenary liason nearby! <-- hacking attempt check if no mercenary merchant is in the zone!
15 - You are too far away from the liason! <-- Liason exists as type in the zone, but client is too far away. (position update happened)
16 - You do not meet the requirements for that mercenary! <-- For example, if a mercenary is 'unlocked' in some way, send this if they do not have the mercenary unlock.
*/

Secrets
11-05-2012, 11:10 AM
So, the assign packet.

It's actually a 16-byte packet that does different things depending on variable size.

I had a screenshot from when I last worked on it. Basically, there's a few fields, and you were right about the unhire struct being the same as the assign struct:


struct MercenaryAssign_Struct {
/*0000*/ int32 MercEntityID; // Seen 0 (no merc spawned) or 615843841 and 22779137
/*0004*/ int32 MercState; // Seen 0 with no merc hired
/*0008*/ int32 MercSuspended; // Seen 1 when no merc is hired - ID unique to each type of mercenary
/*0012*/ int32 MercTimeRemaining; //UNIX Timestamp. The reason the client accepts this part of the packet missing is because SOE stupidly left no size checks. //I assume they wanted it in another packet but never removed it?
/*0016*/
};

I'm not actually sure if MercSuspended is the suspend state of the merc, it could be a list of stances from the client. It might not be. I'm not sure, I haven't observed the packet.

It's also possible the suspended state is a value from 0-4 depending on if the merc is suspended, active, dismissed or two other states? not sure.

Another thing it could be is that I have the initial hire packet and the assign packet screwed up, which would explain the merctimeremaining part being missing.

I forget what values these were but it *was* working at some point:

http://i.imgur.com/B6s0C.jpg

bad_captain
11-05-2012, 11:55 PM
I did some debugging on the timer stuff. 0 or 1 sized didn't seem to help. I did notice that at some point it was working and tried to figure out how I did it.

I found out there is a bug where if you have a merc suspended, it allows you to purchase a new merc. That part is easily fixed, but I found out something interesting. If I suspend my merc, then purchase a new one, my timer suddenly began to work. With the help of the debug messages, I found that if I had a merc suspended (the client thinks I have one), and purchase a new one, it doesn't do a data request for the merc data, since I assume the client thinks it already knows it. Somewhere in the data response, where it requests the current merc (merchant ID = 0), there's something that causes the timer to not work.

I did notice that there are two very similar structures: MercenaryData_Struct and MercenaryListEntry_Struct. There may be a chance to combine the two, and there may be a mixup of when to use one or the other, or something. I'll check into this a little more, but I thought I would throw it out there.

trevius
11-06-2012, 04:34 AM
Thanks for the info, Secrets! That is some nice data for the hire packets for sure.

I did notice that there are two very similar structures: MercenaryData_Struct and MercenaryListEntry_Struct. There may be a chance to combine the two, and there may be a mixup of when to use one or the other, or something. I'll check into this a little more, but I thought I would throw it out there.

Yeah, when I first wrote the structs, those 2 were using the same struct for their packets. The problem was that on the Live collect from VoA that I have, the MercenaryData_Struct has an extra field at the end, which I am really not too sure about. So, I split them up into 2 separate structs just to get things working. Since we actually build those packets on the fly in the patch files, the structs don't actually matter other than being a place to store the data so we can pull it when creating the packets in the path files. So, at this point, we should be able to just remove the MercenaryListEntry_Struct struct and store everything in MercenaryData_Struct instead, including the additional field. Even if that additional field isn't used, we can determine if we want to use it or not when we create the packets in the patch files.

Right now, it looks like I have that additional field at the end of the data update commented out in the encodes. I would either need a collect from SoD and UF or to have someone like Secrets to check the IDA output to figure out the correct packet struct to verify if it is correct or not. Maybe just uncommenting that so it adds the extra field would make it work, I dunno. I also don't know if that field only comes at the end of the packet, or if it can also come with every iteration of the merc data if more than one merc is owned. If it is related to owning multiple mercs, I think that was added later, so SoD and maybe UF might not have that field. At this point, it is just speculation though.

It is interesting that your timer started working when you had a merc already suspended. That sounds like the client is ignoring the merc data update response the way we are sending it. Something like that could definitely be caused by a packet struct issue, like size, which could be due to that missing field at the end (or any other peice of data). Right now, the data update struct isn't being fully populated based on what I saw on my VoA collects anyway. I know the merc name field is not yet being populated, which could also be the reason why it is failing. The variable sized packets just take a bit more work to get them sending as needed, but I am sure we can work out the rest of whatever is needed easy enough. The merc name field can probably just be changed to be 64 bytes, and we can add that to the encode with the appropriate size and null terminator. Also, if that last field in the data update only comes after the iterations for each merc data, we can't add it after "MercenaryData_Struct MercData[0]" due to the fact that 0 sized arrays have to be at the end of the struct, but we could easily just add it in during the encode by checking if we are on the last iteration and only adding it then. Either way, that doesn't matter too much at this point, until we get to the point of trying to manage more than 1 owned merc at a time.

bad_captain
11-06-2012, 11:35 AM
The ability to have multiple mercs came in December of last year, which was a month after VoA came out. From the December 14th 2011 patch notes:


Mercenary Roster -
- Players can now buy extra mercenary slots on the Marketplace and keep a roster of mercenaries that they can switch between. Mercenaries operate the way they used to, except that if you purchase another mercenary, it will become active and replace the mercenary you had active before (if any). Dismissing a mercenary will cause the first remaining mercenary in your roster to become the active mercenary (though suspended). Transferring a mercenary will cause the target player's active mercenary to be suspended and the newly transferred one to become active.
- To switch mercenaries in your roster, open the Mercenary Management UI.
- Added the new command /mercswitch. With no arguments, it lists the current roster of mercenaries and displays the one that is currently active. Adding a parameter allows switching between mercenaries in the roster.


I don't think the name is needed for SoD or UF, and wasn't present until this patch. I have collects from December 7th or 8th (before the change), and then Provocating sent me caps from December 27th - 30th (after). One of the unknowns may not be needed as well, I will have to double check my packets to verify. The additional fiend at the end may have come at the same time, as I don't believe it is in my captures either. I hope to verify tonight, but things have been a little busy around work with the election.

Here's a packet from 12/5:


12/5/2011 2:56:56 AM
[OPCode: 0x0327] OP_MercenaryDataResponse [Server->Client] [Size: 82]
000 | 01 00 00 00 e4 a4 bf 07 01 00 00 00 16 07 00 00 | ................
016 | e4 a4 bf 07 29 41 c0 07 00 00 00 00 00 00 00 00 | ....)A..........
032 | 00 00 00 00 00 00 00 00 13 00 00 00 00 a0 bb 0d | ................
048 | 00 24 00 00 00 01 00 00 00 02 00 00 00 00 00 00 | .$..............
064 | 00 01 01 00 00 00 02 00 00 00 00 00 00 00 01 00 | ................
080 | 00 00 | ..


The Group UpdateB packet and the two following have the merc's name.


[OPCode: 0x7139] OP_Unknown [Server->Client] [Size: 86]
000 | e1 ad 00 00 02 00 00 00 xx xx xx xx xx xx 00 00 | ........MyName..
016 | 00 00 00 xx xx xx xx xx xx 00 00 00 00 05 00 00 | ...MyName.......
032 | 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 | ................
048 | 44 69 61 73 72 69 72 31 30 32 37 39 39 00 01 00 | Diasrir102799...
064 | xx xx xx xx xx xx 00 05 00 00 00 00 00 00 00 00 | MyName..........
080 | 00 00 00 00 00 00 | ......




12/5/2011 2:56:58 AM
[OPCode: 0x7706] OP_Unknown [Server->Client] [Size: 16]
000 | 5c 02 00 00 c2 04 00 00 44 69 61 73 72 69 72 00 | \.......Diasrir.


I haven't checked to see if those opcodes have been figured out. I just wanted to post them for reference.

trevius
11-06-2012, 01:15 PM
I think those 2 unknowns are just normal group packets. They look pretty familiar just based on the info in them.

That 12/5/11 packet is interesting. Here is the breakdown of the packet into a struct as far as I can tell. Almost all of the fields match up with what I have seen on VoA other than the last extra field on VoA and the Status field for the new F2P membership stuff. Though, there appears to be an extra MercType field at the top of the struct, which is something I haven't seen before. Maybe if we try the struct like that, the update will work properly. I will see if I can figure out a good way to do that. I can't think of a good reason to have the MercType field redundant like that unless it is something to tell the client which is the highest type it currently has access to or something.

01 00 00 00 - 1 - MercStatus
e4 a4 bf 07 - 130000100 - MercType again ?
01 00 00 00 - 1 - MercCount
16 07 00 00 - 1814 - MercID
e4 a4 bf 07 - 130000100 - MercType
29 41 c0 07 - 130040105 - MercSubType
00 00 00 00 - 0 - PurchaseCost
00 00 00 00 - 0 - UpkeepCost
00 00 00 00 - 0 - AltCurrencyCost
00 00 00 00 - 0 - AltCurrencyUpkeep
13 00 00 00 - 19 - AltCurrencyType
00 - 0 - MercUnk01
a0 bb 0d 00 - 900000 - TimeLeft
24 00 00 00 - 36 - MerchantSlot
01 00 00 00 - 1 - MercUnk02
02 00 00 00 - 2 - StanceCount
00 00 00 00 - 0 - MercUnk03
01 - 1 - MercUnk04
01 00 00 00 - 1 - StanceIndex
02 00 00 00 - 2 - Stance
00 00 00 00 - 0 - StanceIndex
01 00 00 00 - 1 - Stance

bad_captain
11-06-2012, 05:22 PM
I think it is the same as the initial data response, where it has the number of types to follow, the merc type, the number of mercs that follow, and then the merc. From what I've seen after hiring 5-10 mercs during that time ( I was mostly trying to get the full response packets so I didn't get as much as I'd like of later packets), the first is always 1, followed by the type. I may be wrong though. I guess I never did try hiring and not actually get to hire. Maybe one of the other fields is status?

And thanks for fixing my post. I was in a hurry to go vote before work and missed that.

trevius
11-07-2012, 08:21 AM
Ahh, that makes more sense. I didn't even think about it that way because the struct I have from April 2 2012 shows the following structure:

[OPCode: 0x6537] OP_MercenaryDataUpdate [Server->Client] [Size: 93]

00 00 00 00 - 0 - MercStatus
01 00 00 00 - 1 - MercCount
8f 01 00 00 - 399 - MercID
e4 66 ab 13 - 330000100 - MercType
09 b5 ab 13 - 330020105 - MercSubType
bb 00 00 00 - 187 - PurchaseCost
b2 00 00 00 - 178 - UpkeepCost
01 00 00 00 - 1 - Status
00 00 00 00 - 0 - AltCurrencyCost
01 00 00 00 - 1 - AltCurrencyUpkeep
13 00 00 00 - 19 - AltCurrencyType
00 - 0 - MercUnk01
a0 bb 0d 00 - 900000 - TimeLeft
05 00 00 00 - 5 - MerchantSlot
01 00 00 00 - 1 - MercUnk02
02 00 00 00 - 2 - StanceCount
88 d5 8b c3 - 3280721288 - MercUnk03
01 - 1 - MercUnk04
4b 65 6b 6c 65 6b 00 Keklek - MercName
00 00 00 00 - 0 - StanceIndex
01 00 00 00 - 1 - Stance
01 00 00 00 - 1 - StanceIndex
02 00 00 00 - 2 - Stance
01 00 00 00 - 1 - MercUnk05

Note the additional fields I saw are in green, and MercUnk03 also has some data in it in the VoA collect, where yours looks almost just like what they do when sent as a merchant list with no data in MercUnk03.

Maybe they used to use the same structs for merchant lists and the data updates, but changed that later in VoA since some things like the MercTypes list are unneeded.

Either way, at least both versions are in this thread as examples for that packet, which may help for comparison purposes.

Secrets
11-07-2012, 09:56 AM
I can confirm that the OP_MercenaryDataUpdate packet that we have listed is not existent in any packet handlers for Seeds of Destruction. Not sure about underfoot but the opcode we have listed is not there at all.

Secrets
11-09-2012, 02:22 PM
http://i.imgur.com/SYhg9.jpg

http://i.imgur.com/1zlme.jpg

Secrets
11-09-2012, 06:59 PM
Gonna be committing the next part of the merc stuff tonight; I got the packets in order and well, a quite nice result:

http://i.imgur.com/IjZin.jpg

trevius
11-09-2012, 09:47 PM
Score! Good work :)

Secrets
11-11-2012, 05:35 PM
Mercenaries are now in an implementable state! I finished the last few bits of packet work over the last few days. We now can suspend/unsuspend, have a merc charge upkeep based on a timer, and all of these features are saving cross-zone.

I also tested in on the Underfoot client and it works just as well as titanium. The only thing that doesn't work is the auto-assist button but I assume we can implement that during the AI stuff. It's a simple button setting that the client sends to the server, and the server must send it back at some point. I could look into it, but I would rather get the AI stuff working before we go implementing an auto-assist/call target function!

bad_captain or trevius, if you would like to start work on the AI with me, that would be great. Thankfully we can just copy-paste bots for the most part. I'd like to see this go live on PEQ soon, would be nice to add this to an array of features EQEmulator has. And I can't even begin to imagine the custom server possibilities.

bad_captain
11-11-2012, 11:11 PM
Great work, Secrets!

I took a few days off, but planned on getting back to it. I was planning on working on the database side, for getting the basic stats per level, class, proficiency, etc., naming rules, and anything else that's still needed.

A decision that still needs to be made is whether mercs use equipment (and weapons) or max & min hit values. The benefit of using weapons would seem to be less balancing that would need to be done in the database, since there wouldn't be records that would need to be updated per level, class, proficiency, and tier. That's quite a few records to have to change if melee attacks are under or over powered. On the other hand, if weapons are used, it could require more data elements that need to be edited to change the resulting damage.

As you said, much of the AI can be copied from bots and edited where needed. I'm sure the stance code for bots can be improved, but that could provide a start. I'm still working to get all spells used, and I know they differ based on the selected stance, so that data still needs to be captured completely. I think I can currently come up with basic spell sets for all of them, but more data is needed, especially for higher levels.

Secrets
11-11-2012, 11:24 PM
Fairly certain on live mercs do not use weaponry, and instead have min/max values based on level. According to a few posts on ZAM, proficiency determines how many NPCs a merc can take on at once before feeling 'overwhelmed', an overwhelmed merc will fight but with a debuff. Not sure where the debuff is from or if it's a spell or anything. Tier determines the quality (dps output) of the mercenary.

Also, from limited testing on live, mercs seem to follow NPC stat rules more than PC stat rules. With the exception of HP, their damage seems more like that of an equal level NPC. For example, a level 50 mercenary deals around 151 points of damage and quad-attacks. This is close to being on par with a Plane of Justice sentinel, but with extra quad attacks. As for HP their HP is more so that of a player. They do not follow AA rules as far as I can tell, however, they have considerably more AC than a player would at that level. They seemed easily damaged by spell casters, so I assume they have very little resists.

I think the best way to do it would be min/max anyways; weapons do not make sense as mercenaries on live do not store items.

That only covers tank mercs, caster mercs are another animal entirely but from my testing they follow PC spell rules in general but only basic functionality; ie, heals, hots, very minor buffs (no resist buffs. hp/ac only), and cures. I didn't play live when caster (ranged dps) mercs were implemented so I cannot comment on them.

Due to the 'era' of what PEQ is in, If they were added on PEQ they would severely imbalance gameplay unless tweaked. The level 68 mercenaries were doing 768 damage quad (!) and that's a bit absurd for PEQ's DPS output at the moment.

Perhaps PEQ can increase the quality of mercenaries per expansion. They should always match the quality of NPC that is in the next expansion, for general rule of thumb. This is why SOE does level cap increases with most expansions; so they can balance out mercenaries and do a gear reset.

Robregen
11-12-2012, 01:15 AM
Due to the 'era' of what PEQ is in

could probably add in an optional rule to allow mercenary or what's not.

bad_captain
11-12-2012, 01:33 AM
Okay, I'll see what I can do stat-wise, and use min & max hit. Once it's in place and scaling somewhat, the attack & other combat code can be cleaned up.

For confidence, it also determines if and when a merc flees. I was 'moloing' around crushbone and had 4-5 even or higher con mobs attacking me, and had my merc high-tail it out of there. It was pretty funny.

I have spells cast by healer mercs for apprentice mercs through level 60. I will try to test on the test server with journeyman mercs for their spell lineups- it's based on stance, and journeymen have more stances available.

Once option is to have a scaling rule available where at 100 (%), merc damage output would be exactly what is listed in the database, whereas 50 (%) would be half that. That may be oversimplifying it, but I think something could be in place to easily allow server admins to adjust merc damage (and possible stats), without having to manually update thousands of records (or run a script updating all records).

sorvani
11-12-2012, 02:35 AM
Once option is to have a scaling rule available where at 100 (%), merc damage output would be exactly what is listed in the database, whereas 50 (%) would be half that. That may be oversimplifying it, but I think something could be in place to easily allow server admins to adjust merc damage (and possible stats), without having to manually update thousands of records (or run a script updating all records).

This would be the best way to handle it hands down. Most basic server admins can not do a lot of SQL and a simple rule would be perfect.

trevius
11-12-2012, 03:01 AM
could probably add in an optional rule to allow mercenary or what's not.

I believe PEQ has optional SQL that enables the Mercenary Merchants in PoK (at least). If someone doesn't want to use mercs, they just don't run that SQL. I know it changes the NPC names, but I am not certain if it changes their class to be Merc Merchant class or not. If it does change the class, then it should be fairly simple for servers to decide to use mercs or not by enabling the merchants or not. For anyone using Live collects (such as the ones Robregen has done), people would manually have to change all other zones with merc merchants like Crescent Reach or other newbie zones that might have them.

A rule would probably be fine, but I think the simplest rule would be to just have it disable the merchants. If it doesn't send class 71, then they can't get the mercenaries. We could probably add a rule to the fill spawn struct function to change class 71 to class 1 or something instead if mercs are disabled.

And yeah, from what I have read, confidence only effects how many NPCs they can have on their hate list before they start fleeing. There were some interesting posts on ZAMs about people finding ways around having their mercs flee when multiples were attacking. It probably wouldn't be too hard to copy that mechanic based on the info provided, but to me that sounds like implementing an exploit from Live just to try to copy it exactly.

I agree with Secrets that Live probably uses min/max for Mercs as well as stats instead of equiping armor. There is really no need to have them equip actual items unless they were going to allow those items to be changed out by players. Otherwise, it is just a waste of DB space for them and more DB hits than would be required without them.

I know there was a time when anytime you saw an NPC with a weapon, they actually had that weapon in their inventory. I am not sure exactly when that changed, but I am positive they don't do that all of the time anymore. I know at least by TBS they had started just sending weapon models with wearchange packets for NPCs that didn't actually wield the weapon they showed. I know this because I remember seeing an NPC in Stonehive with a weapon that wasn't on its corpse after I killed it (and wasn't something that is included with that NPC model). They probably changed that to be more flexible and maybe to mess with ShowEQ users as well, since I know people used to look for NPCs with weapons equipped so they knew which ones to go after.

BTW, awesome work so far, Secrets! Hopefully we will be ready to merge with the trunk soon.

blackdragonsdg
11-12-2012, 03:06 AM
While I like the idea of percentage based control over mercs I do think a rule should be in place to allow for complete disabling of the mercs. Not all servers will want the bots/mercs because of potential balance and/or performance issues. How about stick with the percentage idea but make 0% completely disable the mercs.

sorvani
11-12-2012, 03:55 AM
bots != mercs ever.

Mercs will always be active in code (once implemented) as that is the correct matching live route that EQEmu has taken. If you do not want them, do not add a merchant offering them, that is the customization route that EQEmu has taken.

Robregen
11-12-2012, 10:08 AM
another thing to consider is SoD+ clients are not available to purchase or download from stream at this time. Probably the majority of players use Titanium across most server. Unless someone wants to keep up with Live client to make it playable with emu to make use of mercenaries.

bad_captain
11-12-2012, 10:53 AM
The way it is currently in the database (and handled by the server), is that it will not send the data to the client if they do not match the correct client version. So, if a client is using titanium, it won't send any data to it (and it wouldn't be able to handle it anyway).

If the majority of users use titanium, then they have the ability to use bots, if the server allows it, of course.

I guess we just have to hope that they put another version of EQ on steam or somewhere else for purchase.

Noport
11-13-2012, 12:14 AM
Secrets said, Fairly certain on live mercs do not use weaponry, Problem has been solved they do now 80)

trevius
11-13-2012, 08:41 AM
Probably the majority of players use Titanium across most server.

I don't think that is the case anymore. I think TFH is about 50% SoD+ clients, and EZ is probably 90% or more now. I don't know offhand what the numbers are for PEQ, but they are probably 50% or so as well for SoD+ clients. Most people run the UF client these days. Even though Titanium and SoF are the only legally available clients, they are still fairly hard to come across and most people don't bother trying to find them. The majority of clients attained these days are probably from illegal downloads. It is unfortunate there isn't a better option at this time, but it is what it is. At least most people who would want SoD or UF could probably get them if they really wanted to so they can use mercs and such.

Hopefully at some point in the future we will have a legal route for clients again that isn't so hard to locate and purchase (especially considering international players).

Sounds like Noport tried the MercsAndBots branch and saw that they are wielding weapons (which they always have on the branch). I guess he thinks that means we figured out the solution to the Mercs equiping weapons discussion in this thread. That is my interpretation anyway. Problem solved!

KLS
11-13-2012, 06:59 PM
I've stuck this since it's currently active.

Also yeah the client thing is becoming an issue. I think realistically we're going to have to have a discussion about actually creating our own client sooner or later.

Caryatis
11-13-2012, 08:21 PM
Thats going to be an interesting discussion considering the current stance on torrents. At least with torrents, there is wiggle room as if you bought something and lost the CDs you are kind of entitled to that data still, however its much more cut and dry when you are talking about ripping out the intellectual property(models, textures, zones, etc) and using them in your own product.

KLS
11-13-2012, 09:41 PM
It's not really anything new, game recreations requiring original installs have been around for a long time. Regardless this isn't the place.

Secrets
11-13-2012, 10:32 PM
Just an update, moved mercs to NPC derived, gonna be a lot of bugs/un-implemented things that were bandaided before, such as merc death, merc zoning, etc.

Group joining/states will also be a pain to work with, from my limited testing.

Committing what I did tonight though

trevius
11-14-2012, 07:56 AM
Committing what I did tonight though

Did this commit go in? The last rev I see is 2255 from Nov 11th.

The sooner we can get this on the Trunk, the better, I think. I know Akka has a big change ready to go that might be a bit of a pain to get merged into the branch.

Inheriting mercs from NPCs will likely require quite a bit of work and testing to get the kinks all knocked out. It does make sense since technically mercs are NPCs. It would probably require a lot more duplicated code leaving mercs as their own class under mob. I kinda liked the idea of mercs being directly under mob, but hopefully having them under NPCs can be worked out before too long if we stick with using that route. I think having them as their own class directly under mob would probably allow for a cleaner and more flexible solution (even with duplicated code).

bad_captain
11-14-2012, 04:44 PM
That why I created them under mob, but with stats being handled more like NPCs, I can see why it might work.

I have been working on getting stats in the database. I'm looking through my logs while writing a script to generate the stats and insert statements. I'm getting close to having something usable that can be tweaked, but I have little data for mercs > level 65, besides just DPS numbers ( no max hits, etc). If anyone has any readily available, I'd appreciate it.

Secrets
11-14-2012, 06:30 PM
Been terribly busy, sorry :x am fixing up my local source, then I'll commit it tonight.

edit: just committed it.

Secrets
11-14-2012, 07:28 PM
Just an inquiry, can we use the scalerate field in NPC_types and keep them in their own range?

That seems like it would make the most sense, people are more than capable of doing an update query by ID, and we can keep templates somewhat modular that way.

Thoughts?

bad_captain
11-15-2012, 12:00 AM
I'm not sure what you mean 'in their own range'? I think it's been agreed that keeping mercs in a separate table from npc_types makes the most sense, if that's what you mean. KLS commented on that earlier.

Keep in mind, we need to include spell damage modifiers (per spell type, as I believe HoT spells aren't affected), as well as melee skills or discs, which don't conform to the npc_types table.

I agree some kind of scaling feature would be nice, but I also think allowing for complete customization has its benefits as well. I may have come over to Trevius' thinking in that respect. I'm not sure some aspects match a specific scaling rate, as looking at maxhit from lvl 1-60 does not seem to follow any particular equation, or any set of equations. I'm sure the same can be said of spell damage modifiers, etc. This also allows customization shown in live pets, where one particular pet focused with a particular focus has extreme regen - a bug I'm sure, but created some differentiation. SOmething similar could be done with something like the mercenary contracts, where obtaining a contract and hiring your mercenary that way results in a superior merc than what is available from the merchant, at the same proficiency and tier.

What I had planned to do was basically split the npc_types table in two and pull out any unneeded fields, and end up with a stats table (hp, mana, str, sta, resists, regen, etc for each level of a particular proficiency and tier), a texture table (to store visible textures and tints- weapons seem to change every 5 levels, and armor maybe every 20 or so?) - no need to duplicate the textures for every level. Then, one more table for the spell & skill mods (instant heal mods, nuke mods, buff duration mods if any, etc.).

trevius
11-15-2012, 04:37 AM
I think the npc_types_tint table could be re-used for mercs as well. We would just need to add texture/model fields for each slot. It would be good to have that option for NPCs as well anyway, so you could have different textures for each slot if you wanted (plate chest, chain legs, etc). Then you would just assign a tint set ID to the merc and it would give the appropriate look.

I haven't tried the RoF beta yet (and don't plan to), but I hear that mercs may now have a new UI window that lets you at least view the equipment they are using. I don't have much detail on the subject, but if this is true, it would confirm that mercs do in fact equip gear. If no one can confirm now, we may have to wait until it goes live to be sure. Mercs equiping items could be something new to Live (assuming the info is true), or they may have done it all along.

Either way, even if it is true that Mercs can use gear, that is something that could always be added in later. Just like NPCs can use gear or not. It can factor into their combat, but not on the same scale as it does for player characters.

It is very possible that the casting bonuses and such come directly from focus effects on worn items. Though, it would be nice to have the option to change those values directly via a table like bad_captain mentioned.

As mentioned, a scaling option would be good if it could be worked out properly, but I think it would be pretty hard to really properly scale more than a few levels at a time. There may still be a good way to consolidate the large number of DB updates that would be required otherwise, though. We may be able to split stats out into a couple more tables and assign IDs from those stat tables to individual merc templates. There are probably different stats that overlap between different merc types. Maybe all tiers use the same STR/STA/INT/WIS/AGI/DEX/CHA and Resist values for each respective level of the merc, but they use different min/max and hp/mana/AC values. We could have one table that deals with stats and resists, then another that deals with min/max damage and hp/mana/AC, or whatever. It may take some analysis and thought to see if this approach would be worth-while, but if it can consolidate the amount of entries considerably, it could be worth it. Just kinda thinking out loud here, heh.

Trackye
11-15-2012, 08:52 AM
Trev these were found on a Merc FAQ I was looking at

Q: Can I give my mercenary weapons and armor similar to a pet?

A: No. your mercenary comes equipped with the armor and weapons he needs. Also his armor and weapons will get better as he levels up.

source http://almarsguides.com/eq/general/mercenaries.cfm


Can I give the mercenary gear?
No, you cannot gear the mercenaries or hand them any thing at all.

Source : http://www.necrotalk.com/showthread.php?t=9993

So it may be that in ROF giving them equipment is new..But looks like atm you cannot and their gear scales accordingly with preset sets of Gear based on level.

trevius
11-15-2012, 10:30 AM
Ya, but the information may not be accurate in those FAQs. They say that mercs come with their own gear, but they don't know for sure if that means they actually have a full set of equiped items (inventory) or if they are just simulating a set of gear by sending texture and wearchange packets and adjusting NPC stats accordingly to scale. Considering that all of the mercs I have seen in the past only wore armor with no tint, that makes me lean toward them just sending a texture change. If they were using actual gear, why not use existing gear sets made for players (which would have a tint applied)? Of course, they could also send a tint to simulate that as well, which we already have an option for in the emu.

Noport
11-15-2012, 11:16 AM
http://i.imgur.com/ABQu4.jpg

sorvani
11-15-2012, 11:49 AM
I have not looked into the MQ2 source for their spawn searches but found this over on their forums
You're right, anything doing a spawnsearch using "pc" will not return a merc- there is "mercenary" for that (I use Autobot and had to heavily modify it to allow a tank merc as MT).

bad_captain
11-15-2012, 03:01 PM
I'm tempted to just go ahead and add in equipment, as it won't be that much work (minus weapons), and it will affect the stats used as base stats (what I'm working on now & they would need to be significantly adjusted later if equipment we added). Not only that, but secondary stats such as spellshield, healing amount, etc would need to be addressed. Equipment allows mercs to have those stats without having to give them the stats initially. Plus, it allows for a lot of possible customization.

I would be curious to see just what equipment they do use on live, if any. I know it was odd to see my tank merc alternate between weapon types, using 1hs, 1hp, and hand-to-hand weapons at lower levels.

Also, not sure about this, but just because a merc is 'wearing' a piece of equipment doesn't necessarily mean it has to use that texture, right? They could use the equipment for stats, but display what we specify, correct?

trevius
11-15-2012, 09:25 PM
I haven't tried the RoF beta yet (and don't plan to), but I hear that mercs may now have a new UI window that lets you at least view the equipment they are using. I don't have much detail on the subject, but if this is true, it would confirm that mercs do in fact equip gear. If no one can confirm now, we may have to wait until it goes live to be sure. Mercs equiping items could be something new to Live (assuming the info is true), or they may have done it all along.


FYI, the info quoted above is false.

And, Noport, mercs have always displayed weapons and armor like you show in that pic. That is nothing new. It doesn't mean that they actually equip any of the items they are displaying, it could just be (and most likely is) for display only.


Also, not sure about this, but just because a merc is 'wearing' a piece of equipment doesn't necessarily mean it has to use that texture, right? They could use the equipment for stats, but display what we specify, correct?

That is correct. We can send texture changes, or wearchanges to make any NPC appear to wear/wield whatever we want, no matter what their inventory actually is (or isn't). Keep in mind that there is 1 extra step that has to be taken to make different weapon type changes work as needed; we have to also change the attack message to match the weapon model (slashes, crushes, etc). NPCs already support this type of change in fields of the npc_types table.

Noport
11-15-2012, 09:43 PM
i'll say this Trevius is correct there is nothing new. my mercenary hits for 2k a swing not counting crits. this is what you get when you receive your mercenary this is a tier V mercenary. the mercemary ui looks just like what Secrets posted (just for display only).

Caryatis
11-15-2012, 11:53 PM
I think its fairly obvious that mercenaries wear opcodes.

bad_captain
11-16-2012, 01:18 AM
The sooner we can get this on the Trunk, the better, I think. I know Akka has a big change ready to go that might be a bit of a pain to get merged into the branch.


I think if we make sure all servers can continue to run without mercs after getting latest, it should be able to be merged now. And for that to happen, we just need a simple script to change the 9 mercenary liaisons (class_id 71) to guards or whatever, then we should be good to go. (I have 9, stock peq may have fewer- I can't remember if I've added any mercenary liaisons)

We still need the scripts to change all of the current PoK guards into mercenary liaisons, but that shouldn't be too much work. I have a bunch of collects, so I think I'd just need to create the scripts and test it all out. This would then be added to the current mercs.sql to fully enable mercs on servers who want them.

KLS
11-16-2012, 06:08 PM
Could you not add a rule that just makes them not respond?

Secrets
11-16-2012, 06:59 PM
Could you not add a rule that just makes them not respond?

Would probably be the best way to do it. I just got a job irl (shocking i know) so i'll have less time to work on this but i'll see about doing that.

Akkadius
11-16-2012, 09:59 PM
You really really aren't going to want to merge all of my changes manually, so give me an idea of when this is going to happen.

bad_captain
11-16-2012, 10:51 PM
Yeah, not sure what I was thinking. I guess that's what I get for posting so late. A rule would be best. I would say sometime this weekend, Akkadius.

bad_captain
11-17-2012, 01:53 PM
Secrets, I took a look at your code and have a question. Why did you put the merc_npc_type_id in the merc_types table instead of putting the merc_type_id, merc_template_id, or something else within merc_npc_types to designate what it belongs to?

Because the stats aren't dependent on race, the table I created for holding merc stats had the class, proficiency, tier, and level to designate which record to use. Unless I'm missing something, I'm not sure how to get a specific record within the merc_npc_types table, although I guess id isn't auto_incremented, so I guess you could reuse the id multiple times. But, again, the stats aren't race dependent (I guess the appearance fields may be; although they are actually randomly generated on hire and may not be necessary to have in the table. They aren't level dependent anyway so it may be best to put that stuff in another table to avoid duplication). Plus, having to update the merc_types table with an arbitrary id from another table after the data has been generated, will most likely be tedious, and to me, harder to maintain.

If we add in trevius' suggestion to use the npc tints table (or at least a copy of it for mercs), it may be best to pull out the textures and tints to another table, especially since they will not be changing every level (I don't think armor changed but every 10-20 levels, where weapons changed every 5). I haven't done this in my example, but could easily be done.

Also, some of the fields in npc_types aren't relevant to mercs, and could most likely be removed.

Just for reference, here's how I had it broken down (I could easily remove the id and just use class, proficiency, tier, and level as the primary key - I just prefer one field for the key that is not dependent on any other field or in any way related to the actual data):


CREATE TABLE merc_stats (
id int(11) NOT NULL auto_increment,
class tinyint(2) unsigned NOT NULL default '1',
proficiency tinyint(3) unsigned NOT NULL default '1',
tier tinyint(3) unsigned NOT NULL default '1',
level tinyint(2) unsigned NOT NULL default '1',
hp int(11) NOT NULL default '1',
mana int(11) NOT NULL default '0',
AC smallint(5) NOT NULL default '1',
ATK mediumint(9) NOT NULL default '1',
STR mediumint(8) unsigned NOT NULL default '75',
STA mediumint(8) unsigned NOT NULL default '75',
DEX mediumint(8) unsigned NOT NULL default '75',
AGI mediumint(8) unsigned NOT NULL default '75',
_INT mediumint(8) unsigned NOT NULL default '80',
WIS mediumint(8) unsigned NOT NULL default '80',
CHA mediumint(8) unsigned NOT NULL default '75',
MR smallint(5) NOT NULL default '15',
CR smallint(5) NOT NULL default '15',
DR smallint(5) NOT NULL default '15',
FR smallint(5) NOT NULL default '15',
PR smallint(5) NOT NULL default '15',
Corrup smallint(5) NOT NULL default '15',
mindmg int(10) unsigned NOT NULL default '1',
maxdmg int(10) unsigned NOT NULL default '1',
attack_count smallint(6) NOT NULL default '-1',
attack_speed float NOT NULL default '0',
specialattks varchar(36) NOT NULL default '',
Accuracy mediumint(9) NOT NULL default '0',
hp_regen_rate int(11) unsigned NOT NULL default '1',
mana_regen_rate int(11) unsigned NOT NULL default '1',
runspeed float NOT NULL default '0',
PRIMARY KEY (id)
)

CREATE TABLE merc_armortextures (
id int(11) NOT NULL auto_increment,
class tinyint(2) unsigned NOT NULL default '1',
proficiency tinyint(3) unsigned NOT NULL default '1',
tier tinyint(3) unsigned NOT NULL default '1',
minlevel tinyint(2) unsigned NOT NULL default '0',
maxlevel tinyint(2) unsigned NOT NULL default '0',
texture tinyint(2) unsigned NOT NULL default '0',
helmtexture tinyint(2) unsigned NOT NULL default '0',
armortint_id int(10) unsigned NOT NULL default '0',
armortint_red tinyint(3) unsigned NOT NULL default '0',
armortint_green tinyint(3) unsigned NOT NULL default '0',
armortint_blue tinyint(3) unsigned NOT NULL default '0',
PRIMARY KEY (id)
)

CREATE TABLE merc_meleetextures (
id int(11) NOT NULL auto_increment,
class tinyint(2) unsigned NOT NULL default '1',
proficiency tinyint(3) unsigned NOT NULL default '1',
tier tinyint(3) unsigned NOT NULL default '1',
minlevel tinyint(2) unsigned NOT NULL default '0',
maxlevel tinyint(2) unsigned NOT NULL default '0',
d_meele_texture1 int(10) unsigned NOT NULL default '0',
d_meele_texture2 int(10) unsigned NOT NULL default '0',
prim_melee_type tinyint(4) unsigned NOT NULL default '28',
sec_melee_type tinyint(4) unsigned NOT NULL default '28',
prim_melee_delay tinyint(4) unsigned NOT NULL default '30',
sec_melee_delay tinyint(4) unsigned NOT NULL default '30',
PRIMARY KEY (id)
)


Any thoughts, or am I thinking too deeply about avoiding duplicate data within the table? I'm mostly just trying to keep it as easy as possible for admins to manage, as well as us if we need to make tweaks (which we will).

bad_captain
11-17-2012, 03:35 PM
Also, is the purpose of the client_level just so we can have mercs not have the same level as clients if admins want to?

Secrets
11-17-2012, 05:07 PM
Also, is the purpose of the client_level just so we can have mercs not have the same level as clients if admins want to?

The purpose of client_level is to assign an appropriate template for the client's level. For example, let's say a merc template is an erudite paladin and the client is 66. The two key system works like this:

merc_npc_type ID 644, level 66: We get the stats, appearance (some mercs have weapon changes and/or texture changes on specific pieces of gear at specific levels) of merc type 644. We duplicate the race/class appearance currently in the table and that can be changed. What is not duplicated however is the stats, weapon appearance, and any other npc-specific fields.

If the client is 65, and the merc_npc_type ID is 644, we get ID 644-65 instead. This allows us to fine-tune npcs by ranges at the expense of more database entries. Keep in mind we're not loading this entire table, only specific NPCs as they are referenced just like the npc_types table, so it is highly memory efficient as well.

What is loaded, however, is the entire list of templates. We reference a specific template, which references a specific merc_npc_type_id. When it comes time to actually getting the template, we have to pass the client's level to the equation in getting the absolute proper merc_npc_type_id

This allows us to fine-tune a merc_npc_type to a specific level. For example, from 65 to 66 on live, I believe there's a rather large gap in power. A simple scaling template will not be plausible in that scenario. Also, npc weapons vary depending on level. I suppose we could template that as well, not sure.

The class/race IDs are still there in the templates table right now for determining stances. No other purpose is what I intended... might be bugging out atm though. Just for live-collected data purposes.

I suppose we could have appearance in its own table and assign each merc_npc_type an entry, but that seems like it would overcomplicate things by adding another table.

bad_captain
11-18-2012, 12:48 AM
Is there any difference between client_level and level in merc_npc_types? Since the merc is supposed to be the same level as the client, couldn't you just go by level? It's not a big deal, just curious.

Also, I don't think having the merc_npc_type_id in the merc_types table will work. There will by many merc_npc_types for every merc_type. Merc Types are what show up in the dropdown of the mercenary purchase window. It only relies on the race and proficiency (apprentice or journeyman). Subtypes include the class & tier. The merc_npc_types table will also depend on the merc_subtypes, since there will be different stats for different classes & tiers. You could put it in merc_templates, but because the stats really don't depend on race, you would have to duplicate the merc_npc_type_id for each record in merc_templates with the same class, proficiency & tier. That's why I just included the class, proficiency & tier in my stats table, but it could be done in merc_templates as well.

I just want to make sure I understand your logic before putting the stats in, since it will be harder to change once it's merged into the trunk and people start playing around with them.

Secrets
11-18-2012, 12:55 AM
Is there any difference between client_level and level in merc_npc_types? Since the merc is supposed to be the same level as the client, couldn't you just go by level? It's not a big deal, just curious.

Also, I don't think having the merc_npc_type_id in the merc_types table will work. There will by many merc_npc_types for every merc_type. Merc Types are what show up in the dropdown of the mercenary purchase window. It only relies on the race and proficiency (apprentice or journeyman). Subtypes include the class & tier. The merc_npc_types table will also depend on the merc_subtypes, since there will be different stats for different classes & tiers. You could put it in merc_templates, but because the stats really don't depend on race, you would have to duplicate the merc_npc_type_id for each record in merc_templates with the same class, proficiency & tier. That's why I just included the class, proficiency & tier in my stats table, but it could be done in merc_templates as well.

I just want to make sure I understand your logic before putting the stats in, since it will be harder to change once it's merged into the trunk and people start playing around with them.

Could do it by level, I just wanted to have the opportunity for different merc levels than what the client is actually having for custom server purposes. For example, a merc might be level 44 for a level 50 character, 45 for a 51, etc, in a custom scenario anyways.

I wanted to leave it open-ended enough that PEQ and other servers that need the merc to be more modular can use it in their own way without having to change too much.

Currently the class/race is set from the merc's template, not the merc_npc_types table. If you would like to trim that merc_npc_types table of duplicate entries be my guest.

Secrets
11-26-2012, 07:33 AM
Made a ton of progress tonight. Mercs now save groups across zone, they now show up as 'in the zone' on the group window. They do not save health or any buffs across zones yet. I'd say the basic functionality works great so far.

Gonna commit it later tonight after I fix it up a bit. Perhaps we can start moving it into the main branch? It seems 'ready' so to speak. I'd like to see about PEQ trying to break them when I commit it to SVN and we have PEQ's database updated.

Secrets
11-26-2012, 07:37 AM
Picture of the mercs in groups. When one merc is removed, they get suspended. Not sure if that's how live intended mercs, but it seems 'better' imho.

When the leader is removed, the merc gets added to a new group with the person who got kicked.

Currently, you have to unsuspend your merc once you are in a group. Perhaps support for pending invites from players both merc grouped could be added later.

http://i.imgur.com/o4TcC.jpg

bad_captain
12-14-2012, 11:40 AM
Updated mercs last night. It includes a significant database update, and mercs.sql will need to be re-run for it all to work. There were really too many to create an update, so just source in mercs.sql again. The only other thing needed from secret's update 2 is adding ismerc to the one group table.

There are now merc stats for up to level 85. Up to 65 should be reasonably close, but more data is needed after that. Once mercs are able to act in combat, a better approximation can be made on some stats. Hp, mana, and maxhit would be the three most important to update post 65. We may need to add in the advanced stats, or add in equipment (I've read a few rumors of mercs having cloaks or something similar to pets (which are equipped based on pet power), and include the advanced stats. Depending on how well mercs perform in battle may help decide how to approach this.

Armor and weapon textures are set from the database. Currently, there's a record per proficiency/tier/class combination (check out reference table, merc_npc_types). Melee mercs have two records, one prior to dual wield, and one after. Healers and casters have one record only. This should suffice until more important work is accomplished. Weapon textures set from db is used instead of the previously hard coded values.

Mercs level with you- they will update stats when you level, but will con dark blue until you zone/suspend/etc.

Note: merchants are given the merc data if they should, but the npcs still need to be updated for correct placement, race, gender, etc. Two vendors that work are Mjdai in crescent reach tent, and guardian norerd in pok, who is at the top of the bridge by the soulbinder.

Two bugs I've noticed: after zoning, suspending/unsuspending, my merc no longer follows me ( code appears to be there to set the correct followID), and after dismissing a mercs, then rehiring, the second merc doesn't have stance data in merc window.

I will try to update my earlier post concerning what still needs to be accomplished for mercs tonight. I will be testing out the bugs listed earlier, and work on getting mercs into combat. I will need some more data on spell lists for healers and dps casters. I will focus on melee mercs first.

I also merged in everything from the trunk, so if everything checks out, it should be able to be merged into the trunk. A sql update would need to be added for the merc rules that have been added into the source. I can try to add that this weekend as well.

bad_captain
01-08-2013, 07:15 PM
I committed mercs to the trunk.

I split out the sql into 4 files which need to be sourced for mercs to work correctly:

OPTIONAL SQL: utils/sql/svn/2380_optional_merc_rules.sql
OPTIONAL SQL: utils/sql/svn/2380_optional_merc_merchant_npctypes_update.sql
OPTIONAL SQL: utils/sql/svn/2380_optional_merc_data.sql
OPTIONAL SQL: utils/sql/svn/mercs.sql

Splitting it up was done to keep rules separate from the data, and some servers may not need to update the PoK merc merchant spawns. The merc data that should not change much if at all is in the merc_data.sql, while merc stats, textures, and eventually spells & discs will be put into mercs.sql. This way, whenever changes are made to merc stats or spell casting AI is finalized, you will only need to source mercs.sql instead of the whole thing.

Included in the commit is basic merc functionality for melee (tank) mercs. Healing & Caster DPS mercs do not have spell lists or spell casting AI yet. I currently compiling spell lists for them, and I am adding the AI for the next commit.

Mercs do not currently charge you for being purchased or upkeep (the code just need to be uncommented), but until they are more functional, I would keep it commented out. I think a rule could be added as come servers may not want to be charged anway, but for now, I just have it commented out.

Current bugs I will be working on are the merc timer and stance bugs. SOmetimes, stances fail to show up (rarely) when hiring a merc, and sometimes (often the same time), the merc timer doesn't function. This will be addressed before players are charged for mercs.

I will update my earlier post about the current state of mercs and what still needs to be accomplished, but for now, I wanted to state that you can at least play around with them. They should group with you, attack when you get aggro, level with you, and increase in power as you level.

I'm still looking for post 65 data for mercs as far as HP, max hit, spells lists, etc. Just include class, proficiency, tier, and level please.

sorvani
01-08-2013, 11:57 PM
The newb merc you get in me tutorial on live has no purchase cost or upkeep cost. So the base merc code should account for a merc with no costs.

bad_captain
01-09-2013, 12:07 AM
I haven't look at the tutorial yet. If the player is below level 10, there shouldn't be a cost or upkeep. Is the merc from a merchant in the tutorial zone? I think if we add data to their merchant list, it should show up as being 0. If nothing is sent to them, it reads as 123p or something. I still need to get spawn data for merc merchants in starting cities, then I can finalize the merc merchant stuff. PoK should be done, and I know the one in Crescent Reach works.

bad_captain
01-26-2013, 05:32 PM
Today, I committed the initial spell casting code & AI. The spell data is in the mercs.sql file, which should be rerun. With this commit, healers should heal and tanks will use their aggro discs. I'm still working on dps mercs. For now, stances don't factor in, but will be added in soon.

Another issue I'm working on is the built in merc focus effects. I have most of the data, they are just not implemented yet.

Feel free to comment.

Noport
01-26-2013, 05:40 PM
i picked up on another opcode that might have to with mercs found in 1-16-13 patch [OPCode: 0x27af] OP_MercenaryUnknown2 [Server->Client] [Size: 68] Merc Name????????*** i'll look back on patch 12/12/12 and see if i can find it. 0x38e3 12/12/12 [Size: 68]

all found in patch 1-16-13

[OPCode: 0x60a8] OP_ZoneEntry [Client->Server] [Size: 76] Players Mercenary or Quest,Corpse,Mercenary Liaison, a_diseased_spiderling's_corpse
[OPCode: 0x39a1] OP_MercenaryTimerRequest [Client->Server] [Size: 0]
[OPCode: 0x6e0e] OP_MercenaryUnknown1 [Server->Client] [Size: 1]
[OPCode: 0x35cc] OP_GroupFollow [Server->Client] [Size: 148] Char Name with Merc Name
[OPCode: 0x27af] OP_MercenaryUnknown2 [Server->Client] [Size: 68] Merc Name????????***
[OPCode: 0x1919] OP_MercenaryDataUpdateRequest [Client->Server] [Size: 0]
[OPCode: 0x27a5] OP_MercenaryList [Server->Client] [Size: 94] Merc Name ??? OP_MercenaryDataUpdate
[OPCode: 0x5de1] OP_Find [Server->Client] [Size: 112] Blightfire Moors Zone, Banker Etc, Quest,Mercenary Liaison ?? OP_SendFindableNPCs

Shiny151
01-26-2013, 06:25 PM
Today, I committed the initial spell casting code & AI. The spell data is in the mercs.sql file, which should be rerun. With this commit, healers should heal and tanks will use their aggro discs. I'm still working on dps mercs. For now, stances don't factor in, but will be added in soon.

Another issue I'm working on is the built in merc focus effects. I have most of the data, they are just not implemented yet.

Feel free to comment.

Great work. Looks to be working okay so far. They are buffing me; only thing I've noticed right away is I'm getting continuously spammed by their upkeep cost. Not tried combat with them yet. Thanks captain, impressive so far. Look forward to future updates.

gibroni
01-26-2013, 07:00 PM
is there a specific order to run the sql for mercs? wanted to try em out, but having issues trying to run those sql's. only getting errors with em.

bad_captain
01-26-2013, 07:31 PM
From the changelog:
REQUIRED SQL: utils/sql/svn/2383_required_group_ismerc.sql -- adds ismerc column to group_id table
OPTIONAL SQL: utils/sql/svn/2380_optional_merc_rules.sql -- Contains rules for mercs including rule to enable mercs
OPTIONAL SQL: utils/sql/svn/2380_optional_merc_merchant_npctypes_update.sql -- Contains npc_types & spawn updates for merc merchants in PoK
OPTIONAL SQL: utils/sql/svn/2380_optional_merc_data.sql -- Contains basic merc data, template info, & merc merchant entries
OPTIONAL SQL: utils/sql/svn/mercs.sql

Do them in that order. Actually, you just need to do 2380_optional_merc_merchant_npctypes_update.sql before 2380_optional_merc_data.sql, before mercs.sql

The rules one and isMerc for group_id can be done whenever.

sorvani
01-26-2013, 07:31 PM
run mercs.sql last.

gibroni
01-26-2013, 08:08 PM
thanks, that worked for the most part. at the end of sourcing the last one (mercs.sql) i get an error that says " column spell_id cannot be null". gives me four of those errors right at the end.

bad_captain
01-26-2013, 09:07 PM
Yeah, that happens if the spells_new table doesn't have all of the correct spells. On the default peq spells_new (at least from a while ago), many if not most of the 75-80 spells are duplicates of the 70-75 spells, so it's not matching the spell name.

You can remove the ones it didn't find by doing:
DELETE FROM merc_spell_list_entries WHERE spell_id = 0;

Or, update the spells_new table to have all of the correct spells.

I'll see if I can add the missing spells as needed later.

gibroni
01-26-2013, 10:44 PM
ok just a question now that i had a second to install and see it for myself. Upkeep is charging every 3 minutes, not sure if that has been changed, but back a few years when i played upkeep was charged every 10 minutes.


nm i see it can be set in the db

trevius
01-26-2013, 11:14 PM
Yeah, I think the SQL for the upkeep cost was committed as testing settings, where it is easier to tell if upkeep is working properly when you don't have to wait 15 minutes between each one. On live, it is 15 minutes for upkeep and 3 minutes for the suspend interval. If you want to set that, you can run the following SQL:

UPDATE rule_values SET rule_value = 900000 WHERE rule_name = 'Mercs:UpkeepIntervalMS';
UPDATE rule_values SET rule_value = 900 WHERE rule_name = 'Mercs:UpkeepIntervalS';
UPDATE rule_values SET rule_value = 180000 WHERE rule_name = 'Mercs:SuspendIntervalMS';
UPDATE rule_values SET rule_value = 180 WHERE rule_name = 'Mercs:SuspendIntervalS';

I think the upkeep timers are still a bit flakey, but hopefully we can get that stuff ironed out along with a few other things soon.

gibroni
01-27-2013, 03:05 AM
noticed that after zoning the mercs mana goes to zero. so it isnt retaining their mana when zoning.

bad_captain
01-27-2013, 01:43 PM
Yeah, nothing is saved currently. I plan on working on buffs & other stuff in the next couple days.

Drajor
02-04-2013, 11:27 AM
I left Trevius a message on IRC but I am really not sure who this should go to.
After looking into the dbstr_us.txt file changes I was able to pull out data for 2375 mercs. The data includes ID, Race, Type, Confidence, Proficiency and Tier.

Anyone want it?

bad_captain
02-04-2013, 04:01 PM
What's in there that's not already in game? I haven't looked at RoF to see if there were any new mercs, but the rest should be in there ( then again, half or more of them are only available through expansion purchases, special merchant contracts, and other methods that may not be available in game).

Drajor
02-05-2013, 12:17 AM
What's in there that's not already in game? I haven't looked at RoF to see if there were any new mercs, but the rest should be in there ( then again, half or more of them are only available through expansion purchases, special merchant contracts, and other methods that may not be available in game).

I don't know. I haven't played live since PoP!

thepoetwarrior
02-07-2013, 11:35 AM
Some of these rule values seem duplicated.

Mercs:SuspendIntervalMS
Mercs:SuspendIntervalS

Mercs:UpkeepIntervalMS
Mercs:UpkeepIntervalS

Mercs:AggroRadius
Mercs:AggroRadiusPuller

Is one or the other obsolete?

bad_captain
02-07-2013, 08:47 PM
The top two sets are, and I think were done for convenience. The last pair are not, as it allows two different aggro radii, depending on if the mob's target is the puller or not (puller radius is smaller, or they would run out to attack before you want them to.)

trevius
02-08-2013, 12:39 PM
Here are the default rule settings from ruletypes.h for the merc timer stuff:

RULE_INT (Mercs, SuspendIntervalMS, 10000)
RULE_INT (Mercs, UpkeepIntervalMS, 180000)
RULE_INT (Mercs, SuspendIntervalS, 10)
RULE_INT (Mercs, UpkeepIntervalS, 180)


I dunno why they were done in seconds and ms, since we could just multiple or divide by 1000 in the source to switch from seconds to ms. I think the reasoning was because some places use seconds and some use ms, so it might be a bit less resources to not have to do the math even though the math is pretty simple/quick. We can probably remove whichever rule is used the least and just do the math for the seconds or ms depending on which one is kept. Either way, for now, just make sure they are the same amount of time for the MS and S rules with the same name (as shown in the defaults).

To be Live-Like, the UpkeepIntervals should actually be 15 minutes, otherwise you get spammed every 3 minutes about upkeep costs. Currently, upkeep costs are disabled until the merc stuff is more finalized, so there is no actual charge that happens, just a message about it.

Thuz989
02-24-2013, 10:56 PM
I would love to see mercs succeed. That being said here is what i am observing..

ROF clients trying to zone with most mercs = zone crash Ill have to compile with debug and try this...

Cleric mercs just chain cast group loyalty buffs
Cleric mercs just keep chain casting group hp buff if it cant buff pet of PC.

When you dismis a bot, it still hows on your screen, and is targetable, but strangely enough you can do anything to it. Still shows in group. Zoning seems to clear the issue ONLY for the PC that zoned. everyone else can still see merc in group and standing there doing nothing.

After you dismiss a merc it is not deleted from database.

I realize its an enormous amount of work, and i appreciate your efforts.

Shiny151
02-25-2013, 01:29 AM
The top two sets are, and I think were done for convenience. The last pair are not, as it allows two different aggro radii, depending on if the mob's target is the puller or not (puller radius is smaller, or they would run out to attack before you want them to.)

So since the 2/18 merc update with:

REQUIRED SQL: 2013_02_18_Merc_Rules_and_Tables.sql
OPTIONAL SQL: 2013_02_18_Merc_Spells.sql

...is the mercs.sql in the utils\sql\svn still required as well?

myeqsf
02-25-2013, 07:40 AM
How unlock mercs slot one more?

trevius
02-25-2013, 08:18 AM
How unlock mercs slot one more?

That is not possible yet in EQEmu. The only client we have that can even support that option is RoF. And there are probably some new packets that deal with owning multiple mercs that we have not yet looked into.

bad_captain
02-25-2013, 09:51 AM
So since the 2/18 merc update with:

REQUIRED SQL: 2013_02_18_Merc_Rules_and_Tables.sql
OPTIONAL SQL: 2013_02_18_Merc_Spells.sql

...is the mercs.sql in the utils\sql\svn still required as well?

No, from now on, all sql scripts will be in the git folder. They are basically the same file.


Edit: the file referenced in my git commit about merc spells is the same as the one you referenced. The earlier files are required as they add the necessary tables, if this is an initial install. If it is just an update, then just use the version in the git sql folder.

Thuz989
02-25-2013, 11:41 AM
Can this code even work anymore now that mercs have own table?? I assume they dont have NPC ids that i have seen?? I assume since they dont have a special attack field this wont ever be true?

//try main hand first
if(attack_timer.Check()) {
Attack(GetTarget(), SLOT_PRIMARY);

bool tripleSuccess = false;

if(GetOwner() && GetTarget() && CanThisClassDoubleAttack()) {

if(GetOwner()) {
Attack(GetTarget(), SLOT_PRIMARY, true);
}

if(GetOwner() && GetTarget() && SpecAttacks[SPECATK_TRIPLE]) {
tripleSuccess = true;
Attack(GetTarget(), SLOT_PRIMARY, true);
}

//quad attack, does this belong here??
if(GetOwner() && GetTarget() && SpecAttacks[SPECATK_QUAD]) {
Attack(GetTarget(), SLOT_PRIMARY, true);
}
}

bad_captain
02-25-2013, 11:59 AM
I haven't tested it specifically, but mercs have a specialattks field. They also have an attack_count field. I'm pretty sure I've at least seen my merc triple, but I'd have to look. I dont think there's any data in the specialattks field, whereas attack_count should match where client get double, triple, and quad attacks. I know there will be a lot of little things that need tweaked, but I am focusing on the major issues right now.

The best way to test is to parse or do some debugging to see for sure.

Shiny151
02-25-2013, 12:01 PM
No, from now on, all sql scripts will be in the git folder. They are basically the same file.


Edit: the file referenced in my git commit about merc spells is the same as the one you referenced. The earlier files are required as they add the necessary tables, if this is an initial install. If it is just an update, then just use the version in the git svn folder.

Okay great because how you described the update is how i followed it. I just wanted to make sure i didn't miss anything. And by the way, thank for for working on Mercs; I have a half a dozen folks who play on my server and we have really been enjoying the greater possibilities they bring. We appreciate all the work you've done to bring this to us.

Armm
02-25-2013, 09:49 PM
Using ROF and UF client with latest 32 bit GIT build, running latest PEQ and patches, up to and including git sql patches.

These problems happen on both ROF and UF clients every time:

Suspend and Dismiss merc leaves merc standing there, targetable, but only has an entity number. Cant use #kill or #damage on him. If you zone you cant see them anymore.


With 2PC in group with mercs, if you suspend a bot, UNSUSPEND him and then zone, you end up with 2 mercs with same name in database. Repeat and you get more mercs in database with same name. The old ones show as suspended. If you start chain dismissing them you can get rid of some but not all of dupes.


Assuming 2 PCs and mercs in group, 1 tank merc, 1 healer merc... 2 pets. Healer will chain cast loyalty group buff series because it wont stick on pets im guessing. Get rid of pets, problem goes away.


Thank you for working on mercs! they seem to zone better than bots. If the ghost/dupe thing was figured out it would be great.

bad_captain
02-26-2013, 01:44 AM
I'm working on the dismiss/suspend issue. I'm not sure why that broke, but I'm working on it.

I'll check out the duplicate save entries as well.

About the spell, do you mean Blessing of Loyalty, the spell haste buff? I'll have to look more into this, as I don't see this issue at 65. What level and what kind of pet?

Thanks for the feedback.


Edit: I think I've fixed the duplicate saves, and will try to commit tomorrow after more testing.

myeqsf
02-26-2013, 05:00 AM
That is not possible yet in EQEmu. The only client we have that can even support that option is RoF. And there are probably some new packets that deal with owning multiple mercs that we have not yet looked into.

I realize its an enormous amount of work, and i appreciate your efforts.

Armm
02-26-2013, 08:47 AM
I had level 85 characters, not sure what level the spell is but the spell haste cleric buff yes. If you have pets in the group who dont have pet affinity ( and thus cant get buffs) the cleric chain casts it. If you give the characters pet affinity, the buff sticks on pets and the clerics stop casting it.

bad_captain
02-26-2013, 10:07 AM
Gotcha. Thanks, that should give me what I need. I was using pet affinity, so that's why I didn't see it.

Now, a good question would be why a level 85 character wouldn't have pet affinity.. :)

Armm
02-26-2013, 05:01 PM
For servers that pets can be used by all classes :) Yes i will likely change AA but i thought id let you know because ive seen it happen on bots also.

Thank you for your willingness to converse about this stuff. It is appreciated.

Armm
02-27-2013, 07:25 PM
I am not sure if this is the right place for this but since it happens only when i am trying to purchase a fungusman or orc tier 2 journeyman healer. Right after i purchase them the zone crashes... debug info below (this is using ROF client)

---------------------------------------------
[02.27. - 17:15:14] Starting Log: logs/crash_zone_3860.log
[02.27. - 17:15:14] EXCEPTION_ACCESS_VIOLATION
[02.27. - 17:15:14] SymInit: Symbol-SearchPath: '.;C:\EQEMU;C:\EQEMU;C:\Windows;C:\Windows\system3 2;SRV*C:\websymbols*http://msdl.microsoft.com/download/symbols;', symOptions: 530, UserName: 'Administrator'
[02.27. - 17:15:14] OS-Version: 6.2.9200 () 0x110-0x3
[02.27. - 17:15:14] C:\EQEMU\zone.exe:zone.exe (00D00000), size: 24731648 (result: 0), SymType: 'PDB', PDB: 'C:\EQEMU\zone.exe'
[02.27. - 17:15:14] C:\Windows\SYSTEM32\ntdll.dll:ntdll.dll (777D0000), size: 1404928 (result: 0), SymType: '-exported-', PDB: 'C:\Windows\SYSTEM32\ntdll.dll', fileVersion: 6.2.9200.16420
[02.27. - 17:15:14] C:\Windows\SYSTEM32\KERNEL32.DLL:KERNEL32.DLL (76680000), size: 1245184 (result: 0), SymType: '-exported-', PDB: 'C:\Windows\SYSTEM32\KERNEL32.DLL', fileVersion: 6.2.9200.16384
[02.27. - 17:15:14] C:\Windows\SYSTEM32\KERNELBASE.dll:KERNELBASE.dll (77420000), size: 679936 (result: 0), SymType: '-exported-', PDB: 'C:\Windows\SYSTEM32\KERNELBASE.dll', fileVersion: 6.2.9200.16451
[02.27. - 17:15:14] C:\Windows\system32\apphelp.dll:apphelp.dll (71850000), size: 684032 (result: 0), SymType: '-exported-', PDB: 'C:\Windows\system32\apphelp.dll', fileVersion: 6.2.9200.16420
[02.27. - 17:15:14] C:\Windows\AppPatch\AcLayers.DLL:AcLayers.DLL (70530000), size: 2555904 (result: 0), SymType: '-exported-', PDB: 'C:\Windows\AppPatch\AcLayers.DLL', fileVersion: 6.2.9200.16420
[02.27. - 17:15:14] C:\Windows\SYSTEM32\msvcrt.dll:msvcrt.dll (75440000), size: 724992 (result: 0), SymType: '-exported-', PDB: 'C:\Windows\SYSTEM32\msvcrt.dll', fileVersion: 7.0.9200.16384
[02.27. - 17:15:14] C:\Windows\SYSTEM32\USER32.dll:USER32.dll (76E50000), size: 1138688 (result: 0), SymType: '-exported-', PDB: 'C:\Windows\SYSTEM32\USER32.dll', fileVersion: 6.2.9200.16420
[02.27. - 17:15:14] C:\Windows\SYSTEM32\GDI32.dll:GDI32.dll (76A10000), size: 1036288 (result: 0), SymType: '-exported-', PDB: 'C:\Windows\SYSTEM32\GDI32.dll', fileVersion: 6.2.9200.16433
[02.27. - 17:15:14] C:\Windows\SYSTEM32\SHELL32.dll:SHELL32.dll (75500000), size: 17588224 (result: 0), SymType: '-exported-', PDB: 'C:\Windows\SYSTEM32\SHELL32.dll', fileVersion: 6.2.9200.16496
[02.27. - 17:15:14] C:\Windows\SYSTEM32\SHLWAPI.dll:SHLWAPI.dll (76F70000), size: 262144 (result: 0), SymType: '-exported-', PDB: 'C:\Windows\SYSTEM32\SHLWAPI.dll', fileVersion: 6.2.9200.16384
[02.27. - 17:15:14] C:\Windows\SYSTEM32\OLEAUT32.dll:OLEAUT32.dll (774D0000), size: 569344 (result: 0), SymType: '-exported-', PDB: 'C:\Windows\SYSTEM32\OLEAUT32.dll', fileVersion: 6.2.9200.16384
[02.27. - 17:15:14] C:\Windows\SYSTEM32\MPR.dll:MPR.dll (727D0000), size: 77824 (result: 0), SymType: '-exported-', PDB: 'C:\Windows\SYSTEM32\MPR.dll', fileVersion: 6.2.9200.16384
[02.27. - 17:15:14] C:\Windows\SYSTEM32\SETUPAPI.dll:SETUPAPI.dll (75020000), size: 1765376 (result: 0), SymType: '-exported-', PDB: 'C:\Windows\SYSTEM32\SETUPAPI.dll', fileVersion: 6.2.9200.16496
[02.27. - 17:15:14] C:\Windows\SYSTEM32\sfc.dll:sfc.dll (746B0000), size: 12288 (result: 0), SymType: '-exported-', PDB: 'C:\Windows\SYSTEM32\sfc.dll', fileVersion: 6.2.9200.16384
[02.27. - 17:15:14] C:\Windows\SYSTEM32\WINSPOOL.DRV:WINSPOOL.DRV (719D0000), size: 393216 (result: 0), SymType: '-exported-', PDB: 'C:\Windows\SYSTEM32\WINSPOOL.DRV', fileVersion: 6.2.9200.16384
[02.27. - 17:15:14] C:\Windows\SYSTEM32\RPCRT4.dll:RPCRT4.dll (751D0000), size: 704512 (result: 0), SymType: '-exported-', PDB: 'C:\Windows\SYSTEM32\RPCRT4.dll', fileVersion: 6.2.9200.16384
[02.27. - 17:15:14] C:\Windows\SYSTEM32\combase.dll:combase.dll (77150000), size: 1269760 (result: 0), SymType: '-exported-', PDB: 'C:\Windows\SYSTEM32\combase.dll', fileVersion: 6.2.9200.16420
[02.27. - 17:15:14] C:\Windows\SYSTEM32\CFGMGR32.dll:CFGMGR32.dll (76C10000), size: 286720 (result: 0), SymType: '-exported-', PDB: 'C:\Windows\SYSTEM32\CFGMGR32.dll', fileVersion: 6.2.9200.16384
[02.27. - 17:15:14] C:\Windows\SYSTEM32\DEVOBJ.dll:DEVOBJ.dll (768E0000), size: 122880 (result: 0), SymType: '-exported-', PDB: 'C:\Windows\SYSTEM32\DEVOBJ.dll', fileVersion: 6.2.9200.16384
[02.27. - 17:15:14] C:\Windows\SYSTEM32\SspiCli.dll:SspiCli.dll (74E60000), size: 114688 (result: 0), SymType: '-exported-', PDB: 'C:\Windows\SYSTEM32\SspiCli.dll', fileVersion: 6.2.9200.16420
[02.27. - 17:15:14] C:\Windows\SYSTEM32\sfc_os.DLL:sfc_os.DLL (71900000), size: 57344 (result: 0), SymType: '-exported-', PDB: 'C:\Windows\SYSTEM32\sfc_os.DLL', fileVersion: 6.2.9200.16384
[02.27. - 17:15:14] C:\Windows\SYSTEM32\CRYPTBASE.dll:CRYPTBASE.dll (74E50000), size: 36864 (result: 0), SymType: '-exported-', PDB: 'C:\Windows\SYSTEM32\CRYPTBASE.dll', fileVersion: 6.2.9200.16384
[02.27. - 17:15:14] C:\Windows\SYSTEM32\sechost.dll:sechost.dll (74F80000), size: 212992 (result: 0), SymType: '-exported-', PDB: 'C:\Windows\SYSTEM32\sechost.dll', fileVersion: 6.2.9200.16384
[02.27. - 17:15:14] C:\Windows\SYSTEM32\bcryptPrimitives.dll:bcryptPri mitives.dll (74DF0000), size: 331776 (result: 0), SymType: '-exported-', PDB: 'C:\Windows\SYSTEM32\bcryptPrimitives.dll', fileVersion: 6.2.9200.16384
[02.27. - 17:15:14] C:\Windows\system32\IMM32.DLL:IMM32.DLL (76E10000), size: 131072 (result: 0), SymType: '-exported-', PDB: 'C:\Windows\system32\IMM32.DLL', fileVersion: 6.2.9200.16384
[02.27. - 17:15:14] C:\Windows\SYSTEM32\MSCTF.dll:MSCTF.dll (74E80000), size: 905216 (result: 0), SymType: '-exported-', PDB: 'C:\Windows\SYSTEM32\MSCTF.dll', fileVersion: 6.2.9200.16496
[02.27. - 17:15:14] C:\Perl\bin\perl512.dll:perl512.dll (28000000), size: 1273856 (result: 0), SymType: '-exported-', PDB: 'C:\Perl\bin\perl512.dll', fileVersion: 5.12.3.1204
[02.27. - 17:15:14] C:\Windows\SYSTEM32\WS2_32.dll:WS2_32.dll (76BC0000), size: 327680 (result: 0), SymType: '-exported-', PDB: 'C:\Windows\SYSTEM32\WS2_32.dll', fileVersion: 6.2.9200.16384
[02.27. - 17:15:14] C:\Windows\SYSTEM32\VERSION.dll:VERSION.dll (73840000), size: 32768 (result: 0), SymType: '-exported-', PDB: 'C:\Windows\SYSTEM32\VERSION.dll', fileVersion: 6.2.9200.16384
[02.27. - 17:15:14] C:\Windows\SYSTEM32\ADVAPI32.dll:ADVAPI32.dll (76B10000), size: 712704 (result: 0), SymType: '-exported-', PDB: 'C:\Windows\SYSTEM32\ADVAPI32.dll', fileVersion: 6.2.9200.16384
[02.27. - 17:15:14] C:\Windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_5.82.9200.16384_none_bf1 00cd445f4d954\COMCTL32.dll:COMCTL32.dll (76900000), size: 552960 (result: 0), SymType: '-exported-', PDB: 'C:\Windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_5.82.9200.16384_none_bf1 00cd445f4d954\COMCTL32.dll', fileVersion: 5.82.9200.16384
[02.27. - 17:15:14] C:\Windows\SYSTEM32\NSI.dll:NSI.dll (74F60000), size: 32768 (result: 0), SymType: '-exported-', PDB: 'C:\Windows\SYSTEM32\NSI.dll', fileVersion: 6.2.9200.16384
[02.27. - 17:15:14] C:\Windows\system32\napinsp.dll:napinsp.dll (74D00000), size: 65536 (result: 0), SymType: '-exported-', PDB: 'C:\Windows\system32\napinsp.dll', fileVersion: 6.2.9200.16384
[02.27. - 17:15:14] C:\Windows\system32\NLAapi.dll:NLAapi.dll (74CF0000), size: 65536 (result: 0), SymType: '-exported-', PDB: 'C:\Windows\system32\NLAapi.dll', fileVersion: 6.2.9200.16420
[02.27. - 17:15:14] C:\Windows\System32\mswsock.dll:mswsock.dll (74DA0000), size: 303104 (result: 0), SymType: '-exported-', PDB: 'C:\Windows\System32\mswsock.dll', fileVersion: 6.2.9200.16433
[02.27. - 17:15:14] C:\Windows\SYSTEM32\DNSAPI.dll:DNSAPI.dll (74C70000), size: 479232 (result: 0), SymType: '-exported-', PDB: 'C:\Windows\SYSTEM32\DNSAPI.dll', fileVersion: 6.2.9200.16420
[02.27. - 17:15:14] C:\Windows\System32\winrnr.dll:winrnr.dll (74C60000), size: 36864 (result: 0), SymType: '-exported-', PDB: 'C:\Windows\System32\winrnr.dll', fileVersion: 6.2.9200.16384
[02.27. - 17:15:14] C:\Windows\System32\rasadhlp.dll:rasadhlp.dll (731D0000), size: 28672 (result: 0), SymType: '-exported-', PDB: 'C:\Windows\System32\rasadhlp.dll', fileVersion: 6.2.9200.16384
[02.27. - 17:15:14] C:\EQEMU\EMuShareMem.DLL:EMuShareMem.DLL (71910000), size: 622592 (result: 0), SymType: 'PDB', PDB: 'C:\EQEMU\EMuShareMem.DLL'
[02.27. - 17:15:14] C:\Perl\lib\auto\Cwd\Cwd.dll:Cwd.dll (10000000), size: 20480 (result: 0), SymType: '-exported-', PDB: 'C:\Perl\lib\auto\Cwd\Cwd.dll'
[02.27. - 17:15:14] C:\Perl\lib\auto\DBI\DBI.dll:DBI.dll (03020000), size: 98304 (result: 0), SymType: '-exported-', PDB: 'C:\Perl\lib\auto\DBI\DBI.dll'
[02.27. - 17:15:14] C:\Perl\lib\auto\List\Util\Util.dll:Util.dll (04CC0000), size: 28672 (result: 0), SymType: '-exported-', PDB: 'C:\Perl\lib\auto\List\Util\Util.dll'
[02.27. - 17:15:14] C:\Perl\lib\auto\Filter\Util\Call\Call.dll:Call.dl l (04CD0000), size: 20480 (result: 0), SymType: '-exported-', PDB: 'C:\Perl\lib\auto\Filter\Util\Call\Call.dll'
[02.27. - 17:15:14] C:\Perl\lib\auto\IO\IO.dll:IO.dll (04CE0000), size: 24576 (result: 0), SymType: '-exported-', PDB: 'C:\Perl\lib\auto\IO\IO.dll'
[02.27. - 17:15:14] C:\Windows\System32\fwpuclnt.dll:fwpuclnt.dll (740E0000), size: 258048 (result: 0), SymType: '-exported-', PDB: 'C:\Windows\System32\fwpuclnt.dll', fileVersion: 6.2.9200.16465
[02.27. - 17:15:14] C:\Windows\SYSTEM32\dbghelp.dll:dbghelp.dll (71170000), size: 1216512 (result: 0), SymType: '-exported-', PDB: 'C:\Windows\SYSTEM32\dbghelp.dll', fileVersion: 6.2.9200.16384
[02.27. - 17:15:14] c:\eqemu\eqemuserver\zone\client_packet.cpp (13639): Client::Handle_OP_MercenaryHire
[02.27. - 17:15:14] c:\eqemu\eqemuserver\zone\client_packet.cpp (472): Client::HandlePacket
[02.27. - 17:15:14] c:\eqemu\eqemuserver\zone\client_process.cpp (712): Client::Process
[02.27. - 17:15:14] c:\eqemu\eqemuserver\zone\entity.cpp (509): EntityList::MobProcess
[02.27. - 17:15:14] c:\eqemu\eqemuserver\zone\net.cpp (492): main
[02.27. - 17:15:14] f:\dd\vctools\crt_bld\self_x86\crt\src\crt0.c (278): __tmainCRTStartup
[02.27. - 17:15:14] f:\dd\vctools\crt_bld\self_x86\crt\src\crt0.c (189): mainCRTStartup
[02.27. - 17:15:14] ERROR: SymGetLineFromAddr64, GetLastError: 487 (Address: 766A8543)
[02.27. - 17:15:14] 766A8543 (KERNEL32): (filename not available): BaseThreadInitThunk
[02.27. - 17:15:14] ERROR: SymGetLineFromAddr64, GetLastError: 487 (Address: 7782AC69)
[02.27. - 17:15:14] 7782AC69 (ntdll): (filename not available): RtlInitializeExceptionChain
[02.27. - 17:15:14] ERROR: SymGetLineFromAddr64, GetLastError: 487 (Address: 7782AC3C)
[02.27. - 17:15:14] 7782AC3C (ntdll): (filename not available): RtlInitializeExceptionChain

Armm
02-27-2013, 07:32 PM
Happens whenever you purchase a merc and you are over level 85. Somewhat expected but i was suprised it crashed the zone. FYI

trevius
02-28-2013, 03:25 AM
Odd, I thought I had fixed that particular crash and committed the fix, but maybe I only fixed it on my own server and forgot to commit it.

The problem is that in the handling for hiring a merc in client_packet.cpp, it makes the call to LoadMerc(), and then spawns the merc without first making sure it actually got one returned. I highlighted the line below where the issue is. We just need an "if (merc)" added right below that line to prevent the crash.
void Client::Handle_OP_MercenaryHire(const EQApplicationPacket *app)
{
// The payload is 16 bytes. First four bytes are the Merc ID (Template ID)
if(app->size != sizeof(MercenaryMerchantRequest_Struct))
{
LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_MercenaryHire expected %i got %i", sizeof(MercenaryMerchantRequest_Struct), app->size);

DumpPacket(app);

return;
}

MercenaryMerchantRequest_Struct* mmrq = (MercenaryMerchantRequest_Struct*) app->pBuffer;
uint32 merc_template_id = mmrq->MercID;
uint32 merchant_id = mmrq->MercMerchantID;
uint32 merc_unk1 = mmrq->MercUnk01;
uint32 merc_unk2 = mmrq->MercUnk02;

DumpPacket(app);

if(MERC_DEBUG > 0)
Message(7, "Mercenary Debug: Template ID (%i), Merchant ID (%i), Unknown1 (%i), Unknown2 (%i)", merc_template_id, merchant_id, merc_unk1, merc_unk2);

//HirePending = true;
SetHoTT(0);
SendTargetCommand(0);

MercTemplate* merc_template = zone->GetMercTemplate(merc_template_id);

if(merc_template) {

if (GetMercID()) {
// 6 - You must dismiss the mercenary before hiring a new one.
SendMercMerchantResponsePacket(6);
}
else
{
// 0 is approved hire request
SendMercMerchantResponsePacket(0);

// Set time remaining to max on Hire
GetEPP().mercTimerRemaining = RuleI(Mercs, UpkeepIntervalMS);

// Get merc, assign it to client & spawn
Merc* merc = Merc::LoadMerc(this, merc_template, merchant_id);
SpawnMerc(merc);
}
}

}

bad_captain
02-28-2013, 09:37 AM
I have this fix in (as well as others) , I just need some time to merge in all the recent changes and commit. The issue is there is only merc data through lvl 85. On my next stat update, I'll try to add merc data through lvl 100, since RoF can be used.

I've just been crazy busy and haven't had a chance to commit (I've also been trying to track down the depop bug).

bad_captain
03-01-2013, 01:24 AM
It should no longer crash if a merc can't spawn, but I will have to add in mercs to 100 when I get a chance. It's more of an issue for spells and such for those levels as I have a script I use to generate the stats, but I'll see what i can do.

Armm
03-01-2013, 08:52 AM
Thank you for that update! I hear yah on the crazy busy.

Armm
03-01-2013, 12:26 PM
i compiled the latest version alright, i went to source in the merc_rules_and_equipment.sql statement and i get errors about primary key for first two lines which i fixed because they already exist...

However alter table also got tripped up claiming it couldnt find mercbuffs, in my case it was already named properly to merc_buffs??

The final error i couldnt get past and i tried this in mysqldump and heidesql... once it get to the part where it wants to create merc_inventory it throws an error saying..

DROP TABLE IF EXISTS merc_inventory;
CREATE TABLE merc_inventory (
merc_inventory_id int(10) unsigned NOT NULL auto_increment,
merc_subtype_id int(10) unsigned NOT NULL default '0',
item_id int(11) unsigned NOT NULL default '0',
min_level int(10) unsigned NOT NULL default '0',
max_level int(10) unsigned NOT NULL default '0',
PRIMARY KEY (merc_inventory_id),
KEY FK_merc_inventory_1 (merc_subtype_id),
CONSTRAINT FK_merc_inventory_1 FOREIGN KEY (merc_subtype_id) REFERENCES merc_subtypes (merc_subtype_id)
);
/* SQL Error (1005): Can't create table 'peq.merc_inventory' (errno: 150)

Foreign key constraint is incorrectly formed */

Armm
03-01-2013, 01:05 PM
Also if you do a SHOW INNODB STATUS you get this relevant portion..

LATEST FOREIGN KEY ERROR\n------------------------\n130301 10:49:53 Error in foreign key constraint of table peq/merc_inventory:\n FOREIGN KEY (merc_subtype_id) REFERENCES merc_subtypes (merc_subtype_id)):\nCannot resolve table name close to:\n (merc_subtype_id))\n------------\n

bad_captain
03-01-2013, 01:52 PM
Did you have all of the previous sql updates applied? I compiled that script from all of my changes and applied it as one to my secondary database, and it ran correctly.

Do you have to table merc_subtypes? what is its primary key?

Had you somehow run the script before? Those rules are new, and should not already exist.

Did you resource the database? Maybe it was already put in peq db?

Armm
03-01-2013, 03:26 PM
i just dropped all merc related tables except rule values, modified rule inserts to updates, and it went in this time. Sorry, its a bit confusing knowing what to apply first and some of that stuff is included in PEQ 2506(?) or whatever latest is.

Armm
03-01-2013, 03:45 PM
I can confirm that the duplicate merc entry bug seems fixed. I can also confirm that trying to hire a merc above level 85 doesnt crash the zone anymore, you just get a message saying it failed, which is fine.

Thanks for the tips, info, and fixes, very much appreciated.

bad_captain
03-01-2013, 03:48 PM
Yeah, I would prefer to have 1 script for all things merc, but we have seen the issues it causes, so this is the best we can do. I'm not sure what else can be done, but it would be nice if there was some way to know what updates peq has included so people would know what to and what not to source in. Maybe a list of applied updates that can be compared to before sourcing in updates.

Something like db version, but for applied updates? A table with rows for all of the updates included in that version? I don't know.

bad_captain
03-01-2013, 03:50 PM
I can confirm that the duplicate merc entry bug seems fixed. I can also confirm that trying to hire a merc above level 85 doesnt crash the zone anymore, you just get a message saying it failed, which is fine.

Thanks for the tips, info, and fixes, very much appreciated.

Good to hear! While I do test it all, it's nice to get feedback that it works for others as well, since others have different play styles or setups that I may not be able to reproduce.

rencro
03-01-2013, 08:14 PM
Table merc_subtypes is MyISAM when building new db from 2506, will not take FK until I changed it to InnoDB..

This is in relation to 2013_03_1_Merc_Rules_and_Equipment.sql with a new db sourced from peqdb_rev2506...

Armm
03-02-2013, 10:49 AM
Confirming no ghosting of mercs after i suspend or dismiss, buffing seems to work correctly now. Thanks!!

bad_captain
03-02-2013, 11:29 AM
No problem. It was actually an easier fix than I thought. I just had to have to time to sit down and debug through the entire suspend/dismiss procedure to figure out what it was.

I plan to tackle dps mercs next, I just need more data on spells cast / skills used, especially for Journeyman mercs (using different stances). I have a decent idea of Apprentice mercs at least to 65. After that, I'm clueless, but I should be able to come up with something. I just hate using a melee DPS merc because they are so picky on when to attack (they hate getting aggro and their range to decide to join the fight when the main tank is also the puller is miniscule).

Timers still need work, and every once in a while I don't get stances when hiring (but suspending/unsuspending or zoning fixes it), but I think they are starting to work pretty well.

I'll try to clean up the sql as well. I'm not sure why it would work on mine, but not using the peq download.

bad_captain
03-06-2013, 12:57 PM
Requesting Data- if you play on live (or test) and you use mercs, I could use some data. I'm trying to compile spell lists for caster dps specifically, but can use any other data.

I have pretty good data between lvl 60 - 65. I will be creating lvl 1 toons to get data, but this will take a lot of time. If anyone has data for any level, I would appreciate it. If you have it, lvl, stance, and proficiency should be known ( but not required) . I could also use /logs if you don't want to compile it on your own. ( just need the message when the spell hits) .

I have basic nuke code working on my local machine, so spell lists are all I need now. Once stances are fully in, then the spell casting can be further tweaked.

Thanks.

Shiny151
03-06-2013, 02:55 PM
Hey captain; my mercs don't rez for some reason. I'm up to date with the most recent build as of last night and I'm pretty sure i've got your .sql order down.

Clerics have really only been hitting my group with Virtue and that's about it.

How can I resolve this?

Thanks!

bad_captain
03-06-2013, 03:40 PM
What level, proficiency, tier?


select * from merc_spell_list_entries
where merc_spell_list_id = 3
and spell_type = 65536;


what does that return? that should list the 8 resurrect spells.

If it returns nothing, check that sql for those spells has been run. Also check spell_type in that same table for the datatype. I think at one time I had it as a tinyint, should be int.

Other than that, the corpse's owner should be in your group.

Do they heal at all, or just buff? What class are you?

bad_captain
03-06-2013, 03:43 PM
BTW, about spell lists- a good way to get them for apprentice and journeyman is to do a /testcopy for your characters so you don't have to worry about hiring/ upkeep cost, and gives you access to journeyman mercs as if you are gold member.

Shiny151
03-06-2013, 04:43 PM
What level, proficiency, tier?


select * from merc_spell_list_entries
where merc_spell_list_id = 3
and spell_type = 65536;


what does that return? that should list the 8 resurrect spells.

If it returns nothing, check that sql for those spells has been run. Also check spell_type in that same table for the datatype. I think at one time I had it as a tinyint, should be int.

Other than that, the corpse's owner should be in your group.

Do they heal at all, or just buff? What class are you?

Thanks. I'll check it out when i get home. Levels range from 66-69 Balanced, Journeyman, T2. I've not played around with much else. They heal and buff but they don't keep mana well at all. Usually 50% or OOM; even idle. (using UF and RoF clients) Proficiencies have no noticeable impact; most likely i've got something jacked in my sql then. No issues with melee, they do their jobs well. Altho i think it's hilarious that the Vah Shir grunt and jump in your face when a mob dies.

Thanks for the tips.

bad_captain
03-06-2013, 05:02 PM
Yeah, mana regen seemz slow. I think there's a bug with rest regen that I've also fixed on my local machine, but rest regen helps ( if turned on of course). The higher level you try, the worse it probably is. I don't have much data above level 65, and had to guess on a lot of stats.

Prior to my commit with merc equipment, they had no mana preservation or improved healing. The equipment's focus items help a lot. There's still a lot of room for improvement, and tweaking will continue. I'm mostly worried about getting things working, and then making improvements. Especially after getting more feedback.

Let me know about the resurrect spells.

Shiny151
03-07-2013, 09:41 AM
Let me know about the resurrect spells.

So I ran the query and I'm getting 'empty sets' returned; which is odd because I ran the 2/18 merc spells update .sql and i can see the 65536 spell line in the update but it's not sticking to my database table. What in the world?

So I ran it again and it's still not sticking; even clearing the table and rerunning doesn't help. Maybe i'll just have to dump all the merc tables and rerun them all from scratch.

bad_captain
03-07-2013, 11:27 AM
I just realized the problem. On my 2/18 commit, I referenced the mercs.sql file from the svn folder, which KLS fixed by copying over and adding to a new commit with the spell lists, since I wasn't supposed to reference the old svn scripts.. The mercs.sql file also included a change to the merc_spell_list_entries table, which wasn't copied over.

To fix, change the spell_type column to be an int instead of tinyint. You should be able to run:


ALTER TABLE merc_spell_list_entries MODIFY spell_type INT UNSIGNED NOT NULL default '0';


You will then need to re-run the spell inserts, or update the table create script and drop and recreate before running the spell insert scripts.

I will be updating spell lists this week for dps caster, so I will fix this officially then. Let me know if this works.

Shiny151
03-07-2013, 11:54 AM
Okay thanks; i'll try that when I get home tonight. Since i cleared the table and reran the script for merc spells it created about 200+ line items; is this correct? It seemed like the first time i cleared the table there were a lot more lines than this.

Shiny151
03-08-2013, 09:25 AM
ALTER TABLE merc_spell_list_entries MODIFY spell_type INT UNSIGNED NOT NULL default '0';

Okay that worked. I'm seeing the sets in my tables now. The next step is to test them out. Thank you!

Armm
03-08-2013, 08:43 PM
Things im noticing...

2 boxing 2 chars with mercs... one tank merc, J2 one helaer merc j2 both level 85...

Once in combat, cleric gets low on mana fast, sits to regen, and because i had restregentimetoactivate rule set to 3 the cleric starts getting back massive mana quickly. I assume restregen shouldnt kick in while in combat?

If you suspend the merc and lose/gain a level one of two things happen.

1.)Either the timer to unsuspend counts down to 0, and the unsuspend button lights up again, but you push on it and nothing happens. You try to dismiss and it asks you it you want to dismiss, you click yes, nothing happens.

2.) Or else the timer counts down to 0 and stays greyed out and only the dismiss button is active but doesnt work.

After either 1 or 2 I then zoned. After the zone the merc is by my side again without me having to push unsuspend. Acts normally.

All of the above was true with either UF or ROF clients.

Armm
03-08-2013, 10:56 PM
Addition..

I set restregenrule to 18 seconds.

Started fight with 2pc, 1 healer merc and 1 tank merc, all level 85.

Out of five fights, only ONE did the cleric merc not constantly regen 15+% of mana every random few seconds(3-9 seconds roughly).

Cleric merc never runs out of mana in this state. Kill a 500k hp mob with just tank and cleric merc going at it.

Cleric casting frenetic renewal every 3-5 seconds(checked in logs), default recast on that spell should be 30 seconds... Are they meant to adhere to recast times?

bad_captain
03-08-2013, 11:37 PM
Yes, they should only regen while out of combat.

Yes, they should respect spell recast timers.

Both work correctly for bots, so I just need to figure out why not for mercs.


I doubt there's any check for losing or gaining a level while suspended, so I'll check that out. Thanks for the info and keep it coming. I'm sure there are plenty of other issues out there.

Armm
03-10-2013, 09:39 PM
Update-

With 2 PC, 2 merc group(like before), if the PC with the healer DOES NOT damage the mob being fought by the other PC and merc. THAT is when the healer regens mana like he is in restregen mode. If the PC with the healer engages in combat then healer never enters restregen mode.

bad_captain
03-10-2013, 10:00 PM
Okay, that helps a lot.

I wasn't seeing it in my tests, which makes sense because I only usually run 1 PC. There is code there that seems like it should accomplish what we want (get the npc on the merc's hate list to make him Engaged()), so I will take a look at that.

I will fire up a second PC and test this out further.

I'm just trying to come up with a basic spell list for caster DPS mercs (they cast so many different spells on live, it's taking a while to get live-lie, so I'm just doing a temporary generic list for them), then I will commit what I have.

Armm
03-11-2013, 11:10 AM
Upon thinking about it i wondered if this is because mercs act like mobs... For example when you are fighting a mob with a PC, you can have another mob heal the mob you are fighting without aggroing or joining the fight?

Check your PMs from me BadCaptain please.

Armm
03-11-2013, 02:10 PM
Update-

I can trigger the restregen with one PC.

One PC had level 85 J2 healer merc. PC sends in pet and causes no dmg. Merc healer heals pet down to 20ish percent mana, then soon after that whenever they sit down they trigger restregen for mana. It stops the moment i do any damage with PC.

bad_captain
03-11-2013, 02:23 PM
That may be a related, but somewhat different issue. I may be wrong, but there may be an issue of hate transferrence from pet to owner ( I know it's not 1:1, but if your pet is killing an npc, the npc should be adding some hate for you). I will try to test this out some on live and on my test server.

I did change how the mercs have npcs added to their hate list, but didn't get to test last night. I will try it tonight. Having 1 npc on their hate list should be sufficient to keep them from going into rest mode.

Shiny151
03-11-2013, 02:43 PM
One thing I did notice with rezzing now with the cleric mercs is that they will only rez their master/hirerer. My experience is that if someone else dies in the group the merc cleric will not rez them.

Just offering additional feedback.

bad_captain
03-14-2013, 11:35 PM
Spell recast timers should be fixed, and OOC regen shouldn't happen, even if no damage was done (it now looks at the mob's hate list and if a group member is present, it adds the mob to the merc's hate list).

I still have to test out rezzing (I've only had about an hour this week to work on this stuff), but it should find all group member's corpses.

I've added Caster DPS merc spells in (at least a few spells for them to use, I'm still compiling data from live - lvl 65 & 85 dps caster mercs use like 10 spells total for all of the different stances. Multiply that by all the different levels and that's a lot of spells)

Shiny151
03-15-2013, 07:10 AM
DPS casters seem to be working good so far. Definitely another fun element to the game. Captain, I know this isn't a priority right now but later it would be great to have each merc have a randomized look each time you hire one (robe, face, hair etc.)

Thank you for all of your work!

Armm
03-15-2013, 07:29 AM
This is awesome. Ill start testing these right away. Thank you!

Armm
03-15-2013, 08:10 AM
Good news - ooc regen problem seems solved, nice work and thank you.

Bad news - recast timers still dont work.

Level 85 merc cleric still chain casts frenetic renewal spell every couple seconds till oom. Should be 30 second recast like stated here...

http://lucy.allakhazam.com/spell.html?id=18364&setcookie=1

Ill test more later. Thanks again, the ooc regen was a real issue.

bad_captain
03-15-2013, 09:21 AM
Hmmm.. I'll try a longer recast spell and test on it. Maybe I only saw them being respected because the math worked out. I know the recast time is now being carried over ( before it was saved somewhere different than where it was accessed).

I'm glad the ooc regen thing is fixed. It actually is a better method of getting aggro anyway, I think, so it's good that was fixed.

As far as randomizing the merc's look, there is code in there to randomize hair, face, tattoos, eyes, etc, so maybe it just isn't being called at the right time or is being overwritten. The robes is a different thing (well, similar, but many different options), so it makes it harder to randomize I.E. you have to know the available texture values for each race. One live, they will change their armor or robe at certain levels, which is available in the code now. I just have 1 set in the database, but it could easily have more added. I suppose it could be changed to allow different textures to be selected from when the merc is created, but that may be more work than it would be worth. I'll check out the other random stuff and see why it's not working.

Armm
03-15-2013, 09:50 PM
First, there is still a major bug where when for example at level 85 i am fighting a mob with just merc and PC and the PC dies and loses a level. After i zone back to bind point the merc is visually there, but unresponsive, i cant unsuspend, i cant dismiss them, cant purchase a new one, and the old merc remains in database. If i RELOG, when i come back into the game the merc is there and responsive. If i then dismiss it it in fact dismisses properly, and is erased from the database.


The second bug i think i can help you out with. When a tank merc is fighting a mob and you get within melee range you draw immediate aggro no matter what, just like with pets... Since i had just been looking into changing that for pets i tested this code and it seems to work. I basically modified what you did with bots.... After i applied this ,ercs could hold aggro no problem even when in melee range unless i outdmged them... Hope this helps.

This is in hate_list.cpp

+++ "b/C:\\EQEMU\\EQEmuServer\\zone\\hate_list.cpp"
@@ -361,6 +361,20 @@ Mob *HateList::GetTop(Mob *center)
}
}
#endif //BOTS
+
+
+ if(!isTopClientType) {
+ if(top->IsMerc()) {
+ isTopClientType = true;
+ topClientInRange = top;
+ }
+ }
+
if(!isTopClientType)
return topClientInRange;

daerath
03-17-2013, 08:45 AM
First, there is still a major bug where when for example at level 85 i am fighting a mob with just merc and PC and the PC dies and loses a level. After i zone back to bind point the merc is visually there, but unresponsive, i cant unsuspend, i cant dismiss them, cant purchase a new one, and the old merc remains in database. If i RELOG, when i come back into the game the merc is there and responsive. If i then dismiss it it in fact dismisses properly, and is erased from the database.


I haven't looked at the mercenaries code (and don't have a dev environment set up to check), but I'm going to assume that gating back to bind (or porting) doesn't break mercenaries in the same way.

It sounds like you're losing a pointer to your mercenary. When you die, does your character object get recreated? If so, perhaps the code responsible isn't transferring over the pointer to the mercenary.

Shiny151
03-17-2013, 02:48 PM
One thing with cleric mercs my server has noticed is that if you suspend them and then unsuspend them their mana will regen to full. Is this intended by default? I can't remember how that works on Live

bad_captain
03-18-2013, 08:32 AM
I'm not 100% sure, but I believe that they do. The issue is, on live, they become available to unsuspend in 5 minutes, as opposed to a few seconds here. Someone would have to verify though.

orionsun
03-18-2013, 09:58 AM
Mercs on live do not change state while suspended, they come out at the exact hp/mana/end that they were suspended with.

Shiny151
03-18-2013, 12:59 PM
Maybe there's a setting within the database we can tweak but if there isn't, would it be possible to change the minimum health that a cleric merc actually starts casting heals?

For example, if you're looting your corpse and you have a cleric merc, they will spam you for each item you reequip since this raises your total hitpoints and you would normally have to regen that health. The cleric thinks you are taking damage and tries to top you off and wastes a bunch of mana for each item you reequip.

I'm thinking if you go below 30-40% of your health then the cleric starts healing you. Just a suggestion.

lerxst2112
03-18-2013, 02:25 PM
The cleric mercs on live are the same way. It's even more fun if you're in a zone where buff timers are suspended. When my int casters cast their shielding spell I end up with a hot and a promised heal sucking up buff slots if I'm not paying attention. All for a gap that was less than I'd regen in a single tick.

Secrets
03-20-2013, 04:17 AM
Just posting that I *think* I fixed the remaining mercenary memory leaks in code and when my pull request is accepted you should probably update. These were rather large fixes, and your RAM will thank you for it.

Armm
03-20-2013, 04:50 PM
Summary of existing issues:

x86 debug build, built March 20th 8:47am. Using ROF or UF clients.

Cleric mercs chain cast bulwark of vie on themselves with a level 66 j2 healer merc for example, this happens on a number of buffs for healer mercs. Strange part is after i died and delveled to 65 the merc would still chain cast buff but it wouldnt say bulwark of vie, just say casting a spell, surrounded by bright white aura...

Tank mercs dont rest regen at all, ever.

If you suspend your merc and delvel(like if you died in a zone, had someone rezz you in zone, and tried to bring merc back) you cant unsuspend, dismiss, or do anything with pet. Sometimes zoning brings it back, sometimes not.

Seeing lots and lots of chars with 1-8 mercs for same charid with the multiples suspended. i saw one instance of a single char having 14 different mercs with all suspended but 1.

All in all, lots of improvements, thank you for the hard work.

bad_captain
03-20-2013, 07:53 PM
I'll have to do some more testing. I haven't seen the chain casting of any of the vie spells, at least at 65, but there shouldn't be much difference between the two.

Unless I'm wrong, you need to sit to rest regen, correct? I guess I could have them sit, but that would look a little strange, the tank merc sitting in between pulls.

I still haven't fixed the delevel bug. Yes, it will be the same between suspending and dying and deleveling. I will try to get it done by the end of the weekend.

I know i fixed the multi-save issue a while back, so I'm not sure why that came back. I know there have been a lot of changes in the last week or so, so maybe something broke again. Or it's happening after the merc gets bugged. Right now, mercs are being suspended when you die, so that could be the cause. I'll look into it.

Armm
03-20-2013, 09:41 PM
Update-

Everyone on server that i could talk to had healer mercs chain buffing. i personally saw them(mercs) chain buffing bulwark of vie on themselves, and after i jumped my level up they started chain casting symbols on themselves. The point being is they only seem to chain cast buffs on self. Perhaps that helps. I have disabled them from buffing for now till it gets squared away.

Tank and melee mercs sitting is fairly important early on because people use the tank merc to duo with and since most arent healers, rest regen in between fights is important to them. Its quicker in the early levels to let a merc tank plow through stuff rather than try to tank something and have a merc healing you.


To add more detail on the multisave. I am not sure what triggers it for sure yet, seems to involve suspending/unsuspending. In database there are no DUPLICATE mercs that are exactly the same name. There are just multiple mercs with different names for ONE pc.

Secrets
03-21-2013, 12:31 AM
To add more detail on the multisave. I am not sure what triggers it for sure yet, seems to involve suspending/unsuspending. In database there are no DUPLICATE mercs that are exactly the same name. There are just multiple mercs with different names for ONE pc.

I have fixed this bug specifically, going to add it to my pull request. Basically we added the merc to the group too many times along with not creating the group correctly, there's also some issues with suspending the mercenary artificially through group merging and manually kicking the mercenary that I resolved.

As for the AI, I will take a look at that next.

edit: AI issue seems to be maybe related to having wrong merc spells data. The buffs they cast need to be set to type buff, or 8. Should work in its current form heh.

bad_captain
03-21-2013, 09:35 AM
Secrets, is there any way you could split out the merc stuff into a separate pull request? I was looking through it last night and saw a bunch of other stuff I don't feel comfortable messing with. I'd like to be able to apply just those changes to my local machine and test them with some other changes I've made. If not, I can just apply each change manually, but I'd like to try out the pull requesy stuff. Still learning git and coming up with a more efficient process.

bad_captain
03-21-2013, 09:37 AM
Also, I guess we can add a check for melee mercs to sit if there's no healer and/or below a certain level.

Secrets
03-21-2013, 09:55 AM
Secrets, is there any way you could split out the merc stuff into a separate pull request? I was looking through it last night and saw a bunch of other stuff I don't feel comfortable messing with. I'd like to be able to apply just those changes to my local machine and test them with some other changes I've made. If not, I can just apply each change manually, but I'd like to try out the pull requesy stuff. Still learning git and coming up with a more efficient process.

https://github.com/SecretsOTheP/Server/commit/56825e9ed0bbb460da0ea8ceca4f223ee70db104 This commit has the two fixes that aren't related to mercs. You can revert them if it makes you feel more comfortable, but the rest are required to fix a few memory leaks that Derision reported.

I'm not exactly sure but I think you can just clone my repository and test the changes that way. Basically, the things I fixed are the following:
-Made emulator structure for two packets (OP_MercenaryData and OP_MercenaryMerchantResponse) static instead of creating it dynamically twice
-Fixed a memory leak in the AI code.
-Fixed a memory leak related to groups. In their current form, groups are leaking memory because they are never assigned a group ID in the unsuspend command.
-Fixed a few issues with merging groups with mercenaries in them.
-Fixed an issue where group IDs were not being handed out and leaking memory in OP_GroupDisband and OP_GroupFollow

The two changes that were not related to mercs are:
-Fixed a crash issue in the RoF encoder
-Fixed a crash issue related to calling NPC functions after the deconstructor for NPC was called.

Armm
03-21-2013, 10:32 AM
Question-

Double checking merc_spell_list_entries

What does the slot number do exactly?

Secrets
03-21-2013, 10:58 AM
Question-

Double checking merc_spell_list_entries

What does the slot number do exactly?

Looks unused, glancing over code.

bad_captain
03-21-2013, 11:15 AM
Slot is how the spells are ordered. So, when buffing, healers will loop through their spells, starting slot 1, and going up from there. I have plans to use it to help identify single and group spells. I.E. Virtue is slot 1- I want it cast first. I would also check for a buff in slot 1 that was a group spell, and assume it was Hand of Virtue. I would then cast it if a group spell was prefered. That code isn't in yet, but the spells should be ordered by slot so the mercs will cycle through their spells. CastercDPS mercs also use it to cycle through all of their nukes once they are all in. That way, specific nukes higher in the spell list will be cast more often.

I'll check it out more tonight, secrets. It was just hard to see the merc specific changes- there seemed to be a lot of unrelated changes in the pull request. Maybe I'm just looking at it wrong.

Armm
03-21-2013, 11:35 AM
Thank you for the information, that is helpful

Secrets
03-21-2013, 11:55 AM
I'll check it out more tonight, secrets. It was just hard to see the merc specific changes- there seemed to be a lot of unrelated changes in the pull request. Maybe I'm just looking at it wrong.

Some of it was something I accidentally pushed out, was using visual leak detector to find some of these leaks and eliminate them. That accounted for maybe 2-4 commits which you can ignore.

Armm
03-21-2013, 02:18 PM
Update on chain casting bug..

I happened to log my 66 necro, who did not have a pet out at the time. I noticed the merc did NOT chain cast buffs... strange i thought because every other character had so far. Then i summoned a pet with no buffs... J2 healer merc level 66 starts chain casting virtue on HIMSELF not the pet. Been doing it for 10 minutes now.

Once is get rid of the pet the merc healer stops trying to buff himself.

Even more interesting is i suspended the healer merc, and summoned pet to do some tests.. after i was done with the pet i dismissed the PET, and tried to unsuspend the merc, couldnt do it, nothing happened. After i zoned the merc was out and responsive, but when i picked dismiss, it dismissed him but said " an error created your mercenary" or something very close.

So it would seem it has something to do with pets. I never noticed before because my server is very pet centric(everyone gets one)

Well i made a new char, put him at level 66, hired a j2 healer merc, who castst hand of virt, aura of temp, then chain casts bulwark of vie. There was never a pet cast or present during this process.. im lost.

Armm
03-21-2013, 03:10 PM
Figured out way to create another merc for same char.

Created level 66 j2 healer merc, suspended him while hes trying to chain cast, then try and unsuspend...., nothing happens, i pick dismiss it says it was dismissed even thou it wasnt unsuspended. You get "an error created your mercenary" when you dismiss it. I then bought a new j2 tank merc in same zone, which it gave me... boom, now it shows i have both mercs in database.

bad_captain
03-21-2013, 09:21 PM
Well, I've figured out the chain casting issues. And it involves pets. I like your bug reports. They usually send me to the right place to look.

I have Secret's changes merged into mine, so it might take a little while to test everything. I'll try to get it comitted tonight, however.

bad_captain
03-22-2013, 12:11 AM
Buffing should be fixed.

Secret's fixes are in, so hopefully they will take care of the other issues you are having. If not, please let us know. Thanks!

Armm
03-22-2013, 07:53 AM
Thank you very much for putting all that in, compiling now, will test this morning.

Armm
03-22-2013, 12:05 PM
Chain cast bug seems to be gone, thanks.

I have not been able to create duplicate mercs yet, not very many on yet.

I have not had any crashes yet, will take some time to see if this happens.

Thanks again, those were showstoppers for me.

bad_captain
03-22-2013, 12:53 PM
To clarify, I didn't commit his fixes for two crashes you listed in your other thread, the one for emotes and the other. I just got the merc ones in, so you might still get those. I just didn't have much time last night and wanted to get those couple of things fixed.

Armm
03-23-2013, 10:07 AM
Ok thanks for info.

I found a few sql errors you may want to correct...

From 2013_03_14_Merc_Spells.sql

((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 2 AND proficiency_id = 1), (SELECT id FROM spells_new WHERE name = 'Ethereal Remedy' ORDER BY id DESC LIMIT 1), 8, 0, 59, 60, 6, 0 ),


I think the 8 stands for buff, when it should be 2 for a heal?? This happens throughout all the merc healer ranks.

Pious Remedy has max level of 255?? Pious elixir has maxlevel of 255. Aura of Devotion has max level of 255. All those i THINK should be alot lower max level??

Just trying to pitch in.

bad_captain
03-23-2013, 11:18 AM
Yeah, Ethereal Remedy should be spell type should be 2 for heal, and slot 1.
The others with their max levels:
Pious Remedy 70
Pious Elixir 71
Aura of Devotion 71


UPDATE merc_spell_list_entries
SET spell_type = 2, slot = 1
WHERE spell_id = (SELECT id FROM spells_new WHERE name = 'Ethereal Remedy' ORDER BY id DESC LIMIT 1);

UPDATE merc_spell_list_entries
SET maxlevel = 70
WHERE spell_id = (SELECT id FROM spells_new WHERE name = 'Pious Remedy' ORDER BY id DESC LIMIT 1);

UPDATE merc_spell_list_entries
SET maxlevel = 71
WHERE spell_id = (SELECT id FROM spells_new WHERE name = 'Pious Elixir' ORDER BY id DESC LIMIT 1);

UPDATE merc_spell_list_entries
SET maxlevel = 71
WHERE spell_id = (SELECT id FROM spells_new WHERE name = 'Aura of Devotion' ORDER BY id DESC LIMIT 1);


This is untested, but should work.

Good catch.

vkrr
03-23-2013, 12:04 PM
is there a way besides cost to restrict merc purchases? I'd prefer players to not have access to a Tier V merc at level 1. Are there any rules in place for this, either flagging Qglobals or level?

Armm
03-23-2013, 01:35 PM
Update-

After i pulled down secrets source around 11:30am CST and built that i hopped into the game ( UCS seems broken after that, says mail key is not right for world.exe).

Bug where develeing after death would cause merc to become unresponsive is gone. The only way i can temporarily get it to become unresponsive is if i die, lost level, and rezz in same zone, and even then after i zone the merc comes back just fine.

Chain casting bug is gone.

Well see on the zone crash stuff.

Pretty much every possible thing i could think of, cant break mercs right now. We will see if players can.

bad_captain
03-25-2013, 04:23 PM
is there a way besides cost to restrict merc purchases? I'd prefer players to not have access to a Tier V merc at level 1. Are there any rules in place for this, either flagging Qglobals or level?

The database allows for a qglobal value to be entered. Currently there aren't any checks in the code for it since the ones from live ( theme completion to unlock specific merc level) aren't coded yet, I don't believe.

It will get put in eventually, but if you want to play around with it, check for where it sends the available merc templates to the client in MercenaryMerchantResponse or whatever.

Armm
03-25-2013, 08:15 PM
Things are getting better. Trying secrets update to fix the one crash in last 20 hours ive had.

Here is a summary of bugs and issues:

Bug - If you die and delevel/rezz in same zone merc unresponsive.

Issue - Healer mercs do not cure themselves or anyone else of anything?
Issue - Healer mercs do not cast healdots, tried enabling it and they cast them but the spells dont heal for anything... weird..
Issue - Tank Mercs dont rest regen


Thanks for all the work!

vkrr
03-26-2013, 09:45 AM
Great info Bad_capn. I will play with it.

In the meantime, If i wanted to remove (I'd much rather just disable them) journeyman mercs (without completely breaking the merc tables) what's the easiest way to do that?

Should I:
1) Wipe the hired merc table, delete the mercs from the merchant template entries where (and i'm not sure how to do in in SQL -- MERC ID matches with name like '%journeyman%' from the merc_npc_types table) so they should be unpurchasable?

2) Just delete * where name like '%journeyman%' from merc_npc_types table -- but will that break the merc merchants?

3) Is there a way to implement a cost PER MERC? -- I would love to set the journeyman mercs to cost a crazy amount of plat, that would solve everything rather nicely.

Thanks again for any help you guys can provide

bad_captain
03-26-2013, 11:22 AM
There is a function that returns the cost of the merc based on a simple formula I came up with that is pretty close up to level 65 or so. You should be able to add more based on the proficiency if you wanted to.

You could also do it in sql. I can't test right now, but removing the templates from the merchants would be the best of your options, so you could keep most of the data there in case you wanted it later.

Another option is client version, which is in merc_templates. Set that to a very high number so it won't show up for any client (this restriction works so you don't get unknown dbstring errors for invalid races or classes depending on your client). I'll try to come up with a script when I get a chance.

Armm
03-27-2013, 03:02 PM
After yesterdays build with secrets latest patch, the crashes stopped, so i thought things were good until i noticed mercs with no owners standing around in hub area today. I checked DB and lots and lots of multiple mercs per PC in merc database.

I am cleaning out the DB and rebuilding source and will let you know results.

Armm
03-27-2013, 04:33 PM
Running latest git pull, x86 build, seems to happen on either UF and ROF clients.

Considering ive only had 6 people over last couple hours, and already i have 2 instances of multiple mercs per PC.

No crashes that i can find.

Armm
03-28-2013, 11:10 AM
Still havent figured what causes it. It might be related to grouping because these mercs below are run by a guy who multiboxes/groups...

Anyhow demonstrating the "leftovers"

http://s13.postimg.org/tdhjqxq6v/mercs.jpg

Secrets
03-28-2013, 02:59 PM
Still havent figured what causes it. It might be related to grouping because these mercs below are run by a guy who multiboxes/groups...

Anyhow demonstrating the "leftovers"

http://s13.postimg.org/tdhjqxq6v/mercs.jpg

I'll take a look into this soon; been busy so I haven't had time for mercs.

Armm
04-02-2013, 10:55 AM
Ok, sounds good.

bad_captain
04-02-2013, 07:31 PM
Issue - Healer mercs do not cast healdots, tried enabling it and they cast them but the spells dont heal for anything... weird..


They should now cast the heal over time spells. I'll look further into the spells not being effective.

Armm
04-03-2013, 08:03 AM
Thank you much, that should ease the mana strain on them.

Shiny151
04-03-2013, 08:43 AM
Some additional feedback; i'm not sure if this is exclusive to me or those of us using mercs but; has anyone noticed with the latest build and mercs that grouping seems off? If I'm two boxing, the invitee doesn't see the other's merc in the group but the inviter sees the group leader's merc within the group.

If i revert a few builds back the issue isn't there. Disbanding, suspending etc. doesn't seem to fix the problem.

Armm
04-05-2013, 08:09 PM
Is that GetSTR() supposed to be there in merc.cpp

int16 Merc::CalcAGI() {
int16 val = _baseAGI + itembonuses.AGI + spellbonuses.AGI;
int16 mod = aabonuses.AGI;

int16 str = GetSTR();

AGI = val + mod;

if(AGI < 1)
AGI = 1;

return(AGI);
}

Armm
04-06-2013, 01:41 PM
One bug and a few things i dont understand.

I buy a level 50 J2 tank merc, has base stats like DB using #showstats. If i buff him with "Swift like the wind" spell number 172 which to my knowledge has no stat or resist buffs in it, then the merc has around 20 added to str,dex,40 to sta, 20 to agi, and resists are bumped up 60? When you suspend and restore the merc MOST of the time the stats return back to normal. Picture is below demonstrating me buying the merc, #showstats, buffing-showstats, suspending and bringing him back - showstats. I totally don't understand this.

Why do the mercs have so much attack? The values in the database don't match up with stats shown in game, and the ATK stats in the database are SKY high.

If i am understanding the code in attack.cpp right below then its looking for merc ATK which doesn't seem to be the same as in the database(which is even higher) Is it using CalcATK() from merc.cpp?? If so does then CalcATK also adds strength and skill to come up with its number?? If CalcATK does that then isnt Str and Offense added twice when it hits the code below??

I am trying pretty hard to balance things for my server, and the ground keeps shifting under my feet every time i solve one problem. Any information is apprecaited. Thank you.

if(attacker->IsClient())
{
attack_rating = (attacker->CastToClient()->CalcATK() + ((attacker->GetSTR()-66) * 0.9) + (attacker->GetSkill(OFFENSE)*1.345));
}

else
{
attack_rating = (attacker->GetATK() + (attacker->GetSkill(OFFENSE)*1.345) + ((attacker->GetSTR()-66) * 0.9));
}



http://s23.postimg.org/dbtw2hniz/mercstats.jpg

bad_captain
04-06-2013, 02:30 PM
I've been out and busy the last 2 weeks, so I'm going to try and get back into this this weekend and check out some of the issues you've pointed out.

I'd have to look into the buffs. Not sure what's going on there.

Attack and AC are kind of confusing and how they are calculated and displayed are different between clients, npc, bots, mercs, and pretty much everything else. Merc base ATK and AC may be higher than what clients are used to because they have little to no way to improve them. No equipment upgrades, no AAs, etc. Only buffs can be used to increase them. They may still be a little high, as I just guessed when I created them, trying to get them close to high end client values at that level. If you have a specific example of what one should be, I can adjust them accordingly.

#Showstats shows different values for Bots as well, but I'd have to look into it again, as it's been a while since I tried to figure it out. I do remember ATK values being maybe half what they should have shown for bots.

Edit: Looks like that is being added twice. I'll get that removed.

bad_captain
04-06-2013, 02:44 PM
I have figured out the buffs issue, I believe. I'll see if I can get it in this weekend.

Armm
04-06-2013, 06:20 PM
Thank you.

I agree the attack code is confusiing. Since you asked for a specific example ill give you one with the level 50 scenario above. The example below ASSUMES i know what the code is doing. I am going to leave ATK values out of it because im not sure what is being calced here.

Mob is level 50 Froglok Dar Knight from sebilis who has an AC of 429 in DB.

Level 50 Merc attack the Froglok. Merc has str of 267, and warrior for that level has offense of 210. Running that through formuyla listed above WIHTOUT the ATK added onto it gives you 463 for attack RATING.

Froglok is an NPC so the NPCACfactor rule is 2.25 by default.

else if(IsNPC())
{
armor = CastToNPC()->GetRawAC();

if(!IsPet())
{
armor = (armor / RuleR(Combat, NPCACFactor));
}

armor += spellbonuses.AC + itembonuses.AC + 1;
}

so the Frogloks armor is AC/2.25 + spells and item bonuses which means his AC before class armor caps is 190.

You can see the problem is that the attack rating is already over 2 times the AC to begin with. Now if you add (im working from memory) several hundred or thousand ATK once or twice you can see that the attack rating to AC ratio is someplace from 3x to 20x.

To be fair , you are remarkably close on your AC settings for mercs tanking NPCs.

bad_captain
04-25-2013, 01:00 AM
I removed the doubling of the strength factor & offense for ATK for mercs, and some extra stats added in during stat calculations (I still had bot racial/class stats being added in), which I removed.

I will look more into the attack issue, and see if I can get ATK to be a little more reasonable comparable to group content geared clients. At 50, the highest value in the DB is 1600 for melee DPS (1550 for tanks). At 65, these values are 2080 and 2015. Adding in STR & Offense twice would mean 600-700 extra attack at 65, not really a few thousand. Either way, the calculation will still mostly come out where the attacker's attack rating is significantly higher than the mobs defense rating (when using the NPCACFactor), as mob AC is fairly low, especially at those lower levels.

Anyway, hopefully that helps.

Furniture
04-30-2013, 09:44 PM
Tonight I started building an eqemu server after many months of inactivity and I am encountering this same exact error with the duplicate keys and it wont create the mercs_inv table. Any help would be appreciated!

Furniture
04-30-2013, 09:49 PM
Sorry - heres my error, latest compile of everything, just cant source this update - 2013_03_1_Merc_Rules_and_Equipment

It stops when it tries to create the merc_inventory table:

Furniture
04-30-2013, 09:52 PM
Heres the exact error I am getting




The final error i couldnt get past and i tried this in mysqldump and heidesql... once it get to the part where it wants to create merc_inventory it throws an error saying..

DROP TABLE IF EXISTS merc_inventory;
CREATE TABLE merc_inventory (
merc_inventory_id int(10) unsigned NOT NULL auto_increment,
merc_subtype_id int(10) unsigned NOT NULL default '0',
item_id int(11) unsigned NOT NULL default '0',
min_level int(10) unsigned NOT NULL default '0',
max_level int(10) unsigned NOT NULL default '0',
PRIMARY KEY (merc_inventory_id),
KEY FK_merc_inventory_1 (merc_subtype_id),
CONSTRAINT FK_merc_inventory_1 FOREIGN KEY (merc_subtype_id) REFERENCES merc_subtypes (merc_subtype_id)
);
/* SQL Error (1005): Can't create table 'peq.merc_inventory' (errno: 150)

Foreign key constraint is incorrectly formed */

bad_captain
05-01-2013, 10:00 AM
See my response here:

www.eqemulator.org/forums/showthread.php?t=36795

GurkhaPanzers
07-17-2013, 05:21 PM
I haven't compiled the source code in a while. May I ask Merc status. Do they work today? Are Mercs clerics and tanks only still?

provocating
09-14-2013, 08:48 AM
I am rather wondering the same thing. I had previously sourced in all of the merc SQL statements months ago. Two days ago I did a drop_system.sql and imported in the newest PEQ, recompiled my server source, maybe sure mercs were enabled in the rules table. If I go up to a liaison and right click nothing happens. I went ahead and sourced in the SQL for the mercs again, listed from a previous post and still nothing.

I did read were there were a few problems with ghosting mercs and saw there is a GIT fix request posted from Kimmy have mercs been disabled in code recently?

Robregen
09-14-2013, 11:12 AM
http://www.eqemulator.org/forums/showthread.php?t=37086&page=2

provocating
09-14-2013, 12:02 PM
I guess I was looking in the wrong direction. I did see where the was a "failed to spawn" error people were talking about but I did not think it was related. RandyMarsh's sql update fixed it for me, yay!!

Thank you so much Robregen, your help to the community is always greatly appreciated.

provocating
09-14-2013, 04:12 PM
One thing I did notice today is that I am indeed getting charged the merc upkeep cost, but the window shows 0 pp and 0 gold. Is this possibly just a client issue, I do believe I could had been using RoF instead of UF when I noticed it.