Fair Strides

Fair Strides' Script Shack

Recommended Posts

Yeah i know, sorry I couldn’t ever get it to work again after going to windows10.

That is now priority now though, if someone could help me get it running.

thanks a bunch

 

 

Share this post


Link to post
Share on other sites

There's no reason it shouldn't run under Win 10. It requires Java though, which is less than ideal. You could always spin up a Win 7 VM and run it under that if you want to contain the taint.

Edit: Added the Upari amulet fix to K1CP - https://github.com/KOTORCommunityPatches/K1_Community_Patch/blob/master/Source/k_pkas_hurtgive.nss

Share this post


Link to post
Share on other sites

*Sigh*

Sorry, it won't decompile. I tried and tried and tried. DP, want to take a shot at it? Could you explain why? Too big? Not the correct game script? 

From tat_m17aa s.rim

k_ptat_sithattk.ncs

 

Share this post


Link to post
Share on other sites

This particular instance is caused by one of the module include constants. Read more here. Per that thread, you can bypass it by hex editing.

#include "k_inc_generic"

void main() {
    
    object oDarkJedi02 = GetObjectByTag("tat17_darkjedi02", 0);
    object oDarkJedi03 = GetObjectByTag("tat17_darkjedi03", 0);
    
    ChangeToStandardFaction(oDarkJedi02, STANDARD_FACTION_HOSTILE_1);
    ChangeToStandardFaction(oDarkJedi03, STANDARD_FACTION_HOSTILE_1);
    ChangeToStandardFaction(OBJECT_SELF, STANDARD_FACTION_HOSTILE_1);
    
    AssignCommand(oDarkJedi02, DelayCommand(1.0, GN_DetermineCombatRound()));
    AssignCommand(oDarkJedi03, DelayCommand(1.0, GN_DetermineCombatRound()));
    DelayCommand(1.0, GN_DetermineCombatRound());
}

 

Share this post


Link to post
Share on other sites

Alright I see.  thanks for doing that. 

Unfortunately when I added my saber replace bit to it it still didn't work.

Just replacing the .utc file for the npc to override won't work either, he just fights bare handed. \

Don't know what's going on. Trying something else.

Share this post


Link to post
Share on other sites

The AI is set up to wait a round before equipping weapons to prevent it breaking. If you want someone unarmed to equip a weapon then you need to do that before turning them hostile and initiating combat. Try something like this:

#include "k_inc_generic"

void GoHostile() {
    ChangeToStandardFaction(OBJECT_SELF, STANDARD_FACTION_HOSTILE_1);
    DelayCommand(1.0, GN_DetermineCombatRound());
}

void main() {
    
    object oDarkJedi02 = GetObjectByTag("tat17_darkjedi02", 0);
    object oDarkJedi03 = GetObjectByTag("tat17_darkjedi03", 0);
    
    ActionEquipItem(GetItemPossessedBy(OBJECT_SELF, "ITEM_TAG_HERE"), INVENTORY_SLOT_RIGHTWEAPON, FALSE);
    AssignCommand(oDarkJedi02, ActionEquipItem(GetItemPossessedBy(oDarkJedi02, "ITEM_TAG_HERE"), INVENTORY_SLOT_RIGHTWEAPON, FALSE));
    AssignCommand(oDarkJedi03, ActionEquipItem(GetItemPossessedBy(oDarkJedi03, "ITEM_TAG_HERE"), INVENTORY_SLOT_RIGHTWEAPON, FALSE));
    
    ActionDoCommand(GoHostile());
    AssignCommand(oDarkJedi02, ActionDoCommand(GoHostile()));
    AssignCommand(oDarkJedi03, ActionDoCommand(GoHostile()));
}

 

Share this post


Link to post
Share on other sites

Welp, it's those 3 dark jedi that are waiting for you behind the wall in Anchorhead. The guy with the short sabers (i hate short sabers) is getting a pair of curved dueling sabers. lol.

So would this work?

