Infinite Loop - how to fix?

Post » Thu Nov 04, 2010 5:34 am

Here is my script (attached to a custom weapon):

Begin OnEquip player	set AmmoSwitch to 2EndBegin GameMode	set Frag to player.GetItemCount WeapGrenadeFrag	set Plasma to player.GetItemCount WeapGrenadePlasma	set Pulse to player.GetItemCount WeapGrenadePulse	set Nuka to player.GetItemCount WeapNukaCocktail	set AmmoCount to player.GetItemCount AmmoMatol	if Frag == 0 && Plasma == 0 && Pulse == 0 && Nuka == 0		set AmmoSwitch to 1	endif	if AmmoSwitch == 1		ShowMessage MatolAmmoFail	elseif AmmoSwitch == 2		ShowMessage MatolAmmoMessage		set Button to GetButtonPressed		if Button == -1 ; None of the buttons have been pressed yet			Return		elseif Button == 0 ; Frag Grenades chosen			ShowMessage test			player.AddItem AmmoMatol Frag			set Projectile to GrenadeFragProjectile		elseif Button == 1 ; Plasma Grenades chosen			player.AddItem AmmoMatol Plasma			set Projectile to GrenadePlasmaProjectile		elseif Button == 2 ; Pulse Grenades chosen			player.AddItem AmmoMatol Pulse			set Projectile to GrenadePulseProjectile		else ; Nuka Grenades chosen			player.AddItem AmmoMatol Nuka			set Projectile to GrenadeNukaProjectile		endif			SetWeaponProjectile Projectile			set AmmoSwitch to 0	endifEnd

Whenever the weapon is equipped, the message box just keeps appearing no matter which option is chosen. Any ideas what's causing this infinite loop?
User avatar
Melanie Steinberg
 
Posts: 3365
Joined: Fri Apr 20, 2007 11:25 pm

Post » Thu Nov 04, 2010 6:12 am

if Button == -1 ; None of the buttons have been pressed yet
Return



'Return' would restart the script if a button hadn't been pressed, right? I'm not sure... I'm guessing the game returns to the start of the script before a button is pressed, so ammoswitch isn't set back to 0, so the message appears again.

What if you delete the quoted part?
User avatar
SiLa
 
Posts: 3447
Joined: Tue Jun 13, 2006 7:52 am

Post » Thu Nov 04, 2010 2:00 am

You're calling ShowMessage every frame until the player selects a button, causing "AmmoSwitch" to be set to 0. This causes a build up of messages that display one by one once the initial one has been closed.

Try using this instead:
Begin OnEquip player	set Frag to player.GetItemCount WeapGrenadeFrag	set Plasma to player.GetItemCount WeapGrenadePlasma	set Pulse to player.GetItemCount WeapGrenadePulse	set Nuka to player.GetItemCount WeapNukaCocktail	set AmmoCount to player.GetItemCount AmmoMatol	if Frag == 0 && Plasma == 0 && Pulse == 0 && Nuka == 0		ShowMessage MatolAmmoFail	else		ShowMessage MatolAmmoMessage		set AmmoSwitch to 1	endifEndBegin GameMode	if AmmoSwitch == 1		set Button to GetButtonPressed		if Button == -1 ; None of the buttons have been pressed yet			Return		elseif Button == 0 ; Frag Grenades chosen			ShowMessage test			player.AddItem AmmoMatol Frag			set Projectile to GrenadeFragProjectile		elseif Button == 1 ; Plasma Grenades chosen			player.AddItem AmmoMatol Plasma			set Projectile to GrenadePlasmaProjectile		elseif Button == 2 ; Pulse Grenades chosen			player.AddItem AmmoMatol Pulse			set Projectile to GrenadePulseProjectile		else ; Nuka Grenades chosen			player.AddItem AmmoMatol Nuka			set Projectile to GrenadeNukaProjectile		endif		SetWeaponProjectile Projectile		set AmmoSwitch to 0	endifEnd

Cipscis
User avatar
Astargoth Rockin' Design
 
Posts: 3450
Joined: Mon Apr 02, 2007 2:51 pm

Post » Thu Nov 04, 2010 7:01 am

Thanks, but thing is, later in the script, I want that when the player presses 'L' the MatolAmmoMessage is showed again and the process returns - without equipping and unequipping the weapon.
User avatar
Céline Rémy
 
