I would probably either have a different main character or box outfit. Like using a war instead of an SK for instance or a wizard instead of a rogue. Maybe a beastlord and cleric mercs instead of a cleric/shammy combo etc. I honestly don't think I would still be playing EQ without Macroquest though. It isn't that EQ is "unplayable" without it, but the ability to box my own group just adds a whole new level of entertainment for me.
If I might ask, what exactly does change with an expansion release? By "structure changes" does that refer to the inventory overhaul and how MacroQuest interacts with it? Obviously I'm no coder, but it's all very interesting to me.
I'll give you a example of how I understand it.
Here is the CHARINFO structure from macroquest2 from an old patch.
Code:
// actual size: 0x499c 7-14-10 - ieatacid
typedef struct _CHARINFO {
/*0x0000*/ void *vtable1;
/*0x0004*/ void *punknown;
/*0x0008*/ struct _CI_INFO* charinfo_info;
/*0x000c*/ BYTE Unknown0xc[0x101c];
/*0x1028*/ struct _LEADERABILITIES MyAbilities; //points spent in each ability (size 0x40)
/*0x1068*/ BYTE Unknown0x1068[0xc0];
/*0x1128*/ struct _CONTENTS* Bank[NUM_BANK_SLOTS];
/*0x1190*/ BYTE unknown0x1190[0xdc];
/*0x126c*/ DWORD GuildID;
/*0x1270*/ BYTE Unknown0x1270[0x8];
/*0x1278*/ DWORD GuildRank; // 0=Member, 1=Officer, 2=Leader
/*0x127c*/ BYTE Unknown0x127c[0x18];
/*0x1294*/ DWORD AAExp;
/*0x1298*/ BYTE Unknown0x1298;
/*0x1299*/ BYTE PercentEXPtoAA;
/*0x129a*/ BYTE Unknown0x129a[0x42];
/*0x12dc*/ DWORD TributeTimer;
/*0x12e0*/ DWORD CareerFavor;
/*0x12e4*/ DWORD Unknown0x12e4;
/*0x12e8*/ DWORD CurrFavor;
/*0x12ec*/ BYTE Unknown0x12ec[0xc];
/*0x12f8*/ DOUBLE GroupLeadershipExp;
/*0x1300*/ DOUBLE RaidLeadershipExp;
/*0x1308*/ DWORD GroupLeadershipPoints;
/*0x130c*/ DWORD RaidLeadershipPoints;
/*0x1310*/ BYTE Unknown0x1310[0x194];
/*0x14a4*/ DWORD RadiantCrystals;
/*0x14a8*/ DWORD Unknown0x14a8;
/*0x14ac*/ DWORD EbonCrystals;
/*0x14b0*/ BYTE Unknown0x14b0[0x630];
/*0x1ae0*/ DWORD Exp;
/*0x1ae4*/ BYTE Unknown0x1ae4[0x64];
/*0x1b48*/ void *PlayerPointManager;
/*0x1b4c*/ BYTE Unknown0x1b4c[0x634];
/*0x2180*/ void *vtable2;
/*0x2184*/ struct _EQC_INFO* eqc_info;
/*0x2188*/ struct _SPAWNINFO* pSpawn;
/*0x218c*/ DWORD Unknown0x218c;
/*0x2190*/ DWORD Unknown0x2190;
/*0x2194*/ DWORD CurrWeight;
/*0x2198*/ BYTE Unknown0x2198[0xc];
/*0x21a4*/ DWORD HPBonus;
/*0x21a8*/ DWORD ManaBonus;
/*0x21ac*/ DWORD EnduranceBonus;
/*0x21b0*/ DWORD CombatEffectsCap;
/*0x21b4*/ DWORD ShieldingCap;
/*0x21b8*/ DWORD SpellShieldCap;
/*0x21bc*/ DWORD AvoidanceCap;
/*0x21c0*/ DWORD AccuracyCap;
/*0x21c4*/ DWORD StunResistCap;
/*0x21c8*/ DWORD StrikeThroughCap;
/*0x21cc*/ DWORD Unknown0x21cc[0x9];
/*0x21f0*/ DWORD SkillMinDamageModBonus[0x9];
/*0x2214*/ BYTE Unknown0x2214[0x4];
/*0x2218*/ DWORD DoTShieldCap;
/*0x221c*/ DWORD DamageShieldMitigationCap;
/*0x2220*/ DWORD CombatEffectsBonus;
/*0x2224*/ DWORD SpellShieldBonus;
/*0x2228*/ DWORD ShieldingBonus;
/*0x222c*/ DWORD DamageShieldBonus;
/*0x2230*/ DWORD DoTShieldBonus;
/*0x2234*/ DWORD DamageShieldMitigationBonus;
/*0x2238*/ DWORD AvoidanceBonus;
/*0x223c*/ DWORD AccuracyBonus;
/*0x2240*/ DWORD StunResistBonus;
/*0x2244*/ DWORD StrikeThroughBonus;
/*0x2248*/ DWORD HeroicSTRBonus;
/*0x224c*/ DWORD HeroicINTBonus;
/*0x2250*/ DWORD HeroicWISBonus;
/*0x2254*/ DWORD HeroicAGIBonus;
/*0x2258*/ DWORD HeroicDEXBonus;
/*0x225c*/ DWORD HeroicSTABonus;
/*0x2260*/ DWORD HeroicCHABonus;
/*0x2264*/ DWORD HeroicSvMagicBonus;
/*0x2268*/ DWORD HeroicSvFireBonus;
/*0x226c*/ DWORD HeroicSvColdBonus;
/*0x2270*/ DWORD HeroicSvDiseaseBonus;
/*0x2274*/ DWORD HeroicSvPoisonBonus;
/*0x2278*/ DWORD HeroicSvCorruptionBonus;
/*0x227c*/ DWORD HealAmountBonus;
/*0x2280*/ DWORD SpellDamageBonus;
/*0x2284*/ DWORD Unknown0x2284[0x2];
/*0x228c*/ DWORD ClairvoyanceBonus;
/*0x2290*/ DWORD AttackBonus;
/*0x2294*/ DWORD HPRegenBonus;
/*0x2298*/ DWORD ManaRegenBonus;
/*0x229c*/ DWORD EnduranceRegenBonus;
/*0x22a0*/ DWORD DamageShieldCap;
/*0x22a4*/ DWORD AttackSpeed;
/*0x22a8*/ BYTE Unknown0x22a8[0xa8];
/*0x2350*/ struct _XTARGETMGR *pXTargetMgr;
/*0x2354*/ DWORD InCombat;
/*0x2358*/ DWORD Downtime;
/*0x235c*/ DWORD DowntimeStamp;
/*0x2360*/ BYTE Unknown0x2360[0x4];
/*0x2364*/ struct _GROUPINFO *pGroupInfo;
/*0x2368*/ BYTE Unknown0x2368[0x1c];
/*0x2384*/ void *pUnknown2;
/*0x2388*/ struct _CI2_INFO* pCI2;
/*0x238c*/ DWORD Unknown0x238c;
/*0x2390*/ BYTE languages[0x20];
/*0x23b0*/ BYTE Unknown0x23b0[0x10];
/*0x23c0*/ CHAR Name[0x40];
/*0x2400*/ CHAR Lastname[0x20];
/*0x2420*/ BYTE Unknown0x2420[0x60];
/*0x2480*/ BYTE Stunned;
/*0x2481*/ BYTE Unknown0x2481[0x3];
/*0x2484*/ WORD zoneId;
/*0x2486*/ WORD instance;
/*0x2488*/ DWORD standstate;
/*0x248c*/ BYTE Unknown0x248c[0x4];
/*0x2490*/ struct _LEADERABILITIES ActiveAbilities; //ability levels of the leader of your group (size 0x40)
/*0x24d0*/ BYTE Unknown0x24d0[0x334];
/*0x2804*/ DWORD BankSharedPlat;
/*0x2808*/ DWORD BankSharedGold;
/*0x280c*/ DWORD BankSharedSilver;
/*0x2810*/ DWORD BankSharedCopper;
/*0x2814*/ DWORD BankPlat;
/*0x2818*/ DWORD BankGold;
/*0x281c*/ DWORD BankSilver;
/*0x2820*/ DWORD BankCopper;
/*0x2824*/ DWORD STR;
/*0x2828*/ DWORD STA;
/*0x282c*/ DWORD CHA;
/*0x2830*/ DWORD DEX;
/*0x2834*/ DWORD INT;
/*0x2838*/ DWORD AGI;
/*0x283c*/ DWORD WIS;
/*0x2840*/ DWORD SavePoison;
/*0x2844*/ DWORD SaveMagic;
/*0x2848*/ DWORD SaveDisease;
/*0x284c*/ DWORD SaveCorruption;
/*0x2850*/ DWORD SaveFire;
/*0x2854*/ DWORD SaveCold;
/*0x2858*/ BYTE Unknown0x2858[0x2144];
/*0x499c*/
} CHARINFO, *PCHARINFO;
Pretty much the server sends all this data to your client in just letters and numbers. The client knows what it all means as the structure is stored in your memory and filled by the client with appropriate data. We have no clue what it means, but we have to tell MQ2 how/where to access that data (offset(s)) and exactly how to read it (structure, or layout of the data)
On new expansions they add new pieces to this information and suddenly it's a few bytes bigger or they change a single piece of information inside it and you have to figure out what it is.
Your looking at about 40+ structures like above that need to be checked and fixed.
Here's another one for item info to give you another example
Code:
typedef struct _ITEMINFO {
/*0x000*/ CHAR Name[ITEM_NAME_LEN];
/*0x040*/ CHAR LoreName[LORE_NAME_LEN];
/*0x0b0*/ CHAR IDFile[0x20];
/*0x0d0*/ DWORD ItemNumber;
/*0x0d4*/ DWORD EquipSlots;
/*0x0d8*/ DWORD Cost;
/*0x0dc*/ DWORD IconNumber;
/*0x0e0*/ BYTE Unknown0xe0[0x9];
/*0x0e9*/ BYTE Weight;
/*0x0ea*/ BYTE NoRent; // 0=temp, 1=default
/*0x0eb*/ BYTE NoDrop; // 0=no drop, 1=can drop
/*0x0ec*/ BYTE Attuneable;
/*0x0ed*/ BYTE Unknown0xf0;
/*0x0ee*/ BYTE Size;
/*0x0ef*/ BYTE Type;
/*0x0f0*/ BYTE TradeSkills;
/*0x0f1*/ BYTE Padding0xf1[0x3];
/*0x0f4*/ BYTE Lore;
/*0x0f5*/ BYTE Unknown0xf5[0x3];
/*0x0f8*/ BYTE Artifact;
/*0x0f9*/ BYTE Summoned;
/*0x0fa*/ BYTE SvCold;
/*0x0fb*/ BYTE SvFire;
/*0x0fc*/ BYTE SvMagic;
/*0x0fd*/ BYTE SvDisease;
/*0x0fe*/ BYTE SvPoison;
/*0x0ff*/ BYTE SvCorruption;
/*0x100*/ BYTE STR;
/*0x101*/ BYTE STA;
/*0x102*/ BYTE AGI;
/*0x103*/ BYTE DEX;
/*0x104*/ BYTE CHA;
/*0x105*/ BYTE INT;
/*0x106*/ BYTE WIS;
/*0x107*/ BYTE Unknown0x107;
/*0x108*/ DWORD HP;
/*0x10c*/ DWORD Mana;
/*0x110*/ DWORD AC;
/*0x114*/ DWORD RequiredLevel;
/*0x118*/ DWORD RecommendedLevel;
/*0x11c*/ BYTE RecommendedSkill;
/*0x11d*/ BYTE Unknown0x11d[0x3];
/*0x120*/ BYTE SkillModType;
/*0x121*/ BYTE Unknown0x121[0x3];
/*0x124*/ DWORD Unknown0x124;
/*0x128*/ DWORD SkillModValue;
/*0x12c*/ DWORD BaneDMGRace;
/*0x130*/ DWORD BaneDMGBodyType;
/*0x134*/ BYTE BaneDMGBodyTypeValue;
/*0x135*/ BYTE BaneDMGRaceValue;
/*0x136*/ BYTE Unknown0x136[0x6];
/*0x13c*/ DWORD InstrumentType;
/*0x140*/ DWORD InstrumentMod;
/*0x144*/ DWORD Classes;
/*0x148*/ DWORD Races;
/*0x14c*/ DWORD Diety;
/*0x150*/ BYTE Unknown0x150[0x4];
/*0x154*/ BYTE Magic;
/*0x155*/ BYTE Light;
/*0x156*/ BYTE Delay;
/*0x157*/ BYTE DmgBonusType;
/*0x158*/ BYTE DmgBonusVal;
/*0x159*/ BYTE Range;
/*0x15a*/ BYTE Unknown0x15a[0x2];
/*0x15c*/ DWORD Damage;
/*0x160*/ DWORD BackstabDamage;
/*0x164*/ DWORD DamageShieldMitigation;
/*0x168*/ DWORD HeroicSTR;
/*0x16c*/ DWORD HeroicINT;
/*0x170*/ DWORD HeroicWIS;
/*0x174*/ DWORD HeroicAGI;
/*0x178*/ DWORD HeroicDEX;
/*0x17c*/ DWORD HeroicSTA;
/*0x180*/ DWORD HeroicCHA;
/*0x184*/ DWORD HeroicSvMagic;
/*0x188*/ DWORD HeroicSvFire;
/*0x18c*/ DWORD HeroicSvCold;
/*0x190*/ DWORD HeroicSvDisease;
/*0x194*/ DWORD HeroicSvPoison;
/*0x198*/ DWORD HeroicSvCorruption;
/*0x19c*/ DWORD HealAmount;
/*0x1a0*/ DWORD SpellDamage;
/*0x1a4*/ BYTE ItemType;
/*0x1a5*/ BYTE Unknown0x1a5[0x3];
/*0x1a8*/ BYTE Material;
/*0x1a9*/ BYTE Unknown0x1a9[0xb];
/*0x1b4*/ DWORD AugSlot1;
/*0x1b8*/ DWORD AugSlot1_Unknown;
/*0x1bc*/ DWORD AugSlot2;
/*0x1c0*/ DWORD AugSlot2_Unknown;
/*0x1c4*/ DWORD AugSlot3;
/*0x1c8*/ DWORD AugSlot3_Unknown;
/*0x1cc*/ DWORD AugSlot4;
/*0x1d0*/ DWORD AugSlot4_Unknown;
/*0x1d4*/ DWORD AugSlot5;
/*0x1d8*/ DWORD AugSlot5_Unknown;
/*0x1dc*/ DWORD AugType;
/*0x1e0*/ DWORD AugRestrictions;
/*0x1e4*/ DWORD SolventNeeded; //ID# of Solvent (Augs only)
/*0x1e8*/ DWORD LDTheme;
/*0x1ec*/ DWORD LDCost;
/*0x1f0*/ DWORD LDType;
/*0x1f4*/ DWORD Unknown0x1f4;
/*0x1f8*/ BYTE Unknown0x1f8[0x4];
/*0x1fc*/ DWORD FactionModType[0x4];
/*0x20c*/ DWORD FactionModValue[0x4];
/*0x21c*/ BYTE CharmFile[0x20];
/*0x23c*/ BYTE Unknown0x23c[0x4];
/*0x240*/ struct _ITEMSPELLS Clicky;
/*0x2a4*/ struct _ITEMSPELLS Proc;
/*0x308*/ struct _ITEMSPELLS Worn;
/*0x36c*/ struct _ITEMSPELLS Focus;
/*0x3d0*/ struct _ITEMSPELLS Scroll;
/*0x434*/ BYTE Unknown0x434[0x78];
/*0x4ac*/ DWORD CombatEffects;
/*0x4b0*/ DWORD Shielding;
/*0x4b4*/ DWORD StunResist;
/*0x4b8*/ DWORD DoTShielding;
/*0x4bc*/ DWORD StrikeThrough;
/*0x4c0*/ DWORD DmgBonusSkill; // SkillMinDamageMod;
/*0x4c4*/ DWORD DmgBonusValue; // MinDamageMod;
/*0x4c8*/ DWORD SpellShield;
/*0x4cc*/ DWORD Avoidance;
/*0x4d0*/ DWORD Accuracy;
/*0x4d4*/ DWORD CharmFileID;
/*0x4d8*/ DWORD CastTime;
/*0x4dc*/ BYTE Combine;
/*0x4dd*/ BYTE Slots;
/*0x4de*/ BYTE SizeCapacity;
/*0x4df*/ BYTE WeightReduction;
/*0x4e0*/ BYTE BookType; // 0=note, !0=book
/*0x4e1*/ BYTE BookLang;
/*0x4e2*/ CHAR BookFile[0x1e];
/*0x500*/ DWORD Favor; // Tribute Value
/*0x504*/ DWORD GuildFavor;
/*0x508*/ DWORD Unknown0x508;
/*0x50c*/ DWORD Endurance;
/*0x510*/ DWORD Attack;
/*0x514*/ DWORD HPRegen;
/*0x518*/ DWORD ManaRegen;
/*0x51c*/ DWORD EnduranceRegen;
/*0x520*/ DWORD Haste;
/*0x524*/ DWORD DamShield;
/*0x528*/ BYTE Unknown0x528[0x8];
/*0x530*/ BYTE NoPet;
/*0x531*/ BYTE Unknown0x531[0xb];
/*0x53c*/ DWORD StackSize;
/*0x540*/ BYTE Unknown0x540[0x4];
/*0x544*/ DWORD MaxPower;
/*0x548*/ DWORD Purity;
/*0x54c*/ BYTE Unknown0x54c[0x4];
/*0x550*/ DWORD Unknown0x550;
/*0x554*/ BYTE QuestItem;
/*0x555*/ BYTE Unknown0x555[0x3];
/*0x558*/ DWORD Clairvoyance;
/*0x55c*/ BYTE Unknown0x55c[0x18];
/*0x574*/
} ITEMINFO, *PITEMINFO;
You pretty much get a long string of information that is unlabeled and you have to figure out what it is. You get these wrong and your client wont enter game (Well if item info is wrong you wont be able to view item stats).
I would take a guess that ieatacid and other developers at macroquest2.com have these pretty much updated by now, the new thing they threw at us is the new backpack system, and trying to make sure plugins/macros will work with it will take a bit of time as this will be a little bit of custom coding we have never had to do before.
This is how I understand it, I'm no trained programmer so I could be a little wrong. I also have no inside information at what goes on at macroquest2.com.
I hope that helps.