Monsters and Memories (Project_N) - Old School Indie MMO

Flobee

Vyemm Raider
2,671
3,067
Far too early to have an opinion but I've been hanging out in the lead dev's Twitch recently and they just sent out the first description of the game. Guy(Shawn) running this is the same one doing the interviews with OG EQ devs. Himself being an EQ designer. He's saying a lot of the stuff I've been saying regarding an indie MMO so hoping for the best with this one. He may not be ready for this to be shared someplace like this, but we're essentially the target audience so its seems appropriate.


BmuKMg_ogoGaHjOXW5hcW-dxl8mR1hUe7Ajv56pi4kbrE1rbKtrozJGO4RKtmfJIoU30Ohl2DaqSE8c4ujsyFnslhABTdB2ZIIcwd5pNBfe-Wf-UkBuqaKLUkvrxeofELVX_7oumbGd_F3ifb1k03W-lSH-1tw=s0-d-e1-ft


What is Project_N?​

Project_N started as a discussion between MMO fans during a series of livestreams about what it would be like to create a niche, smaller budget / indie game, in the style of a classic MMO, but utilizing modern day tools and development practices.
The discussion focused on the idea that by focusing on a very specific audience and core beliefs, a MMORPG could be developed without spending 10’s of millions of dollars, and do well enough to maintain an ongoing live service.
This was supported by Shawn’s experience working on smaller, more niche live MMOs, and in looking at independent MMOs that were available at the time.
As talks continued, a small, passionate group of like minded individuals shared interest in working on a game together.
Project_N is now in the early prototyping stages and already hitting some early milestones focused on establishing a working client-server, content development tools, game design, and lore.
u5sCuAs5-DL2l_ip84GQ-DCio-OSIyUyEv5_3EbHy1AMpkavPAqkyeMMXvP7uSIhionEp3LTvjY-WEi2AuzIuuuyYsbPkzEFecPzyDdhZoLTPHvRHiN2IaZ63ZU5Q93x2qSz_TVpPmQXNxHhBI8c9VEMBmcTLQ=s0-d-e1-ft

What are the working design tenets?​

Nostalgia, Familiarity, Timelessness
  • Highly referential of classic fantasy themes, tropes, stories, media, and 70s-80s rock album covers
  • An art style that leverages the modern engine, but allows the imagination to fill in the blanks
  • A world filled with places, races, and classes that feels familiar, yet unpredictable
Simple, Deliberate Gameplay
  • Simple, streamlined, strategic combat; reminiscent of classic era MMOs
  • Slower gameplay and progression pacing
  • Persistence and ongoing involvement with the world and other players pays off over time
Community, Identity, and Reliance
  • Adventuring is at the heart of the game, and focused on single groups
  • Class & Skills are designed to feel familiar, with distinct identities and interdependence
  • Even solo play ties into a greater/communal purpose
  • World & Starting City designs focus on longevity and long-term utility, in order to maintain social friction and mitigate “generational stratification”
World is living, layered, and immersive (“the world as a Living Onion”)
  • A focus on scheduled and ever-changing content & NPC behaviors
  • Using time, seasonality, factions, and relationships to maintain a sense of mystery and discovery
  • Many systems are stripped of hand-holding and overt explanation
  • Other systems provide discoverable, new ways to interact with the world, including:
    • “Playable Monsters”
    • “Monster Cities”
    • “Transformations”
    • “Storytellers”
rUAenraZS49KZjnnLqrXpwl5ytCDMjtDZ_YYm2Y9XK1P7GNLy8hXWPx4rfmz80QaisOU3pwW9W2IBGYNI2vyDlEKr5F-DkTov2N-oktGLJsTpgxhGWzhI12sP0DuTaNRFOkmyROssMvp3-mxuJiBHfTVnDyJlg=s0-d-e1-ft

What is the setting?​

Project_N has the setting of a fairly traditional, classic fantasy world.
While standard high fantasy characters, creatures, and biomes are to be expected, a key defining feature of our world is that it is a land of ruins, on top of ruins, on top of ruins.

The goal of some day finding out how they got there, quickly becomes apparent.
And in our world, given it’s histories and catastrophes, its inhabitants always keep an watchful eye on the vast oceans, sprawling caverns, and most importantly, night skies.

