 Rem File: Cmd998.bas
 Rem Sub: Main.Loop.Update
 Rem $Include: 'dndbbs.inc'
 On Error Goto Main.Error
 If Chained=0 Then
    Color 15,0
    Print "DNDBBS Command 998 -- Main.Loop.Update. (Sub 2)."
    Color 7,0
    End
 Endif

 Rem check new mail/check bank interest/check inventory persistence.
 Rem removed all repair subroutines 10/10/2024.

 ' get config settings
 Gosub Get.Config

 ' reset round counter
 '  modulo of counter is a power of 2
 New.Mail.Count = New.Mail.Count + 1
 If New.Mail.Count > 64 Then
    New.Mail.Count = 1
 Endif

 ' check called from dndbbs
 If Chained=-2 Then
    optionx=0:optiony=0
    New.Mail.Time! = 0!
    If TempX=1 Then
       optionx=-1
       optionz1=-1
       Strng="Checking bank.."
       Call IO.O
    Endif
    If TempX=2 Then
       optiony=-1
       optionz2=-1
       Strng="Checking mail.."
       Call IO.O
    Endif
 Endif

 ' check read bank interest
 If optionx Then ' display bank interest
    If optionz1 Then ' only display bank interest once
       If (New.Mail.Time! And 1!) = 0! Then
          Call Bank.Interest
          New.Mail.Time! = New.Mail.Time! Or 1!
       Endif
    Else
       If (New.Mail.Count Mod option0)=0 Then
          Call Bank.Interest
       Endif
    Endif
 Endif

 ' check read new mail
 If optiony Then ' display new mail
    If optionz2 Then ' only display new mail once
       If (New.Mail.Time! And 2!) = 0! Then
          Call Check.New.Mail(Chained)
          New.Mail.Time! = New.Mail.Time! Or 2!
       Endif
    Else
       If (New.Mail.Count Mod option1)=0 Then
          Call Check.New.Mail(Chained)
       Endif
    Endif
 Endif

 ' check called from dndbbs
 If Chained=-2 Then
    New.Mail.Time! = 3!
    Chain DND.Path+"DNDBBS.EXE"
 Endif

 ' fill containers
 If (New.Mail.Count Mod option2)=0 Then
    Call Fill.Container.With.Item
 Endif

 ' userinv persist
 If (New.Mail.Count Mod option3)=0 Then
    Call Init.Persist1
    Call Refresh.Persist1
 Endif

 ' moninv persist
 If (New.Mail.Count Mod option4)=0 Then
    Call Init.Persist2
    Call Refresh.Persist2
 Endif

 ' teaminv persist
 If (New.Mail.Count Mod option5)=0 Then
    Call Init.Persist3
    Call Refresh.Persist3
 Endif

Main.Resume:
 Gosub Get.Config2
 If Chained=-3 Then
    Chain Option1$+"CMD999.EXE"
 Else
    Chain DND.Path+"DNDBBS.EXE"
 Endif
 End

Get.Config2:
 VarX$="CMD999"
 Option1$=DND.Path
 VarX=0
 Do
    VarX=VarX+1
    If VarX>Options.Lines Then
       Exit Do
    Endif
    Var$=Ltrim$(Rtrim$(Options.Array(VarX)))
    If Ucase$(Var$)="[RAMDRIVE]" Then
       Do
          VarX=VarX+1
          If VarX>Options.Lines Then
             Return
          Endif
          Var$=Ltrim$(Rtrim$(Options.Array(VarX)))
          If Ucase$(Var$)="[END]" Then
             Return
          Endif
          VarZ=Instr(Var$,"=")
          If VarZ Then
             Var2$=Ltrim$(Rtrim$(Left$(Var$,VarZ-1)))
             Var3$=Ltrim$(Rtrim$(Mid$(Var$,VarZ+1)))
             If Ucase$(Var2$)=VarX$ Or Ucase$(Var2$)="CMD*" Then
                ' force cmd module to ramdrive
                If Var3$="-1" Then
                   Option1$=Data.Path3
                Else
                   Var3$=Ucase$(Var3$)
                   If Len(Var3$) Then
                      If Left$(Var3$,1)>="A" And Left$(Var3$,1)<="Z" Then
                         Select Case Len(Var3$)
                         Case 1
                            Option1$=Var3$+":\"
                         Case 2
                            If Right$(Var3$,1)=":" Then
                               Option1$=Var3$+"\"
                            Endif
                         Case 3
                            If Right$(Var3$,2)=":\" Then
                               Option1$=Var3$
                            Endif
                         End Select
                      Endif
                   Endif
                Endif
             Endif
          Endif
       Loop
    Endif
 Loop
 Return

