Files
dsrc/sku.0/sys.server/compiled/game/script/object/autostack.script
T

310 lines
8.0 KiB
Plaintext

include library.loot;
include library.utils;
include library.sui;
include library.static_item;
include library.structure;
const boolean BLOGGING_ON = false;
const string BLOGGING_CATEGORY = "auto_stack";
trigger OnAttach()
{
//restackIt( self );
messageTo(self, "msgStackItem", null, 1, false);
return SCRIPT_CONTINUE;
}
trigger OnTransferred(obj_id sourceContainer, obj_id destContainer, obj_id transferer)
{
// Don't call "restack" if we're being moved from a top level cell object into the top level player
// inventory, so that the item decorative position/orientation can be restored if that is what the
// player is picking up the item for; if the player still want to stack the item, he can do it manually
if (isIdValid(sourceContainer) && isIdValid(destContainer))
{
string templateNameSourceContainer = getTemplateName(sourceContainer);
string templateNameDestContainer = getTemplateName(destContainer);
if ((templateNameSourceContainer != null) && (templateNameDestContainer != null) && templateNameSourceContainer.equals(structure.TEMPLATE_CELL) && templateNameDestContainer.equals("object/tangible/inventory/character_inventory.iff"))
return SCRIPT_CONTINUE;
}
// Don't call "restack" if we're in a factory crate. This causes wierdness.
if ( getGameObjectType(destContainer) != GOT_misc_factory_crate )
{
blog("Sending Stack messageTo msgStackItem");
messageTo(self, "msgStackItem", null, 1, false);
//restackIt( self );
}
return SCRIPT_CONTINUE;
}
trigger OnObjectMenuRequest(obj_id player, menu_info mi)
{
if (!canRestack(self))
{
return SCRIPT_CONTINUE;
}
if (getCount(self) > 1 )
{
mi.addRootMenu (menu_info_types.SERVER_MENU49, new string_id("autostack","unstack"));
menu_info_data mid = mi.getMenuItemByType(menu_info_types.SERVER_MENU49);
if(mid == null)
return SCRIPT_CONTINUE;
else
mid.setServerNotify(true);
}
mi.addRootMenu (menu_info_types.SERVER_MENU50, new string_id("autostack","stack"));
menu_info_data mid = mi.getMenuItemByType(menu_info_types.SERVER_MENU50);
if(mid == null)
return SCRIPT_CONTINUE;
else
mid.setServerNotify(true);
return SCRIPT_CONTINUE;
}
trigger OnObjectMenuSelect(obj_id player, int item)
{
if(!canRestack(self))
return SCRIPT_CONTINUE;
//the unstack it:
if (getCount(self) > 1 )
{
if(item == menu_info_types.SERVER_MENU49)
{
unstackIt(self, player);
}
}
if(item == menu_info_types.SERVER_MENU50)
{
utils.removeScriptVar( player, "autostack.ignoreitems");
restackIt( self );
}
return SCRIPT_CONTINUE;
}
trigger OnGetAttributes(obj_id player, string[] names, string[] attribs)
{
int free = getFirstFreeIndex(names);
if (free == -1)
{
return SCRIPT_CONTINUE;
}
int numInStack = getCount(self);
names[free] = "num_in_stack"; // data\sku.0\sys.shared\built\game\string\en\obj_attr_n.stf
attribs[free] = "" + numInStack;
return SCRIPT_CONTINUE;
}
boolean canRestack(obj_id self)
{
blog("canRestack init");
if(isInSecureTrade(self))
{
blog("isInSecureTrade");
return false;//Do not restack in a secure trade.
}
obj_id containerObject = utils.getContainingPlayer(self);
if(!isIdValid(containerObject))
{
if(!isContainerValidForStacking(self))
return false;
blog("containerObject is okay to use");
containerObject = getContainedBy(self);
}
blog("containerObject is valid");
return true;//we're golden!
}
void restackIt(obj_id self)
{
blog("restackIt init");
if(!isIdValid(self) || !exists(self))
return;
blog("restackIt validation complete");
if(isInSecureTrade(self)) //Do not restack in a secure trade.
return;
blog("restackIt - not isInSecureTrade");
obj_id containerObject = utils.getContainingPlayer(self);
if(!isIdValid(containerObject))
{
blog("restackIt - not a player container");
if(!isContainerValidForStacking(self))
return;
blog("restackIt - containerObject = getContainedBy");
containerObject = getContainedBy(self);
}
blog("restackIt - containerObject = valid");
if(utils.hasScriptVar(containerObject, "autostack.ignoreitems"))
return;
obj_id item = loot.findItemToStack(self);
if(isIdValid(item) && !isInSecureTrade(item))
{
if(utils.hasScriptVar(self, "unstacking") || utils.hasScriptVar(item, "unstacking"))
return;
if(item!=self)
{
loot.stackItem(self, item);
if (!hasScript(item, "object.autostack"))
attachScript(item, "object.autostack");
}
}
}
void unstackIt( obj_id self, obj_id player )
{
if (!isInSecureTrade(self)) //Do not restack in a secure trade.
{
if ( getCount( self ) == 2 )
{
createNewStack( player, self, 1, 2);
utils.setScriptVar(self, "unstacking", 1);
messageTo(self, "clearUnstackingScriptVar", null, 3, false);
}
else
{
sui.inputbox(self, player, "@autostack:stacksize", "msgUnstackItem");
}
}
}
messageHandler msgStackItem()
{
blog("msgStackItem init");
restackIt( self );
return SCRIPT_CONTINUE;
}
messageHandler clearUnstackingScriptVar()
{
utils.removeScriptVar(self, "unstacking");
return SCRIPT_CONTINUE;
}
messageHandler msgUnstackItem()
{
obj_id player = sui.getPlayerId(params);
if(!canRestack(self))
return SCRIPT_CONTINUE;
string amount_str = sui.getInputBoxText(params);
if ( amount_str == null || amount_str == "" )
{
//sendSystemMessage( player, new string_id( "autostack", "invalid" ));
return SCRIPT_CONTINUE;
}
int oldStackSize = getCount( self );
int newStackSize = utils.stringToInt(amount_str);//will return a -1
if ( newStackSize == 0 )
{
sendSystemMessage( player, new string_id( "autostack", "zero_size" ));
return SCRIPT_CONTINUE;
}
else if ( newStackSize < 0 )
{
sendSystemMessage( player, new string_id( "autostack", "number_format_wrong" ));
return SCRIPT_CONTINUE;
}
else if ( newStackSize > oldStackSize )
{
sendSystemMessage( player, new string_id( "autostack", "too_big" ));
return SCRIPT_CONTINUE;
}
else if ( newStackSize == oldStackSize )
{
return SCRIPT_CONTINUE;//if they're the same size then we're done.
}
createNewStack( player, self, newStackSize, oldStackSize );
utils.setScriptVar(self, "unstacking", 1);
messageTo(self, "clearUnstackingScriptVar", null, 3, false);
return SCRIPT_CONTINUE;
}
void createNewStack( obj_id player, obj_id item, int newStackSize, int oldStackSize )
{
obj_id container = getContainedBy(item);
if (!isIdValid(container))
{
sendSystemMessage( player, new string_id( "autostack", "bad_container" ));
return ;
}
if (getVolumeFree(container) <= 0)
{
sendSystemMessage( player, new string_id( "autostack", "full_container" ));
return;
}
utils.setScriptVar( player, "autostack.ignoreitems", true );
obj_id newItem = null;
if(static_item.isStaticItem (item))
newItem = static_item.createNewItemFunction( getStaticItemName(item), container);
else
newItem = createObject( item, container, "" );
if ( !isIdValid( newItem ) )
{
sendSystemMessage( player, new string_id( "autostack", "unknown_failure" ));
utils.removeScriptVar( player, "autostack.ignoreitems");
return;
}
setCount( item, (oldStackSize - newStackSize) );
setCount( newItem, newStackSize );
utils.removeScriptVar( player, "autostack.ignoreitems");
}
boolean isContainerValidForStacking(obj_id self)
{
if(!isValidId(self) || !exists(self))
return false;
string containerTemplate = getTemplateName(getContainedBy(self));
blog("isContainerValidForStacking containerTemplate: "+containerTemplate);
if(isGameObjectTypeOf(getContainedBy(self), GOT_misc_container_wearable))//backpack or other player wearable is ok.
return true;
else if(isGameObjectTypeOf(getContainedBy(self), GOT_misc_container))//furniture is cool, other specialty containers = bad
{
if(containerTemplate.startsWith("object/tangible/furniture/") || containerTemplate.startsWith("object/tangible/poi/object/"))
return true;//Furniture and poi objects are cool
//all else isn't.
return false;
}
return false;
}
boolean blog(string msg)
{
if(!BLOGGING_ON)
return false;
else if(msg == null || msg.equals(""))
return false;
LOG(BLOGGING_CATEGORY, msg);
return true;
}