;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)
	)
)