Get.Config:
 option0=16
 option1=32
 option2=2
 option3=1
 option4=1
 option5=1

 optionx=-1
 optiony=-1
 optionz1=-1
 optionz2=-1

 VarX=0
 Do
    VarX=VarX+1
    If VarX>Options.Lines Then
       Exit Do
    Endif
    Var$=Ltrim$(Rtrim$(Options.Array(VarX)))
    If Ucase$(Var$)="[CMD999]" Then
       Do
          VarX=VarX+1
          If VarX>Options.Lines Then
             Return
          Endif
          Var$=Ltrim$(Rtrim$(Options.Array(VarX)))
          If Ucase$(Var$)="[END]" Then
             Return
          Endif
          Var=Instr(Var$,"=")
          If Var Then
             Var2$=Ltrim$(Rtrim$(Left$(Var$,Var-1)))
             Var3$=Ltrim$(Rtrim$(Mid$(Var$,Var+1)))
             VarQ=Int(Val(Var3$)+.5)
             Select Case Lcase$(Var2$)
             Case "display.bank.interest"
                Select Case Lcase$(Var3$)
                Case "0","off","false"
                   optionx=0
                End Select
             Case "display.bank.once"
                Select Case Lcase$(Var3$)
                Case "0","off","false"
                   optionz1=0
                End Select
             Case "display.new.mail"
                Select Case Lcase$(Var3$)
                Case "0","off","false"
                   optiony=0
                End Select
             Case "display.mail.once"
                Select Case Lcase$(Var3$)
                Case "0","off","false"
                   optionz2=0
                End Select
             End Select
             Select Case VarQ
             Case 1,2,4,8,16,32,64
                Select Case Lcase$(Var2$)
                Case "bank.count"
                   option0=VarQ
                Case "mail.count"
                   option1=VarQ
                Case "fill.count"
                   option2=VarQ
                Case "persist.count1"
                   option3=VarQ
                Case "persist.count2"
                   option4=VarQ
                Case "persist.count3"
                   option5=VarQ
                End Select
             End Select
          Endif
       Loop
    Endif
 Loop
 Return

Main.Error:
 Resume Main.Resume

Sub Check.New.Mail(VarZ1)
 On Local Error Goto ErrTrap2z
 Message.Base.Name=Config3(58)
 Message.Base="public"
 Gosub Check.Mail2
 Message.Base.Name=Config3(60)
 Message.Base="private"
 Gosub Check.Mail2
 If Lof(MessBaseFile)/MessBaseRecLen>SFalse Then
    Var=False
    For Temp3!=1! To Lof(MessBaseFile)/MessBaseRecLen
       Call Read.Record(MessBaseFile,Temp3!)
       If MessageBaseRecord.BaseDeleted=False Then
          Var=True
          Exit For
       Endif
    Next
    If Var Then
       For Temp3!=1! To Lof(MessBaseFile)/MessBaseRecLen
          Call Read.Record(MessBaseFile,Temp3!)
          If MessageBaseRecord.BaseDeleted=False Then
             Message.Base.Name=MessageBaseRecord.BaseFileName
             Message.Base=Rtrim$(MessageBaseRecord.BaseMessName)
             Gosub Check.Mail2
          Endif
       Next
    Endif
 Endif
 If VarZ Then
    Call More.Prompt
 Else
    If VarZ1=-2 Then
       Graphics.Off=False
       Strng="No new mail."
       Call IO.O
    Endif
 Endif
 If VarZ1=-2 Then
    Graphics.Off=True
    Strng="End mail scan.."
    Call IO.O
 Endif
 Exit Sub

Check.Mail2:
 Close #TableFile
 Message.Base.Name=Rtrim$(Message.Base.Name)
 FileName=Data.Path4+Message.Base.Name+".TBL"
 Open FileName For Random Shared As #TableFile Len=TableRecLen

 Close #NewFile
 FileName=Data.Path4+Message.Base.Name+".NEW" ' public message to user
 Open FileName For Random Shared As #NewFile Len=NewMessRecLen
 VarX=1
 Gosub Check.New.Mail2
 VarA!=Temp5!

 Close #NewFile
 FileName=Data.Path4+Message.Base.Name+".NW3" ' private message to user
 Open FileName For Random Shared As #NewFile Len=NewMessRecLen
 VarX=3
 Gosub Check.New.Mail2
 VarB!=Temp5!

 If VarA! Or VarB! Then
    Gosub New.Mail.Message
    Graphics.Off=True
    Strng=Lcase$(Message.Base)
    Mid$(Strng,1,1)=Ucase$(Mid$(Strng,1,1))
    Strng=Chr$(34)+Strng+Chr$(34)+" Message Base>"
    Strng=Strng+Str$(VarA!)+" public,"+Str$(VarB!)+" private."
    Call IO.O
    Graphics.Off=False
    VarZ=VarZ+1
    If VarZ>=User.Pagelength-2 Then
       VarZ=False
       Call More.Prompt
       If No Or Quit Then
          Exit Sub
       Endif
    Endif
 Endif
 Return

