gerg357 Posted September 9, 2016 Share Posted September 9, 2016 Scriptname PlayDice extends ObjectReferenceMessage Property playgame AutoMessage Property singlediceproll AutoMessage Property singlediceoroll AutoMessage Property singledicetie AutoMessage Property singledicelose AutoMessage Property singledicewin AutoMessage Property singledicenoplay200 AutoMessage Property singledicenoplay400 AutoMessage Property singledicenoplay600 AutoMessage Property gambleammount AutoMiscObject Property Gold001 AutoActor Property gambler AutoEvent OnActivate(ObjectReference akActionRef)if akActionRef != Game.GetPlayer() ; do not let other NPCs trigger this return endif Int iPlayOption = playgame.Show()If (iPlayOption == 0) Int imoneyOption = gambleammount.Show() If (imoneyOption == 0) If (Game.GetPlayer().GetItemCount(Gold001) >= 200 && gambler.GetItemCount(Gold001) >= 200) Game.GetPlayer().removeItem(Gold001, 200) gambler.removeItem(Gold001, 200) int diceplayer = Utility.RandomInt(0, 6) ; Generates a random number between 0 and 2 int diceopponent = Utility.RandomInt(0, 6) ; Generates a random number between 0 and 2 If (diceplayer == diceopponent) singledicetie.Show(diceplayer) Game.GetPlayer().AddItem(Gold001, 200) gambler.AddItem(Gold001, 200) ElseIf (diceplayer > diceopponent) singlediceproll.Show(diceplayer) singlediceoroll.Show(diceopponent) singledicewin.Show() Game.GetPlayer().AddItem(Gold001, 400) ElseIf (diceplayer < diceopponent) singlediceproll.Show(diceplayer) singlediceoroll.Show(diceopponent) singledicelose.Show() gambler.addItem(Gold001, 400) EndIf ElseIf (Game.GetPlayer().GetItemCount(Gold001) < 200 && gambler.GetItemCount(Gold001) < 200) singledicenoplay200.Show() EndIf EndIf If (imoneyOption == 1) If (Game.GetPlayer().GetItemCount(Gold001) >= 400 && gambler.GetItemCount(Gold001) >= 400) Game.GetPlayer().removeItem(Gold001, 200) gambler.removeItem(Gold001, 200) int diceplayer = Utility.RandomInt(0, 6) ; Generates a random number between 0 and 2 int diceopponent = Utility.RandomInt(0, 6) ; Generates a random number between 0 and 2 If (diceplayer == diceopponent) singledicetie.Show(diceplayer) Game.GetPlayer().AddItem(Gold001, 400) gambler.AddItem(Gold001, 400) ElseIf (diceplayer > diceopponent) singlediceproll.Show(diceplayer) singlediceoroll.Show(diceopponent) singledicewin.Show() Game.GetPlayer().AddItem(Gold001, 800) ElseIf (diceplayer < diceopponent) singlediceproll.Show(diceplayer) singlediceoroll.Show(diceopponent) singledicelose.Show() gambler.addItem(Gold001, 800) EndIf ElseIf (Game.GetPlayer().GetItemCount(Gold001) < 400 && gambler.GetItemCount(Gold001) < 400) singledicenoplay400.Show() EndIf EndIf If (imoneyOption == 2) If (Game.GetPlayer().GetItemCount(Gold001) >= 600 && gambler.GetItemCount(Gold001) >= 600) Game.GetPlayer().removeItem(Gold001, 600) gambler.removeItem(Gold001, 600) int diceplayer = Utility.RandomInt(0, 6) ; Generates a random number between 0 and 2 int diceopponent = Utility.RandomInt(0, 6) ; Generates a random number between 0 and 2 If (diceplayer == diceopponent) singledicetie.Show(diceplayer) Game.GetPlayer().AddItem(Gold001, 600) gambler.AddItem(Gold001, 600) ElseIf (diceplayer > diceopponent) singlediceproll.Show(diceplayer) singlediceoroll.Show(diceopponent) singledicewin.Show() Game.GetPlayer().AddItem(Gold001, 1200) ElseIf (diceplayer < diceopponent) singlediceproll.Show(diceplayer) singlediceoroll.Show(diceopponent) singledicelose.Show() gambler.addItem(Gold001, 1200) EndIf ElseIf (Game.GetPlayer().GetItemCount(Gold001) < 600 && gambler.GetItemCount(Gold001) < 600) singledicenoplay600.Show() EndIf EndIf If (iPlayOption == 1)EndIf EndIf EndEvent this is my code everything seems to run fine so i put all my gold in a container and the npc is broke as well yet the singledicenoplay200 400 or 600 will not show... i know its something simple im missing using multiple menus is confusing as hell lol Link to comment Share on other sites More sharing options...
IsharaMeradin Posted September 9, 2016 Share Posted September 9, 2016 Obvious things first...Did you fill the properties? Link to comment Share on other sites More sharing options...
gerg357 Posted September 9, 2016 Author Share Posted September 9, 2016 Yep I went to autofill and all match and are set in ck Link to comment Share on other sites More sharing options...
IsharaMeradin Posted September 9, 2016 Share Posted September 9, 2016 Few things you can try.1. For thread safety swap out using Game.GetPlayer() and use akActionRef after first ensuring that akActionRef does indeed equal Game.GetPlayer() See code below2. Use ElseIf between each of your message options for that given level. After all only one option can be selected at a time. See code below3. Use Else for the failure when one of the player or gambler don't have enough money. Unless you have multiple things to do under different conditions there is no need for ElseIf. See code below4. Double check your EndIf positions. Your check for iPlayOption == 1 is at level with your imoneyOption checks. Adjusted to be in line with the other iPlayOption check in the code below5. Under the imoneyOption == 1 check you're checking for 400 on the player and gambler but only taking 200. Probably left over from a copy paste of code. #3 might allow your message to show. Event OnActivate(ObjectReference akActionRef) if akActionRef != Game.GetPlayer() ; do not let other NPCs trigger this return endif Int iPlayOption = playgame.Show() If (iPlayOption == 0) Int imoneyOption = gambleammount.Show() If (imoneyOption == 0) If (akActionRef.GetItemCount(Gold001) >= 200 && gambler.GetItemCount(Gold001) >= 200) ;<snip> Else singledicenoplay200.Show() EndIf ElseIf (imoneyOption == 1) If (akActionRef.GetItemCount(Gold001) >= 400 && gambler.GetItemCount(Gold001) >= 400) ;<snip Else singledicenoplay400.Show() EndIf ElseIf (imoneyOption == 2) If (akActionRef.GetItemCount(Gold001) >= 600 && gambler.GetItemCount(Gold001) >= 600) ;<snip> Else singledicenoplay600.Show() EndIf EndIf ElseIf (iPlayOption == 1) EndIf EndEvent Link to comment Share on other sites More sharing options...
gerg357 Posted September 27, 2016 Author Share Posted September 27, 2016 Was property issue in ck... somehow didn't replace with new one... all is working fine Link to comment Share on other sites More sharing options...
JonathanOstrus Posted September 29, 2016 Share Posted September 29, 2016 (edited) Just some common "good practice" advice. Mostly for performance concerns and readability. You might consider changing all of your Game.GetPlayer() calls to a variable or property. I can't see why your player ref would ever change during the script run. And repeatedly calling other functions seems like a waste of cpu cycles. I personally use the property scenario. So adding something like this: Actor Property PlayerREF Auto {Player reference} Then you can replace all your calls with something like Event OnActivate(ObjectReference akActionRef) if akActionRef != PlayerREF ; do not let other NPCs trigger this return endif if (PlayerREF.GetItemCount(Gold001) >= 200 && gambler.GetItemCount(Gold001) >= 200) ;snip endif EndEventYou could also refactor your code to use a function call with a "betting" amount variable. Then use that variable to calculate winnings and such. This has a benefit so that you don't have the same code 3 times, so if you do an update you don't have to do it 3 times. Also prevents the typo that IsharaMeradin mentions for #5 in the 400 section. Like this Change this bit If (imoneyOption == 0) If (Game.GetPlayer().GetItemCount(Gold001) >= 200 && gambler.GetItemCount(Gold001) >= 200) ;snip ElseIf (Game.GetPlayer().GetItemCount(Gold001) < 200 && gambler.GetItemCount(Gold001) < 200) singledicenoplay200.Show() EndIf EndIf ;If (imoneyOption == 0) If (imoneyOption == 1) If (Game.GetPlayer().GetItemCount(Gold001) >= 400 && gambler.GetItemCount(Gold001) >= 400) ;snip ElseIf (Game.GetPlayer().GetItemCount(Gold001) < 400 && gambler.GetItemCount(Gold001) < 400) singledicenoplay400.Show() EndIf EndIf ;If (imoneyOption == 1) If (imoneyOption == 2) If (Game.GetPlayer().GetItemCount(Gold001) >= 600 && gambler.GetItemCount(Gold001) >= 600) ;snip ElseIf (Game.GetPlayer().GetItemCount(Gold001) < 600 && gambler.GetItemCount(Gold001) < 600) singledicenoplay600.Show() EndIf EndIf ;If (imoneyOption == 2) To something like:Event OnActivate(ObjectReference akActionRef) ;snip snip snip ;snip snip snip if (imoneyOption == 0) GambleIt(200, singledicenoplay200) elseif (imoneyOption == 1) GambleIt(400, singledicenoplay400) elseif (imoneyOption == 2) GambleIt(600, singledicenoplay600) endif ;snip snip snip ;snip snip snip EndEvent Function GambleIt(int iGoldBet, Message mNotEnoughMoney) Actor winner Actor loser If (PlayerREF.GetItemCount(Gold001) >= iGoldBet && gambler.GetItemCount(Gold001) >= iGoldBet) ;No need to remove gold up front int diceplayer = Utility.RandomInt(0, 6) int diceopponent = Utility.RandomInt(0, 6) if (diceplayer == diceopponent) singledicetie.Show(diceplayer) ; refund bets - we did not remove gold up front there is nothing to do return ElseIf (diceplayer > diceopponent) winner = PlayerREF loser = gambler Else winner = gambler loser = PlayerREF EndIf ; since we did not remove gold up front we just add the bet and remove the bet equally winner.addItem(Gold001, iGoldBet) loser.removeItem(Gold001, iGoldBet) singlediceproll.Show(diceplayer) singlediceoroll.Show(diceopponent) if (winner == PlayerREF) singledicewin.Show() else singledicelose.Show() endif else mNotEnoughMoney.Show() EndIf EndFunction This has many benefits. Less chance for typos in copy + paste + fix. One place to modify logic code instead of 3 (or more if you add additional betting amounts) Depending on your messages for not enough money, you could probably reduce it to one that says something like "Sorry one of you doesn't have at least %.0f gold" and then do a message.show(needed_gold) and reduce it to one message. My philosophy. Less is more :smile: More code means more chance for things to be/go wrong. Edited September 29, 2016 by BigAndFlabby Link to comment Share on other sites More sharing options...
NexusComa Posted September 29, 2016 Share Posted September 29, 2016 (edited) This is good advice ... I can't repeat the error I was getting.( removed the comment ) Edited September 29, 2016 by NexusComa Link to comment Share on other sites More sharing options...
JonathanOstrus Posted September 29, 2016 Share Posted September 29, 2016 Something like this: Debug.Notification("Starting gold: " + PlayerREF.GetItemCount(Gold001)) PlayerREF.AddItem(Gold001, 1000) Debug.Notification("We now have: " + PlayerREF.GetItemCount(Gold001)) Should display the first line stating how much you have. Then the second line should be updated for the new amount with the 1000 added. If I understood what you were saying, you said that it doesn't return the updated amount? If you're using PlayerREF as a property you should make sure it's being set as FormID 0x00000014. If you wanted to you could also use Actor PlayerREF = Game.GetPlayer()If you're calling GetItemCount() in the check and not storing it in a variable somewhere, it should always be checking for updated values. Link to comment Share on other sites More sharing options...
NexusComa Posted September 29, 2016 Share Posted September 29, 2016 (edited) I agree with the whole PlayerRef thing. But, I have ran into a problem with it with longer scripts.After debugging a script pass what I could see to be an error, it turned out to be a PlayerRefwasn't getting a current update and I had to use game.getplayer() Honestly not even sure what I was working on at the time.Now that I think about it, it may even have been a dice game.I just really check the PlayerRef now to make sure it working correctlyOr I use the game.getplayer() if it's not being called that many times. I check all the properties 1st when I see in game errors on compiled code. Edited September 29, 2016 by NexusComa Link to comment Share on other sites More sharing options...
Recommended Posts