Files
dsrc/sku.0/sys.server/compiled/game/script/library/slicing.scriptlib
T
2013-09-10 23:17:15 -07:00

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