Posts: 3443
Joined: Sat Apr 07, 2007 12:45 am

Post » Wed Nov 03, 2010 5:38 pm

Ok, try something like this instead then:
Begin OnEquip player	set AmmoSwitch to 2EndBegin GameMode	set Frag to player.GetItemCount WeapGrenadeFrag	set Plasma to player.GetItemCount WeapGrenadePlasma	set Pulse to player.GetItemCount WeapGrenadePulse	set Nuka to player.GetItemCount WeapNukaCocktail	set AmmoCount to player.GetItemCount AmmoMatol	if Frag == 0 && Plasma == 0 && Pulse == 0 && Nuka == 0		set AmmoSwitch to 1	endif	if AmmoSwitch == 1		ShowMessage MatolAmmoFail		set AmmoSwitch to 0	elseif AmmoSwitch == 2		ShowMessage MatolAmmoMessage		set AmmoSwitch to 3	elseif AmmoSwitch == 3		set Button to GetButtonPressed		if Button == -1 ; None of the buttons have been pressed yet			Return		elseif Button == 0 ; Frag Grenades chosen			ShowMessage test			player.AddItem AmmoMatol Frag			set Projectile to GrenadeFragProjectile		elseif Button == 1 ; Plasma Grenades chosen			player.AddItem AmmoMatol Plasma			set Projectile to GrenadePlasmaProjectile		elseif Button == 2 ; Pulse Grenades chosen			player.AddItem AmmoMatol Pulse			set Projectile to GrenadePulseProjectile		else ; Nuka Grenades chosen			player.AddItem AmmoMatol Nuka			set Projectile to GrenadeNukaProjectile		endif		SetWeaponProjectile Projectile		set AmmoSwitch to 0	endifEnd

Cipscis
User avatar
Albert Wesker
 
Posts: 3499
Joined: Fri May 11, 2007 11:17 pm

Post » Thu Nov 04, 2010 9:16 am

Thanks, that part is taken care of but I have another problem. This is the current complete script:

scn MatolScriptint Fragint Plasmaint Pulseint Nukaint Ammo ; 0 = none | 1 = someint Buttonint AmmoSwitchint AmmoCountref ProjectileBegin OnEquip player	set AmmoSwitch to 2EndBegin GameMode	set Frag to player.GetItemCount WeapGrenadeFrag	set Plasma to player.GetItemCount WeapGrenadePlasma	set Pulse to player.GetItemCount WeapGrenadePulse	set Nuka to player.GetItemCount WeapNukaCocktail	if Frag == 0 && Plasma == 0 && Pulse == 0 && Nuka == 0 && AmmoSwitch !=4		set AmmoSwitch to 1	endif	if AmmoSwitch == 1		ShowMessage MatolAmmoFail		set AmmoSwitch to 4	elseif AmmoSwitch == 2		ShowMessage MatolAmmoMessage		set AmmoSwitch to 3	elseif AmmoSwitch == 3		set Button to GetButtonPressed		if Button == -1 ; None of the buttons have been pressed yet			Return		elseif Button == 0 ; Frag Grenades chosen			player.AddItem AmmoMatol Frag			set Projectile to GrenadeFragProjectileMatol		elseif Button == 1 ; Plasma Grenades chosen			player.AddItem AmmoMatol Plasma			set Projectile to GrenadePlasmaProjectileMatol		elseif Button == 2 ; Pulse Grenades chosen			player.AddItem AmmoMatol Pulse			set Projectile to GrenadePulseProjectileMatol		else ; Nuka Grenades chosen			player.AddItem AmmoMatol Nuka			set Projectile to GrenadeNukaProjectileMatol		endif		SetWeaponProjectile Projectile		set AmmoSwitch to 0	endif	If IsControlPressed 4 == 1		if Button == 0			player.RemoveItem WeapGrenadeFrag 1		elseif Button == 1			player.RemoveItem WeapGrenadePlasma 1		elseif Button == 2			player.RemoveItem WeapGrenadePulse 1		elseif Button == 3			player.RemoveItem WeapNukaCocktail 1		endif	endif	If IsControlPressed 7 == 1		if Frag == 0 && Plasma == 0 && Pulse == 0 && Nuka == 0			set AmmoSwitch to 1		else			set AmmoSwitch to 2		endif	endifEndBegin OnUnEquip	set AmmoCount to player.GetItemCount AmmoMatol	player.RemoveItem AmmoMatol AmmoCountEnd


