delaunay mapgen 1st version
This commit is contained in:
		
							
								
								
									
										9
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								Makefile
									
									
									
									
									
								
							@@ -20,8 +20,8 @@ all: build test
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
build: distclean build.deps build.game
 | 
					build: distclean build.deps build.game
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# build.game: build.game.linux64 build.game.win64 build.game.mac
 | 
					build.game: build.game.linux64 build.game.win64 build.game.mac
 | 
				
			||||||
build.game: build.game.linux64 build.game.win64
 | 
					# build.game: build.game.linux64 build.game.win64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
build.deps:
 | 
					build.deps:
 | 
				
			||||||
	GIT_SSL_NO_VERIFY=true $(GO) mod vendor
 | 
						GIT_SSL_NO_VERIFY=true $(GO) mod vendor
 | 
				
			||||||
@@ -45,11 +45,14 @@ build.game.win64:
 | 
				
			|||||||
	/usr/bin/x86_64-w64-mingw32-strip $(DISTFOLDER)/game.exe && \
 | 
						/usr/bin/x86_64-w64-mingw32-strip $(DISTFOLDER)/game.exe && \
 | 
				
			||||||
	cd $(DISTFOLDER) && zip -r ../$(PROJECT_NAME)-$(OS)-${PKG_VER}.zip . -x *.git*
 | 
						cd $(DISTFOLDER) && zip -r ../$(PROJECT_NAME)-$(OS)-${PKG_VER}.zip . -x *.git*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
					# OSXCROSS_NO_INCLUDE_PATH_WARNINGS=1 MACOSX_DEPLOYMENT_TARGET=10.6 CC=o64-clang CXX=o64-clang++ GOOS=darwin GOARCH=amd64 CGO_ENABLED=1 $(GO) build -ldflags $(LDFLAGS) -o $(DISTFOLDER)/game $(CWD)/cmd/game/main.go && 
 | 
				
			||||||
build.game.mac:
 | 
					build.game.mac:
 | 
				
			||||||
	cp $(CWD)/lib/mac/libBearLibTerminal.dylib $(DISTFOLDER) && \
 | 
						cp $(CWD)/lib/mac/libBearLibTerminal.dylib $(DISTFOLDER) && \
 | 
				
			||||||
	cp $(CWD)/config.json $(DISTFOLDER) && \
 | 
						cp $(CWD)/config.json $(DISTFOLDER) && \
 | 
				
			||||||
	cp -r $(CWD)/assets $(DISTFOLDER) && \
 | 
						cp -r $(CWD)/assets $(DISTFOLDER) && \
 | 
				
			||||||
	OSXCROSS_NO_INCLUDE_PATH_WARNINGS=1 MACOSX_DEPLOYMENT_TARGET=10.6 CC=o64-clang CXX=o64-clang++ GOOS=darwin GOARCH=amd64 CGO_ENABLED=1 $(GO) build -ldflags $(LDFLAGS) -o $(DISTFOLDER)/game $(CWD)/cmd/game/main.go && \
 | 
						OSXCROSS_NO_INCLUDE_PATH_WARNINGS=1 MACOSX_DEPLOYMENT_TARGET=10.6 CC=clang CXX=clang++ GOOS=darwin GOARCH=amd64 CGO_ENABLED=1 $(GO) build -ldflags $(LDFLAGS) -o $(DISTFOLDER)/game $(CWD)/cmd/game/main.go && \
 | 
				
			||||||
	strip $(DISTFOLDER)/game.exe && \
 | 
						strip $(DISTFOLDER)/game.exe && \
 | 
				
			||||||
	cd $(DISTFOLDER) && zip -r ../$(PROJECT_NAME)-$(OS)-${PKG_VER}.zip . -x *.git*
 | 
						cd $(DISTFOLDER) && zip -r ../$(PROJECT_NAME)-$(OS)-${PKG_VER}.zip . -x *.git*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										17
									
								
								assets/logo2.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								assets/logo2.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					                                              ^^:^|+     !.  ,|      .'::
 | 
				
			||||||
 | 
					                                               'Uz       3F` |/     `cz RR
 | 
				
			||||||
 | 
					                                                U|       ye=-/l     zy-^^
 | 
				
			||||||
 | 
					                                                gc       ff  ^v     ik`  :
 | 
				
			||||||
 | 
					                                                l|       :F   c      -!!:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					               .-                 ,`     `,      ''                           :  ''       -.       `'        ``  `-'!!
 | 
				
			||||||
 | 
					     '.f^      sw!            !u|,,\%N;  ipf     tdD    -|l!":aXr  ',||      lf  u%'      tOc   ru;.,C0q   ,r` iXD! !t
 | 
				
			||||||
 | 
					     `uqE'     !w:          -!w      ul  ,Uw     !e#   rye-   ?ez   ';3=    !B?  /d>      :az !v0|    ,a       'kw
 | 
				
			||||||
 | 
					    `vv=ee     i%!          !w'          ,o9i?zFsfU#  !39z|?|//     ^OWws` taq?  -dgc    `/f   `t#%+           'oe
 | 
				
			||||||
 | 
					   `r3  ueo    s%!         'qQ`          ,pe     >kW  lgw           |OXX|-ue/9>    zgO! =e'       ^DQw.        'Fe
 | 
				
			||||||
 | 
					   :Cr!::|Ec   cq!          UQs          'Da     >%W  !QB`          vR- cC' ^e>      3EW!           -eQ%:      'qU
 | 
				
			||||||
 | 
					  :a`    `ON;  /q|          `#@e    .yd  ,ge     |BQ   sBp,    ,y   |D      +k|      :kd       EB=    !q:      'pq
 | 
				
			||||||
 | 
					 ^w"      ,qd  :dE+!!!!!sw    eQqs|zU/    #Q^    ,Q@z   ,qU/::i|    Fg      zN/      !Qg        E#pz>zw'        R@C
 | 
				
			||||||
 | 
					                 `''''''`        `                                           ,        ,                              
 | 
				
			||||||
