% -------------- 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 : 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 - 150) div 13 var scrollX, scrollY : int := 0 var chars : array char of boolean var isExplored : array 1 .. 40, 1 .. 40 of boolean View.Set ("graphics:" + intstr (tileSize * 18 + 300) + "," + intstr (tileSize * 13 + 200) + ";position:10,100;nobuttonbar;offscreenonly") var screenX := tileSize * 18 + 220 var screenY := tileSize * 13 + 200 proc initializeMap % -> Josh for i : 1 .. 40 for j : 1 .. 40 map (i, j) := 2 unitLocations (i, j) := false isExplored (i, j) := false end for end for end initializeMap initializeMap % ********************* 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 terrtype := map (gridX, gridY) if terrtype = SHALLOW or terrtype = WATER then result false else result true 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 + 18 and y < scrollY + 13 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, 101, screenY - 59, black) for i : 1 .. 40 for j : 1 .. 40 drawfillbox (14 + i * 2, screenY - 141 + j * 2, 20 + i * 2, screenY - 140 + j * 2, terrainTypes (map (i, j))) end for end for drawbox (16 + scrollX * 2, screenY - 139 + scrollY * 2, 56 + 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 proc findPossibleMoves (x, y, moveCount : int) var diffX, diffY : int var movesLeft : real := moveCount diffX := x - scrollX diffY := y - scrollY end findPossibleMoves % 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 end drawMap 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 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) 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 changeTerrType (x, y, terrType : int) map (x, y) := terrType end changeTerrType proc saveMap var filename : string := "" var output : int locate (1, 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 (1, 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) loop get : input, character : * if length (character) > 4 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 mapEditor % Created by both initializeMap initializeEditor drawMap (0, 0) drawMinimap loop mousewhere (mx, my, mb) locate (1, 1) put mx, " ", my .. locate (2, 1) if isHuman = true then put "RED TEAM (Human)" .. else put "BLUE TEAM (Computer)" .. end if 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 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 % Draw the GUI drawfillbox (screenX - 80, 0, maxx, maxy, grey) drawfillbox (0, 0, 135, maxy, grey) drawfillbox (0, 0, maxx, 135, grey) drawMinimap 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 ("unit", unitQuery (scrollX + pixToGridX (mx), scrollY + pixToGridY (my))) findPossibleMoves (scrollX + pixToGridX (mx), scrollY + pixToGridY (my), unitData (unitNum).moveRng) else updateLeftDisp ("clear", 0) end if end if View.Update delay (100) end loop end playGame playGame