Check.New.Mail2:
 Temp5!=SFalse
 Temp7!=SFalse
 Strng=UserRecord.CodeName
 Strng=Rtrim$(Strng)
 Strng=Lcase$(Strng)

 ' extend new message pointers
 Var!=Lof(NewFile)/NewMessRecLen
 If User.Index>Var! Then
    For Var1!=Var!+1! To User.Index
       NewMessages.LastMessage=SFalse
       Call Write.Record(NewFile,Var1!)
    Next
 Endif

 Call Read.Record(NewFile,User.Index)
 Temp1!=NewMessages.LastMessage
 Temp2!=Lof(TableFile)/TableRecLen
 If Temp1!>=SFalse And Temp1!<Temp2! Then
    For Temp4!=Temp1!+1! To Temp2!
       Call Read.Record(TableFile,Temp4!)
       If TableRecord.Killed=False Then
          Strng2=TableRecord.To
          Strng2=Rtrim$(Strng2)
          Strng2=Lcase$(Strng2)
          If Strng=Strng2 Then
             Temp7!=Temp7!+1! ' total messages
             If VarX=1 Then ' public message to user
                If TableRecord.Private=False Then
                   Temp5!=Temp5!+1!
                Endif
             Else ' private message to user
                If TableRecord.Private Then
                   Temp5!=Temp5!+1!
                Endif
             Endif
          Endif
       Endif
    Next
 Endif
 Return

New.Mail.Message:
 If VarC=0 Then
    VarZ=VarZ+2
    VarC=-1
    Call Put.Modem(Chr$(7))
    Strng="Mail alert!"
    Call IO.O
    Strng="You have unread mail in areas:"
    Call IO.O
 Endif
 Return
ErrResume2z:
 Strng="Error"+Str$(Err)
 Call IO.O
 Exit Sub
ErrTrap2z:
 Resume ErrResume2z
End Sub

' init new persistent treasure in user inventory
Sub Init.Persist1
 On Local Error Goto ErrTrap2z2
 For Temp5!=1! To Lof(MessWorkFile6)/MessWorkRecLen6
    Call Read.Record(MessWorkFile6,Temp5!)
    If MessWorkRecord6.User=User.Index Then
       VarQ!=MessWorkRecord6.Index
       If VarQ!>SFalse And VarQ!<=Lof(TreasureFile)/TreasureRecLen Then
          Call Read.Record(TreasureFile,VarQ!)
          If TreasureRecord.Persistent Then
             If MessWorkRecord6.Time1=0! Then
                MessWorkRecord6.Time1=Timeit!
                Call Write.Record(MessWorkFile6,Temp5!)
             Else
                If MessWorkRecord6.Charges>0 Then
                   MessWorkRecord6.Time1=Timeit!
                   Call Write.Record(MessWorkFile6,Temp5!)
                Endif
             Endif
             If MessWorkRecord6.Time2=0! Then
                MessWorkRecord6.Time2=Timeit!
                Call Write.Record(MessWorkFile6,Temp5!)
             Endif
          Endif
       Endif
    Endif
 Next
ErrResume2z2:
 Exit Sub
ErrTrap2z2:
 Resume ErrResume2z2
End Sub

' refresh persistent treasure in user inventory
Sub Refresh.Persist1
 On Local Error Goto ErrTrap2z3
 For Temp5!=1! To Lof(MessWorkFile6)/MessWorkRecLen6
    Call Read.Record(MessWorkFile6,Temp5!)
    If MessWorkRecord6.User=User.Index Then
       If MessWorkRecord6.Charges=False Then
          VarQ!=MessWorkRecord6.Index
          If VarQ!>SFalse And VarQ!<=Lof(TreasureFile)/TreasureRecLen Then
             Call Read.Record(TreasureFile,VarQ!)
             If TreasureRecord.Charges>0 Then
                If TreasureRecord.Persistent Then
                   VarZ!=TreasureRecord.PersistTime
                   If VarZ!>0! Then
                      VarQ!=MessWorkRecord6.Time1
                      If VarQ!>0! Then
                         If Time.Elapsed(VarQ!,VarZ!) Then
                            MessWorkRecord6.Charges=TreasureRecord.MaxPersistCharges
                            MessWorkRecord6.Time1=Timeit!
                            MessWorkRecord6.Time2=Timeit!
                            Call Write.Record(MessWorkFile6,Temp5!)
                         Endif
                      Endif
                   Endif
                Endif
             Endif
          Endif
       Else
          VarQ!=MessWorkRecord6.Index
          If VarQ!>SFalse And VarQ!<=Lof(TreasureFile)/TreasureRecLen Then
             Call Read.Record(TreasureFile,VarQ!)
             If TreasureRecord.Charges>0 Then
                If TreasureRecord.Persistent Then
                   VarZ!=TreasureRecord.DischargePersist
                   If VarZ!>0! Then
                      VarQ!=MessWorkRecord6.Time2
                      If VarQ!>0! Then
                         If Time.Elapsed(VarQ!,VarZ!) Then
                            MessWorkRecord6.Charges=0
                            MessWorkRecord6.Time1=Timeit!
                            MessWorkRecord6.Time2=Timeit!
                            Call Write.Record(MessWorkFile6,Temp5!)
                         Endif
                      Endif
                   Endif
                Endif
             Endif
          Endif
       Endif
    Endif
 Next
