% -------------- TURING WARS.T % Declare the unit type type units : record name, unitType, targetType : string typeNum, attack, defense, attackRng, moveRng, los, currentHP, totalHP, locX, locY, team : int end record type point : record x, y, parentX, parentY : int end record % Declare the unit properties var unitNames : array 1 .. 3 of string := init ("Infantry", "Tank", "Artilery") var unitGraphics : array 1 .. 3 of string := init ("I", "T", "A") % Just strings for now. Pictures later :) var unitTypes : array 1 .. 3 of string := init ("ground,light", "ground,med", "ground,moveCountd") var unitTargets : array 1 .. 3 of string := init ("ground,lowair", "ground", "ground,sea") var unitAttackVals : array 1 .. 3 of int := init (1, 3, 3) var unitDefVals : array 1 .. 3 of int := init (1, 3, 2) var unitAttackRng : array 1 .. 3 of int := init (1, 1, 3) var unitMoveRng : array 1 .. 3 of int := init (1, 3, 2) var unitHP : array 1 .. 3 of int := init (5, 15, 10) var unitLOS : array 1 .. 3 of int := init (2, 3, 4) % Fonts, pictures, etc. var verdana := Font.New ("verdana:10") var verdanaBold := Font.New ("verdana:12:bold") % Declare the terrain constants const CITY := 1 const GRASS := 2 const FOREST := 3 const MOUNTAIN := 4 const ROAD := 5 const SHALLOW := 6 const WATER := 7 const SHORE := 8 var movementCosts : array 1 .. 8 of real := init (1.5, 1, 2, 3, 0.5, 1, 1.5, 1) var terrainTypes : array 1 .. 8 of int := init (42, 48, 2, 66, 15, 53, 55, 91) var unitLocations : array 1 .. 40, 1 .. 40 of boolean % The array whether a space has a unit in it var unitData : flexible array 1 .. 1 of units % The actual unit data var unitToAdd : int := 1 var map : array 1 .. 40, 1 .. 40 of int var mx, my, mb, terrType : int := 1 var isHuman : boolean := true var tileSize := (maxx - 250) div 13 var scrollX, scrollY : int := 0 var chars : array char of boolean var possibleMovePoints : flexible array 1 .. 1 of point var possibleAttackPoints : flexible array 1 .. 1 of point var expandedPoint : array 1 .. 40, 1 .. 40 of boolean var showingMoveTiles : boolean := false View.Set ("graphics:" + intstr (tileSize * 18 + 300) + "," + intstr (tileSize * 13 + 200) + ";position:10,100;nobuttonbar") var screenX := tileSize * 18 + 220 var screenY := tileSize * 13 + 200 % ********************* COMMON PROCEDURES AND FUNCTIONS ************************* var addTerr : boolean := false function pixToGridX (mx : int) : int % -> The next 4 were done by both result (mx - 100) div tileSize end pixToGridX function pixToGridY (my : int) : int result (my - 100) div tileSize end pixToGridY function gridToPixX (gridX : int) : int result 100 + gridX * tileSize end gridToPixX function gridToPixY (gridY : int) : int result 100 + gridY * tileSize end gridToPixY function findCharInString (word : string, character : string (1)) : int % -> Josh for i : 1 .. length (word) if word (i) = character then result i end if end for result 0 end findCharInString function isPassable (gridX, gridY : int) : boolean var terrtype : int if gridX > 0 and gridY > 0 and gridX <= 40 and gridY <= 40 then terrtype := map (gridX, gridY) if terrtype = SHALLOW or terrtype = WATER then result false else result true end if else result false end if end isPassable proc updateTile (tileX, tileY, terrType : int) % -> Josh drawfillbox (100 + tileX * tileSize, 100 + tileY * tileSize, 100 + tileSize + tileX * tileSize, 100 + tileSize + tileY * tileSize, terrainTypes (map (scrollX + tileX, scrollY + tileY))) end updateTile proc refreshUnit (unitType, x, y, side : int) var diffX, diffY, col : int if side = 0 then col := red else col := blue end if if x > scrollX and y > scrollY and x < scrollX + 19 and y < scrollY + 14 then diffX := x - scrollX diffY := y - scrollY locate (5, 1) drawfillbox (gridToPixX (diffX) + (tileSize div 5), gridToPixY (diffY) + (tileSize div 5), gridToPixX (diffX) + tileSize - (tileSize div 5), gridToPixY (diffY) + tileSize - (tileSize div 5), col) Font.Draw (unitGraphics (unitType), gridToPixX (diffX) + (tileSize div 4), gridToPixY (diffY) + (tileSize div 3), verdanaBold, white) end if end refreshUnit proc newUnit (unitType, x, y : int, side : boolean) var temp : int new unitData, upper (unitData) + 1 temp := upper (unitData) unitData (temp).typeNum := unitType if side = true then unitData (temp).team := 0 else unitData (temp).team := 1 end if unitData (temp).name := unitNames (unitType) unitData (temp).unitType := unitTypes (unitType) unitData (temp).targetType := unitTargets (unitType) unitData (temp).attack := unitAttackVals (unitType) unitData (temp).defense := unitDefVals (unitType) unitData (temp).attackRng := unitAttackRng (unitType) unitData (temp).moveRng := unitMoveRng (unitType) unitData (temp).los := unitLOS (unitType) unitData (temp).totalHP := 10 unitData (temp).currentHP := unitHP (unitType) unitData (temp).locX := x unitData (temp).locY := y unitLocations (x, y) := true refreshUnit (unitData (temp).typeNum, unitData (temp).locX, unitData (temp).locY, unitData (temp).team) end newUnit proc drawMinimap drawbox (15, screenY - 140, 97, screenY - 59, black) for i : 1 .. 40 for j : 1 .. 40 drawfillbox (14 + i * 2, screenY - 141 + j * 2, 16 + i * 2, screenY - 140 + j * 2, terrainTypes (map (i, j))) end for end for drawbox (16 + scrollX * 2, screenY - 139 + scrollY * 2, 52 + scrollX * 2, screenY - 114 + scrollY * 2, white) end drawMinimap function unitQuery (x, y : int) : int for i : 2 .. upper (unitData) if unitData (i).locX = x and unitData (i).locY = y then result i end if end for result 0 end unitQuery function findCombinations (x, y, arrayStart : int) : int var temp : int if x - 1 >= 1 and isPassable (x - 1, y) and unitLocations (x - 1, y) = false then new possibleMovePoints, upper (possibleMovePoints) + 1 temp := upper (possibleMovePoints) possibleMovePoints (temp).x := x - 1 possibleMovePoints (temp).y := y possibleMovePoints (temp).parentX := x possibleMovePoints (temp).parentY := y end if if x + 1 <= 40 and isPassable (x + 1, y) and unitLocations (x + 1, y) = false then new possibleMovePoints, upper (possibleMovePoints) + 1 temp := upper (possibleMovePoints) possibleMovePoints (temp).x := x + 1 possibleMovePoints (temp).y := y possibleMovePoints (temp).parentX := x possibleMovePoints (temp).parentY := y end if if x >= 1 and y - 1 >= 1 and x <= 40 and isPassable (x, y - 1) and unitLocations (x, y - 1) = false then new possibleMovePoints, upper (possibleMovePoints) + 1 temp := upper (possibleMovePoints) possibleMovePoints (temp).x := x possibleMovePoints (temp).y := y - 1 possibleMovePoints (temp).parentX := x possibleMovePoints (temp).parentY := y end if if x >= 1 and y + 1 <= 40 and x <= 40 and isPassable (x, y + 1) and unitLocations (x, y + 1) = false then new possibleMovePoints, upper (possibleMovePoints) + 1 temp := upper (possibleMovePoints) possibleMovePoints (temp).x := x possibleMovePoints (temp).y := y + 1 possibleMovePoints (temp).parentX := x possibleMovePoints (temp).parentY := y end if result upper (possibleMovePoints) - arrayStart end findCombinations function findAttackCombinations (x, y, arrayStart : int) : int var temp : int if x - 1 >= 1 and isPassable (x - 1, y) then new possibleAttackPoints, upper (possibleAttackPoints) + 1 temp := upper (possibleAttackPoints) possibleAttackPoints (temp).x := x - 1 possibleAttackPoints (temp).y := y possibleAttackPoints (temp).parentX := x possibleAttackPoints (temp).parentY := y end if if x + 1 <= 40 and isPassable (x + 1, y) then new possibleAttackPoints, upper (possibleAttackPoints) + 1 temp := upper (possibleAttackPoints) possibleAttackPoints (temp).x := x + 1 possibleAttackPoints (temp).y := y possibleAttackPoints (temp).parentX := x possibleAttackPoints (temp).parentY := y end if if x >= 1 and y - 1 >= 1 and x <= 40 and isPassable (x, y - 1) then new possibleAttackPoints, upper (possibleAttackPoints) + 1 temp := upper (possibleAttackPoints) possibleAttackPoints (temp).x := x possibleAttackPoints (temp).y := y - 1 possibleAttackPoints (temp).parentX := x possibleAttackPoints (temp).parentY := y end if if x >= 1 and y + 1 <= 40 and x <= 40 and isPassable (x, y + 1) then new possibleAttackPoints, upper (possibleAttackPoints) + 1 temp := upper (possibleAttackPoints) possibleAttackPoints (temp).x := x possibleAttackPoints (temp).y := y + 1 possibleAttackPoints (temp).parentX := x possibleAttackPoints (temp).parentY := y end if result upper (possibleAttackPoints) - arrayStart end findAttackCombinations proc findPossibleMoves (x, y, moveCount : int) % Use some of the principles of pathfinding to find the possible squares a unit can move to. var costs : array 1 .. 40, 1 .. 40 of real var diffX, diffY : int var movesLeft : real := moveCount var numNodes, nodeFirst, nodeLast, nodeNextLast : int := 0 var nodeX, nodeY, retVal : int var costToAdd : real := 0 possibleMovePoints (1).x := x possibleMovePoints (1).y := y possibleMovePoints (1).parentX := x possibleMovePoints (1).parentY := y % Reset the values numNodes := 0 for i : 1 .. 40 for j : 1 .. 40 costs (i, j) := 0 end for end for new possibleMovePoints, 1 nodeFirst := 1 nodeLast := findCombinations (x, y, numNodes) for i : 1 .. (moveCount) nodeNextLast += 1 for a : nodeFirst .. nodeLast if possibleMovePoints (a).parentX not= -2 then costToAdd := costs (possibleMovePoints (a).parentX, possibleMovePoints (a).parentY) % Store nodeX and nodeY values for speed nodeX := possibleMovePoints (a).x nodeY := possibleMovePoints (a).y if nodeX >= 1 and nodeY >= 1 then if a > 1 then costs (nodeX, nodeY) := movementCosts (map (nodeX, nodeY)) + costToAdd end if if round (costs (nodeX, nodeY)) >= moveCount + 3 then % Kill off the node possibleMovePoints (a).x := -2 possibleMovePoints (a).y := -2 else % Find the next 4 nodes retVal := findCombinations (possibleMovePoints (a).x, possibleMovePoints (a).y, nodeNextLast) nodeNextLast := nodeNextLast + round (retVal) if nodeX > scrollX and nodeY > scrollY and nodeX < scrollX + 19 and nodeY < scrollY + 14 then diffX := nodeX - scrollX diffY := nodeY - scrollY drawbox (gridToPixX (diffX), gridToPixY (diffY), gridToPixX (diffX) + tileSize, gridToPixY (diffY) + tileSize, black) end if nodeFirst += 1 nodeLast := nodeNextLast end if else nodeFirst += 1 nodeLast := nodeNextLast end if end if end for end for showingMoveTiles := true end findPossibleMoves proc findPossibleAttacks (x, y, attackRange : int) % Use some of the principles of pathfinding to find the possible squares a unit can move to. var costs : array 1 .. 40, 1 .. 40 of real var diffX, diffY : int var numAttackNodes, attackNodeFirst, attackNodeLast, attackNodeNextLast : int := 0 var nodeX, nodeY, retVal : int var count : int := 0 possibleAttackPoints (1).x := x possibleAttackPoints (1).y := y possibleAttackPoints (1).parentX := x possibleAttackPoints (1).parentY := y new possibleAttackPoints, 1 % Reset the values numAttackNodes := 0 for i : 1 .. 40 for j : 1 .. 40 costs (i, j) := 0 end for end for attackNodeFirst := 1 attackNodeLast := findAttackCombinations (x, y, numAttackNodes) for i : 1 .. (attackRange) attackNodeNextLast += 1 for a : attackNodeFirst .. attackNodeLast if possibleAttackPoints (a).parentX not= -2 then % Store nodeX and nodeY values for speed nodeX := possibleAttackPoints (a).x nodeY := possibleAttackPoints (a).y if nodeX >= 1 and nodeY >= 1 then if a > 1 then costs (nodeX, nodeY) := costs (possibleAttackPoints (a).parentX, possibleAttackPoints (a).y) + 1 end if if count >= attackRange + 1 then % Kill off the node possibleAttackPoints (a).x := -2 possibleAttackPoints (a).y := -2 else % Find the next 4 nodes retVal := findAttackCombinations (possibleAttackPoints (a).x, possibleAttackPoints (a).y, attackNodeNextLast) attackNodeNextLast := attackNodeNextLast + round (retVal) if nodeX > scrollX and nodeY > scrollY and nodeX < scrollX + 19 and nodeY < scrollY + 14 and unitLocations (nodeX, nodeY) and unitData (unitQuery (nodeX, nodeY)).team = 1 then diffX := nodeX - scrollX diffY := nodeY - scrollY drawfillbox (gridToPixX (diffX), gridToPixY (diffY), gridToPixX (diffX) + tileSize, gridToPixY (diffY) + tileSize, red) end if attackNodeFirst += 1 attackNodeLast := attackNodeNextLast end if else attackNodeFirst += 1 attackNodeLast := attackNodeNextLast end if end if end for end for showingMoveTiles := true end findPossibleAttacks function isValidMove (x, y : int) : boolean for i : 1 .. upper (possibleMovePoints) if possibleMovePoints (i).x = x and possibleMovePoints (i).y = y then result true end if end for result false end isValidMove % Back proc drawMap (minX, minY : int) % -> Josh for i : 1 .. 18 for j : 1 .. 13 drawfillbox (100 + i * tileSize, 100 + j * tileSize, 100 + i * tileSize + tileSize, 100 + j * tileSize + tileSize, terrainTypes (map (minX + i, minY + j))) end for end for View.Update end drawMap proc initializeMap % -> Josh for i : 1 .. 40 for j : 1 .. 40 map (i, j) := 2 unitLocations (i, j) := false expandedPoint (i, j) := false end for end for drawMap (0, 0) end initializeMap proc changeAllMap (terrType : int) for i : 1 .. 40 for j : 1 .. 40 map (i, j) := terrType end for end for drawMap (0, 0) end changeAllMap proc refreshAllUnits % Update the unit pictures for i : 2 .. upper (unitData) refreshUnit (unitData (i).typeNum, unitData (i).locX, unitData (i).locY, unitData (i).team) end for end refreshAllUnits proc scrollMap % If an arrow key is pressed, move the scrollable map Input.KeyDown (chars) if chars (KEY_UP_ARROW) and scrollY < 27 then scrollY += 1 drawMap (scrollX, scrollY) refreshAllUnits drawMinimap elsif chars (KEY_DOWN_ARROW) and scrollY > 0 then scrollY -= 1 drawMap (scrollX, scrollY) refreshAllUnits drawMinimap elsif chars (KEY_RIGHT_ARROW) and scrollX < 22 then scrollX += 1 drawMap (scrollX, scrollY) refreshAllUnits drawMinimap elsif chars (KEY_LEFT_ARROW) and scrollX > 0 then scrollX -= 1 drawMap (scrollX, scrollY) refreshAllUnits drawMinimap end if end scrollMap % ********************* GUI FUNCTIONS AND PROCEDURES ******************************** proc updateLeftDisp (displayType : string, num : int) if displayType = "unit" then Font.Draw ("Unit Name: " + unitData (num).name, screenX - 70, screenY - 40, verdana, black) Font.Draw ("Attack: " + intstr (unitData (num).attack), screenX - 70, screenY - 55, verdana, black) Font.Draw ("Defense: " + intstr (unitData (num).defense), screenX - 70, screenY - 70, verdana, black) Font.Draw ("Movement Range: " + intstr (unitData (num).moveRng), screenX - 70, screenY - 85, verdana, black) unitData (num).currentHP := 10 Font.Draw ("HP: " + intstr (unitData (num).currentHP) + "/" + intstr (unitData (num).totalHP), screenX - 50, screenY - 100, verdana, black) drawbox (screenX - 60, screenY - 115, screenX + 30, screenY - 105, black) drawfillbox (screenX - 59, screenY - 114, (screenX - 59) + unitData (num).currentHP div 10 * 88, screenY - 106, blue) elsif displayType = "clear" then drawfillbox (screenX - 80, 0, maxx, maxy, grey) end if end updateLeftDisp % ********************* MAP EDITOR PROCEDURES AND FUNCTIONS ************************* proc changeTerrType (x, y, terrType : int) map (x, y) := terrType end changeTerrType proc saveMap var filename : string := "" var output : int locate (3, 1) put "Enter a name: " .. get filename open : output, "maps\\" + filename + ".map", put for i : 1 .. 40 for j : 1 .. 40 put : output, map (i, j), " " .. end for end for put "" for i : 2 .. upper (unitData) put : output, unitData (i).team, unitData (i).typeNum, ",", unitData (i).locX, ",", unitData (i).locY end for close : output locate (1, 1) put "Map Saving Completed." end saveMap proc loadMap var filename : string := "" var input : int var Char : string (1) var character : string var temp, temp2, unitX, unitY, side : int := 0 var onHuman : boolean := false locate (3, 1) put "Enter a name: " .. get filename open : input, "maps\\" + filename + ".map", get if Error.Last = eNoError then for i : 1 .. 40 for j : 1 .. 40 get : input, Char if strintok (Char) = false and Char not= " " then put "Data file corrupted! Tile (", i, ",", j, ") returned to Default Type" elsif strintok (Char) then map (i, j) := strint (Char) end if end for end for drawMap (0, 0) if eof (input) then return end if loop get : input, character : * if length (character) > 4 and strintok (character (1)) then % Evil little region of code, took me 20min! side := strint (character (1)) if side = 0 then onHuman := true else onHuman := false end if temp := findCharInString (character, ",") temp2 := temp + findCharInString (character (temp + 1 .. *), ",") unitX := strint (character (temp + 1 .. temp2 - 1)) unitY := strint (character (temp2 + 1 .. *)) if strintok (character (1)) then newUnit (strint (character (2)), unitX, unitY, onHuman) else put "Data file corrupted, unit ignored" end if end if exit when eof (input) end loop close : input else locate (1, 1) put "File not Found." end if end loadMap proc exitEditor return end exitEditor proc initializeEditor % The Save Button drawbox (50, 250, 100, 275, black) drawfill (51, 251, red, black) Font.Draw ("SAVE", 58, 258, verdana, white) % The Load Button drawbox (50, 280, 100, 305, black) drawfill (51, 281, red, black) Font.Draw ("LOAD", 58, 288, verdana, white) % The New Button drawbox (50, 310, 100, 335, black) drawfill (51, 311, red, black) Font.Draw ("NEW", 58, 318, verdana, white) % The Fill Button drawbox (50, 340, 100, 365, black) drawfill (51, 341, red, black) Font.Draw ("FILL", 58, 348, verdana, white) var unitnames : array 1 .. 3 of string := init ("Inf.", "Tank", "Art.") Draw.Text ("Units", 125, 90, verdana, black) drawbox (65, 75, 95, 100, black) drawfill (66, 76, red, black) drawbox (65, 30, 95, 55, black) drawfill (66, 31, blue, black) for u : 1 .. 3 drawbox (130 + (u * 35), 55, 155 + (u * 35), 80, black) Draw.Text (unitnames (u), 130 + (u * 35), 40, verdana, black) end for % This first bit was done by Mike. Following done by Josh, with help from Mike for i : 1 .. 2 for j : 1 .. 4 if i = 1 then drawfillbox (25 + (i * 25), 100 + (j * 25), 50 + (i * 25), 125 + (j * 25), terrainTypes (j)) else drawfillbox (25 + (i * 25), 100 + (j * 25), 50 + (i * 25), 125 + (j * 25), terrainTypes (4 + j)) end if end for end for end initializeEditor proc mapEditor % Created by both initializeMap initializeEditor drawMap (0, 0) drawMinimap View.Set ("offscreenonly") loop mousewhere (mx, my, mb) if isHuman = true then drawbox (64, 29, 96, 56, white) drawbox (64, 74, 96, 101, green) else drawbox (64, 74, 96, 101, white) drawbox (64, 29, 96, 56, green) end if scrollMap if mx >= 65 and mx <= 95 then if my >= 75 and my <= 100 and mb = 1 then isHuman := true elsif my >= 30 and my <= 55 and mb = 1 then isHuman := false end if end if % Choose units to add if my > 54 and my < 80 and mb = 1 then if mx > 165 and mx < 190 then unitToAdd := 1 addTerr := false elsif mx > 200 and mx < 225 then unitToAdd := 2 addTerr := false elsif mx > 235 and mx < 260 then unitToAdd := 3 addTerr := false end if end if % Add New Units to the Map if mx > 100 + (tileSize) and my > 100 + (tileSize) and mx < 100 + (tileSize * 19) and my < 100 + (tileSize * 14) and mb = 1 then if unitLocations (scrollX + pixToGridX (mx), scrollY + pixToGridY (my)) = false and isPassable (scrollX + pixToGridX (mx), scrollY + pixToGridY (my)) and addTerr = false then newUnit (unitToAdd, scrollX + pixToGridX (mx), scrollY + pixToGridY (my), isHuman) delay (100) end if end if % Choose the terrain type to add if mx > 50 and my > 125 and mx < 100 and my < 224 and mb = 1 then if mx < 75 then terrType := 1 + (my - 125) div 25 addTerr := true else terrType := 5 + ((my - 125) div 25) addTerr := true end if end if if mx > 100 + (tileSize) and my > 100 + (tileSize) and mx < 100 + (tileSize * 19) and my < 100 + (tileSize * 14) and mb = 1 and addTerr = true then changeTerrType (scrollX + pixToGridX (mx), scrollY + pixToGridY (my), terrType) updateTile (pixToGridX (mx), pixToGridY (my), map (scrollX + pixToGridX (mx), scrollY + pixToGridY (my))) drawMinimap end if if mx > 50 and my > 250 and mx < 100 and my < 275 and mb = 1 then saveMap elsif mx > 50 and my > 280 and mx < 100 and my < 305 and mb = 1 then loadMap drawMinimap elsif mx > 50 and my > 310 and mx < 100 and my < 335 and mb = 1 then % New Map new unitData, 1 % Eliminate the other elements in the unitData array initializeMap drawMap (0, 0) drawMinimap elsif mx > 50 and my > 340 and mx < 100 and my < 365 and mb = 1 then changeAllMap (terrType) drawMinimap end if % Update display % if addTerr = false then % if unitToAdd = 1 then % put "INFANTRY " .. % elsif unitToAdd = 2 then % put "TANKS " .. % elsif unitToAdd = 3 then % put "ARTILLERY " .. % end if % elsif addTerr = true then % if terrType = 1 then % put "CITY " .. % elsif terrType = 2 then % put "GRASS " .. % elsif terrType = 3 then % put "FOREST " .. % elsif terrType = 4 then % put "MOUNTAIN " .. % elsif terrType = 5 then % put "ROAD " .. % elsif terrType = 6 then % put "SHALLOWS " .. % elsif terrType = 7 then % put "WATER " .. % elsif terrType = 8 then % put "SAND " .. % end if % end if View.Update end loop end mapEditor proc playGame var unitNum : int initializeMap loadMap View.Set ("offscreenonly") % Draw the GUI drawfillbox (screenX - 80, 0, maxx, maxy, grey) drawfillbox (0, 0, 135, maxy, grey) drawfillbox (0, 0, maxx, 135, grey) drawMinimap View.Update loop mousewhere (mx, my, mb) scrollMap if mb = 1 then if unitQuery (scrollX + pixToGridX (mx), scrollY + pixToGridY (my)) > 0 then unitNum := unitQuery (scrollX + pixToGridX (mx), scrollY + pixToGridY (my)) updateLeftDisp ("clear", 0) updateLeftDisp ("unit", unitQuery (scrollX + pixToGridX (mx), scrollY + pixToGridY (my))) if unitData (unitNum).team = 0 then findPossibleMoves (scrollX + pixToGridX (mx), scrollY + pixToGridY (my), unitData (unitNum).moveRng) findPossibleAttacks (scrollX + pixToGridX (mx), scrollY + pixToGridY (my), unitData (unitNum).attackRng) end if elsif showingMoveTiles and isValidMove (scrollX + pixToGridX (mx), scrollY + pixToGridY (my)) and unitData (unitNum).team = 0 then unitLocations (unitData (unitNum).locX, unitData (unitNum).locY) := false unitData (unitNum).locX := scrollX + pixToGridX (mx) unitData (unitNum).locY := scrollY + pixToGridY (my) refreshUnit (unitData (unitNum).typeNum, unitData (unitNum).locX, unitData (unitNum).locY, unitData (unitNum).team) drawMap (scrollX, scrollY) refreshAllUnits showingMoveTiles := false delay (75) elsif showingMoveTiles and isValidMove (scrollX + pixToGridX (mx), scrollY + pixToGridY (my)) = false then drawMap (scrollX, scrollY) refreshAllUnits else updateLeftDisp ("clear", 0) end if end if View.Update end loop end playGame playGame