Aller au contenu

Photo

while loop enemy counter locking game


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

#1
Morbane

Morbane
  • Members
  • 1 883 messages
Is there a way to count enemies with a loop like the one below - which locks the game - apparently it counts every enemy in an endless loop - I am trying to manage a condition that reacts according to how many enemies there are...
while(GetIsObjectValid(oTarget))	
{	
	if(oTarget == oSelf)	
	{	
		oTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_ASTRONOMIC, lSelf, TRUE, OBJECT_TYPE_CREATURE);	
	}
				if(GetIsInCombat() == TRUE)
		{	
		SendMessageToPC(oSelf, "In Combat");	
   if(GetIsEnemy(oTarget, oSelf))	
		{	
			nEnemyCount += 1;	
						}//enemy	
					if(nEnemyCount > nBonus && GetCurrentHitPoints(OBJECT_SELF) < GetMaxHitPoints(OBJECT_SELF)/2)	
		{	
			ActiveWereWolf(OBJECT_SELF);	
			ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, OBJECT_SELF, TurnsToSeconds(nDuration));	
		}	
 }	
		oTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_ASTRONOMIC, lSelf, TRUE, OBJECT_TYPE_CREATURE);	
}//while

Thanks for any solution or suggestions.

Modifié par Morbane, 18 juillet 2010 - 01:52 .


#2
Morbane

Morbane
  • Members
  • 1 883 messages
SORRY ABOUT THE MESSY CODE! POSTING CODE IN HERE IS NUTS...



I HOPE THE ADMINS MAKE IT BETTER SOMEDAY!?

#3
Morbane

Morbane
  • Members
  • 1 883 messages
while(GetIsObjectValid(oTarget))
{
if(oTarget == oSelf)
{
oTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_ASTRONOMIC, lSelf, TRUE, OBJECT_TYPE_CREATURE);
}

if(GetIsInCombat() == TRUE)
{
SendMessageToPC(oSelf, "In Combat");

if(GetIsEnemy(oTarget, oSelf))
{
nEnemyCount += 1;

}//enemy

if(nEnemyCount > nBonus && GetCurrentHitPoints(OBJECT_SELF)
{
ActiveWereWolf(OBJECT_SELF);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, OBJECT_SELF, TurnsToSeconds(nDuration));
}

}
oTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_ASTRONOMIC, lSelf, TRUE, OBJECT_TYPE_CREATURE);
}//while

Modifié par Morbane, 18 juillet 2010 - 01:56 .


#4
Guest_ElfinMad_*

Guest_ElfinMad_*
  • Guests
It can certainly be done. Might need to post the whole script, I assume you are using GetFirstObjectInShape above the while loop to kick the whole thing off? I would get rid of the if(oTarget == oSelf) conditional and subsequent code so you are not calling GetNextObjectInShape twice. Wrap all the enemy specific code in your GetIsEnemy conditional, that will exclude the PC/friendlies anyway. You should be able to use any of the area effect spell codes as a guide.



Your use of OBJECT_SELF as an argument in places will refer to the object running the script, is this on purpose?

#5
Lightfoot8

Lightfoot8
  • Members
  • 2 535 messages
 // I see no reason for the check for oTarget==oSelf
 // Your next check will filter it out since he will never be hostile to himself.
 
 oTarget = GetFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_ASTRONOMIC, lSelf, TRUE, OBJECT_TYPE_CREATURE);
while(GetIsObjectValid(oTarget))
{

if(GetIsInCombat(oTarget) && GetIsEnemy(oTarget, oSelf) )
{

SendMessageToPC(oSelf, "In Combat");
nEnemyCount += 1;
}
oTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_ASTRONOMIC, lSelf, TRUE, OBJECT_TYPE_CREATURE);
     [/list]}//while
// I am  having trouble following what you are checking here.
//  Enemies Greater then bouns and has hit points ?
//also no reason for it to be in the While loop
//unless you also put a break in with it.
if(nEnemyCount > nBonus && GetCurrentHitPoints(OBJECT_SELF))
{

         ActiveWereWolf(OBJECT_SELF);
         ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, OBJECT_SELF, TurnsToSeconds(nDuration));
}