ErrResume2z3:
 Exit Sub
ErrTrap2z3:
 Resume ErrResume2z3
End Sub

' init all persistent treasure in monster inventory
Sub Init.Persist2
 On Local Error Goto ErrTrap2z5
 For Temp5!=1! To Lof(MessWorkFile3)/MessWorkRecLen3
    Call Read.Record(MessWorkFile3,Temp5!)
    For Var2=1 To 3
       VarQ!=MessWorkRecord3.Weapon(Var2).Index
       If VarQ!>SFalse And VarQ!<=Lof(TreasureFile)/TreasureRecLen Then
          Call Read.Record(TreasureFile,VarQ!)
          If TreasureRecord.Persistent Then
             If MessWorkRecord3.Weapon(Var2).Time1=0! Then
                MessWorkRecord3.Weapon(Var2).Time1=Timeit!
                Call Write.Record(MessWorkFile3,Temp5!)
             Else
                If MessWorkRecord3.Weapon(Var2).Charges>0 Then
                   MessWorkRecord3.Weapon(Var2).Time1=Timeit!
                   Call Write.Record(MessWorkFile3,Temp5!)
                Endif
             Endif
             If MessWorkRecord3.Weapon(Var2).Time2=0! Then
                MessWorkRecord3.Weapon(Var2).Time2=Timeit!
                Call Write.Record(MessWorkFile3,Temp5!)
             Endif
          Endif
       Endif
    Next
 Next
ErrResume2z5:
 Exit Sub
ErrTrap2z5:
 Resume ErrResume2z5
End Sub

' refresh persistent treasure in monster inventory
Sub Refresh.Persist2
 On Local Error Goto ErrTrap2z6
 For Temp5!=1! To Lof(MessWorkFile3)/MessWorkRecLen3
    Call Read.Record(MessWorkFile3,Temp5!)
    For Var2=1 To 3
       If MessWorkRecord3.Weapon(Var2).Charges=False Then
          VarQ!=MessWorkRecord3.Weapon(Var2).Index
          If VarQ!>SFalse And VarQ!<=Lof(TreasureFile)/TreasureRecLen Then
             Call Read.Record(TreasureFile,VarQ!)
             If TreasureRecord.Charges>0 Then
                If TreasureRecord.Persistent Then
                   VarZ!=TreasureRecord.PersistTime
                   If VarZ!>0! Then
                      VarQ!=MessWorkRecord3.Weapon(Var2).Time1
                      If VarQ!>0! Then
                         If Time.Elapsed(VarQ!,VarZ!) Then
                            MessWorkRecord3.Weapon(Var2).Charges=TreasureRecord.MaxPersistCharges
                            MessWorkRecord3.Weapon(Var2).Time1=Timeit!
                            MessWorkRecord3.Weapon(Var2).Time2=Timeit!
                            Call Write.Record(MessWorkFile3,Temp5!)
                         Endif
                      Endif
                   Endif
                Endif
             Endif
          Endif
       Else
          VarQ!=MessWorkRecord3.Weapon(Var2).Index
          If VarQ!>SFalse And VarQ!<=Lof(TreasureFile)/TreasureRecLen Then
             Call Read.Record(TreasureFile,VarQ!)
             If TreasureRecord.Charges>0 Then
                If TreasureRecord.Persistent Then
                   VarZ!=TreasureRecord.DischargePersist
                   If VarZ!>0! Then
                      VarQ!=MessWorkRecord3.Weapon(Var2).Time2
                      If VarQ!>0! Then
                         If Time.Elapsed(VarQ!,VarZ!) Then
                            MessWorkRecord3.Weapon(Var2).Charges=0
                            MessWorkRecord3.Weapon(Var2).Time1=Timeit!
                            MessWorkRecord3.Weapon(Var2).Time2=Timeit!
                            Call Write.Record(MessWorkFile3,Temp5!)
                         Endif
                      Endif
                   Endif
                Endif
             Endif
          Endif
       Endif
    Next
 Next
ErrResume2z6:
 Exit Sub
ErrTrap2z6:
 Resume ErrResume2z6
End Sub