Have you decided on player races & classes?​

We are still finalizing our race and class list for Project_N.

However, you shouldn’t be shocked to find many of the usual races and classes you would expect in classic high fantasy, as well as other old school MMOs, will be available for play.
Again, for us, familiarity and maintaining a sense of nostalgia are key.
One thing of note, is our desire to maintain a very open dialogue with the community about class design, as well as posted class design intents.
Classes are key to who we are as players, so it’s critical to maintain transparency and involvement here.
Ud3BdO1FoeWDmkVkhg0uyYwNdbdmIhEcNXp0KkSVEW1t7MTXgfutWo9UDQpOAU_3g48pwduIYxBu01FXYKxullBTJQdUG3Q7cOKlqQfyi3BDkVQCUkqbm_kjmYM_PFHrE59K1LBpTjR7HoY_ZtUgMot8XJZftjcUCeeaZg=s0-d-e1-ft

What art style are you aiming for?​

We’re set on a slightly stylized, hand-painted art style, which looks to the paintings of classic fantasy artists for inspiration. It uses lower-fidelity geometry to recreate the classic MMO feel, while leveraging the power of the modern game engines (in our case, Unity).
The tone is lighthearted, despite often touching on menacing or serious themes. And in some cases juxtaposes terrifying situations with goofy looking characters (like Gnomes, Ogres, and Trolls).
This should all create a sense of Fantastic Realism, which draws heavily on classic fantasy games, illustration, and film.

Who is your target audience?​

OG MMO players!
Our core target audience are PC gamers who have played MMORPGs during their “classic” eras or legacy versions, or have come to them more recently while searching for a greater sense of challenge and free-form exploration.
Within this group, we are targeting individuals that prefer paying for a monthly subscription, over F2P with microtransactions. They’re looking to figure things out on their own, prefer a slower pace, which allows for time to chat and/or drink an adult beverage or two. They are looking for a sense of place, rather than a skill-based challenge.
Many of these individuals found the first MMORPGs based on their love of MUDs, pen & paper games, CRPGs, or just a desire to share in an online fantasy world.
While we believe this to be our core audience, we also believe that secondary and tertiary audiences do exist for this game, including those who enjoy social tabletop roleplaying or even simulation games, or are just learning about online games from other sources, and seek out the traits listed above.

What's the business model?​

Project_N will use the monthly subscription model, with no pay-to-win microtransactions. Paid customization is also likely to be excluded from this model, with a focus instead on purchasable elements which remain outside of the gameworld to allow players to provide additional support to the team.
This includes nostalgic items, such as cloth maps and trinkets, as well as clothing, stickers, and an ultra-bitchin' backpatch for your sleeveless blue jean jacket.

Who is involved?​

The current roster is as follows:
aLovingRobot - Robot aka Shawn has been working in the gaming industry for the past 20 years at companies like Sony Online Entertainment and KingsIsle Entertainment.
He was a Lead Designer on several hit MMO titles including EverQuest and DC Universe Online. Most recently, Shawn was the Executive Producer and Chief Product Officer at Star Stable Entertainment.
Shawn is focused on Creative Direction and Product Management, while also contributing as an Artist and Designer.

Ali - Ali is a farmer by day and experienced Game Programmer, Designer, and Artist by night. Hailing from the emulator community, he has also been known to do game jams in his spare time.
Ali has spearheaded the creation of the Project_N client/server prototype, as well as many other technical aspects of the project.

Nick - Nick has been working in the gaming industry for the past 2 years at NetherRealm Studios, during which he was part of the team that shipped Mortal Kombat 11. However, his history with gaming is much more storied.
An MMO veteran of 20+ years, Nick spends his spare time working on several MMO related side projects. In the past, he’s been a professional gamer, in which he streamed to a large audience as a Twitch Partner.
Nick is focused on design, project management, testing, community, and other responsibilities for Project_N.

Shakabrah - Shakabrah is an experienced front end and Unity developer currently working on the Project_N User Interface.

