Finished PRC8 integration. Moved creature abilities to top hak. Setup tooling. Created release archive
1050 lines
35 KiB
Plaintext
1050 lines
35 KiB
Plaintext
//:://////////////////////////////////////////////
|
|
//:: Completely redone Armor and Weapon redesign functions
|
|
//:: stx_inc_craft
|
|
//:://////////////////////////////////////////////
|
|
/*
|
|
This is a complete rework of the Armor- and Weaponcrafting skill
|
|
No existing scripts are overridden or replaced, only the conversation
|
|
x0_skill_ctrap needs to be replaced to activate the custom crafting.
|
|
|
|
Additions to the original Bioware scripts:
|
|
- Bugs fixed
|
|
- Enhanced performance
|
|
- Support for custom armor- and weaponmodels
|
|
- Built in color selection
|
|
- Use of crafting placeables (like Forge)
|
|
- Use of NPC crafters
|
|
- Reworked Cost and DC
|
|
- Helmet and Shield crafting added
|
|
- Counters the 'double item' exploit !
|
|
|
|
Uses the complete dyeset made by android79
|
|
- http://nwvault.ign.com/Files/prefabs/data/1070781839104.shtml
|
|
|
|
This crafting system has been made primairly for:
|
|
Xunder Burakan,
|
|
- http://xunder.vulcanusgames.net
|
|
- http://nwn.bioware.com/guilds_registry/viewguild.html?gid=3425
|
|
World of Palladium,
|
|
- http://palladium.vulcanusgames.net
|
|
- http://nwn.bioware.com/guilds_registry/viewguild.html?gid=6161
|
|
|
|
This scriptset has been posted on nwvault:
|
|
- http://nwvault.ign.com/Files/scripts/data/1071920548260.shtml
|
|
*/
|
|
//:://////////////////////////////////////////////
|
|
//:: Created By: SartriX
|
|
//:: Created On: 16-dec-2003
|
|
//:: Updated On: 01-jan-2004
|
|
//:://////////////////////////////////////////////
|
|
#include "prc_inc_racial"
|
|
#include "prc_x2_craft"
|
|
|
|
// Set to FALSE to disable the requirement of the proper placeable to be near the PC
|
|
const int STX_CR_REQUIRE_PLACEABLE = FALSE;
|
|
// Set to FALSE to disable the requirement and use of dyes when recolouring
|
|
const int STX_CR_REQUIRE_DYES = FALSE;
|
|
|
|
// Maximum cost in percent of the item's original valie at all times regardless of any other settings
|
|
const int STX_CR_MAXCOST = 90;
|
|
// Percentage of cost for each part of a weapon (3 parts max) or a helmet/shield (1 part max)
|
|
const int STX_CR_PARTCOST = 20;
|
|
// Added percentage of cost for dye changes by NPC
|
|
const int STX_CR_NPCDYECOST = 1;
|
|
// Percentage it costs to craft one self compared to what a NPC would ask for the same
|
|
// NPC cost is always 100% of the CraftCost in des_crft_aparts.2da
|
|
const int STX_CR_SELFCRAFT = 70;
|
|
// The DC that's added to craft magical items. This DC is added for each magical property it has
|
|
const int STX_CR_DCADD = 2;
|
|
|
|
// Tag of the backup container
|
|
// One is supplied as custom placeable (custom -> special -> custom5 -> stx_cr_backup)
|
|
// and should be placed on a preferrably inaccessible location. If the container can not be found,
|
|
// the backup item will be added to the PC's inventory, it won't break the entire script.
|
|
const string STX_CR_BACKUP_PLACEABLE = "stx_cr_backup";
|
|
|
|
// Tag of the required placeables
|
|
const string STX_CR_CLOTH_PLACEABLE = "stx_cr_loom";
|
|
const string STX_CR_LEATHER_PLACEABLE = "stx_cr_tanpool";
|
|
const string STX_CR_METAL_PLACEABLE = "stx_cr_forge";
|
|
const string STX_CR_WOOD_PLACEABLE = "stx_cr_fletchtable";
|
|
const float STX_CR_REQUIRED_DISTANCE = 4.0f;
|
|
|
|
const string STX_CR_SMITH_NPC = "stx_cr_smith";
|
|
const string STX_CR_TAILOR_NPC = "stx_cr_tailor";
|
|
|
|
|
|
// Internal constants, do not touch!
|
|
const int STX_CR_DONE_SUCCESS = 1;
|
|
const int STX_CR_DONE_FAILED = 2;
|
|
const int STX_CR_DONE_NOGOLD = 3;
|
|
const int STX_CR_DONE_NODYE = 4;
|
|
|
|
const int STX_CR_PART_NEXT = 0;
|
|
const int STX_CR_PART_PREV = 1;
|
|
const int STX_CR_COLOR_NEXT = 3;
|
|
const int STX_CR_COLOR_PREV = 4;
|
|
|
|
const int STX_CR_TOKENBASE = 20000;
|
|
|
|
const int STX_CR_HELMET = 8888;
|
|
const int STX_CR_SHIELD = 8889;
|
|
|
|
// - End of constants - //
|
|
|
|
|
|
// Sets up everything for oPC to start crafting on oItem
|
|
void StX_StartCraft(object oPC, object oItem);
|
|
|
|
// Tries to let oPC perform the crafting of his current item
|
|
// Will set the localvar STX_CR_DONE on success or fail with one
|
|
// of the following values to check with a conditional script:
|
|
// STX_CR_DONE_SUCCESS
|
|
// STX_CR_DONE_FAILED
|
|
// STX_CR_DONE_NOGOLD
|
|
// STX_CR_DONE_NODYE
|
|
void StX_AttemptCraft(object oPC);
|
|
|
|
// Stops crafting and cleans up everything set by the crafting script
|
|
// When nExecute is FALSE, it will abort the craft,
|
|
// when it's TRUE, it will replace the old item with the new one.
|
|
void StX_StopCraft(object oPC, int nExecute=FALSE);
|
|
|
|
// Sets the current part oPC is working on
|
|
// It accepts all 4 partseries ITEM_APPR_ARMOR_MODEL_*,
|
|
// ITEM_APPR_WEAPON_MODEL_*, ITEM_APPR_ARMOR_COLOR_*, ITEM_APPR_WEAPON_COLOR_*
|
|
// as long as the proper item has been set to craft on
|
|
// Focusses the camery on the selected part (if applicable)
|
|
void StX_SetPart(object oPC, int nPart, int nStrRef);
|
|
|
|
// Gets the cost to modify oItem into oNew
|
|
// Calls the default bioware routines for this, edit this function to override
|
|
int StX_GetModificationCost(object oItem, object oNew, int nNPC=FALSE);
|
|
|
|
// Gets the DC to modify oItem into oNew
|
|
// Calls the default bioware routines for this, edit this function to override
|
|
int StX_GetModificationDC(object oItem, object oNew, int nNPC=FALSE);
|
|
|
|
// Remakes and equips the item oPC is working, having the currently set part
|
|
// cycled either forward or backward
|
|
// nMode: STX_CR_PART_NEXT - cycle forward
|
|
// nMode: STX_CR_PART_PREV - cycle backward
|
|
void StX_RemakeItem(object oPC, int nMode);
|
|
|
|
// Remakes and equips the item oPC is working, having the currently set color
|
|
// cycled either forward or backward
|
|
// nMode: STX_CR_COLOR_NEXT - cycle forward
|
|
// nMode: STX_CR_COLOR_PREV - cycle backward
|
|
void StX_RecolorItem(object oPC, int nMode);
|
|
|
|
|
|
// - Implementation - //
|
|
|
|
|
|
// Sets up everything for oPC to start crafting on oItem
|
|
void StX_StartCraft(object oPC, object oItem) {
|
|
// Immobilize player while crafting
|
|
effect eImmob = EffectCutsceneImmobilize();
|
|
eImmob = ExtraordinaryEffect(eImmob);
|
|
ApplyEffectToObject(DURATION_TYPE_PERMANENT,eImmob,oPC);
|
|
|
|
// Make the camera float near the PC
|
|
StoreCameraFacing();
|
|
float fFacing = GetFacing(oPC) + 180.0;
|
|
if (fFacing >= 360.0) fFacing -=360.0;
|
|
SetCameraFacing(fFacing, 3.5f, 75.0, CAMERA_TRANSITION_TYPE_FAST);
|
|
|
|
// Make backup
|
|
object oBackup = CopyItem(oItem, GetObjectByTag(STX_CR_BACKUP_PLACEABLE), TRUE);
|
|
SetLocalObject(oPC, "STX_CR_BACKUP", oBackup);
|
|
|
|
// Mark temporary item
|
|
SetStolenFlag(oItem, TRUE);
|
|
SetLocalInt(oItem, "STX_CR_TEMPITEM", TRUE);
|
|
SetLocalObject(oPC, "STX_CR_ITEM", oItem);
|
|
|
|
// Preset settings
|
|
SetLocalInt(oPC, "STX_CR_STARTED", 1);
|
|
SetLocalInt(oPC, "STX_CR_COST", 0);
|
|
SetLocalInt(oPC, "STX_CR_DC", 0);
|
|
SetLocalInt(oPC, "STX_CR_DONE", 0);
|
|
SetLocalInt(oPC, "STX_CR_CHANGED", FALSE);
|
|
SetCustomToken(STX_CR_TOKENBASE, "");
|
|
SetCustomToken(STX_CR_TOKENBASE+1, "0");
|
|
SetCustomToken(STX_CR_TOKENBASE+2, "0");
|
|
SetCustomToken(STX_CR_TOKENBASE+3, "");
|
|
}
|
|
|
|
// - private -
|
|
// Checks if the color for nIndex has changed, if not returns TRUE
|
|
// if it has, checks if oPC has the new dye and returns TRUE when he has
|
|
// returns FALSE and sets CUSTOM20003 when the required dye is not present
|
|
int StX_ColorCheck(object oPC, object oItem, object oBackup, int nType, int nIndex) {
|
|
// if required dyes are disabled, always return TRUE
|
|
if (!STX_CR_REQUIRE_DYES) return TRUE;
|
|
|
|
// get new color
|
|
int nColor = GetItemAppearance(oItem, nType, nIndex);
|
|
string sDyeTag = "Dye";
|
|
|
|
if (nColor != GetItemAppearance(oBackup, nType, nIndex)) {
|
|
// color has changed, build the tag for the required dye
|
|
if (nType == ITEM_APPR_TYPE_ARMOR_COLOR) {
|
|
switch(nIndex) {
|
|
case ITEM_APPR_ARMOR_COLOR_CLOTH1:
|
|
case ITEM_APPR_ARMOR_COLOR_CLOTH2: sDyeTag+= "C"; break;
|
|
case ITEM_APPR_ARMOR_COLOR_LEATHER1:
|
|
case ITEM_APPR_ARMOR_COLOR_LEATHER2: sDyeTag+= "L"; break;
|
|
case ITEM_APPR_ARMOR_COLOR_METAL1:
|
|
case ITEM_APPR_ARMOR_COLOR_METAL2: sDyeTag+= "M";
|
|
if (nColor>55 && nColor<60) nColor-=4; break; // translate missing/double metal colors
|
|
}
|
|
if (nColor<10) sDyeTag+= "0";
|
|
sDyeTag+= IntToString(nColor);
|
|
} else {
|
|
switch (nColor) {
|
|
case 1: sDyeTag+= "M01"; break; // Steel
|
|
case 2: sDyeTag+= "M13"; break; // Gold
|
|
case 3: sDyeTag+= "M21"; break; // Copper
|
|
case 4: sDyeTag+= "M02"; break; // Dark Steel
|
|
}
|
|
}
|
|
if (GetIsObjectValid(GetItemPossessedBy(oPC, sDyeTag))) {
|
|
// oPC has the dye, so this color is alright
|
|
SetLocalString(oPC, "STX_CR_DYES", GetLocalString(oPC, "STX_CR_DYES") + sDyeTag + ":");
|
|
return TRUE;
|
|
} else {
|
|
// oPC does not have the dye, tell which dye is missing
|
|
if (GetName(GetObjectByTag(sDyeTag))=="") SpeakString("Missing dye/name: "+sDyeTag);
|
|
SetCustomToken(STX_CR_TOKENBASE+3, GetName(GetObjectByTag(sDyeTag)));
|
|
return FALSE;
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
// Tries to let oPC perform the crafting of his current item
|
|
// Will set the localvar STX_CR_DONE on success or fail with one
|
|
// of the following values to check with a conditional script:
|
|
// STX_CR_DONE_SUCCESS
|
|
// STX_CR_DONE_FAILED
|
|
// STX_CR_DONE_NOGOLD
|
|
// STX_CR_DONE_NODYE
|
|
void StX_AttemptCraft(object oPC)
|
|
{
|
|
// Palmer - fixed this so it is simply impossible to fail.
|
|
SetLocalInt(oPC, "STX_CR_DONE", STX_CR_DONE_SUCCESS);
|
|
// Destroy used dye
|
|
object oDye=GetLocalObject(oPC,"dye_con_obj");
|
|
DestroyObject(oDye);
|
|
DeleteLocalObject (oPC,"dye_con_obj");
|
|
}
|
|
|
|
// Stops crafting and cleans up everything set by the crafting script
|
|
// When nExecute is FALSE, it will abort the craft,
|
|
// when it's TRUE, it will replace the old item with the new one.
|
|
void StX_StopCraft(object oPC, int nExecute) {
|
|
// Get and equip correct item (backup when not successfull or cancelled)
|
|
object oItem = GetLocalObject(oPC, "STX_CR_ITEM");
|
|
object oBackup = GetLocalObject(oPC, "STX_CR_BACKUP");
|
|
if (nExecute) {
|
|
DestroyObject(oBackup);
|
|
SetStolenFlag(oItem, FALSE);
|
|
DeleteLocalInt(oItem, "STX_CR_TEMPITEM");
|
|
} else {
|
|
DestroyObject(oItem);
|
|
oItem = CopyItem(oBackup, oPC, TRUE);
|
|
DestroyObject(oBackup);
|
|
}
|
|
AssignCommand(oPC, ClearAllActions(TRUE));
|
|
if (GetBaseItemType(oItem)==BASE_ITEM_ARMOR) {
|
|
AssignCommand(oPC, ActionEquipItem(oItem, INVENTORY_SLOT_CHEST));
|
|
} else if (GetBaseItemType(oItem)==BASE_ITEM_HELMET) {
|
|
AssignCommand(oPC, ActionEquipItem(oItem, INVENTORY_SLOT_HEAD));
|
|
} else {
|
|
AssignCommand(oPC, ActionEquipItem(oItem, INVENTORY_SLOT_RIGHTHAND));
|
|
}
|
|
// PALMER - remove dupe ints
|
|
DeleteLocalInt(oItem, "jw_craft_copy");
|
|
DeleteLocalInt(oItem, "STX_CR_TEMPITEM");
|
|
// Postclean settings
|
|
DeleteLocalInt(oPC, "STX_CR_COST");
|
|
DeleteLocalInt(oPC, "STX_CR_DC");
|
|
DeleteLocalInt(oPC, "STX_CR_PART");
|
|
DeleteLocalInt(oPC, "STX_CR_DONE");
|
|
DeleteLocalInt(oPC, "STX_CR_CHANGED");
|
|
DeleteLocalObject(oPC, "STX_CR_ITEM");
|
|
DeleteLocalObject(oPC, "STX_CR_BACKUP");
|
|
DeleteLocalObject(oPC, "STX_CR_NPC");
|
|
|
|
// Remove custscene immobilize and light from player
|
|
effect eEff = GetFirstEffect(oPC);
|
|
while (GetIsEffectValid(eEff)) {
|
|
if (GetEffectType(eEff) == EFFECT_TYPE_CUTSCENEIMMOBILIZE)
|
|
RemoveEffect(oPC,eEff);
|
|
eEff = GetNextEffect(oPC);
|
|
}
|
|
RestoreCameraFacing();
|
|
}
|
|
|
|
// - private -
|
|
void StX_SetColorToken(int nIndex, int nColor) {
|
|
string sDyeTag = "Dye";
|
|
switch(nIndex) {
|
|
case ITEM_APPR_ARMOR_COLOR_CLOTH1:
|
|
case ITEM_APPR_ARMOR_COLOR_CLOTH2: sDyeTag+= "C"; break;
|
|
case ITEM_APPR_ARMOR_COLOR_LEATHER1:
|
|
case ITEM_APPR_ARMOR_COLOR_LEATHER2: sDyeTag+= "L"; break;
|
|
case ITEM_APPR_ARMOR_COLOR_METAL1:
|
|
case ITEM_APPR_ARMOR_COLOR_METAL2: sDyeTag+= "M";
|
|
if (nColor>55 && nColor<60) nColor-=4; break; // translate missing/double metal colors
|
|
}
|
|
if (nColor<10) sDyeTag+= "0";
|
|
sDyeTag+= IntToString(nColor);
|
|
SetCustomToken(STX_CR_TOKENBASE+3, GetName(GetObjectByTag(sDyeTag)));
|
|
}
|
|
|
|
// Sets the current part oPC is working on
|
|
// It accepts all 4 partseries ITEM_APPR_ARMOR_MODEL_*,
|
|
// ITEM_APPR_WEAPON_MODEL_*, ITEM_APPR_ARMOR_COLOR_*, ITEM_APPR_WEAPON_COLOR_*
|
|
// as long as the proper item has been set to craft on
|
|
// Focusses the camery on the selected part (if applicable)
|
|
void StX_SetPart(object oPC, int nPart, int nStrRef) {
|
|
SetLocalInt(oPC, "STX_CR_PART", nPart);
|
|
object oItem = GetLocalObject(oPC, "STX_CR_ITEM");
|
|
|
|
// * Make the camera float near the PC
|
|
float fFacing = GetFacing(oPC) + 180.0;
|
|
float fPitch = 75.0;
|
|
float fDistance= 3.5;
|
|
|
|
if (GetBaseItemType(oItem)==BASE_ITEM_ARMOR) {
|
|
switch (nPart) {
|
|
case ITEM_APPR_ARMOR_MODEL_LBICEP:
|
|
case ITEM_APPR_ARMOR_MODEL_LFOREARM:
|
|
case ITEM_APPR_ARMOR_MODEL_LHAND:
|
|
case ITEM_APPR_ARMOR_MODEL_LSHOULDER:
|
|
case ITEM_APPR_ARMOR_MODEL_LTHIGH:
|
|
case ITEM_APPR_ARMOR_MODEL_LSHIN:
|
|
case ITEM_APPR_ARMOR_MODEL_LFOOT: fFacing += 60.0; break;
|
|
case ITEM_APPR_ARMOR_MODEL_RBICEP:
|
|
case ITEM_APPR_ARMOR_MODEL_RFOREARM:
|
|
case ITEM_APPR_ARMOR_MODEL_RHAND:
|
|
case ITEM_APPR_ARMOR_MODEL_RSHOULDER:
|
|
case ITEM_APPR_ARMOR_MODEL_RTHIGH:
|
|
case ITEM_APPR_ARMOR_MODEL_RSHIN:
|
|
case ITEM_APPR_ARMOR_MODEL_RFOOT: fFacing -= 60.0; break;
|
|
}
|
|
switch (nPart) {
|
|
case ITEM_APPR_ARMOR_MODEL_LBICEP:
|
|
case ITEM_APPR_ARMOR_MODEL_RBICEP:
|
|
case ITEM_APPR_ARMOR_MODEL_LFOOT:
|
|
case ITEM_APPR_ARMOR_MODEL_RFOOT: fDistance = 3.5; fPitch = 47.0; break;
|
|
case ITEM_APPR_ARMOR_MODEL_LFOREARM:
|
|
case ITEM_APPR_ARMOR_MODEL_RFOREARM:
|
|
case ITEM_APPR_ARMOR_MODEL_LHAND:
|
|
case ITEM_APPR_ARMOR_MODEL_RHAND: fDistance = 2.0; fPitch = 60.0; break;
|
|
case ITEM_APPR_ARMOR_MODEL_LSHIN:
|
|
case ITEM_APPR_ARMOR_MODEL_RSHIN: fDistance = 3.5; fPitch = 95.0; break;
|
|
case ITEM_APPR_ARMOR_MODEL_LSHOULDER:
|
|
case ITEM_APPR_ARMOR_MODEL_RSHOULDER: fDistance = 3.0; fPitch = 50.0; break;
|
|
case ITEM_APPR_ARMOR_MODEL_LTHIGH:
|
|
case ITEM_APPR_ARMOR_MODEL_RTHIGH: fDistance = 2.5; fPitch = 65.0; break;
|
|
case ITEM_APPR_ARMOR_MODEL_NECK: fPitch = 90.0; break;
|
|
case ITEM_APPR_ARMOR_MODEL_BELT:
|
|
case ITEM_APPR_ARMOR_MODEL_PELVIS: fDistance = 2.0; break;
|
|
}
|
|
} else if (nPart==STX_CR_HELMET) {
|
|
fDistance = 2.5;
|
|
fPitch = 85.0;
|
|
} else if (nPart==STX_CR_SHIELD) {
|
|
fFacing += 60.0;
|
|
fDistance = 3.0;
|
|
fPitch = 65.0;
|
|
} else {
|
|
fFacing -= 60.0;
|
|
fDistance = 3.0;
|
|
fPitch = 65.0;
|
|
}
|
|
if (fFacing >= 360.0) fFacing -=360.0;
|
|
if (MyPRCGetRacialType(oPC) == RACIAL_TYPE_HALFORC) fDistance += 1.0f;
|
|
SetCameraFacing(fFacing, fDistance, fPitch, CAMERA_TRANSITION_TYPE_VERY_FAST);
|
|
|
|
int nCost = GetLocalInt(oPC, "STX_CR_COST");
|
|
int nDC = GetLocalInt(oPC, "STX_CR_DC");
|
|
SetCustomToken(STX_CR_TOKENBASE, GetStringByStrRef(nStrRef));
|
|
SetCustomToken(STX_CR_TOKENBASE+1, IntToString(nCost));
|
|
SetCustomToken(STX_CR_TOKENBASE+2, IntToString(nDC));
|
|
StX_SetColorToken(nPart, GetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, nPart));
|
|
|
|
}
|
|
|
|
// - private -
|
|
// Gets the cost to modify oItem into oNew
|
|
int StX_GetModificationCost(object oItem, object oNew, int nNPC=FALSE) {
|
|
int nCost = 0;
|
|
int nChanges = -1;
|
|
int nPart;
|
|
float fFactor;
|
|
|
|
// Find and count changes
|
|
if (GetBaseItemType(oItem)==BASE_ITEM_ARMOR) {
|
|
for (nPart = 0; nPart<=ITEM_APPR_ARMOR_MODEL_ROBE; nPart++) {
|
|
if (GetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_MODEL, nPart) != GetItemAppearance(oNew, ITEM_APPR_TYPE_ARMOR_MODEL, nPart)) {
|
|
// Part changed, add price factor
|
|
nCost += StringToInt(Get2DAString("des_crft_aparts", "CraftCost", nPart));
|
|
nChanges++;
|
|
}
|
|
}
|
|
} else {
|
|
for (nPart = 0; nPart<3; nPart++) {
|
|
if (GetItemAppearance(oItem, ITEM_APPR_TYPE_WEAPON_MODEL, nPart) != GetItemAppearance(oNew, ITEM_APPR_TYPE_WEAPON_MODEL, nPart)) {
|
|
// Part changed, add price factor
|
|
nCost += STX_CR_PARTCOST;
|
|
nChanges++;
|
|
}
|
|
}
|
|
nChanges *= 5;
|
|
}
|
|
// More as 1 part changed, give a 'discount'
|
|
if (nChanges>0) nCost -= nChanges;
|
|
// Reworked item may not cost more as 90% of a brand new one
|
|
if (nCost>STX_CR_MAXCOST) nCost = STX_CR_MAXCOST;
|
|
if (nNPC) {
|
|
// If made by a NPC, charge for the dyes
|
|
if (GetBaseItemType(oItem)==BASE_ITEM_ARMOR) {
|
|
for (nPart = 0; nPart<=ITEM_APPR_ARMOR_MODEL_ROBE; nPart++) {
|
|
if (GetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, nPart) != GetItemAppearance(oNew, ITEM_APPR_TYPE_ARMOR_COLOR, nPart)) {
|
|
// Part changed, add price factor
|
|
nCost += STX_CR_NPCDYECOST;
|
|
}
|
|
}
|
|
} else {
|
|
for (nPart = 0; nPart<3; nPart++) {
|
|
if (GetItemAppearance(oItem, ITEM_APPR_TYPE_WEAPON_COLOR, nPart) != GetItemAppearance(oNew, ITEM_APPR_TYPE_WEAPON_COLOR, nPart)) {
|
|
// Part changed, add price factor
|
|
nCost += STX_CR_NPCDYECOST;
|
|
}
|
|
}
|
|
}
|
|
fFactor = IntToFloat(nCost) / 100.0;
|
|
} else {
|
|
// If made by the PC himself, the price is 70% of what an NPC would ask him
|
|
fFactor = IntToFloat(nCost * STX_CR_SELFCRAFT) / 10000.0;
|
|
}
|
|
// Calculate and return final cost
|
|
nCost = FloatToInt(IntToFloat(GetGoldPieceValue(oItem)) * fFactor);
|
|
if (nCost<1) nCost=1;
|
|
return nCost;
|
|
}
|
|
|
|
// - private -
|
|
// Gets the DC to modify oItem into oNew
|
|
int StX_GetModificationDC(object oItem, object oNew, int nNPC=FALSE) {
|
|
if (nNPC) return 0;
|
|
int nDC;
|
|
int nChanges = -1;
|
|
int nPart;
|
|
float fFactor;
|
|
|
|
// Find and count changes
|
|
if (GetBaseItemType(oItem)==BASE_ITEM_ARMOR) {
|
|
for (nPart = 0; nPart<=ITEM_APPR_ARMOR_MODEL_ROBE; nPart++) {
|
|
if (GetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_MODEL, nPart) != GetItemAppearance(oNew, ITEM_APPR_TYPE_ARMOR_MODEL, nPart)) {
|
|
// Part changed, add DC factor
|
|
nDC += StringToInt(Get2DAString("des_crft_aparts", "CraftDC", nPart));
|
|
nChanges++;
|
|
}
|
|
}
|
|
} else {
|
|
for (nPart = 0; nPart<3; nPart++) {
|
|
if (GetItemAppearance(oItem, ITEM_APPR_TYPE_WEAPON_MODEL, nPart) != GetItemAppearance(oNew, ITEM_APPR_TYPE_WEAPON_MODEL, nPart)) {
|
|
// Part changed, add DC factor
|
|
nDC += 6;
|
|
nChanges++;
|
|
}
|
|
}
|
|
nChanges *= 2;
|
|
}
|
|
// More as 1 part changed, give a 'discount'
|
|
if (nChanges>0) nDC -= nChanges;
|
|
itemproperty iP = GetFirstItemProperty(oItem);
|
|
while (GetIsItemPropertyValid(iP)) {
|
|
nDC += STX_CR_DCADD;
|
|
iP = GetNextItemProperty(oItem);
|
|
}
|
|
return nDC;
|
|
}
|
|
|
|
// - private -
|
|
// Reverses a : seperated stringlist
|
|
string StX_ListReverse(string s) {
|
|
string sCache;
|
|
int n;
|
|
int l = GetStringLength(s);
|
|
s = GetSubString(s, 1, l);
|
|
while (s!="") {
|
|
// take string upto next seperator and put this in front of cache
|
|
n = FindSubString(s, ":")+1;
|
|
sCache = GetStringLeft(s, n) + sCache;
|
|
s = GetSubString(s, n, l);
|
|
}
|
|
return ":"+sCache;
|
|
}
|
|
|
|
// - private -
|
|
// Prereads the parts_chest.2da-file for sAC and puts all used ID's in a : seperated stringlist
|
|
string StX_PreReadArmorACList(string sAC) {
|
|
// pick the right 2da to read the parts from
|
|
string s2DA = "parts_chest";
|
|
string sCache= ":";
|
|
string sLine;
|
|
// get the maxID used (not the amount of ID's !!!)
|
|
int nMax = IPGetNumberOfArmorAppearances(ITEM_APPR_ARMOR_MODEL_TORSO);
|
|
int n=1;
|
|
while (n<=nMax) {
|
|
// Verify validity of the ID and add to the list
|
|
sLine = Get2DAString(s2DA, "ACBONUS", n);
|
|
if (sLine==sAC) {
|
|
sCache+= IntToString(n)+":";
|
|
}
|
|
n++;
|
|
}
|
|
// Store the list in a modulestring, once normal, once reversed, both with ID 0 added as first index for cycling
|
|
SetLocalString(GetModule(), "StX_IDPreReadAC_"+GetStringLeft(sAC,1), sCache);
|
|
SetLocalString(GetModule(), "StX_IDPreReadACR_"+GetStringLeft(sAC,1), StX_ListReverse(sCache));
|
|
// SpeakString("PreRead: "+sAC+" - "+sCache);
|
|
return sCache;
|
|
}
|
|
|
|
// - private -
|
|
// Prereads the 2da-file for nPart and puts all used ID's in a : seperated stringlist
|
|
string StX_PreReadArmorPartList(int nPart) {
|
|
// pick the right 2da to read the parts from
|
|
string s2DA = "parts_";
|
|
switch (nPart) {
|
|
case ITEM_APPR_ARMOR_MODEL_LBICEP:
|
|
case ITEM_APPR_ARMOR_MODEL_RBICEP: s2DA+= "bicep"; break;
|
|
case ITEM_APPR_ARMOR_MODEL_LFOOT:
|
|
case ITEM_APPR_ARMOR_MODEL_RFOOT: s2DA+= "foot"; break;
|
|
case ITEM_APPR_ARMOR_MODEL_LFOREARM:
|
|
case ITEM_APPR_ARMOR_MODEL_RFOREARM: s2DA+= "forearm"; break;
|
|
case ITEM_APPR_ARMOR_MODEL_LHAND:
|
|
case ITEM_APPR_ARMOR_MODEL_RHAND: s2DA+= "hand"; break;
|
|
case ITEM_APPR_ARMOR_MODEL_LSHIN:
|
|
case ITEM_APPR_ARMOR_MODEL_RSHIN: s2DA+= "shin"; break;
|
|
case ITEM_APPR_ARMOR_MODEL_LSHOULDER:
|
|
case ITEM_APPR_ARMOR_MODEL_RSHOULDER: s2DA+= "shoulder"; break;
|
|
case ITEM_APPR_ARMOR_MODEL_LTHIGH:
|
|
case ITEM_APPR_ARMOR_MODEL_RTHIGH: s2DA+= "belt"; break;
|
|
case ITEM_APPR_ARMOR_MODEL_NECK: s2DA+= "neck"; break;
|
|
case ITEM_APPR_ARMOR_MODEL_BELT: s2DA+= "belt"; break;
|
|
case ITEM_APPR_ARMOR_MODEL_PELVIS: s2DA+= "pelvis"; break;
|
|
case ITEM_APPR_ARMOR_MODEL_ROBE: s2DA+= "robe"; break;
|
|
}
|
|
|
|
string sCache= ":";
|
|
string sLine;
|
|
// get the maxID used (not the amount of ID's !!!)
|
|
int nMax = StringToInt(Get2DAString("des_crft_aparts", "NumParts", nPart));
|
|
int n=1;
|
|
while (n<=nMax) {
|
|
// Verify validity of the ID and add to the list
|
|
sLine = Get2DAString(s2DA, "ACBONUS", n);
|
|
if (sLine!="") {
|
|
sCache+= IntToString(n)+":";
|
|
}
|
|
n++;
|
|
}
|
|
// Store the list in a modulestring, once normal, once reversed, both with ID 0 added as first index for cycling
|
|
SetLocalString(GetModule(), "StX_IDPreRead_"+IntToString(nPart), ":0"+sCache);
|
|
SetLocalString(GetModule(), "StX_IDPreReadR_"+IntToString(nPart), ":0"+StX_ListReverse(sCache));
|
|
// SpeakString("PreRead: "+IntToString(nPart)+s2DA+" - "+sCache);
|
|
return sCache;
|
|
}
|
|
|
|
// Remakes and equips the item oPC is working, having the currently set part
|
|
// cycled either forward or backward
|
|
// nMode: STX_CR_PART_NEXT - cycle forward
|
|
// nMode: STX_CR_PART_PREV - cycle backward
|
|
void StX_RemakeItem(object oPC, int nMode) {
|
|
SetLocalInt(oPC, "STX_CR_CHANGED", TRUE);
|
|
object oItem = GetLocalObject(oPC, "STX_CR_ITEM");
|
|
int nPart = GetLocalInt(oPC, "STX_CR_PART");
|
|
int nCurrApp, nSlot, nCost, nDC;
|
|
string sPreRead;
|
|
object oNew;
|
|
|
|
if (GetBaseItemType(oItem)==BASE_ITEM_ARMOR) {
|
|
// Handle Armor change
|
|
nCurrApp = GetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_MODEL, nPart);
|
|
|
|
if (nPart == ITEM_APPR_ARMOR_MODEL_TORSO) {
|
|
string sAC = Get2DAString("parts_chest", "ACBONUS", nCurrApp);
|
|
// Fetch the stringlist that holds the ID's for this part
|
|
sPreRead = GetLocalString(GetModule(), "StX_IDPreReadAC_"+GetStringLeft(sAC,1));
|
|
if (sPreRead=="") // list didn't exist yet, so generate it
|
|
sPreRead = StX_PreReadArmorACList(sAC);
|
|
if (nMode==STX_CR_PART_PREV)
|
|
sPreRead = GetLocalString(GetModule(), "StX_IDPreReadACR_"+GetStringLeft(sAC,1));
|
|
} else {
|
|
// Fetch the stringlist that holds the ID's for this part
|
|
sPreRead = GetLocalString(GetModule(), "StX_IDPreRead_"+IntToString(nPart));
|
|
if (sPreRead=="") // list didn't exist yet, so generate it
|
|
sPreRead = StX_PreReadArmorPartList(nPart);
|
|
if (nMode==STX_CR_PART_PREV) sPreRead = GetLocalString(GetModule(), "StX_IDPreReadR_"+IntToString(nPart));
|
|
}
|
|
|
|
// Find the current ID in the stringlist and pick the one coming after that
|
|
string sID;
|
|
string sCurrApp = IntToString(nCurrApp);
|
|
int n = FindSubString(sPreRead, ":"+sCurrApp+":");
|
|
sID = GetSubString(sPreRead, n+GetStringLength(sCurrApp)+2, 5);
|
|
n = FindSubString(sID, ":");
|
|
sID = GetStringLeft(sID, n);
|
|
if (sID=="" && nPart == ITEM_APPR_ARMOR_MODEL_TORSO) {
|
|
sID = GetSubString(sPreRead, 1, 5);
|
|
n = FindSubString(sID, ":");
|
|
sID = GetStringLeft(sID, n);
|
|
}
|
|
// SpeakString("Old: "+IntToString(nCurrApp)+", New: "+sID);
|
|
nCurrApp = StringToInt(sID);
|
|
|
|
oNew = CopyItemAndModify(oItem, ITEM_APPR_TYPE_ARMOR_MODEL, nPart, nCurrApp, TRUE);
|
|
nSlot = INVENTORY_SLOT_CHEST;
|
|
|
|
} else if (nPart == STX_CR_HELMET) {
|
|
// Handle Helmet change
|
|
nCurrApp = GetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_MODEL, 0);
|
|
int nMin = 1;
|
|
int nMax = StringToInt(Get2DAString("baseitems", "MaxRange", BASE_ITEM_HELMET));
|
|
|
|
if (nMode == STX_CR_PART_NEXT) {
|
|
if (++nCurrApp>nMax) nCurrApp = nMin;
|
|
} else {
|
|
if (--nCurrApp<nMin) nCurrApp = nMax;
|
|
}
|
|
// SpeakString("New: "+IntToString(nCurrApp));
|
|
|
|
oNew = CopyItemAndModify(oItem, ITEM_APPR_TYPE_ARMOR_MODEL, 0, nCurrApp, TRUE);
|
|
nSlot = INVENTORY_SLOT_HEAD;
|
|
|
|
} else if (nPart == STX_CR_SHIELD) {
|
|
// Handle Shield change
|
|
nCurrApp = GetItemAppearance(oItem, ITEM_APPR_TYPE_SIMPLE_MODEL, 0);
|
|
int nBaseType = GetBaseItemType(oItem);
|
|
int nMod = (nCurrApp/10)*10;
|
|
nCurrApp-= nMod;
|
|
int nMin = StringToInt(Get2DAString("baseitems", "MinRange", nBaseType));
|
|
int nMax = (StringToInt(Get2DAString("baseitems", "MaxRange", nBaseType)) /10)*10;
|
|
|
|
if (nMode == STX_CR_PART_NEXT) {
|
|
nMod+=10;
|
|
if (nMod>nMax) nMod = nMin;
|
|
} else {
|
|
nMod-=10;
|
|
if (nMod<nMin) nMod = nMax;
|
|
}
|
|
nCurrApp += nMod;
|
|
// SpeakString("New: "+IntToString(nCurrApp));
|
|
|
|
oNew = CopyItemAndModify(oItem, ITEM_APPR_TYPE_SIMPLE_MODEL, 0, nCurrApp, TRUE);
|
|
nSlot = INVENTORY_SLOT_LEFTHAND;
|
|
|
|
} else {
|
|
// Handle Weapon change
|
|
nCurrApp = GetItemAppearance(oItem, ITEM_APPR_TYPE_WEAPON_MODEL, nPart);
|
|
int nBaseType = GetBaseItemType(oItem);
|
|
int nMin = StringToInt(Get2DAString("baseitems", "MinRange", nBaseType)) /10;
|
|
int nMax = StringToInt(Get2DAString("baseitems", "MaxRange", nBaseType)) /10;
|
|
|
|
if (nMode == STX_CR_PART_NEXT) {
|
|
if (++nCurrApp>nMax) nCurrApp = nMin;
|
|
} else {
|
|
if (--nCurrApp<nMin) nCurrApp = nMax;
|
|
}
|
|
// SpeakString("New: "+IntToString(nCurrApp));
|
|
|
|
oNew = CopyItemAndModify(oItem, ITEM_APPR_TYPE_WEAPON_MODEL, nPart, nCurrApp, TRUE);
|
|
nSlot = INVENTORY_SLOT_RIGHTHAND;
|
|
}
|
|
|
|
if (GetIsObjectValid(oNew)) {
|
|
// new object is valid
|
|
// get cost and DC
|
|
int nNPC = GetIsObjectValid(GetLocalObject(oPC, "STX_CR_NPC"));
|
|
object oBackup = GetLocalObject(oPC, "STX_CR_BACKUP");
|
|
nCost = StX_GetModificationCost(oBackup, oNew, nNPC);
|
|
nDC = StX_GetModificationDC(oBackup, oNew, nNPC);
|
|
SetLocalInt(oPC, "STX_CR_COST", nCost);
|
|
SetLocalInt(oPC, "STX_CR_DC", nDC);
|
|
SetCustomToken(STX_CR_TOKENBASE+1, IntToString(nCost));
|
|
SetCustomToken(STX_CR_TOKENBASE+2, IntToString(nDC));
|
|
|
|
// replace old current object with new one
|
|
DestroyObject(oItem);
|
|
oItem = oNew;
|
|
SetLocalObject(oPC, "STX_CR_ITEM", oItem);
|
|
AssignCommand(oPC, ClearAllActions(TRUE));
|
|
AssignCommand(oPC, ActionEquipItem(oItem, nSlot));
|
|
}
|
|
}
|
|
|
|
// Remakes and equips the item oPC is working, having the currently set color
|
|
// cycled either forward or backward
|
|
// nMode: STX_CR_COLOR_NEXT - cycle forward
|
|
// nMode: STX_CR_COLOR_PREV - cycle backward
|
|
void StX_RecolorItem(object oPC, int nMode) {
|
|
SetLocalInt(oPC, "STX_CR_CHANGED", TRUE);
|
|
object oItem = GetLocalObject(oPC, "STX_CR_ITEM");
|
|
int nPart = GetLocalInt(oPC, "STX_CR_PART");
|
|
int nCurrApp, nSlot, nCost, nDC;
|
|
object oNew;
|
|
|
|
|
|
if (GetBaseItemType(oItem)==BASE_ITEM_ARMOR || GetBaseItemType(oItem)==BASE_ITEM_HELMET) {
|
|
// Handle Armor change
|
|
nCurrApp = GetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, nPart);
|
|
int nMin = 0;
|
|
int nMax = 63;
|
|
|
|
if (nMode == STX_CR_COLOR_NEXT) {
|
|
if (++nCurrApp>nMax) nCurrApp = nMin;
|
|
} else {
|
|
if (--nCurrApp<nMin) nCurrApp = nMax;
|
|
}
|
|
|
|
// Palmer - banned colours
|
|
/// do Cloth and leather first
|
|
if (nPart==ITEM_APPR_ARMOR_COLOR_CLOTH1||nPart==ITEM_APPR_ARMOR_COLOR_CLOTH2||nPart==ITEM_APPR_ARMOR_COLOR_LEATHER1||nPart==ITEM_APPR_ARMOR_COLOR_LEATHER2)
|
|
{
|
|
|
|
if (nCurrApp==16)
|
|
{
|
|
if (nMode == STX_CR_COLOR_NEXT)
|
|
{
|
|
nCurrApp=17;
|
|
}
|
|
else
|
|
{
|
|
nCurrApp=15;
|
|
}
|
|
}
|
|
|
|
|
|
else
|
|
if (nCurrApp==26||nCurrApp==27||nCurrApp==28||nCurrApp==29||nCurrApp==30||nCurrApp==31)
|
|
{
|
|
if (nMode == STX_CR_COLOR_NEXT)
|
|
{
|
|
nCurrApp=32;
|
|
}
|
|
else
|
|
{
|
|
nCurrApp=25;
|
|
}
|
|
|
|
}
|
|
else
|
|
if (nCurrApp==40)
|
|
{
|
|
if (nMode == STX_CR_COLOR_NEXT)
|
|
{
|
|
nCurrApp=41;
|
|
}
|
|
else
|
|
{
|
|
nCurrApp=39;
|
|
}
|
|
|
|
}
|
|
else
|
|
if (nCurrApp==46||nCurrApp==47||nCurrApp==48||nCurrApp==49||nCurrApp==50||nCurrApp==51||nCurrApp==52||nCurrApp==53||nCurrApp==54||nCurrApp==55||nCurrApp==56||nCurrApp==57||nCurrApp==58||nCurrApp==59)
|
|
{
|
|
if (nMode == STX_CR_COLOR_NEXT)
|
|
{
|
|
nCurrApp=60;
|
|
}
|
|
else
|
|
{
|
|
nCurrApp=45;
|
|
}
|
|
|
|
}
|
|
else
|
|
if (nCurrApp==61||nCurrApp==62||nCurrApp==63)
|
|
{
|
|
if (nMode == STX_CR_COLOR_NEXT)
|
|
{
|
|
nCurrApp=0;
|
|
}
|
|
else
|
|
{
|
|
nCurrApp=60;
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
/// now do the metals
|
|
else
|
|
{
|
|
if (nCurrApp==0)
|
|
{
|
|
if (nMode == STX_CR_COLOR_NEXT)
|
|
{
|
|
nCurrApp=1;
|
|
}
|
|
else
|
|
{
|
|
nCurrApp=60;
|
|
}
|
|
|
|
}
|
|
else
|
|
if (nCurrApp==8||nCurrApp==9)
|
|
{
|
|
if (nMode == STX_CR_COLOR_NEXT)
|
|
{
|
|
nCurrApp=10;
|
|
}
|
|
else
|
|
{
|
|
nCurrApp=7;
|
|
}
|
|
|
|
}
|
|
else
|
|
if (nCurrApp==12)
|
|
{
|
|
if (nMode == STX_CR_COLOR_NEXT)
|
|
{
|
|
nCurrApp=13;
|
|
}
|
|
else
|
|
{
|
|
nCurrApp=11;
|
|
}
|
|
|
|
}
|
|
else
|
|
if (nCurrApp==16)
|
|
{
|
|
if (nMode == STX_CR_COLOR_NEXT)
|
|
{
|
|
nCurrApp=17;
|
|
}
|
|
else
|
|
{
|
|
nCurrApp=15;
|
|
}
|
|
|
|
}
|
|
else
|
|
if (nCurrApp==20)
|
|
{
|
|
if (nMode == STX_CR_COLOR_NEXT)
|
|
{
|
|
nCurrApp=21;
|
|
}
|
|
else
|
|
{
|
|
nCurrApp=19;
|
|
}
|
|
|
|
}
|
|
else
|
|
if (nCurrApp==24)
|
|
{
|
|
if (nMode == STX_CR_COLOR_NEXT)
|
|
{
|
|
nCurrApp=25;
|
|
}
|
|
else
|
|
{
|
|
nCurrApp=23;
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
if (nCurrApp==26)
|
|
{
|
|
if (nMode == STX_CR_COLOR_NEXT)
|
|
{
|
|
nCurrApp=27;
|
|
}
|
|
else
|
|
{
|
|
nCurrApp=25;
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
if (nCurrApp==28)
|
|
{
|
|
if (nMode == STX_CR_COLOR_NEXT)
|
|
{
|
|
nCurrApp=29;
|
|
}
|
|
else
|
|
{
|
|
nCurrApp=27;
|
|
}
|
|
|
|
}
|
|
else
|
|
if (nCurrApp==30)
|
|
{
|
|
if (nMode == STX_CR_COLOR_NEXT)
|
|
{
|
|
nCurrApp=31;
|
|
}
|
|
else
|
|
{
|
|
nCurrApp=29;
|
|
}
|
|
|
|
}
|
|
else
|
|
if (nCurrApp==32)
|
|
{
|
|
if (nMode == STX_CR_COLOR_NEXT)
|
|
{
|
|
nCurrApp=33;
|
|
}
|
|
else
|
|
{
|
|
nCurrApp=31;
|
|
}
|
|
|
|
}
|
|
else
|
|
if (nCurrApp==34)
|
|
{
|
|
if (nMode == STX_CR_COLOR_NEXT)
|
|
{
|
|
nCurrApp=35;
|
|
}
|
|
else
|
|
{
|
|
nCurrApp=33;
|
|
}
|
|
|
|
}
|
|
else
|
|
if (nCurrApp==36||nCurrApp==37||nCurrApp==38)
|
|
{
|
|
if (nMode == STX_CR_COLOR_NEXT)
|
|
{
|
|
nCurrApp=39;
|
|
}
|
|
else
|
|
{
|
|
nCurrApp=35;
|
|
}
|
|
|
|
}
|
|
else
|
|
if (nCurrApp==40||nCurrApp==41||nCurrApp==42)
|
|
{
|
|
if (nMode == STX_CR_COLOR_NEXT)
|
|
{
|
|
nCurrApp=43;
|
|
}
|
|
else
|
|
{
|
|
nCurrApp=39;
|
|
}
|
|
|
|
}
|
|
else
|
|
if (nCurrApp==44||nCurrApp==45||nCurrApp==46)
|
|
{
|
|
if (nMode == STX_CR_COLOR_NEXT)
|
|
{
|
|
nCurrApp=47;
|
|
}
|
|
else
|
|
{
|
|
nCurrApp=43;
|
|
}
|
|
|
|
}
|
|
else
|
|
if (nCurrApp==48)
|
|
{
|
|
if (nMode == STX_CR_COLOR_NEXT)
|
|
{
|
|
nCurrApp=49;
|
|
}
|
|
else
|
|
{
|
|
nCurrApp=47;
|
|
}
|
|
|
|
}
|
|
else
|
|
if (nCurrApp==58)
|
|
{
|
|
if (nMode == STX_CR_COLOR_NEXT)
|
|
{
|
|
nCurrApp=59;
|
|
}
|
|
else
|
|
{
|
|
nCurrApp=57;
|
|
}
|
|
|
|
}
|
|
else
|
|
if (nCurrApp==61||nCurrApp==62||nCurrApp==63)
|
|
{
|
|
if (nMode == STX_CR_COLOR_NEXT)
|
|
{
|
|
nCurrApp=0;
|
|
}
|
|
else
|
|
{
|
|
nCurrApp=59;
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// SpeakString("New: "+IntToString(nCurrApp));
|
|
|
|
StX_SetColorToken(nPart, nCurrApp);
|
|
oNew = CopyItemAndModify(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, nPart, nCurrApp, TRUE);
|
|
nSlot = INVENTORY_SLOT_CHEST;
|
|
if (GetBaseItemType(oItem)==BASE_ITEM_HELMET)
|
|
nSlot = INVENTORY_SLOT_HEAD;
|
|
|
|
}
|
|
|
|
if (GetIsObjectValid(oNew)) {
|
|
// new object is valid
|
|
// get cost and DC
|
|
int nNPC = GetIsObjectValid(GetLocalObject(oPC, "STX_CR_NPC"));
|
|
object oBackup = GetLocalObject(oPC, "STX_CR_BACKUP");
|
|
nCost = StX_GetModificationCost(oBackup, oNew, nNPC);
|
|
nDC = StX_GetModificationDC(oBackup, oNew, nNPC);
|
|
SetLocalInt(oPC, "STX_CR_COST", nCost);
|
|
SetLocalInt(oPC, "STX_CR_DC", nDC);
|
|
SetCustomToken(STX_CR_TOKENBASE+1, IntToString(nCost));
|
|
SetCustomToken(STX_CR_TOKENBASE+2, IntToString(nDC));
|
|
// PALMER - put local int on the item
|
|
SetLocalInt(oNew,"jw_craft_copy",TRUE);
|
|
|
|
// replace old current object with new one
|
|
DestroyObject(oItem);
|
|
oItem = oNew;
|
|
SetLocalObject(oPC, "STX_CR_ITEM", oItem);
|
|
AssignCommand(oPC, ClearAllActions(TRUE));
|
|
AssignCommand(oPC, ActionEquipItem(oItem, nSlot));
|
|
}
|
|
}
|
|
|