It's supposed to be that when the weapon is fired a grenade is removed from the player's inventory depending on the ammo chosen. The menu can also be brought up using the Reload key. The problems:
-After the first shot, all of the grenades of the chosen type are removed instead of one
-When the menu is brought up using the Reload key, it pops up twice. This is minor, but any ideas?
User avatar
Jason Rice
 
Posts: 3445
Joined: Thu Aug 16, 2007 3:42 pm

Post » Thu Nov 04, 2010 9:37 am

Thanks, that part is taken care of but I have another problem. This is the current complete script:

	If IsControlPressed 4 == 1		if Button == 0			player.RemoveItem WeapGrenadeFrag 1		elseif Button == 1			player.RemoveItem WeapGrenadePlasma 1		elseif Button == 2			player.RemoveItem WeapGrenadePulse 1		elseif Button == 3			player.RemoveItem WeapNukaCocktail 1		endif	endif	If IsControlPressed 7 == 1		if Frag == 0 && Plasma == 0 && Pulse == 0 && Nuka == 0			set AmmoSwitch to 1		else			set AmmoSwitch to 2		endif	endifEndBegin OnUnEquip	set AmmoCount to player.GetItemCount AmmoMatol	player.RemoveItem AmmoMatol AmmoCountEnd


It's supposed to be that when the weapon is fired a grenade is removed from the player's inventory depending on the ammo chosen. The menu can also be brought up using the Reload key. The problems:
-After the first shot, all of the grenades of the chosen type are removed instead of one
-When the menu is brought up using the Reload key, it pops up twice. This is minor, but any ideas?


You may need a timer to disable the 'IsControlPressed' blocks for a bit after they are triggered. For example, when you press the 'attack' control, this block could run multiple times while your finger is pressing the control because it runs every frame. If you are at 60fps and it takes .25 sec to hit the button, it will run 15 times.
User avatar
john palmer
 
Posts: 3410
Joined: Fri Jun 22, 2007 8:07 pm

Post » Thu Nov 04, 2010 8:47 am

Oh, I got it. Is there a command to suspend the script or a while (like Sleep in many programming languages) or do I need to set up a timer?
User avatar
Sheila Reyes
 
Posts: 3386
Joined: Thu Dec 28, 2006 7:40 am

Post » Wed Nov 03, 2010 7:47 pm

Oh, I got it. Is there a command to suspend the script or a while (like Sleep in many programming languages) or do I need to set up a timer?


You have to do a timer. I would make one timer that disables all the control blocks while it is counting down.
User avatar
koumba
 
Posts: 3394
Joined: Thu Mar 22, 2007 8:39 pm

Post » Thu Nov 04, 2010 1:26 am

I did a timer, but it didn't work. Any other ideas?
User avatar
NAtIVe GOddess
 
Posts: 3348
Joined: Tue Aug 15, 2006 6:46 am

Post » Wed Nov 03, 2010 10:01 pm

I did a timer, but it didn't work. Any other ideas?


This is from the wiki. It will make sure your code only runs once when the control is pressed. Once the key is pressed it executes your command, and sets the variable. As long as the key is held down from then on the script will return, and not run your code again.

if ( curKey && isControlPressed curkey ) ; key still being held down
return ; wait until it's released
else
set curkey to 0
endif

if ( isControlPressed )
; do stuff
set curKey to
endif
User avatar
TWITTER.COM
 
Posts: 3355
Joined: Tue Nov 27, 2007 3:15 pm

Post » Wed Nov 03, 2010 11:40 pm

Hmm, I'm not sure how to integrate that into my script...
User avatar
Oscar Vazquez
 
Posts: 3418
Joined: Sun Sep 30, 2007 12:08 pm

Post » Wed Nov 03, 2010 7:30 pm

Placement of the first section with the return is critical. It must be before the section below it, but can be near the top of your script if you want.
short curKeyif ( curKey && isControlPressed curkey ) ; key still being held downreturn ; wait until it's releasedelseset curkey to 0endif	If IsControlPressed 7 == 1		if Frag == 0 && Plasma == 0 && Pulse == 0 && Nuka == 0			set AmmoSwitch to 1                        set curKey to 7		else			set AmmoSwitch to 2                         set curKey to 7		endif	endif

