Jump to content

Home

Qui-Gon's Script Shack


Qui-Gon Glenn

Recommended Posts

  • Replies 352
  • Created
  • Last Reply

Okay, so I'm making a script for KotOR II to work in the onEndRound field for a character. Basically, this would make it so that every time you're in combat, and someone is currently attacking you, then you get a decrease to your attack stats and accuracy (dexterity). But, if you're in combat and no one is attacking you, then you get a bonus to your to your attack stats and accuracy (dexterity). And if you're not in combat, it returns your stats to their normal state. What I would like to know is if this script is actually set up correctly to do that, and if there are any holes in my scripting.

 

void main()
{

  object oAttacker = GetGoingToBeAttackedBy(OBJECT_SELF);

  effect eAtkBonusM = EffectAttackIncrease(3, ATTACK_BONUS_ONHAND);

  effect eAtkBonusO = EffectAttackIncrease(4, ATTACK_BONUS_OFFHAND);

  effect eDamBonus = EffectDamageIncrease(3, DAMAGE_TYPE_UNIVERSAL);

  effect eDexBonus = EffectAbilityIncrease(ABILITY_DEXTERITY, 2);

  effect eAtkBonusMN = EffectAttackDecrease(3, ATTACK_BONUS_ONHAND);

  effect eAtkBonusON = EffectAttackDecrease(4, ATTACK_BONUS_OFFHAND);

  effect eDamBonusN = EffectDamageDecrease(3, DAMAGE_TYPE_UNIVERSAL);

  effect eDexBonusN = EffectAbilityDecrease(ABILITY_DEXTERITY, 2);

     if( oAttacker == OBJECT_INVALID)
     {

        if( GetIsInCombat(OBJECT_SELF, TRUE)
        {   

           ClearAllEffects();

           ApplyEffectToObject(DURATION_TYPE_PERMANENT, eAtkBonusM, OBJECT_SELF);

           ApplyEffectToObject(DURATION_TYPE_PERMANENT, eAtkBonusO, OBJECT_SELF);

           ApplyEffectToObject(DURATION_TYPE_PERMANENT, eDamBonus, OBJECT_SELF);

           ApplyEffectToObject(DURATION_TYPE_PERMANENT, eDexBonus, OBJECT_SELF);

        }

     }

     if( oAttacker != OBJECT_INVALID)
     {
        ClearAllEffects();

        ApplyEffectToObject(DURATION_TYPE_PERMANENT, eAtkBonusMN, OBJECT_SELF);

        ApplyEffectToObject(DURATION_TYPE_PERMANENT, eAtkBonusON, OBJECT_SELF);

        ApplyEffectToObject(DURATION_TYPE_PERMANENT, eDamBonusN, OBJECT_SELF);

        ApplyEffectToObject(DURATION_TYPE_PERMANENT, eDexBonusN, OBJECT_SELF);
     }

     if( !GetIsInCombat(OBJECT_SELF, TRUE)
     {
        ClearAllEffects();
     }

}

Link to comment
Share on other sites

It does heal them if they have max VP, but for 0 points and then you get the floating green zero and a report in the feedback screen. You might not want that in some situations.

Aaaaaaaah, I hadn't considered that.

 

 

Okay, so I'm making a script for KotOR II to work in the onEndRound field for a character. Basically, this would make it so that every time you're in combat, and someone is currently attacking you, then you get a decrease to your attack stats and accuracy (dexterity). But, if you're in combat and no one is attacking you, then you get a bonus to your to your attack stats and accuracy (dexterity). And if you're not in combat, it returns your stats to their normal state.

All right, interesting premise.

What I would like to know is if this script is actually set up correctly to do that, and if there are any holes in my scripting.

All right, first thing that comes to mind is ClearAllEffects might clear stuff you don't want cleared. There are a few ways to get around that, though.

 

Second thing that comes to mind is these are permanent effects but the OnEndRound script fires every three seconds during combat. This would lead to a slippery slope, with more and more bonuses or penalties applied until they're ridiculously high or low in a matter of seconds. Change those duration types to temporary and set a duration of three seconds and you should be fine.

 

Third thing is I'm not sure if OnEndRound ever fires if you aren't in combat, so the reset might never happen. I could be wrong though.

 

Last thing is GetGoingToBeAttackedBy. The notes say not to use it. But maybe it works like it seems.

Link to comment
Share on other sites

What are the ways to get around the clear all effects issues?

 

Also, revised the scripting as per your suggestions, here it is:

 

void main()
{

  object oAttacker = GetGoingToBeAttackedBy(OBJECT_SELF);

  effect eAtkBonusM = EffectAttackIncrease(3, ATTACK_BONUS_ONHAND);

  effect eAtkBonusO = EffectAttackIncrease(4, ATTACK_BONUS_OFFHAND);

  effect eDamBonus = EffectDamageIncrease(3, DAMAGE_TYPE_UNIVERSAL);

  effect eDexBonus = EffectAbilityIncrease(ABILITY_DEXTERITY, 2);

  effect eAtkBonusMN = EffectAttackDecrease(3, ATTACK_BONUS_ONHAND);

  effect eAtkBonusON = EffectAttackDecrease(4, ATTACK_BONUS_OFFHAND);

  effect eDamBonusN = EffectDamageDecrease(3, DAMAGE_TYPE_UNIVERSAL);

  effect eDexBonusN = EffectAbilityDecrease(ABILITY_DEXTERITY, 2);

     if( oAttacker == OBJECT_INVALID)
     {

        if( GetIsInCombat(OBJECT_SELF, TRUE)
        {   

           ClearAllEffects();

           ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eAtkBonusM, OBJECT_SELF, 3.0);

           ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eAtkBonusO, OBJECT_SELF, 3.0);

           ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eDamBonus, OBJECT_SELF, 3.0);

           ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eDexBonus, OBJECT_SELF, 3.0);

           SetLocalBoolean(OBJECT_SELF, 60, TRUE);

           SetLocalBoolean(OBJECT_SELF, 61, FALSE);

        }

     }

     if( oAttacker != OBJECT_INVALID)
     {
        ClearAllEffects();

        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eAtkBonusMN, OBJECT_SELF, 3.0);

        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eAtkBonusON, OBJECT_SELF, 3.0);

        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eDamBonusN, OBJECT_SELF, 3.0);

        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eDexBonusN, OBJECT_SELF, 3.0);

        SetLocalBoolean(OBJECT_SELF, 60, FALSE);

        SetLocalBoolean(OBJECT_SELF, 61, TRUE);
     }

}

 

