PDA

View Full Version : Firing a script.


Hangout Hermit
02-02-2007, 05:52 PM
Hello all! :waive1:

Last night i was looknig through KotOR2 scripts and i spotted this one:
// 746: SetAreaFogColor
// Set the fog color for the area oArea.

void SetAreaFogColor( object oArea, float fRed, float fGreen, float fBlue );
Looks cool, huh!

I made it into a script like so...
// By Hangout Hermit.
// Will set up fog color depending on dark or light.

#include "k_inc_debug"
#include "k_inc_utility"

void main(){
if(IsDark()==TRUE){

float fRed = 1.00;
float fGreen = 0.15;
float fBlue = 0.10;
SetAreaFogColor( GetFirstPC(), fRed, fGreen, fBlue );
}

else{

float fRed = 1.40;
float fGreen = 1.40;
float fBlue = 2.40;
SetAreaFogColor( GetFirstPC(), fRed, fGreen, fBlue );

}

return;

}

Now my plan is to get this onto an armband so that when you equip it, whatever module you are in it will set the fog colour. Is this possible? And if so how?

Thanks.

H-h

stoffe
02-02-2007, 06:03 PM
H
Now my plan is to get this onto an armband so that when you equip it, whatever module you are in it will set the fog colour. Is this possible? And if so how?


It's not possible to directly fire a script when an item is equipped, since there are no event hooks that are run when this happens. I can think of two workarounds for this:
Make an armband that an be activated like a forearm shield, which will run the script when activated. This is the easiest and most straightforward way of doing it, and it's pretty easy to make it compatible with other mods, but it requires the player to actively use the armband for the script to run.


Change the OnHeartbeat event AI script to continually check if the armband has been equipped, and if so run your script. This will make it happen automatically, but there can be a delay of several seconds between the armband being equipped and anything happens. It also requires you to edit one of the standard game scripts, which makes your mod incompatible with any other mod that does the same.


* * *

Oh, and...

SetAreaFogColor( GetFirstPC(), fRed, fGreen, fBlue );

...should be...

SetAreaFogColor( GetArea(GetFirstPC()), fRed, fGreen, fBlue );

...since the function wants an area object as first parameter, and the player isn't an area. :)

Dashus
02-02-2007, 09:32 PM
On your 'else' clause: if they are standard RGB floats then each value should be 0.0 -> 1.0

Hangout Hermit
02-03-2007, 03:54 AM
It's not possible to directly fire a script when an item is equipped, since there are no event hooks that are run when this happens. I can think of two workarounds for this:

1. Make an armband that an be activated like a forearm shield, which will run the script when activated. This is the easiest and most straightforward way of doing it, and it's pretty easy to make it compatible with other mods, but it requires the player to actively use the armband for the script to run.

2. Change the OnHeartbeat event AI script to continually check if the armband has been equipped, and if so run your script. This will make it happen automatically, but there can be a delay of several seconds between the armband being equipped and anything happens. It also requires you to edit one of the standard game scripts, which makes your mod incompatible with any other mod that does the same.

I have gone for number 2 as i am useless at .Uti editing. I have edited this "k_def_heartbt01.nss" so that whenever you enter an area whatever is in that module will check the script to see the fog color. Here is the script i have changed.
#include "k_inc_switch"
#include "k_inc_debug"
#include "k_inc_utility"

void main()
{
{
if(IsDark()==TRUE){

float fRed = 1.00;
float fGreen = 0.15;
float fBlue = 0.10;
SetAreaFogColor( GetArea(GetFirstPC()), fRed, fGreen, fBlue );
}

else{

float fRed = 1.40;
float fGreen = 1.40;
float fBlue = 2.40;
SetAreaFogColor( GetArea(GetFirstPC()), fRed, fGreen, fBlue );

}

return;
}
ExecuteScript("k_ai_master", OBJECT_SELF, KOTOR_DEFAULT_EVENT_ON_HEARTBEAT);
/*
object oEnemy = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF,1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);

if(!GN_GetSpawnInCondition(SW_FLAG_AI_OFF))
{
if(GN_GetSpawnInCondition(SW_FLAG_AMBIENT_ANIMATIO NS) || GN_GetSpawnInCondition(SW_FLAG_AMBIENT_ANIMATIONS_ MOBILE))
{
string sWay = "WP_" + GetTag(OBJECT_SELF) + "_01";
int nSeries = GetLocalNumber(OBJECT_SELF, WALKWAYS_SERIES_NUMBER);
if(!GetIsObjectValid(GetObjectByTag(sWay)) && nSeries <= 0)
{
if(GetCurrentAction(OBJECT_SELF) != ACTION_MOVETOPOINT)
{
if(!GN_GetIsFighting(OBJECT_SELF) && !GetIsObjectValid(oEnemy))
{
GN_PlayAmbientAnimation();
}
}
}
}
}
if(GN_GetSpawnInCondition(SW_FLAG_EVENT_ON_HEARTBE AT))
{
SignalEvent(OBJECT_SELF, EventUserDefined(1001));
}
*/
}

*****

Notice i have changed the:

SetAreaFogColor( GetArea(GetFirstPC()), fRed, fGreen, fBlue ); ;)

stoffe
02-03-2007, 08:42 AM
I have gone for number 2 as i am useless at .Uti editing. I have edited this "k_def_heartbt01.nss" so that whenever you enter an area whatever is in that module will check the script to see the fog color. Here is the script i have changed.

