|################################################### # This is the core file for the GRIDMAP packages! # # This file holds the basic classes that are # # required for anything based on the GRIDMAP # # framework to function. # # # # by Richard Halstead # # last modified 3/26/2005 # ###################################################| ||defines all the types of land a MapSquare could have {define-enum Terrain land = "land", water = "deep water", shore = "shallow and deep water", port = "deep water only" } ||defines a location on a gridmap {define-class public Location field x:int field y:int {constructor public {default x:int, y:int} set self.x = x set self.y = y } {method public {make-graphic}:String ||-- {return {HBox self.x, ", ", self.y}} {return {format "%s, %s", self.x, self.y}} } {method public {equals other:Location}:bool {if self.x == other.x and self.y == other.y then {return true} else {return false} } } } ||usually attached to Entities; denotes something with which the user can interact. {define-class public abstract Active {getter abstract {control}:Control} } ||defines a map, inside of which all things will happen {define-class public abstract Map field grid:{Array-2-of MapSquare} field public players:{Array-of Player} field upperleft:Location = {Location 0, 0} field current-player:int = 0 {constructor {default rows:int, cols:int, players:int} set self.grid = {new {Array-2-of MapSquare}, rows, cols} set self.players = {new {Array-of Player}, efficient-size = players} } {method abstract public {show-map}:Graphic} {method abstract public {get-square-at location:Location}:MapSquare} {method {replace oldsquare:MapSquare, newsquare:MapSquare}:bool {unless {self.on-map? oldsquare.location} and {newsquare.location.equals oldsquare.location} do {return false} } set self.grid[oldsquare.location.x, oldsquare.location.y] = newsquare {for each-entity in oldsquare.contents do {if {newsquare.enter each-entity} then set each-entity.location = newsquare } {oldsquare.exit each-entity} } {return true} } {method {on-map? location:Location}:bool let x:int = location.x - self.upperleft.x let y:int = location.y - self.upperleft.y {return {self.grid.in-bounds? x, y}} } {method public {add-player player:Player}:int {self.players.append player} {return self.players.size} } {getter public {player}:Player {return self.players[self.current-player]} } } ||defines a basic square on a map {define-class public abstract MapSquare field map:Map field location:Location field contents:{Array-of Entity} = {new {Array-of Entity}} field type:Terrain field bgcolor:String = "white" field textcolor:String = "black" {constructor {default map:Map, location:Location, type:Terrain} set self.map = map set self.location = location set self.type = type } {method abstract {passable-for entity:Entity}:bool} {method public {enter entity:Entity}:bool {if {self.passable-for entity} then {for each-entity in self.contents do {each-entity.inform-entry entity} } {self.contents.append entity} {return true} else {return false} } } {method public {exit entity:Entity}:bool let i:int = {self.contents.find entity} {if i != -1 then {self.contents.remove i} {for each-entity in self.contents do {each-entity.inform-exit entity} } {return true} else {return false} } } {method public {get-actives}:{Array-of Active} let actives:{Array-of Active} = {new {Array-of Active}} {for each-entity in self.contents do {if each-entity isa Active then {actives.append each-entity asa Active} } } {return actives} } {method public {replace-with newsquare:MapSquare}:bool {return {self.map.replace self, newsquare}} } {method {get-map-terrain button?:bool = false}:Graphic let terrain-list:VBox = {VBox spacing = 1pt, hstretch? = true } {for each-entity in self.contents do {unless each-entity.mobile do {terrain-list.add {each-entity.make-graphic}} } } let view:VBox = {VBox ||-- border-color = "black", ||-- border-width = 2pt, background = self.bgcolor, color = self.textcolor, halign = "center", margin = 2pt, height = 3cm, width = 2.5cm, spacing = 2pt, {self.location.make-graphic} } {if button? then {view.add {CommandButton label = "Here", {on Action do {self.map.player.button-action self} } }} } {view.add terrain-list} {return view} } {method {get-view-terrain coordinates?:bool = true, button?:bool = true}:Graphic let terrain-list:VBox = {VBox spacing = 1pt, hstretch? = true } {for each-entity in self.contents do {terrain-list.add {each-entity.make-graphic}} } let view:VBox = {VBox ||-- border-color = "black", ||-- border-width = 2pt, background = self.bgcolor, color = self.textcolor, halign = "center", margin = 2pt, height = 3cm, width = 2.5cm, spacing = 2pt } {if coordinates? then {view.add {self.location.make-graphic}} } {if button? then {view.add {CommandButton label = "Go Here", {on Action do {self.map.player.button-action self} } }} } {view.add terrain-list} {return view} } } ||defines a generic entity at a MapSquare {define-class public abstract Entity field location:MapSquare field name:String field natural-domain:Terrain {constructor {default position:MapSquare, label:String, medium:Terrain} set self.name = label set self.natural-domain = medium set self.location = position {self.location.enter self} } {getter abstract {mobile}:bool} {getter {domain}:Terrain {return self.natural-domain} } {method {make-graphic}:Graphic {return {HBox {hcenter self.name}}} } ||NOTICE! These methods are not abstract; they just do nothing unless overridden! {method {inform-entry entity:Entity}:void} {method {inform-exit entity:Entity}:void} } ||defines a basic non-movable entity {define-class abstract Immobile-Entity {inherits Entity} {constructor {default position:MapSquare, label:String, medium:Terrain} {construct-super position, label, medium} } {getter {mobile}:bool {return false} } } ||defines a basic movable entity {define-class abstract Movable-Entity {inherits Entity} field carrier:#Entity = null {constructor {default position:MapSquare, label:String, domain:Terrain} {construct-super position, label, domain} } {method abstract {move-to location:MapSquare}:bool} {getter {mobile}:bool {return true} } {getter {domain}:Terrain {if-non-null self.carrier then {return self.carrier.domain} else {return self.natural-domain} } } } ||defines the concept of a player {define-class abstract Player {inherits Movable-Entity} {constructor {default location:MapSquare, name:String} {construct-super location, name, location.type} } {method abstract {button-action location:any}:void} {method abstract public {show-vision}:Graphic} }