Note: LucasForums Archive Project
The content here was reconstructed by scraping the Wayback Machine in an effort to restore some of what was lost when LF went down. The LucasForums Archive Project claims no ownership over the content or assets that were archived on archive.org.

This project is meant for research purposes only.

Force Removal Script?

Page: 1 of 1
 KnightFxr
08-24-2004, 12:27 AM
#1
I've been scripting a lot with force powers recently and ran into a snag. I'm trying to write a conditional into my script that removes the force power effects if you attack a creature. I've tried a lot of various methods, and I'm going nowhere fast. Any suggestions would be extremely helpful! Thanks!
 tk102
08-24-2004, 2:28 AM
#2
Hello,
I assume the problem you're having is scripting the when (not how) to remove the Force effects. Is this correct?

Well it is tricky because there is no way that your spell script can do it alone -- KotOR does not provide a DURATION constant that expires when combat ensues.

Here's my suggestion. If you haven't tried it already take a look at the k_ai_master.nss which uses GN_DetermineCombatRound function during combat events (event #3001- 3003). This function is in the k_inc_generic.nss file. In that function you could add a call to a subroutine that you write yourself that removes the force power if it is in effect.

Example:
k_inc_generic.nss

void GN_DetermineCombatRound(object oIntruder = OBJECT_INVALID)
{
// ... snip ...
TurnOffSpecialFP(); // here is your function
GN_SetLastRoundData();
int nPartyAI = GetPartyAIStyle();
// etc. etc.. snip

then elsewhere in k_inc_generic.nss

void TurnOffSpecialFP()
{
/* in this example, which only works
for the PC, each effect is cycled through
looking for a subtype of Extraordinary
(which you will have to set in your
force power script that's ref'd in spells.2da) */

object oPC=GetFirstPC();
effect eThisEffect;
eThisEffect = GetFirstEffect(oPC);
while (GetIsEffectValid(eThisEffect))
{
if (GetEffectSubType(eThisEffect) == SUBTYPE_EXTRAORDINARY)
{
RemoveEffect(oPC, eThisEffect);
}
//Get next effect on the target
eThisEffect = GetNextEffect(oPC);
}
}

and in your force power script (ref'd by spells.2da) be sure to use

ExtraordinaryEffect(eFX);
where eFX is any effect that you apply to the PC.

Hope that works. It's all theory. :)

Edit: forgot to close the comment with */
 KnightFxr
08-24-2004, 4:27 AM
#3
In theory that seems like an excellent idea. However, it also doesn't seem to be getting me anywhere. Is there maybe conditional I could write up that would check to see if the PC has made an attack attempt, and remove the effects if TRUE?
.
.
.
Should have paid a bit more attention in Comp Sci...
 tk102
08-24-2004, 9:53 AM
#4
The problem with that is there is no way to trigger that kind of script. So you have to use exisiting event triggers. k_ai_master.nss handles all the default .utc OnEvent scripts so that's why I led you there.

What exactly have you attempted to do without success?
 beancounter
08-24-2004, 6:53 PM
#5
Originally posted by tk102
Hello,
I assume the problem you're having is scripting the when (not how) to remove the Force effects. Is this correct?

Well it is tricky because there is no way that your spell script can do it alone -- KotOR does not provide a DURATION constant that expires when combat ensues.

Here's my suggestion. If you haven't tried it already take a look at the k_ai_master.nss which uses GN_DetermineCombatRound function during combat events (event #3001- 3003). This function is in the k_inc_generic.nss file. In that function you could add a call to a subroutine that you write yourself that removes the force power if it is in effect.

Example:
k_inc_generic.nss

void GN_DetermineCombatRound(object oIntruder = OBJECT_INVALID)
{
// ... snip ...
TurnOffSpecialFP(); // here is your function
GN_SetLastRoundData();
int nPartyAI = GetPartyAIStyle();
// etc. etc.. snip

then elsewhere in k_inc_generic.nss

void TurnOffSpecialFP()
{
/* in this example, which only works
for the PC, each effect is cycled through
looking for a subtype of Extraordinary
(which you will have to set in your
force power script that's ref'd in spells.2da) */

object oPC=GetFirstPC();
effect eThisEffect;
eThisEffect = GetFirstEffect(oPC);
while (GetIsEffectValid(eThisEffect))
{
if (GetEffectSubType(eThisEffect) == SUBTYPE_EXTRAORDINARY)
{
RemoveEffect(oPC, eThisEffect);
}
//Get next effect on the target
eThisEffect = GetNextEffect(oPC);
}
}

and in your force power script (ref'd by spells.2da) be sure to use

ExtraordinaryEffect(eFX);
where eFX is any effect that you apply to the PC.

Hope that works. It's all theory. :)

Edit: forgot to close the comment with */


Cases 3001, 3002 & 3003 do not fire when the PC attacks.
You should stick your function call in Case 1005 - Which fires when a creature has been attacked.

Just add the following lines in the case:

if(GetLastAttacker() == GetFirstPC())
{
TurnOffSpecialFP();
}

The script will fire when your PC attacks another creature. I tested it just to be sure and it works.
 KnightFxr
08-24-2004, 11:33 PM
#6
That sounds like my answer, especially since you said you've gotten it to work. But I'm still having trouble. When I go to compile k_ai_master, everything compiles just fine. But ingame, everytime I go to talk to a character, nothing happens... then the keyboard functions are locked out (i.e. i wouldnt be able to access my inventory via the hotkey). It almost seems like the function is getting stuck in a loop of some sort. Ever had this problem?
 beancounter
08-25-2004, 12:27 AM
#7
I never had that. When programming, it is sometimes helpful to test out each section of code by itself to find the problem area. Below is the block of code I used to verify that it should work. Just copy and paste the block between the custom mod sections into your K_ai_master, compile it and go attack someone with your PC. Then check the feedback screen and you should see the following message: "(Creature Name) Case 1005". Let me know if that works for you.

case 1005: //KOTOR_DEFAULT_EVENT_ON_ATTACKED
{

// CUSTOM MOD - START COPY HERE
string cmMessage;
cmMessage = GetName(OBJECT_SELF) + " CASE 1005";

if(GetLastAttacker() == GetFirstPC())
{
SendMessageToPC(GetFirstPC(), cmMessage);
}
// END CUSTOM MOD - END COPY HERE


//Shout that I was attacked
SpeakString("GEN_I_WAS_ATTACKED", TALKVOLUME_SILENT_TALK);
//SpeakString("GEN_COMBAT_ACTIVE", TALKVOLUME_SILENT_TALK);
if(GetCommandable() && !GN_GetSpawnInCondition(SW_FLAG_AI_OFF))
{
if(!GetIsObjectValid(GetAttemptedAttackTarget()) && !GetIsObjectValid(GetAttemptedSpellTarget()) && !GetIsObjectValid(GetAttackTarget()))
{
GN_MyPrintString("GENERIC DEBUG *************** Determine Combat Round from On Attacked");
GN_DetermineCombatRound();
//Shout that I was attacked
SpeakString("GEN_I_WAS_ATTACKED", TALKVOLUME_SILENT_TALK);
//SpeakString("GEN_COMBAT_ACTIVE", TALKVOLUME_SILENT_TALK);
}
else if(GetCurrentAction() == ACTION_QUEUEEMPTY)
{
GN_MyPrintString("GENERIC DEBUG *************** Determine Combat Round from On Attacked");
GN_DetermineCombatRound();
//Shout that I was attacked
SpeakString("GEN_I_WAS_ATTACKED", TALKVOLUME_SILENT_TALK);
}
}
if(GN_GetSpawnInCondition(SW_FLAG_EVENT_ON_ATTACKE D))
{
SignalEvent(OBJECT_SELF, EventUserDefined(1005));
}
}
 tk102
08-25-2004, 1:18 AM
#8
Thanks for the follow-up beancounter.
Page: 1 of 1