Astra - Astra has dabbled in competitive Esports, plays like 15 MMOs at once all the time and has played all of them ever, and is currently writing Lore for Project_N in preparation for designing quests and content. Astra, aka Moonybun, was also the first mod (and pretty much the first follower) on aLovingRobot’s Twitch stream.
PDyijFi3uU7L-F35UHaDaSFGNTq52NqdQaTf-QlejgPNlM3EcPWpMajy6pjiGlYarIAlG8fc2th39bmxEJ7UER-0ngSPjhbcfmruKJ0dqZvAdOxu0jcJkoxpNklQ0bAI9ZeZT-zlUPQC5omxUL1DcvWVe44-Sw=s0-d-e1-ft

When will it be finished?​

While we don’t have a release date in mind for Project_N, one of our goals with this project is to avoid scope creep, and maintain humble, realistic expectations for launch.
We do not want this to be an extremely long development cycle. We want to get this game into the hands of players soon.
As part of this, we’ve been very open with our development (frequently livestreaming work in real-time), often discussing ideas with the community and other teams as we go.
Our goal is to maintain this level of openness and transparency, despite potential risks, and use this process as a means of sharing in the experience with our community.
Plus, this is a MMO… it’ll never be finished, even when it’s “finished.”

How can I support the project?​

The best way to support the project is to continue tuning into Shawn’s stream on Twitch: https://twitch.tv/aLovingRobot.
All subscriptions, bits, and other revenue from the Twitch stream is fed back into the project’s costs (ex. concept art, premium software services, domain costs, etc), so it’s super appreciated, but definitely not required.
Just being part of the community helps drive this forward.
Please keep hanging out, and sharing information about the project, stream, YouTube channel, etc with your friends and network.
We appreciate the offers to assist directly, and this is something we’re currently researching and working out, as part of the continued evolution of the project.
News and information about additional ways to support the project will be made known as they are determined.

 
Last edited:
  • 3Like
Reactions: 2 users

ili

Blackwing Lair Raider
517
193
They should 100% go with the p2w approach and have a real money auction house like Diablo 3 had. Clearly most people don't care about RMT anymore, take EQ for example, with the Korno stuff, buying bags, and buff pots, and WoW with the, whatever it's called, Tokens.
 
  • 1Pants on Fire!
Reactions: 1 user

velk

Trakanon Raider
2,628
1,205
They should 100% go with the p2w approach and have a real money auction house like Diablo 3 had. Clearly most people don't care about RMT anymore, take EQ for example, with the Korno stuff, buying bags, and buff pots, and WoW with the, whatever it's called, Tokens.

You call that pay to win ?! What they really need to is have popups when you are losing that show your character beaten and up and crying with the equivalent of 'insert coin to continue' plastered across the screen ;p
 
  • 1Like
Reactions: 1 user

fjurn

Molten Core Raider
15
16
I love it - hoping them all the best. Will be following this as it develops.

Why all the negativity? They seem to be stepping up and taking a swing with a pretty level headed approach. Its way to early to know much about anything other than a desire to make the world that people seem to want.
 
  • 3Like
Reactions: 2 users

Lambourne

Ahn'Qiraj Raider
2,838
6,759
Definitely interested, I think they make some good points. Keep it simple, don't reinvent the wheel with wacky settings or strange races. EQ just copied Forgotten Realms and it served them very well because it helped the target audience quickly feel at home and made the world believable. Some things are popular because they work.
 

TJT

Mr. Poopybutthole
<Gold Donor>
42,510
108,122
Cool idea. I'll casually observe it's progress.

And on that note I agree. Keeping the lore intentionally vague but recognizable (high fantasy) is ideal for immersion and character establishment. This is why DND has done it forever.
 
  • 1Like
Reactions: 1 user

Secrets

ResetEra Staff Member
1,900
1,914
Project N comes after Project M, of course. ;)

All the people involved are talented folks. I've been sort of a background advisor for them getting off the ground, and they kept the expectations realistic. I would be working with them if I didn't have my own position elsewhere in industry currently.

Nick and Ali are some of the coolest folks from EQ I have ever met, and they share the design tenants that a lot of EQ players do. They all have exceptional synergy together and it's exciting to see the development progress livestreamed on Twitch. It's a lot more grassroots than say, Pantheon, which seems to be taking the more 'wait till it's done to show it all off' approach.

This is super early dev (lot of the art is all placeholder or intermediate placeholders) and is in no way representative of a final product.
One of the biggest benefits of doing streams like this, is that players are actually feeling 'involved' in some way. Feedback comes in real-time and it helps the developers shape expectations and gives those that may be new to game development a chance to learn what goes into the games themselves. This also lets potential players set their expectations before they jump in and 'buy or try' a game they may actually want to play without any upfront cost in doing so.

 
  • 2Like
