My script is causing a ctd

Post » Tue May 17, 2011 7:28 am

I'm working on a hunger mod, and I'm havign quite a bit of trouble with this particular script.

Here's what my script is supposed to do: When the player clicks on a food item in their inventory, the food's information is passed to a function so that it can be processed and runger reduced appropriately.

Here's what it does: When I click on a food item in my inventory, I get a CTD. I commented out all of the code that's supposed to happen, so that the only thing left is a PrintToConsole, but I still get a CTD. What the heck?

I'm using OBSE v19. Here's my script.
scn HvHungerOBSEWort;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;This script detects when the player eats food from their inventory, and reduces hunger appropriately.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;short initfloat fQuestDelayTimeref FoodRefshort EatOnce	;;;;; We only need to run the script while the player is in their inventory screen (MenuMode 1002), so that's all we'll be using. ;;;;;Begin MenuMode 1002		;;;;; Here we initialize the script.  This is only ever done once. ;;;;;	if ( init == 0 )		let fQuestDelayTime := 0.01		let init := 1	endif		;;;;; Here, we detect the menu selection your mouse is currently scrolled over.  If it's food, we disable the left mouse button. ;;;;;		;;;;; With the left mouse button disabled, we can detect the button press via the script.  If it is pressed, we can first pass the ;;;;;		;;;;; food's information to the rest of the script, then force-eat the food.  When the player isn't mousing over a food item, we ;;;;;		;;;;; enable the left mouse button again. ;;;;;	let FoodRef := GetActiveMenuSelection	if eval ( IsIngredient  FoodRef ) && ( IsFood FoodRef )		DisableControl 4	else		EnableControl 4		return	endif		;;;;; The following block runs when the player presses down "control 4" (by default, left mouse button). ;;;;;	if ( OnControlDown 4 )		;if ( IsKeyPressed3 42 ) ;; <- This checks if the player is holding the left shift key - ie, to drop the food instead of eat it. ;;		;	Player.Drop FoodRef 1		;	PrintToConsole "Force-dropped n% (or tried to)." FoodRef		;else		;	;Call HvEat FoodRef 0 ;;;;; <- caused a ctd? ;;;;;		;	Player.EquipItemNS FoodRef ;;;; <- happened twice? ;;;;;			PrintToConsole "Force-ate n% (or tried to)." FoodRef		;endif	endifEnd

Note: I've tried using IsControlPressed instead of OnControlDown, with a check to make sure it only runs once. I wasn't getting a CTD, but it was eating 2 pieces of food instead of one. Also, when I called the function, it *still* CTD'd.
User avatar
xxLindsAffec
 
Posts: 3604
Joined: Sun Jan 14, 2007 10:39 pm

Post » Tue May 17, 2011 8:32 am

Ooookay, so after reviewing my code above, I fixed the "n%" on the console printouts, so they're "%n" now. CTD fixed. Problem still not fixed. When I click on the food item in my inventory now, I eat it (vanilla eat, not my eat). This is a problem. According to how I have the script set up, the button should be disabled. Clicking on the food SHOULD do nothing, except give me a console printout.


...Huh, wait a sec. Maybe I can work with this. I was planning to force-eat the food anyway, with EquipItemNS, this would just eliminate the need to do so.


I'd still like to know why DisableControl isn't disabling the control like it should. Any ideas?
User avatar
Johanna Van Drunick
 
Posts: 3437
Joined: Tue Jun 20, 2006 11:40 am

Post » Tue May 17, 2011 6:10 am

if eval ( IsIngredient FoodRef ) && ( IsFood FoodRef )
Have you checked that the items really are considered food and ingredient at the same time, since that's what you require? Sure you don't mean "if eval ( IsIngredient FoodRef ) || ( IsFood FoodRef )"?


Btw, the following code is problematic from a compatibility view:
	if eval ( IsIngredient  FoodRef ) && ( IsFood FoodRef )		DisableControl 4	else		EnableControl 4		return	endif

This code effectively prevents any other mod from disabling the same control in that menu. If you instead change to:
	if eval ( IsIngredient  FoodRef ) && ( IsFood FoodRef )		let controlDisabled := 1		DisableControl 4	else		if  controlDisabled			EnableControl 4			let controlDisabled := 0		endif		return	endif
you ensure that you only enable the control once when you really have disabled it.
User avatar
Farrah Barry
 
Posts: 3523
Joined: Mon Dec 04, 2006 4:00 pm

Post » Tue May 17, 2011 4:02 am

Hm, you make good points with the compatability thing. I do mean "( IsIngredient FoodRef ) && ( IsFood FoodRef )" by the way. Some potions (ie alchohol) are considered food as well, so using "if eval ( IsIngredient FoodRef ) || ( IsFood FoodRef )" instead would make it return true for ANY ingredient, as well as any edible potion.

For now, though, I've given up on disabling controls altogether. Detecting controls appears to be enough, I guess. Here's my latest version:

scn HvHungerOBSEWort;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;This script detects when the player eats food from their inventory, and reduces hunger appropriately.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;short initfloat fQuestDelayTimeref FoodRef	;;;;; We only need to run the script while the player is in their inventory screen (MenuMode 1002), so that's all we'll be using. ;;;;;Begin MenuMode 1002		;;;;; Here we initialize the script.  This is only ever done once. ;;;;;	if ( init == 0 )		let fQuestDelayTime := 0.01		let init := 1	endif			let FoodRef := GetActiveMenuSelection	if eval ( IsIngredient  FoodRef == 0 ) || ( IsFood FoodRef == 0 )		return	endif		;;;;; The following block runs when the player presses down "control 4" (by default, left mouse button). ;;;;;	if ( OnControlDown 4 )		if ( IsKeyPressed3 42 ) ;; <- This checks if the player is holding the left shift key - ie, to drop the food instead of eat it. ;;		;	Player.Drop FoodRef 1		;	PrintToConsole "Force-dropped %n (or tried to)." FoodRef		else			Call HvEat FoodRef 0 ;;;;; <- let's try this again ;;;;;		;	Player.EquipItemNS FoodRef ;;;; <- happened twice? ;;;;;		;	PrintToConsole "Force-ate %n (or tried to)." FoodRef		endif	endifEnd


The only bug is that when I first load up the game, the first food item I click on is registered as eaten (called successfully to HvEat), but the player doesn't actually eat it. This only seems to happen once though, but I don't know why it's causing it.
User avatar
Devils Cheek
 
Posts: 3561
Joined: Sun Aug 13, 2006 10:24 pm

Post » Tue May 17, 2011 2:06 pm

The only bug is that when I first load up the game, the first food item I click on is registered as eaten (called successfully to HvEat), but the player doesn't actually eat it. This only seems to happen once though, but I don't know why it's causing it.


Try setting fQuestDelayTime somewhere else. In your script fQuestDelayTime will not be set before you first open the inventory. And then the quest script might run yet when you press the key.
User avatar
Dina Boudreau
 
Posts: 3410
Joined: Thu Jan 04, 2007 10:59 pm


Return to IV - Oblivion