Recommended Posts

1 hour ago, JCarter426 said:

If you want to see how it looks in the game, you can load the model in MDLEdit and go to edit > textures to enable the bump map flag for that. Then, change N_SithSolder01.txi to:


bumpshinytexture cm_baremetal
bumpmaptexture N_SithSoldier_b

Thanks for adding details with the MDLEdit! That should give much clearer instruction to the potential reader. :cheers:

Yes, I have done that- but instead of applying CM_Baremetal, I am using mycube, and using TPC instead of TGA.

1 hour ago, DarthParametric said:

You must be looking at something different, as there is no discernible difference with or without it as far as I can tell.

Oops- as you say "something different", I take notice that I am using K1CP model instead of the vanilla, and then having another result with the vanilla model.

With all due respect, commander- but on my end the difference is quite noticeable. Another screenshots- but from closer range:

  • No bump-map with K1CP model:

Spoiler

NoBmpMpwithK1CPModel.png.d0fe3e5cde93ddd1e4a835ef1d30483f.png

  • Bump-map applied with K1CP model:
Spoiler

BmpMpwithK1CPModel.png.637d70a5be911b85c6a5f21e48930462.png

  • Bump-map applied with vanilla model:
Spoiler

BmpMpwithVanillaModel.thumb.png.def3306cdf6fa99b7a97a1bd3488523a.png

 

So, why does the vanilla model lacks light and appears darker? I took the picture from the slightly different spot but I believe is with the same amount of light to the K1CP model has. 🤔

Edited by ebmar

Share this post


Link to post
Share on other sites
4 minutes ago, ebmar said:

quite noticeable

I am old and probably need glasses, but I'd still dispute that assertion. To me the differences are so subtle as to be more or less imperceptible without multiple back and forth comparisons. And from the range that you would generally see a Trooper you'd never tell the difference.

  • Like 1

Share this post


Link to post
Share on other sites

Greetings, fellow Jedi!

Have anyone using Vurt/zane's "Junkyard Ebon Hawk", Curtis1973's "Ebon Hawk High Resolution" and/or any E-Hawk's texture enhancement ends-up wondering- why does the texture on Dreshdae's Docking Bay wasn't change as it needs to? But why are they working on every planets but not this one?

