Scripting workaround for manual eating

Post » Thu Sep 01, 2011 6:28 am

Hello,
First of all sorry for a long post and please excuse my poor grammar - I'm not a native speaker.

I'm working on a new modular necessities mod for Morrowind (not based on NOM). The hunger plugin tracks how hungry you are and applies increasing penalties. Unlike other similar mods this plugin is not based on a fixed eating habits - instead the hunger is increasing every in-game hour and can be reduced (even if the penalties are not yet applied) by manually eating some food. I've already finished all of the main scripts for hunger, thirst, sleep and bath needs. Basically, the only thing left is finishing the manual eating system.

For manual eating I'm using Toccatta's solution introduced in Morrowind Crafting plugin (cooked food as potions with "remove curse" effect and "( player -> geteffect, sEffectRemoveCurse == 1)" function running every second to effectively reduce hunger). The plugin is already compatible with cooked food introduced in Morrowind Crafting. Unfortunetly for compatibility sake I can't change the vanilla ingredients into potions so I'm looking for a different method to implement manual eating for ingredients, without adding script into them (because of compatibility and the fact that scripted items are not stacking in inventory).

My current solution for adding an effect to vanilla ingredients without attaching scripts is as shown below:

begin nec_hunger_manualeat_i        ;short nec_hunger_effect    ;GLOBAL    short done    short frame        ;VANILLA    short bread_01_old    short kwama_egg_01_old    short kwama_egg_02_old    short scrib_jerky_01_old    short rat_meat_01_old    short crab_meat_01_old    short hound_meat_01_old    short durzog_meat_01_old    short scuttle_01_old    short hackle-lo_leaf_01_old    short saltrice_01_old    short bc_hypha_facia_old    short marshmerrow_01_old    short comberry_01_old    short scrib_cabbage_01_old    short holly_01_old    set frame to ( frame + 1 )    if ( frame < 10 )        return    else        set frame to 0    endif    if ( PCVampire == 1 )        return    elseif ( player->IsWerewolf == 1 )        return    endif    if ( done == 0 )        set bread_01_old to ( player->GetItemCount "ingred_bread_01" )        set kwama_egg_01_old to ( player->GetItemCount "food_kwama_egg_01" )        set kwama_egg_02_old to ( player->GetItemCount "food_kwama_egg_02" )        set scrib_jerky_01_old to ( player->GetItemCount "ingred_scrib_jerky_01" )        set rat_meat_01_old to ( player->GetItemCount "ingred_rat_meat_01" )        set crab_meat_01_old to ( player->GetItemCount "ingred_crab_meat_01" )        set hound_meat_01_old to ( player->GetItemCount "ingred_hound_meat_01" )        set durzog_meat_01_old to ( player->GetItemCount "ingred_durzog_meat_01" )        set scuttle_01_old to ( player->GetItemCount "ingred_scuttle_01" )        set hackle-lo_leaf_01_old to ( player->GetItemCount "ingred_hackle-lo_leaf_01" )        set saltrice_01_old to ( player->GetItemCount "ingred_saltrice_01" )        set bc_hypha_facia_old to ( player->GetItemCount "ingred_bc_hypha_facia" )        set marshmerrow_01_old to ( player->GetItemCount "ingred_marshmerrow_01" )        set comberry_01_old to ( player->GetItemCount "ingred_comberry_01" )        set scrib_cabbage_01_old to ( player->GetItemCount "ingred_scrib_cabbage_01" )        set holly_01_old to ( player->GetItemCount "ingred_holly_01" )        set done to 1    endif    if ( Player->GetSoundPlaying, "Item Ingredient Down" == 1 )        set done to 0            ;MessageBox "Debug message: GetSoundPlaying"        return    endif    if ( bread_01_old > ( player->GetItemCount "ingred_bread_01" ) )        set bread_01_old to ( player->GetItemCount "ingred_bread_01" )        set nec_hunger_effect to ( nec_hunger_effect + 6 )    elseif ( bread_01_old < ( player->GetItemCount "ingred_bread_01" ) )        set bread_01_old to ( player->GetItemCount "ingred_bread_01" )            ;MessageBox, "Debug message: old < current."    endif    if ( kwama_egg_01_old > ( player->GetItemCount "food_kwama_egg_01" ) )        set kwama_egg_01_old to ( player->GetItemCount "food_kwama_egg_01" )        set nec_hunger_effect to ( nec_hunger_effect + 3 )    elseif ( kwama_egg_01_old < ( player->GetItemCount "food_kwama_egg_01" ) )        set kwama_egg_01_old to ( player->GetItemCount "food_kwama_egg_01" )    endif    if ( kwama_egg_02_old > ( player->GetItemCount "food_kwama_egg_02" ) )        set kwama_egg_02_old to ( player->GetItemCount "food_kwama_egg_02" )        set nec_hunger_effect to ( nec_hunger_effect + 6 )    elseif ( kwama_egg_02_old < ( player->GetItemCount "food_kwama_egg_02" ) )        set kwama_egg_02_old to ( player->GetItemCount "food_kwama_egg_02" )    endif    if ( scrib_jerky_01_old > ( player->GetItemCount "ingred_scrib_jerky_01" ) )        set scrib_jerky_01_old to ( player->GetItemCount "ingred_scrib_jerky_01" )        set nec_hunger_effect to ( nec_hunger_effect + 4 )    elseif ( scrib_jerky_01_old < ( player->GetItemCount "ingred_scrib_jerky_01" ) )        set scrib_jerky_01_old to ( player->GetItemCount "ingred_scrib_jerky_01" )    endif    if ( rat_meat_01_old > ( player->GetItemCount "ingred_rat_meat_01" ) )        set rat_meat_01_old to ( player->GetItemCount "ingred_rat_meat_01" )        set nec_hunger_effect to ( nec_hunger_effect + 4 )    elseif ( rat_meat_01_old < ( player->GetItemCount "ingred_rat_meat_01" ) )        set rat_meat_01_old to ( player->GetItemCount "ingred_rat_meat_01" )    endif    if ( crab_meat_01_old > ( player->GetItemCount "ingred_crab_meat_01" ) )        set crab_meat_01_old to ( player->GetItemCount "ingred_crab_meat_01" )        set nec_hunger_effect to ( nec_hunger_effect + 6 )    elseif ( crab_meat_01_old < ( player->GetItemCount "ingred_crab_meat_01" ) )        set crab_meat_01_old to ( player->GetItemCount "ingred_crab_meat_01" )    endif    if ( hound_meat_01_old > ( player->GetItemCount "ingred_hound_meat_01" ) )        set hound_meat_01_old to ( player->GetItemCount "ingred_hound_meat_01" )        set nec_hunger_effect to ( nec_hunger_effect + 6 )    elseif ( hound_meat_01_old < ( player->GetItemCount "ingred_hound_meat_01" ) )        set hound_meat_01_old to ( player->GetItemCount "ingred_hound_meat_01" )    endif    if ( durzog_meat_01_old > ( player->GetItemCount "ingred_durzog_meat_01" ) )        set durzog_meat_01_old to ( player->GetItemCount "ingred_durzog_meat_01" )        set nec_hunger_effect to ( nec_hunger_effect + 6 )    elseif ( durzog_meat_01_old < ( player->GetItemCount "ingred_durzog_meat_01" ) )        set durzog_meat_01_old to ( player->GetItemCount "ingred_durzog_meat_01" )    endif    if ( scuttle_01_old > ( player->GetItemCount "ingred_scuttle_01" ) )        set scuttle_01_old to ( player->GetItemCount "ingred_scuttle_01" )        set nec_hunger_effect to ( nec_hunger_effect + 8 )    elseif ( scuttle_01_old < ( player->GetItemCount "ingred_scuttle_01" ) )        set scuttle_01_old to ( player->GetItemCount "ingred_scuttle_01" )    endif    if ( hackle-lo_leaf_01_old > ( player->GetItemCount "ingred_hackle-lo_leaf_01" ) )        set hackle-lo_leaf_01_old to ( player->GetItemCount "ingred_hackle-lo_leaf_01" )        set nec_hunger_effect to ( nec_hunger_effect + 4 )    elseif ( hackle-lo_leaf_01_old < ( player->GetItemCount "ingred_hackle-lo_leaf_01" ) )        set hackle-lo_leaf_01_old to ( player->GetItemCount "ingred_hackle-lo_leaf_01" )    endif    if ( saltrice_01_old > ( player->GetItemCount "ingred_saltrice_01" ) )        set saltrice_01_old to ( player->GetItemCount "ingred_saltrice_01" )        set nec_hunger_effect to ( nec_hunger_effect + 4 )    elseif ( saltrice_01_old < ( player->GetItemCount "ingred_saltrice_01" ) )        set saltrice_01_old to ( player->GetItemCount "ingred_saltrice_01" )    endif    if ( bc_hypha_facia_old > ( player->GetItemCount "ingred_bc_hypha_facia" ) )        set bc_hypha_facia_old to ( player->GetItemCount "ingred_bc_hypha_facia" )        set nec_hunger_effect to ( nec_hunger_effect + 3 )    elseif ( bc_hypha_facia_old < ( player->GetItemCount "ingred_bc_hypha_facia" ) )        set bc_hypha_facia_old to ( player->GetItemCount "ingred_bc_hypha_facia" )    endif    if ( marshmerrow_01_old > ( player->GetItemCount "ingred_marshmerrow_01" ) )        set marshmerrow_01_old to ( player->GetItemCount "ingred_marshmerrow_01" )        set nec_hunger_effect to ( nec_hunger_effect + 4 )    elseif ( marshmerrow_01_old < ( player->GetItemCount "ingred_marshmerrow_01" ) )        set marshmerrow_01_old to ( player->GetItemCount "ingred_marshmerrow_01" )    endif    if ( comberry_01_old > ( player->GetItemCount "ingred_comberry_01" ) )        set comberry_01_old to ( player->GetItemCount "ingred_comberry_01" )        set nec_hunger_effect to ( nec_hunger_effect + 3 )    elseif ( comberry_01_old < ( player->GetItemCount "ingred_comberry_01" ) )        set comberry_01_old to ( player->GetItemCount "ingred_comberry_01" )    endif    if ( scrib_cabbage_01_old > ( player->GetItemCount "ingred_scrib_cabbage_01" ) )        set scrib_cabbage_01_old to ( player->GetItemCount "ingred_scrib_cabbage_01" )        set nec_hunger_effect to ( nec_hunger_effect + 4 )    elseif ( scrib_cabbage_01_old < ( player->GetItemCount "ingred_scrib_cabbage_01" ) )        set scrib_cabbage_01_old to ( player->GetItemCount "ingred_scrib_cabbage_01" )    endif    if ( holly_01_old > ( player->GetItemCount "ingred_holly_01" ) )        set holly_01_old to ( player->GetItemCount "ingred_holly_01" )        set nec_hunger_effect to ( nec_hunger_effect + 3 )    elseif ( holly_01_old < ( player->GetItemCount "ingred_holly_01" ) )        set holly_01_old to ( player->GetItemCount "ingred_holly_01" )    endifEnd


