PRC8/nwn/nwnprc/trunk/include/prc_inc_skin.nss
Jaysyn904 6ec137a24e Updated AMS marker feats
Updated AMS marker feats.  Removed arcane & divine marker feats.  Updated Dread Necromancer for epic progression. Updated weapon baseitem models.  Updated new weapons for crafting & npc equip.
 Updated prefix.  Updated release archive.
2024-02-11 14:01:05 -05:00

140 lines
5.4 KiB
Plaintext

//::///////////////////////////////////////////////
//:: skin include
//:: prc_inc_skin
//::///////////////////////////////////////////////
/** @file
This include contains GetPCSkin(). If only using
this function please include this directly and not via
the entire spell engine :p
Is included by inc_persist_loca for persistent
local variables
*/
//:://////////////////////////////////////////////
//:: Created By: fluffyamoeba
//:: Created On: 2008-4-23
//:://////////////////////////////////////////////
//////////////////////////////////////////////////
/* Function prototypes */
//////////////////////////////////////////////////
/**
* Sets up the pcskin object on oPC.
* If it already exists, simply return it. Otherwise, create and equip it.
*
* @param oPC The creature whose skin object to look for.
* @return Either the skin found or the skin created.
*/
object GetPCSkin(object oPC);
//////////////////////////////////////////////////
/* Includes */
//////////////////////////////////////////////////
#include "inc_debug"
//////////////////////////////////////////////////
/* private functions */
//////////////////////////////////////////////////
// to duplicate ForceEquip() from inc_utility
void _ForceEquipSkin(object oPC, object oSkin, int nThCall = 0)
{
// Make sure that the object we are attempting equipping is the latest one to be ForceEquipped into this slot
if(GetIsObjectValid(GetLocalObject(oPC, "ForceEquipToSlot_17"))
&& GetLocalObject(oPC, "ForceEquipToSlot_17") != oSkin)
return;
// Fail on non-commandable NPCs after ~1min
if(!GetIsPC(oPC) && !GetCommandable(oPC) && nThCall > 60)
{
WriteTimestampedLogEntry("ForceEquip() failed on non-commandable NPC: " + DebugObject2Str(oPC) + " for item: " + DebugObject2Str(oSkin));
return;
}
float fDelay;
// Check if the equipping has already happened
if(GetItemInSlot(INVENTORY_SLOT_CARMOUR, oPC) != oSkin)
{
// Test and increment the control counter
if(nThCall++ == 0)
{
// First, try to do the equipping non-intrusively and give the target a reasonable amount of time to do it
AssignCommand(oPC, ActionEquipItem(oSkin, INVENTORY_SLOT_CARMOUR));
fDelay = 1.0f;
// Store the item to be equipped in a local variable to prevent contest between two different calls to ForceEquip
SetLocalObject(oPC, "ForceEquipToSlot_17", oSkin);
}
else
{
// Nuke the target's action queue. This should result in "immediate" equipping of the item
if(GetIsPC(oPC) || nThCall > 5) // Skip nuking NPC action queue at first, since that can cause problems. 5 = magic number here. May need adjustment
{
if(!GetIsObjectValid(oSkin))
{
oSkin = GetPCSkin(oPC);
return;
}
else
{
AssignCommand(oPC, ClearAllActions());
AssignCommand(oPC, ActionEquipItem(oSkin, INVENTORY_SLOT_CARMOUR));
}
}
// Use a lenghtening delay in order to attempt handling lag and possible other interference. From 0.1s to 1s
fDelay = (nThCall < 10 ? nThCall : 10) / 10.0f; // yes this is the same as min(nThCall, 10)
}
// Loop
DelayCommand(fDelay, _ForceEquipSkin(oPC, oSkin, nThCall));
}
// It has, so clean up
else
DeleteLocalObject(oPC, "ForceEquipToSlot_17");
}
//////////////////////////////////////////////////
/* Function defintions */
//////////////////////////////////////////////////
object GetPCSkin(object oPC)
{
// According to a bug report, this is being called on non-creature objects. This should catch the culprit
if(DEBUG) Assert(GetObjectType(oPC) == OBJECT_TYPE_CREATURE, "GetObjectType(oPC) == OBJECT_TYPE_CREATURE", "GetPRCSkin() called on non-creature object: " + DebugObject2Str(oPC), "prc_inc_skin", "object GetPCSkin(object oPC)");
object oSkin = GetItemInSlot(INVENTORY_SLOT_CARMOUR, oPC);
if(!GetIsObjectValid(oSkin))
{
//oSkin = GetLocalObject(oPC, "PRCSkinCache");
//if(!GetIsObjectValid(oSkin))
{
//Added this check to prevent creation of extra skins on module entry
oSkin = GetItemPossessedBy(oPC, "base_prc_skin");
if(GetIsObjectValid(oSkin))
{
_ForceEquipSkin(oPC, oSkin, INVENTORY_SLOT_CARMOUR);
//AssignCommand(oPC, ActionEquipItem(oSkin, INVENTORY_SLOT_CARMOUR));
}
else
{
oSkin = CreateItemOnObject("base_prc_skin", oPC);
_ForceEquipSkin(oPC, oSkin, INVENTORY_SLOT_CARMOUR);
//AssignCommand(oPC, ActionEquipItem(oSkin, INVENTORY_SLOT_CARMOUR));
// The skin should not be droppable
SetDroppableFlag(oSkin, FALSE);
// other scripts should not be able to destroy the skin
AssignCommand(oSkin, SetIsDestroyable(FALSE));
}
// Cache the skin reference for further lookups during the same script
//SetLocalObject(oPC, "PRCSkinCache", oSkin);
//DelayCommand(0.0f, DeleteLocalObject(oPC, "PRCSkinCache"));
}
}
return oSkin;
}