352 lines
15 KiB
Plaintext
352 lines
15 KiB
Plaintext
/****************************************************
|
|
Begin Crafting Script
|
|
ats_inc_cr_begin
|
|
|
|
Last Updated: August 25, 2002
|
|
|
|
***Ambrosia Tradeskill System***
|
|
Created by Mojo(Allen Sun)
|
|
|
|
This script contains the bulk of the crafting
|
|
system. It is responsible for doing skill checks
|
|
and producing the appropriate results.
|
|
|
|
*****************************************************/
|
|
#include "ats_inc_menustub"
|
|
#include "ats_inc_math"
|
|
#include "ats_inc_tool"
|
|
#include "ats_inc_stats"
|
|
|
|
|
|
|
|
void PlayCraftingAnimation(string sTradeskillName)
|
|
{
|
|
object oPlayer = GetPCSpeaker();
|
|
if(sTradeskillName == CSTR_SKILLNAME_ARMORCRAFTING ||
|
|
sTradeskillName == CSTR_SKILLNAME_WEAPONCRAFTING)
|
|
{
|
|
ActionPauseConversation();
|
|
AssignCommand(oPlayer, PlayAnimation(ANIMATION_LOOPING_GET_MID, 1.0, 4.0));
|
|
DelayCommand(1.0, PlaySound("as_cv_smithhamr1"));
|
|
|
|
location locAnvil = GetLocation(OBJECT_SELF);
|
|
vector vEffectPos = GetPositionFromLocation(locAnvil);
|
|
vEffectPos.z += 1.0;
|
|
location locEffect = Location( GetAreaFromLocation(locAnvil), vEffectPos,
|
|
GetFacingFromLocation(locAnvil) );
|
|
|
|
ApplyEffectAtLocation (DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_COM_SPARKS_PARRY), locEffect);
|
|
DelayCommand(1.7, ApplyEffectAtLocation (DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_COM_SPARKS_PARRY), locEffect));
|
|
DelayCommand(2.4, ApplyEffectAtLocation (DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_COM_SPARKS_PARRY), locEffect));
|
|
DelayCommand(3.1, ApplyEffectAtLocation (DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_COM_SPARKS_PARRY), locEffect));
|
|
DelayCommand(3.8, ApplyEffectAtLocation (DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_COM_SPARKS_PARRY), locEffect));
|
|
DelayCommand(6.0, ActionResumeConversation());
|
|
}
|
|
else if(sTradeskillName == CSTR_SKILLNAME_TANNING)
|
|
{
|
|
|
|
if(GetLocalInt(oPlayer, "ats_tanning_subskill") == ATS_TANNING_SUBSKILL_CURING)
|
|
{
|
|
ActionPauseConversation();
|
|
AssignCommand(oPlayer, PlayAnimation(ANIMATION_LOOPING_GET_LOW, 1.0, 4.0));
|
|
|
|
location locOven = GetLocation(OBJECT_SELF);
|
|
vector vEffectPos = GetPositionFromLocation(locOven);
|
|
|
|
float fDirection = ATS_CorrectDirection(GetFacing(OBJECT_SELF));
|
|
vEffectPos.z += 0.25;
|
|
vector vRelativeVector = Vector(0.1, -0.4, 0.0);
|
|
vector vTranslate = ATS_Transform2DVector(vRelativeVector, fDirection);
|
|
vEffectPos += vTranslate;
|
|
|
|
|
|
location locEffect = Location( GetAreaFromLocation(locOven), vEffectPos,
|
|
GetFacingFromLocation(locOven) );
|
|
|
|
object oFlame = CreateObject(OBJECT_TYPE_PLACEABLE, "ats_flame_small", locEffect, TRUE);
|
|
vEffectPos = GetPositionFromLocation(locOven);
|
|
|
|
vEffectPos.z += 4.2;
|
|
vRelativeVector = Vector(0.0, 1.0, 0.0);
|
|
vTranslate = ATS_Transform2DVector(vRelativeVector, fDirection);
|
|
vEffectPos += vTranslate;
|
|
locEffect = Location( GetAreaFromLocation(locOven), vEffectPos,
|
|
GetFacingFromLocation(locOven) );
|
|
|
|
ApplyEffectAtLocation (DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_FNF_SMOKE_PUFF), locEffect, 3.0);
|
|
DelayCommand(2.0, DestroyObject(oFlame));
|
|
DelayCommand(4.0, ActionResumeConversation());
|
|
}
|
|
else if(GetLocalInt(oPlayer, "ats_tanning_subskill") == ATS_TANNING_SUBSKILL_TANNING)
|
|
{
|
|
ActionPauseConversation();
|
|
AssignCommand(oPlayer, PlayAnimation(ANIMATION_LOOPING_GET_MID, 1.0, 4.5));
|
|
PlaySound("as_na_waterlap1");
|
|
DelayCommand(5.0, ActionResumeConversation());
|
|
}
|
|
else if(GetLocalInt(oPlayer, "ats_tanning_subskill") == ATS_TANNING_SUBSKILL_HARDENING)
|
|
{
|
|
ActionPauseConversation();
|
|
AssignCommand(oPlayer, PlayAnimation(ANIMATION_LOOPING_GET_MID, 1.0, 4.0));
|
|
|
|
location locOven = GetLocation(OBJECT_SELF);
|
|
vector vEffectPos = GetPositionFromLocation(locOven);
|
|
vEffectPos.z += 1.0;
|
|
location locEffect = Location( GetAreaFromLocation(locOven), vEffectPos,
|
|
GetFacingFromLocation(locOven) );
|
|
|
|
ApplyEffectAtLocation (DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_FNF_SMOKE_PUFF), locEffect, 2.0);
|
|
DelayCommand(4.0, ActionResumeConversation());
|
|
|
|
}
|
|
else if(GetLocalInt(oPlayer, "ats_tanning_subskill") == ATS_TANNING_SUBSKILL_SEWING)
|
|
{
|
|
AssignCommand(oPlayer, ActionPauseConversation());
|
|
AssignCommand(oPlayer, PlayAnimation(ANIMATION_LOOPING_PAUSE, 1.0, 4.0));
|
|
|
|
DelayCommand(3.0, AssignCommand(oPlayer, ActionResumeConversation()));
|
|
|
|
}
|
|
}
|
|
else if(sTradeskillName == CSTR_SKILLNAME_GEMCUTTING)
|
|
{
|
|
ActionPauseConversation();
|
|
AssignCommand(oPlayer, PlayAnimation(ANIMATION_LOOPING_GET_MID, 1.0, 3.0));
|
|
PlaySound("as_cv_chiseling2");
|
|
DelayCommand(3.0, ActionResumeConversation());
|
|
}
|
|
else if(sTradeskillName == CSTR_SKILLNAME_JEWELCRAFTING)
|
|
{
|
|
ActionPauseConversation();
|
|
AssignCommand(oPlayer, PlayAnimation(ANIMATION_LOOPING_GET_MID, 1.0, 4.0));
|
|
PlaySound("as_cv_shopmetal1");
|
|
DelayCommand(2.5, PlaySound("it_bladesmall"));
|
|
DelayCommand(2.75, PlaySound("it_bladesmall"));
|
|
DelayCommand(3.0, PlaySound("it_bladesmall"));
|
|
DelayCommand(3.25, PlaySound("it_bladesmall"));
|
|
DelayCommand(3.5, PlaySound("it_jewelry"));
|
|
DelayCommand(4.0, ActionResumeConversation());
|
|
}
|
|
else if(sTradeskillName == CSTR_SKILLNAME_BOWYERING)
|
|
{
|
|
ActionPauseConversation();
|
|
AssignCommand(oPlayer, PlayAnimation(ANIMATION_LOOPING_GET_MID, 1.0, 4.0));
|
|
PlaySound("as_cv_shopmetal1");
|
|
DelayCommand(2.5, PlaySound("it_bladesmall"));
|
|
DelayCommand(2.75, PlaySound("it_bladesmall"));
|
|
DelayCommand(3.0, PlaySound("it_bladesmall"));
|
|
DelayCommand(3.25, PlaySound("it_bladesmall"));
|
|
DelayCommand(3.5, PlaySound("it_jewelry"));
|
|
DelayCommand(4.0, ActionResumeConversation());
|
|
}
|
|
else if(sTradeskillName == CSTR_SKILLNAME_FLETCHING)
|
|
{
|
|
ActionPauseConversation();
|
|
AssignCommand(oPlayer, PlayAnimation(ANIMATION_LOOPING_GET_MID, 1.0, 4.0));
|
|
PlaySound("as_cv_shopmetal1");
|
|
DelayCommand(2.5, PlaySound("it_bladesmall"));
|
|
DelayCommand(2.75, PlaySound("it_bladesmall"));
|
|
DelayCommand(3.0, PlaySound("it_bladesmall"));
|
|
DelayCommand(3.25, PlaySound("it_bladesmall"));
|
|
DelayCommand(3.5, PlaySound("it_jewelry"));
|
|
DelayCommand(4.0, ActionResumeConversation());
|
|
}
|
|
//Tailor Code Starts
|
|
else if(sTradeskillName == CSTR_SKILLNAME_TAILOR)
|
|
{
|
|
ActionPauseConversation();
|
|
AssignCommand(oPlayer, PlayAnimation(ANIMATION_LOOPING_GET_MID, 1.0, 4.0));
|
|
PlaySound("as_cv_shopmetal1");
|
|
DelayCommand(2.5, PlaySound("it_bladesmall"));
|
|
DelayCommand(2.75, PlaySound("it_bladesmall"));
|
|
DelayCommand(3.0, PlaySound("it_bladesmall"));
|
|
DelayCommand(3.25, PlaySound("it_bladesmall"));
|
|
DelayCommand(3.5, PlaySound("it_jewelry"));
|
|
DelayCommand(4.0, ActionResumeConversation());
|
|
}
|
|
///Tailor Code Ends
|
|
else if(sTradeskillName == CSTR_SKILLNAME_TINKER)
|
|
{
|
|
ActionPauseConversation();
|
|
AssignCommand(oPlayer, PlayAnimation(ANIMATION_LOOPING_GET_MID, 1.0, 4.0));
|
|
PlaySound("as_cv_shopmetal1");
|
|
DelayCommand(2.5, PlaySound("it_bladesmall"));
|
|
DelayCommand(2.75, PlaySound("it_bladesmall"));
|
|
DelayCommand(3.0, PlaySound("it_bladesmall"));
|
|
DelayCommand(3.25, PlaySound("it_bladesmall"));
|
|
DelayCommand(3.5, PlaySound("it_jewelry"));
|
|
DelayCommand(4.0, ActionResumeConversation());
|
|
}
|
|
}
|
|
|
|
int BeginCrafting(object oPlayer, string sCraftTag, int iMaterialType, float fDelay)
|
|
{
|
|
string sTradeskillName = ATS_GetTradeSkillFromCraftTag(sCraftTag);
|
|
string sItemTag;
|
|
string sItemResRef;
|
|
int iTokenOffset = ATS_GetTokenOffset(oPlayer);
|
|
|
|
int iPlayersSkillValue = ATS_GetTradeskill(oPlayer, sTradeskillName);
|
|
|
|
int iMinSkill = ATS_GetCraftMinSkill(sCraftTag);
|
|
int iMaxSkill = ATS_GetCraftMaxSkill(sCraftTag);
|
|
|
|
if(ATS_IsCraftSingleType(sCraftTag) == FALSE)
|
|
{
|
|
iMinSkill += ATS_GetMaterialMinBonus(iMaterialType);
|
|
iMaxSkill += ATS_GetMaterialMaxBonus(iMaterialType);
|
|
}
|
|
int iSkillRange = iMaxSkill - iMinSkill + 1;
|
|
float fMultiplier = 100.0 / IntToFloat(iSkillRange);
|
|
int iFlatFailure = FALSE;
|
|
int iSkillGainAdjustment;
|
|
int iBaseSkillGainChance;
|
|
|
|
//Check Tool and adjust durability
|
|
object oCraftTool = ATS_GetToolForCraft(oPlayer, sTradeskillName);
|
|
if(GetLocalInt(oPlayer, "ats_flag_notool_needed") == FALSE)
|
|
{
|
|
if(oCraftTool == OBJECT_INVALID)
|
|
{
|
|
SendMessageToPC(oPlayer, "You must have the proper tool in order to finish.");
|
|
return FALSE;
|
|
}
|
|
ATS_AdjustCraftToolDurability(oCraftTool, 1);
|
|
}
|
|
|
|
|
|
//FloatingTextStringOnCreature("Attempting to craft...", oPlayer, FALSE);
|
|
AssignCommand(oPlayer, SpeakString("Attempting to craft..."));
|
|
PlayCraftingAnimation(sTradeskillName);
|
|
|
|
// Keep track of attempts
|
|
ATS_IncrementAttemptsCount(oPlayer, sTradeskillName);
|
|
|
|
DEBUG_PrintString("MinSkill: " + IntToString(iMinSkill) + " MaxSkill: " + IntToString(iMaxSkill));
|
|
|
|
int iSuccessValue = FloatToInt(fMultiplier * (iMaxSkill - iPlayersSkillValue));
|
|
|
|
int iDiceRoll;
|
|
|
|
iDiceRoll = d100(1);
|
|
DEBUG_PrintString("DiceRoll: " + IntToString(iDiceRoll) + " <= " + IntToString(CINT_FLATFAILURE_OVERALL));
|
|
if(iDiceRoll <= CINT_FLATFAILURE_OVERALL)
|
|
iFlatFailure = TRUE;
|
|
|
|
iDiceRoll = d100(1);
|
|
DEBUG_PrintString("DiceRoll: " + IntToString(iDiceRoll) + " <= " + IntToString(ATS_GetFlatFailure(sTradeskillName)));
|
|
if(iDiceRoll <= ATS_GetFlatFailure(sTradeskillName))
|
|
iFlatFailure = TRUE;
|
|
|
|
|
|
|
|
iDiceRoll = d100(1);
|
|
DEBUG_PrintString("DiceRoll: " + IntToString(iDiceRoll) + " + " +
|
|
IntToString(ATS_GetAttributeBonus(oPlayer, sTradeskillName))
|
|
+ " SuccessValue: " + IntToString(iSuccessValue));
|
|
|
|
|
|
if((iFlatFailure == FALSE) &&
|
|
(iDiceRoll + ATS_GetAttributeBonus(oPlayer, sTradeskillName) >= iSuccessValue))
|
|
{
|
|
//Remove materials freom player
|
|
if(ATS_RemoveCraftMaterials(oPlayer, sCraftTag, iMaterialType) == FALSE)
|
|
{
|
|
//Could not find all materials
|
|
FloatingTextStringOnCreature("Not all the materials could be found to make this.", oPlayer, FALSE);
|
|
return FALSE;
|
|
}
|
|
|
|
// Success
|
|
DelayCommand(fDelay, FloatingTextStringOnCreature("**SUCCESSFUL**", GetPCSpeaker()));
|
|
//Successfully made normal version
|
|
sItemTag = ATS_CraftToItemTag(sCraftTag, CSTR_QUALITY_NORMAL, ATS_GetMaterialTag(iMaterialType));
|
|
|
|
//Keep track of successes
|
|
ATS_IncrementSuccessCount(oPlayer, sTradeskillName);
|
|
|
|
// Check to see if exceptional version of item exists
|
|
if(ATS_CheckCraftItemExistence(sCraftTag, CINT_QUALITY_EXCEPTIONAL, iMaterialType) == TRUE)
|
|
{
|
|
//Check to see if exceptional version was made
|
|
iDiceRoll = d100(1);
|
|
string sRelatedSkill = ATS_GetRelatedQualitySkill(sTradeskillName);
|
|
int iRelatedSkillValue = ATS_GetTradeskill(oPlayer, sRelatedSkill);
|
|
if(ATS_IsPrimarySkill(sRelatedSkill) == FALSE)
|
|
iRelatedSkillValue = 2 * iRelatedSkillValue;
|
|
|
|
/*int iQualitySuccessValue = FloatToInt(fMultiplier * (iMaxSkill - iRelatedSkillValue));
|
|
iQualitySuccessValue = iQualitySuccessValue / 2;
|
|
if(iQualitySuccessValue < 0)
|
|
iQualitySuccessValue = 0;
|
|
iQualitySuccessValue += 50;*/
|
|
|
|
int iQualitySuccessValue = 95 - FloatToInt(iPlayersSkillValue/100.0 + iRelatedSkillValue/200.0);
|
|
|
|
if(iDiceRoll > iQualitySuccessValue)
|
|
{
|
|
//Successly made exceptional version
|
|
sItemTag = ATS_CraftToItemTag(sCraftTag, CSTR_QUALITY_EXCEPTIONAL, ATS_GetMaterialTag(iMaterialType));
|
|
// Check secondary skill gain
|
|
if(iRelatedSkillValue < iMaxSkill)
|
|
{
|
|
iDiceRoll = d100(1);
|
|
iBaseSkillGainChance = 5 + iQualitySuccessValue + GetAbilityModifier(ABILITY_INTELLIGENCE, oPlayer);
|
|
iSkillGainAdjustment = FloatToInt((CFLOAT_SKILLGAIN_ADJUST_OVERALL * iBaseSkillGainChance) +
|
|
(ATS_GetSkillGainAdjustment(sRelatedSkill) * iBaseSkillGainChance));
|
|
if(iDiceRoll <= (iBaseSkillGainChance + iSkillGainAdjustment) )
|
|
DelayCommand(fDelay, ATS_RaiseTradeskill(oPlayer, sRelatedSkill, 1));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Check secondary skill gain on failure of exceptional item
|
|
if(iRelatedSkillValue < iMaxSkill)
|
|
{
|
|
iDiceRoll = d100(1);
|
|
if(iDiceRoll <= CINT_SKILLGAIN_FAILURE )
|
|
DelayCommand(fDelay, ATS_RaiseTradeskill(oPlayer, sRelatedSkill, 1));
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// Check primary skill gain on success
|
|
if(iPlayersSkillValue < iMaxSkill) //Check trivial
|
|
{
|
|
iDiceRoll = d100(1);
|
|
|
|
iBaseSkillGainChance = 5 + iSuccessValue + GetAbilityModifier(ABILITY_INTELLIGENCE, oPlayer);
|
|
iSkillGainAdjustment = FloatToInt((CFLOAT_SKILLGAIN_ADJUST_OVERALL * iBaseSkillGainChance) +
|
|
(ATS_GetSkillGainAdjustment(sTradeskillName) * iBaseSkillGainChance));
|
|
|
|
DEBUG_PrintString("Skill Gain Chance for" + sTradeskillName);
|
|
DEBUG_PrintString("DiceRoll: " + IntToString(iDiceRoll) +
|
|
" <= BaseSuccessValue: " + IntToString(iBaseSkillGainChance) +
|
|
" + SkillAdjust: " + IntToString(iSkillGainAdjustment));
|
|
|
|
if(iDiceRoll <= (iBaseSkillGainChance + iSkillGainAdjustment) )
|
|
DelayCommand(fDelay, ATS_RaiseTradeskill(oPlayer, sTradeskillName, 1));
|
|
}
|
|
sItemResRef = GetStringLowerCase(sItemTag);
|
|
DelayCommand(fDelay + 1.0, ATS_CreateItemOnPlayer(sItemResRef, oPlayer));
|
|
|
|
if(GetIsObjectValid(GetObjectByTag(sItemTag)) == FALSE)
|
|
sItemTag = GetLocalString(GetModule(), sItemTag);
|
|
// Sets the custom tag
|
|
SetCustomToken(55090 + iTokenOffset, GetName(GetObjectByTag(sItemTag)));
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// Check primary skill gain on failure
|
|
if(iPlayersSkillValue < iMaxSkill) //Check trivial
|
|
{
|
|
if(d100(1) <= CINT_SKILLGAIN_FAILURE)
|
|
DelayCommand(fDelay, ATS_RaiseTradeskill(oPlayer, sTradeskillName, 1));
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|