• New Horizons on Maelstrom
    Maelstrom New Horizons


    Visit our website www.piratehorizons.com to quickly find download links for the newest versions of our New Horizons mods Beyond New Horizons and Maelstrom New Horizons!

Need Help Change the main character without reloading the location.

Myth

Freebooter
Good afternoon. Interested in this question: you can change the main character without reloading the location? The hero changes without problems, but the new hero can not be controlled. How can I unblock the control?
 
Have a look in the PotC Build Mod console.
There is a sample line in there that changes the player model instantly.
Trace where that leads and hopefully you can figure out how to make it work in CoAS too.
It is definitely possible. :yes
 
I do not want to change the model. I need to assign a new character as the main character and after the exit from the dialogue do the opposite. I will clarify the problem.
 
In that case, just swap the player model and name.
That way, it'll SEEM as if you are another character.

I know there is one part of the PotC standard storyline where an actual swap is done.
But that is really complicated and I don't recommend it...
 
This is the code in question:
Code:
       case "dagger_3":
           LAi_ActorAnimation(characterFromID("blaze"), "Lay_1", "", -1);
           LAi_SetPlayerType(characterFromID("danielle"));
           SetMainCharacterIndex(GetCharacterIndex("danielle"));
           PChar = GetMainCharacter(); // PB: This is IMPORTANT to update that you are now 'Danielle'!
           ChangeCharacterAddress(characterFromID("Blaze"), "Rheims_house_inside", "goto5");

           DoQuestReloadToLocation("Rheims_house_inside", "item", "item1", "start_quest_movie_speak_with_rheims_complete");
           pchar.quest.main_line = "danielle_speak_with_almost_dead_rheims";

           locations[FindLocation("Douwesen_town_exit")].reload.l1.disable = 0;
           locations[FindLocation("Douwesen_town_exit")].reload.l2.disable = 0;
       break;
Note that there is a 'DoQuestReloadToLocation' line, so even here, the location needs to be reloaded.

There is also some character switching in the "Hornblower" storyline. Hornblower is leading an attack on a signal tower and there are a few points at which you switch to another character somewhere else, effectively a cut scene which lets the player know what is going on at the beach or on the ship while he's at the lighthouse, and later while he's a prisoner. Again, these do involve reloading location - they have to, as the whole point is to show what is happening somewhere else! These cut scenes do exactly what @Pieter Boelen suggests - change your model, change your name, then it looks as though you're a different character.

But switching models should in theory not require a scene reload. Tailors in PoTC do it routinely. You tell them which outfit you like and they use the function 'SetModel' to change their appearance and show you the outfit. So, in "Hornblower", this is how you change from Horatio Hornblower to Jack Hammond:
Code:
           SetModelfromArray(PChar, GetModelIndex("Wellard_18"));
           PChar.name = "Jack";
           PChar.lastname = "Hammond";
And this is how you change back:
Code:
           SetModelfromArray(PChar, GetModelIndex("brtHComdr_18"));
           PChar.name = "Horatio";
           PChar.lastname = "Hornblower";
 
Maybe I found a way out. Tomorrow I'll check. And I will report the result.

This will get you started on the correct path. I tested this and it works, but there is still some work you will have to do with dialog attributes and anything else special the main character in your game might have for attributes that will not exist in the character you swap with:

Code:
//Test swap with my officer, PSHero_115
    int testChar = GetCharacterIndex("PSHero_115"); //Get my officer by id
    int oldMain = nMainCharacterIndex;
    LogoffCharacter(&characters[testChar]);
    LogoffCharacter(&characters[oldMain]);
    SetMainCharacterIndex(testChar);
    PChar = GetMainCharacter();
    LAi_SetPlayerType(PChar);
    LAi_SetOfficerType(&characters[oldMain]); //This is hero index, switching with my officer
    LoginCharacter(&characters[testChar], loadedLocation.id);
    LoginCharacter(&characters[oldMain], loadedLocation.id);
    locCameraTarget(&characters[testChar]);
    locCameraFollow();

ETA: Funny thing is since I don't set everything needed in this small example, all my officers run away to some random spot because they presumably have some other attribute for the character they are supposed to follow, which has obviously changed...it just looks funny to me when they immediately scatter upon the switch.

ETA2: Also forgot to mention that this will set the two swapped characters to their last stored locator id, which of course will probably be undesirable. You may have to copy/modify your LoginCharacter function, to where you can pass the current character coordinates to both of the new login function.
 
Last edited:
Impressive, @ChezJfrey! :onya

Funny thing is since I don't set everything needed in this small example, all my officers run away to some random spot because they presumably have some other attribute for the character they are supposed to follow, which has obviously changed...it just looks funny to me when they immediately scatter upon the switch.
:rofl :rofl
 
Maybe I found a way out. Tomorrow I'll check. And I will report the result.

Expanded example to show what I'm talking about the teleport:

