Aller au contenu

Photo

Perception and range


  • Veuillez vous connecter pour répondre
6 réponses à ce sujet

#1
Jereniva

Jereniva
  • Members
  • 114 messages

In the ranges.2da, I found the distances for the different "perception" settings on a creature.

Most creatures have Perception set at default. What does default mean?

 

Also each range defined has a primary and secondary, when does second come in to play?

 

What I was playing around with was in a container's disturbed event, if the owner of the container was within range of the container, based on his perception rating, he'd react to the PC disturbing the container.

Example, Short perception is 10 meters. If PC opens the chest while NPC is 11 meters away, he does not notice, 10 meters or less and he reacts.

 

I can do all of it except get the Perception Range property of an NPC.

How do you you get that property off the NPC object?

Am I correct that Last perceived heard and seen occur as objects enter within the range of that setting?



#2
kevL

kevL
  • Members
  • 4 052 messages
things i notice:

- range_default seems to be same as range_medium
- no scripted constants; NPC properties uses row# from Ranges.2da
- can't find a getter, eg GetPerceptionRange() doesn't exist.

- from Ranges.2da

Rich Taylor: Primary Range is the Spot range (Visual range) Secondary Range is the Listen range (Hearing range).


ah,

If something is flagged as PercepRngDefault, instead of reading the values from the columns on that row, it looks up the creature's appearance in Appearance.2da and uses the PERCEPTIONDIST column to find out what row creatures with that appearance are supposed to use. PERCEPTIONDIST in Appearance.2da should reference back to a row in Ranges.2da from which to read the values in from.


What I was playing around with was in a container's disturbed event, if the owner of the container was within range of the container, based on his perception rating, he'd react to the PC disturbing the container.
Example, Short perception is 10 meters. If PC opens the chest while NPC is 11 meters away, he does not notice, 10 meters or less and he reacts.

I can do all of it except get the Perception Range property of an NPC.


if (GetObjectSeen(oTarget) == TRUE)

that should test the value you're looking for. basically ...
  • Jereniva aime ceci

#3
Jereniva

Jereniva
  • Members
  • 114 messages

GetObjectSeen seems to work if NPC is *not* moving, but doesn't work if he is moving.

 

Non-moving NPC, short perception range, chest 5 meters away and he says "Hey, leave my 'Item' alone!" 

Non-moving NPC, short perception range, chest 15 meters away and he does not notice me steal his entire collection of nymph hair.

Perfect!

 

But, I now put a pair of waypoints, and using completely untouched standard WalkWaypoint or whatever is already default, I put one way point next to chest, and another 15 feet away.

The distance between object and owner text fires but even with distances under 10, and me stealing all his goods, he never says "hey, leave my item alone"

 

Does WalkWaypoint change the way Perception works?

 

Also, I notice that gold never produces any text for either GetName or GetTag, when calling GetInventoryDisturbItem

void main()

{
object oPC = GetLastDisturbed();
string sOwnd = GetLocalString(OBJECT_SELF, "sOwner");
object oOwner = GetObjectByTag(sOwnd);
int nSeen = GetObjectSeen(oPC, oOwner);
string sItem = GetName(GetInventoryDisturbItem());
float fDist = GetDistanceBetween(oOwner, OBJECT_SELF);

SendMessageToPC(oPC, "Distance between object and owner is: " + FloatToString(fDist,18,0) + " meters.");

    if (nSeen == TRUE)
    {
        AssignCommand(oOwner,ActionSpeakString("Hey, leave my " + sItem + " alone!"));
    }
}


#4
Dann-J

Dann-J
  • Members
  • 3 161 messages

Gold ceases to exist as an item once you pick it up. Since the inventory disturb event fires *after* you've acquired it, there won't be an item remaining to get any information about.

 

You could have the chest's OnOpen script store the opener's current gold amount as a local variable on the chest, then have the chests's OnInventoryDisturbed script check that variable against the opener's gold amount. If it doesn't match then the opener must have taken gold from the chest (since you can't give gold *to* the chest).


  • GCoyote et Jereniva aiment ceci

