mirror of
https://github.com/SWG-Source/dsrc.git
synced 2026-07-29 23:15:55 -04:00
505 lines
16 KiB
Plaintext
505 lines
16 KiB
Plaintext
//------------------------------------------------
|
|
// slicing.scriptlib
|
|
// Brandon Reinhart
|
|
//------------------------------------------------
|
|
|
|
// - add X wire puzzles
|
|
// - abort if the item becomes unlocked while we are slicing it
|
|
|
|
//------------------------------------------------
|
|
// Include
|
|
//------------------------------------------------
|
|
|
|
include library.sui;
|
|
include library.utils;
|
|
include library.jedi;
|
|
include library.powerup;
|
|
|
|
//------------------------------------------------
|
|
// Constants
|
|
//------------------------------------------------
|
|
|
|
const string_id SID_SLICING_UNDERWAY = new string_id("slicing/slicing", "slicing_underway");
|
|
const string_id SID_ALREADY_SLICING = new string_id("slicing/slicing", "already_slicing");
|
|
const string_id SID_ALREADY_SLICED = new string_id("slicing/slicing", "already_sliced");
|
|
const string_id SID_ALREADY_BEING_SLICED = new string_id("slicing/slicing", "already_being_sliced");
|
|
const string_id SID_JEDI_NO_SLICE = new string_id("slicing/slicing", "jedi");
|
|
const string_id SID_STATIC_ITEM = new string_id("slicing/slicing", "static");
|
|
|
|
const string_id SID_CUSTOMIZATION = new string_id("slicing/slicing", "customization");
|
|
const string_id SID_SLICE_NO_SKILL = new string_id("slicing/slicing", "no_skill");
|
|
const string_id SID_NOT_ENOUGH_SKILL = new string_id("slicing/slicing", "not_enough_skill");
|
|
const string_id SID_ALREADY_APPLIED = new string_id("slicing/slicing", "already_applied_sys");
|
|
const string_id SID_CANT_APPLY = new string_id("slicing/slicing", "cant_apply_sys");
|
|
const string_id SID_COST_TOO_HIGH = new string_id("slicing/slicing", "cost_too_high");
|
|
const string_id SID_CANT_FIX = new string_id("slicing/slicing", "cant_fix");
|
|
const string_id SID_FIX_SUCCESSFUL = new string_id("slicing/slicing", "fix_successful");
|
|
const string_id SID_REQUIRES_COMPONENT = new string_id("slicing/slicing", "requires_component");
|
|
const string_id SID_NO_COMPONENT_REQUIRED = new string_id("slicing/slicing", "no_comp_required");
|
|
const string_id SID_MISSING_COMP = new string_id("slicing/slicing", "missing_comp");
|
|
|
|
const string SLICE_WEAPON_TABLE = "datatables/smuggler/slice_weapon.iff";
|
|
const string SLICE_ARMOR_TABLE = "datatables/smuggler/slice_armor.iff";
|
|
|
|
//------------------------------------------------
|
|
// startSlicing
|
|
//------------------------------------------------
|
|
|
|
void startSlicing( obj_id player, obj_id item, string callback, string type )
|
|
{
|
|
if (jedi.isLightsaber(item))
|
|
{
|
|
sendSystemMessage(player, SID_JEDI_NO_SLICE); // cant slice lightsabers
|
|
return;
|
|
}
|
|
|
|
if (static_item.isStaticItem(item))
|
|
{
|
|
sendSystemMessage(player, SID_STATIC_ITEM); // cant slice to static Items
|
|
return;
|
|
}
|
|
|
|
// Check to see if the player is already slicing something.
|
|
if ( utils.hasScriptVar( player, "slicing.slice_item" ) )
|
|
{
|
|
sendSystemMessage( player, SID_ALREADY_SLICING );
|
|
return;
|
|
}
|
|
if ( hasObjVar( item, "slice_start" ) )
|
|
{
|
|
int slice_start = getIntObjVar( item, "slice_start" );
|
|
int delta = getGameTime() - slice_start;
|
|
if ( delta < 172800 )
|
|
{
|
|
obj_id first_slicer = getObjIdObjVar( item, "sliced_by" );
|
|
if ( (first_slicer != player) && (delta < 900) )
|
|
{
|
|
// Two people tried to slice this item.
|
|
CustomerServiceLog( "exploit", "Two players tried to double slice an item within 15 minutes, they may be exploiting." );
|
|
CustomerServiceLog( "exploit", "--First Slicer: %TU", first_slicer );
|
|
CustomerServiceLog( "exploit", "--Second Slicer: %TU", player );
|
|
}
|
|
sendSystemMessage( player, SID_ALREADY_BEING_SLICED );
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Set this up to be sliced.
|
|
utils.setScriptVar( player, "slicing.slice_item", item );
|
|
utils.setScriptVar( player, "slicing.type", type );
|
|
utils.setScriptVar( player, "slicing.callback", callback );
|
|
|
|
// Mark the item as being sliced.
|
|
setObjVar( item, "slice_start", getGameTime() );
|
|
setObjVar( item, "sliced_by", player );
|
|
|
|
// Attach slicing handler script to the player.
|
|
attachScript( player, "player.player_slicing" );
|
|
|
|
// Pop up the initial query.
|
|
slicingQuery( player, item, type );
|
|
}
|
|
|
|
//------------------------------------------------
|
|
// clearSlicing
|
|
//------------------------------------------------
|
|
|
|
void clearSlicing( obj_id player )
|
|
{
|
|
obj_id slice_item = utils.getObjIdScriptVar( player, "slicing.slice_item" );
|
|
if ( isIdValid( slice_item ) )
|
|
{
|
|
removeObjVar( slice_item, "slice_start" );
|
|
removeObjVar( slice_item, "sliced_by" );
|
|
}
|
|
|
|
// Remove slicing vars.
|
|
utils.removeScriptVar( player, "slicing.slice" );
|
|
utils.removeScriptVar( player, "slicing.type" );
|
|
utils.removeScriptVar( player, "slicing.cat" );
|
|
utils.removeScriptVar( player, "slicing.callback" );
|
|
utils.removeScriptVar( player, "slicing.slice_item" );
|
|
utils.removeScriptVar( player, "slicing.last_query" );
|
|
utils.removeScriptVar( player, "slicing.apply_status" );
|
|
|
|
// Remove slicing script.
|
|
detachScript( player, "player.player_slicing" );
|
|
}
|
|
|
|
//------------------------------------------------
|
|
// slicingQuery
|
|
//------------------------------------------------
|
|
|
|
void slicingQuery( obj_id player, obj_id item, string query )
|
|
{
|
|
// Determine the player's skill mod for this slice.
|
|
int skillMod = getSkillStatisticModifier( player, "slice_"+query );
|
|
if ( skillMod == 0 )
|
|
{
|
|
// This might be a generic slice.
|
|
// See if we are a smuggler.
|
|
// NOTE: This is the split point for slices like keypads or locks.
|
|
if ( hasSkill( player, "class_smuggler_phase1_novice" ) )
|
|
{
|
|
successSlicing( player, item, 0 );
|
|
return;
|
|
}
|
|
|
|
// Cannot slice, no skill.
|
|
sendSystemMessage( player, SID_SLICE_NO_SKILL );
|
|
clearSlicing( player );
|
|
return;
|
|
}
|
|
|
|
// Grab the categories the player can slice.
|
|
string table = null;
|
|
if ( query == "weapon" )
|
|
table = SLICE_WEAPON_TABLE;
|
|
else if ( query == "armor" )
|
|
table = SLICE_ARMOR_TABLE;
|
|
int rows = dataTableGetNumRows( table );
|
|
resizeable string[] categories = new string[0];
|
|
for ( int i=0; i<rows; i++ )
|
|
{
|
|
string is_this_cat = dataTableGetString( table, i, "SLICE_CAT" );
|
|
if ( is_this_cat == null || is_this_cat == "" )
|
|
continue;
|
|
int req = dataTableGetInt( table, i, "SKILL_REQ" );
|
|
if ( skillMod >= req )
|
|
categories = utils.addElement( categories, "@slicing/slicing_"+query+":"+is_this_cat );
|
|
}
|
|
if ( categories.length == 0 )
|
|
{
|
|
// Cannot slice, we don't qualify for any slices.
|
|
sendSystemMessage( player, SID_SLICE_NO_SKILL );
|
|
clearSlicing( player );
|
|
return;
|
|
}
|
|
|
|
sui.listbox( player, player, "@slicing/slicing:" + query, sui.OK_CANCEL, "@slicing/slicing:cat_title", categories, "handleSlicingCategory", true );
|
|
}
|
|
|
|
//------------------------------------------------
|
|
// handleSlicingCategory
|
|
//------------------------------------------------
|
|
|
|
void handleSlicingCategory( obj_id player, int idx )
|
|
{
|
|
string query = utils.getStringScriptVar( player, "slicing.type" );
|
|
obj_id item = utils.getObjIdScriptVar( player, "slicing.slice_item" );
|
|
if ( !isIdValid( item ) )
|
|
{
|
|
clearSlicing( player );
|
|
return;
|
|
}
|
|
|
|
// Determine the player's skill mod for this slice.
|
|
int skillMod = getSkillStatisticModifier( player, "slice_"+query );
|
|
|
|
// Get the types of slice for the chosen category.
|
|
string table = null;
|
|
if ( query == "weapon" )
|
|
table = SLICE_WEAPON_TABLE;
|
|
else if ( query == "armor" )
|
|
table = SLICE_ARMOR_TABLE;
|
|
int rows = dataTableGetNumRows( table );
|
|
resizeable string[] slices = new string[0];
|
|
idx++;
|
|
int cats = 0;
|
|
int type = 0;
|
|
utils.setScriptVar( player, "slicing.cat", idx );
|
|
for ( int i=0; i<rows; i++ )
|
|
{
|
|
string is_this_cat = dataTableGetString( table, i, "SLICE_CAT" );
|
|
if ( is_this_cat != "" )
|
|
{
|
|
cats++;
|
|
continue;
|
|
}
|
|
if ( cats == idx )
|
|
{
|
|
string slice = dataTableGetString( table, i, "SLICE" );
|
|
string stat = dataTableGetString( table, i, "STAT" );
|
|
int req = dataTableGetInt( table, i, "SKILL_REQ" );
|
|
int rank = dataTableGetInt( table, i, "RANK" );
|
|
int cur_rank = getIntObjVar( item, "slice.rank."+stat );
|
|
if ( skillMod >= req )
|
|
{
|
|
string color_prefix = "";
|
|
string status_suffix = "";
|
|
if ( rank > cur_rank+1 )
|
|
{
|
|
// Can't be applied yet.
|
|
color_prefix = "\\#888888";
|
|
status_suffix = "-- Can't be applied, yet.";
|
|
}
|
|
else if ( rank <= cur_rank )
|
|
{
|
|
// Has already been applied.
|
|
color_prefix = "\\#FFFFFF";
|
|
status_suffix = "-- Already applied.";
|
|
}
|
|
/*
|
|
else
|
|
{
|
|
// Can be applied.
|
|
color_prefix = "\\#00FF00";
|
|
status_suffix = "-- Can be applied.";
|
|
}
|
|
*/
|
|
|
|
slices = utils.addElement( slices, "@slicing/slicing_"+query+":"+slice + " " + color_prefix + status_suffix );
|
|
utils.setScriptVar( player, "slicing."+type, i );
|
|
type++;
|
|
}
|
|
}
|
|
}
|
|
|
|
sui.listbox( player, player, "@slicing/slicing:select_slice", sui.OK_CANCEL, "@slicing/slicing:slice_title", slices, "handleSlicingSelect", true );
|
|
}
|
|
|
|
//------------------------------------------------
|
|
// handleSlicingSelect
|
|
//------------------------------------------------
|
|
|
|
void handleSlicingSelect( obj_id player, int idx )
|
|
{
|
|
int cat = utils.getIntScriptVar( player, "slicing.cat" );
|
|
int row = utils.getIntScriptVar( player, "slicing."+idx );
|
|
obj_id item = utils.getObjIdScriptVar( player, "slicing.slice_item" );
|
|
string query = utils.getStringScriptVar( player, "slicing.type" );
|
|
string table = null;
|
|
if ( query == "weapon" )
|
|
table = SLICE_WEAPON_TABLE;
|
|
else if ( query == "armor" )
|
|
table = SLICE_ARMOR_TABLE;
|
|
|
|
// Determine the player's skill mod for this slice.
|
|
int skillMod = getSkillStatisticModifier( player, "slice_"+query );
|
|
dictionary effect = dataTableGetRow( table, row );
|
|
int req = effect.getInt( "SKILL_REQ" );
|
|
if ( skillMod < req )
|
|
{
|
|
sendSystemMessage( player, SID_NOT_ENOUGH_SKILL );
|
|
clearSlicing( player );
|
|
return;
|
|
}
|
|
|
|
// Can this be applied?
|
|
string stat = effect.getString( "STAT" );
|
|
int rank = effect.getInt( "RANK" );
|
|
int cur_rank = getIntObjVar( item, "slice.rank."+stat );
|
|
string_id apply_status = null;
|
|
string_id apply_status_also = null;
|
|
if ( skillMod >= req )
|
|
{
|
|
if ( rank > cur_rank+1 )
|
|
{
|
|
// Can't be applied yet.
|
|
apply_status = new string_id( "slicing/slicing", "cant_apply" );
|
|
dictionary effect_prereq = dataTableGetRow( table, row-1 );
|
|
apply_status_also = new string_id( "slicing/slicing_"+query, effect_prereq.getString( "SLICE" ) );
|
|
utils.setScriptVar( player, "slicing.apply_status", 1 );
|
|
}
|
|
else if ( rank <= cur_rank )
|
|
{
|
|
// Has already been applied.
|
|
apply_status = new string_id( "slicing/slicing", "already_applied" );
|
|
utils.setScriptVar( player, "slicing.apply_status", 2 );
|
|
}
|
|
else
|
|
{
|
|
// Can be applied.
|
|
apply_status = new string_id( "slicing/slicing", "can_apply" );
|
|
utils.setScriptVar( player, "slicing.apply_status", 3 );
|
|
}
|
|
}
|
|
|
|
// Check to see if this would put us over our customization limit.
|
|
int new_cust = effect.getInt( "COST" );
|
|
int cust = getIntObjVar( item, "slice.customized" );
|
|
if ( cust + new_cust > 100 )
|
|
{
|
|
apply_status = new string_id( "slicing/slicing", "cant_apply_cost" );
|
|
utils.setScriptVar( player, "slicing.apply_status", 5 );
|
|
}
|
|
|
|
// Check to see if we have the object required to apply the slice.
|
|
string component_line = null;
|
|
string component = effect.getString( "COMPONENT" );
|
|
string component_path = "object/tangible/smuggler/"+component+".iff";
|
|
string_id component_sid = new string_id( "smuggler/items", component );
|
|
if ( component != null && component != "" )
|
|
{
|
|
obj_id pInv = utils.getInventoryContainer( player );
|
|
obj_id[] contents = utils.getContents( pInv, true );
|
|
int found = 0;
|
|
for ( int i=0; i<contents.length; i++ )
|
|
{
|
|
string tn = getTemplateName( contents[i] );
|
|
if ( tn == component_path )
|
|
{
|
|
found = 1;
|
|
break;
|
|
}
|
|
}
|
|
if ( found == 0 )
|
|
{
|
|
apply_status = new string_id( "slicing/slicing", "missing_component" );
|
|
utils.setScriptVar( player, "slicing.apply_status", 4 );
|
|
utils.setScriptVar( player, "slicing.comp", component );
|
|
}
|
|
}
|
|
|
|
// Show slice info.
|
|
utils.setScriptVar( player, "slicing.row", row );
|
|
prose_package slice_attributes[] = new prose_package[4];
|
|
slice_attributes[0] = prose.getPackage( SID_CUSTOMIZATION, effect.getInt("COST") );
|
|
slice_attributes[1] = prose.getPackage( new string_id( "slicing/slicing_"+query, effect.getString("STAT")+"_attrib" ), effect.getInt("AMOUNT") );
|
|
if ( component == null || component == "" )
|
|
{
|
|
slice_attributes[2] = prose.getPackage( SID_NO_COMPONENT_REQUIRED );
|
|
}
|
|
else
|
|
{
|
|
slice_attributes[2] = prose.getPackage( SID_REQUIRES_COMPONENT, component_sid );
|
|
}
|
|
slice_attributes[3] = prose.getPackage( apply_status, apply_status_also );
|
|
sui.listbox( player, player, "@slicing/slicing_"+query+":"+effect.getString("STAT")+"_detail", sui.OK_CANCEL, "@slicing/slicing:slice_attributes", slice_attributes, "handleApplySlice", true, false );
|
|
}
|
|
|
|
//------------------------------------------------
|
|
// handleApplySlice
|
|
//------------------------------------------------
|
|
|
|
void handleApplySlice( obj_id player, int idx )
|
|
{
|
|
int row = utils.getIntScriptVar( player, "slicing.row" );
|
|
string query = utils.getStringScriptVar( player, "slicing.type" );
|
|
string table = null;
|
|
if ( query == "weapon" )
|
|
table = SLICE_WEAPON_TABLE;
|
|
else if ( query == "armor" )
|
|
table = SLICE_ARMOR_TABLE;
|
|
obj_id item = utils.getObjIdScriptVar( player, "slicing.slice_item" );
|
|
|
|
// Make sure we can apply the slice.
|
|
// See if the slice has already been applied.
|
|
int apply_status = utils.getIntScriptVar( player, "slicing.apply_status" );
|
|
if ( apply_status == 2 )
|
|
{
|
|
sendSystemMessage( player, SID_ALREADY_APPLIED );
|
|
clearSlicing( player );
|
|
return;
|
|
}
|
|
else if ( apply_status == 1 )
|
|
{
|
|
dictionary effect_prereq = dataTableGetRow( table, row-1 );
|
|
string_id apply_status_also = new string_id( "slicing/slicing_"+query, effect_prereq.getString( "SLICE" ) );
|
|
prose_package pp = prose.getPackage( SID_CANT_APPLY, apply_status_also );
|
|
sendSystemMessageProse( player, pp );
|
|
clearSlicing( player );
|
|
return;
|
|
}
|
|
else if ( apply_status == 4 )
|
|
{
|
|
string comp = utils.getStringScriptVar( player, "slicing.comp" );
|
|
string_id missing_comp = new string_id( "smuggler/items", comp );
|
|
prose_package pp = prose.getPackage( SID_MISSING_COMP, missing_comp );
|
|
sendSystemMessageProse( player, pp );
|
|
clearSlicing( player );
|
|
return;
|
|
}
|
|
|
|
// Check to see if this would put us over our customization limit.
|
|
dictionary effect = dataTableGetRow( table, row );
|
|
int new_cust = effect.getInt( "COST" );
|
|
int cust = getIntObjVar( item, "slice.customized" );
|
|
if ( cust + new_cust > 100 )
|
|
{
|
|
sendSystemMessage( player, SID_COST_TOO_HIGH );
|
|
clearSlicing( player );
|
|
return;
|
|
}
|
|
|
|
// Remove the component if we have one.
|
|
string component = effect.getString( "COMPONENT" );
|
|
string component_path = "object/tangible/smuggler/"+component+".iff";
|
|
if ( component != null && component != "" )
|
|
{
|
|
obj_id pInv = utils.getInventoryContainer( player );
|
|
obj_id[] contents = utils.getContents( pInv, true );
|
|
int found = 0;
|
|
for ( int i=0; i<contents.length; i++ )
|
|
{
|
|
string tn = getTemplateName( contents[i] );
|
|
if ( tn == component_path )
|
|
{
|
|
found = 1;
|
|
consumeComponent( contents[i] );
|
|
break;
|
|
}
|
|
}
|
|
if ( found == 0 )
|
|
{
|
|
string comp = utils.getStringScriptVar( player, "slicing.comp" );
|
|
string_id missing_comp = new string_id( "smuggler/items", comp );
|
|
prose_package pp = prose.getPackage( SID_MISSING_COMP, missing_comp );
|
|
sendSystemMessageProse( player, pp );
|
|
clearSlicing( player );
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Apply the effect.
|
|
successSlicing( player, item, row );
|
|
}
|
|
|
|
|
|
//------------------------------------------------
|
|
// successSlicing
|
|
//------------------------------------------------
|
|
|
|
void successSlicing( obj_id player, obj_id item, int row )
|
|
{
|
|
// Callback to the sliced item.
|
|
string callback = utils.getStringScriptVar( player, "slicing.callback" );
|
|
dictionary outp = new dictionary();
|
|
outp.put( "success", 1 );
|
|
outp.put( "row", row );
|
|
outp.put( "player", player );
|
|
messageTo( item, callback, outp, 0.f, true );
|
|
|
|
// Clear slicing flags.
|
|
clearSlicing( player );
|
|
}
|
|
|
|
//------------------------------------------------
|
|
// failSlicing
|
|
//------------------------------------------------
|
|
|
|
void failSlicing( obj_id player, obj_id item )
|
|
{
|
|
// Callback to the sliced item.
|
|
string callback = utils.getStringScriptVar( player, "slicing.callback" );
|
|
dictionary outp = new dictionary();
|
|
outp.put( "success", 0 );
|
|
outp.put( "player", player );
|
|
messageTo( item, callback, outp, 0.f, true );
|
|
|
|
// Clear slicing flags.
|
|
clearSlicing( player );
|
|
}
|
|
|
|
void consumeComponent( obj_id item )
|
|
{
|
|
int count = getCount(item);
|
|
count--;
|
|
|
|
if(count <= 0)
|
|
destroyObject(item);
|
|
else
|
|
setCount(item, count);
|
|
}
|
|
|