User avatar
louise fortin
 
Posts: 3327
Joined: Wed Apr 04, 2007 4:51 am

Post » Wed Nov 03, 2010 11:28 pm

Placement of the first section with the return is critical. It must be before the section below it, but can be near the top of your script if you want.
short curKeyif ( curKey && isControlPressed curkey ) ; key still being held downreturn ; wait until it's releasedelseset curkey to 0endif	If IsControlPressed 7 == 1		if Frag == 0 && Plasma == 0 && Pulse == 0 && Nuka == 0			set AmmoSwitch to 1                        set curKey to 7		else			set AmmoSwitch to 2                         set curKey to 7		endif	endif


Thanks! It worked! Now to solve the part where all of the grenades are removed...
User avatar
Claire Vaux
 
Posts: 3485
Joined: Sun Aug 06, 2006 6:56 am

Post » Thu Nov 04, 2010 12:41 am

My preferred code structure for hotkey detection is this:
int bIsNPressedBegin GameMode	if bIsNPressed != IsKeyPressed 49 ; N		set bIsNPressed to IsKeyPressed 49		if bIsNPressed			; N has been pressed		else			; N has been released		endif	endifEnd
The fact that it doesn't include a "Return" statement will probably make it easier to integrate into a script.

Cipscis
User avatar
Natalie Taylor
 
Posts: 3301
Joined: Mon Sep 11, 2006 7:54 pm

Post » Wed Nov 03, 2010 8:30 pm

Thanks, but my script works perfectly now. Here it is:

scn MatolScriptint Fragint Plasmaint Pulseint Nukaint Ammo ; 0 = none | 1 = someint Buttonint AmmoSwitchint AmmoCountint Shootshort curKeyref ProjectileBegin OnEquip player	set AmmoSwitch to 2EndBegin GameMode	set Frag to player.GetItemCount WeapGrenadeFrag	set Plasma to player.GetItemCount WeapGrenadePlasma	set Pulse to player.GetItemCount WeapGrenadePulse	set Nuka to player.GetItemCount WeapNukaCocktail	set AmmoCount to player.GetItemCount AmmoMatol	if Frag == 0 && Plasma == 0 && Pulse == 0 && Nuka == 0 && AmmoSwitch !=4 && AmmoCount == 0		set AmmoSwitch to 1	endif	if AmmoSwitch == 1		ShowMessage MatolAmmoFail		set AmmoSwitch to 4	elseif AmmoSwitch == 2		ShowMessage MatolAmmoMessage		set AmmoSwitch to 3	elseif AmmoSwitch == 3		set Button to GetButtonPressed		if Button == -1 ; None of the buttons have been pressed yet			Return		elseif Button == 0; Frag Grenades chosen			player.AddItem AmmoMatol Frag 1			player.removeitem AmmoMatol AmmoCount 1			set Projectile to GrenadeFragProjectileMatol		elseif Button == 1 ; Plasma Grenades chosen			player.AddItem AmmoMatol Plasma 1			player.removeitem AmmoMatol AmmoCount 1			set Projectile to GrenadePlasmaProjectileMatol		elseif Button == 2 ; Pulse Grenades chosen			player.AddItem AmmoMatol Pulse 1			player.removeitem AmmoMatol AmmoCount 1			set Projectile to GrenadePulseProjectileMatol		else ; Nuka Grenades chosen			player.AddItem AmmoMatol Nuka 1			player.removeitem AmmoMatol AmmoCount 1			set Projectile to GrenadeNukaProjectileMatol		endif		SetWeaponProjectile Projectile		set AmmoSwitch to 0	endif	If IsControlPressed 4 == 1		if Button == 0 && Shoot == 0			player.RemoveItem WeapGrenadeFrag 1 1			set Shoot to 1		elseif Button == 1 && Shoot == 0			player.RemoveItem WeapGrenadePlasma 1 1			set Shoot to 1		elseif Button == 2 && Shoot == 0			player.RemoveItem WeapGrenadePulse 1 1			set Shoot to 1		elseif Button == 3 && Shoot == 0			player.RemoveItem WeapNukaCocktail 1 1			set Shoot to 1		endif	else		set Shoot to 0	endif	if ( curKey && isControlPressed curkey ) ; key still being held down		return ; wait until it's released	else		set curkey to 0	endif	If IsControlPressed 7 == 1		if Frag == 0 && Plasma == 0 && Pulse == 0 && Nuka == 0			set AmmoSwitch to 1			set curKey to 7		else			set AmmoSwitch to 2			set curKey to 7		endif	endifEndBegin OnUnEquip	set AmmoCount to player.GetItemCount AmmoMatol	player.RemoveItem AmmoMatol AmmoCountEnd