Modifié par Lightfoot8, 18 juillet 2010 - 11:30 .


#6
Morbane

Morbane
  • Members
  • 1 883 messages
Here is the modified code - it still locks the game...

#include "a_include_mor"
#include "a_inc_lycanthrope"

void main()
{
SendMessageToPC(GetFirstPC(FALSE), "Uncontrolled Cycling");

object oSelf = GetAreaOfEffectCreator();
location lSelf = GetLocation(oSelf);
object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_ASTRONOMIC, lSelf, TRUE, OBJECT_TYPE_CREATURE);

int nBonus = GetLevelByclass(class_TYPE_LYCANTHROPE, oSelf);

int nEnemyCount = 0;
int nDuration = GetCasterLevel(oSelf) - nBonus;

if(nDuration
nDuration = 1;

SendMessageToPC(GetFirstPC(), "Duration = " + IntToString(nDuration));

int nBonusMod = GetAbilityModifier(ABILITY_CONSTITUTION);

if(GetHasFeat(Feat_Bloodlust, oSelf, TRUE))
{
nDuration *= 2;
}

effect eHitPt = EffectBonus*Hitpoints(nBonus * nBonusMod);
effect eHaste = EffectHaste();
effect eWild = EffectInsane();
effect eLink = EffectLinkEffects(eHaste, eHitPt);
eLink = EffectLinkEffects(eLink, eWild);

while(GetIsObjectValid(oTarget))
{
if(GetIsInCombat() == TRUE && GetIsEnemy(oTarget, oSelf))
{
SendMessageToPC(oSelf, "In Combat/Is Enemy");
nEnemyCount ++;

}

oTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_ASTRONOMIC, lSelf, TRUE, OBJECT_TYPE_CREATURE);

}//while
SendMessageToPC(oSelf, "nEnemyCount = " + IntToString(nEnemyCount));

}//main

Modifié par Morbane, 19 juillet 2010 - 12:31 .


#7
Morbane

Morbane
  • Members
  • 1 883 messages
BTW lightfoot - how did you preserve the formatting in your post?

#8
Lightfoot8

Lightfoot8
  • Members
  • 2 535 messages
I doubt you will like the answer.

I used the BBC list code.

I searched the code and replaced all the '{' with ' {  < list]'
and all the '}' with '</list] }'

Then I still had some trouble with spaces being left so went in a removed all the spaces from the begining of the lines again. lol

