Infinite Arrow Script

Post » Sat Feb 19, 2011 7:07 am

--> Snapshot: The IsWeaponOut function in my script is not working!!! Instead, IsWeaponOut always returns false. I'm using OBSE (18.6), the code is below. WHY WON'T IT WORK?!?
Also, my script suddenly, and for no apparent reason, stopped running.<--


So I decided to make a special magical bow that automatically refills whatever arrow it shoots. I'm using OBSE's GetEquippedObject function to get the current arrow equipped. In an effort to make sure that only fired arrows are counted, I want to use MenuMode to detect when various menus are open, and IsWeaponOut (in conjunction with an equip check) to detect if the player has that bow drawn or not. So far I've only succeed in being able to tell if that bow is equipped. I was able to get MenuMode working, but shortly after that, the script stopped running for no reason.
I was testing my MenuMode fix with message boxes, and at first I was able to get a single "In Main Menus" message to appear at the correct times. Then, with the game still running and nothing changed, the messages stopped appearing. On firing an arrow, it was not replaced, nothing happened. On a reboot of Oblivion, the script still won't run. Is there any way to test if a script is running and/or any reason it would self-terminate and not start back up?

Edit: Further testing showed that the GameMode block was running, but none of the Menu blocks were... And still no arrows, either...

On a final note, IsWeaponOut won't work at all, never has, and I have no idea why... If it were at all possible, I'd like to replace both MenuMode and IsWeaponOut checks with a Is/Was-This-Weapon-Just-Fired function, but I don't think any such function exists...

Here is the code (it is attached to the bow):
scn umBowInfiniteAmmoref NULLref CurAmmoshort Equippedshort AmmoCountshort AddAmmoshort DoOnce ; To test that MenuMode is working...begin OnEquip ;if the bow was just equipped, initalize CurAmmo and AmmoCount	set Equipped to 1	set CurAmmo to Player.GetEquippedObject 17	set AmmoCount to Player.GetItemCount CurAmmoendbegin MenuMode 1 ;Main Menus  -  update CurAmmo and AmmoCount to reflect any changes made	set CurAmmo to Player.GetEquippedObject 17	set AmmoCount to Player.GetItemCount CurAmmo	if DoOnce == 0 ;Display a single confirmation message.		MessageBox "In Main Menus"		set DoOnce to 1	endifendbegin MenuMode 1008 ;Container/Barter Menu  -  update CurAmmo and AmmoCount to reflect any changes made	set CurAmmo to Player.GetEquippedObject 17	set AmmoCount to Player.GetItemCount CurAmmoendbegin MenuMode 1009 ;Dialouge Menu  -  update CurAmmo and AmmoCount to reflect any changes made, like a in quest.	set CurAmmo to Player.GetEquippedObject 17	set AmmoCount to Player.GetItemCount CurAmmoendbegin MenuMode 1042 ;Enchanting Menu  -  update CurAmmo and AmmoCount to reflect any changes made	set CurAmmo to Player.GetEquippedObject 17	set AmmoCount to Player.GetItemCount CurAmmoendbegin GameMode	set DoOnce to 0 ;Reset DoOnce	if Equipped == 0 ;bow not equipped		return ;exit, we're not fireing arrows right now	endif	if Player.GetEquippedObject 17 == NULL && AmmoCount == 1 ;check arrow fired was the last one and resupply and equip.		Player.AddItem CurAmmo 1		Player.EquipItem CurAmmo	elseif CurAmmo != Player.GetEquippedObject 17 ;otherwise, if arrow type changes/becomes null, reset CurAmmo and AmmoCount		set CurAmmo to Player.GetEquippedObject 17		set AmmoCount to Player.GetItemCount CurAmmo	endif	if AmmoCount > Player.GetItemCount CurAmmo ;if arrow fired, resupply		set AddAmmo to AmmoCount - Player.GetItemCount CurAmmo ;Technically we should only ever be one arrow short, but who knows?  If not, this will save time.		Player.AddItem CurAmmo AddAmmo		Player.EquipItem CurAmmo	elseif AmmoCount < Player.GetItemCount CurAmmo ;if more arros were added, increase AmmoCount 		set AmmoCount to Player.GetItemCount CurAmmo	endifendbegin OnUnEquip ;if bow is unequipped, reset CurAmmo	set Equipped to 0	set CurAmmo to NULLend



What's going on here? Why won't this work?
User avatar
Ellie English
 
Posts: 3457
Joined: Tue Jul 11, 2006 4:47 pm

Post » Sat Feb 19, 2011 12:35 am

Have a look at OBSE event handlers. "OnBowAttack" and "OnRelease" may be what you need.
User avatar
Nikki Hype
 
Posts: 3429
Joined: Mon Jan 01, 2007 12:38 pm

Post » Sat Feb 19, 2011 10:57 am

Have a look at OBSE event handlers. "OnBowAttack" and "OnRelease" may be what you need.


Hmmm, two OBSE block events that are exactly what I was looking for...but they're only just released under the still unstable Beta OBSE v0020... And yet they are so EXACTLY what I need! I decided to use them, and reduced my 50+ lines of code to a dozen...but now it won't compile!!! WHAT AM I DOING WRONG?!?

