Aller au contenu

Photo

Heartbeat or OnInjured? Which is Best For This Script? (Solved)


  • Veuillez vous connecter pour répondre
16 réponses à ce sujet

#1
Morbane

Morbane
  • Members
  • 1 883 messages
 I am trying out a new creature behaviour - its main attack is an AOE - but when it gets injured to a certain point it is supposed to try and run away. 

The scripts in the next post handle the creatures behaviours

I cant determine what is broken or if the broken script is just written wrong for the event

(see next post)

Modifié par Morbane, 28 avril 2012 - 06:08 .


#2
Morbane

Morbane
  • Members
  • 1 883 messages
This script works great: (OnSpawn)

void main()
{
object oSelf = OBJECT_SELF;

if(GetLocalInt(oSelf, "once") == TRUE)
{
ExecuteScript("nw_c2_default9", oSelf);
return;
}

ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectCutsceneImmobilize(), oSelf);

SetLocalInt(oSelf, "once", TRUE);

ExecuteScript("nw_c2_default9", oSelf);

}

This script is broken: (HB or OnDamaged?)

void main()
{
object oChant = OBJECT_SELF;
effect eCS = GetFirstEffect(oChant);
effect eHaste = EffectHaste();

if(GetCurrentHitPoints(oChant) <= GetMaxHitPoints(oChant) / 3)
{
SendMessageToPC(GetFirstPC(), "Injured");
while(GetIsEffectValid(eCS))
{
if(GetEffectType(eCS) == EFFECT_TYPE_CUTSCENEIMMOBILIZE)
{
SendMessageToPC(GetFirstPC(), "Found Effect");
RemoveEffect(oChant, eCS);
}
GetNextEffect(oChant);
}

SetImmortal(oChant, TRUE);

ApplyEffectToObject(DURATION_TYPE_PERMANENT, eHaste, oChant);

AssignCommand(oChant, ActionMoveToLocation(GetLocation(GetWaypointByTag("wp_chant_flee")), TRUE));

SoundObjectStop(GetObjectByTag("chanter_s"));
DelayCommand(3.5f, DestroyObject(GetObjectByTag("chanter")));
}

}


Modifié par Morbane, 28 avril 2012 - 03:44 .


#3
kevL

kevL
  • Members
  • 4 070 messages
+1 for onDamaged ( just to keep it off the HB )

#4
Morbane

Morbane
  • Members
  • 1 883 messages
Sounds good - I did try both to see if the timing was right but I am still not getting debug messages

Could there be something wrong with the if(GetCurrentHitPoints(oChant) <= GetMaxHitPoints(oChant) / 3) ?

#5
M. Rieder

M. Rieder
  • Members
  • 2 530 messages
Definitely use the on damaged event. You will want to set the immortal flag to true on the blueprint instead of in code, just in case someone has an uber weapon and gets a crit that can actually kill it too soon.

I'd look at the OC. Remember when you have to fight that wizard at the docks in neverwinter and after you get them to a certain HP, they start a convo? Well, that script should work for you, except instead of starting a convo, just make it run away.

#6
M. Rieder

M. Rieder
  • Members
  • 2 530 messages
Also, before you assign the command for oChant to move to location, you may need to
ClearAllActions(TRUE);

or it may not execute the command.

#7
M. Rieder

M. Rieder
  • Members
  • 2 530 messages
Also, when giving movement commands, I prefer

ActionForceMoveToObject() I think that it makes the object try a little harder to get to the object.

#8
M. Rieder

M. Rieder
  • Members
  • 2 530 messages
There is also a ForceExit() command. I bielieve it may be in ginc_cutscene, but I'm not sure. that command will force a creature to move to a specified waypoint, then destroy itsself.

#9
Morbane

Morbane
  • Members
  • 1 883 messages
There is definitely something wrong with my while loop - the debug finally came up but it cycled like 100s of times before breaking out and the EffectCutsceneImmobilize() did not get removed

while(GetIsEffectValid(eCSI))
{
SendMessageToPC(GetFirstPC(), "Found Effect");
if(GetEffectType(eCSI) == EFFECT_TYPE_CUTSCENEIMMOBILIZE)
{
SendMessageToPC(GetFirstPC(), "Found Effect");
RemoveEffect(oChant, eCSI);
}
GetNextEffect(oChant);
}


I cant see what could be wrong here :pinched:

Modifié par Morbane, 28 avril 2012 - 05:03 .


#10
M. Rieder

M. Rieder
  • Members
  • 2 530 messages
the line

GetNextEffect(oChant);

should read

eCSI=GetNextEffect(oChant);

Modifié par M. Rieder, 28 avril 2012 - 05:23 .


#11
Morbane

Morbane
  • Members
  • 1 883 messages
OMG!

Yeah, works now :blink: but it still reads like 5 debugs instead of only the 2 in there - unless the creature's AOE is somehow affecting itself - gotta look into that now

Modifié par Morbane, 28 avril 2012 - 05:33 .


#12
MasterChanger