Edit: Replace the < with [ in the above post

Modifié par Lightfoot8, 19 juillet 2010 - 12:41 .


#9
Morbane

Morbane
  • Members
  • 1 883 messages

Lightfoot8 wrote...

I doubt you will like the answer.

I used the BBC list code.

I searched the code and replaced all the '{' with ' {  < list]'
and all the '}' with '</list] }'

Then I still had some trouble with spaces being left so went in a removed all the spaces from the begining of the lines again. lol

Edit: Replace the < with [ in the above post


Its never easy lol 
:P

#10
Lightfoot8

Lightfoot8
  • Members
  • 2 535 messages
I cut the script down to just the while loop as posted above and had no problems with it. The only error I see in the script as Posted is



if(nDuration

nDuration = 1;





The If statment is incompleat. So I have to ask did the script compile correctly. You may still be running the old script.



Sorry if Im nit picking now. in your line.



if(GetIsInCombat() == TRUE && GetIsEnemy(oTarget, oSelf))



The expression 'GetIsInCombat() == TRUE' Concidering that GetIsInCombat () returns true or false is the same thing as 'GetIsInCombat()' So it would be better written as



if(GetIsInCombat() && GetIsEnemy(oTarget, oSelf))



This was you do not have, Or at leas I dont have to, Thry and figure out what takes presecence in the expression. I really do not know if it evaluates the == or the && first. Not that it would make a differance in this case.

#11
Morbane

Morbane
  • Members
  • 1 883 messages
My code compiles - it is just when I post - it filters out things for unknown reasons.



like with this is how I have it:

if(nDuration < 1)

nDuration = 1;



I will try to post the code again but with this expression:

effect eHitPt = EffectBonus*Hitpoints(nBonus * nBonusMod);

if I dont have the * it thinks I am trying to say the bad word for poopoo - lol



This new forum is really limited with the posting of code - every time I post something is different than what I really have. But I am sure that if the while loop is empty the script - which by the way is an AOE heartbeat script - it runs fine and the game does not lock up. I am pretty good at debugging - I was just looking for a quick fix.

#12
Lightfoot8

Lightfoot8
  • Members
  • 2 535 messages
First just encase anything I say here sounds iff.  I dont own NWN2 Im a NWN1  player.  So I may be wrong on some of your function calls.  

Here is my Cut dow version of you script that I tested. 

void main()
{
SendMessageToPC(GetFirstPC( ), "Uncontrolled Cycling");
object oSelf = OBJECT_SELF;
location lSelf = GetLocation(oSelf);
int nEnemyCount = 0;

object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_COLOSSAL, lSelf, TRUE, OBJECT_TYPE_CREATURE);
while(GetIsObjectValid(oTarget))
{
if(GetIsInCombat() && GetIsEnemy(oTarget, oSelf))
{
SendMessageToPC(oSelf, "In Combat/Is Enemy");
nEnemyCount ++;
}
oTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_COLOSSAL, lSelf, TRUE, OBJECT_TYPE_CREATURE);
[/list]}//while
SendMessageToPC(oSelf, "nEnemyCount = " + IntToString(nEnemyCount));
[/list]}//main

now I was running it on the PC.   hence I canged oSelf to   object oSelf = OBJECT_SELF;

This makes the GetInCombat() functiom get wether or not the PC (being the object it is running on)  is in combat. 

Now in your version if our functions work the same way you may need to enter in the peramater for the function.  If not you are checking to see if the AOE is in combat or not. 

Now if this is running on a HB.  and it is the oSelf that we are checking to see if they are in combat.  We may want to limit the number of times it is checking down to once.  and move the check for the limited reached back into the loop and break out of it once it is meet.  This will hopefully make the loop a little more efficent.   The only other real processor intensive calculation going on is in the GetNextObjectInShape with the line of sight peramerter being set to TRUE. 

The slightly more efficent script would look like this.  

void main()
{
SendMessageToPC(GetFirstPC( ), "Uncontrolled Cycling");
object oSelf = OBJECT_SELF;
location lSelf = GetLocation(oSelf);
int nEnemyCount = 0;
int nBonus;
// If oSelf Is not in comabt bail out no reason to go on.
// Or if His HP's are greater then half.  He will not change so no reason to check futher.
if(!GetIsInCombat(oSelf)|| (GetCurrentHitPoints(oSelf) > GetMaxHitPoints(oSelf)/2) ) return;
object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_COLOSSAL, lSelf, TRUE, OBJECT_TYPE_CREATURE);
while(GetIsObjectValid(oTarget))
{
if(GetIsEnemy(oTarget, oSelf))
{
SendMessageToPC(oSelf, "In Combat/Is Enemy");
//add one to the count and break out of while loop if quota
if (nEnemyCount > nBonus )break ;
}
oTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_COLOSSAL, lSelf, TRUE, OBJECT_TYPE_CREATURE);
[/list] }//while
SendMessageToPC(oSelf, "nEnemyCount = " + IntToString(nEnemyCount));
//in combat and HP already checked befor loop
if (nEnemyCount++ > nBonus )
{
   // Apply your effects here.
}
[/list] }//main 

Of course it is still  my cut down version. 

on building your Effects It also would not hurt to build them just befor useing them instead of at the begining of the script.  No reason to wast the time every HB if they are not needed..

The other thing i see in this and have not placed a fix for.  Is that it will apply the effects again to oSelf  even if he is has already changed.  You will need to add a check or control  to exit the script if oself is already changed.

Modifié par Lightfoot8, 19 juillet 2010 - 05:31 .


#13
Morbane

Morbane
  • Members
  • 1 883 messages
Thanks Lightfoot - looks much more streamlined. I'll put it to the test tonight after work.