It seems the aforementioned mods did not include the needed files to have them working with Dreshdae's portion. So, these are those things that you need to do:

  • Copy one of the files, i.e: LDA_EHawk01.tga, and then paste it on the same folder so its copy would be labelled as LDA_EHawk01 - Copy.tga
  • Rename LDA_EHawk01 - Copy.tga to M36_EHawk01.tga, and now you will have the needed file to work with Dreshdae's Docking Bay.
  • Copy-paste the M36_EHawk01.tga to the 'Override' folder [I believe you won't need the TXI as it seems those mods are not involving alpha channel on them texture].

Now you have the needed change installed, particularly on Dreshdae's portion.

It took me quite awhile to guess; why there's no LKO_EHawk01.tga inside the game file and/or any Ebon Hawk texture enhancement mods? Because the game is trolling with us by naming the E-Hawk's texture on Dreshdae with M36 instead of LKO. Nice one, BioWare! :beer:

Hope this findings kind of helps! :cheers:

Share this post


Link to post
Share on other sites

Greetings, fellow Jedi! May the Force be with you all! :cheers:

I'm quite sure some may have known of this, but is certain the majority wasn't.

There are two [more] "unused" bump-map texture inside the game files; for Dantooine's Jedi Enclave in particular- and they gave significant end-result which I believe is nice to have them activated.

So, with vanilla models, the floor tagged as LDA_flr11 and LDA_flr12- as their native resolution is 256x256. Inside the game files there are several higher resolution for these two variant; I take the LDA_flr01 and LDA_flr02 for the replacement. They are sized at 512x512, and had alpha channel on the texture. For whom of you understand on using the KotOR Tool, I believe you will find it easy on assigning each envmap to the respective texture [there are example of TXI's setup by double-clicking certain texture]. One thing that is important is to assign bumpmaptexture for them respectively with the appropriate bump-map [LDA_flr01B for 11 variant, and LDA_flr02B for 12].

I'll get to the point which is the result of the attempt:

  • Spoiler

    Dantooine_Unused_BM.thumb.jpg.0e6230ddb27ad485cc939233f9391aa4.jpg

     

  • Spoiler

    Dantooine_Unused_BM2.thumb.jpg.182d1bff29312feb1fde78cb85addc77.jpg

    It looked even more amazing in-game. By my perspective, is one of the [if not the] most beautiful scenery in the game

  • Spoiler

    Dantooine_Unused_BM3.thumb.jpg.de57dd9c4ff7679fdc866e52adcc2d32.jpg

    This area is tricky. As seen by the floor that the reflection is indeed the outside of the Enclave [CM_jedcom]. I think it should be either CM_Dantne, CM_danint, or CM_dantii perhaps? Which by their looks more resemblance of what's inside the Enclave. But each of the area model share the same textures so, more laborious tinkering [using custom meshes models] will need to be done then

Hope this findings could enhances your K1 experience! :cheers:

Edited by ebmar
  • Like 1

Share this post


Link to post
Share on other sites
4 minutes ago, DarthParametric said:

Custom models. You don't need to touch the meshes, just the texture assignments.

Thank you for the heads-up! I got confused between meshes and models and textures most of the time lol. I'll revised the information above accordingly.

Edited by ebmar

Share this post


Link to post
Share on other sites

A model is the entire...container, for want of a better term. A mesh is the polygonal geometry within the model. Typically a model is comprised of multiple meshes, although in some cases, such as VFX, there may be no meshes at all.

  • Thanks 1

Share this post


Link to post
Share on other sites

Entry#10: Trigger's ScriptOnEnter x GetEnteringObject

Took two days for me to figure this out, lol -

So, with a trigger's ScriptOnEnter that has ActionStartConversation, ones should always has GetEnteringObject with the script, something like -

	// Participants
	object oDLGOwner = GetObjectByTag("DLGOwner");

	// Declared Functions
	object oEntering = GetEnteringObject();
	
	// Checks if the player is entering the trigger
	if(GetIsPC(oEntering))
	{	
		// Starts the conversation
		AssignCommand(oDLGOwner, ActionStartConversation(GetFirstPC(), "DLGString"));
	}

Otherwise, the conversation will sometimes triggered at random points of the area/module. Either it doesn't at all, the other chance it does as intended or most of the times it triggered like 100 meters away from the geometry.

Thought at first that ScriptOnEnter does checks if something enters the trigger and appropriately calls the included commands, which apparently it doesn't.

Edited by ebmar
Testing JC's "Odyssey++" 's coloring convention with script and templates reference

Share this post


Link to post
Share on other sites

The On Enter script of a trigger is working just as it should. It triggers every time some creature enters the trigger area which may result in something that seems like random behaviour but isn't.

So if you want a trigger that only works with the PC, then you need the additional check you mentioned but that is the intended behaviour.

  • Like 1

Share this post


Link to post
Share on other sites

You'll typically also want to set a boolean on the trigger, or destroy it after it has triggered, assuming it is intended to be a one-and-done event. Alternative options include checking the creature or object that is assigned the conversation for a boolean, or checking a global boolean/number, as appropriate.

Here's one example:

#include "k_inc_utility"

int HasNeverTriggered() {
    int bReturn;
    if (UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01) == FALSE)
    {
        bReturn = TRUE;
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, TRUE);
    }
    return bReturn;
}

void Main() {
	
	object oDLGOwner = GetObjectByTag("DLGOwner");
	object oEntering = GetEnteringObject();
	
	if (GetIsPC(oEntering) && HasNeverTriggered())
		{
			AssignCommand(oDLGOwner, ActionStartConversation(GetFirstPC(), "DLGString"));
		}
}

You can also cut out the middle-man and just do it like this:

