Aller au contenu

Photo

Jump player back to location before overland encounter happens?


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

#1
Ugly_Duck_01

Ugly_Duck_01
  • Members
  • 69 messages
I'm trying to figure out a way to jump the player back to the location they were at BEFORE the overland encounter happened.  Any help would be great.  I cant script well, so if you could provide a script, that would be great too.  thanks in advance!

#2
Ugly_Duck_01

Ugly_Duck_01
  • Members
  • 69 messages
Also, need to destroy the NPC starting the Encounter Conversation.

#3
Tchos

Tchos
  • Members
  • 5 042 messages
Destroying an NPC during a conversation with that same NPC will break the conversation and its scripts, so you should do that through another means. You could add a line in the area's On Exit script, for instance, to destroy the NPC when the player is jumped out.

To go back to the location where you were, you can store the location, waypoint, or whatever you're using, as a local variable on the PC when they enter the encounter, and then have the conversation check that variable when it's time to jump back.

Modifié par Tchos, 20 février 2014 - 05:32 .


#4
Ugly_Duck_01

Ugly_Duck_01
  • Members
  • 69 messages
Thank you Tchos. Any idea on how to script that?

#5
Tchos

Tchos
  • Members
  • 5 042 messages
Well, I don't know how you're handling the transition to the encounter.  Is the encounter at a static location, with a waypoint marking where you should reappear after the encounter?  Is it a dynamic one like SoZ's wandering monsters on the overland map?  Let's say it's the latter, and the monsters initiate the transition with a conversation.

Something like this.  These are two scripts.  The first one takes a parameter in a conversation, and the other doesn't need one.

// Create a waypoint to return to after encounter, and save it as a local object to retrieve later.

#include "ginc_worldmap"
void main(string sEncounterWP)
{
    object oPC = GetFirstPC();
   
    object oReturnWP = CreateObject(OBJECT_TYPE_WAYPOINT, "nw_waypoint001", GetLocation(oPC), FALSE, "tp_return");
    SetLocalObject(oPC, "ReturnWP", oReturnWP);
    JumpParty(oPC, GetObjectByTag("sEncounterWP"));
}


// Return to saved waypoint

#include "ginc_worldmap"
void main()
{
    object oPC = GetFirstPC();  
    object oWP = GetLocalObject(oPC, "ReturnWP", oReturnWP);

    JumpParty(oPC, oWP);

    DeleteLocalObject(oPC, "ReturnWP");
}

Modifié par Tchos, 20 février 2014 - 01:17 .


#6
Dann-J

Dann-J
  • Members
  • 3 161 messages
This is a cut-down version of a conversation script I'm using to lay down a return waypoint and jump the party to an overland encounter area. I've removed a heap of encounter-related code. The exit from the encounter area links back to the return waypoint (wherever it may be). The waypoint tags are all hardcoded, but it would be easy enough to make them customisable via the conversation node.

#include "ginc_group"

void main()
{
object oPC = GetPCSpeaker();
object oWP = GetObjectByTag("olmenc_in");// destination waypoint to jump to

object oOldWP = GetObjectByTag("olmenc_out");// remove any previous return waypoint
DestroyObject(oOldWP);

location lLoc = GetLocation(oPC);// create a new return waypoint
CreateObject(OBJECT_TYPE_WAYPOINT, "nw_waypoint001", lLoc, FALSE, "olmenc_out");

string sGroupName = "Party_Jump_Group";// jump the party to the overland encounter area
ResetGroup(sGroupName);
GroupAddFaction(sGroupName, oPC, GROUP_LEADER_FIRST, TRUE);
GroupSetScriptHidden(sGroupName, 0);
GroupSetLineFormation(sGroupName, 2.0);
GroupSetNoise(sGroupName, 0.0f, 10.0f, 0.5f);
DelayCommand(0.1, GroupJumpToWP(sGroupName, "olmenc_in"));
}

Modifié par DannJ, 20 février 2014 - 01:55 .


