Creating a waypoint on a placeable (RESOLVED)

Does anyone know a script or can help create a script for me:

That when I create a placeable it creates a waypoint with a specific tag name alongside the placeable.

And when the placeable is destroyed the waypoint is destroyed along with it.

Anyone?

Thanks

Here is the script I have so far. All I need to do is have the waypoint created with the placeable. And when the placeable is destroyed the waypoint is destroyed with it.

{
     effect eVis = EffectVisualEffect(VFX_FNF_SMOKE_PUFF);
object OM = CreateObject(OBJECT_TYPE_PLACEABLE,"rpetrick", GetSpellTargetLocation(), TRUE);
DelayCommand(0.5f, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, OM));
SendMessageToPC(OBJECT_SELF, "You have cast the Rope Trick spell.");
SendMessageToAllDMs(GetName(OBJECT_SELF) + " has cast the Rope Trick Spell.");


}

How is the placeable being destroyed? Is it by PC action? Script? Something else? And any reason not to use the placeable itself as a pseudo-waypoint?

Hi tinygiant,

Hey thanks for your interest in helping.

Well as you could probably guess. I did a “Rope Trick” spell

This is how I set it up:

The above script as you know creates the placeable (a rope). On the rope that appears I have a script on the onuse which ports me to a waypoint in a small enclosure on a tileset. Inside that tileset I have a rope placeable also.

So, I want the PC(s) to touch the rope placeable in the Rope Trick tileset (I would also have a script on the rope placeable on use to port to the waypoint that had been created) to port them back to the original place the rope was created (where a waypoint was created when the spell was cast) To make it look like they climbed back down the rope. But, I want the PC’s to destroy the rope after leaving it so no one else can use it. And when they destroy it ,…the waypoint is also destroyed with it so when I cast the rope trick spell again…it won’t port to that waypoint that was created in the previous spell cast.

Hope this makes sense…lol

Gotcha. Seems like a lot of extra work. I would recommend the following:

  • when the PC first touches the rope to go to the other end of the rope, either save the location of the rope or the object id of the rope into a local variable on the pc. Using the object id will make it easier to destroy when you return.
  • when the PC touches the rope to return, get the object id you saved and jump to that object instead of a waypoint.
  • destroy the object.

Here’s some snippets. Without seeing the rest of your code, I’m just guessing at some things, but you should be able to integrate this pretty easily without creating more waypoints.

So, in the OnUsed code for the rope placeable that the PC creates with the spell:

...
object oPC = GetLastUsedBy();
object oDestination = GetWaypointByTag("my_destination_waypoint");
SetLocalObject(oPC, "ROPE_SOURCE", OBJECT_SELF);
(... code to jump to oDestination and anything else you want to do here ...)

Then, when returning, in the OnUsed of the rope placeable at your tileset/destination:

