Jump to content

Home

Qui-Gon's Script Shack


Qui-Gon Glenn

Recommended Posts

Please look at this thread for an idea as to what I would like to do. New Hybrid Saber Crystals Help Please. I am not sure this can be done with a script but if it can be and would be easier I am all for that and very interested in learning how to do it.

 

I should clarify I am requesting help in the form of 1) is this even possible with a script? 2) a mentor who would help me along the way and work with me on creating the script 3) if it is a good idea and you want to take over to get it posted by all means run with with but please credit me with the idea lol.

 

I am really new to this never totally scripted before so it could be slow going but with the right input I might surprise myself and go faster than I expect.

Link to comment
Share on other sites

  • Replies 352
  • Created
  • Last Reply

Here are two basic templates that should handle the job (well, two and a half); you just need to replace the stuff in quotes with the correct information, and repeat stuff as needed. The first checks if a container has the crystal you want:

int StartingConditional() {

object oPLC = GetObjectByTag("plc", 0);
string sTag = "tag";
object oCrystal = GetItemPossessedBy(oPLC, sTag)

if(GetIsObjectValid(oCrystal)) return TRUE;
return FALSE;

}

You would attach this to a dialogue node... I'd do it as a player node; have the computer say "select the crystal you would like to modify" and then you choose one from the list it gives you, conditional script attached to each node. Then the next node gives you the list of which ones you can blend it with, in a similar fashion.

 

Now, for K1 you would have to create a different conditional script for every crystal. It would just be copy/paste work, put in a different tag. With K2 you wouldn't have to do this, though; you could create a universal script:

int StartingConditional() {

object oPLC = GetObjectByTag("plc", 0);
string sTag = GetScriptStringParameter();
object oCrystal = GetItemPossessedBy(oPLC, sTag)

if(GetIsObjectValid(oCrystal)) return TRUE;
return FALSE;

}

Then you would just have to enter the appropriate tag in the string parameter of each dialogue node.

 

You might also want to have different conditionals, like "there aren't any crystals" or "a foreign object is present". That would be a bit more complicated.

 

The second script destroys two crystals and then creates a new one:

void main() {

object oPLC = GetObjectByTag("plc", 0);
string sTag1 = "tag1";
object oCrystal1 = GetItemPossessedBy(oPLC, sTag1)
string sTag2 = "tag2";
object oCrystal2 = GetItemPossessedBy(oPLC, sTag2)
string sNewTag = "newtag";

ActionTakeItem(oCrystal1, oPLC);
ActionTakeItem(oCrystal2, oPLC);
CreateItemOnObject(sNewTag, oPLC, 1, 0);

}

It could be converted to delete three, four, and so on; just duplicate the string sTag, object oCrystal, and ActionTakeItem lines, and adjust the information as required.

 

 

 

Now, I have a conundrum of my own. I was working on a script and I thought an efficient way to do it would be to use a switch for the string parameter. However, I wasn't sure if this is possible. I believe I've seen it done before, but I couldn't find anything by searching. I eventually did it with if trees instead... it was probably easier with ifs, actually. But I'm still curious. I believe it should look something like:

case "whatever":

...but you know how the engine is. Anyway, just curious... not a big deal. If any of you remember seeing something like this, just let me know.

Link to comment
Share on other sites

  • 2 weeks later...

Alright, so I've come here with an on enter script filled with conditionals. Now my only problem with this script while compiling, at least so far, is that I keep getting syntax errors at the && symbols in lines 52, 78 and 103, or all the lines I've put in red. I believe it has something to do with the parentheses on the ends of each line but I'm not entirely sure. Could anyone please help?

 