Code:
//Test swap with my officer, PSHero_115
    int testChar = GetCharacterIndex("PSHero_115"); //Get my officer by id
    int oldMain = nMainCharacterIndex;
    int ldLoc = FindLoadedLocation();
    SendMessage(&Locations[ldLoc], "l", MSG_LOCATION_SETCHRPOSITIONS); // This message actually just stores current character coordinates in a .saveposition attribute for all chars in location...nothing else.  But now we can retrieve them.
    object aChr, bChr;
    aChr.x = characters[testChar].saveposition.x;
    aChr.y = characters[testChar].saveposition.y;
    aChr.z = characters[testChar].saveposition.z;
    aChr.ay = characters[testChar].saveposition.ay;
    bChr.x = characters[oldMain].saveposition.x;
    bChr.y = characters[oldMain].saveposition.y;
    bChr.z = characters[oldMain].saveposition.z;
    bChr.ay = characters[oldMain].saveposition.ay;
    LogoffCharacter(&characters[testChar]);
    LogoffCharacter(&characters[oldMain]);
    SetMainCharacterIndex(testChar);
    PChar = GetMainCharacter();
    LAi_SetPlayerType(PChar);
    LAi_SetOfficerType(&characters[oldMain]); //This is hero index, switching with my officer
    LoginCharacter(&characters[testChar], loadedLocation.id);
    LoginCharacter(&characters[oldMain], loadedLocation.id);
    TeleportCharacterToPosAy(&characters[testChar], stf(aChr.x), stf(aChr.y), stf(aChr.z), stf(aChr.ay));
    TeleportCharacterToPosAy(&characters[oldMain], stf(bChr.x), stf(bChr.y), stf(bChr.z), stf(bChr.ay));
    locCameraTarget(&characters[testChar]);
    locCameraFollow();

Now the characters stay exactly where they were during the switch. Sad thing is now my other officers no longer scatter, either, LOL

But this technically involves two teleports for each of the characters, because there is a teleport call in LoginCharacter(). This is why I suggest making a copy of that function, but add 4 more parameters, so you instead do this:

LoginCharacterToPos(&characters[oldMain], loadedLocation.id, stf(bChr.x), stf(bChr.y), stf(bChr.z), stf(bChr.ay));

And inside your new LoginCharacterToPos() function, change the TeleportCharacterToLocator call to TeleportCharacterToPosAy. That way you don't need to teleport twice and can remove the TeleportCharacterToPosAy calls in my example, once you switch out to the new LoginCharacterToPos you make.
 
Expanded example to show what I'm talking about the teleport:

Code:
//Test swap with my officer, PSHero_115
    int testChar = GetCharacterIndex("PSHero_115"); //Get my officer by id
    int oldMain = nMainCharacterIndex;
    int ldLoc = FindLoadedLocation();
    SendMessage(&Locations[ldLoc], "l", MSG_LOCATION_SETCHRPOSITIONS); // This message actually just stores current character coordinates in a .saveposition attribute for all chars in location...nothing else.  But now we can retrieve them.
    object aChr, bChr;
    aChr.x = characters[testChar].saveposition.x;
    aChr.y = characters[testChar].saveposition.y;
    aChr.z = characters[testChar].saveposition.z;
    aChr.ay = characters[testChar].saveposition.ay;
    bChr.x = characters[oldMain].saveposition.x;
    bChr.y = characters[oldMain].saveposition.y;
    bChr.z = characters[oldMain].saveposition.z;
    bChr.ay = characters[oldMain].saveposition.ay;
    LogoffCharacter(&characters[testChar]);
    LogoffCharacter(&characters[oldMain]);
    SetMainCharacterIndex(testChar);
    PChar = GetMainCharacter();
    LAi_SetPlayerType(PChar);
    LAi_SetOfficerType(&characters[oldMain]); //This is hero index, switching with my officer
    LoginCharacter(&characters[testChar], loadedLocation.id);
    LoginCharacter(&characters[oldMain], loadedLocation.id);
    TeleportCharacterToPosAy(&characters[testChar], stf(aChr.x), stf(aChr.y), stf(aChr.z), stf(aChr.ay));
    TeleportCharacterToPosAy(&characters[oldMain], stf(bChr.x), stf(bChr.y), stf(bChr.z), stf(bChr.ay));
    locCameraTarget(&characters[testChar]);
    locCameraFollow();

Now the characters stay exactly where they were during the switch. Sad thing is now my other officers no longer scatter, either, LOL

But this technically involves two teleports for each of the characters, because there is a teleport call in LoginCharacter(). This is why I suggest making a copy of that function, but add 4 more parameters, so you instead do this:

LoginCharacterToPos(&characters[oldMain], loadedLocation.id, stf(bChr.x), stf(bChr.y), stf(bChr.z), stf(bChr.ay));

And inside your new LoginCharacterToPos() function, change the TeleportCharacterToLocator call to TeleportCharacterToPosAy. That way you don't need to teleport twice and can remove the TeleportCharacterToPosAy calls in my example, once you switch out to the new LoginCharacterToPos you make.

Here is the above code, demonstrated:

 
=O i would so love to have this in my game did you finish the code and where did you get the girl in the blue coat
 
Back
Top