Jump to content
Sign in to follow this  
jaenak

Script error

Recommended Posts

I copied the script by ConanOfOz called "SimpleScan" recently and have tried it out. It seems to work but every now and then when I play the level I get an error message. Its not all the time, and its not even every time I play the level but I still get it and I'm not sure what it means or what to do about it. The error message is

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

_ThisGuy = _Enemies Select _Index|#|: Error Zero Divisor

and the script is

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

;SimpleScan.sqs

;This script makes up for the fact that the OFP Mission Trigger will return a TRUE

;condition for detection even though the 'detecting' unit has just died.

;Requirements...

;init.sqs must set -

; NeedToScan = False

; ICU = False

; KAThreshold = a number between 0 and 4 (recommend 1.6)

;

;Trigger

; Name - EastPresent

; Activation - East Present, Repeatedly

; Condition - This

;

;Trigger

; Name - Busted

; Activation - None

; Condition - ICU (Boolean set by this script)

; Note - This is the actual 'alarm' per se. Set your Effect (e.g. sound alarm)

; or whatever action you wish to take here, or as On Activation, or both

;

;Trigger

; Name - Detected

; Activation - West Detected by East, Repeatedly

; Condition - This

; On Activation - NeedToScan = True; [] Exec "SimpleScan.sqs"

; On Deactivation - NeedToScan = False

; Note - We are using this mainly because we can avoid running our SimpleScan script

; all the time. NeedToScan = False will tell this script to exit. ICU = False

; will deactivate Trigger "Busted", our true 'alarm' Trigger.

#StartHere

;Get list of potential enemy 'detectors'

;'EastPresent' is a trigger activated by 'East - Present'.

_Enemies = List EastPresent

;Initialise our index pointer

_Index = 0

;Discover size of _Enemies array

_MaxEnemies = Count _Enemies

?_MaxEnemies == 0: Goto "NoEnemies"

Goto "CarryOn"

#NoEnemies

~1

Goto "StartHere"

#CarryOn

;Start by assuming there is no true detection

_ThisICU = False

#LivingDetect

;Enemy must have a KnowsAbout (KA) value greater than KAThreshold

;KAThreshold is defined in init.sqs. Values are 0 - 4 (decimals permitted)

;This enemy must be alive!

;If in ANY case an Enemy has KA > KAThreshold AND is alive, trigger the Busted

_ThisGuy = _Enemies Select _Index

_ThisICU = _ThisICU or (((_ThisGuy KnowsAbout Player) >= KAThreshold) and (Alive _ThisGuy))

;Move to next unit.

_Index = _Index + 1

;If there is a 'next unit', go get him.

?(_Index < _MaxEnemies): Goto "LivingDetect"

;_ThisICU will now be true if ANY of the above iterations was true

ICU = _ThisICU

;If ICU is true, we can wait a few seconds before repeating this script

?!ICU: Goto "DontWait"

~2

#DontWait

;Whether ICU is true or not, we don't need to scan every microsecond.

;4 times per second is ample, so...

~0.25

?NeedToScan : Goto "StartHere"

;If Trigger "Detect" has deactivated and set NeedToScan to false, then we can assume

;that ICU can also be false, and thereby deactivate Trigger "Busted"

ICU = False

I don't know if the error message causes the script to quit or not or if its just one of those annoying cosmetic things.

If anyone can help me out, I'd be very appreciative. If you need more info on the SimpleScan script, do a search for SimpleScan and click on the thread of the same name.

Share this post


Link to post
Share on other sites

Optimisation tip:

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

_ThisICU = _ThisICU or (((_ThisGuy KnowsAbout Player) >= KAThreshold) and (Alive _ThisGuy))

;Move to next unit.

_Index = _Index + 1

Once _ThisICU becomes set to a non-zero value (boolean TRUE), the loop should exit - there is no need to move to the next unit (with _index = _index +1)

So, replace above code with:

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

_ThisICU = _ThisICU or (((_ThisGuy KnowsAbout Player) >= KAThreshold) and (Alive _ThisGuy))

; Tracy_t: this optimises the loop

? _ThisICU !=0: goto "loopdone"

;Move to next unit.

_Index = _Index + 1

Now when _ThisICU is TRUE, the loop will exit. See below for where the loop will exit to smile_o.gif

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

;_ThisICU will now be true if ANY of the above iterations was true

; Inserted by tracy_t

#loopdone

ICU = _ThisICU

Share this post


Link to post
Share on other sites

Oh yes, and the reason why you are getting the zero divisor error is because you are trying to access an element (in your case, a vehicle/soldier etc) in the list that does not exist any more, because:

a) The vehicle/ soldier has died since

b) The vehicle / soldier has been deleted since (with DeleteVehicle statement - see command reference.)

So:

You could check that _ThisGuy will hold a valid object reference by using:

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

?_Index >= count list EastPresent: goto "loopdone" ; see my previous code

_ThisGuy = _Enemies Select _Index

; Best to check that the guy hasn't died!!!

? !alive(_ThisGuy): goto "theguyisdead"

Share this post


