% -------------- 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