Battledale_PRC8/_module/nss/stx_inc_craft.nss
Jaysyn904 e5b3f6ad61 Finished PRC8 integration
Finished PRC8 integration.  Moved creature abilities to top hak.  Setup tooling.  Created release archive
2024-03-12 21:27:23 -04:00

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));
}
}