Link to post
Share on other sites

I'm not sure if I said it already so I'll just go ahead and say it. The reason the guy came up with this particular script was to develop a different version of the side detected by side trigger condition. Currently the one side is detected at a knowsabout level of 1.0 and can be detected by anyone regardless of whether or not the person has died or not. And if the person shoots someone in a group or near someone else, that group or that person can also detect the individual. For an example, if I wanted to snipe an officer in a group and he was standing infront of someone and talking to them, I shoot the officer, he shoots up a knowsabout rating of 1.5 regardless of the fact that he's dead. The person he's talking to and his group as well also throw up the same rating of 1.5 regardless of the fact that they can't see the person. He wrote this script to perform the side detected by side trigger condition PLUS the knowsabout level can be set to whatever the mission designer wants and can only be set off by a person that's still alive. If the person with the knowsabout rating equal to or higher than the threshhold set by the mission designer is already dead, than his rating is ignored and the trigger isn't set off.

Your second post, yes that's true. Now that you mention it I always did get that error message AFTER I killed someone. And your code in your second post fixes the error caused by that, right? But as for your first post, I don't want the script to exit once someone has a knowsabout level higher than zero. I want it to continue functioning until one of the people's knowsabout levels reaches or exceeds the knowsabout level set in the init file. When that has been accomplished, I want the script to set ICU to be true and then exit.

If I've misunderstood anything, sorry.

Share this post


Link to post
Share on other sites

Hello.

Sorry, I know what the code is intended to achieve but look at the following statement:

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

_ThisICU = _ThisICU or (((_ThisGuy KnowsAbout Player) >= KAThreshold) and (Alive _ThisGuy))

