PenUltima Online Forum Index Official Core: 096.7
Official Core: 097 2008-02-26
Donate towards the POL web hosting bill!
 POL Home   FAQ   Search    Memberlist   Usergroups    Register    Profile   Log in to check your private messages   Log in
Share-a-function thread

 
Post new topic   Reply to topic    PenUltima Online Forum Index -> Custom Script Releases
Display posts from previous:   

Author Message
itec



Joined: 10 Feb 2006
Posts: 35
Location: Finland

PostPosted: Tue Mar 04, 2008 5:37 am    Post subject: Share-a-function thread Reply with quote

To encourage everyone to give something back to the community, share a small (or big) helper function you are frequently using in your scripting. Maybe some of thease would fit in the distro as well.

To start off, here's two of our item functions.

Code:

/*
   Reaches

   Checks if player reaches the wanted item.
   
   Params:
      Char      Who uses
      Item      What
      ~Integer   Options
      ~String      What item name will be messaged, if 0 sends nothing
   
   Returns: true or error
 */

enum OPTIONS
   OPT_UNMOVABLE   := 0x1      // Allowing unmovables
endenum

function Reaches( who, item, options := 0, what := "item" )
   
   var msg;
   
   if (!Accessible(who, item))
      msg := " is unreachable.";
   elseif (!(options & OPT_UNMOVABLE) && item.movable == 0)
      msg := " is unmovable.";
   elseif (!ReserveItem(item))
      msg := " is already in use.";
   elseif (Distance(who, item) > 2)
      msg := " is too far away.";
   elseif (item.GetProp("Vendored"))
      // Player merchants, remove if not needed
      msg := " is not yours.";
   else
      return 1;
   endif
   
   // Does not reach
   if (what)
      SendSysMessageUC(who, CAscZ("The "+what+msg));
   endif
   
   return 0;
   
endfunction


Code:

/*
   ItemEquip
   
   Acts as EquipItem, but removes weared equipment of the same layer.
   
   Params:
      Char      who
      Item      Equipment to be weared
      ~Integer      Options in bit-form
      
         OPT_FORCE         Skip reaches() check
         OPT_LIST_STRIPPED   Lists and returns removed items
   
   Returns:
      item array   if OPT_LIST_STRIPPED is set
      1         if item is equipped
      error      when failed
*/

enum EQUIP_OPTIONS
   OPT_FORCE         := 1,   
   OPT_LIST_STRIPPED   := 2
endenum

function ItemEquip( who, itemref, options := 0 )
   
   if (!(options & OPT_FORCE))
      
      var res := Reaches(who, itemref);
      if (res == error)
         return res;
      endif
   endif

   var result := 0;
   var stripped := array;
   
   // Item already equpped (core EquipItem() returns negative if item is already weared)
   if (itemref.container == who)
      
      result := 1;
   elseif (itemref.isa(POLCLASS_EQUIPMENT))
      
      result := EquipItem(who, itemref);
      
      if (!result)
         // Conflicting items are unequipped
         var itemlayer := itemref.layer;
         
         if (itemlayer == 1 || itemlayer == 2)
            // Layer 2 needs layer 1 to be empty and vice versa
            itemlayer := { 1, 2 };
         else
            itemlayer := { itemlayer };
         endif
         
         foreach layer in itemlayer
            var equipped := GetEquipmentByLayer(who, layer);
            
            if (equipped)
               // Moving conflicting equipment to backpack or ground
               if (!MoveItemToContainer(equipped, who.backpack))
                  MoveObjectToLocation(equipped, who.x, who.y, who.z, who.realm, MOVEOBJECT_FORCELOCATION);
               endif
               
               if (options & OPT_LIST_STRIPPED)
                  stripped.append(equipped);
               endif
            endif
         endforeach
         
         // New try
         result := EquipItem(who, itemref);
      endif
   endif
   
   if (options & OPT_LIST_STRIPPED)
      return stripped;
   endif
   
   return result;
   
endfunction

Author Message
ncrsn



Joined: 10 Feb 2006
Posts: 183

PostPosted: Tue Mar 04, 2008 3:05 pm    Post subject: Reply with quote

Some other item functions.

1. DivideStack

Say, you need to do modify item (change its graphic or something), but it happens to be stackable: an example could be a unlit torch you wish to lit without affecting all n torches.

You could do 'if (item.amount > 1) // Throw error message: too many torches in stack!', but that would be rude and unprofessional; so, instead, write 'DivideStack(item, -1)' and you will get the stack subtracted to just one item, without item's being really taken from player.

Code:

/*
   DivideStack
   
   Divides item stack into defined sized
   stacks.
   
   Params:
      Item   Item stack
      Integer   Size of split stack
   
   Returns:
      Created stack or 0 if failed.
   
   Note:
      If 'amt' is below zero, created
      stack will be sized .amount - amt.
      
      If 'amt' is between 1 and item.amount,
      created stack will be it's size.
      
      Created stack will be placed next to
      the original stack.
*/

function DivideStack( item, amt )
   
   if (amt < 0)
      // User wanted to leave amt items to original stack.
      amt += item.amount;
      
      if (amt < 1)
         // There are too few.
         return 0;
      endif
   elseif (item.amount <= amt)
      // Stack should have amt + 1.
      return 0;
   endif
   
   // Copy into abstract location.
   var newitem := CreateItemCopyAtLocation(1, 1, 1, item, _DEFAULT_REALM);
   
   if (!SubtractAmount(newitem, item.amount - amt))
      // Subtracting required amount from new stack - Failed.
      DestroyItem(newitem);
      return 0;
   elseif (!SubtractAmount(item, amt))
      // Subtracting required amount from original stack - Failed.
      DestroyItem(newitem);
      return 0;
   endif
   
   // Move new item into same location (container or coordinates) the original is.
   MoveItem(newitem, item);
   
   // Reference to created item.
   return newitem;
   
endfunction


2. MoveItem

Move item to another location, were it to be a container or just struct with x, y, z and realm.

Code:

/*
   MoveItem
   
   Moves item into a backpack, container or coordinates. If
   container is full, moves item into container's  container,
   or eventually, onto ground.
   
   Params:
      Item   Item
      Object   Mobile / Container / Coordinates
   
   Returns:
      True or error
   
   Note:
      Coordinates could be just struct, but you have to
      define, not only "x", "y" and "z", but also "realm".
*/

function MoveItem( item, object )
   
   if (object.isa(POLCLASS_MOBILE))
      if (object.backpack)
         // Move into backpack; if there's no backpack, at feet.
         object := object.backpack;
      endif
   endif
   
   if (object.isa(POLCLASS_CONTAINER))
      // Check if container can take this.
      if (MoveItemToContainer(item, object))
         return 1;
      endif
   endif
   
   // Container is full or object is coordinate-struct. Next
   // step is to try object's container; if there is one.
   
   while (object.container)
      
      // Object is now it's container.
      object := object.container;
      
      if (MoveItemToContainer(item, object))
         return 1;
      endif
      
   endwhile
   
   // Every level of container's were full; or there were none.
   // Last try is to move item onto ground level.
   
   return MoveObjectToLocation(item, object.x, object.y, object.z, object.realm, MOVEOBJECT_FORCELOCATION);
   
endfunction

Post new topic   Reply to topic    PenUltima Online Forum Index -> Custom Script Releases All times are GMT - 4 Hours
Page 1 of 1

 




Powered by phpBB © 2001, 2005 phpBB Group :: Theme & Graphics by GHS & Scott E. Royalty