#include "k_inc_generic"

    void main() {
    
        object oDarkJedi02 = GetObjectByTag("tat17_darkjedi02", 0);
        object oDarkJedi03 = GetObjectByTag("tat17_darkjedi03", 0);
    object oSaber = GetItemPossessedBy(oDarkJedi02, "duel_lghtsbr_159");        
    object oSaber2 = GetItemPossessedBy(oDarkJedi02, "duel_lghtsbr_159");

    AssignCommand(oDarkJedi02, ActionEquipItem(oSaber, INVENTORY_SLOT_RIGHTWEAPON)));
    AssignCommand(oDarkJedi02, ActionEquipItem(oSaber2, INVENTORY_SLOT_LEFTWEAPON)));

        ChangeToStandardFaction(oDarkJedi02, STANDARD_FACTION_HOSTILE_1);
        ChangeToStandardFaction(oDarkJedi03, STANDARD_FACTION_HOSTILE_1);
        ChangeToStandardFaction(OBJECT_SELF, STANDARD_FACTION_HOSTILE_1);
    
            
        AssignCommand(oDarkJedi02, DelayCommand(1.0, GN_DetermineCombatRound()));
        AssignCommand(oDarkJedi03, DelayCommand(1.0, GN_DetermineCombatRound()));
        DelayCommand(1.0, GN_DetermineCombatRound());
}

Just lookin at it I don't think it will, lol.

Here I'm just gonna adapt yours to what I need. 

Edited by Kaidon Jorn

Share this post


Link to post
Share on other sites

Like this?

#include "k_inc_generic"

void GoHostile() {
    ChangeToStandardFaction(OBJECT_SELF, STANDARD_FACTION_HOSTILE_1);
    DelayCommand(1.0, GN_DetermineCombatRound());
}