Reactions: 1 users

WorryPlaysGames

Blackwing Lair Raider
537
311
This is actually pretty cool that they are streaming as they work on it. Basically a updated EQ but with he same type of graphics it seems?

I just hope they are able to keep some mystery involved and not have everything datamined before it happens. Sure, with the internet, stuff is out there right away, but not knowing full quests or drop tables would be fun for new stuff.
 

Mat'hir Uth Gan

Trakanon Raider
312
1,007
Nick is the guy from some of the pre-alpha Pantheon videos that were allowed a few years ago. Part of Zaide's guild I believe. Is this a bunch of forum bros getting together to out-Pantheon, Pantheon?
 
  • 1Like
Reactions: 1 user

Secrets

ResetEra Staff Member
1,900
1,914
This is actually pretty cool that they are streaming as they work on it. Basically a updated EQ but with he same type of graphics it seems?

I just hope they are able to keep some mystery involved and not have everything datamined before it happens. Sure, with the internet, stuff is out there right away, but not knowing full quests or drop tables would be fun for new stuff.

I don't think that'll be an issue. EQ was made in 1999 and had no 'datamining' issues.

Sure, you might be able to see new creature models, graphical assets, etc, but considering the year EQ was made in and that we don't know everything about the game still, and rely on Twitch streams like Shawn Lord's to find out the behind the scenes work... it's safe to say that the Project N team realizes that mystery is a big part of their design, and plans to embrace it like the devs of old, but now there's tech out there that allows you to hide that stuff way better.

Unsurprisingly, EQ's full items data are still not known. There's stuff hidden in the DB that it would take years to be precise and accurate with. There's items in the Plane of Disease that are 0.1% chance of dropping from certain named creatures. Torven has been discovering them left and right on EQLive when trying to recreate it for TAKProject's PoP release. There's a ton of mystery in EQ, albeit most stemming from bad design. But systems like these do build hype for exploration and character progression as a core gameplay mechanic. Sure, they might all be figured out eventually - but part of the fun in EQ's early years were mapping and documenting the game together.
 
  • 3Like
Reactions: 2 users

Lambourne

Ahn'Qiraj Raider
2,838
6,759
I'm not a programmer but couldn't the data mining be countered by streaming data to the client rather than having some huge client-side database with every quest/model/item in it for hackers to poke at?
EQ (and even WoW) were designed to work with dial-up, the average user has several orders of magnitude more bandwidth available these days. Obviously it's not going to stop it completely but at least it wouldn't all be out weeks/months in advance like WoW patches.
 

Secrets

ResetEra Staff Member
1,900
1,914
I'm not a programmer but couldn't the data mining be countered by streaming data to the client rather than having some huge client-side database with every quest/model/item in it for hackers to poke at?
EQ (and even WoW) were designed to work with dial-up, the average user has several orders of magnitude more bandwidth available these days. Obviously it's not going to stop it completely but at least it wouldn't all be out weeks/months in advance like WoW patches.
Accessibility is important for games, too. Not everyone has 5Mbit download in today's day and age, even though great progress was made. It'd exclude a lot of folks from being able to play.

The same goes with hardware.

When a game I worked on professionally cut off 32-bit support, and killed the DX9 renderer, we saw a significant drop in players able to run the game. Most who previously had a good system for the game's age were all of a sudden not able to play due to the 8 byte addressing raising the memory requirement, and the increased GPU demand from DX11.

Bandwith and hardware are the two most limiting factors. With all being said, there's a lot on the client side for EQ that shouldn't really be there. Like the AC/ATK formulas. A lot of the shared code is ifdef'd out in EQ (as seen from code stubs in disassembly) but there's a lot that *isn't*.

I'd say you could get away with a game like EQ being headless and only taking commands from the server to store stats, items, inventory slots, etc, for pretty much everything except local player movement inputs - hell, I even did that -within- EQ on Classless 3.0 where stats are now piped down to the client from the server's calculations, and that's done without even having the source code to the game!

Implementation snippet below:

