Skip to content

Stop Monsters from passing through Transitions

How do we stop monsters from following players through transitions while allowing summoned pets or familiar? I see there is a Faction "Hostile" in the Advanced Tab of the creature properties.
if(!GetIsPC(GetEnteringObject()))
{
  object oMob= GetEnteringObject();	
  string faction = GetFaction(oMob);	//Is there a function to get the Faction name?

	 if(faction == "Hostile")
	 {
		DestroyObject(oMob);
	 }	

}



Unless there is a far more simple way to solve this.

Comments

  • ProlericProleric Member Posts: 1,281
    The default script for area transitions is nw_g0_transition. If you want to stop all creatures other than PCs and their party, make a custom version beginning
        if (!GetIsPC(oClicker))
          if (!GetIsPC(GetMaster(oClicker)))
             if (!GetIsPC(GetMaster(GetMaster(oClicker))))
               return;
    
    This will leave the monsters on the other side of the door. You can destroy oClicker if you prefer.

    This works regardless of faction. The only non-party creatures that use doors are (a) those hostile to a PC or (b) those scripted to walk across areas (which require a further condition above if you have them).

    If you prefer to filter on faction, be aware that in classic NWScript there is no way to get the faction directly. A common trick is to put a benchmark member of each faction in an inaccessible area with a tag like FactionHostile or whatever. I use CEP armour stands for this purpose so that they don't start fighting each other. Then you can use GetFactionEqual to determine whether a creature belongs to the same faction as the benchmark.

    EE now allows you to read the fields in the creature .utc file directly, using TemplateToJson() and the GFF functions. However, I would be wary of manipulating faction directly, because classic NWN was never designed to do that. In particular, assigning constants to custom factions should be avoided, as the values can change if you delete a faction in the toolset.
  • BuddywarriorBuddywarrior Member Posts: 62
    object oClicker=GetClickingObject(); is a big help. Thanks as always Proleric.
  • ProlericProleric Member Posts: 1,281
    For completeness, I should perhaps add that the TemplateToJson() method only allows you to examine the template for the creature resref - the actual faction of the creature instance might have been changed in the toolset or by script, though of course that is under builder control.
  • KamirynKamiryn Member Posts: 74
    edited October 2021
    In EE JsonGetInt(JsonPointer(ObjectToJson(oCreature), "/FactionID/value"))-1 should give you oCreature's faction ID.

    [edit]Fixed error: JsonToObject() is ObjectToJson() of course. And it's JsonGetInt() and not JsonToInt().[/edit]
    Post edited by Kamiryn on
  • ProlericProleric Member Posts: 1,281
    Is that right? Surely JsonToObject takes a Json argument, not an object?

    I was thinking, for example,
    #include "nw_inc_gff"
    
    void main()
    {
    json   jNPC = TemplateToJson("x3_hummount001", RESTYPE_UTC);
    
    Int nFaction  = GffGetWord(jNPC, "FactionID") - 1;
    }
    
  • KamirynKamiryn Member Posts: 74
    Proleric wrote: »
    Is that right? Surely JsonToObject takes a Json argument, not an object?
    JsonToObject() should be ObjectToJson().

  • ProlericProleric Member Posts: 1,281
    OK that makes perfect sense, and overcomes the issue about template v instance that I mentioned.

    Does the Json returned by ObjectToJson() work with the Gff functions?

    The Lexicon documentation isn't at all clear, as it has a broken link to @niv's nimtools (which I have to admit I don't understand anyway).

    If so, GffGetWord() is arguably more legible, especially for those of us who are familiar with GFF edits.

  • KamirynKamiryn Member Posts: 74
    Proleric wrote: »
    Does the Json returned by ObjectToJson() work with the Gff functions?
    Yes.
    If so, GffGetWord() is arguably more legible, especially for those of us who are familiar with GFF edits.

    json GffGetWord(json jGff, string sLabel)

    is a wrapper for GffGetField(jGff, sLabel, GFF_FIELD_TYPE_WORD) with
    json GffGetField(json jGff, string sLabel, string sType)
    {
        json jType = GffGetFieldType(jGff, sLabel);
        if (jType == JsonNull())
            return jType;
        else if (jType != JsonString(sType))
            return JsonNull("field type does not match");
        else
            return GffGetFieldValue(jGff, sLabel);
    }
    

    where GffGetFieldType(json jGff, string sLabel) and GffGetFieldValue(json jGff, string sLabel) are wrappers for JsonPointer(jGff, "/" + sLabel + "/type") and JsonPointer(jGff, "/" + sLabel + "/value").

    So yes, you can use GffGetWord() but it has a lot of overhead (all the type checking) and working with jsons isn't really fast anyway. So I try to avoid the functions from the gff library. In my mod I have to read 19*6=114 values to check whether two items have different colors and it's really noticeable if you have 228 calls to JsonPointer() or only 114 (actually I work with JsonDump() and string checks because that even faster :D).

    But if you want to use the library instead of GffGetWord() you could use GffGetFieldValue(). It's faster and it doesn't care if you're reading a byte, an int, a word or a dword.


  • ForSeriousForSerious Member Posts: 446
    edited October 2021
    The old Lala Land server had something in place to stop monsters from following hasted players all over the server. I'm not sure if this is the way they did it, but there were some ways to get around it. In the same way that you can (could) select that you want to barter with a player that's running away from you, and your character will follow them even through transitions. Monsters would also do that by selecting to do something like Ki Damage or Smite Good on you.
    Just something to maybe be aware of.
Sign In or Register to comment.