void main() {
    
    object oDarkJedi02 = GetObjectByTag("tat17_darkjedi02", 0);
    object oDarkJedi03 = GetObjectByTag("tat17_darkjedi03", 0);
    object oShortsbr1 = GetItemPossessedBy(oDarkJedi02, "g_w_shortsbr02");
    object oShortsbr2 = GetItemPossessedBy(oDarkJedi02, "g_w_shortsbr05");

    AssignCommand(oDarkJedi02, ActionUnequipItem(oShortsbr1, TRUE);
    AssignCommand(oDarkJedi02, ActionUnequipItem(oShortsbr2, TRUE);
    AssignCommand(oDarkJedi02, ActionEquipItem(CreateItemOnObject("duel_lghtsbr_159", oDarkJedi02), INVENTORY_SLOT_RIGHTWEAPON, FALSE));
    AssignCommand(oDarkJedi02, ActionEquipItem(CreateItemOnObject("duel_lghtsbr_159", oDarkJedi02), INVENTORY_SLOT_LEFTWEAPON, FALSE));
    
    ActionDoCommand(GoHostile());
    AssignCommand(oDarkJedi02, ActionDoCommand(GoHostile()));
    AssignCommand(oDarkJedi03, ActionDoCommand(GoHostile()));
}

I returned the .utc to normal

Share this post


Link to post
Share on other sites

Ok that works well. But....

*smh*

I'm an idiot. I forgot I put a feat required on that saber. So I'm also giving the npc that feat. (dueling).

Really appreciate the expertise and advise, DP.

Share this post


Link to post
Share on other sites

I am tempted to do a Recruit Mod with a re skinned PFHC02 head.

 

Monique: she is a re skinned of PFHC02 with extremely longer voluminous darker red hair with dark blue eyes; using Female Revan Soldier as a base for her body. yes she is a mild reference to the Callidus Assassin in her appearance

 

My Story idea is Monique would encountered on Taris in the Sith Base as a Prisoner with the Duros. And she would join you to escape Taris and On Dantioone, If Juhani lives, Monique would leave the group to the Ord Mantell to assist the Jedi there. and Encounter with Quatra, Juhani's Jedi Master, requests an Audience with Juhani about what happen during her Jedi trials. Juhani will leave to reconnect with Quatra. 

If Juhani is dead, Monique will stay in the group.

 

Regardless if Juhani is lives or dead, Monique's content involves tracking a Rogue Dark Jedi and 2 Sith Juggernauts.

 

In Short, how would I do that for a mod?

Share this post


Link to post
Share on other sites

So I am trying to replace Bastila's saber from default to mine. I'm close. It did spawn in inventory and destroy the default one but she didn't equip it. Why?

// Globals
    int intGLOB_1 = 1;
    int intGLOB_2 = 2;
    int intGLOB_3 = 3;
    int intGLOB_4 = 4;
    int intGLOB_5 = 5;
    int intGLOB_6 = 6;
    int intGLOB_7 = 3;
    int intGLOB_8 = 4;
    int intGLOB_9 = 5;
    int intGLOB_10 = 6;
    int intGLOB_11 = 7;
    int intGLOB_12 = 1;
    int intGLOB_13 = 2;
    int intGLOB_14 = 3;
    int intGLOB_15 = 4;
    int intGLOB_16 = 5;
    int intGLOB_17 = 6;
    int intGLOB_18 = 7;
    int intGLOB_19 = 8;
    int intGLOB_20 = 9;
    int intGLOB_21 = 10;
    int intGLOB_22 = 11;
    int intGLOB_23 = 12;
    int intGLOB_24 = 13;
    int intGLOB_25 = 14;
    int intGLOB_26 = 15;
    int intGLOB_27 = 16;
    int intGLOB_28 = 17;
    int intGLOB_29 = 18;
    int intGLOB_30 = 19;
    int intGLOB_31 = 20;
    int intGLOB_32 = 21;
    int intGLOB_33 = 22;
    int intGLOB_34 = 23;
    int intGLOB_35 = 24;
    int intGLOB_36 = 25;
    int intGLOB_37 = 26;
    int intGLOB_38 = 27;
    int intGLOB_39 = 28;
    int intGLOB_40 = 29;
    int intGLOB_41 = 30;
    int intGLOB_42 = 59;
    int intGLOB_43 = 0;
    int intGLOB_44 = 1;
    int intGLOB_45 = 2;
    int intGLOB_46 = 29;
    int intGLOB_47 = 30;
    int intGLOB_48 = 34;
    int intGLOB_49 = 35;
    int intGLOB_50 = 36;
    int intGLOB_51 = 37;
    int intGLOB_52 = 38;
    int intGLOB_53 = 39;
    int intGLOB_54 = 41;
    int intGLOB_55 = 42;
    int intGLOB_56 = 46;
    int intGLOB_57 = 47;
    int intGLOB_58 = 15;
    int intGLOB_59 = 10;
    int intGLOB_60 = 5;
    int intGLOB_61 = 2;
    int intGLOB_62;
    int intGLOB_63;
    int intGLOB_64;
    object objectGLOB_1;
    int intGLOB_65;
    int intGLOB_66;
    int intGLOB_67;
    int intGLOB_68;
    int intGLOB_69;
    int intGLOB_70;
    int intGLOB_71 = 1;
    int intGLOB_72 = 2;
    int intGLOB_73 = 3;
    int intGLOB_74 = 20;
    int intGLOB_75 = 21;
    int intGLOB_76 = 22;
    int intGLOB_77 = 23;
    int intGLOB_78 = 24;
    int intGLOB_79 = 25;
    int intGLOB_80 = 26;
    int intGLOB_81 = 27;
    int intGLOB_82 = 28;
    int intGLOB_83 = 31;
    int intGLOB_84 = 32;
    int intGLOB_85 = 33;
    int intGLOB_86 = 40;
    int intGLOB_87 = 43;
    int intGLOB_88 = 44;
    int intGLOB_89 = 45;
    int intGLOB_90 = 48;
    int intGLOB_91 = 49;
    int intGLOB_92 = 50;
    int intGLOB_93 = 51;
    int intGLOB_94 = 52;
    int intGLOB_95 = 53;
    int intGLOB_96 = 54;
    int intGLOB_97 = 55;
    int intGLOB_98 = 56;
    int intGLOB_99 = 57;
    int intGLOB_100 = 58;
    int intGLOB_101 = 60;
    int intGLOB_102 = 61;
    int intGLOB_103 = 62;
    int intGLOB_104 = 63;
    int intGLOB_105 = 64;
    int intGLOB_106 = 65;
    int intGLOB_107 = 66;
    int intGLOB_108 = 67;
    int intGLOB_109 = 68;
    int intGLOB_110 = 69;
    int intGLOB_111 = 70;
    int intGLOB_112 = 71;
    int intGLOB_113 = 72;
    int intGLOB_114 = 1;
    int intGLOB_115 = 2;
    int intGLOB_116 = 3;
    int intGLOB_117 = 4;

void main() {

    object oBastila = GetObjectByTag("Bastila", 0);
    object oDblSbr = GetItemPossessedBy(oBastila, "g_w_dblsbr002");
    object oBastSbr = CreateItemOnObject("bast_dblsbr_151", oBastila, 1);
    
    ActionPauseConversation();
    AddPartyMember(0, GetObjectByTag("bastila", 0));
    DestroyObject(oDblSbr, 0.0, 0, 0.0);
    AssignCommand(oBastila, ActionEquipItem(oBastSbr, INVENTORY_SLOT_RIGHTWEAPON, 0));
    ActionResumeConversation();
}

This is k_punk_bastjoin2.ncs from unk_m44ac.mod

Oh, and I wanted to ask...there is k_punk_bastjoin and k_punk_bastjoin2. 

I was assuming k_punk_bastjoin was for dark side because it has the section that removes Jolee and Juhani from the party and available npc's.

But now I think that's wrong because bastjoin2.ncs worked for Bastila joining me and at least creating the saber (even if equipping didn't work).

So am I mistaken?

Share this post


Link to post
Share on other sites

Both scripts are for the DS route and fire consecutively (as you can see for yourself in unk44_evilbast.dlg). The first one is k_punk_bastjoin, which removes Jolee and Juhani from the party and spawns a level-appropriate Bastila (determined by the player's current level). Then k_punk_bastjoin2 adds the new evil Bastila to the party (the stunt Bastila you've been interacting with up to this point is then destroyed on the DLG exit node).

Btw you don't need all that include garbage in your script. A clean version of the original is simply:

void main() {
	
	ActionPauseConversation();
	
	AddPartyMember(NPC_BASTILA, GetObjectByTag("bastila", 0));
	
	ActionResumeConversation();
}

Note however that K1CP makes some minor alterations to this script, which you'll want to include for compatibility purposes - https://github.com/KOTORCommunityPatches/K1_Community_Patch/blob/master/Source/k_punk_bastjoin2.nss

Your problem with the equipping can likely be resolved simply by a change in the order of operations. Try the following (K1CP additions incorporated):

void AddBast(object oNPC) {
	AddPartyMember(NPC_BASTILA, oNPC);
}

void main() {
	
	object oBastila = GetObjectByTag("Bastila", 0);
	object oJolee = GetObjectByTag("jolee", 0);
	object oJuhani = GetObjectByTag("juhani", 0);
	object oDblSbr = GetItemPossessedBy(oBastila, "g_w_dblsbr002");
	object oBastSbr = CreateItemOnObject("bast_dblsbr_151", oBastila, 1);
	
	ActionPauseConversation();
	
	AssignCommand(oBastila, ActionEquipItem(oBastSbr, INVENTORY_SLOT_RIGHTWEAPON, TRUE));
	
	DelayCommand(0.2, DestroyObject(oDblSbr));
	
	DelayCommand(0.4, AddBast(oBastila));
	
	// Turn off scripted saber blade activation overrides.
	SetLightsaberPowered(GetFirstPC(), FALSE);
	SetLightsaberPowered(oJolee, FALSE);
	SetLightsaberPowered(oJuhani, FALSE);
	DelayCommand(0.5, SetLightsaberPowered(oBastila, FALSE));
	
	DelayCommand(0.6, ActionResumeConversation());
}

 

Share this post


Link to post
Share on other sites

Wow. Ok so don't need all the int globs on top. (why are they there? ...don't have to answer that)

