Nwn2fixes


#102

yep & yep.

// Stores info on item about current possessor and slot equipped.
void RememberEquippedItem(object oPossessor, int iSlot)
{
    object oItem = GetItemInSlot(iSlot, oPossessor);
    if (GetIsObjectValid(oItem))
    {
        SetLocalInt(oItem, LAST_SLOT_NUM, iSlot + 1);
        SetLocalObject(oItem, LAST_SLOT_OBJ, oPossessor);
    }
}

// Stores info on all equipped items of possessor.
void RememberEquippedItems(object oPossessor)
{
    int iSlot = INVENTORY_SLOT_HEAD;
    for (; iSlot != NUM_INVENTORY_SLOTS; ++iSlot)
    {
        RememberEquippedItem(oPossessor, iSlot);
    }
}

// Restores item to slot last remembered.
void RestoreEquippedItem(object oPossessor, object oItem, int bReset = TRUE)
{
//  object oPossessor0 = GetLocalObject(oItem, LAST_SLOT_OBJ);

    int iSlot = GetLocalInt(oItem, LAST_SLOT_NUM);
    if (iSlot)
    {
        AssignCommand(oPossessor, ActionEquipItem(oItem, iSlot - 1));
        if (bReset)
        {
            DeleteLocalInt(oItem, LAST_SLOT_NUM);
            DeleteLocalObject(oItem, LAST_SLOT_OBJ);
        }
    }
}

// Restores all inventory items to equipment slot last remembered if any.
void RestoreEquippedItems(object oPossessor, int bReset = TRUE)
{
    // NOTE: righthand must be equipped before lefthand.
    object oLh;

    int iSlot;
    object oItem = GetFirstItemInInventory(oPossessor);
    while (GetIsObjectValid(oItem))
    {
        iSlot = GetLocalInt(oItem, LAST_SLOT_NUM);
        if (iSlot - 1 != INVENTORY_SLOT_LEFTHAND)
            RestoreEquippedItem(oPossessor, oItem, bReset);
        else
            oLh = oItem;

        oItem = GetNextItemInInventory(oPossessor);
    }

    if (GetIsObjectValid(oLh))
        RestoreEquippedItem(oPossessor, oLh, bReset);
}

#103

@kevL_s
Good. Here are general scripts that need to be recompiled:

  • ga_remember_equipped
  • ga_unequip_hands
  • ga_unequip_slot
  • ga_reequip_all_items
  • ga_restore_equipped

Found a typo in your code:

    if (GetIsObjectValid(oLh))
        RestoreEquippedItem(oPossessor, oLeftHandItem, bReset);

Replace oLeftHandItem with oLh.


#104

Tarmas house quest will clear if you enter the house 2x or more.


#105

added fixes (untested) for Wizard’s Arsenal quest and Remember/Restore Equipped Items functs.

a) Wizard’s Arsenal quest should not be assigned if PC has already entered Tarmas’ house.
b) Handle head-slot properly. Avoid TMI error in RestoreEquippedItems().


#106

done.


#107

Lol, dat jokers from OEI (see code comments).


#108

[dam they’re blocking links to Culture Club vids]


#109

Not from this end. I presume you meant the one with these colourful lyrics -

Karma, karma, karma, karma, karma chameleon
You come and go, you come and go
Loving would be easy if your colors were like my dreams
Red, gold, and green, red, gold, and green

TR


#110

excellent  :D

(is that a guy?)

ps. I tried to listen to a Cindi Lauper video also but then my brain melted.


#111

Boy George. More recently he’s been a judge on the UK version of The Voice.

But enough of this divergence. Back on topic. Looking good.

TR


#112

Fix for the AppendUniqueToNVP() function from ginc_param_const:

// Set a Name-Value pair in a list of Name-Value Pairs
string AppendUniqueToNVP(string sNVPList, string sName, string sValue, string sDelim="=")
{
	string sNameValuePair = sName + sDelim + sValue;

	// Remove old value if it exists.
	sName = RemoveNVP(sNVPList, sName);
	// append new value
	sNVPList = AppendToList(sNVPList, sNameValuePair);

	return (sNVPList);
}

Replace this

sName = RemoveNVP(sNVPList, sName);

with

sNVPList = RemoveNVP(sNVPList, sName);

This auxilary function is used inside the MarkItemAsDone() function from ginc_item_script. I doubt this error strongly affects anything.


#113

Does such construction make any sense? I see it very often in the OC scripts.

object oPC = GetOwnedCharacter(GetFactionLeader(GetFirstPC()));