scn umBowInfiniteAmmoref CurAmmobegin OnBowAttack Player	set CurAmmo to Player.GetEquippedObject 17endbegin OnRelease Player	Player.AddItem CurAmmo 1	Player.EquipItem CurAmmoend

User avatar
Kelli Wolfe
 
Posts: 3440
Joined: Thu Aug 23, 2007 7:09 am

Post » Sat Feb 19, 2011 12:12 am

I'm Back! And still working on that same script... What I want, in total, is a bow that heals and recharges itself and replaces any arrow it uses. Here's the code I have so far, which refuses to compile (it doesn't like the event handler OnBowAttack). What am I doing wrong? I just installed OBSE v20 and it seems to be working just fine, so I don't think that's the problem...

scn umBowScriptref CurAmmoshort CurAmmoCountfloat Timershort doOnceshort doOnce2begin OnEquip	if doOnce == 0		set Timer to 100		set doOnce  to 1	endif	if Timer > 0		set Timer to Timer - GetSecondsPassed	else		set Timer to 100		MessageBox "Recharging"		player.ModEquippedCurrentCharge 1 16		player.ModEquippedCurrentHealth 1 16	endifendbegin OnUnequip	if doOnce == 1		set doOnce  to 0	endifendbegin OnBowAttack	if doOnce2 == 0		set CurAmmo to player.GetEquippedObject 17		set CurAmmoCount to player.GetItemCount CurAmmo		set doOnce2  to 1	endifendbegin OnRelease	if doOnce2 == 1		set CurAmmoCount to (CurAmmoCount - player.GetItemCount CurAmmo)		player.additem CurAmmo CurAmmoCount 		set doOnce2  to 0	endifend


Does this code work for any of you? I'd like the bow to heal and recharge even when it's not being held, but could only find a command that would heal current health for equipped items... Is there any way to do this?
User avatar
Elisha KIng
 
Posts: 3285
Joined: Sat Aug 18, 2007 12:18 am

Post » Sat Feb 19, 2011 5:17 am

I believe CurAmmo needs to be a short instead of a ref. I could be wrong, though. Usually the CS gives an error message when a script doesn't compile. If that is the case here, what error message does it give?
User avatar
Trent Theriot
 
Posts: 3395
Joined: Sat Oct 13, 2007 3:37 am

Post » Sat Feb 19, 2011 4:53 am

I believe CurAmmo needs to be a short instead of a ref. I could be wrong, though. Usually the CS gives an error message when a script doesn't compile. If that is the case here, what error message does it give?


No, if you look at the OBSE v20 documentation, GetEquippedObject returns an base objectID reference.

The error message is an "invalid block type in 'begin' command." on line 32 (OnBowAttack). Just for fun I replaced OnBowAttack with GameMode, and the complier accepted that and all the code within that block. Now, however, it took issue with OnRelease. Replacing that with OnDrop allowed the code to be compiled without further errors, but since neither of those are the events I need to trigger off of, this doesn't do me much good. Why isn't the compiler recognizing these block events? I tried reinstalling OBSE v20, but the problem persists... Will my code compile on your machinve?
User avatar
Guy Pearce
 
Posts: 3499
Joined: Sun May 20, 2007 3:08 pm

Post » Sat Feb 19, 2011 2:37 am

No, if you look at the OBSE v20 documentation, GetEquippedObject returns an base objectID reference.

Yep, you're right. Silly me. :P

Will my code compile on your machine?


I don't use OBSE, so I'm not sure if that would compile or not. I do have a script that will provide an unlimited amount of a specific arrow:

Scriptname WrathOfArkayBowScriptShort CurrentCountShort BaseCountShort AddCountShort myStatBegin OnEquip        set myStat to 1EndBegin OnUnEquip        set myStat to 0EndBegin GameMode        if myStat == 1                Set CurrentCount to Player.GetItemCount WrathArkayArrow                Set BaseCount to 10                If CurrentCount < BaseCount                        Set AddCount to BaseCount - CurrentCount                        Message "  "                        Message "  "                        Player.Additem WrathArkayArrow AddCount                endif        endifEnd


That will ensure I never run out of that specific arrow, bur won't replenish any others. Note that all the variables are shorts, hence my erroneous advice. You may be able to modify this script to achieve your desired result, though.
User avatar
Kieren Thomson
 
Posts: 3454
Joined: Sat Jul 21, 2007 3:28 am

Post » Sat Feb 19, 2011 10:28 am

The error message is an "invalid block type in 'begin' command." on line 32 (OnBowAttack).

Read the "Event Handlers" section of the obse docs. OnBowAttack, OnRelease, and friends don't define new block types - they define events for which you can register a function script as an event handler using SetEventHandler. Silly example:
; your event handler scriptscn MyBowAttackHandlerref attackerbegin Function { attacker }  print $attacker + " just attacked with his bow."end


; a quest script that registers the event handlerscn MyQuestScriptbegin gamemode  if getGameRestarted    SetEventHandler "OnBowAttack" MyBowAttackHandler  endifend

SetEventHandler tells OBSE that whenever an actor fires his bow, your function script should be run. More detailed info in the docs.
User avatar
Sophh
 
Posts: 3381
Joined: Tue Aug 08, 2006 11:58 pm


Return to IV - Oblivion