' init new persistent treasure in team inventory
Sub Init.Persist3
 On Local Error Goto ErrTrap2z7
 For Temp5!=1! To Lof(TeamInvFile)/MessWorkRecLen6
    Call Read.Record(TeamInvFile,Temp5!)
    VarQ!=MessWorkRecord6.Index
    If VarQ!>SFalse And VarQ!<=Lof(TreasureFile)/TreasureRecLen Then
       Call Read.Record(TreasureFile,VarQ!)
       If TreasureRecord.Persistent Then
          If MessWorkRecord6.Time1=0! Then
             MessWorkRecord6.Time1=Timeit!
             Call Write.Record(TeamInvFile,Temp5!)
          Else
             If MessWorkRecord6.Charges>0 Then
                MessWorkRecord6.Time1=Timeit!
                Call Write.Record(TeamInvFile,Temp5!)
             Endif
          Endif
          If MessWorkRecord6.Time2=0! Then
             MessWorkRecord6.Time2=Timeit!
             Call Write.Record(TeamInvFile,Temp5!)
          Endif
       Endif
    Endif
 Next
ErrResume2z7:
 Exit Sub
ErrTrap2z7:
 Resume ErrResume2z7
End Sub

' refresh persistent treasure in team inventory
Sub Refresh.Persist3
 On Local Error Goto ErrTrap2z8
 For Temp5!=1! To Lof(TeamInvFile)/MessWorkRecLen6
    Call Read.Record(TeamInvFile,Temp5!)
    If MessWorkRecord6.Charges=False Then
       VarQ!=MessWorkRecord6.Index
       If VarQ!>SFalse And VarQ!<=Lof(TreasureFile)/TreasureRecLen Then
          Call Read.Record(TreasureFile,VarQ!)
          If TreasureRecord.Charges>0 Then
             If TreasureRecord.Persistent Then
                VarZ!=TreasureRecord.PersistTime
                If VarZ!>0! Then
                   VarQ!=MessWorkRecord6.Time1
                   If VarQ!>0! Then
                      If Time.Elapsed(VarQ!,VarZ!) Then
                         MessWorkRecord6.Charges=TreasureRecord.MaxPersistCharges
                         MessWorkRecord6.Time1=Timeit!
                         MessWorkRecord6.Time2=Timeit!
                         Call Write.Record(TeamInvFile,Temp5!)
                      Endif
                   Endif
                Endif
             Endif
          Endif
       Endif
    Else
       VarQ!=MessWorkRecord6.Index
       If VarQ!>SFalse And VarQ!<=Lof(TreasureFile)/TreasureRecLen Then
          Call Read.Record(TreasureFile,VarQ!)
          If TreasureRecord.Charges>0 Then
             If TreasureRecord.Persistent Then
                VarZ!=TreasureRecord.DischargePersist
                If VarZ!>0! Then
                   VarQ!=MessWorkRecord6.Time2
                   If VarQ!>0! Then
                      If Time.Elapsed(VarQ!,VarZ!) Then
                         MessWorkRecord6.Charges=0
                         MessWorkRecord6.Time1=Timeit!
                         MessWorkRecord6.Time2=Timeit!
                         Call Write.Record(TeamInvFile,Temp5!)
                      Endif
                   Endif
                Endif
             Endif
          Endif
       Endif
    Endif
 Next
ErrResume2z8:
 Exit Sub
ErrTrap2z8:
 Resume ErrResume2z8
End Sub

' search for and fill containers with restricted containers/treasure
Sub Fill.Container.With.Item
 On Local Error Goto ErrTrap2z9
 For TempA!=1! To Lof(ContainerFile)/ContainerRecLen
    Call Read.Record(ContainerFile,TempA!)
    If ContainerRecord.DeletedContainer=False Then
       If ContainerRecord.WithinContainer=SFalse Then
          If ContainerRecord.ContainerMax>False Then
             If ContainerRecord.Scanned=False Then
                ' loop through all restrictions
                VarZ=ContainerRecord.ContainerMax
                For Var4=1 To 3
                   Call Read.Record(ContainerFile,TempA!)
                   If ContainerRecord.RestrictItem(Var4)<>SFalse Then
                      VarA!=ContainerRecord.RestrictItem(Var4)
                      If VarA!<SFalse THEN
                         VarA!=Abs(VarA!)
                         If VarA!>SFalse And VarA!<=Lof(ObjectFile)/ObjectRecLen Then
                            Call Read.Record(ObjectFile,VarA!)
                            ' container of objects
                            ContainerRecord.Scanned=True
                            Call Write.Record(ContainerFile,TempA!)
                            For VarX=1 To VarZ
                               Temp3!=Lof(CtnInvFile)/MessWorkRecLen6+1!
                               MessWorkRecord6.Room=SFalse
                               MessWorkRecord6.User=-VarA!
                               MessWorkRecord6.Index=TempA!
                               MessWorkRecord6.Charges=False
                               MessWorkRecord6.Plus=False
                               Call Write.Record(CtnInvFile,Temp3!)
                               Call Add.List.Node5(Temp3!)
                            Next
                         Endif
                      Else
                         If VarA!>SFalse And VarA!<=Lof(TreasureFile)/TreasureRecLen Then
                            Call Read.Record(TreasureFile,VarA!)
                            ' container of containers
                            If TreasureRecord.Container Then
                               ContainerRecord.Scanned=True
                               Call Write.Record(ContainerFile,TempA!)
                               For VarX=1 To VarZ
                                  Call Add.Container.To.Container(VarA!)
                               Next
                            Else
                               ' container of treasure
                               ContainerRecord.Scanned=True
                               Call Write.Record(ContainerFile,TempA!)
                               For VarX=1 To VarZ
                                  Temp3!=Lof(CtnInvFile)/MessWorkRecLen6+1!
                                  MessWorkRecord6.Room=SFalse
                                  MessWorkRecord6.User=VarA!
                                  MessWorkRecord6.Index=TempA!
                                  MessWorkRecord6.Charges=TreasureRecord.Charges
                                  MessWorkRecord6.Plus=False
                                  Call Write.Record(CtnInvFile,Temp3!)
                                  Call Add.List.Node5(Temp3!)
                               Next
                            Endif
                         Endif
                      Endif
                   Endif
                Next
             Endif
          Endif
       Endif
    Endif
 Next