Maybe it has something to do with the multiplayer game? Because GetIsOwnedByPlayer(GetFirstPC()) obviously returns TRUE in the SP game…


#114

yep it’s for MP

watch out for DM-objects, though; they might or might not be considered PCs by various functs.


#115

ginc_param_const (#include) fixes for Name-Value pairs

also, Feat.2da compatibility for Mysteries of Westgate by NinjaSpectre


#116

I think some functions from ginc_object (SpawnObjectsAtWPs(), DestroyAllWithTag() and GetNumberOfObjects()) need to fix.

Example:

// returns number destroyed
int DestroyAllWithTag(string sTag, int bThisAreaOnly=FALSE)
{
	int i = 0;
	object oObject = GetObjectByTag(sTag, i);
	object oThisArea = GetArea(OBJECT_SELF);

	while (GetIsObjectValid(oObject))
	{
		if (bThisAreaOnly && (GetArea(oObject) != oThisArea))
			break;

		DestroyObject(oObject);
		oObject = GetObjectByTag(sTag, ++i);
	}
	return (i);
}

Modified:

// returns number destroyed
int DestroyAllWithTag(string sTag, int bThisAreaOnly=FALSE)
{
	int i = 0;
	int iCount = 0;
	object oObject = GetObjectByTag(sTag, i);
	object oThisArea = GetArea(OBJECT_SELF);

	while (GetIsObjectValid(oObject))
	{
		if (bThisAreaOnly && (GetArea(oObject) != oThisArea))
		{
			oObject = GetObjectByTag(sTag, ++i);
			continue;
		}

		DestroyObject(oObject);
		iCount++;
		oObject = GetObjectByTag(sTag, ++i);
	}
	return (iCount);
}

Though it probably scans first the current area… so it’s ok then.


#117

Anyway, this function is definitely broken (leads to the infinite loop when the if condtion before the continue statement returns TRUE):

// spawns creature at each wp with specified tag
int SpawnObjectsAtWPs(int nObjectType, string sTemplate, string sWPTag, int bUseAppearAnimation = FALSE, string sNewTag="", int bThisAreaOnly=TRUE)
{
	int i = 0;
	object oTargetWP = GetObjectByTag(sWPTag, i);
	location lTargetWP;
	object oThisArea = GetArea(OBJECT_SELF);
	while (GetIsObjectValid(oTargetWP))
	{
		if (bThisAreaOnly && (GetArea(oTargetWP) != oThisArea))
			continue;

		lTargetWP = GetLocation(oTargetWP);
		CreateObject(nObjectType, sTemplate, lTargetWP, bUseAppearAnimation, sNewTag);
		i++;
		oTargetWP = GetObjectByTag(sWPTag,i);
	}
	//PrintString ("SpawnObjectsAtWPs: Created " + IntToString(i) + " of resref " + sTemplate);
	return(i);
}

#118

#119

Hello,

I found a texturing issue with the half-orc female cloth #10. The texture around the waist has overlapping faces, resulting in a flickering appearance. You can sort of see it in the image below, with the figures on the left:

fix

At the link below is a copy of the repaired version; I just reversed the normals on one layer of the waist mesh faces, then exported via the nwn2mdk tool. It seems to work okay in-game, as seen with the figures to the right.


#120

much appreciated (at least by female half-orc lovers  ;)


#121

Fixed bugs in the gc_check_race_pc script.

	//SETS OF SUBRACES
	else if (sRace == "civdwarves" || nRace == 41)
	{
		return (nRacialType == RACIAL_SUBTYPE_GOLD_DWARF ||
				nRacialType == RACIAL_SUBTYPE_SHIELD_DWARF);
	}
	else if (sRace == "civelves" || nRace == 42)
	{
		return (nRacialType == RACIAL_SUBTYPE_MOON_ELF ||
				nRacialType == RACIAL_SUBTYPE_SUN_ELF ||
				nRacialType == RACIAL_SUBTYPE_WOOD_ELF);
	}
	else if (sRace == "civhalflings" || nRace == 43)
	{
		return (nRacialType == RACIAL_SUBTYPE_LIGHTFOOT_HALF ||
				nRacialType == RACIAL_SUBTYPE_STRONGHEART_HALF);
	}
	else if (sRace == "civorcs" || nRace == 44)
	{
		return (nRacialType == RACIAL_SUBTYPE_HALFORC ||
				nRacialType == RACIAL_SUBTYPE_GRAYORC);
	}

The checks here were completely wrong.