Jump to content

Dice Gambling Script Help


gerg357

Recommended Posts

Scriptname PlayDice extends ObjectReference
Message Property playgame Auto
Message Property singlediceproll Auto
Message Property singlediceoroll Auto
Message Property singledicetie Auto
Message Property singledicelose Auto
Message Property singledicewin Auto
Message Property singledicenoplay200 Auto
Message Property singledicenoplay400 Auto
Message Property singledicenoplay600 Auto
Message Property gambleammount Auto
MiscObject Property Gold001 Auto
Actor Property gambler Auto

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 (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

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 below

2. 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 below

3. 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 below

4. 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 below

5. 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

  • 3 weeks later...

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
EndEvent
You 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 by BigAndFlabby
Link to comment
Share on other sites

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

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 PlayerRef

wasn'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 correctly

Or 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 by NexusComa
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...