...
object oPC = GetLastUsedBy();
object oDestination = GetLocalObject(oPC, "ROPE_SOURCE");
(... jump to oDestination however you're doing it ...)
DestroyObject(oDestination);
...

Note: These code snippets don’t check that the object still exists when the pc returns, nor will the variable be saved across resets…

lol…ugh…

I’m no scripter bud…you talk like to a scripter…I’m not.

I hack that bit of code above from a script to create a placeable…lol

I see the logic but I don’t know how to script it. I thought you would just add to the script above.

See below other script I found (hacked too…lol) that I use on the rope placeable when touched:

//:://////////////////////////////////////////////////////////////////////////////////
//::
//:: Trapdoor_open script -- simulates going through a trap door into another location
//:: >>This performs the PC interaction, the door opening animation and <<
//:: >>the actual translocation <<
//:: This script is placed in the OnUse Event of a trap door
//:: Assumes that the mod designer has created a "return door" in the
//:: Target location.  A waypoint can probably be used if so desired.  This
//:: WORKS when using a door.  The tag used here is "SecretPassageDoor", change
//:: this to whatever you put in the TAG of the target door.
//::
//:: by Will Greenway
//:://////////////////////////////////////////////////////////////////////////////////
void main()
{
   //::///////
   //:: Get the Opener
   //::///////
   object oPC = GetLastUsedBy();
   //::///////
   //:: Get the target location -- Change "SecretPassageDoor" to your desired target object
   //::///////
   location lLoc = GetLocation(GetObjectByTag("rpetrk",0));
   //::///////
   //:: Have the door itself wait for the PC to do the animation
   //::///////
   ActionWait(1.0);
   //:://////
   //::///////
   //:: Play the door opening sound
   //:://///
   PlaySound("as_cv_woodcreak1" );
   //:://////
   //:: Tell the PC to jump to location.
   //:: Note the DelayCommand is added so that
   //:: the jump isn't done while animations are in progress.
   //:://///
   AssignCommand(oPC, DelayCommand(1.0,JumpToLocation(lLoc)));
   //:://////

}

Wish I could find the rope noise to use rather than the wood creak sound “as_cv_woodcreak1”

I’d just be happy to keep it simple…well if it is simple.

Just have the initial script create a waypoint when the spell is cast. I then will add a name to that waypoint I create in the toolset to appear when the rope placeable is created it is created side by side.

On the inside I will have a script similar to port to the waypoint that was created…well I think that is simple enough.

I just don’t know how to create the waypoint with the placeable. AND…don’t know how to destroy the waypoint when you destroy the initial rope.

Hope this makes sense

What is the tag of the destination object rope placeable in your interior/tileset (the destination)? Also, is “reptrk” the resref of the rope placeable that is created when when the user casts the spell?

This is the destination interior of where you go when you touch the rope outside where it was created along with the waypoint tag. I hope this helps. Forgive me…this is propbably not as fancy as stuff you see out there by pros…lol

Rope placeable created:

rope created

Interior - better view:

So I would touch that rope in the interior to take me back to the original place the rope was created.

What is the tag of the repo placeable in the interior area (the one the player touches to go back)?

Would be extra cool to be able to look out of the interior to see below (like the original spell)…but that would probably be hard to script.

If I could script…I would do it like I have a script for a window. If the PC touches the window it creates an invisible copy of your PC outside (original place rope was cast) to see what is going on there. Like the old 2ed D&D spell. In that spell you could look down the hole in the middle of the floor to see what was going on down below. But that is too complicated.

Here it is “ropeback”

The complicated version would be to use the portal placeable (the glowing portal) to touch it to look down below.

Simple version is totally fine…not trying to create more work for you. I just thought that would be cool to add the other feature.

  • What’s the tag of the placeable rope in the interior area?
  • What’s the name of the script used for this spell?

The tag of the rope on the inside is: ropeback

The spell script name is: CS_S1_RopeTrik <---- this is the actual spell name on the spell 2da

or did you mean the spell script that would go here below? (I never had one)

Oy, capital letters. Never a good idea in nwn. But okay. Here’s a replacement script for your spell script. Add this and fire off the spell and see if it all works. No other setup required, assuming the spellscript is assigned in your spells.2da.

Again, I have not tested this, so keep a copy of your old script just in case. There’s a bunch of debugging statements just in case. If it doesn’t work, let me know what the statements say. If it does work, set DEBUG_ME to FALSE and recompile.

string THIS = "CS_S1_RopeTrik";

int DEBUG_ME = TRUE;
void debug(object o, string s)
{
    if (DEBUG_ME) SendMessageToPC(o, s);
}

void _JumpToExterior(object oPC)
{
    object oTarget = GetLocalObject(oPC, "ROPE_SOURCE");
    if (!GetIsObjectValid(oTarget))
    {
        debug(oPC, "Could not find source rope");
        return;
    }

    debug(oPC, "Jumping PC back to original location");
    AssignCommand(oPC, DelayCommand(1.0, JumpToObject(oTarget)));
    DestroyObject(oTarget);
}

void _JumpToInterior(object oPC)
{
    object oTarget = GetWaypointByTag("rpetrk");
    if (!GetIsObjectValid(oTarget))
    {
        debug(oPC, "Could not find valid destination with tag `rpetrk`");
        return;
    }

    debug(oPC, "Jumping PC back to interior location");
    AssignCommand(oPC, DelayCommand(1.0, JumpToObject(oTarget)));
}

void _CastSpell()
{
    object oPC = GetLastSpellCaster();
    if (!GetIsPC(oPC) || !GetIsObjectValid(oPC))
    {
        debug(GetFirstPC(), "Unable to find valid PC for ropetrick");
        return;
    }

    object oRope = CreateObject(OBJECT_TYPE_PLACEABLE, "rpetrick", GetSpellTargetLocation(), TRUE, "ropetrick_source");
    object oTarget = GetObjectByTag("ropeback");
    
    if (!GetIsObjectValid(oRope)) debug(oPC, "Unable to create rope placeable");
    if (!GetIsObjectValid(oTarget)) debug(oPC, "Unable to find destination placeable");
    
    DelayCommand(0.5f, ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_SMOKE_PUFF), oRope));
    SetEventScript(oRope, EVENT_SCRIPT_PLACEABLE_ON_USED, THIS);
    SetEventScript(oTarget, EVENT_SCRIPT_PLACEABLE_ON_USED, THIS);
    SetLocalObject(oPC, "ROPE_SOURCE", oRope);
    SendMessageToPC(OBJECT_SELF, "You have cast the Rope Trick spell.");
    SendMessageToAllDMs(GetName(OBJECT_SELF) + " has cast the Rope Trick Spell.");
}

void main()
{
    int n = GetCurrentlyRunningEvent();
    if (n == 0) n = GetCurrentlyRunningEvent(FALSE);

    if (n == EVENT_SCRIPT_PLACEABLE_ON_USED)
    {
        object oPC = GetLastUsedBy();
        if (!GetIsPC(oPC) || !GetIsObjectValid(oPC))
        {
            debug(GetFirstPC(), "Unable to find valid PC for ropetrick");
            return;
        }

        string sTag = GetTag(OBJECT_SELF);
        if (sTag == "ropetrick_source")
            _JumpToInterior(oPC);
        else if (sTag == "ropeback")
            _JumpToExterior(oPC);
        else
            debug(oPC, "CS_S1_RopeTrik called without valid placeable");
    }
    else 
        _CastSpell();
}