And to remove all effects after combat, I put this into the heartbeat script:

 

void main()
{

  if( !GetIsInCombat(OBJECT_SELF, TRUE)
  {

     if( GetLocalBoolean(OBJECT_SELF, 60, TRUE) || GetLocalBoolean(OBJECT_SELF, 61, TRUE)
     {
        ClearAllEffects();

        SetLocalBoolean(OBJECT_SELF, 60, FALSE);

        SetLocalBoolean(OBJECT_SELF, 61, FALSE);
     }
  }
}

Link to comment
Share on other sites

RemoveEffect should work since it's all in one script:

// 87: Remove eEffect from oCreature.
// * No return value
void RemoveEffect(object oCreature, effect eEffect);

K2 also has RemoveEffectByID and RemoveEffectByExactMatch if that doesn't work.

 

I also forgot to mention before you should probably check if applying effects to both hands stacks when you're using a two-handed weapon.

Link to comment
Share on other sites

RemoveEffect should work since it's all in one script:

// 87: Remove eEffect from oCreature.
// * No return value
void RemoveEffect(object oCreature, effect eEffect);

K2 also has RemoveEffectByID and RemoveEffectByExactMatch if that doesn't work.

 

I also forgot to mention before you should probably check if applying effects to both hands stacks when you're using a two-handed weapon.

 

All right, will do. Thanks JC. I'll report back in a bit.

Link to comment
Share on other sites

I'm trying to invent a 'smart script' to automatically heal yourself(Here I mean your companion to auto-heal themselves), but it doesn't do anything at all in-game. The script is K1, though if it ever works, I'll adapt a TSL version:

 

Show spoiler
(hidden content - requires Javascript to show)
void main()
{

ExecuteScript("k_hen_heartbt02", OBJECT_SELF);

object oPC = OBJECT_SELF;
int CHEALTH = GetCurrentHitPoints(oPC);
int MHEALTH = GetMaxHitPoints(oPC);
object oFriend = GetNearestCreature(CREATURE_TYPE_RACIAL_TYPE, 6, OBJECT_SELF, CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC, CREATURE_TYPE_IS_ALIVE, 1);

object oHEAL1 = GetItemPossessedBy(oPC, "g_i_medeqpmnt01");
object oHEAL2 = GetItemPossessedBy(oPC, "g_i_medeqpmnt02");
object oHEAL3 = GetItemPossessedBy(oPC, "g_i_medeqpmnt03");

MHEALTH/2;

while(CHEALTH < MHEALTH);
{

	if(GetHasSpell(10, oPC) && GetDistanceBetween(oPC, oFriend) < 15.0)
	{
		if(GetHasSpell(28, oPC) && GetDistanceBetween(oPC, oFriend) < 15.0)
		{
			SignalEvent(oPC, EventSpellCastAt(oPC, 28, FALSE));
		}
		else
		{
			SignalEvent(oPC, EventSpellCastAt(oPC, 10, FALSE));
		}
	}

	if(GetIsObjectValid(oHEAL1))
	{
		if(GetIsObjectValid(oHEAL2))
		{
			if(GetIsObjectValid(oHEAL3))
			{
				SignalEvent(oPC, EventActivateItem(oHEAL3, GetLocation(oPC)));
			}
			else
			{
				SignalEvent(oPC, EventActivateItem(oHEAL2, GetLocation(oPC)));
			}
		}
		else
		{
			SignalEvent(oPC, EventActivateItem(oHEAL1, GetLocation(oPC)));
		}
	}
	else
	{
	}


}
}

 

EDIT: I'll expand and explain the script. Sorry for not doing so earlier.

 

This script is to be placed inside, or related to, the heartbeat script. It is supposed to check if you meet the prerequisites for the force power cure and then checks if you have the advanced form, Heal, and if yes, it casts it; if you don't have Heal, it casts cure.

 

IF you don't have either power, it embarks on a jpourney to see if you have a medpac, then an advanced medpac, and finally a lifepack. If one of the tiers of healing items returns false, the script will use the previous tier item, or if tier one fails, nothing happens.

 

I might also mention that all of this only happens if you have less than half your max health(I hope I set that part up right with

"

int CHEALTH = GetCurrentHitPoints(oPC);

int MHEALTH = GetMaxHitPoints(oPC);

MHEALTH/2;

 

while(CHEALTH < MHEALTH)

").

Link to comment
Share on other sites

How can i get an npc to move near the pc during dialog?

 

This is my code currently

 location lMe=GetLocation(GetFirstPC());
ActionDoCommand(SetCommandable(TRUE,oNPC));
AssignCommand (oNPC,ActionForceMoveToLocation(lMe,FALSE));

 

It works, but he ends up inside the pc, not near him. This is for k1.

Link to comment
Share on other sites

// 383: Force the action subject to move to oMoveTo.
void ActionForceMoveToObject(object oMoveTo, int bRun=FALSE, float fRange=1.0f, float fTimeout=30.0f);

So something like this:

AssignCommand(oNPC, ActionForceMoveToObject(GetFirstPC(), 0, 1.0, 30.0));

You shouldn't have to use SetCommandable() as creatures are always set to commandable by default, and it doesn't affect movement anyway. All it affects is whether the character can queue actions; setting it to false is essentially stunning them without the stun effect. Since you haven't done that (I think) you can ignore it.

Link to comment
Share on other sites

Huh, i guess my door isn't opening in time.

I have, in another code, fired from another node,

  ActionPauseConversation();
 object oDoor = GetObjectByTag("door1_elv01");
 SetLocked(oDoor,FALSE);
 AssignCommand(oDoor, ActionOpenDoor(oDoor));
 ActionWait(3.0);
 ActionResumeConversation();

 

The door opens, but i think its not working right.

Link to comment
Share on other sites

The commandable effects wheter you can "click" an NPC. Very handy for preventing repeat conversations, and thus XP-exploits. Primarily used for during the 'run away and be deleted'

 

Doors can block NPC movement. I've had a lot of issues with that in the Nar Shaddaa cantina, and in the end just gave up on trying any proper pathing there, since it was a nightmare.

 

Pause, resume work for cutscenes, not for the VO. So yeah. From what I hear in KOTOR1 you can't partially skip (like KOTOR2 can), which sounds extremely frustrating to me. Sorry I can't really help there either...

 

EDIT: Looking at the script, ActionWait() doesn't work for that. So it might be that prevents it from working properly.

Maybe use

DelayCommand(3.0, ExecuteScript("contalk", OBJECT_SELF));

instead, with the new script (contalk.ncs) being the continue dialog (usuable for much more than just this one convo obviously).

Link to comment
Share on other sites

I am still getting the teleportation issue. I got the dialog to not be skippable, but my npc won't move still.

I have 2 codes from 2 different dialog nodes.

 

void main()
{

 object oDoor = GetObjectByTag("m55aa_elv01");
 SetLocked(oDoor,FALSE);
 AssignCommand(oDoor, ActionOpenDoor(oDoor));

 object oNPC=GetObjectByTag("n_shol");    

 float x=101.39;                          
 float y=148.00;                        
 float z=36.32;                        

 int bRun=FALSE;                                                   

 vector vExit=Vector(x,y,z);
 location lExit=Location(vExit,0.0f);
 ActionDoCommand(SetCommandable(TRUE,oNPC));
 DelayCommand(3.0, AssignCommand (oNPC,ActionForceMoveToLocation(lExit,bRun)));

}

void main() 
{


object oNPC = GetObjectByTag("nshol");

DelayCommand(3.0, AssignCommand(oNPC, ActionForceMoveToObject(GetFirstPC(), 0, 1.0, 30.0)));



}

Link to comment
Share on other sites

I feel a bit silly asking this, but I really haven't done much modding for K1 at all... so my question is: is it not possible to play animations from animations.2da and dialoganimations.2da in K1? I am so used to it in K2 that this seems hard to believe. But all my efforts thus far have been in vain.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.


×
×
  • Create New...