ErrResume2z9:
 Exit Sub
ErrTrap2z9:
 Resume ErrResume2z9
End Sub

Sub Bank.Interest
 On Local Error Goto ErrorTrp41
 Activity=0
 Dnow$=DATES$
 Tnow$=Format$(Now,"hh:mm:ss")
 Close #TempFile1
 FileName = Data.Path1 + Bank.FileName + File.Extension1
 OPEN FileName FOR RANDOM AS #TempFile1 LEN = BankRecLen
 If UserRecord.Bank>0# Then
    P$ = "A" ' account balance
    GOSUB Process
    p3#=DFalse
    If p2#>DFalse Then
       TempX#=UserRecord.Bank
       MaxDbl#=CDBL(1D+308)
       If TempX#+p2#<=MaxDbl# Then
          Activity=-1
          p3#=p2#
          UserRecord.Bank=TempX#+p2#
          Call Extend.Amount2(p2#,Var$)
          Graphics.Off=True
          Strng="Bank activity for "+Fclock$
          Call IO.O
          Strng="Bank reports posting of"+Var$+" gold interest to your account."
          Call IO.O
          VarZ=True
       Endif
    Endif
 Endif
 If UserRecord.Borrow>0# Then
    P$ = "B" ' amount borrowed
    GOSUB Process
    p4#=DFalse
    p5#=DFalse
    If p2#>DFalse Then
       TempX#=UserRecord.Borrow
       MaxDbl#=CDBL(1D+308)
       If TempX#+p2#<=MaxDbl# Then
          p4#=p2#
          UserRecord.Borrow=TempX#+p2#
          Call Extend.Amount2(p2#,Var$)
          Activity=-1
          If VarZ=0 Then
             Strng="Bank activity for "+Fclock$
             Call IO.O
          Endif
          VarZ=True
          Graphics.Off=True
          Strng="Bank reports posting of"+Var$+" gold interest to your borrowed amount."
          Call IO.O
          p2#=Int(p2#/10#)
          If p2#>DFalse Then
             If UserRecord.Gold-p2#>DFalse Then
                p5#=p2#
                UserRecord.Gold=UserRecord.Gold-p2#
                UserRecord.Borrow=UserRecord.Borrow-p2#
                Call Extend.Amount2(p2#,Var$)
                Strng="Bank pays off"+Var$+" gold of your loan from your gold."
                Call IO.O
             Endif
          Endif
       Endif
    Endif
 Endif
 ' clear transactions.
 Call Write.Record(UserFile,User.Index)
 FOR z! = 1! TO LOF(TempFile1) / BankRecLen
    Call Read.Record(BankFile,z!)
    IF BankRecord.UserIndex = User.Index THEN
       IF BankRecord.Deleted = False THEN
          BankRecord.Balance2 = BankRecord.Balance
          BankRecord.Balance = False
          BankRecord.Deleted = True
          Call Write.Record(BankFile,z!)
       END IF
    END IF
 NEXT
 ' post user balance.
 BankRecord.UserIndex = User.Index
 BankRecord.DatePost = Dnow$
 BankRecord.TimePost = Tnow$
 BankRecord.Balance = UserRecord.Bank
 BankRecord.Deleted = False
 BankRecord.PostAmount = DFalse
 BankRecord.PostType = "A"
 BankRecord.PostSubType = "A"
 BankRecord.PostSubType2 = False
 BankRecord.From = UserRecord.CodeName
 BankRecord.To = Nul
 z! = LOF(TempFile1) / BankRecLen + 1!
 Call Write.Record(BankFile,z!)
 ' post user loan.
 BankRecord.UserIndex = User.Index
 BankRecord.DatePost = Dnow$
 BankRecord.TimePost = Tnow$
 BankRecord.Balance = UserRecord.Borrow
 BankRecord.Deleted = False
 BankRecord.PostAmount = DFalse
 BankRecord.PostType = "B"
 BankRecord.PostSubType = "A"
 BankRecord.PostSubType2 = False
 BankRecord.From = UserRecord.CodeName
 BankRecord.To = Nul
 z! = LOF(TempFile1) / BankRecLen + 1!
 Call Write.Record(BankFile,z!)
 ' post user interest earned.
 If p3#>DFalse Then
    BankRecord.UserIndex = User.Index
    BankRecord.DatePost = Dnow$
    BankRecord.TimePost = Tnow$
    BankRecord.Balance = UserRecord.Bank
    BankRecord.Deleted = False
    BankRecord.PostAmount = p3#
    BankRecord.PostType = "I"
    BankRecord.PostSubType = "I"
    BankRecord.PostSubType2 = 2
    BankRecord.From = UserRecord.CodeName
    BankRecord.To = Nul
    z! = LOF(TempFile1) / BankRecLen + 1!
    Call Write.Record(BankFile,z!)
    ' decrement user earned interest from bank.
    BankRecord.UserIndex = True
    BankRecord.DatePost = Dnow$
    BankRecord.TimePost = Tnow$
    BankRecord.Balance = False
    BankRecord.Deleted = False
    BankRecord.PostAmount = p3#
    BankRecord.PostType = "D"
    BankRecord.PostSubType = "I"
    BankRecord.PostSubType2 = 2
    BankRecord.From = UserRecord.CodeName
    BankRecord.To = Nul
    z! = LOF(TempFile1) / BankRecLen + 1!
    Call Write.Record(BankFile,z!)
 Endif
 ' post user loan interest.
 If p4#>DFalse Then
    BankRecord.UserIndex = User.Index
    BankRecord.DatePost = Dnow$
    BankRecord.TimePost = Tnow$
    BankRecord.Balance = UserRecord.Borrow
    BankRecord.Deleted = False
    BankRecord.PostAmount = p4#
    BankRecord.PostType = "I"
    BankRecord.PostSubType = "I"
    BankRecord.PostSubType2 = 3
    BankRecord.From = UserRecord.CodeName
    BankRecord.To = Nul
    z! = LOF(TempFile1) / BankRecLen + 1!
    Call Write.Record(BankFile,z!)
 Endif
 ' post user loan payment.
 If p5#>DFalse Then
    BankRecord.UserIndex = True
    BankRecord.DatePost = Dnow$
    BankRecord.TimePost = Tnow$
    BankRecord.Balance = False
    BankRecord.Deleted = False
    BankRecord.PostAmount = p2#
    BankRecord.PostType = "C"
    BankRecord.PostSubType = "P"
    BankRecord.PostSubType2 = 1
    BankRecord.From = UserRecord.CodeName
    BankRecord.To = Nul
    z! = LOF(TempFile1) / BankRecLen + 1!
    Call Write.Record(BankFile,z!)
 Endif
 ' store user account activity in bank logfile.
 Close #TempFile1
 FileName=Data.Path1+Bank.FileName+Log.Extension
 Open FileName For Append Shared As #TempFile1
 If p3#>DFalse Then
    Call Extend.Amount2(p3#,Var$)
    Strng="Bank Interest Earned:"+Var$
    Strng2="Bank Interest Paid:"+Var$
    Gosub Bank.Log
 Endif
 If p4#>DFalse Then
    Call Extend.Amount2(p4#,Var$)
    Strng="Loan Interest:"+Var$
    Strng2=Strng
    Gosub Bank.Log
 Endif
 If p5#>DFalse Then
    Call Extend.Amount2(p5#,Var$)
    Strng="Loan Payment:"+Var$
    Strng2=Strng
    Gosub Bank.Log
 Endif
 Close #TempFile1
 If TempX=1 Then
    If Activity=0 Then
       Strng="No bank activity to report."
       Call IO.O
    Endif
 Endif
 EXIT SUB

' process user account.
Process:
 p2# = DFalse
 ' search for first bank record
 f = False
 FOR z! = 1! TO LOF(TempFile1) / BankRecLen
    Call Read.Record(BankFile,z!)
    IF BankRecord.UserIndex = User.Index THEN
       IF BankRecord.PostType = P$ THEN
          f = True
          EXIT FOR
       END IF
    END IF
 NEXT
 IF f THEN
    ' first balance record
    d1$ = BankRecord.DatePost
    t1$ = BankRecord.TimePost
    a1# = BankRecord.Balance
    q$ = BankRecord.PostType
    ' search for second bank record
    f = False
    FOR z! = z! + 1! TO LOF(TempFile1) / BankRecLen
       Call Read.Record(BankFile,z!)
       IF BankRecord.UserIndex = User.Index THEN
          IF BankRecord.PostType = P$ THEN
             f = True
             EXIT FOR
          END IF
       END IF
    NEXT
    IF f THEN
       DO
          ' next transaction record
          d2$ = BankRecord.DatePost
          t2$ = BankRecord.TimePost
          a2# = BankRecord.Balance
          q$ = BankRecord.PostType
          GOSUB Process1
          d1$ = d2$: t1$ = t2$ ' store previous date/time
          a1# = a2# ' flat rate (no accrued interest).
          ' search for next transaction record
          f = False
          FOR z! = z! + 1! TO LOF(TempFile1) / BankRecLen
             Call Read.Record(BankFile,z!)
             IF BankRecord.UserIndex = User.Index THEN
                IF BankRecord.PostType = P$ THEN
                   f = True
                   EXIT FOR
                END IF
             END IF
          NEXT
          IF f = False THEN
             EXIT DO
          END IF
       LOOP
    END IF
    d2$ = Dnow$
    t2$ = Tnow$
    GOSUB Process1
 END IF
 RETURN

' subroutine processes yearly interest on a balance for a date/time range.
Process1:
 d1# = cdbl(DateValue(d1$))
 If Val(Left$(t1$,2))>23 Then
    V = Val(Mid$(t1$,1,2))
    V = V MOD 24
    V$ = Right$("00"+Mid$(Str$(V),2), 2)
    Mid$(t1$,1,2)=V$
 Endif
 If Mid$(t1$,3,1)<>":" Or Mid$(t1$,6,1)<>":" Then t1$="00:00:00"
 t1# = cdbl(TimeValue(t1$))
 d2# = cdbl(DateValue(d2$))
 If Val(Left$(t2$,2))>23 Then
    V = Val(Mid$(t2$,1,2))
    V = V MOD 24
    V$ = Right$("00"+Mid$(Str$(V),2), 2)
    Mid$(t2$,1,2)=V$
 Endif
 If Mid$(t2$,3,1)<>":" Or Mid$(t2$,6,1)<>":" Then t2$="00:00:00"
 t2# = cdbl(TimeValue(t2$))
 d3# = d2# - d1#
 H1% = Hour(t1#)
 M1% = Minute(t1#)
 S1% = Second(t1#)
 t1! = CSNG(H1%) * 3600! + CSNG(M1%) * 60! + CSNG(S1%)
 H2% = Hour(t2#)
 M2% = Minute(t2#)
 S2% = Second(t2#)
 t2! = CSNG(H2%) * 3600! + CSNG(M2%) * 60! + CSNG(S2%)
 ' calculate seconds elapsed from previous login.
 IF d3# = 0# THEN
    t3# = cdbl(t2!) - cdbl(t1!)
 ELSE
    IF d3# >= 1# THEN
       t3# = cdbl(86400!) - cdbl(t1!) + cdbl(t2!)
       t3# = t3# + cdbl(86400!) * (d3# - 1#)
    END IF
 END IF
 ' calculate days in year range.
 L#=365#
 L1=Val(Right$(d1$,4))
 L2=Val(Right$(d2$,4))
 FOR Var=L1 TO L2
    ' calculate leap years.
    f=False
    IF (Var MOD 4)=False THEN
       f=True
       IF (Var MOD 100)=False THEN
          f=False
          IF (Var MOD 400)=False THEN
             f=True
          END IF
       END IF
    END IF
    IF f THEN
       ' check leap year date range.
       d4$="01-01-"+Mid$(Str$(Var),2)
       d5$="12-31-"+Mid$(Str$(Var),2)
       d4#=DateValue(d4$)
       d5#=DateValue(d5$)
       If d1#<=d4# And d2#>=d5# Then
          L#=L#+1# ' add one day.
       Endif
    Endif
 NEXT
 ' calculate interest based on seconds in time interval.
 T#=86400#*L#
 R#=Cdbl(InterestRate3/100!)
 p1#=a1#*t3#/T#*R# ' 365 days @ rate / second.
 p1#=INT(p1#) ' round to one gold.
 ' add to accrued interest.
 IF p1#>0# THEN
    p2#=p2#+p1# ' flatrate (not compounded).
 END IF
 RETURN

Bank.Log:
 DTime$=DateS$+", "+Format$(Now,"hh:mm:ss")
 Var$=Lcase$(Rtrim$(UserRecord.CodeName))
 Mid$(Var$,1,1)=Ucase$(Mid$(Var$,1,1))
 Var2$=Var$+": "+DTime$+"; Logged: "+Strng+" gold."
 Print #TempFile1,Var2$
 Var2$="Bank: "+Var$+"; "+DTime$+"; Logged: "+Strng2+" gold."
 Print #TempFile1,Var2$
 Return
ErrorRsm41:
 Exit Sub
ErrorTrp41:
 Strng="Error"+Str$(Err)+" processing bank balance."
 Call Io.o
 Resume ErrorRsm41
End Sub

Sub Extend.Amount2(Var#,Var$)
 VarX$=Ltrim$(Str$(Var#)) ' 1.111D308
 V=Instr(VarX$,"D")
 If V Then
    If Mid$(VarX$,2,1)="." Then
       VarX$=Left$(VarX$,1)+Mid$(VarX$,V)
    Endif
    Var$=" "+VarX$
 Else
    Var$=" "+Form$(Var#)
 Endif
End Sub