void Main() {
	
	object oDLGOwner = GetObjectByTag("DLGOwner");
	object oEntering = GetEnteringObject();
	int SW_PLOT_BOOLEAN_01 = 0;
	
	if (GetIsPC(oEntering) && !GetLocalBoolean(OBJECT_SELF, SW_PLOT_BOOLEAN_01))
		{
			SetLocalBoolean(oTarget, OBJECT_SELF, SW_PLOT_BOOLEAN_01);
			
			AssignCommand(oDLGOwner, ActionStartConversation(GetFirstPC(), "DLGString"));
		}
}

 

  • Thanks 1

Share this post


Link to post
Share on other sites
1 hour ago, Kexikus said:

The On Enter script of a trigger is working just as it should. It triggers every time some creature enters the trigger area which may result in something that seems like random behaviour but isn't.

Thank you for the insight. And woah -

Oboy.gif.5029cf7671f14d00961f2a122bf46075.gif

- that must be it! It must be the wandering creatures inside the room that triggers the conversation instead of the intended PC, because I didn't do the additional check with my initial attempt [and didn't thought of that possibility to be fair, lol]. Just realized it by now, thanks! :cheers:

57 minutes ago, DarthParametric said:

You'll typically also want to set a boolean on the trigger, or destroy it after it has triggered, assuming it is intended to be a one-and-done event.

Thanks for the input! Yeah, I did the latter which is destroying the trigger in a relevant node.

57 minutes ago, DarthParametric said:

Alternative options include checking the creature or object that is assigned the conversation for a boolean, or checking a global boolean/number, as appropriate.

Appreciate the elaboration of that two alternative options. Both are not something that I often practiced to, but I'll take a considerate look unto them. :cheers:

Edited by ebmar
Attached something to show my actual expression on realizing that

Share this post


Link to post
Share on other sites

Entry#11: ActionJumpToLocation >= ActionJumpToObject

Today I learned that to avoid T-posing of a jumped creatures, ones should use ActionJumpToLocation rather than ActionJumpToObject. Though they have a same purpose but the end-result look to be different some other times.

I was having a trial-and-error experience with the HoloRakata/unk41_holo spawned outside the Elder Settlement [Lehon - South Beach/unk_m41ab]. Originally it was spawned by unk41_holo02 using CreateObject, thus having the holo spawned with a T-pose. I recognize the taste of the fruit for sometimes so I moved the spawn part one script earlier -with custom location- to have it with unk41_holo01 and jump the holo with the latter. The waypoint/UTW for initial spawn location already present, which is spawn1 - I have to go with ActionJumpToObject for convenience's sake to avoid fiddling with location's Vector for the jump.

Alas, the T-pose still there. I thought I had to add a PlayAnimation before the jumping part [to override the T animation] but it didn't worked. So I look for a location to pair it with ActionJumpToLocation, as well as using it instead, and then - yeah, the T-pose's gone.

I hope this information can be helpful to you, fellow Jedi. May the Force be with you. :cheers:

Edited by ebmar
Testing JC's "Odyssey++" 's coloring convention with script and templates reference
  • Like 2

Share this post


Link to post
Share on other sites

Entry#12: Rakatan "SWAG" Idle Animation VS ANIMATION_LOOPING_TALK_NORMAL

Rakatan "SWAG" idle animation has been in exposure lately, either for its attitude or a grieve to look at. For one that doesn't like it there's a good news which is partially possible to work around that by having something like this with their OUD [preferably with the idle ones, not that is roaming the area/having something like k_def_ambmob on their ScriptSpawn] and the relevant DLG's EndConverAbort/EndConversation -

//:://////////////////////////////////////////////////////////////
//:: Rakatan Idle Animation Removal Workaround
//:://////////////////////////////////////////////////////////////
/*
	Fired by Rakatan UTC's *ScriptUserDefine* and relevant DLG's
	*EndConverAbort/EndConversation* to override their "SWAG" idle
	animation.
	
	P.S. Left-hand raising talking animation is to be expected
	and kind of awkward to see as no one it refers to.
*/
//:://////////////////////////////////////////////////////////////
//:: Constructed By: ebmar
//:: Constructed On: December 08, 2019
//:://////////////////////////////////////////////////////////////