(The commented out lines with stars in them are there to help me keep track of what's happening in the script.)

 

#include "k_inc_debug" 
#include "k_inc_utility" 

void main() 
{ 

//***** DEFINING THE OBJECTS *****\\

object oPC = GetFirstPC();

object oHound = GetObjectByTag("g_hound01");

object oCantDoor = GetObjectByTag("d_654_dor01");

object oSwooper = GetObjectByTag("swoopmcx01");

//***** DEFINING THE CONDITIONAL CHECKS *****\\

              int ncheck = GetGlobalNumber("dt_num01");

 int iResult = ((GetGlobalBoolean("dt_check01")));

 int iResult2 = ((GetGlobalBoolean("dt_check02")));

 int iResult3 = ((GetGlobalBoolean("dt_check03")));

 int iResult4 = ((GetGlobalBoolean("dt_check04")));

//***** BEGINNING CONDITIONAL FOR SPAWN *****\\

if (!GetLocalBoolean(OBJECT_SELF, 40) && (GetEnteringObject() == GetFirstPC())) { 

  if (ncheck != 5)
  {

SetLocalBoolean(OBJECT_SELF, 40, TRUE); 

vector cPosition=Vector(29.7199993133545,-32.4500007629395,0.06339);
location lHound=Location(cPosition,175.01396);

   object oCre = CreateObject(OBJECT_TYPE_CREATURE, "g_hound01", lHound); 


   }

}

//***** CONDITIONAL FOR NEVER TALKING *****\\

[color="Red"]   if (iResult == TRUE) && (!GetLocalBoolean(OBJECT_SELF, 41) && (GetEnteringObject() == GetFirstPC())) {[/color]

DestroyObject(oHound);

SetLocalBoolean(OBJECT_SELF, 41, TRUE); 


//***** CONDITIONAL FOR CHECKING IF PC ENTERED IN FROM CLOSE TO CUTSCENE POINT *****\\

if( GetDistanceBetween(oCantDoor, oPC) <= 5.0 ) {

AssignCommand(oSwooper, ActionStartConversation(oPC, "dt_man_dist"));

                                                }

//***** CONDITIONAL FOR DID NOT ENTER THE AREA CLOSE TO CUTSCENE POINT*****\\

if( GetDistanceBetween(oCantDoor, oPC) > 5.0 ) {

SetGlobalBoolean(dt_304_trig, FALSE);

                                               }
                                                                 }

//***** CONDITIONAL IF THE PC TOLD PERSON TO LEAVE *****\\

[color="Red"]   if (iResult2 == TRUE) && (!GetLocalBoolean(OBJECT_SELF, 42) && (GetEnteringObject() == GetFirstPC())) {[/color]

DestroyObject(oHound);

SetLocalBoolean(OBJECT_SELF, 42, TRUE); 


//***** CONDITIONAL FOR CHECKING IF PC ENTERED IN FROM CLOSE TO CUTSCENE POINT *****\\

if( GetDistanceBetween(oCantDoor, oPC) <= 5.0 ) {

AssignCommand(oSwooper, ActionStartConversation(oPC, "dt_man_hap"));

                                                }

//***** CONDITIONAL FOR DID NOT ENTER THE AREA CLOSE TO CUTSCENE POINT*****\\

if( GetDistanceBetween(oCantDoor, oPC) > 5.0 ) {

SetGlobalBoolean(dt_304_trig, FALSE);

                                               }
                                                                 }

//***** CONDITIONAL IF THE PC WANTED IT DONE BUT TOOK TOO LONG *****\\

[color="Red"]   if (iResult3 == TRUE) && (iResult4 == TRUE) && (!GetLocalBoolean(OBJECT_SELF, 43) && (GetEnteringObject() == GetFirstPC())) {[/color]

DestroyObject(oHound);

SetLocalBoolean(OBJECT_SELF, 43, TRUE); 

//***** CONDITIONAL FOR CHECKING IF PC ENTERED IN FROM CLOSE TO CUTSCENE POINT *****\\

if( GetDistanceBetween(oCantDoor, oPC) <= 5.0 ) {

AssignCommand(oSwooper, ActionStartConversation(oPC, "dt_man_sdlor"));

                                                }

//***** CONDITIONAL FOR DID NOT ENTER THE AREA CLOSE TO CUTSCENE POINT*****\\

if( GetDistanceBetween(oCantDoor, oPC) > 5.0 ) {

SetGlobalBoolean(CC_207_TRIGGER, FALSE);

                                               }
                                                                 }




}

Link to comment
Share on other sites

Okay I'll give that a try and report back.

 

EDIT: It compiles! Thanks JC. Now to see if it works in-game...

Doesn't look like you use an addition () around the whole function... so

if (iResult == TRUE) && (!GetLocalBoolean(OBJECT_SELF, 41) && (GetEnteringObject() == GetFirstPC())) {

 

would become;

 

if ((iResult == TRUE) && (!GetLocalBoolean(OBJECT_SELF, 41) && (GetEnteringObject() == GetFirstPC()))) {

Link to comment
Share on other sites

I generally prefer it all in one line, makes it easier to go through scripts if containing a lot of code, and easier to see what's wrong if the compiler gives a line error.

The debugger is sometimes pretty vague about what's wrong, though. In Fallen Guardian's case, it probably just said "syntax error at &&" or whatever, and since there are a handful on those lines, figuring out what's wrong is that much harder. If you have every condition on a different line, then you get more useful data - it would flag all of them.

Link to comment
Share on other sites

Well, I'm back. And with a scripting problem. I'm doing a request that requires adding the items to the locker on the Endar Spire. I edited the k_inc_end.nss script, which details the Endar Spire, and when I compile it with KT, saving it as k_inc_end.ncs, it compiles, but there's no output file. I try it with HazardX's compiler, and it's an include file and becomes ignored. The specific parts of code I added were these:

Show spoiler
(hidden content - requires Javascript to show)
#include "k_inc_utility"
#include "k_inc_generic"

string sTraskTag = "end_trask";
string sTraskWP = "endwp_tarsk01";
string sCarthTag = "Carth";

string SOLDIER_WEAPON = "g_w_blstrrfl001";
string SOLDIER_ITEM01 = "g_i_adrnaline003";
string SOLDIER_ITEM02 = "";
[color="Red"]string SOLDIER_ITEM03 = "reptroop";[/color]

string SCOUT_WEAPON = "g_w_blstrpstl001";
string SCOUT_ITEM01 = "g_i_adrnaline002";
string SCOUT_ITEM02 = "g_i_implant101";
[color="Red"]string SCOUT_ITEM03 = "recvest";[/color]

string SCOUNDREL_WEAPON = "g_w_blstrpstl001";
string SCOUNDREL_ITEM01 = "g_i_secspike01";
string SCOUNDREL_ITEM02 = "g_i_progspike01";
[color="Red"]string SCOUNDREL_ITEM03 = "smugluck";[/color]

int ROOM3_DEAD = 3;
int ROOM5_DEAD = 4;
int ROOM7_DEAD = 2;

<I'm skipping down to the end. The file is long.>

void SpawnStartingEquipment()
{
   object oLocker = GetObjectByTag(LOCKER_TAG);
   int nClass = GetClassByPosition(1,GetFirstPC());
   if(nClass == CLASS_TYPE_SCOUNDREL)
   {
       CreateItemOnObject(SCOUNDREL_WEAPON,oLocker);
       CreateItemOnObject(SCOUNDREL_ITEM01,oLocker);
       CreateItemOnObject(SCOUNDREL_ITEM02,oLocker);
[color="Red"]        CreateItemOnObject(SCOUNDREL_ITEM03,oLocker);[/color]
   }
   else if(nClass == CLASS_TYPE_SCOUT)
   {
       CreateItemOnObject(SCOUT_WEAPON,oLocker);
       CreateItemOnObject(SCOUT_ITEM01,oLocker);
       CreateItemOnObject(SCOUT_ITEM02,oLocker);
[color="Red"]        CreateItemOnObject(SCOUT_ITEM03,oLocker);[/color]
   }
   else if(nClass == CLASS_TYPE_SOLDIER)
   {
       CreateItemOnObject(SOLDIER_WEAPON,oLocker);
       CreateItemOnObject(SOLDIER_ITEM01,oLocker);
       CreateItemOnObject(SOLDIER_ITEM02,oLocker);
[color="Red"]        CreateItemOnObject(SOLDIER_ITEM03,oLocker);[/color]
   }

   if(GetHasSkill(SKILL_STEALTH,GetFirstPC()))
   {
       CreateItemOnObject(STEALTH_UNIT,oLocker);
   }
}

 

Before you ask, yes I have the tags correct, the files in the override, and yes they all work in-game. But I can't find a solution. Nothing else has been modified, so it's not a capitalization error. It is an include file, but in what should I include it? Thanks for the help in advance guys.

 

EDIT2:I read this thread about compiling scripts, and discovered that the "_CompileAll.bat" file included in HazardX's compiler download is faulty, at least for me. I copied down the code in the thread linked above and made my own "Compile.bat" It worked, but the script didn't. I ended up slagging the above script and used this one instead:

 

Show spoiler
(hidden content - requires Javascript to show)
void main()
{
   vector MyVec;
   MyVec.x = 0.00f; 
   MyVec.y = 0.00f;
   MyVec.z = 0.00f;
   float r = 0.0f;

   object oLocker = CreateObject( OBJECT_TYPE_PLACEABLE, "footlker013", Location(MyVec, r));
   int nClass = GetClassByPosition(1,GetFirstPC());
   if(nClass == CLASS_TYPE_SCOUNDREL)
   {
       CreateItemOnObject(g_w_blstrpstl001,oLocker);
       CreateItemOnObject(g_i_secspike01,oLocker);
       CreateItemOnObject(g_i_progspike01,oLocker);
       CreateItemOnObject(smugluck,oLocker);
   }
   else if(nClass == CLASS_TYPE_SCOUT)
   {
       CreateItemOnObject(g_w_blstrpstl001,oLocker);
       CreateItemOnObject(g_i_adrnaline002,oLocker);
       CreateItemOnObject(g_i_implant101,oLocker);
       CreateItemOnObject(recvest,oLocker);
   }
   else if(nClass == CLASS_TYPE_SOLDIER)
   {
       CreateItemOnObject(g_w_blstrrfl001,oLocker);
       CreateItemOnObject(g_i_adrnaline003,oLocker);
       CreateItemOnObject(reptroop,oLocker);
   }
}

 

This was taken and modified right from the "k_inc_end.nss". And yet, I hit compile in KT, and try the compile.bat I made, and I get

Show spoiler
(hidden content - requires Javascript to show)
Compiler.jpg

 

Any suggestions, guys?

 

EDIT3:I slagged everything, as far as the script went. I went with the following:

Show spoiler
(hidden content - requires Javascript to show)
[HIDDEN]string SOLDIER_WEAPON = "g_w_blstrrfl001";

string SOLDIER_ITEM01 = "g_i_adrnaline003";

string SOLDIER_ITEM02 = "reptroop";

 

string SCOUT_WEAPON = "g_w_blstrpstl001";

string SCOUT_ITEM01 = "g_i_adrnaline002";

string SCOUT_ITEM02 = "g_i_implant101";

string SCOUT_ITEM03 = "recvest";

 

string SCOUNDREL_WEAPON = "g_w_blstrpstl001";

string SCOUNDREL_ITEM01 = "g_i_secspike01";

string SCOUNDREL_ITEM02 = "g_i_progspike01";

string SCOUNDREL_ITEM03 = "smugluck";

//////////////////////////////////////////////////////////////////////////

 

 

 

void main()

{

vector MyVec;

MyVec.x = 19.89f;

MyVec.y = 27.49f;

MyVec.z = -1.11f;

float r = 90.0f;

 

object oLocker = CreateObject( OBJECT_TYPE_PLACEABLE, "footlker013", Location(MyVec, r));

int nClass = GetClassByPosition(1,GetFirstPC());

if(nClass == CLASS_TYPE_SCOUNDREL)

{

CreateItemOnObject(SCOUNDREL_WEAPON,oLocker);

CreateItemOnObject(SCOUNDREL_ITEM01,oLocker);

CreateItemOnObject(SCOUNDREL_ITEM02,oLocker);

CreateItemOnObject(SCOUNDREL_ITEM03,oLocker);

}

else if(nClass == CLASS_TYPE_SCOUT)

{

CreateItemOnObject(SCOUT_WEAPON,oLocker);

CreateItemOnObject(SCOUT_ITEM01,oLocker);

CreateItemOnObject(SCOUT_ITEM02,oLocker);

CreateItemOnObject(SCOUT_ITEM03,oLocker);

}

else if(nClass == CLASS_TYPE_SOLDIER)

{

CreateItemOnObject(SOLDIER_WEAPON,oLocker);

CreateItemOnObject(SOLDIER_ITEM01,oLocker);

CreateItemOnObject(SOLDIER_ITEM02,oLocker);

}

}[/code]

It all compiled fine. No more worries.

Link to comment
Share on other sites

Well, you need the semicolon. Every command has to end with a semicolon. However, you're also missing a close parenthesis.

 

 

Hmm. I'm afraid I can't be of much help, because I've never messed around with k_inc_force. Frankly I don't like including scripts, generally; too easy to mess things up. The amount of work including saves is countered by the amount of work it takes to get it to work. So the only thing I can suggest is you look at k_inc_force and make sure you've done everything right; if I had to guess, I'd say the first P in "Sp_RemoveSpellEffectsGeneral" has to be capitalized.

 

As for VFX_IMP_BATTLE_MED_III, I'm not entirely sure what's going wrong there, but you can easily resolve it by looking at visualeffects.2da and finding the actual line number of VFX_IMP_BATTLE_MED_III and input that in its place.

 

Just thought that you might like to know, I finally revisited this script, and spent the last few hours pouring over this conversation and NWNLexicon(which is VERY helpful), and managed to get the script to work. Here's the code:

Show spoiler
(hidden content - requires Javascript to show)
#include "k_inc_force"

int FORCE_POWER_FINAL_STAND = 177;

void main()
{
       object oTarget = GetSpellTargetObject(); 
       effect eVFX = EffectVisualEffect(1015);
       effect eConI = EffectAbilityIncrease(ABILITY_CONSTITUTION, 25);
       effect eConD = EffectAbilityDecrease(ABILITY_CONSTITUTION, 15);

       if(GetHasSpell(FORCE_POWER_FINAL_STAND))
       {
       Sp_RemoveSpellEffectsGeneral(FORCE_POWER_FINAL_STAND, oTarget);
       }

       SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId()));


       ApplyEffectToObject(1, eVFX, oTarget, 3.0);
       ApplyEffectToObject(1, eConI, oTarget, 30.0);
       SetEffectIcon(eConI, 69);
       DelayCommand(30.0, ApplyEffectToObject(1, eConD, oTarget, 15.0));
}

 

Had to change a few things, like the visual effect entirely, but oh well. The only issue, which I'm happy to overlook at this time, unless you know how to correct it, is that the script increases your base CON by 30 and reduces your base CON by 9, as opposed to what the intention was.

Link to comment
Share on other sites

I'm just guessing, but it might be hard coded to round. I'd suggest testing a few different numbers to see if there's a pattern.

 

I tried by adjusting it to 20 CON increase, and 18 CON decrease, on account of how far it was off to either side, and nothing. I tried something outrageous like 60 CON increase and 40 CON decrease, and nothing. Could it be Spells.2da?

 

Here's the line(Whatever info I skip is ****):

Row:177
Label:FORCE_POWER_LAST_STAND
name:49332
spelldesc:49333
good/evil:-(neutral)
usertype:1(same as cure, valor,etc.)
guardian,consular,sentimel,inate:15
maxcr:6
range:P
using "ip_ lightning"
script is correct
conjtime and anim are the same as everything else.
casttime and anim are the same as everything else.
castsound is default.
Everything else is the same, except "Forcefriendly"is 27, to make it in it's own row in the level-up gui.
And "pips" is 1(though who knows what the pips have to do with anything.)

Link to comment
Share on other sites

Well, I've determined that your CON will never drop below 3. Probably hard coded. So if you have a CON of 12, it will only decrease it by 9. I also believe invulnerability makes you immune from CON decreases, but not CON increases. I really should turn it off... it screwed up other test results in a similar manner just yesterday.

 

However, I've reported no problems regarding CON increase of any kind. Here's the script I used:

void main() {

float fDelay = IntToFloat(GetScriptParameter(1));
int iAbility = GetScriptParameter(2);
int iAmount = GetScriptParameter(3);
float fDuration = IntToFloat(GetScriptParameter(4));

switch(GetScriptParameter(5)) {

case 0:
	DelayCommand(fDelay, ApplyEffectToObject(1, EffectAbilityDecrease(iAbility, iAmount), GetSpellTargetObject(), fDuration));
	break;

case 1:
	DelayCommand(fDelay, ApplyEffectToObject(1, EffectAbilityIncrease(iAbility, iAmount), GetSpellTargetObject(), fDuration));
	break;

}

}

I really can't see anything fundamentally different. So I'm not sure what the problem is. Are you sure you're doing your math correctly? :xp:

Link to comment
Share on other sites

  • 1 month later...

Okay so I've been setting up an onenter script for one of my areas in KotOR 1 and in this area I've decided to include sitting placeables. So here's the part of the script that sets up the sitters:

 

    int nNth = 0;
   object oPlaceable = GetObjectByTag("d50ab_sitter",nNth);
   while (GetIsObjectValid(oPlaceable))
   {
       AssignCommand(oPlaceable,ActionPlayAnimation(ANIMATION_PLACEABLE_ANIMLOOP01));
       nNth++;
       oPlaceable = GetObjectByTag("d50ab_sitter",nNth);
   }

 

Now the issue is only one of the placeables will actually sit down, the other just stands there in the default model pose with its arms stretched out. Now I'm thinking this may have to do with the nNth but I copied this code straight from Manaan, where'd they'd set up multiple sitters.

Link to comment
Share on other sites

That's the same problem I ran into on the first page. I'll quote to save you the trouble of going back:

My problem was that one NPC seemed to be excluded 95% of the time, which I resolved by using GetNearestObjectByTag rather than GetObjectByTag, which is screwy... clearly why GetNearestObjectByTag exists. However, GetObjectByTag does recognize 0, and inputting 0 doesn't immediately crash the game. So there's that.

And the essential code:

int i = 1;

for(; {
	i++;
	object oCreature1 = GetNearestObjectByTag(sTag, OBJECT_SELF, i);
	if( GetIsObjectValid(oCreature1) ){
		ChangeToStandardFaction(oCreature1, iFaction);
		DelayCommand(1.0, AssignCommand(oCreature1, ActionAttack(GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, oCreature1, 1, -1, -1, -1, -1 ), 0)));
		}
	else break;
	}

So something like this should work:

	sTag = "d50ab_sitter";
int i = 1;

for(; {
	i++;
	object oPlaceable = GetNearestObjectByTag(sTag, OBJECT_SELF, i);
	if( GetIsObjectValid(oPlaceable) ){
		AssignCommand(oPlaceable,ActionPlayAnimation(ANIMATION_PLACEABLE_ANIMLOOP01));
		}
	else break;
	}

You might have to fiddle with it a bit. I can't remember all of the details.

Link to comment
Share on other sites

I've been having trouble recently with a WIP to get the following script to run off a dialog that starts when the player enters the module.

 

void main() {

string sTemplate = "ke_crpse001";
object oContainer=GetObjectByTag("EchoCorpse");
vector vCorpse = Vector(-21.23365, -6.85682, 0.0);
location lCorpse = Location(vCorpse, 0.0);

 CreateObject(OBJECT_TYPE_PLACEABLE, sTemplate, lCorpse);
}

 

Any thoughts about what I'm doing wrong? As far as I can tell, it looked right and it compiled without giving me any errors.

Link to comment
Share on other sites

Well, for one thing...

object oContainer=GetObjectByTag("EchoCorpse")

is not doing anything, so you can remove that.

 

Apart from that, there are three things that could be wrong. First, make sure you got the template right. I know, I know... but you wouldn't believe how much time I've wasted before noticing a typo. Second, make sure the coordinates are correct, particularly the Z value. It could be spawning in some part of the module you can't see, like below. Finally, if those two are correct, then I'd blame it on the vector. I've found them to be particularly unreliable, and I can only suggest to find a way to do it without using one, such as spawning near something that's already in the module.

Link to comment
Share on other sites

Or you could make a waypoint in the GIT, and make the waypoint's location the location of your vector. Then grab that waypoint's location via the script and use it for location lCorpse. So something like this:

 

void main()
{

string sTemplate = "ke_crpse001";

object oWP = GetObjectByTag("sp_point");

location lCorpse = GetLocation(oWP);

 CreateObject(OBJECT_TYPE_PLACEABLE, sTemplate, lCorpse);

}

 

Also, JC, it appears that my script works it's just that SittingSelkath placeable does not.

Link to comment
Share on other sites

Or you could make a waypoint in the GIT, and make the waypoint's location the location of your vector. Then grab that waypoint's location via the script and use it for location lCorpse.

Well, if you're going to edit the module, you could just put the placeable in it that way. :raise:

Also, JC, it appears that my script works it's just that SittingSelkath placeable does not.

Ah well... that would explain it. Nothing I can do about that, I'm afraid. I take it the Selkath don't have the regular sitting animation?

Link to comment
Share on other sites

Well, if you're going to edit the module, you could just put the placeable in it that way. :raise:

 

Oh yeah, I forgot about that.

 

Ah well... that would explain it. Nothing I can do about that, I'm afraid. I take it the Selkath don't have the regular sitting animation?

 

Yeah, they don't have the drinking animation either. I don't know about the Pazaak one.

Link to comment
Share on other sites

  • 2 weeks later...

Just thought I'd add some scripting knowledge of my own on here, especially since we're supposed to be helping each other out and sharing knowledge...

 

Here's an easy, foolproof(as far as I have tested it with death field) to add a command dependent on how big the current party is:

Show spoiler
(hidden content - requires Javascript to show)

if(GetPartyMemberCount() == 3)
[color="DarkOrange"]{
if(GetCurrentHitPoints(GetPartyMemberByIndex(0)) < GetMaxHitPoints(GetPartyMemberByIndex(0)) && nHealCount > 0)
{
	ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(nHealCount), GetPartyMemberByIndex(0));
}

if(GetCurrentHitPoints(GetPartyMemberByIndex(1)) < GetMaxHitPoints(GetPartyMemberByIndex(1)) && nHealCount > 0)
{
	ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(nHealCount), GetPartyMemberByIndex(1));
}

if(GetCurrentHitPoints(GetPartyMemberByIndex(2)) < GetMaxHitPoints(GetPartyMemberByIndex(2)) && nHealCount > 0)
{ 
	ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(nHealCount), GetPartyMemberByIndex(2));
}
}[/color]
else if(GetPartyMemberCount() == 2)
[color="DarkOrange"]{
if(GetCurrentHitPoints(GetPartyMemberByIndex(0)) < GetMaxHitPoints(GetPartyMemberByIndex(0)) && nHealCount > 0)
{
	ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(nHealCount), GetPartyMemberByIndex(0));
}