User avatar
Angel Torres
 
Posts: 3553
Joined: Thu Oct 25, 2007 7:08 am

Post » Thu Nov 04, 2010 9:20 am

Glad to hear it. You can shorten your script slightly by optimising your conditional statements like this:
Spoiler
scn MatolScriptint Fragint Plasmaint Pulseint Nukaint Ammo ; 0 = none | 1 = someint Buttonint AmmoSwitchint AmmoCountint Shootshort curKeyref ProjectileBegin OnEquip player	set AmmoSwitch to 2EndBegin GameMode	set Frag to player.GetItemCount WeapGrenadeFrag	set Plasma to player.GetItemCount WeapGrenadePlasma	set Pulse to player.GetItemCount WeapGrenadePulse	set Nuka to player.GetItemCount WeapNukaCocktail	set AmmoCount to player.GetItemCount AmmoMatol	if Frag == 0 && Plasma == 0 && Pulse == 0 && Nuka == 0 && AmmoSwitch !=4 && AmmoCount == 0		set AmmoSwitch to 1	endif	if AmmoSwitch == 1		ShowMessage MatolAmmoFail		set AmmoSwitch to 4	elseif AmmoSwitch == 2		ShowMessage MatolAmmoMessage		set AmmoSwitch to 3	elseif AmmoSwitch == 3		set Button to GetButtonPressed		if Button == -1 ; None of the buttons have been pressed yet			Return		elseif Button == 0; Frag Grenades chosen			player.AddItem AmmoMatol Frag 1			player.removeitem AmmoMatol AmmoCount 1			set Projectile to GrenadeFragProjectileMatol		elseif Button == 1 ; Plasma Grenades chosen			player.AddItem AmmoMatol Plasma 1			player.removeitem AmmoMatol AmmoCount 1			set Projectile to GrenadePlasmaProjectileMatol		elseif Button == 2 ; Pulse Grenades chosen			player.AddItem AmmoMatol Pulse 1			player.removeitem AmmoMatol AmmoCount 1			set Projectile to GrenadePulseProjectileMatol		else ; Nuka Grenades chosen			player.AddItem AmmoMatol Nuka 1			player.removeitem AmmoMatol AmmoCount 1			set Projectile to GrenadeNukaProjectileMatol		endif		SetWeaponProjectile Projectile		set AmmoSwitch to 0	endif	If IsControlPressed 4		if Shoot == 0			if Button != -1				set Shoot to 1				if Button == 0					player.RemoveItem WeapGrenadeFrag 1 1				elseif Button == 1					player.RemoveItem WeapGrenadePlasma 1 1				elseif Button == 2					player.RemoveItem WeapGrenadePulse 1 1				else					player.RemoveItem WeapNukaCocktail 1 1				endif			endif		endif	else		set Shoot to 0	endif	if ( curKey && isControlPressed curkey ) ; key still being held down		return ; wait until it's released	else		set curkey to 0	endif	If IsControlPressed 7		if Frag == 0 && Plasma == 0 && Pulse == 0 && Nuka == 0			set AmmoSwitch to 1			set curKey to 7		else			set AmmoSwitch to 2			set curKey to 7		endif	endifEndBegin OnUnEquip	set AmmoCount to player.GetItemCount AmmoMatol	player.RemoveItem AmmoMatol AmmoCountEnd
You also seem to have not used your "Ammo" variable anywhere. Is it vestigial from something, or have you just not implemented it yet?

Cipscis
User avatar
Charlie Ramsden
 
Posts: 3434
Joined: Fri Jun 15, 2007 7:53 pm

Post » Thu Nov 04, 2010 3:18 am

The ammo is just a leftover from my first attempt. Thanks everyone for your help!
User avatar
leni
 
Posts: 3461
Joined: Tue Jul 17, 2007 3:58 pm


Return to Fallout 3