This code produces a boolean result, 0 or 1 (I'm not being cheeky, apologies if I sound like I am) which is stored in _ThisICU.

Once _ThisICU is set to 1, then no matter what else happens, _ThisICU will remain set to 1, it's just the nature of the OR bit operator.

Therefore there is no point in continuing through the rest of the loop. I've looked at the code again and I can assure you my solution is correct and would make the code faster.

The whole point of the code is to return ICU = _thisICU so, once _thisICU is set to 1 nothing can change it, so you'd be as well as exiting the loop. If that makes sense biggrin_o.gif

Regards,

Scott

Share this post


Link to post
Share on other sites

I gotcha now!  smile_o.gif  So once as the script sets ICU to true (which would set off the alarm) then the script was still going?  That is weird.  If it sets off the alarm, there really is no point in having the script run anymore.  Well, thank you! I'll try this out and post the results.

Share this post


Link to post
Share on other sites

No, once _thisICU was set to 1 the script was still going biggrin_o.gif

But you're on the right lines lol

Regards,

Scott

Share this post


Link to post
Share on other sites
Guest jacobaby

I may be missing something here and I only quickly scanned the thread, but does that line even mean anything?

I mean it uses OR+ AND which are cmds you use in a condition.

But there is NO condition in the line

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

_ThisICU = _ThisICU or (((_ThisGuy KnowsAbout Player) >= KAThreshold) and (Alive _ThisGuy))

by condition i mean @ or ?

see what I mean?

I really dont think that will work, if i get time later I will help you further, gotta go to the bank before it shuts!!

TJ

Share this post


Link to post
Share on other sites

No,

That line of code is correct: _thisICU is being set to the result of a boolean operation: OR + AND are used as boolean & bitwise operators. The product of the boolean calculation is being stored in _thisICU.

You don't need any if (?) or wait (@) conditions.

So here's what's happening.

(_ThisGuy knowsabout Player >= KAThreshold) produces a boolean result, 1 or 0, whether or not the guy has enough knowledge of the player. (The >= operator returns a boolean result)

We'll call this result A.

(_Alive _thisguy) returns 1 or 0 (TRUE or FALSE). We'll call this result B.

The result from the calculation is A AND B, as seen here:

(((_ThisGuy KnowsAbout Player) >= KAThreshold) and (Alive _ThisGuy))

So, if you remember the rules of boolean AND:

1 AND 1 = 1

1 AND 0 = 0

0 AND 1 = 0

0 AND 0 = 0

So only when A and B are set to 1 does the whole expression return 1 (meaning TRUE), otherwise 0 (FALSE) is returned.

Thus, When _thisICU is ORed with the result of the expression, _thisICU can only ever be set to 0 or 1.

However, once _thisICU is set to 1, there is no point in doing any further boolean ORs - an OR cannot reset a value to 0!!!

I hope this explains things  crazy_o.gif

lol

Regards,

Scott

Share this post


Link to post
Share on other sites
Guest jacobaby

I understand the code, but thanks for the lesson tounge_o.gif

What I was unaware of was that a VARIABLE could have an OR in the definition of itself. That may prove useful to know, thanks.

why do you say that the variable cannot be reset to 0/false though?

TJ

Share this post


Link to post
Share on other sites
I understand the code, but thanks for the lesson  tounge_o.gif

What I was unaware of was that a VARIABLE could have an OR in the definition of itself. That may prove useful to know, thanks.

why do you say that the variable cannot be reset to 0/false though?

TJ

Sorry for stating the obvious lol

Oh, _ThisICU can be reset to 0, but not by a bitwise OR statement. There is no way you can reset a variable to 0 using the OR operator.

Say _ThisICU was set to 1.

Whatever number you OR with _ThisICU, you will have a non-zero product.

_ThisICU = _ThisICU or 0 : still gives you 1

_ThisICU = _ThisICU or 65535: gives you 65535 (still non-zero)

etc etc.

Share this post


Link to post
Share on other sites

Tracy_T, did I do this right?

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

#LivingDetect

;Enemy must have a KnowsAbout (KA) value greater than KAThreshold

;KAThreshold is defined in init.sqs. Values are 0 - 4 (decimals permitted)

;This enemy must be alive!

;If in ANY case an Enemy has KA > KAThreshold AND is alive, trigger the Busted

?_Index >= count list EastPresent: goto "loopdone"

_ThisGuy = _Enemies Select _Index

;Best to check the guy hasn't died!!!

? !alive(_ThisGuy): goto "theguyisdead"

_ThisICU = _ThisICU or (((_ThisGuy KnowsAbout Player) >= KAThreshold) and (Alive _ThisGuy))

;Tracy_T: this optimises the loop

?_ThisICU !=0: got "loopdone"

;Move to next unit.

_Index = _Index + 1

;If there is a 'next unit', go get him.

?(_Index < _MaxEnemies): Goto "LivingDetect"

;_ThisICU will now be true if ANY of the above iterations was true

ICU = _ThisICU

;inserted by Tracy_T

#loopdone

ICU = _ThisICU

;If ICU is true, we can wait a few seconds before repeating this script

?!ICU: Goto "DontWait"

~2

And one question, when it says goto "theguyisdead", I can't find any other section with the words "theguyisdead" in it. I am a newbie at scripting so this could be a really stupid question!

Share this post


Link to post
Share on other sites
Guest jacobaby
Oh, _ThisICU can be reset to 0, but not by a bitwise OR statement. There is no way you can reset a variable to 0 using the OR operator.

Say _ThisICU was set to 1.

Whatever number you OR with _ThisICU, you will have a non-zero product.

_ThisICU = _ThisICU or 0 : still gives you 1

_ThisICU = _ThisICU or 65535: gives you 65535 (still non-zero)

etc etc.

Roger that, but you CAN set it to a boolean setting, including setting a previously true var to false, using OR.

Numerical 1 and 0 are numerical values and are perhaps different to TRUE/FALSE,

was gonna type more but the WODKA! is kicking in biggrin_o.gif

TJ

Share this post


Link to post
Share on other sites

Jaenak, did you solve your problem?

I was off for a few weeks to get drunk etc.. you know the score biggrin_o.gif

Regards,

S.

Share this post


Link to post
Share on other sites

Sorry, I've been off for a few days myself. I bought Simcity 4. Anyway though, I have a new error message now.

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

'_ThisICU !=0|#|': Error !=: Type Bool, Expected Number,String,Object,Side,Group

I sure am glad somebody understands this stuff cause this whole problem with this script was way beyond me right from the get go! smile_o.gif

Share this post


Link to post
Share on other sites

Now I get a slightly different error message.

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

'_ThisICU != False|#|': Error !=: Type Bool, Expected Number,String,Object,Side,Group

And I read your post in the Mission Editing FAQ on simplifying scripts. wow_o.gif I was completely ignorant of the fact that the game's speed was effected by how complex the script was! So I copied the SimpleScan script and a bunch of others on my computer and pasted them into a folder on my desktop. I've gone through a couple scripts thus far, (mostly simple ones smile_o.gif ) and have simplified them. This script is way over my head though. The best I could do was:

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

#SH

_Enemies = List EastPresent

_Index = 0

_MaxEnemies = Count _Enemies

?_MaxEnemies == 0: Goto "NE"

Goto "CO"

#NE

~1

Goto "SH"

#CO

_ThisICU = False

#Lid

?_Index >= count list EastPresent: goto "ld"

_ThisGuy = _Enemies Select _Index

? !alive(_ThisGuy): goto "theguyisdead"

_ThisICU = _ThisICU or (((_ThisGuy KnowsAbout Player) >= KAT) and (Alive _ThisGuy))

?_ThisICU != false : goto "ld"

_Index = _Index + 1

?(_Index < _MaxEnemies): Goto "Lid"

ICU = _ThisICU

#ld

ICU = _ThisICU

?!ICU: Goto "DW"

~2

#DW

~0.25

?NTS : Goto "SH"

ICU = False

And for my own sake I took the notes at the top of the file and put them into a notepad file so I can still refer to them if I need to. My question to you though is how else can I simplify this script? And how this particular script works is beyond me but there's alot of scripting here. Is it all nessisary? for an example one line of it says <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">? !alive(_ThisGuy): goto "theguyisdead" I myself can't see any section of this script named "theguyisdead" And I thought you said to avoid the list function whenever possible. Can I do that with this script?

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

×