;rimport.sc   Quest for Glory 2 -- Restore character stats from QG1

(script# rImport)

(public
   import      0
)

;; Bits in svMiscEquip
(define  SWORD_BIT   1)
(define  CHAIN_BIT   2)
(define  PICK_BIT    4)
(define  TOOL_BIT    8)
(define  MIRROR_BIT  16)
(define  BABA_BIT    32)          
(define  SCORE_BIT   64)

(define  EXTRA_DATA  18)   ; Data items other than stats and name
(define  CHECK_DATA  10)   ; Data items that are in check sums

(local
;; local data for restoring hero stats from previous game
                         ;;;;;;;;;;;;;;;;;;start;;;;;;;;;;;;;;;;;;
   statsKey = $53        ;;;;;;;;order dependent variables;;;;;;;;
   svCharType            ;;;;;;;;order dependent variables;;;;;;;;
   svHighGold            ;;;;;;;;order dependent variables;;;;;;;;
   svLowGold             ;;;;;;;;order dependent variables;;;;;;;;
   svScore               ;;;;;;;;order dependent variables;;;;;;;;
   svMiscEquip           ;;;;;;;;order dependent variables;;;;;;;;
   [codedStats OLD_NUM_ATTRIBS] ;;;;;;;;order dependent variables;;;;;;;;
   svDaggers             ;;;;;;;;order dependent variables;;;;;;;;
   svHealing             ;;;;;;;;order dependent variables;;;;;;;;
   svMana                ;;;;;;;;order dependent variables;;;;;;;;
   svStamina             ;;;;;;;;order dependent variables;;;;;;;;
   svGhostOil            ;;;;;;;;order dependent variables;;;;;;;;
   bogus0   = $79        ;;;;;;;;order dependent variables;;;;;;;;
   bogus1   = $86        ;;;;;;;;order dependent variables;;;;;;;;
   checkSum1             ;;;;;;;;order dependent variables;;;;;;;;
   checkSum2             ;;;;;;;;order dependent variables;;;;;;;;
   bogus2   = $43        ;;;;;;;;order dependent variables;;;;;;;;
   bogus3   = $88        ;;;;;;;;order dependent variables;;;;;;;;
   bogus4   = $ad        ;;;;;;;;order dependent variables;;;;;;;;
   bogus5   = $f0        ;;;;;;;;order dependent variables;;;;;;;;
   checkSumKey = $ce     ;;;;;;;;order dependent variables;;;;;;;;
                         ;;;;;;;;;;;;;;;;;;;end;;;;;;;;;;;;;;;;;;;
   check1
   check2
   [YNSTR 5]
   validFile
   [heroFileName 40]
   [bigStr 400]
   [str 40]
   statMap =
   [
      STR      INT      AGIL        VIT      LUCK        WEAPON   PARRY
      DODGE    STEALTH  PICK        THROW    CLIMB       MAGIC    EXPER
      HEALTH   STAMINA  MANA        OPEN     DETMAGIC    TRIGGER  DAZZLE
      ZAP      CALM     FLAMEDART   FETCH
   ]
)

(enum          ;states of importHero Script
   askRestore
   getInfoFileName
   getInfoFileName2
   restoreFile
   readComplete
   importDone
   tryAgain
)

(procedure
   makeZero
   restoreHero
   convWord
   convByte
)

(procedure (makeZero &tmp whichSkill)
   (for  ((= whichSkill 0))
         (< whichSkill NUM_ATTRIBS)
         ((++ whichSkill))
      (= [egoStats whichSkill] 0)
   )
   (= [invNum iGold] (= score 0))
   (= [invNum iSword] 0)
   (= [invNum iShield] 0)
   (= [invNum iDagger] 0)
   (= [invNum iLeather] 0)
   (= [invNum iChainMail] 0)
   (= [invNum iLockPick] 0)
   (= [invNum iThiefKit] (= [invNum iThiefLicense] 0))
;  (= [invNum iHealingPotion] 0)
;  (= [invNum iManaPotion] 0)
;  (= [invNum iStaminaPotion] 0)
   (= score 0)
   (= heroType 0)
   (StrCpy @userName {xxxxxxxxxxy})
   (for  ((= whichSkill 0))
         (< whichSkill (+ OLD_NUM_ATTRIBS EXTRA_DATA))
         ((++ whichSkill))
      (= [statsKey (+ whichSkill 1)] 0)
   )
   (return)
)

(procedure (restoreHero &tmp whichSkill)
   (if (not (heroinfo open: fRead))
      (Print (Format @bigStr "Could not find Hero file -- %s."
                  (heroinfo name?)))
      (return FALSE)
   )

   (heroinfo readString: @userName 52)
   (heroinfo readString: @bigStr 90)

   (for  ((= whichSkill 0))
         (< whichSkill (+ OLD_NUM_ATTRIBS EXTRA_DATA))
         ((++ whichSkill))

      (= [statsKey (+ whichSkill 1)] (convWord [bigStr whichSkill]))

   )

   (for  ((= whichSkill (+ OLD_NUM_ATTRIBS EXTRA_DATA)))
         (< 0 whichSkill)
         ((-- whichSkill))

      (^= [statsKey whichSkill] (& [statsKey (- whichSkill 1)] 127))

   )

   (= check1 checkSumKey)
   (for  ((= whichSkill 0))
         (< whichSkill (+ OLD_NUM_ATTRIBS CHECK_DATA))
         ((+= whichSkill 2))
      (= [statsKey (+ whichSkill 1)] (& [statsKey (+ whichSkill 1)] 127))
      (+= check1 [statsKey (+ whichSkill 1)])
   )

   (= check2 0)
   (for  ((= whichSkill 1))
         (< whichSkill (+ OLD_NUM_ATTRIBS CHECK_DATA))
         ((+= whichSkill 2))
      (= [statsKey (+ whichSkill 1)] (& [statsKey (+ whichSkill 1)] 127))
      (+= check2 [statsKey (+ whichSkill 1)])
   )

   (&= check1 127)
   (&= check2 127)
   (if (or (!= check1 checkSum1) (!= check2 checkSum2))
      (Print "I'm terribly sorry.__That doesn't seem to be a proper
            Quest for Glory I character save file."
      )
      (return FALSE)
   )

   (for  ((= whichSkill 0))
         (< whichSkill OLD_NUM_ATTRIBS)
         ((++ whichSkill))
      (= [egoStats [statMap whichSkill]] [codedStats whichSkill])
      (if (and
            (not (< MAGIC [statMap whichSkill] OPEN))
            (not (<= 0 [codedStats whichSkill] 100))
         )
         (Print "I'm terribly sorry.__That doesn't seem to be a proper
               Quest for Glory I character save file."
         )
         (return FALSE)
      )
   )

   (= [egoStats COMM] (/ (+ (* [egoStats INT] 3) [egoStats LUCK]) 4))

   (= [invNum iDagger]        svDaggers)  
;  (= [invNum iHealingPotion] svHealing)  
;  (= [invNum iManaPotion]    svMana)     
;  (= [invNum iStaminaPotion] svStamina)  
   (= [invNum iGold]          (+ (* svHighGold 100) svLowGold))

;; (= score (+ svScore 128))
;; (if (& svMiscEquip SCORE_BIT) (+= score 256))

   (if (& svMiscEquip SWORD_BIT) (= [invNum iSword] 1))
   (if (& svMiscEquip CHAIN_BIT)
      (= [invNum iChainMail] 1)
   else
      (= [invNum iLeather] 1)
   )
   (if (& svMiscEquip PICK_BIT)
         (= [invNum iLockPick] (= [invNum iThiefLicense] 1))
   )
   (if (& svMiscEquip TOOL_BIT)
         (= [invNum iThiefKit] (= [invNum iThiefLicense] 1))
   )
   (if (== heroType FIGHTER)
      (= [invNum iShield] 1)
   )

   (return TRUE)
)

(procedure (convWord ascii)
   (return (+ (convByte (>> ascii 8)) (* (convByte (& ascii 255)) 16)))
)

(procedure (convByte ascii)
   (cond
      ((== ascii 32)
         (return 0)
      )
      ((<= 48 ascii 57)
         (return (- ascii 48))
      )
      (else
         (return (- ascii 87))
      )
   )
)

(instance import of Room
   (properties
      picture  pBlue
      horizon  0
      style    IRISOUT
   )
   
   (method (dispose)
      (StatusLine code: dftStatusCode)
      (Bset fInMainGame)
      (super dispose:)
   )

   (method (init)
      (Bclr fInMainGame)
      (StatusLine
         code: endStatus,
         enable:)
      (super init: &rest)
      (cSound stop:)

      ; don't let'm control anything!
      (HandsOff)
      (self setScript: importHero)
   )
)


(instance heroinfo of File
   (properties
      name  {glory1.sav})
)

(instance importHero of Script
   (method (changeState newState &tmp whichSkill oldGold)
      (switch (= state newState)
         (askRestore
            (Format @heroFileName "a:glory1.sav")

            (Print "Please insert the disk on which you saved your
                  winning Hero from \"Quest for Glory I:  So You Want To
                  Be A Hero\" into the disk drive so that your Hero
                  can make the journey to Shapeir.")
            (self  cue:)
         )

         (getInfoFileName
            (= cycles 2)
         )

         (getInfoFileName2
            (if (GetHeroFileName @heroFileName)
               (heroinfo name: @heroFileName)
               (= cycles 2)
            else
               (self changeState: importDone)
            )
         )

         (restoreFile
            (makeZero)
            ; Try to restore the character file
            (if (= validFile (restoreHero))
               (= cycles 2)
            else
               (self changeState: tryAgain)
            )
         )

         (readComplete
            (Print "Character successfully imported.")
            (= cycles 1)
         )

         (importDone
            (HandsOn)
            (curRoom  newRoom: (if validFile rChAlloc  else rOpeningScroll))
         )

         (tryAgain
            (if (Print
                  "Do you want to try importing your character again?"
                  #button: {Yes} 1
                  #button: {_No_} 0
                )
               (= bogus0 $79)
               (= bogus1 $86)
               (= bogus2 $43) 
               (= bogus3 $88) 
               (= bogus4 $ad) 
               (= bogus5 $f0) 
               (self changeState: getInfoFileName)
            else
               (self changeState: importDone)
            )
         )
      )
   )
)

(instance endStatus of Code
   (method (doit strg)
      (Format strg "___Wow!__You're Really A Hero!__[score %d of 500]" score)
   )
)