Ok. so wait, I want her to fight Jo and Ju with it so I need to do the switch on #1,.. no? wait....what?

Nevermind I got it.

Thanks for the help!

 

 

Share this post


Link to post
Share on other sites

Those were pulled in from the include files by Bioware's compiler. Just as nwnnsscomp does, all the constants in any listed includes get pulled in, even if they aren't actually referenced by the script. But you can't just blindly delete them every time. Sometimes they will be used (or some of them anyway), most commonly when referencing local boolean constants from k_inc_utility (SW_PLOT_BOOLEAN_01, SW_PLOT_HAS_TALKED_TO, etc.). But anything to do with AI will typically reference a bunch from multiple different includes.

  • Thanks 1

Share this post


Link to post
Share on other sites

Hey guys, 

I'm looking to see if anyone could help me create two conditionals within a script that will spawn an NPC if two quest requirements are met. Here is the script below: 

Spoiler

void main()
{
  int check = GetGlobalBoolean("FOUND_BOD1");
  int check = GetGlobalBoolean("light_crys2");
  if (check == TRUE)

  {
    CreateObject(OBJECT_TYPE_CREATURE, "dan13_jed99", Location(Vector(160.04, 84.16, 12.62), 0.0)); 

  }

  ExecuteScript("k_pdan_13_areaold", OBJECT_SELF); 

}