if(GetCurrentHitPoints(GetPartyMemberByIndex(1)) < GetMaxHitPoints(GetPartyMemberByIndex(1)) && nHealCount > 0)
{
	ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(nHealCount), GetPartyMemberByIndex(1));
}
}[/color]
else
[color="DarkOrange"]{
if(GetCurrentHitPoints(GetPartyMemberByIndex(0)) < GetMaxHitPoints(GetPartyMemberByIndex(0)) && nHealCount > 0)
{
	ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(nHealCount), GetPartyMemberByIndex(0));
}[/color]
}

 

In place of the orange text, you could add anything you want. I think this script would be ideal for certain force powers, and also it could be quite useful in convos...

Link to comment
Share on other sites

This should do the same as the above... well, not entirely as I'm not sure what all your ifs are checking, but it will heal the whole party by nHealCount:

int i;
int n = ( GetPartyMemberCount() - 1 );

for( i = 0; 0 <= n; i++) {

ApplyEffectToObject(0, EffectHeal(nHealCount), GetPartyMemberByIndex(i));

}

I really hate repeated lines of code. :xp:

 

Rather than checking how many party members there are and then doing different functions depending on that, and then applying it to each party member... this simply does one thing to every party member, repeating until there aren't any left.

Link to comment
Share on other sites

