My favorite part of the game has always been the force powers, and since I don't like begging for mods in the requests forum that usually go unanswered even though 2,586 people view it, I'd like to learn how to make my own offensive force power. Beancounter has a rather fantastic tutorial about buffs, but most friendly force powers are quite frankly boring. Beancounter hasn't been seen around here for a while, so could anyone teach me how to make my own force powers? Keep in mind that I'm very new to modding: (I've only done simple reskins and item editing, though I know his spells.2da tutorial by heart.)
Here's what I need to learn:
How to script an offensive force power.
How to use the tslpatcher thing to insert it automatically, so I can use other force power mods I enjoy.
Thanks in advance,
-Illuminatus
could anyone teach me how to make my own force powers? Keep in mind that I'm very new to modding:
How to script an offensive force power.
How to use the tslpatcher thing to insert it automatically, so I can use other force power mods I enjoy.
That depends a bit on what you want your powers to do. It's a pretty big subject to teach someone in general terms, since an offensive force power could do pretty much anything the scripting language allows you to do. If you are a bit more specific in your question it might be easier to give some meaningful advise. :)
* * *
As for TSLPatcher config you first need to use TalkEd (or some other TLK editor) to create an append.tlk file that contains entries for the names and descriptions of your force powers. Then go to the TLK panel in ChangeEdit and load your append.tlk file with the button above the right-hand list, select each entry and press the left-pointing button to create StrRef? tokens.
Then, for 2DA updates the easiest way is to add your force power lines as normal to spells.2da and then use the compare button in the ChangeEdit config utility to compare it to an unaltered spells.2da file and generate instructions for the differences. Then, for each "Add" modifier that was created (doubleclick them in the list to edit them) set the Exclusive column field to label and change the value of the forcehostile column to high(). The first change will ensure that no duplicate lines are added if someone runs the installer more than once. The second will update the group number in the forcehostile column to the next number in sequence (highest value of all rows + 1). Then set the name and desc columns to the StrRef? tokens corresponding to the entries in your append.tlk file you want to use for that power's name and description.
If your power is a simple stand-alone power that isn't part of a family (e.g. Wound->Choke->Kill) and doesn't have any prerequisites that should be enough. If you add several powers that should be grouped together as a family you need to add an instruction that saves the value from the forcehostile column of the first power in a 2DAMEMORY? token, and then assign that token (instead of high()) to the forcehostile column of the other powers that should belong to that family. Should one of your powers need another of your powers as prerequisite you need to assign the RowIndex value of the prerequisite power to a 2DAMEMORY? token, and then assign that token to the prerequisites column for the other power.
If your impact scripts for your spells does not need to have any information inserted into them (such as dialog.tlk StrRefs, line numbers from 2DA files etc) it's best to just ship already compiled NCS files with it and have TSLPatcher just copy them to the override folder (include the NSS source files anyway though in case people need to modify them or make them compatible with something else). If they need to be modified you'll have to place #2DAMEMORY?# and/or #StrRef?# tokens in the script where the values should be inserted and then add the NSS files to the Compile list in the patcher config (and NOT include the NCS files).
Damn. Maybe I'll merge the files myself. I don't think I'll be able to learn TLK editing for a while. Let's focus on scripting. I'm pretty good at figuring out how things work by looking at their parts, so a good approach would be to show the important parts of a script. If you would, take the Death Field or Force Storm script and point out what effect each part has. And just the parts that dictate the effect, not like the void and {] stuff. Stuff that deals with target, damage, visual effects and combat effects, as well as type of damage, save, area of effect, whether damage to target heals you, etc. I'm not asking for a detailed analysis of each one, just what goes where and (if there's not a huge amount of things) what you could possibly put there. Any personal notes of what's useful or tips would be greatly appreciated. I realize this may be a tall order, but it would really give me the boost I need into modding so I could help out myself and the poor souls in the mod request forum.
Thanks,
-Illuminatus
Great. 92 people have read this and no one wants to help. I can't understand why all the mods I download thank holowan for the support.
Your question about how to script an offensive force power is too generic to answer, as stoffe already said. Have you downloaded mods for custom force powers? Did they include the .nss files? If so you already have examples of how to script a force power. Also take a look at k_inc_force.nss in your scripts.bif file to see how the default force powers work. Take a look at other scripting tutorials in that forum to get the hang of how scripts work in the game.
Your timing isn't great -- the game is fairly old and interest levels aren't what they were a couple years ago. Plus our search function is disabled for near future while a hard drive gets replaced.
But yes you can thank Holowan for most of the mods you see out there. Without this community, the modding tools wouldn't be available at all. Try to keep that in mind.
If you would, take the Death Field or Force Storm script and point out what effect each part has.
/*
FORCE STORM
*/
case FORCE_POWER_FORCE_STORM:
{
//just redifining some constants
SWFP_HARMFUL = TRUE;
SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_WILL;
// set the maximum number of hit dice for damage
int nDamage = GetHitDice(OBJECT_SELF);
if(nDamage > 10)
{
nDamage = 10;
}
// calculate damage (d6 is a function defined in nwscript.nss)
SWFP_DAMAGE = d6(nDamage);
// set damage type
SWFP_DAMAGE_TYPE = DAMAGE_TYPE_ELECTRICAL;
// we define the effect of the beam
// the 2061 is an undocumented VFX_BEAM constant for lightning
// OBJECT_SELF is the person generating the beam
// BODY_NODE_HEAD is where the beam comes out of that person
effect eBeam = EffectBeam(2061, OBJECT_SELF, BODY_NODE_HEAD);
// we define the lightning effect (outside the beam)
effect eVis = EffectVisualEffect(VFX_PRO_LIGHTNING_L);
// declare a couple other effects to be defined
effect eForce;
effect eDam;
// this portion determine the targets to be effected
// the GetFirstObjectInShape defines a shape and selects the
// objects that meet the criteria
// sphere, radius = 12m, centered on the target, not in line of sight, creatures or placeables
object oUse = GetFirstObjectInShape(SHAPE_SPHERE, 12.0, GetLocation(oTarget), FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE);
// did we find a valid next target in the shape?
while(GetIsObjectValid(oUse))
{
//Make Immunity Checks
// is it a bad guy?
if(GetIsEnemy(oUse))
{
// tell the bad guy's AI that he just got force powered
SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
// did he fail to resist the force power?
if(!ResistForce(OBJECT_SELF, oUse))
{
// show the lightning (instant)
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oUse);
// show the beam (for a duration)
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eBeam, oUse, fLightningDuration);
// did he fail to make a Will saving throw? (DC is 10+spell level+ability bonus)
if(!WillSave(oUse, Sp_GetJediDCSave()))
{
// now we will define the damage effect
// SWFP_DAMAGE is that d6 roll we made, and SWFP_DAMAGE_TYPE we defined as electrical
eDam = EffectDamage(SWFP_DAMAGE, SWFP_DAMAGE_TYPE);
// and we define how much force point damage (same as hit point damage here)
eForce = EffectDamageForcePoints(SWFP_DAMAGE);
// apply! >:-D
ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oUse);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eForce, oUse);
}
else
{
// made their Will save, so only 1/2 damage
eDam = EffectDamage(SWFP_DAMAGE/2, SWFP_DAMAGE_TYPE);
eForce = EffectDamageForcePoints(SWFP_DAMAGE/2);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oUse);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eForce, oUse);
}
}
else
{
// made resistance, show fizzle effect on the caster
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceFizzle(), OBJECT_SELF);
}
}
// now find the next target in our shape
oUse = GetNextObjectInShape(SHAPE_SPHERE, 12.0, GetLocation(oTarget), FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE);
} // and loop until we can't find anyone else
}
break;
Well, making a statement like that seems to have helped. I offer a full retraction. I'm deeply grateful to you for your help. This is just what I needed to finish my crash course in force modding. And why don't people play Kotor 1 much anymore? TSL may have better combat and robe animations, but the Star Forge plot? The detailed, believable characters we've all come to love? The endings that leave you grinning uncontrollably? The original Kotor is truly excellent, and should be played by all Star Wars and RPG enthusiasts.