Aller au contenu

Photo

Polymorphing and returning the PC to original form.


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

#1
kamal_

kamal_
  • Members
  • 5 250 messages

This part works, the player is correctly polymorphed to the form I want, and they correctly can't cancel the form. Setting only the appearance will also work for my purposes.


const int POLYMORPH_TYPE_PC = 160;
#include "ginc_param_const"

void main()
{

object oPC = GetEnteringObject();

if (!GetIsPC(oPC)) return;

object oTarget;
oTarget = oPC;
int nApp = GetAppearanceType(oPC);
SetLocalInt (oPC, "nAppearance", nApp);

int nPolymorphSelection = POLYMORPH_TYPE_PC;
int nLocked = 1; //prevent player from cancelling.

int nDurationType = DURATION_TYPE_PERMANENT;
effect ePoly = EffectPolymorph(nPolymorphSelection, nLocked);
ApplyEffectToObject(nDurationType, ePoly, oTarget);

//store player name for later restoration.	
SetLocalString (oPC, "sFirstName", (GetFirstName(oPC))); 
SetLocalString (oPC, "sLastName", (GetLastName(oPC)));
SetFirstName(oPC, "name_goes_here"); 
SetLastName(oPC, "");

}

I need to reverse this when the player exits the trigger, restoring the original form (and name, but that's simple). That part's not working.



#2
AGhost_7

AGhost_7
  • Members
  • 62 messages

You could just add a SpellId to the effect. When the PC exits the trigger use an effect loop and sniff out the polymorph effect you applied - then use RemoveEffect to remove it.

 

Also, what would happen if the PC is already polymorphed and you apply another? Sounds like that could cause trouble.



#3
Dann-J

Dann-J
  • Members
  • 3 161 messages

That's the way I usually tag effects for later removal (via SetEffectSpellId). You can use any value at all, since it doesn't have to be a valid spell ID. It's really just a unique identifier. I either use 100 (the light spell), or a number that corresponds to an unused line in spells.2DA. I then use the RemoveEffectsFromSpell() function in nw_i0_spells to remove effects selectively.



#4
kamal_

kamal_
  • Members
  • 5 250 messages

Ok, I have a solution that works for my purposes. I had to add an appearance.2da line. This works reliably to change the appearance and name back and forth.

const int APPEARANCE_POLYMORPH_PC = 5005;
#include "ginc_param_const"

void main()
{

object oPC = GetEnteringObject();

if (!GetIsPC(oPC)) return;

object oTarget;
oTarget = oPC;
int nApp = GetAppearanceType(oPC);
SetLocalInt (oPC, "nAppearance", nApp);

int nAppearance = APPEARANCE_POLYMORPH_PC;
SetCreatureAppearanceType(oPC, nAppearance);

//store player name for later restoration.	
SetLocalString (oPC, "sFirstName", (GetFirstName(oPC))); 
SetLocalString (oPC, "sLastName", (GetLastName(oPC)));
SetFirstName(oPC, "renamed"); 
SetLastName(oPC, "");

}

and to undo it


#include "ginc_param_const"

void main()
{

object oPC = GetExitingObject();
if (!GetIsPC(oPC)) return;

object oTarget;
oTarget = oPC;
int nAppearance = GetLocalInt (oPC, "nAppearance");

if (GetIsPC(oPC) == TRUE)
{
	SetCreatureAppearanceType(oPC, nAppearance);
}	 

SetFirstName (oPC, GetLocalString(oPC, "sFirstName"));
SetLocalString (oPC, "sFirstName", (GetFirstName(oPC))); 
SetLastName (oPC, GetLocalString(oPC, "sLastName"));
SetLocalString (oPC, "sLastName", (GetLastName(oPC)));
}


#5
Dann-J

Dann-J
  • Members
  • 3 161 messages

There'll be a problem with those scripts if a player saves the game while inside a trigger. When they reload the game, the trigger's OnEnter script will fire again, setting their appearance variable to their 'polymorphed' appearance type. When they leave the trigger they will be stuck in that form permanently.

 

One way to avoid that would be to add a second variable in the OnEnter script that indicates they've been polymorphed (ie. int Polymorphed = 1). Then have the OnEnter script abort if it detects that the variable already exists. The OnExit script could delete the variable completely.


  • rjshae et kamal_ aiment ceci

#6
AGhost_7

AGhost_7
  • Members
  • 62 messages

Using your original approach:

 

Enter handler.
 

#include "ginc_param_const"
#include "nw_i0_spells"

const int POLYMORPH_TYPE_PC = 160;

void main()
{
    object oPC = GetEnteringObject();
    
    if (!GetIsPC(oPC)) 
    {
        return;
    }
    
    // Remove all other polymorph effects on the PC just in case.
    RemoveSpecificEffect(EFFECT_TYPE_POLYMORPH, oPC);

    effect ePoly = EffectPolymorph(POLYMORPH_TYPE_PC, TRUE, FALSE);
    ePoly = SetEffectSpellId(ePoly,  100023);
    // probably don't want this to be dispellable.
    ePoly = SupernaturalEffect(ePoly);
    ApplyEffectToObject(DURATION_TYPE_PERMANENT, oPC, ePoly);
}

 

Exit handler.

 

#include "nw_i0_spells"

void main()
{
    object oPC = GetExitingObject();
    
    if(!GetIsPC(oPC))
    {
        return;
    }
    
    RemoveEffectsFromSpell(oPC, 100023);
}

  • kamal_ aime ceci

#7
Dann-J

Dann-J
  • Members
  • 3 161 messages

That would certainly be my preferred approach.

 

I prefer to avoid messing with SetCreatureAppearanceType() if at all possible. There are too many ways to end up as an all-dwarf party (appearance type zero).



#8
kamal_

kamal_
  • Members
  • 5 250 messages

 

Using your original approach:

 

Enter handler.
 

#include "ginc_param_const"
#include "nw_i0_spells"

const int POLYMORPH_TYPE_PC = 160;

void main()
{
    object oPC = GetEnteringObject();
    
    if (!GetIsPC(oPC)) 
    {
        return;
    }
    
    // Remove all other polymorph effects on the PC just in case.
    RemoveSpecificEffect(EFFECT_TYPE_POLYMORPH, oPC);

    effect ePoly = EffectPolymorph(POLYMORPH_TYPE_PC, TRUE, FALSE);
    ePoly = SetEffectSpellId(ePoly,  100023);
    // probably don't want this to be dispellable.
    ePoly = SupernaturalEffect(ePoly);
}

 

Exit handler.

 

#include "nw_i0_spells"

void main()
{
    object oPC = GetExitingObject();
    
    if(!GetIsPC(oPC))
    {
        return;
    }
    
    RemoveEffectsFromSpell(oPC, 100023);
}

 

Perfect, other than I needed to apply the effect to the pc in the onEnter and my spell id was 130. All set.



#9
4760

4760
  • Members
  • 1 207 messages

I prefer to avoid messing with SetCreatureAppearanceType() if at all possible. There are too many ways to end up as an all-dwarf party (appearance type zero).

True!!!

However, the EffectPolymorph approach prevents you from using the inventory, which is a real problem in my campaign.

On the other hand, the SetCreatureAppearanceType requires the new appearance to be fully compatible with the player original appearance (meaning, even if there are cloned copies of the same head, you'll need to have as many head versions for the new appearance as there are head options during the character creation, unless you want a headless PC of course  ;) ).

 

So I'll probably decide to use EffectPolymorph, and change the quests involving a new appearance so no tools or weapons are necessary to complete them. Too bad though.


  • rjshae aime ceci

#10
Dann-J

Dann-J
  • Members
  • 3 161 messages

Surely the only creature shape you can be polymorphed into that includes access to an inventory would be a kangaroo? :)

 

Now there's an idea for an animal companion that doubles as a mule - a kangaroo with a 'pouch of holding'. Apart from an actual mule, of course. Although the kangaroo would have much better boxing skills.



#11
4760

4760
  • Members
  • 1 207 messages

:D Actually, not a kangaroo or a mule, but a child (for flashbacks in the story), hence the need for the inventory.