#7
Tchos

Tchos
  • Members
  • 5 042 messages
It occurs to me that with the method I proposed you would also need to include some code (probably in your area On Enter script) to clean up the waypoint left behind by the encounter, so that you're not adding more waypoints to the area every time you have an encounter, if it's going to be a frequent occurrence. In that case, you should remove the line that deletes the local object from the PC, and move the line to the area On Enter script, to be executed only after the area On Enter script has destroyed the waypoint itself.

Modifié par Tchos, 20 février 2014 - 05:31 .


#8
Loki_999

Loki_999
  • Members
  • 430 messages
Is there a reason you guys are creating waypoint objects rather than just storing the location directly?

You already know the location, so just store that, then use ActionJumpToLocation.... aaahh, unless party members will not follow with this...?

#9
Tchos

Tchos
  • Members
  • 5 042 messages
Well, I'm using a ready-made function to jump the whole party (Dann is too, but a different one), and it takes an object rather than a location. All of the whole-party functions I have on hand use object references instead of locations, so I admit I didn't think of doing it that way. It could certainly be done with a location, but you'd have to put in a loop to jump each of the party members to the location.

#10
Ugly_Duck_01

Ugly_Duck_01
  • Members
  • 69 messages
I'm using this script to have a wandering NPC creature detect, via perception script, then start a convo. with the player:

//Goes OnPerceived of a creature
//** This script makes the creature follow the player, then starts a
// conversation with the player.
void main()
{

object oPC = GetLastPerceived();

if (!GetIsPC(oPC)) return;

if (!GetLastPerceptionSeen()) return;
ActionForceFollowObject(oPC);

ClearAllActions();

object oTarget;
oTarget = GetObjectByTag("CREATURE_TAG_HERE");

AssignCommand(oTarget, ActionStartConversation(oPC, "CONVERSATION HERE"));

}

Then... via conversation, im having the player jump to the random encounter map, and destroy the creature that started the conversation.

All this works, I just don't know how to save the location prior to jumping to random encounter map.

EDIT: Also need a way to clean up the encounter area after PC leaves.  Bags, dropped items, corpses, etc.

Thanks again guys!

Modifié par Ugly_Duck_01, 20 février 2014 - 01:46 .


#11
Tchos

Tchos
  • Members
  • 5 042 messages

Ugly_Duck_01 wrote...
All this works, I just don't know how to save the location prior to jumping to random encounter map.

But you do now, right?  There are two methods posted above.

#12
Ugly_Duck_01

Ugly_Duck_01
  • Members
  • 69 messages
Tchos, where do I put the scripts you made?

#13
Tchos

Tchos
  • Members
  • 5 042 messages
The first one is a ga_ script. You copy it into a new script, name it ga_something, and then fire it through a conversation.  In the conversation, when you add the script, you'll need to write in the tag of the encounter area's entry waypoint in the field that shows up like any ga_ script.

The second one can be called anything, and fired from anywhere -- a conversation, a placeable's On Used slot, a creature's On Death slot, whatever.

Modifié par Tchos, 21 février 2014 - 06:45 .


#14
Ugly_Duck_01

Ugly_Duck_01
  • Members
  • 69 messages
Tchos, the first script works, but the second doesn't - it won't compile either. I was gonna put that on the area transition to get the player back to the saved location the 1st script saved. Thanks agan for everyone's help!

#15
Tchos

Tchos
  • Members
  • 5 042 messages
Oops, it contained an error in the "GetLocalObject".  Here's the corrected version.

// Return to saved waypoint

#include "ginc_worldmap"
void main()
{
    object oPC = GetFirstPC();  
    object oWP = GetLocalObject(oPC, "ReturnWP");

    JumpParty(oPC, oWP);

    DeleteLocalObject(oPC, "ReturnWP");
}

#16
Ugly_Duck_01

Ugly_Duck_01
  • Members
  • 69 messages