Show spoiler
(hidden content - requires Javascript to show)
[quote name='JCarter426']This should do the same as the above... well, not entirely as I'm not sure what all your ifs are checking, but it will heal the whole party by nHealCount:
[HIDDEN][code]int i;
int n = ( GetPartyMemberCount() - 1 );

for( i = 0; 0 <= n; i++) {

ApplyEffectToObject(0, EffectHeal(nHealCount), GetPartyMemberByIndex(i));

}


I really hate repeated lines of code. :xp:

Rather than checking how many party members there are and then doing different functions depending on that, and then applying it to each party member... this simply does one thing to every party member, repeating until there aren't any left.

Then I guess people will have to decide which one to use. The reason my code has repeated lines is because I wanted the same action all around, but if this were you used in dialogues, people might want to make dynamic options, so it still has a purpose.


EDIT: And my code
if(GetPartyMemberCount() == 3)
{
if(GetCurrentHitPoints(GetPartyMemberByIndex(0)) < GetMaxHitPoints(GetPartyMemberByIndex(0)) && nHealCount > 0)
{
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(nHealCount), GetPartyMemberByIndex(0));
}

if(GetCurrentHitPoints(GetPartyMemberByIndex(1)) < GetMaxHitPoints(GetPartyMemberByIndex(1)) && nHealCount > 0)
{
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(nHealCount), GetPartyMemberByIndex(1));
}

