 |
 |
 |
 |
| Author |
Message |
itec
Joined: 10 Feb 2006 Posts: 35 Location: Finland
|
Posted: Tue Mar 04, 2008 5:37 am Post subject: Share-a-function thread |
|
|
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: 168
|
Posted: Tue Mar 04, 2008 3:05 pm Post subject: |
|
|
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
|
|
|
 |
|
|
|