option explicit
class classQuestHandler
private m_objPage
private m_objQuest
private m_oStateHandler
private m_questName
private m_contentType
private m_debug
private m_stationId
private m_sessionId
private m_statesString
' persistent via save/load:
private m_lastStation
private m_beforeLastStation
private m_firstQuestName
private m_defaultImage
private m_defaultMusic
private m_musicLoop
private m_linkInlineStyle
private m_language
private m_gameOver
public sub setStatesString(byVal sValue)
m_statesString = sValue
end sub
public sub setSessionId(byVal sessionId)
m_sessionId = sessionId
end sub
public sub setContentType(byVal contentType)
m_contentType = contentType
end sub
public sub setQuestName(byVal questName)
m_questName = questName
end sub
public sub setStationId(byVal stationId)
m_stationId = stationId
end sub
public sub init
dim pageTitle
set m_oStateHandler = new classStateHandler
randomize
setQmlStartVariables
setQmlVariables
m_linkInlineStyle = ""
m_firstQuestName = m_questName
m_defaultImage = g_none
m_defaultMusic = g_none
m_musicLoop = "0"
if m_contentType = "" then
m_contentType = "text/html"
end if
loadXmlQuestFile mapPathIf(m_questName & ".xml")
if m_objQuest.parseError.errorCode = 0 then
m_debug = getDebug
setObjPage
setStyle
m_language = getLanguage
pageTitle = getPageTitle
setDocTitle pageTitle
m_oStateHandler.setString "qmlTitle", pageTitle
else
showErrorOf m_objQuest
end if
if m_sessionId = "" then
m_sessionId = getNewSessionId
else
loadQuest
end if
end sub
public sub doHandleStation
dim displayGotten
dim inputString
dim station
inputString = ""
set station = getStation(m_stationId)
if (station is nothing) then
exit sub
end if
handleTopChoose station, m_stationId
m_oStateHandler.setString "qmlStation", m_stationId
handleStationSettings station
handleCheckStates station
displayGotten = getDisplay(station, false)
handleInclude m_stationId, displayGotten
output displayGotten
handleStatesInformation
m_beforeLastStation = m_lastStation
m_lastStation = m_stationId
m_oStateHandler.setString "qmlLastStation", m_lastStation
m_oStateHandler.addVisits m_stationId
saveQuest
if g_isServerVersion then
handleServerOutput
end if
end sub
public function getObjPage
set getObjPage = m_objPage
end function
' private __________________________________________________________
private sub handleCheckStates(byRef station)
dim child
dim checkStatesAgain
dim chooseElement
do
m_oStateHandler.handlePreStates station
checkStatesAgain = false
for each child in station.childNodes
if child.nodeName = "if" then
if m_oStateHandler.getNodeState(child) then
set chooseElement = child.selectSingleNode("choose")
if not (chooseElement is nothing) then
processChoose child, station, chooseElement
checkStatesAgain = true
else
set station = child
end if
exit for
end if
elseif child.nodeName = "else" then
set chooseElement = child.selectSingleNode("choose")
if not (chooseElement is nothing) then
processChoose child, station, chooseElement
checkStatesAgain = true
else
set station = child
end if
end if
next
loop until not checkStatesAgain
end sub
private sub processChoose(byRef ifElseElement, byRef station, byRef chooseElement)
dim sStation
dim child
for each child in ifElseElement.childNodes
m_oStateHandler.setStates child
next
sStation = getLink(chooseElement)
set station = getStation(sStation)
m_oStateHandler.addVisits station.getAttribute("id")
end sub
private function handleStatesInformation
dim statesInformation
if m_debug then
statesInformation = m_oStateHandler.getStatesInformation(m_stationId)
if g_isServerVersion then
serverOutputToId "stateDisplay", statesInformation
else
m_objPage.all.stateDisplay.innerHTML = statesInformation
end if
end if
end function
private sub handleServerOutput
dim oServerResponse
set oServerResponse = new classServerResponse
oServerResponse.setContentType m_contentType
oServerResponse.setSessionId m_sessionId
oServerResponse.setQuestName m_questName
oServerResponse.setObjPage m_objPage
oServerResponse.process
end sub
private sub setObjPage
if g_isServerVersion then
setObjPageServer
else
set m_objPage = document
end if
end sub
private sub setObjPageServer
dim xHtml
dim stateDisplay
dim bodyNode
dim xPath
set m_objPage = createObject("Microsoft.XMLDOM")
set xHtml = getXml("script\page.xml")
if m_debug then
set stateDisplay = xHtml.createElement("div")
stateDisplay.setAttribute "id", "stateDisplay"
xPath = "//body[@id = 'bodyNode']"
set bodyNode = xHtml.selectSingleNode(xPath)
bodyNode.appendChild stateDisplay
end if
m_objPage.load xHtml
end sub
private function mapPathIf(byVal filePath)
dim newFilePath
if g_isServerVersion then
newFilePath = server.mapPath(filePath)
else
newFilePath = filePath
end if
mapPathIf = newFilePath
end function
private sub setDocTitle(byVal text)
dim objTitle
if g_isServerVersion then
set objTitle = m_objPage.documentElement.selectSingleNode("//title")
objTitle.text = text
else
m_objPage.title = text
end if
end sub
private sub handleTopChoose(byRef station, byVal stationId)
dim choose
dim sStation
dim child
set choose = station.selectSingleNode("choose")
if not (choose is nothing) then
m_oStateHandler.addVisits stationId
m_oStateHandler.handlePreStates station
for each child in station.childNodes
m_oStateHandler.setStates child
next
sStation = choose.getAttribute("station")
stationId = getLink(choose)
set station = getStation(stationId)
end if
end sub
private sub handleInclude(byVal stationId, byRef oldDisplay)
dim includeIn
dim inNode
dim includeNode
dim doInclude
dim includeState
dim station
dim newDisplay
set includeIn = m_objQuest.documentElement.selectNodes("//in")
for each inNode in includeIn
if compareStrings(inNode.getAttribute("station"), stationId) then
if m_oStateHandler.getNodeState(inNode) then
set includeNode = inNode.parentNode
if m_oStateHandler.getNodeState(includeNode) then
set station = includeNode.parentNode
handleCheckStates station
newDisplay = getDisplay(station, true)
if includeNode.getAttribute("process") = "after" then
oldDisplay = combineDisplay(oldDisplay, newDisplay)
elseif includeNode.getAttribute("process") = "before" then
oldDisplay = combineDisplay(newDisplay, oldDisplay)
else ' if includeNode.getAttribute("process") = "exclusive" then
oldDisplay = newDisplay
end if
end if
end if
end if
next
end sub
private function combineDisplay(byRef station1, byRef station2)
dim station
dim parags
dim parag
dim lastParag
dim listEntry
dim listEntries
dim list1
set station = getXmlString(" " & text & " " & text & " " & text & "
" & table.xml & "
"
getTable = xhtml
end function
private sub insertStyle(byRef element)
dim thisClass
dim thisStyle
if isNull( element.getAttribute("class") ) then
thisClass = "qml" + toPropercase(element.nodeName)
else
thisClass = element.getAttribute("class")
end if
thisStyle = getClassStyle(thisClass)
if thisStyle <> "" then
element.setAttribute "style", thisStyle
end if
element.removeAttribute "class"
end sub
private sub handleMusic(byVal musicSource, byVal supressMusic)
if musicSource <> g_none or m_defaultMusic <> g_none then
if supressMusic then
backgroundMusic.src = ""
else
if musicSource = g_none then
musicSource = m_defaultMusic
end if
if not backgroundMusic.loop = m_musicLoop then
backgroundMusic.loop = m_musicLoop
end if
backgroundMusic.src = musicSource
end if
end if
end sub
private sub checkIfGameOver(byRef path, byRef toInclude, byRef stationNode)
if path <> "" then
path = "" & path & "
"
elseif not toInclude then
if ( stationNode.selectSingleNode(".//choice") is nothing ) then
m_gameOver = true
end if
end if
end sub
private sub displayInput(byRef child, byRef text)
dim station
dim stringName
station = m_oStateHandler.replaceAllValues( child.getAttribute("station") )
'station = replace(station, " ", "%20")
stringName = child.getAttribute("name")
if isNull(stringName) then
stringName = "qmlInput"
else
stringName = m_oStateHandler.replaceAllValues(stringName)
end if
if g_isServerVersion then
text = text & vbNewline
text = text & "" & vbNewline
else
text = text & "" & vbNewline
end if
end sub
private sub displayPath(byRef child, byRef text, byRef imageMap, byRef path, byRef sSource, byRef sText, byRef imageMapString, byRef includesImagemap, byRef imageSource)
dim pathText
dim linkStyle
dim classStyle
dim statesString
dim oStatesString
set oStatesString = new classStatesString
statesString = oStatesString.getStatesFromChoice(child, m_oStateHandler)
if m_oStateHandler.getNodeState(child) then
if child.getAttribute("area") <> "" then
imageMap = imageMap & getImageMapString( _
child.getAttribute("area"), _
getLink(child), _
child.text)
else
linkStyle = m_linkInlineStyle
classStyle = getClassStyle("qmlLink")
if classStyle <> "" then
linkStyle = replace(linkStyle, ";""", ";" & classStyle & """")
end if
pathText = "" & _
getText(child, sSource, sText, imageMapString, includesImagemap, imageSource) & ""
path = path & wrapListWithClass(child, pathText, "qmlChoice")
end if
end if
end sub
private sub displayText(byRef child, byRef text, byRef sSource, byRef sText, byRef imageMapString, byRef includesImagemap, byRef imageSource)
if m_oStateHandler.getNodeState(child) then
text = text & wrapWithParagraphClass(child, getText(child, sSource, sText, imageMapString, includesImagemap, imageSource) )
end if
end sub
private sub displayMusic(byRef child, byRef text, byRef musicSource, byRef sSource, byRef supressMusic)
if m_oStateHandler.getNodeState(child) then
musicSource = child.getAttribute(sSource)
musicSource = m_oStateHandler.replaceAllValues(musicSource)
m_musicLoop = returnIf(child.getAttribute("loop") = "true", "-1", "0")
if child.getAttribute("default") = "true" then
m_defaultMusic = musicSource
end if
supressMusic = (musicSource = g_none)
end if
end sub
private sub displayImage(byRef child, byRef text, byRef sSource, byRef sText, byRef imageMapString, byRef includesImagemap, byRef imageSource, byRef isInline)
dim imageClass
dim supressImage
dim thisImage
dim altText
if m_oStateHandler.getNodeState(child) then
imageSource = child.getAttribute("source")
imageSource = m_oStateHandler.replaceAllValues(imageSource)
supressImage = (imageSource = g_none)
if not supressImage then
altText = child.getAttribute("text")
altText = m_oStateHandler.replaceAllValues(altText)
imageMapString = returnIf(includesImagemap, " usemap=""#imapa""", "")
thisImage = ""
if isNull( child.getAttribute("class") ) then
imageClass = "qmlImage"
else
imageClass = child.getAttribute("class")
end if
if not isInline then
thisImage = wrapWithElementClass(thisImage, "p", imageClass, "")
end if
text = text & thisImage
if child.getAttribute("default") = "true" then
m_defaultImage = imageSource
end if
end if
end if
end sub
private function wrapWithElementClass(byVal content, byVal nodeName, byVal className, byRef realClass)
dim thisStyle
dim elementWithClass
thisStyle = getClassStyle(className)
if thisStyle <> "" then
thisStyle = " style=""" & thisStyle & """"
end if
if realClass <> "" then
realClass = " class=""" & realClass & """"
end if
elementWithClass = "<" & nodeName & thisStyle & realClass & ">" & _
content & "" & nodeName & ">"
wrapWithElementClass = elementWithClass
end function
private function wrapListWithClass(byRef listNode, byVal text, byVal defaultClass)
dim listWithClass
dim className
dim classStyle
className = listNode.getAttribute("class")
if isNull( className ) then className = defaultClass
classStyle = getClassStyle(className)
if classStyle <> "" then
if not instr(classStyle, "list-style-type") >= 1 then
classStyle = "list-style-type: none;" & classStyle
end if
listWithClass = "
"
if child.getAttribute("type") = "strong" then
text = text & "
"
end if
case "emphasis"
text = text & wrapWithElementClass(child.firstChild.text, "em", "qmlEmphasis", "")
case "strong"
text = text & wrapWithElementClass(child.firstChild.text, "strong", "qmlStrong", "")
case "poem"
text = text & "
" & child.firstChild.text & "
" case "display" text = text & wrapWithElementClass(child.firstChild.text, "span", "qmlDisplay", "display") case "link" text = text & "" & _ child.firstChild.text & "" case "image" displayImage child, text, sSource, sText, imageMapString, includesImagemap, imageSource, true end select else convertedText = child.data convertedText = m_oStateHandler.replaceAllValues(convertedText) text = text & convertedText end if next getText = text end function private function getInlineChoice(byRef node) dim choice dim thisClass dim thisStyle if m_oStateHandler.getNodeState(node) then if isNull( node.getAttribute("class") ) then thisClass = "qmlInlineChoice" else thisClass = node.getAttribute("class") end if thisStyle = getClassStyle(thisClass) if thisStyle <> "" then thisStyle = "style=""" & thisStyle & """ " end if choice = "" & _ node.text & "" end if getInlineChoice = choice end function private function getLink(byRef choice) dim leadsTo leadsTo = choice.getAttribute("station") leadsTo = m_oStateHandler.replaceAllValues(leadsTo) if leadsTo = "back" then leadsTo = m_lastStation end if getLink = leadsTo end function private function getStation(byVal id) dim xPath xPath = "//station[@id = '" & id & "']" set getStation = m_objQuest.selectSingleNode(xPath) end function private sub outputStatus(byVal display) if g_isServerVersion then serverOutputToId "statusNode", display else m_objPage.all.statusNode.innerHTML = display end if end sub private sub output(byVal display) if g_isServerVersion then serverOutputToId "displayNode", display else m_objPage.all.displayNode.innerHTML = display end if end sub private sub serverOutputToId(byVal id, byVal display) dim displayNode dim content dim xPath set content = createObject("Microsoft.XMLDOM") xPath = "//div[@id = '" & id & "']" set displayNode = m_objPage.documentElement.selectSingleNode(xPath) content.loadXML "