MasterChanger
  • Members
  • 686 messages
I always advocate for keeping stuff out of the OnHB itself even if it's HB-type behavior as long as it relates to combat. DetermineCombatRound has a call at the very beginning of it looking for a special combat script stored as a local string on the creature. For a situation where you're going to be running the default OnHB anyway, I found it better to just attach that special combat script (don't recall the local string name off the top of my head right now).

This doesn't say anything about whether it's better to put this in OnDamaged or in the combat script, however. If you want it to be when HP drops below a certain point, then OnDamaged is probably better. If you want it to happen repeatedly, then the combat script could be more appropriate.

Also, regarding your OnSpawn: I believe that the default OnSpawn has a hook for a "SpawnScript" variable on the creature to run. You could use that rather than have your call the default handler.

#13
Lugaid of the Red Stripes

Lugaid of the Red Stripes
  • Members
  • 955 messages
My own retreat scripts are actually both in the on-damaged and heartbeat scripts. The on-damaged script sets a local variable/flag, that gets checked by the heartbeat script. So when the NPC gets damaged, they start to run away. And on the next heartbeat, they try to run away again, and if they get damaged again, they try to run away. The problem is that several scripts order NPCs to do various things, and so you have to catch each one. The damaged and physcially attacked scripts tell the NPC to start a new combat round, as does on-combat-round-end. The HB tells the NPC to walk way points if not in combat. The perception script can start combat as well. So even if you tell the little snot to run away, they'll forget about as soon as another event fires, and go off and do something else.

People get wary of putting too much stuff on the heartbeat, but if you look at it, it already has a bunch of junk in it from BioWare and OEI and their spaghetti include scripts, doing gods-know-what, and the program still manages to chug along. In fact, the basic AI of the game is from 2001, and gets run on machines built almost a decade later. A little extra code in there isn't going to hurt anything, especially if that little bit of code tells it to check this variable, and if true, forget all that other stuff and just do this one little thing.

Basically, the only way you can really bog down the game with scripts is either with A) massive loops, B) interactive processes that can spiral out of control like a positive feedback loop, or C) an absurd number of objects. Most of the bogginess I encounter comes from have a bunch of NPCs perceiving and interacting with each other, which geometrically increases the number of scripts called (i.e. 20 NPCs perceiving each other results in 400 calls to the perception script).

So don't worry about putting stuff in those event scripts, just as long as you make sure the NPCs only do exactly what you need them to do, and nothing else.

#14
painofdungeoneternal

painofdungeoneternal
  • Members
  • 1 799 messages
The basic code from 2001 which you are seeing, even in single player, is why the CPU runs so hot on older systems. It is beyond crazy, anything you do is like adding a final straw because it is massive loops constantly. ( A B and C are ALL TRUE with the official content ). Nothing you do CAN be worse than that.

If you redo the AI, or use simpler AI which does not use all that you don't have to worry about heartbeats. ( Lugaid have you tried my AI at all, it should not have a problem until the issue is the graphics or the show message buffer going nuts ). Since what you are describing is AI, you can change the AI used to a your own set of scripts instead of the official ones, which will actually reduce the load.

If you are careful, do not use functions from includes which you don't understand ( which are just massive loops themselves ), and keep things simple you should be good. Avoid some functions which deal with distance in game ( the functions tend to say they are expensive, like the one saying it calcs a safe location ), iterating character inventories constantly, and that sort of thing. I'd suggest posting what you are doing in fact just to ensure you hear what potential issues are involved.

Generally its advice to avoid is aimed at really newer scripters who tend to focus first on the heartbeat, or are just throwing stuff together and the criteria is more on does it almost work instead of performance. If you discuss with more experienced scripters and listen to advice on how to approach things you won't have trouble using heartbeats.

Modifié par painofdungeoneternal, 29 avril 2012 - 12:43 .


#15
Lugaid of the Red Stripes

Lugaid of the Red Stripes
  • Members
  • 955 messages
@pain: can you post a link for me? I'm at the point where I'm almost ready to chuck the original AI altogether, but I hesitate less I disable some important behaviors.

I'm gonna start a new thread on expensive functions, hopefully you can help out there, too.

#16
painofdungeoneternal

painofdungeoneternal
  • Members
  • 1 799 messages
my stuff is at
http://dl.dropbox.co...upportFiles.zip
http://dl.dropbox.co.../CSLScripts.zip

It's all of it basically. It requires 2 folders to do the AI, the CSL Library folder which has all the includes, and the CSL AI folder, and the 2da's which configure how tonyk's stuff works. Should plug and play and work just like official does now, except it relies entirely on my library. Also cslpreferences.2da has all the options. Each folder is a module, so you can pick and choose which to use for the most part.

Caching is done up front as well, bit expensive still on that up front since it's using the bioware DB to store objects. ( Entirely optional but it really speeds things up overall ).

#17
Lugaid of the Red Stripes

Lugaid of the Red Stripes
  • Members
  • 955 messages
thanks, I'll start picking through it.