C++:
typedef enum eStatEntry
{
    eStatClassless = 1,
    eStatCurHP,
    eStatCurMana,
    eStatCurEndur,
    eStatMaxHP,
    eStatMaxMana,
    eStatMaxEndur,
    eStatATK,
    eStatAC,
    eStatSTR,
    eStatSTA,
    eStatDEX,
    eStatAGI,
    eStatINT,
    eStatWIS,
    eStatCHA,
    eStatMR,
    eStatFR,
    eStatCR,
    eStatPR,
    eStatDR,
    eStatWalkspeed,
    eStatRunspeed,
    eStatWeight,
    eStatMaxWeight,
    eStatMeleePower,
    eStatSpellPower,
    eStatHealingPower,
    eStatMeleeHaste,
    eStatSpellHaste,
    eStatHealingHaste,
    eStatMeleeCrit,
    eStatSpellCrit,
    eStatHealingCrit,
    eStatTotalPower,
    eStatSynergyLevel,
    eStatMitigation,
    eStatAAPoints,
    eStatMax
};

typedef struct EdgeStatEntry_Struct {
    uint32_t statKey;
    uint64_t statValue;
};

typedef struct EdgeStat_Struct
{
    uint32_t count;
    EdgeStatEntry_Struct entries[0];
};

typedef string(*pEqTypesFunc)(EQLabelTypes LabelID);

std::map<EQLabelTypes, pEqTypesFunc> eqTypesMap = std::map<EQLabelTypes, pEqTypesFunc>();

std::map<EQLabelTypes, eStatEntry> statLabelMappings = std::map<EQLabelTypes, eStatEntry>();

std::map<eStatEntry, int64_t> statEntries;

