Progress on group selection in combat.

This commit is contained in:
Martin Haye 2019-12-04 10:12:43 -08:00
parent 2043deeb70
commit 386494b8db

View File

@ -44,6 +44,7 @@ byte nPartyFighting
byte nPlayersFighting
byte nEnemiesFighting
byte isFleeing
byte isAdvancing
//combatDebug// byte combatDebug
byte[] S_AN = "an "
@ -58,7 +59,6 @@ word pItemUtil
const MAX_GROUPS = 3
byte nEnemyGroups
byte isAdvancing
///////////////////////////////////////////////////////////////////////////////////////////////////
def preload()#0
@ -123,12 +123,12 @@ def combatPause()#0
pause(global=>w_combatPauseCt)
// Check for speed-up / slow-down
key = ^kbd
if key == (11 + 128) or key == ('-'+128) // up-arrow or minus
if !recordMode; ^kbdStrobe; fin
key = ^kbd & $7F
if key == 11 or key == '-' // up-arrow or minus
^kbdStrobe
global=>w_combatPauseCt = max(100, global=>w_combatPauseCt - addPercent(global=>w_combatPauseCt, 20))
elsif key == (10 + 128) or key == ('+'+128) // down-arrow or plus
if !recordMode; ^kbdStrobe; fin
elsif key == 10 or key == '+' // down-arrow or plus
^kbdStrobe
global=>w_combatPauseCt = min(9999, global=>w_combatPauseCt + addPercent(global=>w_combatPauseCt, 20))
fin
end
@ -380,29 +380,44 @@ def playerDodge(pPlayer)#0
// no need to display anything. Actual dodging mechanics handled in enemy attack function.
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def groupCanFight(p)#1
return first(p=>p_enemies, @canFight)
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def formatGroupName(p, withDist)#1
byte count
count = sum(p=>p_enemies, NULL, @canFight)
isPlural = count <> 1
if (p=>p_enemies=>r_groupSize == 0)
if withDist
return sprintf2("%s at %d'", p=>p_enemies=>s_name, p=>p_enemies->b_enemyAttackRange)
else
return sprintf1("%s", p=>p_enemies=>s_name)
fin
fin
if withDist
return sprintf3("%d %s at %d'", count, p=>p_enemies=>s_name, p=>p_enemies->b_enemyAttackRange)
fin
return sprintf2("%d %s", count, p=>p_enemies=>s_name)
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def displayOpponents()#0
word p
byte count, firstTime
byte firstTime
displayStr("You face ")
firstTime = TRUE
p = global=>p_enemyGroups
while p
if groupCanFight(p)
if !firstTime
if p=>p_nextObj
displayStr(", ")
else
displayStr(" and ")
fin
displayStr(p=>p_nextObj ?? ", " :: " and ")
fin
firstTime = FALSE
count = sum(p=>p_enemies, NULL, @canFight)
isPlural = count <> 1
if (p=>p_enemies=>r_groupSize == 0)
displayf2("%s at %d'", p=>p_enemies=>s_name, p=>p_enemies->b_enemyAttackRange)
else
displayf3("%d %s at %d'", count, p=>p_enemies=>s_name, p=>p_enemies->b_enemyAttackRange)
displayStr(formatGroupName(p, TRUE))
fin
p = p=>p_nextObj
loop
@ -414,7 +429,7 @@ def displayOption(key, str)#0
rawDisplayStr("\n (")
displayChar(key)
rawDisplayStr(")^T028")
rawDisplayStr(str)
displayStr(str)
end
///////////////////////////////////////////////////////////////////////////////////////////////////
@ -425,7 +440,7 @@ def minEnemyDist()#1
// Process each group
p = global=>p_enemyGroups
while p
if first(p=>p_enemies, @canFight)
if groupCanFight(p)
minDist = min(minDist, p=>p_enemies->b_enemyAttackRange)
fin
p = p=>p_nextObj
@ -433,6 +448,71 @@ def minEnemyDist()#1
return minDist
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def noneInRange()#1
rawDisplayStr("^D") // clear to end of page
displayStr("No enemy in range.")
combatPause
return FALSE
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Phase 0: count alive & in-range gangs
// Phase 1: display gangs
// Phase 2: select gang by number, return enemyNum
def groupLoop(minDist, phase, choiceNum)#1
word p
byte n
p = global=>p_enemyGroups
n = 0
while p
if p=>p_enemies->b_enemyAttackRange <= minDist and groupCanFight(p)
if phase == 1
displayOption(n + 'A', formatGroupName(p, FALSE))
elsif phase == 2 and n == choiceNum
return p->b_enemyNum
fin
n++
fin
p = p=>p_nextObj
loop
return n
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def chooseGroup(pl, minDist)#1
word p
byte nAvailGroups, choiceNum
// First, determine how many groups are alive and within striking distance
nAvailGroups = groupLoop(minDist, 0, 0)
// If nobody in range, ack!
if !nAvailGroups; return noneInRange(); fin
// If only one group, the choice is trivially obvious.
if nAvailGroups == 1
choiceNum = 0
else
rawDisplayf1("^D%s attack:", pl=>s_name) // ctrl-D = clear to end of page
groupLoop(minDist, 1, 0)
while TRUE
choiceNum = getUpperKey()
if choiceNum == $1B // esc
return FALSE
fin
choiceNum = choiceNum - 'A'
if choiceNum >= 0 and choiceNum < nAvailGroups; break; fin
beep()
loop
fin
// Success.
pl->b_gangChoice = groupLoop(minDist, 2, choiceNum)
return TRUE
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Determine number of shots. Only gets called for projectile attack
def chooseShotNumber(pl, pWeapon)#0
@ -452,7 +532,7 @@ def chooseShotNumber(pl, pWeapon)#0
if nChoices <= 1; return; fin
// Let player choose
rawDisplayf1("^D%s shoot:", pl=>s_name) // ctrl-D = clear to end of page
rawDisplayf1("^D%s shot type:", pl=>s_name) // ctrl-D = clear to end of page
if pWeapon->ba_attacks[0]; displayOption('O', "One shot"); fin
if pWeapon->ba_attacks[1] == 2
displayOption('D', "Double-shot")
@ -530,7 +610,7 @@ end
def playerCombatChoose(pl)#0
word p, pWeapon
byte key
byte canShoot, canReload, canChange, canAdvance
byte canShoot, canReload, canChange, canAdvance, redisplayMenu
word cursX, cursY
// The party advances all at once
@ -560,7 +640,13 @@ def playerCombatChoose(pl)#0
p = p=>p_nextObj
loop
redisplayMenu = TRUE
// Loop until a valid option is chosen
while TRUE
// Let them know their options
if redisplayMenu
setCursor(cursX, cursY)
rawDisplayStr("^D") // clear to end of page
displayf1("%s:\nM)elee, ", pl=>s_name)
@ -590,11 +676,17 @@ def playerCombatChoose(pl)#0
if canAdvance; displayStr("A)dvance, "); fin
displayStr("F)lee")
setCursor(cursX, cursY)
fin
while TRUE
pl->b_combatChoice = getUpperKey()
redisplayMenu = FALSE
when pl->b_combatChoice
is 'M'
if !chooseGroup(pl, 5)
redisplayMenu = TRUE
break
fin
setCursor(cursX, cursY)
return
is 'F'
isFleeing = TRUE
@ -603,6 +695,11 @@ def playerCombatChoose(pl)#0
return
is 'S'
if canShoot
if !chooseGroup(pl, pWeapon->b_weaponRange)
redisplayMenu = TRUE
break
fin
setCursor(cursX, cursY)
chooseShotNumber(pl, pWeapon)
setCursor(cursX, cursY)
return
@ -638,7 +735,7 @@ def playerCombatChoose(pl)#0
fin
return
wend
beep()
if !redisplayMenu; beep(); fin
loop
end