Skip to content

Check if PC is nearby?

When a creature spawns I need to check if the PC can see the creature that just spawned. Essentially the PC is trying to figure out where all these rats are coming from and there are several locations they can camp to wait and see if rats are coming from that location. So if the rats are already spawned then the PC can't learn anything. But if the PC is nearby and can observe the rats coming out then I need stuff to happen.

My problem is that I don't know how to check all nearby objects and see if PC is one of them. These rats are being spawned with a script that's running on a timer so would it be better to slip this code in there instead of the rat's onSpawn?

Comments

  • ProlericProleric Member Posts: 1,310
    Given the rule "if the rats are already spawned then the PC can't learn anything", OnSpawn is the right place.

    In single player, GetObjectSeen() using GetFirstPC() will tell you whether the PC can see the spawn or not.

    In multiplayer, cycle through the PCs using GetFirstPC() / GetNextPC().

    If you want to specify a maximum distance e.g. 20m or whatever, instead of whether the PC sees the spawn, GetDistanceBetween() the PC and OBJECT_SELF (the spawning rat) will tell you whether the PC is "nearby" or not.

    If you ever need to check all nearby objects, GetNearestObject() is the function to use. Not necessary in this special case, where the object is a PC.
  • ProlericProleric Member Posts: 1,310
    edited August 30
    On reflection, you will need to test GetObjectSeen. I'm not quite sure whether that function uses the table of creatures the PC can see, or, if so, whether it's updated on spawn. There might be a slight delay before the PC sees the rat.

    The distance check will work, but you might want to add refinements e.g. LineOfSightObject().
  • ForSeriousForSerious Member Posts: 455
    edited September 5
    Another way to do it could be: draw a trigger and check to see the the PC (or any PC) is in the area of the trigger on spawn.
  • Dragonfolk2000Dragonfolk2000 Member Posts: 383
    edited September 29
    Stuff happened so I couldn't come back to this sooner but here's what I got. This seems to work?

    Update: this is line of sight, even if the player can't actually SEE the rats. So I need to readdress this.
    object oPC = GetFirstPC();
    
        int gotSeen = 0;
    
        while(GetIsObjectValid(oPC))
        {
            if(GetLocalInt(oPC,"seeRatCheck") != 1)
            {
                if(LineOfSightObject(OBJECT_SELF,oPC))
                {
                    gotSeen = 1;
                    SendMessageToPC(oPC,"You saw the rat crawl out of a sewer drain. Maybe the Ratromancer's lair is in there?");
                }
                SetLocalInt(oPC,"seeRatCheck",1);
            }
    
            oPC = GetNextPC();
        }
    
        oPC = GetFirstPC();
    
        while(GetIsObjectValid(oPC))
        {
            if(GetLocalInt(oPC,"seeRatCheck") == 1)
            {
                SetLocalInt(oPC,"seeRatCheck",0);
            }
    
            oPC = GetNextPC();
        }
    
  • Dragonfolk2000Dragonfolk2000 Member Posts: 383
    Okay, here is the working version of the code. It also has a spot check included based on the distance between the spawning rat and the PC. I don't know if this works in multiplayer yet. Yes, I really did have to look up how to calculate distance between two objects in a 3d space.

    object oPC = GetFirstPC();
    
        int gotSeen = 0;
    
        vector ratVec = GetPosition(OBJECT_SELF);
    
        while(GetIsObjectValid(oPC))
        {
            if(GetLocalInt(oPC,"seeRatCheck") != 1 && GetLocalInt(oPC,"spottedRat") != 1)
            {
                int spotRat = 0;
    
                vector pcVec = GetPosition(oPC);
    
                float dist = sqrt(((pcVec.x - ratVec.x)*(pcVec.x - ratVec.x))+((pcVec.y - ratVec.y)*(pcVec.y - ratVec.y))+((pcVec.z - ratVec.z)*(pcVec.z - ratVec.z)));
    
                int spotDC = FloatToInt(dist);
    
                int skillTotal = GetSkillRank(14, oPC, FALSE);
    
                if((skillTotal + d20()) >= spotDC)
                {
                    spotRat = 1;
                }
    
                if(LineOfSightObject(OBJECT_SELF,oPC) && spotRat ==1)
                {
                    gotSeen = 1;
                    SendMessageToPC(oPC,"You spotted some rats crawl out of a sewer drain. Maybe the Ratromancer's lair is in there?");
                    SetLocalInt(oPC,"spottedRat",1);
                }
                SetLocalInt(oPC,"seeRatCheck",1);
            }
    
            oPC = GetNextPC();
        }
    
        oPC = GetFirstPC();
    
        while(GetIsObjectValid(oPC))
        {
            if(GetLocalInt(oPC,"seeRatCheck") == 1)
            {
                SetLocalInt(oPC,"seeRatCheck",0);
            }
    
            oPC = GetNextPC();
        }
    
  • ForSeriousForSerious Member Posts: 455
    I think they have built-in distance functions…
  • Dragonfolk2000Dragonfolk2000 Member Posts: 383
    Well NOW I know that.
  • ProlericProleric Member Posts: 1,310
    For example, GetDistanceBetweenObjects().

    In the toolset, if you filter functions for "distance", you'll see two more functions of that sort.

    The Lexicon is also searchable.
  • ForSeriousForSerious Member Posts: 455
    There's nothing wrong with learning a little math. I'm just too lazy to try and look actual formulas up, so I'll try to get out of it by seeing if it's already been done.
Sign In or Register to comment.