Final sprint to get display of quest target coords (or nearest exit when applicable).

This commit is contained in:
Martin Haye 2019-01-07 11:38:57 -08:00
parent 046141958a
commit 6455a56f30
3 changed files with 141 additions and 33 deletions

View File

@ -2346,6 +2346,7 @@ class A2PackPartitions
assembleCode("tileEngine", "src/tile/")
assembleCode("marks", "src/marks/")
assembleCode("gen_mapSpecials", "src/mapScripts/")
assembleCode("gen_mapExits", "src/mapScripts/")
code.each { k,v -> addResourceDep("map", "<root>", "code", k) }
@ -2447,15 +2448,43 @@ class A2PackPartitions
}
}
def genMapExits(data)
{
def exits = [:]
data.map.each { map ->
map.scripts.script.each { script ->
if (script?.@name.toLowerCase() =~ /exit/) {
script.locationTrigger.each { trig ->
if (!exits.containsKey(map.@name))
exits[map.@name] = []
assert trig.@x.toInteger() >= 0 && trig.@x.toInteger() <= 255 &&
trig.@y.toInteger() >= 0 && trig.@y.toInteger() <= 255 : "large maps can't have exits"
exits[map.@name].add([trig.@x.toInteger(), trig.@y.toInteger()])
}
}
}
}
new File("build/src/mapScripts/gen_mapexits.s.new").withWriter { out ->
out.println("; Generated code - DO NOT MODIFY BY HAND\n")
out.println("*=0 ; origin irrelevant")
exits.keySet().sort().each { mapName ->
assert mapNames.containsKey(mapName)
int mapNum = mapNames[mapName][1] | (mapNames[mapName][0] == '3D' ? 0x80 : 0)
out.println " !byte $mapNum, ${exits[mapName].size() * 2} ; map num, field size"
exits[mapName].each { coords ->
out.println " !byte ${coords[0]}, ${coords[1]} ; x, y"
}
}
out.println " !byte 0 ; end"
}
replaceIfDiff("build/src/mapScripts/gen_mapexits.s")
}
def genAutomapSpecials()
{
def scriptDir = "build/src/mapScripts/"
if (!new File(scriptDir).exists())
new File(scriptDir).mkdirs()
new File("build/src/mapScripts/gen_mapSpecials.plh.new").withWriter { out ->
out.println("// Generated code - DO NOT MODIFY BY HAND\n")
out.println("const automap_exitTileNum = $automapExitTile")
}
new File("build/src/mapScripts/gen_mapSpecials.s.new").withWriter { out ->
out.println("; Generated code - DO NOT MODIFY BY HAND\n")
out.println("*=0 ; origin irrelevant")
@ -2499,7 +2528,6 @@ class A2PackPartitions
out.println(" !byte \$FF; end of all maps")
}
replaceIfDiff("build/src/mapScripts/gen_mapSpecials.s")
replaceIfDiff("build/src/mapScripts/gen_mapSpecials.plh")
}
/*
@ -2789,6 +2817,9 @@ class A2PackPartitions
// Generate the automap-specials table
genAutomapSpecials()
// Figure out where all the exit scripts are (for quest go-to-map functionality)
genMapExits(dataIn)
// Read in code chunks. For now these are hard coded, but I guess they ought to
// be configured in a config file somewhere...?
//
@ -3985,7 +4016,6 @@ end
def totalSize = mapSizes.size() * 2
assert totalSize < 256 : "too many maps"
out.println("byte[] mapSizes = $totalSize // overall buffer size")
boolean first = true
mapSizes.sort().each { triple ->
out.println(String.format("byte = \$%02X, \$%02X",
(triple[0] == '3D' ? 0x80 : 0) | triple[1], triple[2]))

View File

@ -1092,11 +1092,6 @@ end
def _automap_show(targetX, targetY)#1
byte key
// FIXME FOO
word playerX, playerY
getPos(@playerX, @playerY)
targetX = playerX+1; targetY = playerY // FIXME - just for testing
// Clear out the blank tile buffer
memset(@blankTile, 0, 9)
@ -1117,16 +1112,6 @@ def _automap_show(targetX, targetY)#1
repeat
key = cursorWait(targetX, targetY)
when key
is 'I'; //FIXME FOO
targetY--; break
is 'K'; //FIXME FOO
targetX++; break
is 'M'; //FIXME FOO
targetY++; break
is 'J'; //FIXME FOO
targetX--; break
is 'W'; is 'I'; is 11
if screenY1-8 > 0
screenY0 = screenY0 - 8 // north

View File

@ -16,11 +16,12 @@ include "gen_items.plh"
include "gen_enemies.plh"
include "gen_modules.plh"
include "combat.plh"
include "automap.plh"
predef _showQuests()#1
word[] funcTbl = @_showQuests
word pQuestsModule
word pQuestsModule, pExitsBuf
byte nUnstarted, nActive, nDone
byte nTriggeredSteps, lastTriggered, nSteps
@ -34,12 +35,14 @@ word questMapY[2]
def loadExtraModules()#0
mmgr(START_LOAD, 1) // code is in partition 1
pQuestsModule = mmgr(QUEUE_LOAD, MOD_GEN_QUESTS<<8 | RES_TYPE_MODULE)
pExitsBuf = mmgr(QUEUE_LOAD, CODE_GEN_MAP_EXITS<<8 | RES_TYPE_CODE)
mmgr(FINISH_LOAD, 0)
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def unloadExtraModules()#0
mmgr(FREE_MEMORY, pQuestsModule)
mmgr(FREE_MEMORY, pExitsBuf)
end
///////////////////////////////////////////////////////////////////////////////////
@ -77,7 +80,8 @@ def displayCurQuest()#0
questMapNum[0] = 0
questMapNum[1] = 0
clearPortrait; useMapWindow; clearWindow
clearPortrait
useMapWindow // with clear
setWindow2; clearWindow
rawDisplayStr("^I^Y")
if displayMode == 'A'
@ -158,38 +162,127 @@ def showMenu()#0
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def _showQuests()#1
byte sel, needReInit, needRedisplay
// Locate the closest exit from the town the player is currently within
def findExit(lookFor)#1
word p, pNext
word x, y, tmp, dist, minDist
word playerX, playerY
byte found
needReInit = TRUE
getPos(@playerX, @playerY)
// Scan the list of exits
p = pExitsBuf
minDist = $7FFF
found = FALSE
while ^p
// Each entry is map number (+128 for 3D maps), then length of field
pNext = p + ^(p+1) + 2
if ^p == lookFor
p = p + 2
// Found the map we want. There follows a list of x/y pairs
while p < pNext
x = ^p
y = ^(p+1)
p = p + 2
// Calculate the distance (squared) from the player to the exit
tmp = abs(x - playerX)
dist = tmp*tmp
tmp = abs(y - playerY)
dist = dist + (tmp*tmp)
// Record the closest exit when we find it.
if dist >= 0 and dist < minDist // >= 0 check is in case of mult overflow
minDist = dist
questMapNum[0] = lookFor
questMapX[0] = x
questMapY[0] = y
found = TRUE
fin
loop
else
p = pNext
fin
loop
return found
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def showOnMap()#0
word automapModule
word playerX, playerY
byte lookFor
byte mapIdx
// If player isn't on either of the maps for this quest, direct them to the nearest exit
lookFor = mapNum + (mapIs3D ?? 128 :: 0)
if questMapNum[0] == lookFor
mapIdx = 0
elsif questMapNum[1] == lookFor
mapIdx = 1
else
if !findExit(lookFor)
clearWindow
setWindow2; clearWindow
rawDisplayStr("No route found.")
pause(800)
return
fin
mapIdx = 0
fin
// Load the automap code
mmgr(START_LOAD, 1) // code is in partition 1
automapModule = mmgr(QUEUE_LOAD, MOD_AUTOMAP<<8 | RES_TYPE_MODULE)
mmgr(FINISH_LOAD, 0)
// Show the position of this quest on the map
automapModule()=>automap_show(questMapX[mapIdx], questMapY[mapIdx])
// Free up memory from the automap module
mmgr(FREE_MEMORY, automapModule)
// Get the main frame image back
loadMainFrameImg()
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def _showQuests()#1
byte sel, needSetup, needRedisplay
needSetup = TRUE
while TRUE
if needReInit
// Setup
// Setup (or re-setup after returning from show-on-map)
if needSetup
showMapName("Quest Log")
setWindow2; clearWindow
setWindow3; clearWindow
useMapWindow; clearWindow
useMapWindow // with clear
loadExtraModules
displayMode = 'A'
curQuestNum = 0
needRedisplay = TRUE
needReInit = FALSE // because it's done now
needRedisplay = TRUE // display after init
needSetup = FALSE // because it's done now
fin
// Display after selecting new quest or mode
if needRedisplay
countQuests // also sets current quest
displayCurQuest
showMenu
needRedisplay = FALSE
fin
sel = getUpperKey
when sel
is 'S'
// Show on map
if questMapNum[0] or questMapNum[1]
//showOnMap // FIXME TODO
needReInit = TRUE
showOnMap
needSetup = TRUE
else
beep
fin