Tchos! It worked perfectly!! Thanks a load!
Any chance you know how to add a clean-up routine to that? Clear the area of all corpses, bags, and items?

#17
Ugly_Duck_01

Ugly_Duck_01
  • Members
  • 69 messages
You scripters are amazing creatures! I have no scripting skills, so this is like magic to me!

#18
Tchos

Tchos
  • Members
  • 5 042 messages

Ah yes, that would be a good place to add in the cleanup of the waypoint, too.  This will require another small modification to the script I just posted.  Use this one instead.

// Return to saved waypoint

#include "ginc_worldmap"
void main()
{
    object oPC = GetFirstPC(); 
    object oWP = GetLocalObject(oPC, "ReturnWP");

    // Sets down a marker for another script to use to send in the cleanup crew.
    object oCleanupWP = CreateObject(OBJECT_TYPE_WAYPOINT, "nw_waypoint001", GetLocation(oPC), FALSE, "wp_cleanup_marker");

    JumpParty(oPC, oWP);
}

Now for the cleanup.  The bulk of this is adapted from an SoZ script, made to work with this setup.  It will destroy creatures (living and dead), items on the ground, any area of effect objects, and placeables containing items.  I haven't tested this, but it compiled successfully.

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Clean up.  Attach this script to the original area's On Client Enter script slot (original area as opposed to the random encounter map).  If you already have a Client On Enter script attached to the original area, then just copy the parts within the void main() {      } to your current script.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "ginc_overland"
void main()
{
    object oCleanupWP = GetObjectByTag("wp_cleanup_marker");

    if (GetIsObjectValid(oCleanupWP))
    {
        object oPC = GetFirstPC(); 
        int nEnemy = 1;
        int nItem = 1;
        int nPlaceable = 1;
        int nAoE = 1;
   
        object oGroundItem = GetNearestObject(OBJECT_TYPE_ITEM, oCleanupWP, nItem);
        object oCreature = GetNearestCreature(CREATURE_TYPE_IS_ALIVE,CREATURE_ALIVE_BOTH, oCleanupWP, nEnemy);
        object oPlaceable = GetNearestObject(OBJECT_TYPE_PLACEABLE, oCleanupWP, nPlaceable);
        object oAoE = GetNearestObject(OBJECT_TYPE_AREA_OF_EFFECT, oCleanupWP);
   
        /*    Destroy any hostile creatures which are still alive.    */
        while(GetIsObjectValid(oCreature))           
        {
            if(!GetFactionEqual(oCreature, oPC))    //Don't delete members of the Player Faction, because that will make the player sad.
            {
                PrettyDebug("Removing remaining creatures.");
                object oItem = GetFirstItemInInventory(oCreature);
                while(GetIsObjectValid(oItem))
                {
                    PrettyDebug("Removing Item from Creature");
                    DestroyObject(oItem, 0.2f);
                    oItem = GetNextItemInInventory(oCreature);
                }
                DestroyObject(oCreature, 0.5f);
            }
            nEnemy++;
            oCreature = GetNearestCreature(CREATURE_TYPE_IS_ALIVE,CREATURE_ALIVE_BOTH, oCleanupWP, nEnemy);
        }

        /*    Destroy all items which are lying on the ground.    */   
        while (GetIsObjectValid(oGroundItem))
        {
            PrettyDebug("Removing trash.");
            DestroyObject(oGroundItem, 0.5f);
            nItem++;
            oGroundItem = GetNearestObject(OBJECT_TYPE_ITEM, oCleanupWP, nItem);
        }
   
        /*    Destroy any Placeables containing items    */
        while (GetIsObjectValid(oPlaceable))
        {
            if(GetHasInventory(oPlaceable))
            {
                object oItem = GetFirstItemInInventory(oPlaceable);
                while(GetIsObjectValid(oItem))
                {
                    PrettyDebug("Removing Item from Placeable Container");
                    DestroyObject(oItem, 0.2f);
                    oItem = GetNextItemInInventory(oPlaceable);
                }
           
                PrettyDebug("Removing placeable with inventory.");
                DestroyObject(oPlaceable, 0.5f);
            }
       
            nPlaceable++;
            oPlaceable = GetNearestObject(OBJECT_TYPE_PLACEABLE, oCleanupWP, nPlaceable);
        }
   
        while(GetIsObjectValid(oAoE))
        {
            object oAoECreator = GetAreaOfEffectCreator(oAoE);
            if( GetFactionEqual(oAoECreator, oCleanupWP) == FALSE || GetAreaOfEffectDuration(oAoE) != DURATION_TYPE_PERMANENT )
            {
                PrettyDebug("Removing AoE.");
                DestroyObject(oAoE, 0.5f);
            }
            nAoE++;
            oAoE = GetNearestObject(OBJECT_TYPE_AREA_OF_EFFECT, oCleanupWP, nAoE);
        }

        // Finally, delete the waypoints we created.
        object oReturnWP = GetLocalObject(oPC, "ReturnWP");
        DestroyObject(oCleanupWP, 5.0f);
        DestroyObject(oReturnWP, 5.0f);
        DeleteLocalObject(oPC, "ReturnWP");
    }
}