void main()
{
	/* Play the *talking* animation that lasts 1000 seconds/prac-
	tically forever to permanently override the idle animation */
	PlayAnimation(ANIMATION_LOOPING_TALK_NORMAL, 1.0f, 1000.0f);
	
	// Subsequently calls the defined EUD
	ActionDoCommand(SignalEvent(OBJECT_SELF, EventUserDefined(0)));
}

I recently using that to all the Elder Councillor in the Elder Settlement module, though, as commented above; the left-hand raising animation is to be expected while possibly no-one they talked to, which is kind of awkward to see sometimes. But that should do it in the meanwhile. Alternatively it could be fired with the creature's ScriptSpawn, though from what I tested with the Council it breaks the module's load, not sure with them commoners though.

Hope the information can be helpful to you, fellow Jedi. May the Force be with you. :cheers:

Edited by ebmar
  • Like 1

Share this post


Link to post
Share on other sites

Entry#13: [Success] VS [Failure]

I have been wondering why do this skill check that I put on the DLG won't fires, even though the appropriate script has been put on its Active value. Then I dig through some vanilla DLGs, and realize some -if not most of them- did not actually does the check, and they're only gimmick. Such when the reply node does the [Persuade] thing, then there's no branch following it actually, there's only a gimmick node that tells you're [Success] with the action or [Failure] in other instance.

I thought that was how the thing goes, and long-story-short lately I have learned from Dia's DLG/tar02_dia022.dlg that, apparently to have a successful persuade check on a conversation, the [Success] node [that has the skill check on its Active] should be put on top of the [Failure] ones [that requires none]. It won't work the other way because it would directly call the the latter.

Hope the information can be helpful to you, fellow Jedi. May the Force be with you. :cheers:

Edited by ebmar
  • Like 1

Share this post


Link to post
Share on other sites

Entry#14: GetNearestCreature > GetPartyMemberByIndex

Here to archive [and to not make the knowledge somewhat lost - buried by walls of threads] for @JCarter426's roundabout workaround on party members' control, and not to forget on crediting @eNoodles for brought the issue up in the first place - thank you, guys!

So, I was on an attempt to spawn the PMs to a fixed locations by module's OnEnter. The problem occurred when I was spawning them with GetPartyMemberByIndex as they were not properly located. Such as using this -

Spoiler

/*	Custom Module OnEnter Template
	
	Created By: ebmar
	Created On: December 14, 2019	*/

#include "k_inc_utility"
	
void main()
{
	// StartingConditional
	int iNPCTalkedTo;
	iNPCTalkedTo = GetGlobalBoolean("eb_talked_npc") == FALSE;
	
	// Participants
	object oPC = GetPartyMemberByIndex(0);		// This will be changed with *GetNearestCreature* method later
	object oPM1 = GetPartyMemberByIndex(1);		// --||--
	object oPM2 = GetPartyMemberByIndex(2);		// --||--
	object oNPC = GetObjectByTag("npc_tag");
	
	// Locations/Waypoints
	location lWP_PC = Location(Vector(102.0f, 101.0f), DIRECTION_NORTH);
	location lWP_PM1 = Location(Vector(100.0f, 101.0f), DIRECTION_NORTH);
	location lWP_PM2 = Location(Vector(104.0f, 101.0f), DIRECTION_NORTH);
	
	// Practically set PC as the party leader
	SetPartyLeader(NPC_PLAYER);
	
	// Checks if PC has *not* talked with the NPC
	if(iNPCTalkedTo)
	{
		// Starts the conversation with the NPC
		AssignCommand(oNPC, ActionStartConversation(oPC));
	}
	// Else, if they has --
	else
		{
			// Teleport the party members to each of their fixed locations subsequently
			UT_TeleportPartyMember(oPC, lWP_PC);
			DelayCommand(0.1f, UT_TeleportPartyMember(oPM1, lWP_PM1));
			DelayCommand(0.2f, UT_TeleportPartyMember(oPM2, lWP_PM2));
		}
}

 

will make the PC spawned at a location not as configured by the script. But then, by changing those instances of GetPartyMemberByIndex to this; as JC elaborated on his post -

	// Participants
	object oPC = GetFirstPC();
	object oPM1 = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_NOT_PC, oPC, 1);
	object oPM2 = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_NOT_PC, oPC, 2);