if(GetCurrentHitPoints(GetPartyMemberByIndex(2)) < GetMaxHitPoints(GetPartyMemberByIndex(2)) && nHealCount > 0)
{
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(nHealCount), GetPartyMemberByIndex(2));
}
}
else if(GetPartyMemberCount() == 2)
{
if(GetCurrentHitPoints(GetPartyMemberByIndex(0)) < GetMaxHitPoints(GetPartyMemberByIndex(0)) && nHealCount > 0)
{
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(nHealCount), GetPartyMemberByIndex(0));
}

if(GetCurrentHitPoints(GetPartyMemberByIndex(1)) < GetMaxHitPoints(GetPartyMemberByIndex(1)) && nHealCount > 0)
{
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(nHealCount), GetPartyMemberByIndex(1));
}
}
else
{
if(GetCurrentHitPoints(GetPartyMemberByIndex(0)) < GetMaxHitPoints(GetPartyMemberByIndex(0)) && nHealCount > 0)
{
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(nHealCount), GetPartyMemberByIndex(0));
}
}[/code][/HIDDEN]

The very first 'if', along with the 'else if' and the 'else' checks how many people are in the party. The set of 'ifs' in the conditionals check to see if a person has less than their maximum health, and if so heals them for nHealcount. If their current and maximum health points are the same, nothing happens. I used this bit of code to heal the entire party with death field instead of just the PC, as part of a mod request I picked up.
Link to comment
Share on other sites

Archived

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


×
×
  • Create New...