So I am trying to make working barrels that you can blow up if you use fire or a gun (I use blackpowder guns in my module)
So far I was happy with the one I had made at first, but then I noticed it just won't damage anything with the normal fireball spells, so I try to make a new system... unsuccessfully.
Any help is appreciated (again, lol... I've lots of time and problems.)
Exploding Barrels System
Débuté par
JerrodAmolyan
, août 12 2013 06:53
#1
Posté 12 août 2013 - 06:53
#2
Posté 12 août 2013 - 06:56
void ExplodeAtLocation(location lTarget, int nDamage, int nSaveDC = 30, float fRadius = 7.)
{
int nDamageAfterSave = GetReflexAdjustedDamage(nDamage, oObject, nSaveDC);
object oObject = GetFirstObjectInShape(SHAPE_SPHERE, fRadius, lTarget, FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE | OBJECT_TYPE_DOOR);
oObject = GetNextObjectInShape(SHAPE_SPHERE, fRadius, lTarget, FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE | OBJECT_TYPE_DOOR);
ApplyEffectToObject( DURATION_TYPE_INSTANT, EffectDamage(nDamageAfterSave, DAMAGE_TYPE_FIRE), oObject);
}
//
void main()
{
location lSource = GetLocation(OBJECT_SELF);
object oPC = GetLastHostileActor;
object oWeapon = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND,oPC);
if ((GetDamageDealtByType(DAMAGE_TYPE_FIRE)))
{
DelayCommand(0.1, ExplodeAtLocation(lSource, d20(6)));
PlaySound("zep_explosion");
}
else if ((GetStringLeft(GetResRef(oWeapon), 4)== "gun_"))
{
DelayCommand(0.1, ExplodeAtLocation(lSource, d20(6)));
PlaySound("zep_explosion");
}
else SendMessageToPC(oPC, "You must use fire or a gun");
return;
}
{
int nDamageAfterSave = GetReflexAdjustedDamage(nDamage, oObject, nSaveDC);
object oObject = GetFirstObjectInShape(SHAPE_SPHERE, fRadius, lTarget, FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE | OBJECT_TYPE_DOOR);
oObject = GetNextObjectInShape(SHAPE_SPHERE, fRadius, lTarget, FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE | OBJECT_TYPE_DOOR);
ApplyEffectToObject( DURATION_TYPE_INSTANT, EffectDamage(nDamageAfterSave, DAMAGE_TYPE_FIRE), oObject);
}
//
void main()
{
location lSource = GetLocation(OBJECT_SELF);
object oPC = GetLastHostileActor;
object oWeapon = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND,oPC);
if ((GetDamageDealtByType(DAMAGE_TYPE_FIRE)))
{
DelayCommand(0.1, ExplodeAtLocation(lSource, d20(6)));
PlaySound("zep_explosion");
}
else if ((GetStringLeft(GetResRef(oWeapon), 4)== "gun_"))
{
DelayCommand(0.1, ExplodeAtLocation(lSource, d20(6)));
PlaySound("zep_explosion");
}
else SendMessageToPC(oPC, "You must use fire or a gun");
return;
}
#3
Posté 12 août 2013 - 06:56
That's all I've come up with, and surprisingly it doesn't work... I've tried doing ifs and whiles and dos... but I have no real idea how they work so... well. Help me
#4
Posté 12 août 2013 - 07:55
This may help...
void ExplodeAtLocation(location lTarget, int nDamage)
{
int nDamageAfterSave;
// get the first object in the area of effect
object oObject = GetFirstObjectInShape(SHAPE_SPHERE, 7.0, lTarget, FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE | OBJECT_TYPE_DOOR);
while (oObject != OBJECT_INVALID) // if oObject is not invalid, try to damage it!
{
// Each target object makes it's own Reflex save against the original damage (nDamage)
nDamageAfterSave = GetReflexAdjustedDamage(nDamage, oObject, 30, SAVING_THROW_TYPE_FIRE);
if (nDamageAfterSave > 0) // if target object should suffer any damage, apply it and a fire VFX
{
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(nDamageAfterSave, DAMAGE_TYPE_FIRE), oObject);
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_FLAME_M), oObject);
}
// get the next object in the area of effect
oObject = GetNextObjectInShape(SHAPE_SPHERE, 7.0, lTarget, FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE | OBJECT_TYPE_DOOR);
}
}
// On Damaged script for exploding barrel object
void main()
{
location lSource = GetLocation(OBJECT_SELF);
object oPC = GetLastHostileActor();
object oWeapon = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND,oPC);
if (GetDamageDealtByType(DAMAGE_TYPE_FIRE) > 0)
{
DelayCommand(0.1, ExplodeAtLocation(lSource, d20(6)));
PlaySound("zep_explosion");
}
else if (GetStringLeft(GetResRef(oWeapon), 4) == "gun_")
{
DelayCommand(0.1, ExplodeAtLocation(lSource, d20(6)));
PlaySound("zep_explosion");
}
else
{
SendMessageToPC(oPC, "You must use fire or a gun");
}
}
Modifié par The Amethyst Dragon, 12 août 2013 - 08:02 .
#5
Posté 12 août 2013 - 08:09
The script above made some basic changes to yours.
I put the save DC and explosion radius right into the ExplodeAtLocation() function, since it's just for this script right now and doesn't need to be changed.
I added a proper while loop to the explosion so it cycles through the objects in the area of effect. The reflex save is now done by each object in the area of effect, rather than being done at the start and adjusting damage for every creature after the first.
I added a few comments to the code so you can see what some of the parts of it are supposed to be doing.
You might want to consider changing the delay in exploding from 0.1 seconds to something a little longer, perhaps to 1.0 or even 2.0 seconds, just for effect.
If you have this as the on damaged script for your barrels, it should work. And if you line several of these up within 7 meters of the last one, you could get a chain of explosions as the first sets off the second, and that sets off the third, and onward...
I put the save DC and explosion radius right into the ExplodeAtLocation() function, since it's just for this script right now and doesn't need to be changed.
I added a proper while loop to the explosion so it cycles through the objects in the area of effect. The reflex save is now done by each object in the area of effect, rather than being done at the start and adjusting damage for every creature after the first.
I added a few comments to the code so you can see what some of the parts of it are supposed to be doing.
You might want to consider changing the delay in exploding from 0.1 seconds to something a little longer, perhaps to 1.0 or even 2.0 seconds, just for effect.
If you have this as the on damaged script for your barrels, it should work. And if you line several of these up within 7 meters of the last one, you could get a chain of explosions as the first sets off the second, and that sets off the third, and onward...
Modifié par The Amethyst Dragon, 12 août 2013 - 08:15 .
#6
Posté 12 août 2013 - 08:18
Thanks.
Now I need to try and understand how I will go about adding that damage. As far as I can see it's already supposed to be there... right ? O_o or am I just blind
#7
Posté 12 août 2013 - 08:22
= Tested and it doesn't do a thing, just plays the explosion sound
Am I being dumb here ? lol
#8
Posté 12 août 2013 - 08:29
Is the static box unchecked for all your barrels?
FP!
FP!
#9
Posté 12 août 2013 - 08:31
Yeah, their point is to be useable and portable. I can lug them around and set them back beside myself and now I'm trying to blow them up. I'm just curious though...
ExplodeAtLocation(lSource, d20(6)));
Isn't that the damage dealing thingie ? If so, then the lSource is missing ?
Seriously, talk the grunting orc language to me, I'm not even novice at this yet x)
ExplodeAtLocation(lSource, d20(6)));
Isn't that the damage dealing thingie ? If so, then the lSource is missing ?
Seriously, talk the grunting orc language to me, I'm not even novice at this yet x)
Modifié par JerrodAmolyan, 12 août 2013 - 08:32 .
#10
Posté 12 août 2013 - 08:49
Okay, got the damage and effects applied myself. NOW... I'd like to make it a bit less... well predictable. I had to assign it 100 damage, since it doesn't seem to recognize any d100 or 10d20 or anything with dice. Or if it would, I don't know the correct type
And the visual doesn't apply to the adjacent barrels, only the one I shoot at 
Also, I'd like to make it blow up the PC (if he gets in the radius and miraculously even evades the fire) if he carries those barrels ("jer_explosives") and make those barrels then be taken from the inventory
How can I do that ?
Also, I'd like to make it blow up the PC (if he gets in the radius and miraculously even evades the fire) if he carries those barrels ("jer_explosives") and make those barrels then be taken from the inventory
Modifié par JerrodAmolyan, 12 août 2013 - 08:50 .
#11
Posté 14 août 2013 - 12:51
I've still been unable to work this out. Seems I can't blow up the adjacent barrels, instead the damage just either destroys them, or if I give them lots of hit points, does nothing to them.
Also, I'm unable to assign a damage like 10d20 (or anything d anything) I can just assign a number which will be it, meh. Not that 100 damage isn't "enough", it's just so predictable and you can't get lucky and evade some of it by rolling well. if you fail the reflex, it's 100 damage. It gets boring
Biggest problem is not getting the barrels explode if hit by another barrel, I think it might have something to do with PC being the one who triggers the event, but the barrel being the one who causes the damage... then again it's just a hunch. I really need help
Also, I'm unable to assign a damage like 10d20 (or anything d anything) I can just assign a number which will be it, meh. Not that 100 damage isn't "enough", it's just so predictable and you can't get lucky and evade some of it by rolling well. if you fail the reflex, it's 100 damage. It gets boring
Biggest problem is not getting the barrels explode if hit by another barrel, I think it might have something to do with PC being the one who triggers the event, but the barrel being the one who causes the damage... then again it's just a hunch. I really need help
#12
Posté 14 août 2013 - 01:57
You need to post your current code for us to help with it. 
Funky
Funky
#13
Posté 14 août 2013 - 02:08
Scripting dunce here... but try changing the radius of the GetFirstObjectInShape to a constant like RADIUS_SIZE_HUGE and retry. The effect may not be locating target(s) properly. Have you tried different spacings of the barrels? (The others may be lying just outside the edge of the radius.)
*bumping until a pro shows*
*bumping until a pro shows*
#14
Posté 14 août 2013 - 08:36
*Derps* Right the current code !
void ExplodeAtLocation(location lTarget, int nDamage)
{int nDamageAfterSave;
// get the first object in the area of effect
object oObject = GetFirstObjectInShape(SHAPE_SPHERE, 7.0, lTarget, FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE | OBJECT_TYPE_DOOR);
while (oObject != OBJECT_INVALID) // if oObject is not invalid, try to damage it!
{ // Each target object makes it's own Reflex save against the original damage (nDamage)
nDamageAfterSave = GetReflexAdjustedDamage(nDamage, oObject, 30, SAVING_THROW_TYPE_FIRE);
if (nDamageAfterSave > 0)
// if target object should suffer any damage, apply it and a fire VFX
{ ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(100, nDamageAfterSave, DAMAGE_TYPE_FIRE), oObject);
ActionCastSpellAtObject(SPELL_COMBUST, oObject, METAMAGIC_ANY, TRUE, 0,
PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_FLAME_M), oObject); ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_FIREBALL), lTarget);
}
// get the next object in the area of effect oObject = GetNextObjectInShape(SHAPE_SPHERE, 7.0, lTarget, FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE | OBJECT_TYPE_DOOR);
}
}
// On Damaged script for exploding barrel object
void main()
{location lSource = GetLocation(OBJECT_SELF);
object oPC = GetLastHostileActor();
object oWeapon = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND,oPC);
if (GetDamageDealtByType(DAMAGE_TYPE_FIRE) > 0)
{ DelayCommand(0.1, ExplodeAtLocation(lSource, d20(6)));
PlaySound("zep_explosion");
}
else if (GetStringLeft(GetResRef(oWeapon), 4) == "gun_")
{ DelayCommand(0.1, ExplodeAtLocation(lSource, d20(6)));
PlaySound("zep_explosion");
}
else
{
SendMessageToPC(oPC, "You must use fire or a gun");
}
}
void ExplodeAtLocation(location lTarget, int nDamage)
{int nDamageAfterSave;
// get the first object in the area of effect
object oObject = GetFirstObjectInShape(SHAPE_SPHERE, 7.0, lTarget, FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE | OBJECT_TYPE_DOOR);
while (oObject != OBJECT_INVALID) // if oObject is not invalid, try to damage it!
{ // Each target object makes it's own Reflex save against the original damage (nDamage)
nDamageAfterSave = GetReflexAdjustedDamage(nDamage, oObject, 30, SAVING_THROW_TYPE_FIRE);
if (nDamageAfterSave > 0)
// if target object should suffer any damage, apply it and a fire VFX
{ ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(100, nDamageAfterSave, DAMAGE_TYPE_FIRE), oObject);
ActionCastSpellAtObject(SPELL_COMBUST, oObject, METAMAGIC_ANY, TRUE, 0,
PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_FLAME_M), oObject); ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_FIREBALL), lTarget);
}
// get the next object in the area of effect oObject = GetNextObjectInShape(SHAPE_SPHERE, 7.0, lTarget, FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE | OBJECT_TYPE_DOOR);
}
}
// On Damaged script for exploding barrel object
void main()
{location lSource = GetLocation(OBJECT_SELF);
object oPC = GetLastHostileActor();
object oWeapon = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND,oPC);
if (GetDamageDealtByType(DAMAGE_TYPE_FIRE) > 0)
{ DelayCommand(0.1, ExplodeAtLocation(lSource, d20(6)));
PlaySound("zep_explosion");
}
else if (GetStringLeft(GetResRef(oWeapon), 4) == "gun_")
{ DelayCommand(0.1, ExplodeAtLocation(lSource, d20(6)));
PlaySound("zep_explosion");
}
else
{
SendMessageToPC(oPC, "You must use fire or a gun");
}
}
Modifié par JerrodAmolyan, 14 août 2013 - 08:40 .
#15
Posté 15 août 2013 - 12:41
There are numerous problems in your script. You have the parameters for EffectDamage wrong, and you commented out the line that continues to iterate the while loop. You also appear to be having it cast a Combust spell for no reason I can fathom. I'll post a cleaned-up version in a couple minutes.
Funky
Funky
#16
Posté 15 août 2013 - 01:28
Sorry, I got sidetracked chatting. Here's a test mod with it working:
Barrels Go Boom
Here's the cleaned up script, though I suggest you just yank the one from the mod if the forum eats the indents:
I would probably have written it a bit differently (I just cleaned up your version), but it works as expected.
Funky
Barrels Go Boom
Here's the cleaned up script, though I suggest you just yank the one from the mod if the forum eats the indents:
void ExplodeAtLocation(location lTarget) {
int nDamage;
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_FIREBALL), lTarget);
object oObject = GetFirstObjectInShape(SHAPE_SPHERE, 7.0, lTarget, FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE | OBJECT_TYPE_DOOR);
while (GetIsObjectValid(oObject)) {
nDamage = GetReflexAdjustedDamage(d20(6), oObject, 30, SAVING_THROW_TYPE_FIRE);
if (nDamage > 0) {
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(nDamage, DAMAGE_TYPE_FIRE), oObject);
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_FLAME_M), oObject);
}
oObject = GetNextObjectInShape(SHAPE_SPHERE, 7.0, lTarget, FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE | OBJECT_TYPE_DOOR);
}
}
void main() {
location lSource = GetLocation(OBJECT_SELF);
object oPC = GetLastHostileActor();
object oWeapon = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND,oPC);
if (GetDamageDealtByType(DAMAGE_TYPE_FIRE) > 0) {
DelayCommand(0.1, ExplodeAtLocation(lSource));
PlaySound("zep_explosion");
} else if (GetStringLeft(GetResRef(oWeapon), 4) == "gun_") {
DelayCommand(0.1, ExplodeAtLocation(lSource));
PlaySound("zep_explosion");
}
else {
SendMessageToPC(oPC, "You must use fire or a gun to detonate this barrel.");
}
}
I would probably have written it a bit differently (I just cleaned up your version), but it works as expected.
Funky
#17
Posté 15 août 2013 - 12:02
Hey thanks, this script is just what I wanted.
The module one is very complicated, and I just want a simple exploding barrel you can lug around and so. Of course, I'd like to ask if it's possible for me to add an if sentence somewhere to check if the PC has this barrel in his/her inventory, and if so and caught in that sphere, the PC would also explode = death and losing the barrels. Where would this sentence go to ? To the explosion script or to the main script ?
#18
Posté 15 août 2013 - 04:27
The test module one is identical to the one I posted. Just download it, open it in the editor, and hit F9 to test (assuming your test toon has fire damage). Otherwise, just play it - only takes a minute, and shows off the domino effect.
Where you put the line checking for a barrel in inventory depends on what behavior you want, what you expect the use by players to be, and so on. If you only care about barrels in inventory of the person who sets off the first barrel, you can avoid putting it in the explosion function. If you do care about secondary explosions setting off barrels in player inventory, however, it will have to go in the explosion function, inside the while loop.
You'd need another custom function to iterate the pc's inventory, delete all instances of the barrel while counting deleted instances, and return the number of deleted instances, to know how much damage to apply. Here's a modified script that checks inside the explosion:
Fair warning: I haven't compiled this, so there could be a typo.
Funky
Where you put the line checking for a barrel in inventory depends on what behavior you want, what you expect the use by players to be, and so on. If you only care about barrels in inventory of the person who sets off the first barrel, you can avoid putting it in the explosion function. If you do care about secondary explosions setting off barrels in player inventory, however, it will have to go in the explosion function, inside the while loop.
You'd need another custom function to iterate the pc's inventory, delete all instances of the barrel while counting deleted instances, and return the number of deleted instances, to know how much damage to apply. Here's a modified script that checks inside the explosion:
int DeleteCountItem(object oPC, string sTag) {
int nCount;
object oScan = GetFirstItemInInventory(oPC);
while (GetIsObjectValid(oScan)) {
if (GetTag(oScan) == sTag) {
nCount++;
DestroyObject(oScan);
}
oScan = GetNextItemInInventory(oPC);
}
return nCount;
}
void ExplodeAtLocation(location lTarget) {
int nDamage, nCount;
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_FIREBALL), lTarget);
object oObject = GetFirstObjectInShape(SHAPE_SPHERE, 7.0, lTarget, FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE | OBJECT_TYPE_DOOR);
while (GetIsObjectValid(oObject)) {
if (GetIsPC(oObject)) //saves us from scanning inventory of placeables and other creatures
nCount = DeleteCountItem(oPC, "TAGOFYOURITEM");
nDamage = GetReflexAdjustedDamage(d20(6*(nCount+1)), oObject, 30, SAVING_THROW_TYPE_FIRE);
if (nDamage > 0) {
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(nDamage, DAMAGE_TYPE_FIRE), oObject);
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_FLAME_M), oObject);
}
oObject = GetNextObjectInShape(SHAPE_SPHERE, 7.0, lTarget, FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE | OBJECT_TYPE_DOOR);
}
}
void main() {
location lSource = GetLocation(OBJECT_SELF);
object oPC = GetLastHostileActor();
object oWeapon = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND,oPC);
if (GetDamageDealtByType(DAMAGE_TYPE_FIRE) > 0) {
DelayCommand(0.1, ExplodeAtLocation(lSource));
PlaySound("zep_explosion");
} else if (GetStringLeft(GetResRef(oWeapon), 4) == "gun_") {
DelayCommand(0.1, ExplodeAtLocation(lSource));
PlaySound("zep_explosion");
}
else {
SendMessageToPC(oPC, "You must use fire or a gun to detonate this barrel.");
}
}
Fair warning: I haven't compiled this, so there could be a typo.
Funky
#19
Posté 15 août 2013 - 07:35
You forgot to assign PC as object, but it's okay. The problem still is that the barrels won't get destroyed from your inventory, strangely enough. I'm sure the tag of the item is correct.
Otherwise it works, it does assign damage and blow you up (needed to apply fireball visual to the item holding PC too but yeah. Thanks alot for helping me here
Otherwise it works, it does assign damage and blow you up (needed to apply fireball visual to the item holding PC too but yeah. Thanks alot for helping me here
Modifié par JerrodAmolyan, 15 août 2013 - 07:36 .
#20
Posté 15 août 2013 - 09:49
JerrodAmolyan wrote...
You forgot to assign PC as object, but it's okay. The problem still is that the barrels won't get destroyed from your inventory, strangely enough. I'm sure the tag of the item is correct.
No, it's not okay. That's WHY the barrels aren't being taken.
Change that line's oPC to oObject, like this:
nCount = DeleteCountItem(oObject, "TAGOFYOURITEM");Funky
#21
Posté 19 août 2013 - 07:49
AAAAH. Damn, now it seems to work flawlessly
Thanks man.





Retour en haut