Unfortunately the above won't compile, I've researched this and I know it must have something to do with the && function within a script. 

Share this post


Link to post
Share on other sites

Try this, this one compiles for me --

void main()
{
    int sID_FOUND_BOD1 = GetGlobalBoolean("FOUND_BOD1");
    int sID_light_crys2 = GetGlobalBoolean("light_crys2");

    // Checks if BOTH quest requirements are met
    if(sID_FOUND_BOD1 == TRUE && sID_light_crys2 == TRUE)
    {
	    CreateObject(OBJECT_TYPE_CREATURE, "dan13_jed99", Location(Vector(160.04f, 84.16f, 12.62f), DIRECTION_EAST));
    }

    // Better change the executed-script name as it exceeds the maximum 16 characters the game could read
    ExecuteScript("k_pdan_13_areaold", OBJECT_SELF);
}
18 hours ago, djh269 said:

Unfortunately the above won't compile...

Your problem was--as the compiler said so -- Error: Variable "check" defined multiple times in the same scope

Although to be honest I was surprised looking at your script initially - thinking that'd work and the problem was on something else. Would be cool if the compiler can support that idea, I guess. And yeah, it had something to do with the and function within a script.

Share this post


Link to post
Share on other sites
15 hours ago, ebmar said:

Try this, this one compiles for me --

Your problem was--as the compiler said so -- Error: Variable "check" defined multiple times in the same scope

Although to be honest I was surprised looking at your script initially - thinking that'd work and the problem was on something else. Would be cool if the compiler can support that idea, I guess. And yeah, it had something to do with the and function within a script.

Wow thanks for your help buddy! That's some great scripting knowledge you have mate!  

Share this post


Link to post
Share on other sites
2 hours ago, djh269 said:

...thanks for your help buddy!

No worries, the pleasure's mine. Anyway, in case you missed the added comments you should change the filename of the executed script/k_pdan_13_areaold to something less/equal to 16 characters.

The script will still compile and the ExecuteScript function will fires -- it's just there's nothing to execute 'cause the game can't read it.

2 hours ago, djh269 said:

That's some great scripting knowledge you have mate!  

Appreciate you think of me like that -- but I know there's more about the [KotOR] scripting world that I didn't understand yet, hahah. But as what I have now wouldn't be possible if not with helping hands from other members in the communities.

As for scripting syntax [usage of logical AND && / logical OR || / logical NOT !] I'd suggest you to check on this one -- Introduction to Scripting Syntax - Tutorials: Scripting - The International House of Mojo Forums (mixnmojo.com)

Share this post


Link to post
Share on other sites
3 hours ago, ebmar said:

No worries, the pleasure's mine. Anyway, in case you missed the added comments you should change the filename of the executed script/k_pdan_13_areaold to something less/equal to 16 characters.

The script will still compile and the ExecuteScript function will fires -- it's just there's nothing to execute 'cause the game can't read it.

I did notice that part within the text above, funnily enough there's another time when I called an OnEnter script and it didn't fire at all! I'll add the 16 character limitation to my list of notes haha. 

3 hours ago, ebmar said:

Appreciate you think of me like that -- but I know there's more about the [KotOR] scripting world that I didn't understand yet, hahah. But as what I have now wouldn't be possible if not with helping hands from other members in the communities.

As for scripting syntax [usage of logical AND && / logical OR || / logical NOT !] I'd suggest you to check on this one -- Introduction to Scripting Syntax - Tutorials: Scripting - The International House of Mojo Forums (mixnmojo.com)