VOID InitializeLabels(VOID)
{
    eqTypesMap[EQLabelTypes::CurrentHitPoints] = EQLabelFunction;
    eqTypesMap[EQLabelTypes::ManaNumber] = EQLabelFunction;
    eqTypesMap[EQLabelTypes::EnduranceNumber] = EQLabelFunction;
    eqTypesMap[EQLabelTypes::MaximumHitPoints] = EQLabelFunction;
    eqTypesMap[EQLabelTypes::ManaNumberMax] = EQLabelFunction;
    eqTypesMap[EQLabelTypes::EnduranceNumberMax] = EQLabelFunction;
    eqTypesMap[EQLabelTypes::PlayersCurrentHP] = EQDualHPLabelFunction;
    eqTypesMap[EQLabelTypes::ManaMaxMana] = EQDualManaLabelFunction;
    eqTypesMap[EQLabelTypes::EnduranceMaxEndurance] = EQDualEndurLabelFunction;
    eqTypesMap[EQLabelTypes::Strength] = EQLabelFunction;
    eqTypesMap[EQLabelTypes::Stamina] = EQLabelFunction;
    eqTypesMap[EQLabelTypes::Dexterity] = EQLabelFunction;
    eqTypesMap[EQLabelTypes::Agility] = EQLabelFunction;
    eqTypesMap[EQLabelTypes::Wisdom] = EQLabelFunction;
    eqTypesMap[EQLabelTypes::Intelligence] = EQLabelFunction;
    eqTypesMap[EQLabelTypes::Charisma] = EQLabelFunction;
    eqTypesMap[EQLabelTypes::SpellHaste] = EQLabelFunction;
    eqTypesMap[EQLabelTypes::HitPointPercentage] = EQHPPercentageLabelFunction;
    eqTypesMap[EQLabelTypes::ManaPercentage] = EQManaPercentageLabelFunction;
    eqTypesMap[EQLabelTypes::StaminaEndurancePercentage] = EQEndurPercentageLabelFunction;
    eqTypesMap[EQLabelTypes::MeleeHaste] = EQLabelFunction;
    eqTypesMap[EQLabelTypes::HealingHaste] = EQLabelFunction;
    eqTypesMap[EQLabelTypes::SpellCrit] = EQLabelFunction;
    eqTypesMap[EQLabelTypes::MeleeCrit] = EQLabelFunction;
    eqTypesMap[EQLabelTypes::HealingCrit] = EQLabelFunction;
    eqTypesMap[EQLabelTypes::SpellPower] = EQLabelFunction;
    eqTypesMap[EQLabelTypes::MeleePower] = EQLabelFunction;
    eqTypesMap[EQLabelTypes::HealingPower] = EQLabelFunction;
    eqTypesMap[EQLabelTypes::TotalPower] = EQLabelFunction;
    eqTypesMap[EQLabelTypes::SavevsMagic] = EQLabelFunction;
    eqTypesMap[EQLabelTypes::SavevsCold] = EQLabelFunction;
    eqTypesMap[EQLabelTypes::SavevsFire] = EQLabelFunction;
    eqTypesMap[EQLabelTypes::SavevsPoison] = EQLabelFunction;
    eqTypesMap[EQLabelTypes::SavevsDisease] = EQLabelFunction;
    eqTypesMap[EQLabelTypes::Walkspeed] = EQSpeedLabelFunction;
    eqTypesMap[EQLabelTypes::Runspeed] = EQSpeedLabelFunction;
    eqTypesMap[EQLabelTypes::CurrentOffense] = EQLabelFunction;
    eqTypesMap[EQLabelTypes::CurrentMitigation] = EQLabelFunction;
    eqTypesMap[EQLabelTypes::Classless] = EQLabelFunction;
    eqTypesMap[EQLabelTypes::Class] = EQClasslessFunction;
    eqTypesMap[EQLabelTypes::Weight] = EQLabelFunction;
    eqTypesMap[EQLabelTypes::MaximumWeight] = EQLabelFunction;
    eqTypesMap[EQLabelTypes::WeightMaxWeight] = EQWeightLabelFunction;
    eqTypesMap[EQLabelTypes::SynergyLevel] = EQLabelFunction;
    eqTypesMap[EQLabelTypes::Mitigation] = EQSpeedLabelFunction;
    eqTypesMap[EQLabelTypes::AAPoints] = EQLabelFunction;
  
        statLabelMappings[EQLabelTypes::CurrentHitPoints] = eStatEntry::eStatCurHP;
    statLabelMappings[EQLabelTypes::ManaNumber] = eStatEntry::eStatCurMana;
    statLabelMappings[EQLabelTypes::EnduranceNumber] = eStatEntry::eStatCurEndur;
    statLabelMappings[EQLabelTypes::MaximumHitPoints] = eStatEntry::eStatMaxHP;
    statLabelMappings[EQLabelTypes::ManaNumberMax] = eStatEntry::eStatMaxMana;
    statLabelMappings[EQLabelTypes::EnduranceNumberMax] = eStatEntry::eStatMaxEndur;
    statLabelMappings[EQLabelTypes::Strength] = eStatEntry::eStatSTR;
    statLabelMappings[EQLabelTypes::Stamina] = eStatEntry::eStatSTA;
    statLabelMappings[EQLabelTypes::Dexterity] = eStatEntry::eStatDEX;
    statLabelMappings[EQLabelTypes::Agility] = eStatEntry::eStatAGI;
    statLabelMappings[EQLabelTypes::Wisdom] = eStatEntry::eStatWIS;
    statLabelMappings[EQLabelTypes::Intelligence] = eStatEntry::eStatINT;
    statLabelMappings[EQLabelTypes::Charisma] = eStatEntry::eStatCHA;
    statLabelMappings[EQLabelTypes::SpellHaste] = eStatEntry::eStatSpellHaste;
    statLabelMappings[EQLabelTypes::MeleeHaste] = eStatEntry::eStatMeleeHaste;
    statLabelMappings[EQLabelTypes::HealingHaste] = eStatEntry::eStatHealingHaste;
    statLabelMappings[EQLabelTypes::SpellCrit] = eStatEntry::eStatSpellCrit;
    statLabelMappings[EQLabelTypes::MeleeCrit] = eStatEntry::eStatMeleeCrit;
    statLabelMappings[EQLabelTypes::HealingCrit] = eStatEntry::eStatHealingCrit;
    statLabelMappings[EQLabelTypes::SpellPower] = eStatEntry::eStatSpellPower;
    statLabelMappings[EQLabelTypes::MeleePower] = eStatEntry::eStatMeleePower;
    statLabelMappings[EQLabelTypes::HealingPower] = eStatEntry::eStatHealingPower;
    statLabelMappings[EQLabelTypes::TotalPower] = eStatEntry::eStatTotalPower;
    statLabelMappings[EQLabelTypes::SynergyLevel] = eStatEntry::eStatSynergyLevel;
    statLabelMappings[EQLabelTypes::SavevsMagic] = eStatEntry::eStatMR;
    statLabelMappings[EQLabelTypes::SavevsCold] = eStatEntry::eStatCR;
    statLabelMappings[EQLabelTypes::SavevsFire] = eStatEntry::eStatFR;
    statLabelMappings[EQLabelTypes::SavevsPoison] = eStatEntry::eStatPR;
    statLabelMappings[EQLabelTypes::SavevsDisease] = eStatEntry::eStatDR;
    statLabelMappings[EQLabelTypes::CurrentOffense] = eStatEntry::eStatATK;
    statLabelMappings[EQLabelTypes::CurrentMitigation] = eStatEntry::eStatAC;
    statLabelMappings[EQLabelTypes::Mitigation] = eStatEntry::eStatMitigation;
    statLabelMappings[EQLabelTypes::Classless] = eStatEntry::eStatClassless;
    statLabelMappings[EQLabelTypes::Class] = eStatEntry::eStatClassless;
    statLabelMappings[EQLabelTypes::Weight] = eStatEntry::eStatWeight;
    statLabelMappings[EQLabelTypes::MaximumWeight] = eStatEntry::eStatMaxWeight;
    statLabelMappings[EQLabelTypes::AAPoints] = eStatEntry::eStatAAPoints;
}