#5
kevL

kevL
  • Members
  • 4 052 messages
try putting in,

AssignCommand(oOwner, ClearAllActions());

just before ActionSpeakString()


Jereniva, you should download and unzip
http://neverwinterva...wn-lexicon-v169

it's for NwN1, but 90% of it's the same. Or use the online version (I like having it on my desktop quickbar, tho). Here's what it says about GetInventoryDisturbItem() and gold:
 

It has been previously noted that the event OnDisturbed does not fire when the item being disturbed is gold. ...


Apparently it also has problems with stackable items. so, Special handling would be required in the onOpen and onHB scripts -- eg. count the gold onOpen, store the value and have the heartbeat check if it changes, then do a fudge that assumes GetNearestPC ( or as Dj says, GetLastOpenedBy() ) is the target

less than optimal, but i think that's what would need to be done for gold (or something similar for stackable items).
  • Jereniva aime ceci

#6
kevL

kevL
  • Members
  • 4 052 messages
it's not as fudgy as i expected ...

these two scripts, onOpened & onDisturbed, should deal with gold as well as individual items (but not other stacks)

onOpened:
// 'jer_opened'
//
// Counts amount of gold in a container when it's opened.
// Place in the onOpened event.


// Counts gold in container.
int GetGoldQuantity();

//___________
// ** MAIN **
void main()
{
    int iGold = GetGoldQuantity();
    SetLocalInt(OBJECT_SELF, "gold", iGold);
}


// Counts gold in container.
int GetGoldQuantity()
{
    int iGold = 0;

    object oGold = GetFirstItemInInventory();
    while (GetIsObjectValid(oGold))
    {
        if (GetTag(oGold) == "nw_it_gold001")
            iGold += GetItemStackSize(oGold);

        oGold = GetNextItemInInventory();
    }

    return iGold;
}

onDisturbed:
// 'jer_disturb'
//
// Causes proprieter of a container to react to removed/stolen contents.
// Place in the onDisturbed event.


// Counts gold in container.
int GetGoldQuantity();

//___________
// ** MAIN **
void main()
{
    switch (GetInventoryDisturbType())
    {
        case INVENTORY_DISTURB_TYPE_REMOVED:
        case INVENTORY_DISTURB_TYPE_STOLEN:
        {
            object oPC = GetLastDisturbed(); // disturber

            string sProprietor = GetLocalString(OBJECT_SELF, "sOwner");
            object oProprietor = GetObjectByTag(sProprietor); // proprietor

            float fDist = GetDistanceBetween(oProprietor, OBJECT_SELF);
            SendMessageToPC(oPC, "Distance between object and owner is: " + FloatToString(fDist,18,0) + " meters.");

            if (GetObjectSeen(oPC, oProprietor))
            {
                string sItem;

                int iGold = GetGoldQuantity();
                if (iGold < GetLocalInt(OBJECT_SELF, "gold"))
                {
                    SetLocalInt(OBJECT_SELF, "gold", iGold);
                    sItem = "gold";
                }
                else
                    sItem = GetName(GetInventoryDisturbItem()); // disturbed item

                AssignCommand(oProprietor, ClearAllActions());
                AssignCommand(oProprietor, ActionSpeakString("Hey, leave my " + sItem + " alone!"));
            }
        }
    }
}


// Counts gold in container.
int GetGoldQuantity()
{
    int iGold = 0;

    object oGold = GetFirstItemInInventory();
    while (GetIsObjectValid(oGold))
    {
        if (GetTag(oGold) == "nw_it_gold001")
            iGold += GetItemStackSize(oGold);

        oGold = GetNextItemInInventory();
    }

    return iGold;
}

  • Jereniva aime ceci

#7
Jereniva

Jereniva
  • Members
  • 114 messages

This is perfect, thank you Kev for your script, and Dann for the tip about gold