Skip to content

Copy Area Transition

Trying to instance player housing. I have been messing with this for far too long and cannot get it to work. Any insights would be great. playerhouse is the name and tag of the house area.
void main()
{
object oPC = GetPCSpeaker();
string spc = GetName(oPC);
object oArea = GetObjectByTag("playerhouse");
int iexist = GetIsObjectValid(oArea);

if (iexist !=1)
CreateArea("playerhouse");

//rename waypoint for player
object oWP = GetWaypointByTag("playerhousestart");
string destination = spc + "dest";
SetTag(oWP,destination);
object oTarget = GetWaypointByTag(destination);

// create area

CopyArea(oArea);

    // Teleport the PC.
AssignCommand(oPC, ClearAllActions());
AssignCommand(oPC, JumpToObject(oTarget));


Comments

  • ForSeriousForSerious Member Posts: 446
    It looks like CreateArea and CopyArea are being used in the wrong ways.
    Your first if statement should look more like:
    if(iexist !=1)
    {
        // Always put brackets on if statements to avoid unexpected happenings.
        oArea = CreateArea("playerhouse");
    }
    

    Now the CopyArea call. I don't think it's doing anything helpful. Let's say you have a template area for a player house. When a player builds a house, that template could be copied, then populated with placeables.
    (Or the server has reset and the built house needs to be recreated and populated.) If that is the way it's being done, then that template area should never be modified by scripts.
  • ForSeriousForSerious Member Posts: 446
    On another note, I've noticed that so far, you are using player names in most of your scripts as unique ways of identifying things. That's all fine and dandy until someone names their character the same thing as someone else.

    One idea I suggest is to add a function to your OnClientEnter script that assigns players a unique tag.
    That way, any time you need to tie something to a character, you can just use GetTag on them. (I am more than happy to share my function with you if you want.)
    vonstorm
  • vonstormvonstorm Member Posts: 66
    I guess I'm confused with the difference between CreateArea and CopyArea. Ive never been sure if all areas in the module exist or if they are just templates called when needed. The Idea is to create/copy (whichever is needed) the area with a waypoint named after the PC so that the PC arrives in the correct instance of the area. When he leaves I plan to burn down the house until needed again :)
  • vonstormvonstorm Member Posts: 66
    The function would be great, thanks
  • ForSeriousForSerious Member Posts: 446
    Oh, yeah I don't know that either. I think the key to working with creating areas is to give it a unique tag right after creating it. Maybe look into locations instead: Location(object oArea, vector vPosition, float fOrientation). You can copy the area, give it a tag, then use it with a predefined vector and float to create a location to teleport to.

    Here's my function:
    // Give the player a unique tag.
    // sIsNew — The name of the database
    string MakePlayerTag(object oPC, string sIsNew);
    string MakePlayerTag(object oPC, string sIsNew)
    {
        string sTag = "tag";
        // Get the last number that was used to make a tag.
        int iTag = GetCampaignInt(sIsNew, sTag);
        iTag = iTag + 1;
        // Mark that number has been used now.
        SetCampaignInt(sIsNew, sTag, iTag);
        string sParsed = IntToString(iTag);
        // Pad the tag with some zeros.
        int iLen;
        for(iLen = GetStringLength(sParsed); iLen <= 6; iLen++)
        {
            sParsed = "0" + sParsed;
        }
        sParsed = "ZZ" + sParsed;
        SetTag(oPC, sParsed);
        return sParsed;
    }
    
    And then the if statements in OnClientEnter:
    void main()
    {
        //.... 
        string sName = GetTag(oPC);
        if(GetStringLength(sName) <= 0 || GetSubString(sName, 0, 2) != "ZZ")
        {
            MakePlayerTag(oPC, "DB_Name");
        }
        //…
    }
    
    Obviously you can change the ZZ part to whatever you want. I just have it in there in the off chance that someone is somehow able to sneak a character in that already has a tag. If they already have that, what else have they given themself?
    vonstorm
  • vonstormvonstorm Member Posts: 66
    Appreciated as always
  • WilliamDracoWilliamDraco Member Posts: 175
    CreateArea creates an area according to its file, as in the toolset. It has the local variables that were set in the toolset, the placeables set in toolset, the items set in toolset. etc.etc. It creates the area similar to how you can create a creature or object.

    CopyArea follows the naming convention. It Copies an area that currently exists and makes a replica of the area in it's current state.


    Let's imagine a tiny area with a single chest in the middle. The Chest is empty in the toolset and when the module loads.

    A player walks into the area, and puts a longsword into the chest, then leaves.

    Now:
    CreateArea: Creates a new area with an empty chest, as it was in the toolset.
    CopyArea: Creates a new area with a chest that has a longsword in it, as the area currently does.

    There are now three areas. The Original, the Created one (no sword) and the Copied one (Sword)
    ForSeriousvonstorm
  • vonstormvonstorm Member Posts: 66
    that helped :) thanks
  • vonstormvonstorm Member Posts: 66
    Thanks for all the help, I got it working. I think it may have been using playername as tag for the destination waypoint. Gave PC a tag on entry, got my head around create and copy. Thanks again for the help.
    void main()
    {
    object oPC = GetPCSpeaker();
    string spc = GetTag(oPC);
    string PCname = GetName(oPC);
    SendMessageToPC(oPC,spc);
    object oArea = GetObjectByTag("playerhouse");
    string destination = spc + "dest";
    
    // create area
    CreateArea("playerhouse",spc,PCname +"s House");
    
    //rename waypoint for player
    //original template waypoint
    object oWP = GetWaypointByTag("playerhousestart");
    
    //rename so only this PC goes to it
    SetTag(oWP,destination);
    object oTarget = GetWaypointByTag(destination);
    
     // Teleport the PC.
    AssignCommand(oPC, ClearAllActions());
    AssignCommand(oPC, JumpToObject(oTarget));
    
    
    }
    
    
  • ForSeriousForSerious Member Posts: 446
    edited February 2021
    Humm, you may have some bugs to squash:
    void main()
    {
    object oPC = GetPCSpeaker();
    string spc = GetTag(oPC);
    string PCname = GetName(oPC);
    SendMessageToPC(oPC,spc);
    // oArea never gets used
    object oArea = GetObjectByTag("playerhouse");
    string destination = spc + "dest";
    
    // create area returns an object that might be helpful.
    CreateArea("playerhouse",spc,PCname +"s House");
    
    //oWP could be the original waypoint, or the one from the new area.
    //They're both going to have the same tag, and GetWaypointByTag says it just gets the first one.
    //If it's working you probably don't have to worry too much.
    object oWP = GetWaypointByTag("playerhousestart");
    
    //rename so only this PC goes to it
    SetTag(oWP,destination);
    // oTarget is already defined as oWP. You can delete this.
    object oTarget = GetWaypointByTag(destination);
    
     // Teleport the PC.
    AssignCommand(oPC, ClearAllActions());
    AssignCommand(oPC, JumpToObject(oTarget));
    }
    

    The biggest change I would make is this:
    object oArea = CreateArea("playerhouse", spc, PCname +"s House");
    object oWP = GetNearestObjectByTag("playerhousestart", oArea);
    
    Post edited by ForSerious on
    vonstorm
  • vonstormvonstorm Member Posts: 66
    The way I think it works is that every time this is called an area is created which contains the waypoint "playerhousestart". One of the areas that is vanilla gets the waypoint tag renamed a unique name and the player is transported to it. The next time it runs it will look for a vanilla areas waypoint, not an area that is in use because there is no "playerhousestart" waypoint in it. and so on.
    However, you have provided a cleaner method of doing this so thank you very much.
Sign In or Register to comment.