#19
Ugly_Duck_01

Ugly_Duck_01
  • Members
  • 69 messages
Tchos... you are AWESOME! Thanks so much for your help. All the scripts work, and do what I need them to do!

Just a quick question: if I have multiple random encounter maps (where the player fights monsters), how do I make the player jump to them randomly. Example: When a zombie attacks the player on the overland map, transport the party to a graveyard encounter. versus an ogre, transport them to a mountainous region?

#20
Tchos

Tchos
  • Members
  • 5 042 messages

I appreciate the enthusiastic response.  :)

Hmm, probably something like this added to the script that sends them to the map, replacing just the plain JumpParty() line from before.  This assumes you're firing the script from a conversation.

// If this conversation is fired by an enemy, then OBJECT_SELF is that enemy.
object oEnemy = OBJECT_SELF;
int iRace = GetSubRace(oEnemy);
string sEncounterMap;

   switch ( iRace )
    {

        case RACIAL_SUBTYPE_GIANT:    // Ogres are giants
            sEncounterMap = "mountain_map";
            break;

        case RACIAL_SUBTYPE_UNDEAD:    // Zombies
            sEncounterMap = "graveyard_map";
            break;

        case 300:    // other racial subtypes as needed.
            break;

        case 400:    //
            break;

        case 500:    //
            break;
   
    object oPC = GetPCSpeaker();
    JumpParty(oPC, GetObjectByTag(sEncounterMap));

    }


#21
Ugly_Duck_01

Ugly_Duck_01
  • Members
  • 69 messages
Cool, but I don't understand how to implement that script. Where do I put it? In a conversation like the "ga_whatever" script?

#22
kamal_

kamal_
  • Members
  • 5 240 messages
The Northern Cormyr map on the Vault is a fully functional OM. No need to reinvent the wheel.

#23
Ugly_Duck_01

Ugly_Duck_01
  • Members
  • 69 messages
I examined the N. Cormyr map like you suggested. But the scripts and waypoints doesn't make much sense to me. I need someone to explain things; I need instruction..

#24
Tchos

Tchos
  • Members
  • 5 042 messages

Ugly_Duck_01 wrote...
Cool, but I don't understand how to implement that script. Where do I put it? In a conversation like the "ga_whatever" script?

If you used the ga_ script I wrote before, you put it in there, replacing the single JumpParty() line with the new block of code.

That Cormyr map looks like it could be useful.  I haven't looked at that one, but I have examined the Storm of Zehir overland map pretty thoroughly.

#25
Ugly_Duck_01

Ugly_Duck_01
  • Members
  • 69 messages
I've checked the cormyr map and the OM's from SoZ, but I cannot figure out how to spawn fightable creatures from the overland conversations.