the PMs does spawned at the location as configured with the script, as well as the PC.

I was lucky had stumbled to that post earlier because like about hours later, I had to face this particular script issue.

Hope the information can be helpful to you, fellow Jedi. May the Force be with you. :cheers:

 

____________________________________________

 

Update: with input from @DarthParametric I have reconstructed the script using the wondrous #include taken from K1CP.

The updated script should pretty much looking like this -

Spoiler

/*	Custom Module OnEnter Template

	Created By: ebmar
	Created On: December 15, 2019
	Revised On: December 16, 2019

	Special Thanks To:
	- JCarter426 & DarthParametric
	- Qui-Gon Glenn for this -- "...comment your code to death. You will thank yourself later."

	Grab K1CP include from here -
	[https://github.com/KOTORCommunityPatches/K1_Community_Patch/blob/master/Source/cp_inc_k1.nss]	*/

#include "cp_inc_k1"

void main()
{
	// Participants
	object oNPC = GetObjectByTag("npc_tag");

	// Locations/Waypoints
	location lWP_PC = Location(Vector(/*float x=0.0f*/, /*float y=0.0f*/), /*float fOrientation*/);
	location lWP_PM1 = Location(Vector(/*float x=0.0f*/, /*float y=0.0f*/), /*float fOrientation*/);
	location lWP_PM2 = Location(Vector(/*float x=0.0f*/, /*float y=0.0f*/), /*float fOrientation*/);

	// Checks if PC has *not* talked with the NPC
	if(!GetGlobalBoolean("eb_talked_npc"))
	{
		// Starts the conversation with the NPC
		AssignCommand(oNPC, ActionStartConversation(GetFirstPC()));
	}
	/* Else, if PC *has talked* with the NPC and
	module *not* loaded from a saved game */
	else if(GetGlobalBoolean("eb_talked_npc") && !GetLoadFromSaveGame())
			{
				/* Teleport the party members to each of their fixed
				locations using *CP_PartyHerder* */
				CP_PartyHerder(lWP_PC, lWP_PM1, lWP_PM2);
			}
}

/*	P.S. In pre-revised version, it didn't include a load from save exclusion/!GetLoadFromSaveGame,
	hence causing someone that saved and load the game from the module, it'd loaded from the
	scripted locations, and not at their current ones. Thanks to DarthParametric for the input on
	using said function	*/

 

Edited by ebmar
Posted the revised version of the updated script using K1CP's #include

Share this post


Link to post
Share on other sites
6 minutes ago, DarthParametric said:

...be better off lifting the party member code from K1CP.  It has greater control.

Thank you for the heads-up! Yeah, I was always gets reminded myself about K1CP's party-herding method when I had to face party members teleporting matters. I'll look into how it works, and adapt myself to it.

Share this post


Link to post
Share on other sites

A good example of why you'd want to use the K1CP code rather than the above is when Bastila is removed during the early part of Dantooine. If you try to get a non-player party member there, you can inadvertently grab her, and accidentally move her out of position. JC added code to prevent that, after I ran into that very problem with an earlier version of the party herding functions.

  • Thanks 1

Share this post


Link to post
Share on other sites
59 minutes ago, DarthParametric said:

...good example of why you'd want to use the K1CP code rather than the above is when Bastila is removed during the early part of Dantooine. If you try to get a non-player party member there, you can inadvertently grab her, and accidentally move her out of position. JC added code to prevent that...

Oh, I see. Yeah, that makes very sense. Anyway, many thanks for the insight and assistance, as using K1CP code does wonder. I have updated the relevant post with the updated script that is using K1CP's #include. :cheers:

Share this post


Link to post
Share on other sites

Entry#15: TSL's Hologram

Apparently the hologram in TSL was a build-in blending additive. Guessing that by stripping off the alpha-channel from Holotex - texture used by the hologram as an overlay. The alpha-masking that were used by the texture was designed to reduce the blending effect [aside of to create scan-line overlays] from the additive, the same as why in lightsaber's blade-texture its alpha was always in solid-white state. Any darker than that then the glowing effect will be reduced.

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.