@@ -5,7 +5,7 @@ import (
 | 
				
			|||||||
	"github.com/rs/zerolog/log"
 | 
						"github.com/rs/zerolog/log"
 | 
				
			||||||
	"lab.zaar.be/thefish/alchemyst-go/engine/ecs"
 | 
						"lab.zaar.be/thefish/alchemyst-go/engine/ecs"
 | 
				
			||||||
	"lab.zaar.be/thefish/alchemyst-go/engine/gamemap"
 | 
						"lab.zaar.be/thefish/alchemyst-go/engine/gamemap"
 | 
				
			||||||
	"lab.zaar.be/thefish/alchemyst-go/engine/gamemap/mapgens"
 | 
						"lab.zaar.be/thefish/alchemyst-go/engine/gamemap/mapgens/delaunaymst"
 | 
				
			||||||
	"lab.zaar.be/thefish/alchemyst-go/engine/gamestate"
 | 
						"lab.zaar.be/thefish/alchemyst-go/engine/gamestate"
 | 
				
			||||||
	"lab.zaar.be/thefish/alchemyst-go/engine/mob"
 | 
						"lab.zaar.be/thefish/alchemyst-go/engine/mob"
 | 
				
			||||||
	"lab.zaar.be/thefish/alchemyst-go/engine/mob/movement"
 | 
						"lab.zaar.be/thefish/alchemyst-go/engine/mob/movement"
 | 
				
			||||||
@@ -70,7 +70,8 @@ func main() {
 | 
				
			|||||||
	go decodeInput(mainCtx, mw.GetLayer("base"))
 | 
						go decodeInput(mainCtx, mw.GetLayer("base"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	//fixme set up (load / generate) level - move to game / enter or title / exit
 | 
						//fixme set up (load / generate) level - move to game / enter or title / exit
 | 
				
			||||||
	level, rooms := mapgens.DefaultGen(mainCtx, gamemap.NewLevel(mainCtx, "test", 1))
 | 
						//level, rooms := _default.DefaultGen(mainCtx, gamemap.NewLevel(mainCtx, "test", 1))
 | 
				
			||||||
 | 
						level, rooms := delaunaymst.DelaunayMstGen(mainCtx, gamemap.NewLevel(mainCtx, "test", 1))
 | 
				
			||||||
	State.Level = level
 | 
						State.Level = level
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sidebarWidth := 0
 | 
						sidebarWidth := 0
 | 
				
			||||||
@@ -136,16 +137,12 @@ func main() {
 | 
				
			|||||||
		SetBgColor("#ef305c70").
 | 
							SetBgColor("#ef305c70").
 | 
				
			||||||
		SetFgColor("white").
 | 
							SetFgColor("white").
 | 
				
			||||||
		SetItems([]interface{}{
 | 
							SetItems([]interface{}{
 | 
				
			||||||
			"hjklyubn, NumPad 12346789, arrow keys - move",
 | 
								`"Fisheye" crafty shaded glasses`,
 | 
				
			||||||
			"s or . - pass turn",
 | 
								"Xecutor's glowing visor",
 | 
				
			||||||
			"g or , - pick up item",
 | 
								"Kitschy goggles of many pathways",
 | 
				
			||||||
			"i - inventory",
 | 
								"Ring of inexistence",
 | 
				
			||||||
			"? - this screen",
 | 
								"Orb of omniscience",
 | 
				
			||||||
			"Ctrl+q - exit",
 | 
								"Wand of amnesia",
 | 
				
			||||||
			"f or F - fire or throw weapon",
 | 
					 | 
				
			||||||
			"z or Z - cast a spell",
 | 
					 | 
				
			||||||
			"p - pray",
 | 
					 | 
				
			||||||
			"Ctrl+p - message log",
 | 
					 | 
				
			||||||
		}).MakeList(),
 | 
							}).MakeList(),
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,10 +1,10 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    "version": "v0.0.1.5-1-gbecf7ea",
 | 
					    "version": "v0.0.1.6",
 | 
				
			||||||
    "title": "Alchemyst",
 | 
					    "title": "Alchemyst",
 | 
				
			||||||
    "sizeX": 100,
 | 
					    "sizeX": 100,
 | 
				
			||||||
    "sizeY": 47,
 | 
					    "sizeY": 47,
 | 
				
			||||||
    "fpsLimit": 60,
 | 
					    "fpsLimit": 60,
 | 
				
			||||||
    "font": "./assets/fonts/bitmap/ibmnew8x12.png",
 | 
					    "font": "./assets/fonts/ttf/LiberationMono-Bold.ttf",
 | 
				
			||||||
    "fontSize": "8x12",
 | 
					    "fontSize": "8x14",
 | 
				
			||||||
    "verbosity": "debug"
 | 
					    "verbosity": "debug"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -8,6 +8,11 @@ const MobComponent = "mob"
 | 
				
			|||||||
const MoveableComponent = "movable"
 | 
					const MoveableComponent = "movable"
 | 
				
			||||||
const CarriedComponent = "carried"
 | 
					const CarriedComponent = "carried"
 | 
				
			||||||
const UsableComponent = "usable"
 | 
					const UsableComponent = "usable"
 | 
				
			||||||
 | 
					const WearableComponent = "usable"
 | 
				
			||||||
 | 
					const ArmsComponent = "arms"
 | 
				
			||||||
 | 
					const RangedComponent = "ranged"
 | 
				
			||||||
 | 
					const AmmoComponent = "ammo"
 | 
				
			||||||
 | 
					const ArmorComponent = "armor"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Component interface {
 | 
					type Component interface {
 | 
				
			||||||
	Type() string
 | 
						Type() string
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -167,7 +167,7 @@ func (ps *precomputedShade) PrecomputeFovMap() {
 | 
				
			|||||||
	//Bresanham lines / Raycast
 | 
						//Bresanham lines / Raycast
 | 
				
			||||||
	var lineX, lineY float64
 | 
						var lineX, lineY float64
 | 
				
			||||||
	for i := 0; i < 720; i++ { // 1/2 of angles
 | 
						for i := 0; i < 720; i++ { // 1/2 of angles
 | 
				
			||||||
		dx := math.Sin(float64(i) / (float64(360) / math.Pi)) //1/2 of angles
 | 
							dx := math.Sin(float64(i) / (float64(360) / math.Pi)) //1/2 of angle
 | 
				
			||||||
		dy := math.Cos(float64(i) / (float64(360) / math.Pi))
 | 
							dy := math.Cos(float64(i) / (float64(360) / math.Pi))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		lineX = 0
 | 
							lineX = 0
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
package mapgens
 | 
					package _default
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
							
								
								
									
										196
									
								
								engine/gamemap/mapgens/delaunaymst/delaunay_mst.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										196
									
								
								engine/gamemap/mapgens/delaunaymst/delaunay_mst.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,196 @@
 | 
				
			|||||||
 | 
					package delaunaymst
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"lab.zaar.be/thefish/alchemyst-go/engine/gamemap"
 | 
				
			||||||
 | 
						"lab.zaar.be/thefish/alchemyst-go/engine/types"
 | 
				
			||||||
 | 
						"lab.zaar.be/thefish/alchemyst-go/util"
 | 
				
			||||||
 | 
						"lab.zaar.be/thefish/alchemyst-go/util/appctx"
 | 
				
			||||||
 | 
						"lab.zaar.be/thefish/alchemyst-go/util/delaunay"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//fixme move to config
 | 
				
			||||||
 | 
					var minRoomSize = 5
 | 
				
			||||||
 | 
					var maxRoomSize = 15
 | 
				
			||||||
 | 
					var maxrooms = 59
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var fges = map[int]types.RectFill{
 | 
				
			||||||
 | 
						1: types.RectFill{
 | 
				
			||||||
 | 
							Top:         func() *gamemap.Tile { return gamemap.NewWall() },
 | 
				
			||||||
 | 
							Bottom:      func() *gamemap.Tile { return gamemap.NewWall() },
 | 
				
			||||||
 | 
							Left:        func() *gamemap.Tile { return gamemap.NewWall() },
 | 
				
			||||||
 | 
							Right:       func() *gamemap.Tile { return gamemap.NewWall() },
 | 
				
			||||||
 | 
							BottomLeft:  func() *gamemap.Tile { return gamemap.NewWall() },
 | 
				
			||||||
 | 
							BottomRight: func() *gamemap.Tile { return gamemap.NewWall() },
 | 
				
			||||||
 | 
							TopLeft:     func() *gamemap.Tile { return gamemap.NewWall() },
 | 
				
			||||||
 | 
							TopRight:    func() *gamemap.Tile { return gamemap.NewWall() },
 | 
				
			||||||
 | 
							Body:        func() *gamemap.Tile { return gamemap.NewFloor() },
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						2: types.RectFill{
 | 
				
			||||||
 | 
							Top:         func() *gamemap.Tile { return gamemap.NewWaterTile() },
 | 
				
			||||||
 | 
							Bottom:      func() *gamemap.Tile { return gamemap.NewWaterTile() },
 | 
				
			||||||
 | 
							Left:        func() *gamemap.Tile { return gamemap.NewWaterTile() },
 | 
				
			||||||
 | 
							Right:       func() *gamemap.Tile { return gamemap.NewWaterTile() },
 | 
				
			||||||
 | 
							BottomLeft:  func() *gamemap.Tile { return gamemap.NewWaterTile() },
 | 
				
			||||||
 | 
							BottomRight: func() *gamemap.Tile { return gamemap.NewWaterTile() },
 | 
				
			||||||
 | 
							TopLeft:     func() *gamemap.Tile { return gamemap.NewWaterTile() },
 | 
				
			||||||
 | 
							TopRight:    func() *gamemap.Tile { return gamemap.NewWaterTile() },
 | 
				
			||||||
 | 
							Body:        func() *gamemap.Tile { return gamemap.NewDeepWaterTile() },
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func DelaunayMstGen(ctx appctx.ClientCtx, l *gamemap.Level) (*gamemap.Level, []gamemap.Room) {
 | 
				
			||||||
 | 
						rng := util.NewRNG()
 | 
				
			||||||
 | 
						//load prefabs
 | 
				
			||||||
 | 
						pfLoader := gamemap.NewPrefabLoader(ctx)
 | 
				
			||||||
 | 
						pfRooms := pfLoader.PrefabRoomsList()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//fill with walls
 | 
				
			||||||
 | 
						for i := 0; i < l.W; i ++ {
 | 
				
			||||||
 | 
							for j := 0; j < l.H; j++ {
 | 
				
			||||||
 | 
								l.SetTileByXY(i, j, gamemap.NewWall())
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						rooms := make([]gamemap.Room, 0)
 | 
				
			||||||
 | 
						prefabUsed := false
 | 
				
			||||||
 | 
						for i := 0; i < maxrooms; i++ {
 | 
				
			||||||
 | 
							failed := false
 | 
				
			||||||
 | 
							var fillage types.RectFill
 | 
				
			||||||
 | 
							fillage = fges[rng.GetWeightedEntity(map[int]int{1: 10, 2: 1})]
 | 
				
			||||||
 | 
							var newRoom gamemap.Room
 | 
				
			||||||
 | 
							if !prefabUsed || rng.Range(0, 5) > 3 {
 | 
				
			||||||
 | 
								//prefab
 | 
				
			||||||
 | 
								prefabUsed = true
 | 
				
			||||||
 | 
								r := pfRooms[rng.Range(0, len(pfRooms))] //copy to local scope
 | 
				
			||||||
 | 
								newRoom = r
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								newRoom = gamemap.NewRandomRectRoom(
 | 
				
			||||||
 | 
									rng,
 | 
				
			||||||
 | 
									rng.Range(minRoomSize, maxRoomSize),
 | 
				
			||||||
 | 
									rng.Range(minRoomSize, maxRoomSize),
 | 
				
			||||||
 | 
									fillage,
 | 
				
			||||||
 | 
								)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							where := types.Coords{
 | 
				
			||||||
 | 
								rng.Range(1, l.W-2-newRoom.W),
 | 
				
			||||||
 | 
								rng.Range(1, l.H-2-newRoom.H),
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							newRoom.MoveToCoords(where)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for _, otherRoom := range rooms {
 | 
				
			||||||
 | 
								if otherRoom.Intersects(newRoom.Rect) {
 | 
				
			||||||
 | 
									failed = true
 | 
				
			||||||
 | 
									break
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if failed {
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if len(newRoom.Connectors) > 0 {
 | 
				
			||||||
 | 
								rooms = append(rooms, newRoom)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, room := range rooms {
 | 
				
			||||||
 | 
							err := room.BlitToLevel(l)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								fmt.Printf("err: %v", err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						centers := make([]types.Coords, 0)
 | 
				
			||||||
 | 
						for _, room := range rooms {
 | 
				
			||||||
 | 
							centers = append(centers, room.Center)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, edge := range delaunay.GetMst(centers, l.W, l.H) {
 | 
				
			||||||
 | 
							MedianStraight(rng, l, rooms, centers, edge)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return l, rooms
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func MedianStraight(rng *util.RNG, l *gamemap.Level, rooms []gamemap.Room, centers []types.Coords, edge types.Edge) {
 | 
				
			||||||
 | 
						//find connected rooms
 | 
				
			||||||
 | 
						var  fromRoom, toRoom gamemap.Room
 | 
				
			||||||
 | 
						for _, room := range rooms {
 | 
				
			||||||
 | 
							if room.Center == edge.From {
 | 
				
			||||||
 | 
								fromRoom = room
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if room.Center == edge.To {
 | 
				
			||||||
 | 
								toRoom = room
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if len(fromRoom.Connectors) > 0 && len(toRoom.Connectors) > 0 {
 | 
				
			||||||
 | 
								break
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						midpoint := edge.Midpoint()
 | 
				
			||||||
 | 
						fromConnector := findNearestCoonector(midpoint, fromRoom)
 | 
				
			||||||
 | 
						toConnector := findNearestCoonector(midpoint, toRoom)
 | 
				
			||||||
 | 
						connectStraight(rng, l, fromConnector, toConnector, midpoint)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func findNearestCoonector(midpoint types.Coords, room gamemap.Room) types.Coords {
 | 
				
			||||||
 | 
						var nearest types.Coords
 | 
				
			||||||
 | 
						for _, con := range room.Connectors {
 | 
				
			||||||
 | 
							if nearest.X == 0 {
 | 
				
			||||||
 | 
								nearest = con
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if midpoint.DistanceTo(con) < midpoint.DistanceTo(nearest) {
 | 
				
			||||||
 | 
								nearest = con
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nearest
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func connectStraight(rng *util.RNG, l *gamemap.Level, from, to, midpoint types.Coords) {
 | 
				
			||||||
 | 
						toss := rng.Range(0, 1)
 | 
				
			||||||
 | 
						if toss == 0 {
 | 
				
			||||||
 | 
							digHTunnel(l, from.X, midpoint.X, from.Y)
 | 
				
			||||||
 | 
							digVTunnel(l, from.Y, to.Y, midpoint.X)
 | 
				
			||||||
 | 
							digHTunnel(l, midpoint.X, to.X, to.Y)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							digVTunnel(l, from.Y, midpoint.Y, from.X)
 | 
				
			||||||
 | 
							digHTunnel(l, from.X, to.X, midpoint.Y)
 | 
				
			||||||
 | 
							digVTunnel(l, midpoint.Y, to.Y, to.X)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func digHTunnel(l *gamemap.Level, x1, x2, y int) {
 | 
				
			||||||
 | 
						var start, finish int
 | 
				
			||||||
 | 
						if x1 < x2 {
 | 
				
			||||||
 | 
							start = x1
 | 
				
			||||||
 | 
							finish = x2
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							start = x2
 | 
				
			||||||
 | 
							finish = x1
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for i := start; i <= finish; i++ {
 | 
				
			||||||
 | 
							if l.InBounds(types.Coords{i, y}) {
 | 
				
			||||||
 | 
								l.SetTileByXY(i, y, gamemap.NewFloor())
 | 
				
			||||||
 | 
								//l.Tiles[i][y] = gamemap.NewFloor()
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func digVTunnel(l *gamemap.Level, y1, y2, x int) {
 | 
				
			||||||
 | 
						var start, finish int
 | 
				
			||||||
 | 
						if y1 < y2 {
 | 
				
			||||||
 | 
							start = y1
 | 
				
			||||||
 | 
							finish = y2
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							start = y2
 | 
				
			||||||
 | 
							finish = y1
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for i := start; i <= finish; i++ {
 | 
				
			||||||
 | 
							if l.InBounds(types.Coords{x, i}) {
 | 
				
			||||||
 | 
								l.SetTileByXY(x, i, gamemap.NewFloor())
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -57,11 +57,12 @@ func (pfbl PrefabLoader) PrefabRoomsList() []Room {
 | 
				
			|||||||
		panic(err)
 | 
							panic(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//prepare actual legends
 | 
				
			||||||
 | 
						currentTileLegend := file.DefaultTileLegend
 | 
				
			||||||
 | 
						currentMobsLegend := file.DefaultMobsLegend
 | 
				
			||||||
 | 
						currentItemLegend := file.DefaultItemLegend
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, rawPrefab := range file.Prefabs {
 | 
						for _, rawPrefab := range file.Prefabs {
 | 
				
			||||||
		//prepare actual legends
 | 
					 | 
				
			||||||
		currentTileLegend := file.DefaultTileLegend
 | 
					 | 
				
			||||||
		currentMobsLegend := file.DefaultMobsLegend
 | 
					 | 
				
			||||||
		currentItemLegend := file.DefaultItemLegend
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for k,v := range rawPrefab.TileLegend {
 | 
							for k,v := range rawPrefab.TileLegend {
 | 
				
			||||||
			currentTileLegend[k] = v
 | 
								currentTileLegend[k] = v
 | 
				
			||||||
@@ -99,7 +100,7 @@ func (pfbl PrefabLoader) PrefabRoomsList() []Room {
 | 
				
			|||||||
					continue
 | 
										continue
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				if shortName == "connector" {
 | 
									if shortName == "connector" {
 | 
				
			||||||
					f = NewFloor
 | 
										f = NewWall
 | 
				
			||||||
					room.Connectors = append(room.Connectors, types.Coords{i,j})
 | 
										room.Connectors = append(room.Connectors, types.Coords{i,j})
 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					f, ok = TileTypeMap[shortName]
 | 
										f, ok = TileTypeMap[shortName]
 | 
				
			||||||
@@ -122,4 +123,4 @@ var TileTypeMap = map[string]func()*Tile{
 | 
				
			|||||||
	"decorated_wall": NewDecoratedWall,
 | 
						"decorated_wall": NewDecoratedWall,
 | 
				
			||||||
	"water": NewWaterTile,
 | 
						"water": NewWaterTile,
 | 
				
			||||||
	"deep_water": NewDeepWaterTile,
 | 
						"deep_water": NewDeepWaterTile,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										14
									
								
								engine/items/ammo.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								engine/items/ammo.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					package items
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"lab.zaar.be/thefish/alchemyst-go/engine/ecs"
 | 
				
			||||||
 | 
						"lab.zaar.be/thefish/alchemyst-go/engine/items/itemprops"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Ammo struct {
 | 
				
			||||||
 | 
						itemprops.DamageProfile
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (a *Ammo) Type() string {
 | 
				
			||||||
 | 
						return ecs.AmmoComponent
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										11
									
								
								engine/items/armor.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								engine/items/armor.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					package items
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "lab.zaar.be/thefish/alchemyst-go/engine/ecs"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Armor struct {
 | 
				
			||||||
 | 
						DefenceProfile struct{}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (a *Armor) Type() string {
 | 
				
			||||||
 | 
						return ecs.ArmorComponent
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										14
									
								
								engine/items/arms.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								engine/items/arms.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					package items
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"lab.zaar.be/thefish/alchemyst-go/engine/ecs"
 | 
				
			||||||
 | 
						"lab.zaar.be/thefish/alchemyst-go/engine/items/itemprops"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Arms struct {
 | 
				
			||||||
 | 
						itemprops.DamageProfile
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (a Arms) Type() string {
 | 
				
			||||||
 | 
						return ecs.ArmsComponent
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -2,8 +2,26 @@ package items
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import "lab.zaar.be/thefish/alchemyst-go/engine/ecs"
 | 
					import "lab.zaar.be/thefish/alchemyst-go/engine/ecs"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Carried struct {}
 | 
					type CarriedFace interface {
 | 
				
			||||||
 | 
						Drop()
 | 
				
			||||||
 | 
						Pickup()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Carried struct {
 | 
				
			||||||
 | 
						Mass int //масса в граммах
 | 
				
			||||||
 | 
						Bulk int //внешний размер, см3
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (c *Carried) Type() string {
 | 
					func (c *Carried) Type() string {
 | 
				
			||||||
	return ecs.CarriedComponent
 | 
						return ecs.CarriedComponent
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (c *Carried) Pickup() {}
 | 
				
			||||||
 | 
					func (c *Carried) Drop() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (c *Carried) GetMass() int {
 | 
				
			||||||
 | 
						return c.Mass
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					func (c *Carried) GetBulk() int {
 | 
				
			||||||
 | 
						return c.Bulk
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										7
									
								
								engine/items/itemprops/damage.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								engine/items/itemprops/damage.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					package itemprops
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type DamageProfile struct {
 | 
				
			||||||
 | 
							Pierce int
 | 
				
			||||||
 | 
							Bash int
 | 
				
			||||||
 | 
							Cleave int
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										11
									
								
								engine/items/ranged.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								engine/items/ranged.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					package items
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "lab.zaar.be/thefish/alchemyst-go/engine/ecs"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Ranged struct {
 | 
				
			||||||
 | 
						RangeProfile struct{} //это зависимость дальности-скорости от характеристик и атрибутов
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (r *Ranged) Type() string {
 | 
				
			||||||
 | 
						return ecs.RangedComponent
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -2,9 +2,16 @@ package items
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import "lab.zaar.be/thefish/alchemyst-go/engine/ecs"
 | 
					import "lab.zaar.be/thefish/alchemyst-go/engine/ecs"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Useable struct {}
 | 
					type UsableFace interface {
 | 
				
			||||||
 | 
						Use()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Usable struct {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (u *Useable) Type() string {
 | 
					func (u *Usable) Type() string {
 | 
				
			||||||
	return ecs.UsableComponent
 | 
						return ecs.UsableComponent
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (u *Usable) Use() {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
							
								
								
									
										16
									
								
								engine/items/wearable.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								engine/items/wearable.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
				
			|||||||
 | 
					package items
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "lab.zaar.be/thefish/alchemyst-go/engine/ecs"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type WearableFace interface {
 | 
				
			||||||
 | 
						Wear()
 | 
				
			||||||
 | 
						Takeoff()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Wearable struct {
 | 
				
			||||||
 | 
						Bodypart int //куда собстно одевать
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (w *Wearable) Type() string {
 | 
				
			||||||
 | 
						return ecs.WearableComponent
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										82
									
								
								engine/matertals/properties.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								engine/matertals/properties.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,82 @@
 | 
				
			|||||||
 | 
					package matertals
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "github.com/rs/zerolog/log"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type MaterialProperties struct {
 | 
				
			||||||
 | 
						Density float64 	//Плотность (кг / м3)
 | 
				
			||||||
 | 
						Tougnness float64 	//Ударная вязкость, мера скорости поглощения энергии без деформаций, джоули на квадратный метр в секунду
 | 
				
			||||||
 | 
						Brittleness float64  //Хрупкость - обратная пластичности (в основном за счет внешних эффектов), джоули на квадртаный метр, после которых раскол
 | 
				
			||||||
 | 
						MeltingPoint float64 //точка перехода из твердого в жидкое, градусы Цельсия при нормальном давлении
 | 
				
			||||||
 | 
						BoilingPoint float64 //точка кипения - из жидкого в газ, градусы Цельсия при нормальном давлении
 | 
				
			||||||
 | 
						Conductivity bool //проводимость эл. тока
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//агрегатное состояние
 | 
				
			||||||
 | 
					type MatterState int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						Solid   MatterState = iota //кристаллическая решетка
 | 
				
			||||||
 | 
						Liquid
 | 
				
			||||||
 | 
						Gas
 | 
				
			||||||
 | 
						Plasma
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Glass //нет кристаллической решетки, аморфный
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var transitions = map[MatterState][]MatterState{
 | 
				
			||||||
 | 
						Solid: {Liquid, Gas},
 | 
				
			||||||
 | 
						Liquid: {Solid, Gas, Glass},
 | 
				
			||||||
 | 
						Gas: {Solid, Plasma},
 | 
				
			||||||
 | 
						Plasma: {Gas},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Glass: {Liquid},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ms MatterState) Change(from MatterState, to MatterState) bool {
 | 
				
			||||||
 | 
						if from == to {
 | 
				
			||||||
 | 
							return true
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_, ok := transitions[from]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ok {
 | 
				
			||||||
 | 
							newStateFound := func(lst []MatterState, to MatterState) bool {
 | 
				
			||||||
 | 
								for _, b := range lst {
 | 
				
			||||||
 | 
									if b == to {
 | 
				
			||||||
 | 
										return true
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return false
 | 
				
			||||||
 | 
							}(transitions[from], to)
 | 
				
			||||||
 | 
							if !newStateFound {
 | 
				
			||||||
 | 
								log.Warn().Msgf("Transition %s -> %s is impossible", from, to)
 | 
				
			||||||
 | 
								return false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							// check temperatures/conditions, see template
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
								Solid -> Gas     Sublimation
 | 
				
			||||||
 | 
								Solid -> Liquid  Melting
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Liquid -> Gas    Boiling
 | 
				
			||||||
 | 
								Liquid -> Solid  Freezing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Gas -> Solid     Deposition
 | 
				
			||||||
 | 
								Gas -> Liquid    Condensation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Gas -> Plasma    Ionization
 | 
				
			||||||
 | 
							 	Plasma -> Gas    Recombination
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//При фазовом переходе первого рода скачкообразно изменяются самые главные, первичные экстенсивные параметры:
 | 
				
			||||||
 | 
						// удельный объём,
 | 
				
			||||||
 | 
						// количество запасённой внутренней энергии,
 | 
				
			||||||
 | 
						// концентрация компонентов и т. п.
 | 
				
			||||||
 | 
						//
 | 
				
			||||||
 | 
						// Фазовые переходы второго рода происходят в тех случаях, когда меняется симметрия строения вещества
 | 
				
			||||||
 | 
						// (симметрия может полностью исчезнуть или понизиться).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -101,7 +101,7 @@ func (devm *DevmenuScreen) Render() {
 | 
				
			|||||||
	menuLayer.WithColor(devm.fgColor).PrintInside(
 | 
						menuLayer.WithColor(devm.fgColor).PrintInside(
 | 
				
			||||||
		devm.Rect,
 | 
							devm.Rect,
 | 
				
			||||||
		strings.Join([]string{
 | 
							strings.Join([]string{
 | 
				
			||||||
			"Dev Menu:",
 | 
								"Действия для разработчика:",
 | 
				
			||||||
			"[color=green]v[/color] - set all tiles visible",
 | 
								"[color=green]v[/color] - set all tiles visible",
 | 
				
			||||||
			"[color=green]i[/color] - set all tiles invisible",
 | 
								"[color=green]i[/color] - set all tiles invisible",
 | 
				
			||||||
			fmt.Sprintf("[color=green]p[/color] - toggle passwall: %v",
 | 
								fmt.Sprintf("[color=green]p[/color] - toggle passwall: %v",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,3 +4,23 @@ type Edge struct {
 | 
				
			|||||||
	From Coords
 | 
						From Coords
 | 
				
			||||||
	To   Coords
 | 
						To   Coords
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (e *Edge) Midpoint() Coords {
 | 
				
			||||||
 | 
						var dx, dy, minX, minY int
 | 
				
			||||||
 | 
						if e.From.X > e.To.X {
 | 
				
			||||||
 | 
							minX = e.To.X
 | 
				
			||||||
 | 
							dx = e.From.X - e.To.X
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							minX = e.From.X
 | 
				
			||||||
 | 
							dx = e.To.X - e.From.X
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if e.From.Y > e.To.Y {
 | 
				
			||||||
 | 
							minY = e.To.Y
 | 
				
			||||||
 | 
							dy = e.From.Y - e.To.Y
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							minY = e.From.Y
 | 
				
			||||||
 | 
							dy = e.To.Y - e.From.Y
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return Coords{minX + dx / 2, minY + dy / 2}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										183
									
								
								util/bresenham/bresenham.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										183
									
								
								util/bresenham/bresenham.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,183 @@
 | 
				
			|||||||
 | 
					package bresenham
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"lab.zaar.be/thefish/alchemyst-go/engine/types"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// dx > dy; x1 < x2; y1 < y2
 | 
				
			||||||
 | 
					func BresenhamDxXRYD(canvas types.Putable, From, To types.Coords, symFunc func() interface{}) {
 | 
				
			||||||
 | 
						dx, dy := To.X - From.X, 2*(To.Y - From.Y)
 | 
				
			||||||
 | 
						e, slope := dx, 2*dx
 | 
				
			||||||
 | 
						for ; dx != 0; dx-- {
 | 
				
			||||||
 | 
							canvas.Put(From.X, From.Y, symFunc())
 | 
				
			||||||
 | 
							From.X++
 | 
				
			||||||
 | 
							e -= dy
 | 
				
			||||||
 | 
							if e < 0 {
 | 
				
			||||||
 | 
								From.Y++
 | 
				
			||||||
 | 
								e += slope
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// dy > dx; x1 < x2; y1 < y2
 | 
				
			||||||
 | 
					func BresenhamDyXRYD(canvas types.Putable, From, To types.Coords, symFunc func() interface{}) {
 | 
				
			||||||
 | 
						dx, dy := 2*(To.X - From.X), To.Y - From.Y
 | 
				
			||||||
 | 
						e, slope := dy, 2*dy
 | 
				
			||||||
 | 
						for ; dy != 0; dy-- {
 | 
				
			||||||
 | 
							canvas.Put(From.X, From.Y, symFunc())
 | 
				
			||||||
 | 
							From.Y++
 | 
				
			||||||
 | 
							e -= dx
 | 
				
			||||||
 | 
							if e < 0 {
 | 
				
			||||||
 | 
								From.X++
 | 
				
			||||||
 | 
								e += slope
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// dx > dy; x1 < x2; y1 > y2
 | 
				
			||||||
 | 
					func BresenhamDxXRYU(canvas types.Putable, From, To types.Coords, symFunc func() interface{}) {
 | 
				
			||||||
 | 
						dx, dy := To.X - From.X, 2*(From.Y-To.Y)
 | 
				
			||||||
 | 
						e, slope := dx, 2*dx
 | 
				
			||||||
 | 
						for ; dx != 0; dx-- {
 | 
				
			||||||
 | 
							canvas.Put(From.X, From.Y, symFunc())
 | 
				
			||||||
 | 
							From.X++
 | 
				
			||||||
 | 
							e -= dy
 | 
				
			||||||
 | 
							if e < 0 {
 | 
				
			||||||
 | 
								From.Y--
 | 
				
			||||||
 | 
								e += slope
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func BresenhamDyXRYU(canvas types.Putable, From, To types.Coords, symFunc func() interface{}) {
 | 
				
			||||||
 | 
						dx, dy := 2*(To.X - From.X), From.Y-To.Y
 | 
				
			||||||
 | 
						e, slope := dy, 2*dy
 | 
				
			||||||
 | 
						for ; dy != 0; dy-- {
 | 
				
			||||||
 | 
							canvas.Put(From.X, From.Y, symFunc())
 | 
				
			||||||
 | 
							From.Y--
 | 
				
			||||||
 | 
							e -= dx
 | 
				
			||||||
 | 
							if e < 0 {
 | 
				
			||||||
 | 
								From.X++
 | 
				
			||||||
 | 
								e += slope
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Generalized with integer
 | 
				
			||||||
 | 
					func Bresenham(canvas types.Putable, From, To types.Coords, symFunc func() interface{}) {
 | 
				
			||||||
 | 
						var dx, dy, e, slope int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Because drawing p1 -> p2 is equivalent to draw p2 -> p1,
 | 
				
			||||||
 | 
						// I sort points in x-axis order to handle only half of possible cases.
 | 
				
			||||||
 | 
						if From.X > To.X {
 | 
				
			||||||
 | 
							From.X, From.Y, To.X, To.Y = To.X, To.Y, From.X, From.Y
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dx, dy = To.X - From.X, To.Y - From.Y
 | 
				
			||||||
 | 
						// Because point is x-axis ordered, dx cannot be negative
 | 
				
			||||||
 | 
						if dy < 0 {
 | 
				
			||||||
 | 
							dy = -dy
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Is line a point ?
 | 
				
			||||||
 | 
						case From.X ==To.X && From.Y ==To.Y:
 | 
				
			||||||
 | 
							canvas.Put(From.X, From.Y, symFunc())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Is line an horizontal ?
 | 
				
			||||||
 | 
						case From.Y ==To.Y:
 | 
				
			||||||
 | 
							for ; dx != 0; dx-- {
 | 
				
			||||||
 | 
								canvas.Put(From.X, From.Y, symFunc())
 | 
				
			||||||
 | 
								From.X++
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							canvas.Put(From.X, From.Y, symFunc())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Is line a vertical ?
 | 
				
			||||||
 | 
						case From.X ==To.X:
 | 
				
			||||||
 | 
							if From.Y > To.Y {
 | 
				
			||||||
 | 
								From.Y, To.Y = To.Y, From.Y
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							for ; dy != 0; dy-- {
 | 
				
			||||||
 | 
								canvas.Put(From.X, From.Y, symFunc())
 | 
				
			||||||
 | 
								From.Y++
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							canvas.Put(From.X, From.Y, symFunc())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Is line a diagonal ?
 | 
				
			||||||
 | 
						case dx == dy:
 | 
				
			||||||
 | 
							if From.Y < To.Y {
 | 
				
			||||||
 | 
								for ; dx != 0; dx-- {
 | 
				
			||||||
 | 
									canvas.Put(From.X, From.Y, symFunc())
 | 
				
			||||||
 | 
									From.X++
 | 
				
			||||||
 | 
									From.Y++
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								for ; dx != 0; dx-- {
 | 
				
			||||||
 | 
									canvas.Put(From.X, From.Y, symFunc())
 | 
				
			||||||
 | 
									From.X++
 | 
				
			||||||
 | 
									From.Y--
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							canvas.Put(From.X, From.Y, symFunc())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// wider than high ?
 | 
				
			||||||
 | 
						case dx > dy:
 | 
				
			||||||
 | 
							if From.Y < To.Y {
 | 
				
			||||||
 | 
								// BresenhamDxXRYD(img, x1, y1, x2, y2, col)
 | 
				
			||||||
 | 
								dy, e, slope = 2*dy, dx, 2*dx
 | 
				
			||||||
 | 
								for ; dx != 0; dx-- {
 | 
				
			||||||
 | 
									canvas.Put(From.X, From.Y, symFunc())
 | 
				
			||||||
 | 
									From.X++
 | 
				
			||||||
 | 
									e -= dy
 | 
				
			||||||
 | 
									if e < 0 {
 | 
				
			||||||
 | 
										From.Y++
 | 
				
			||||||
 | 
										e += slope
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								// BresenhamDxXRYU(img, x1, y1, x2, y2, col)
 | 
				
			||||||
 | 
								dy, e, slope = 2*dy, dx, 2*dx
 | 
				
			||||||
 | 
								for ; dx != 0; dx-- {
 | 
				
			||||||
 | 
									canvas.Put(From.X, From.Y, symFunc())
 | 
				
			||||||
 | 
									From.X++
 | 
				
			||||||
 | 
									e -= dy
 | 
				
			||||||
 | 
									if e < 0 {
 | 
				
			||||||
 | 
										From.Y--
 | 
				
			||||||
 | 
										e += slope
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							canvas.Put(To.X, To.Y, symFunc())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// higher than wide.
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							if From.Y < To.Y {
 | 
				
			||||||
 | 
								// BresenhamDyXRYD(img, x1, y1, x2, y2, col)
 | 
				
			||||||
 | 
								dx, e, slope = 2*dx, dy, 2*dy
 | 
				
			||||||
 | 
								for ; dy != 0; dy-- {
 | 
				
			||||||
 | 
									canvas.Put(From.X, From.Y, symFunc())
 | 
				
			||||||
 | 
									From.Y++
 | 
				
			||||||
 | 
									e -= dx
 | 
				
			||||||
 | 
									if e < 0 {
 | 
				
			||||||
 | 
										From.X++
 | 
				
			||||||
 | 
										e += slope
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								// BresenhamDyXRYU(img, x1, y1, x2, y2, col)
 | 
				
			||||||
 | 
								dx, e, slope = 2*dx, dy, 2*dy
 | 
				
			||||||
 | 
								for ; dy != 0; dy-- {
 | 
				
			||||||
 | 
									canvas.Put(From.X, From.Y, symFunc())
 | 
				
			||||||
 | 
									From.Y--
 | 
				
			||||||
 | 
									e -= dx
 | 
				
			||||||
 | 
									if e < 0 {
 | 
				
			||||||
 | 
										From.X++
 | 
				
			||||||
 | 
										e += slope
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							canvas.Put(To.X, To.Y, symFunc())
 | 
				
			||||||
 | 
							//img.Set(x2, y2, col)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -12,7 +12,7 @@ type WeightedEdge interface {
 | 
				
			|||||||
	From() int
 | 
						From() int
 | 
				
			||||||
	// To returns the integer identifier of the second vertex.
 | 
						// To returns the integer identifier of the second vertex.
 | 
				
			||||||
	To() int
 | 
						To() int
 | 
				
			||||||
	// Weight returns the integer identifier of the weight/cost.
 | 
						// Mass returns the integer identifier of the weight/cost.
 | 
				
			||||||
	Weight() int
 | 
						Weight() int
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user