nwn2fixes / player

Fixes for the casual NwN2 player
29 stars 11 forks source link

Cannot bargain with Mephasm for stat buffs in the OC #8

Closed Question2 closed 5 years ago

Question2 commented 5 years ago

With the infernal focuse, i can bargain with mephasm for a weapon, helm, boots, or money, but i cannot bargain with him for the stat boosts. I can ask him about the stat boosts, and he will say that i need to sacrifice something important to me, but i get no option to actually do it.

Looking at guides on the net, it seems the script is supposed to ask you to sacrifice a weapon or armor for non-monk classes, but i am not getting any dialog option to do that.

Im playing a favored soul and am using armor/weapons that are self-enchanted, maybe either of those are causing issues with the script?

kevL commented 5 years ago

DANGER Will Robinson - MAJOR SPOILER re. deals w/ Mephasm follow.






Your PC has to enter the Crossroad Keep courtyard with the same item equipped at least three times in a row. For Monks, the item has to be in the Gloves slot; for Sorcerers/Wizards/Warlocks, the Chest slot; any other class checks the Righthand slot (unless it's the Silver Sword in which case the Chest is used instead).

NinjaSpectre commented 5 years ago

FYI you can do a spoiler tag

Super secret stuff ```
Heading that is displayedwhatever you want secret
```
Question2 commented 5 years ago

Yes, ive read that, ive had my custom enchanted weapon equipped every time i entered the keep, and ive done that over a dozen times.

Does it work for custom enchanted weapons for you?

kevL commented 5 years ago

idk, have you tried it without a custom enchanted weapon?

NinjaSpectre commented 5 years ago

EDIT: Never mind, the function not being able to search all classes and therefore just returning -1 should not cause any problems...

Move Along, Nothing to See Here Ok... I think I found it... In script 21_inc_crossroad there is this function: ```c++// Get the main class of the First PC, by checking if the PC has greater than 8 levels in a particular class int GetMainClass() { object oPC = GetFirstPC(); int nClass; for (nClass = 0; nClass < 40; nClass ++) { if ( GetLevelByClass(nClass,oPC) > 8 ) return nClass; } return -1; } ``` Problem is that global ```c++ int CLASS_TYPE_FAVORED_SOUL = 58; ``` Highest defined class global is ```c++ int CLASS_TYPE_HELLFIRE_WARLOCK = 61; ``` Most of the ones over 40 are Prestige, but there are a couple exceptions...
kevL commented 5 years ago

yep

edit: it's still a silly function but it ain't broke ...

funct ```c++ int GetMainClass(object oPc) // kL { int iLevel = 0; int iLevelTest; int iPosHigh = 1; int iPos = 1; for (; iPos <= 4; ++iPos) // iterate over class-positions (1..4) { iLevelTest = GetLevelByPosition(iPos, oPc); if (iLevelTest > iLevel) { iLevel = iLevelTest; iPosHigh = iPos; } else if (!iLevelTest) break; } return GetClassByPosition(iPosHigh, oPc); } ```
kevL commented 5 years ago

It's possible (though highly unlikely) that the tag of the weapon is blank, resulting in some sort of undefined behavior.

Question2 commented 5 years ago

I tried equipping a regular +1 scimitar and Mephasm was willing to bargain with me for stat boosts. He took the +1 scimitar as payment.

It seems that the script cannot handle bargaining if you only have custom enchanted armor/weapons equippped.

kevL commented 5 years ago

here's the code that runs (irrelevant stuff removed)

The PC enters the courtyard:

2100_court_cliententer ```c++ void main() { if (FiredFromPartyTransition()) // enter the courtyard (but not by loading a save) { CheckEvents(); } } void CheckEvents() { object oPc = GetOwnedCharacter(GetFactionLeader(GetFirstPC())); // get party-leader's TruePC character if (iCurrentAct == 3) // is Act III { if (GetGlobalInt(JOIN_MEPHASM) == 2) // Mephasm has been summoned once already { SetFavoredItem(oPc); } } } void SetFavoredItem(object oPc) { object oMeph = GetObjectByTag("31_mephasm"); if (GetIsObjectValid(oMeph) && !GetLocalInt(oMeph, "favored_item_taken")) // Mephasm is valid and hasn't bartered for favored item yet { object oThing; // must have an item equipped in an appropriate slot string sTag; // <- THIS IS WHAT MATTERS switch (GetMainClass(oPc)) // get the PC's reasonably highest class { case CLASS_TYPE_MONK: oThing = GetItemInSlot(INVENTORY_SLOT_ARMS, oPc); if (GetIsObjectValid(oThing)) sTag = GetTag(oThing); break; case CLASS_TYPE_SORCERER: case CLASS_TYPE_WARLOCK: case CLASS_TYPE_WIZARD: oThing = GetItemInSlot(INVENTORY_SLOT_CHEST, oPc); if (GetIsObjectValid(oThing)) sTag = GetTag(oThing); break; default: oThing = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPc); if (GetIsObjectValid(oThing)) sTag = GetTag(oThing); // if the weapon is the Silver Sword of Gith use armor instead if (sTag == "SilverSword") { oThing = GetItemInSlot(INVENTORY_SLOT_CHEST, oPc); if (GetIsObjectValid(oThing)) sTag = GetTag(oThing); else sTag = ""; } break; } if (sTag != "" && sTag == GetGlobalString("31_sFavoredItem")) // if there is a Tag and it's the same tag that's already been set by a previous entry to the Courtyard { SetGlobalInt("31_nFavoredItemCount", GetGlobalInt("31_nFavoredItemCount") + 1); // update the count of entries to the Courtyard } else // set a new favored item Tag and reset the counter { SetGlobalString("31_sFavoredItem", sTag); SetGlobalInt("31_nFavoredItemCount", 0); } } } ```

note: Those are my versions of the functions.

And in dialog '31_mephasm' it must be the third "bargain_attempts" and the second+ "mephasm_visits" or something like that (the dialog file is long and complicated) ... also, the favored item must be equipped and the PC must not have already made a deal for his/her favored item.

As you might see, numerous things can fail. But having coded and tested vast tracts of crafting/enchanting code, I can't think of a reason why simply enchanting an item would make a bargain w/ Mephasm fail.