There's so many helpful members here, it's great to see they've helped you become as proficient as you are in scripting. There's so many resources to look out for, even Lucasforums has mostly been archived and there's tons there! Do you have any other educational resources you use? I'm trying to get through these: 

https://neverwintervault.org/project/nwn1/other/nwn-university-document-help-pdf-reference-guide-tutorial-xls-collection 

Share this post


Link to post
Share on other sites
10 hours ago, djh269 said:

...there's another time when I called an OnEnter script and it didn't fire at all!

Actually I'd suggest you to just edit the OnEnter itself rather than calling/execute it from your script. That way can remove the hassle from having to edit the relevant field on the ARE/IFO. Granted, one can just make a unique name for a script that used for executing the original and placing it to the Override, but I believe that'd do more problems than it solve.

Understandable that there are some edge cases which the original can't be decompiled, but if necessary just go with the editing.

10 hours ago, djh269 said:

Do you have any other educational resources you use?

Not really aside of other members' source, vanilla scripts and once in a while I visit NWN Lexicon for relevant answers that can't be found anywhere. And not to forget asking other members for insights is a great educational resources as well.

Though I find the best way to learn is by decompiling any of the binary, and make your way reconstructing them as readable as can be with intelligible constants -- for example [to where they fit into]; int 1 to TRUE, float 0.0 to DIRECTION_EAST, int 5 to ANIMATION_LOOPING_TALK_NORMAL, etc.].

Oh, and comments [started by // then followed with one] can go a long way too -- as our masters @Qui-Gon Glenn once taught me as well --

On 11/30/2018 at 4:14 AM, Qui-Gon Glenn said:

Also, comment your code to death. You will thank yourself later.

Share this post


Link to post
Share on other sites
On 2/15/2022 at 6:31 AM, ebmar said:

Actually I'd suggest you to just edit the OnEnter itself rather than calling/execute it from your script. That way can remove the hassle from having to edit the relevant field on the ARE/IFO. Granted, one can just make a unique name for a script that used for executing the original and placing it to the Override, but I believe that'd do more problems than it solve.

Understandable that there are some edge cases which the original can't be decompiled, but if necessary just go with the editing.

Not really aside of other members' source, vanilla scripts and once in a while I visit NWN Lexicon for relevant answers that can't be found anywhere. And not to forget asking other members for insights is a great educational resources as well.

Though I find the best way to learn is by decompiling any of the binary, and make your way reconstructing them as readable as can be with intelligible constants -- for example [to where they fit into]; int 1 to TRUE, float 0.0 to DIRECTION_EAST, int 5 to ANIMATION_LOOPING_TALK_NORMAL, etc.].

Oh, and comments [started by // then followed with one] can go a long way too -- as our masters @Qui-Gon Glenn once taught me as well --

That's some great advice mate, I'll try and inject the script into the vanilla OnEnter. 

I've seen the NWN Lexicon before and reading some stuff on there at the moment, it's a great resource. 

Funnily enough I saw the DIRECTION_EAST line in the nwscript.nss file haha. Yeah I leave comments in some scripts :D

 

Share this post


Link to post
Share on other sites

This was clearly using a Korriban module include, but that is not present in the source files. Here's the vanilla script:

#include "k_inc_utility"

void SetShaardanFlag(int nState) {
	UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, nState);
}

int GetShaardanFlag() {
	return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}

void main() {
	
	object oPC = GetFirstPC();
	object oNPC = GetPartyMemberByIndex(0);
	object oShaardan = GetObjectByTag("kor37_shaardan", 0);
	
	if (GetShaardanFlag() == FALSE && GetEnteringObject() == oNPC && GetIsObjectValid(oShaardan))
		{
			SetShaardanFlag(TRUE);
			UT_NPC_InitConversation("kor37_shaardan", "", OBJECT_INVALID);
		}
}

But I would suggest streamlining it to:

#include "k_inc_utility"

void main() {
	
	object oEntering = GetEnteringObject();
	object oShaardan = GetObjectByTag("kor37_shaardan", 0);
	
	if (!UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01) && GetIsPC(oEntering) && GetIsObjectValid(oShaardan))
		{
			UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, TRUE);
			UT_NPC_InitConversation("kor37_shaardan", "", OBJECT_INVALID);
		}
}

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.