Author Topic: [Script] useful thingies  (Read 8144 times)

JovankaB

  • Guest
[Script] useful thingies
« on: February 05, 2013, 09:12:47 pm »
Here you can post small, useful utility functions. Things that anyone could wrote, but we can save time by sharing them. Let me start with a function to find the nearest free hex within a given "radius".

bool FindNearestFreeHex (Map& map, uint16& x, uint16& y, uint radius)

Code: [Select]
// Finds the nearest free hex within a given radius.
//
bool FindNearestFreeHex (Map& map, uint16& x, uint16& y, uint radius)
{
    if (map.IsHexPassed(x, y))
    {
        return true;
    }
    for (uint r = 1; r <= radius; r++)
    {
        map.MoveHexByDir(x, y, 4, 1);
        for (uint side = 0; side < 6; side++)
        {
            for (uint step = 0; step < r; step++)
            {
                map.MoveHexByDir(x, y, side, 1);
                if (map.IsHexPassed(x, y))
                {
                    return true;
                }
            }
        }
    }
    return false;
}
« Last Edit: June 30, 2013, 01:17:49 pm by b__B »

JovankaB

  • Guest
Re: [script] useful thingies
« Reply #1 on: February 06, 2013, 10:15:12 am »
Utils for Locations:

bool LocationHasCritters (Location& loc, uint findType)
uint LocationGetCritters (Location& loc, uint findType, array<Critter@>@ critters)
bool LocationHasItems (Location& loc, uint16 protoId)
uint LocationGetItems (Location& loc, uint16 protoId, array<Item@>@ items)
void LocationDeleteItems (Location& loc, uint16 protoId)


Code: [Select]
// Returns true if there is at least one Critter of given type inside Location.
//
bool LocationHasCritters (Location& loc, uint findType)
{
    array<Map@> maps;
    uint num = loc.GetMaps(maps);
    array<Critter@> critters;
    for (uint i = 0; i < num; i++)
    {
        if (maps[i].GetCritters(0, findType, critters) > 0)
        {
            return true;
        }
    }
    return false;
}

// Gets all Critters of given type inside Location.
//
uint LocationGetCritters (Location& loc, uint findType, array<Critter@>@ critters)
{
    array<Map@> maps;
    uint num = loc.GetMaps(maps);
    for (uint i = 0; i < num; i++)
    {
        maps[i].GetCritters(0, findType, critters);
    }
    return critters.length();
}

// Returns true if there is at least one Item with given protoId inside Location.
//
bool LocationHasItems (Location& loc, uint16 protoId)
{
    array<Map@> maps;
    uint num = loc.GetMaps(maps);
    array<Item@> items;
    for (uint i = 0; i < num; i++)
    {
        if (maps[i].GetItems(protoId, items) > 0)
        {
            return true;
        }
    }
    return false;
}

// Gets all items with given protoId inside Location.
//
uint LocationGetItems (Location& loc, uint16 protoId, array<Item@>@ items)
{
    array<Map@> maps;
    uint num = loc.GetMaps(maps);
    for (uint i = 0; i < num; i++)
    {
        maps[i].GetItems(protoId, items);
    }
    return items.length();
}

// Deletes all items with given protoId inside Location.
//
void LocationDeleteItems (Location& loc, uint16 protoId)
{
    array<Item@> items;
    LocationGetItems(loc, protoId, items);
    DeleteItems(items);
}
« Last Edit: February 06, 2013, 10:35:37 am by JovankaB »

Offline Gob

  • The Good
Re: [script] useful thingies
« Reply #2 on: February 06, 2013, 11:13:02 am »
Really nice of you to share scripts with us common mortals Jovi ^_^ thank you.

Re: [script] useful thingies
« Reply #3 on: February 09, 2013, 10:21:25 am »
Yeah, thanks for sharing Jovanka. I'll keep an eye open for such "utility functions" also. Unfortunately I think most of my stuff is too specific or requires a lot of other changes in order to work.

Here's a function to check whether a player has certain gear equipped. Can be useful if you're making some kind of TC script for example.

Code: [Select]
//returns true if cr have equipped items of tier at least gearTier
//Set checkHands=true to check for items in the hands, checkArmor=true to check for items worn.
//Set both to true to check for both.
bool critterHasGear(Critter& cr, int gearTier, bool checkHands, bool checkArmor)
{
if (!valid(cr) || gearTier <= 0)
return false;

if (checkHands)
{
Item@ weapon1 = cr.GetItem(0, SLOT_HAND1);
Item@ weapon2 = cr.GetItem(0, SLOT_HAND2);
if (!valid(weapon1) || weapon1.Proto.Tier < gearTier)
{
if (!valid(weapon2) || weapon2.Proto.Tier < gearTier)
return false;
}
}

if (checkArmor)
{
Item@ armor = cr.GetItem(0, SLOT_ARMOR);
if (!valid(armor) || armor.Proto.Tier < gearTier)
return false;
}

return true;
}

It requires you to bind a new variable to the ProtoItem class. You can do this by adding a line to _defines.fos, similar to this: (check the bottom part of _defines.fos, you'll find similar lines there)

Code: [Select]
# pragma bindfield "const uint16 ProtoItem::Tier  -> 316"

Take care though if you already added other lines like that before, the number that you bind to needs to be available.

Finally you also need to add a line to the relevant .fopro files of your items:

Code: [Select]
Tier=2
Obviously that sets the item to be tier 2. It is convenient to start counting at 0, since that is the default value and you can just leave that line out for all tier 0 items. So you'd have tier 0, tier 1 and tier 2, for example, rather than tier 1, tier 2 and tier 3.