BOOL OnRecvEdgeStatLabelPacket(DWORD Type, PVOID Packet, DWORD Size)
{
    if ((Size <= 4) || !Packet)
    {
        return true;
    }

    EdgeStat_Struct* incValues = (EdgeStat_Struct*)Packet;
    if (incValues->count * sizeof(EdgeStatEntry_Struct) != (Size - 4))
        return true;

    for (auto i = 0; i < incValues->count; i++)
    {
        if (incValues->entries[i].statKey == 0 || incValues->entries[i].statKey >= eStatMax)
            continue;
        eStatEntry Val = (eStatEntry)incValues->entries[i].statKey;
        statEntries[Val] = incValues->entries[i].statValue;
    }

    return true;
}

//then, use the data in the client when it needs it.
    int32_t CurHP_Trampoline(int, unsigned char);
    int32_t CurHP_Detour(int a1, unsigned char a2)
    {
        if (statEntries.find(eStatCurHP) != statEntries.end())
        {
            //For display purposes we really, really should not care what the value is. Only that it's the 'right' value for unconscious purposes.
            return statEntries[eStatCurHP] >= (INT_MAX - 1) ? INT_MAX - 1 : (int32_t)statEntries[eStatCurHP];
        }
        return 100;
    }

//or in the label function to display stats, for example
int __cdecl GetLabelFromEQ_Trampoline(int, class CXStr *, bool *, unsigned long *);
int __cdecl GetLabelFromEQ_Detour(int EQType, class CXStr *out, bool *arg3, unsigned long *colorout)
{
    int ret = GetLabelFromEQ_Trampoline(EQType, out, arg3, colorout);
    if (out && out->Ptr) {
        bool Found = FALSE;
        std::string eqtypesString = "";

        if (EQType == 29)
        {
            if (pTarget && pLocalPlayer && pTarget == pLocalPlayer)
            {
                eqtypesString = EQHPPercentageLabelFunction((EQLabelTypes)EQType);
                SetCXStr(&out->Ptr, (PCHAR)eqtypesString.c_str());
            }
            return ret;
        }
        for (auto eqtype : eqTypesMap) {
            if (eqtype.first == EQType) {

                auto func = eqtype.second;
                if (func)
                {
                    eqtypesString = (*func)(eqtype.first);
                    Found = TRUE;
                    break;
                }
            }
        }
        if (Found)
        {
            SetCXStr(&out->Ptr, (PCHAR)eqtypesString.c_str());
        }
    }
    return ret;
}

PLUGIN_API BOOL OnLabelReceivePPPacket()
{
    statEntries.clear();
    return true;
}
 
  • 2Like
Reactions: 1 users

Evernothing

Bronze Baronet of the Realm
4,783
8,879
S Secrets I'm interested in setting up an EQemu server, and I have a question about databases.
Would you mind direct messaging me on here or discord?

Evernothing#2770