#include "k_inc_switch"
#include "k_inc_debug"
#include "k_inc_utility"

void main()
{
{
if(IsDark()==TRUE){

float fRed = 1.00;
float fGreen = 0.15;
float fBlue = 0.10;
SetAreaFogColor( GetArea(GetFirstPC()), fRed, fGreen, fBlue );
}

else{

float fRed = 1.40;
float fGreen = 1.40;
float fBlue = 2.40;
SetAreaFogColor( GetArea(GetFirstPC()), fRed, fGreen, fBlue );

}

return;
}
ExecuteScript("k_ai_master", OBJECT_SELF, KOTOR_DEFAULT_EVENT_ON_HEARTBEAT);
}



There are a few problems with this as I see it.
Most importantly k_def_heartbt01 is not used as heartbeat script for the player or party members, it's used for all other characters in the game. The script k_hen_heartbt01 is used for the player and party members.


Second, you have no conditional checks for when the fog change should occur, other than if the character currently in dialog with an NPC is Darkside.

The IsDark() function is only meant to be used in dialog conditional scripts since it uses GetPCSpeaker() to check. This function is used in dialog scripts to get the player character currently speaking with the NPC. You'll need to use GetGoodEvilValue(GetFirstPC()) instead, which returns a value on a scale between 0 and 100, where 0 is Darkside Mastery, 40 is the boundrary between darkside and neutral, 60 is the boundrary between neutral and lightside, and 100 is lightside mastery.

Further, the Fog would be changed every 3 seconds for every creature in the area (if you use k_def_heartbt01) or every party member (if you use k_hen_heartbt01), meaning it's usually done 3 times every 3 seconds. It should be enough that it is done once when the player equips an armband, if you haven't changed your original plan. You can check if the one running the script is the player by using an if-statement with GetIsPlayerMadeCharacter(OBJECT_SELF) as condition. You can check for newly equipped armbands by storing the tag of the currently equipped items in the armband slot in a global string variable and then check on each heartbeat if the tag of the currently equipped item differ, and if it has the tag of your fog armband.


Third, see the part marked in yellow in your quoted script above. This would stop execution of the script right there, preventing it from ever running any of the default heartbeat actions, essentially breaking the functionality the script usually provides.


Finally, as Dashus mentioned above, the scale of the RGB parameters is likely ranging from 0.0 (white) to 1.0 (full Red, Green, Blue), so you should adjust the values of your non-darkside fog color accordingly.


Modifying your k_hen_heartbt01 script accordingly you might end up with something looking like below. Note that this requires two Global string variables with the names ST_LAST_PC_EQUIP_7 and ST_LAST_PC_EQUIP_8 to be added to the globalcat.2da file in order to work correctly. You'll also have to change armbandtag to the tag set in the UTI of the armband item you wish to check if it's equipped:


// k_hen_heartbt01.nss

#include "k_inc_switch"

int ST_EquipmentChanged(int iSlot);
int ST_IsEquipped(int iSlot, string sTag, object oTarget=OBJECT_SELF);


// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// The main function
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void main() {
// ST: Only do this if the Exile is running this script...
if (GetIsPlayerMadeCharacter(OBJECT_SELF)) {
// ST: Set the Tag of the armband item to check for here.
string sTag = "armbandtag";

// ST: Check if the content in either of the armband slots has changed,
// and that the currently equipped item is the special armband.
if ((ST_EquipmentChanged(INVENTORY_SLOT_LEFTARM) && ST_IsEquipped(INVENTORY_SLOT_LEFTARM, sTag))
|| (ST_EquipmentChanged(INVENTORY_SLOT_RIGHTARM) && ST_IsEquipped(INVENTORY_SLOT_RIGHTARM, sTag)))
{
// ST: Change the area fog color depending on Dark/Light alignment
// of the player character.
int bDark = (GetGoodEvilValue(OBJECT_SELF) < 40);
float fRed = (bDark ? 1.00 : 1.40);
float fGreen = (bDark ? 0.15 : 1.40);
float fBlue = (bDark ? 0.10 : 2.40);
SetAreaFogColor( GetArea(OBJECT_SELF), fRed, fGreen, fBlue );
}
}

// ST: Run default heartbeat script actions...
ExecuteScript("k_ai_master", OBJECT_SELF, KOTOR_HENCH_EVENT_ON_HEARTBEAT);
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// ST: Keeps track of if the content of the specified equipment slot on
// the player has changed since the last time the function was run.
// This requires Global String variables with the names
// ST_LAST_PC_EQUIP_ followed by the equipment slot number listed
// in NWSCRIPT.NSS as INVENTORY_SLOT_*.
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int ST_EquipmentChanged(int iSlot) {
if (!GetIsPlayerMadeCharacter(GetFirstPC()))
return FALSE;

string sOld = GetGlobalString("ST_LAST_PC_EQUIP_" + IntToString(iSlot));
string sTag = GetTag(GetItemInSlot(iSlot, GetFirstPC()));

if (sTag != sOld) {
SetGlobalString("ST_LAST_EQUIP_" + IntToString(iSlot), sTag);
return TRUE;
}
return FALSE;
}


// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// ST: Wrapper function for checking if the target has an item with the
// specified tag equipped in the specified equipment slot.
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int ST_IsEquipped(int iSlot, string sTag, object oTarget=OBJECT_SELF) {
object oItem = GetItemInSlot(iSlot, oTarget);
return (GetIsObjectValid(oItem) && (GetTag(oItem) == sTag));
}