If nec_hunger_effect global value is grater than 0 than the "nec_effect_eat" spell is added (with remove curse effect):

begin nec_hunger_effecteat		;float nec_hunger	;GLOBAL		;float nec_hunger_f	;GLOBAL		;short nec_hunger_effect	;GLOBAL	float timer	short flag	if ( menumode == 1 )		return	endif	set timer to ( timer + getsecondspassed )	if ( timer < 1 )		return	endif	set timer to 0		;Toccatta's manual eating (potions)	if ( player -> geteffect, sEffectRemoveCurse == 1 )		if ( nec_hunger > 0 )			set nec_hunger_f to ( nec_hunger_f + 1 )		endif	endif		;Additional chceck for vanilla ingredients	if ( nec_hunger_effect > 0 )		Player->AddSpell, "nec_effect_eat"		set flag to 1	endif	if ( flag == 1 )		set nec_hunger_effect to ( nec_hunger_effect - 1 )		set flag to 0		if ( nec_hunger_effect == 0 )			Player->RemoveSpell, "nec_effect_eat"		endif	endifend


This workaround is partially functional:
- you can manually eat ingredients and the effect (in this case altering the global value) is correctly added,
- if you drop a food from inventory the effect will not be added (thanks to additional check:
if ( Player->GetSoundPlaying, "Item Ingredient Down" == 1 )
- if you try to sell ingredients or place it in container the effect will be added

I’m looking for a way to fix the last issue. I’ve already tried other sound ID (Swallow, Item Ingredient Up, Item Gold Up/Down) but none of them seems to be working like a "Item Ingredient Down" (that is played when you try to drop ingredient). Ingredients in Morrowind can only have up to 4 effects and almost all the time they are already reserved (and most ingredient have different effects) so I can't just add additional "GetEffect" chceck :/

If someone have an idea how to tweak this script in order to fix the above mentioned problem or have a better idea how to achieve this effect I will be very thankful. Maybe there is a MWSE function that could be helpful?
User avatar
Ownie Zuliana
 
Posts: 3375
Joined: Thu Jun 15, 2006 4:31 am

Return to III - Morrowind