Compare commits
	
		
			13 Commits
		
	
	
		
			master
			...
			feature/ho
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| ae3ecb03c5 | |||
| ab3f05f013 | |||
| 5cbc0100d8 | |||
| 5696ac5574 | |||
| 8dc142b907 | |||
| 7dc40122b4 | |||
| 7639bfbe21 | |||
| 149555fb02 | |||
| 257fb07e94 | |||
| b493e10794 | |||
| de1d4fbaf0 | |||
| 859c1d7238 | |||
| 4fd93b6c9e | 
@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					source_md5="5efb9aac4566cc540675ab7478811cac"
 | 
				
			||||||
 | 
					dest_md5="f0bb815a493bfd51d2b236f5f5f2fc8b"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					source_md5="8aa11b5093dfa6e5ad8586cfd48b6e88"
 | 
				
			||||||
 | 
					dest_md5="1922a2eba76828665cd680a720666fe8"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					source_md5="8aa11b5093dfa6e5ad8586cfd48b6e88"
 | 
				
			||||||
 | 
					dest_md5="1922a2eba76828665cd680a720666fe8"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					source_md5="f5097ca7c211920e40c629bc583248e3"
 | 
				
			||||||
 | 
					dest_md5="0b20c79b6ad64f3fbed8b5ab994f4c8c"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					source_md5="57a52ebcb9eefc41ae7c7fe4b17f9929"
 | 
				
			||||||
 | 
					dest_md5="d81086922475a0a88eb18c5b63cfadc4"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					source_md5="6369531b32f45519d9bda64e00cdc847"
 | 
				
			||||||
 | 
					dest_md5="d6d9f94b469ca6b1de4c2ad1759450ed"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					source_md5="91820ac8ea2be3ece9880968e3383d5e"
 | 
				
			||||||
 | 
					dest_md5="1708c1f0340ca66cafbe9371c338ab53"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								client/.import/electus.png-a90a07dfed216f4ba27686034df2153e.stex
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					source_md5="2986d81638e869b47b08fc6a51e530eb"
 | 
				
			||||||
 | 
					dest_md5="fc9df6db0cb50f4e349620f975023c68"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								client/.import/lunaki.png-d46c842ee07941bd7d94068ea9489984.stex
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					source_md5="f13aaf1926c7461f574eff3379d1227a"
 | 
				
			||||||
 | 
					dest_md5="dd9c1dd4ee97dade3f8000d9c2984bd2"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								client/.import/regium.png-1a0832d2ba20f1f704b0231836336246.stex
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 545 B After Width: | Height: | Size: 545 B  | 
@ -2,15 +2,15 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
importer="texture"
 | 
					importer="texture"
 | 
				
			||||||
type="StreamTexture"
 | 
					type="StreamTexture"
 | 
				
			||||||
path="res://.import/dev_player.png-a3e490acef445550df71bca0ea3173dc.stex"
 | 
					path="res://.import/dev_player_1.png-6a7e17e32424a41520db4c795eece2ce.stex"
 | 
				
			||||||
metadata={
 | 
					metadata={
 | 
				
			||||||
"vram_texture": false
 | 
					"vram_texture": false
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[deps]
 | 
					[deps]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
source_file="res://art/entities/player/dev_player.png"
 | 
					source_file="res://art/entities/player/dev/dev_player_1.png"
 | 
				
			||||||
dest_files=[ "res://.import/dev_player.png-a3e490acef445550df71bca0ea3173dc.stex" ]
 | 
					dest_files=[ "res://.import/dev_player_1.png-6a7e17e32424a41520db4c795eece2ce.stex" ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[params]
 | 
					[params]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								client/art/entities/player/dev/dev_player_2.aseprite
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								client/art/entities/player/dev/dev_player_2.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 556 B  | 
							
								
								
									
										34
									
								
								client/art/entities/player/dev/dev_player_2.png.import
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,34 @@
 | 
				
			|||||||
 | 
					[remap]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					importer="texture"
 | 
				
			||||||
 | 
					type="StreamTexture"
 | 
				
			||||||
 | 
					path="res://.import/dev_player_2.png-24cb2fbb0bdff6cc7a030088bf9a60db.stex"
 | 
				
			||||||
 | 
					metadata={
 | 
				
			||||||
 | 
					"vram_texture": false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[deps]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					source_file="res://art/entities/player/dev/dev_player_2.png"
 | 
				
			||||||
 | 
					dest_files=[ "res://.import/dev_player_2.png-24cb2fbb0bdff6cc7a030088bf9a60db.stex" ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[params]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					compress/mode=0
 | 
				
			||||||
 | 
					compress/lossy_quality=0.7
 | 
				
			||||||
 | 
					compress/hdr_mode=0
 | 
				
			||||||
 | 
					compress/bptc_ldr=0
 | 
				
			||||||
 | 
					compress/normal_map=0
 | 
				
			||||||
 | 
					flags/repeat=0
 | 
				
			||||||
 | 
					flags/filter=false
 | 
				
			||||||
 | 
					flags/mipmaps=false
 | 
				
			||||||
 | 
					flags/anisotropic=false
 | 
				
			||||||
 | 
					flags/srgb=2
 | 
				
			||||||
 | 
					process/fix_alpha_border=true
 | 
				
			||||||
 | 
					process/premult_alpha=false
 | 
				
			||||||
 | 
					process/HDR_as_SRGB=false
 | 
				
			||||||
 | 
					process/invert_color=false
 | 
				
			||||||
 | 
					stream=false
 | 
				
			||||||
 | 
					size_limit=0
 | 
				
			||||||
 | 
					detect_3d=true
 | 
				
			||||||
 | 
					svg/scale=1.0
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								client/art/entities/player/dev/dev_player_3.aseprite
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								client/art/entities/player/dev/dev_player_3.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 562 B  | 
							
								
								
									
										34
									
								
								client/art/entities/player/dev/dev_player_3.png.import
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,34 @@
 | 
				
			|||||||
 | 
					[remap]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					importer="texture"
 | 
				
			||||||
 | 
					type="StreamTexture"
 | 
				
			||||||
 | 
					path="res://.import/dev_player_3.png-2b614bba7aea33ebd1625829f7dc4dc8.stex"
 | 
				
			||||||
 | 
					metadata={
 | 
				
			||||||
 | 
					"vram_texture": false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[deps]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					source_file="res://art/entities/player/dev/dev_player_3.png"
 | 
				
			||||||
 | 
					dest_files=[ "res://.import/dev_player_3.png-2b614bba7aea33ebd1625829f7dc4dc8.stex" ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[params]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					compress/mode=0
 | 
				
			||||||
 | 
					compress/lossy_quality=0.7
 | 
				
			||||||
 | 
					compress/hdr_mode=0
 | 
				
			||||||
 | 
					compress/bptc_ldr=0
 | 
				
			||||||
 | 
					compress/normal_map=0
 | 
				
			||||||
 | 
					flags/repeat=0
 | 
				
			||||||
 | 
					flags/filter=false
 | 
				
			||||||
 | 
					flags/mipmaps=false
 | 
				
			||||||
 | 
					flags/anisotropic=false
 | 
				
			||||||
 | 
					flags/srgb=2
 | 
				
			||||||
 | 
					process/fix_alpha_border=true
 | 
				
			||||||
 | 
					process/premult_alpha=false
 | 
				
			||||||
 | 
					process/HDR_as_SRGB=false
 | 
				
			||||||
 | 
					process/invert_color=false
 | 
				
			||||||
 | 
					stream=false
 | 
				
			||||||
 | 
					size_limit=0
 | 
				
			||||||
 | 
					detect_3d=true
 | 
				
			||||||
 | 
					svg/scale=1.0
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								client/art/entities/player/dev/dev_player_4.aseprite
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								client/art/entities/player/dev/dev_player_4.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 561 B  | 
							
								
								
									
										34
									
								
								client/art/entities/player/dev/dev_player_4.png.import
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,34 @@
 | 
				
			|||||||
 | 
					[remap]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					importer="texture"
 | 
				
			||||||
 | 
					type="StreamTexture"
 | 
				
			||||||
 | 
					path="res://.import/dev_player_4.png-75d7bdc3c0acf687884cfb7d56448f69.stex"
 | 
				
			||||||
 | 
					metadata={
 | 
				
			||||||
 | 
					"vram_texture": false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[deps]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					source_file="res://art/entities/player/dev/dev_player_4.png"
 | 
				
			||||||
 | 
					dest_files=[ "res://.import/dev_player_4.png-75d7bdc3c0acf687884cfb7d56448f69.stex" ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[params]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					compress/mode=0
 | 
				
			||||||
 | 
					compress/lossy_quality=0.7
 | 
				
			||||||
 | 
					compress/hdr_mode=0
 | 
				
			||||||
 | 
					compress/bptc_ldr=0
 | 
				
			||||||
 | 
					compress/normal_map=0
 | 
				
			||||||
 | 
					flags/repeat=0
 | 
				
			||||||
 | 
					flags/filter=false
 | 
				
			||||||
 | 
					flags/mipmaps=false
 | 
				
			||||||
 | 
					flags/anisotropic=false
 | 
				
			||||||
 | 
					flags/srgb=2
 | 
				
			||||||
 | 
					process/fix_alpha_border=true
 | 
				
			||||||
 | 
					process/premult_alpha=false
 | 
				
			||||||
 | 
					process/HDR_as_SRGB=false
 | 
				
			||||||
 | 
					process/invert_color=false
 | 
				
			||||||
 | 
					stream=false
 | 
				
			||||||
 | 
					size_limit=0
 | 
				
			||||||
 | 
					detect_3d=true
 | 
				
			||||||
 | 
					svg/scale=1.0
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								client/art/gui/banners/burningwall.aseprite
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								client/art/gui/banners/burningwall.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 783 B  | 
							
								
								
									
										34
									
								
								client/art/gui/banners/burningwall.png.import
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,34 @@
 | 
				
			|||||||
 | 
					[remap]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					importer="texture"
 | 
				
			||||||
 | 
					type="StreamTexture"
 | 
				
			||||||
 | 
					path="res://.import/burningwall.png-46bfd2d39d0cac96f39200d4c53851e9.stex"
 | 
				
			||||||
 | 
					metadata={
 | 
				
			||||||
 | 
					"vram_texture": false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[deps]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					source_file="res://art/gui/banners/burningwall.png"
 | 
				
			||||||
 | 
					dest_files=[ "res://.import/burningwall.png-46bfd2d39d0cac96f39200d4c53851e9.stex" ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[params]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					compress/mode=0
 | 
				
			||||||
 | 
					compress/lossy_quality=0.7
 | 
				
			||||||
 | 
					compress/hdr_mode=0
 | 
				
			||||||
 | 
					compress/bptc_ldr=0
 | 
				
			||||||
 | 
					compress/normal_map=0
 | 
				
			||||||
 | 
					flags/repeat=0
 | 
				
			||||||
 | 
					flags/filter=true
 | 
				
			||||||
 | 
					flags/mipmaps=false
 | 
				
			||||||
 | 
					flags/anisotropic=false
 | 
				
			||||||
 | 
					flags/srgb=2
 | 
				
			||||||
 | 
					process/fix_alpha_border=true
 | 
				
			||||||
 | 
					process/premult_alpha=false
 | 
				
			||||||
 | 
					process/HDR_as_SRGB=false
 | 
				
			||||||
 | 
					process/invert_color=false
 | 
				
			||||||
 | 
					stream=false
 | 
				
			||||||
 | 
					size_limit=0
 | 
				
			||||||
 | 
					detect_3d=true
 | 
				
			||||||
 | 
					svg/scale=1.0
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								client/art/gui/banners/electus.aseprite
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								client/art/gui/banners/electus.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.5 KiB  | 
							
								
								
									
										34
									
								
								client/art/gui/banners/electus.png.import
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,34 @@
 | 
				
			|||||||
 | 
					[remap]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					importer="texture"
 | 
				
			||||||
 | 
					type="StreamTexture"
 | 
				
			||||||
 | 
					path="res://.import/electus.png-a90a07dfed216f4ba27686034df2153e.stex"
 | 
				
			||||||
 | 
					metadata={
 | 
				
			||||||
 | 
					"vram_texture": false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[deps]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					source_file="res://art/gui/banners/electus.png"
 | 
				
			||||||
 | 
					dest_files=[ "res://.import/electus.png-a90a07dfed216f4ba27686034df2153e.stex" ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[params]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					compress/mode=0
 | 
				
			||||||
 | 
					compress/lossy_quality=0.7
 | 
				
			||||||
 | 
					compress/hdr_mode=0
 | 
				
			||||||
 | 
					compress/bptc_ldr=0
 | 
				
			||||||
 | 
					compress/normal_map=0
 | 
				
			||||||
 | 
					flags/repeat=0
 | 
				
			||||||
 | 
					flags/filter=true
 | 
				
			||||||
 | 
					flags/mipmaps=false
 | 
				
			||||||
 | 
					flags/anisotropic=false
 | 
				
			||||||
 | 
					flags/srgb=2
 | 
				
			||||||
 | 
					process/fix_alpha_border=true
 | 
				
			||||||
 | 
					process/premult_alpha=false
 | 
				
			||||||
 | 
					process/HDR_as_SRGB=false
 | 
				
			||||||
 | 
					process/invert_color=false
 | 
				
			||||||
 | 
					stream=false
 | 
				
			||||||
 | 
					size_limit=0
 | 
				
			||||||
 | 
					detect_3d=true
 | 
				
			||||||
 | 
					svg/scale=1.0
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								client/art/gui/banners/lunaki.aseprite
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								client/art/gui/banners/lunaki.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.3 KiB  | 
							
								
								
									
										34
									
								
								client/art/gui/banners/lunaki.png.import
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,34 @@
 | 
				
			|||||||
 | 
					[remap]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					importer="texture"
 | 
				
			||||||
 | 
					type="StreamTexture"
 | 
				
			||||||
 | 
					path="res://.import/lunaki.png-d46c842ee07941bd7d94068ea9489984.stex"
 | 
				
			||||||
 | 
					metadata={
 | 
				
			||||||
 | 
					"vram_texture": false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[deps]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					source_file="res://art/gui/banners/lunaki.png"
 | 
				
			||||||
 | 
					dest_files=[ "res://.import/lunaki.png-d46c842ee07941bd7d94068ea9489984.stex" ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[params]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					compress/mode=0
 | 
				
			||||||
 | 
					compress/lossy_quality=0.7
 | 
				
			||||||
 | 
					compress/hdr_mode=0
 | 
				
			||||||
 | 
					compress/bptc_ldr=0
 | 
				
			||||||
 | 
					compress/normal_map=0
 | 
				
			||||||
 | 
					flags/repeat=0
 | 
				
			||||||
 | 
					flags/filter=true
 | 
				
			||||||
 | 
					flags/mipmaps=false
 | 
				
			||||||
 | 
					flags/anisotropic=false
 | 
				
			||||||
 | 
					flags/srgb=2
 | 
				
			||||||
 | 
					process/fix_alpha_border=true
 | 
				
			||||||
 | 
					process/premult_alpha=false
 | 
				
			||||||
 | 
					process/HDR_as_SRGB=false
 | 
				
			||||||
 | 
					process/invert_color=false
 | 
				
			||||||
 | 
					stream=false
 | 
				
			||||||
 | 
					size_limit=0
 | 
				
			||||||
 | 
					detect_3d=true
 | 
				
			||||||
 | 
					svg/scale=1.0
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								client/art/gui/banners/regium.aseprite
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								client/art/gui/banners/regium.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 961 B  | 
							
								
								
									
										34
									
								
								client/art/gui/banners/regium.png.import
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,34 @@
 | 
				
			|||||||
 | 
					[remap]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					importer="texture"
 | 
				
			||||||
 | 
					type="StreamTexture"
 | 
				
			||||||
 | 
					path="res://.import/regium.png-1a0832d2ba20f1f704b0231836336246.stex"
 | 
				
			||||||
 | 
					metadata={
 | 
				
			||||||
 | 
					"vram_texture": false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[deps]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					source_file="res://art/gui/banners/regium.png"
 | 
				
			||||||
 | 
					dest_files=[ "res://.import/regium.png-1a0832d2ba20f1f704b0231836336246.stex" ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[params]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					compress/mode=0
 | 
				
			||||||
 | 
					compress/lossy_quality=0.7
 | 
				
			||||||
 | 
					compress/hdr_mode=0
 | 
				
			||||||
 | 
					compress/bptc_ldr=0
 | 
				
			||||||
 | 
					compress/normal_map=0
 | 
				
			||||||
 | 
					flags/repeat=0
 | 
				
			||||||
 | 
					flags/filter=true
 | 
				
			||||||
 | 
					flags/mipmaps=false
 | 
				
			||||||
 | 
					flags/anisotropic=false
 | 
				
			||||||
 | 
					flags/srgb=2
 | 
				
			||||||
 | 
					process/fix_alpha_border=true
 | 
				
			||||||
 | 
					process/premult_alpha=false
 | 
				
			||||||
 | 
					process/HDR_as_SRGB=false
 | 
				
			||||||
 | 
					process/invert_color=false
 | 
				
			||||||
 | 
					stream=false
 | 
				
			||||||
 | 
					size_limit=0
 | 
				
			||||||
 | 
					detect_3d=true
 | 
				
			||||||
 | 
					svg/scale=1.0
 | 
				
			||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
[gd_scene load_steps=3 format=2]
 | 
					[gd_scene load_steps=3 format=2]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[ext_resource path="res://art/entities/player/dev_player.png" type="Texture" id=1]
 | 
					[ext_resource path="res://art/entities/player/dev/dev_player_1.png" type="Texture" id=1]
 | 
				
			||||||
[ext_resource path="res://scripts/entities/Player.gd" type="Script" id=2]
 | 
					[ext_resource path="res://scripts/entities/Player.gd" type="Script" id=2]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[node name="Player" type="KinematicBody2D"]
 | 
					[node name="Player" type="KinematicBody2D"]
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,8 @@
 | 
				
			|||||||
[gd_scene load_steps=2 format=2]
 | 
					[gd_scene load_steps=3 format=2]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[ext_resource path="res://art/entities/player/dev_player.png" type="Texture" id=1]
 | 
					[ext_resource path="res://art/entities/player/dev/dev_player_1.png" type="Texture" id=1]
 | 
				
			||||||
 | 
					[ext_resource path="res://scripts/entities/PlayerPuppet.gd" type="Script" id=2]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[node name="PlayerPuppet" type="Sprite"]
 | 
					[node name="PlayerPuppet" type="Sprite"]
 | 
				
			||||||
texture = ExtResource( 1 )
 | 
					texture = ExtResource( 1 )
 | 
				
			||||||
 | 
					script = ExtResource( 2 )
 | 
				
			||||||
 | 
				
			|||||||
@ -106,6 +106,7 @@ config/icon="res://icon.png"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
Nakama="*res://addons/com.heroiclabs.nakama/Nakama.gd"
 | 
					Nakama="*res://addons/com.heroiclabs.nakama/Nakama.gd"
 | 
				
			||||||
ServerConnection="*res://scripts/singletons/ServerConnection.gd"
 | 
					ServerConnection="*res://scripts/singletons/ServerConnection.gd"
 | 
				
			||||||
 | 
					GameData="*res://scripts/singletons/GameData.gd"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[input]
 | 
					[input]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										58
									
								
								client/scenes/CharacterCreation.tscn
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,58 @@
 | 
				
			|||||||
 | 
					[gd_scene load_steps=5 format=2]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[ext_resource path="res://art/gui/banners/burningwall.png" type="Texture" id=1]
 | 
				
			||||||
 | 
					[ext_resource path="res://scripts/menus/character_creation/FactionButtons.gd" type="Script" id=2]
 | 
				
			||||||
 | 
					[ext_resource path="res://scripts/menus/character_creation/NameEdit.gd" type="Script" id=3]
 | 
				
			||||||
 | 
					[ext_resource path="res://scripts/menus/character_creation/CharacterCreation.gd" type="Script" id=4]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[node name="CharacterCreation" type="VBoxContainer"]
 | 
				
			||||||
 | 
					anchor_right = 1.0
 | 
				
			||||||
 | 
					anchor_bottom = 1.0
 | 
				
			||||||
 | 
					script = ExtResource( 4 )
 | 
				
			||||||
 | 
					__meta__ = {
 | 
				
			||||||
 | 
					"_edit_use_anchors_": false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					nameTextEdit = NodePath("NameEdit")
 | 
				
			||||||
 | 
					factionButtonsNode = NodePath("FactionButtons")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[node name="NameLabel" type="Label" parent="."]
 | 
				
			||||||
 | 
					margin_right = 1024.0
 | 
				
			||||||
 | 
					margin_bottom = 14.0
 | 
				
			||||||
 | 
					text = "The Legacy of"
 | 
				
			||||||
 | 
					align = 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[node name="NameEdit" type="LineEdit" parent="."]
 | 
				
			||||||
 | 
					margin_top = 18.0
 | 
				
			||||||
 | 
					margin_right = 1024.0
 | 
				
			||||||
 | 
					margin_bottom = 42.0
 | 
				
			||||||
 | 
					align = 1
 | 
				
			||||||
 | 
					placeholder_text = "Character Name"
 | 
				
			||||||
 | 
					script = ExtResource( 3 )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[node name="FactionLabel" type="Label" parent="."]
 | 
				
			||||||
 | 
					margin_top = 46.0
 | 
				
			||||||
 | 
					margin_right = 1024.0
 | 
				
			||||||
 | 
					margin_bottom = 60.0
 | 
				
			||||||
 | 
					text = "Select your family"
 | 
				
			||||||
 | 
					align = 1
 | 
				
			||||||
 | 
					uppercase = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[node name="FactionButtons" type="HBoxContainer" parent="."]
 | 
				
			||||||
 | 
					margin_top = 64.0
 | 
				
			||||||
 | 
					margin_right = 1024.0
 | 
				
			||||||
 | 
					margin_bottom = 198.0
 | 
				
			||||||
 | 
					alignment = 1
 | 
				
			||||||
 | 
					script = ExtResource( 2 )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[node name="Button" type="Button" parent="FactionButtons"]
 | 
				
			||||||
 | 
					margin_left = 474.0
 | 
				
			||||||
 | 
					margin_right = 550.0
 | 
				
			||||||
 | 
					margin_bottom = 134.0
 | 
				
			||||||
 | 
					icon = ExtResource( 1 )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[node name="Button" type="Button" parent="."]
 | 
				
			||||||
 | 
					margin_top = 202.0
 | 
				
			||||||
 | 
					margin_right = 1024.0
 | 
				
			||||||
 | 
					margin_bottom = 222.0
 | 
				
			||||||
 | 
					text = "Join World"
 | 
				
			||||||
 | 
					[connection signal="button_down" from="Button" to="." method="_on_Button_button_down"]
 | 
				
			||||||
							
								
								
									
										13
									
								
								client/scripts/entities/PlayerPuppet.gd
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					extends Sprite
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export var faction = 1 setget set_faction, get_faction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func _ready():
 | 
				
			||||||
 | 
						set_faction(faction)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func set_faction(new_faction):
 | 
				
			||||||
 | 
						faction = new_faction
 | 
				
			||||||
 | 
						texture = load("res://art/entities/player/dev/dev_player_" + str(faction) + ".png")
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
					func get_faction():
 | 
				
			||||||
 | 
						return faction
 | 
				
			||||||
							
								
								
									
										16
									
								
								client/scripts/menus/character_creation/CharacterCreation.gd
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,16 @@
 | 
				
			|||||||
 | 
					extends Node
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export(NodePath) var nameTextEdit
 | 
				
			||||||
 | 
					export(NodePath) var factionButtonsNode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					onready var nameEdit : LineEdit = get_node(nameTextEdit)
 | 
				
			||||||
 | 
					onready var factionButtons = get_node(factionButtonsNode)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func _on_Button_button_down():
 | 
				
			||||||
 | 
						if nameEdit.text != "":
 | 
				
			||||||
 | 
							if factionButtons.currently_selected:
 | 
				
			||||||
 | 
								for i in range(1,len(GameData.factions)):
 | 
				
			||||||
 | 
									if GameData.factions[i] == factionButtons.currently_selected:
 | 
				
			||||||
 | 
										var created_char = yield(ServerConnection.create_character_async(nameEdit.text, i), "completed")
 | 
				
			||||||
 | 
										if created_char:
 | 
				
			||||||
 | 
											get_tree().change_scene("res://scenes/World.tscn")
 | 
				
			||||||
							
								
								
									
										20
									
								
								client/scripts/menus/character_creation/FactionButtons.gd
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					extends Node
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					signal selection_updated(faction)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var currently_selected : String
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func _ready():
 | 
				
			||||||
 | 
						get_child(0).queue_free()
 | 
				
			||||||
 | 
						for faction in GameData.factions:
 | 
				
			||||||
 | 
							if faction == "Electus":
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							var faction_button = Button.new()
 | 
				
			||||||
 | 
							faction_button.icon = load("res://art/gui/banners/" + faction.to_lower() + ".png")
 | 
				
			||||||
 | 
							faction_button.connect("button_down", self, "on_faction_select", [faction])
 | 
				
			||||||
 | 
							add_child(faction_button)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func on_faction_select(faction):
 | 
				
			||||||
 | 
						currently_selected = faction
 | 
				
			||||||
 | 
						emit_signal("selection_updated", faction)
 | 
				
			||||||
							
								
								
									
										14
									
								
								client/scripts/menus/character_creation/NameEdit.gd
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					extends LineEdit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var invalid_chars = " '.,;/\\,[](){}!@#$%^&*-=|_+1234567890\""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func _ready():
 | 
				
			||||||
 | 
						connect("text_changed", self, "validate_name")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func validate_name(name):
 | 
				
			||||||
 | 
						var cursor_pos = caret_position
 | 
				
			||||||
 | 
						for character in invalid_chars:
 | 
				
			||||||
 | 
							if character in text:
 | 
				
			||||||
 | 
								text = text.replace(character, "")
 | 
				
			||||||
 | 
								caret_position = cursor_pos
 | 
				
			||||||
							
								
								
									
										8
									
								
								client/scripts/singletons/GameData.gd
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					extends Node
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var factions = [
 | 
				
			||||||
 | 
						"Burningwall",
 | 
				
			||||||
 | 
						"Lunaki",
 | 
				
			||||||
 | 
						"Regium",
 | 
				
			||||||
 | 
						"Electus"
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
@ -4,19 +4,21 @@ signal tile_update(tile_data)
 | 
				
			|||||||
signal player_joined(user_id)
 | 
					signal player_joined(user_id)
 | 
				
			||||||
signal player_left(user_id)
 | 
					signal player_left(user_id)
 | 
				
			||||||
signal player_pos_update(user_id, pos)
 | 
					signal player_pos_update(user_id, pos)
 | 
				
			||||||
 | 
					signal player_state_update(user_id, user_name, faction)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const KEY := "defaultkey"
 | 
					const KEY := "defaultkey"
 | 
				
			||||||
const SERVER_ENDPOINT := "nakama.cloudsumu.com"
 | 
					const SERVER_ENDPOINT := "nakama.cloudsumu.com"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var _session : NakamaSession
 | 
					var _session : NakamaSession
 | 
				
			||||||
var _client : NakamaClient = Nakama.create_client(KEY, SERVER_ENDPOINT, 7350, "http")
 | 
					var _client : NakamaClient = Nakama.create_client(KEY, SERVER_ENDPOINT, 7350, "http", Nakama.DEFAULT_TIMEOUT, NakamaLogger.LOG_LEVEL.ERROR)
 | 
				
			||||||
var _socket : NakamaSocket
 | 
					var _socket : NakamaSocket
 | 
				
			||||||
var _precenses : Dictionary = {}
 | 
					var _precenses : Dictionary = {}
 | 
				
			||||||
var _world_id
 | 
					var _world_id
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum OPCODE {
 | 
					enum OPCODE {
 | 
				
			||||||
	tile_update = 1,
 | 
						tile_update = 1,
 | 
				
			||||||
	update_position = 2
 | 
						update_position = 2,
 | 
				
			||||||
 | 
						player_state = 3
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func authenticate_async(email : String, password : String) -> NakamaException:
 | 
					func authenticate_async(email : String, password : String) -> NakamaException:
 | 
				
			||||||
@ -62,6 +64,11 @@ func join_world_async() -> Dictionary:
 | 
				
			|||||||
	var match_join_result : NakamaRTAPI.Match = yield(_socket.join_match_async(world.payload), "completed")
 | 
						var match_join_result : NakamaRTAPI.Match = yield(_socket.join_match_async(world.payload), "completed")
 | 
				
			||||||
	if match_join_result.is_exception():
 | 
						if match_join_result.is_exception():
 | 
				
			||||||
		print("Join match error: %s - %s" % [match_join_result.exception.status_code, match_join_result.exception.message])
 | 
							print("Join match error: %s - %s" % [match_join_result.exception.status_code, match_join_result.exception.message])
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							# THIS SECTION NEEDS TO BE UPADTED TO BE DECOUPLED
 | 
				
			||||||
 | 
							# IT SHOULD ALSO NOT CATCH ALL JOIN ERRORS!
 | 
				
			||||||
 | 
							get_tree().change_scene("res://scenes/CharacterCreation.tscn")
 | 
				
			||||||
 | 
							
 | 
				
			||||||
		return {}
 | 
							return {}
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
	_world_id = world.payload
 | 
						_world_id = world.payload
 | 
				
			||||||
@ -95,7 +102,17 @@ func _on_socket_received_match_state(match_state: NakamaRTAPI.MatchData):
 | 
				
			|||||||
		OPCODE.update_position:
 | 
							OPCODE.update_position:
 | 
				
			||||||
			var pos_data = JSON.parse(match_state.data).result
 | 
								var pos_data = JSON.parse(match_state.data).result
 | 
				
			||||||
			emit_signal("player_pos_update", pos_data["player"], Vector2(float(pos_data["x"]), float(pos_data["y"])))
 | 
								emit_signal("player_pos_update", pos_data["player"], Vector2(float(pos_data["x"]), float(pos_data["y"])))
 | 
				
			||||||
 | 
							OPCODE.player_state:
 | 
				
			||||||
 | 
								var state_data = JSON.parse(match_state.data).result
 | 
				
			||||||
 | 
								emit_signal("player_state_update", state_data["player"], state_data["name"], state_data["faction"])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func send_player_position(position : Vector2) -> void:
 | 
					func send_player_position(position : Vector2) -> void:
 | 
				
			||||||
	_socket.send_match_state_async(_world_id, OPCODE.update_position, JSON.print({X = str(position.x), Y = str(position.y)}))
 | 
						_socket.send_match_state_async(_world_id, OPCODE.update_position, JSON.print({X = str(position.x), Y = str(position.y)}))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func create_character_async(name : String, faction : int) -> Dictionary:
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						var character_response : NakamaAPI.ApiRpc = yield(_client.rpc_async(_session, "create_character", JSON.print({"name":name, "faction" : faction})), "completed")
 | 
				
			||||||
 | 
						if character_response.is_exception():
 | 
				
			||||||
 | 
							print("Create character error occured: %s" % character_response.exception.message)
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						return true
 | 
				
			||||||
 | 
				
			|||||||
@ -11,6 +11,7 @@ func _ready():
 | 
				
			|||||||
	ServerConnection.connect("player_joined", self, "on_player_join")
 | 
						ServerConnection.connect("player_joined", self, "on_player_join")
 | 
				
			||||||
	ServerConnection.connect("player_left", self, "on_player_leave")
 | 
						ServerConnection.connect("player_left", self, "on_player_leave")
 | 
				
			||||||
	ServerConnection.connect("player_pos_update", self, "on_player_pos_update")
 | 
						ServerConnection.connect("player_pos_update", self, "on_player_pos_update")
 | 
				
			||||||
 | 
						ServerConnection.connect("player_state_update", self, "on_player_state_update")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func on_player_join(user_id):
 | 
					func on_player_join(user_id):
 | 
				
			||||||
@ -29,3 +30,12 @@ func on_player_pos_update(user_id, pos):
 | 
				
			|||||||
	if user_id != ServerConnection._session.user_id:
 | 
						if user_id != ServerConnection._session.user_id:
 | 
				
			||||||
		var player_puppet : Node2D = puppets[user_id]
 | 
							var player_puppet : Node2D = puppets[user_id]
 | 
				
			||||||
		player_puppet.global_position = pos
 | 
							player_puppet.global_position = pos
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func on_player_state_update(user_id, user_name, faction):
 | 
				
			||||||
 | 
						if user_id != ServerConnection._session.user_id:
 | 
				
			||||||
 | 
							if user_id in puppets:
 | 
				
			||||||
 | 
								var player_puppet : Node2D = puppets[user_id]
 | 
				
			||||||
 | 
								player_puppet.name = user_name
 | 
				
			||||||
 | 
								player_puppet.set_faction(faction)
 | 
				
			||||||
 | 
							else:
 | 
				
			||||||
 | 
								print("Could not update player state for nonexisting player!")
 | 
				
			||||||
 | 
				
			|||||||
@ -20,6 +20,8 @@ const (
 | 
				
			|||||||
	OpCodeTileUpdate = 1
 | 
						OpCodeTileUpdate = 1
 | 
				
			||||||
	// OpCodeUpdatePosition is used for player position updates
 | 
						// OpCodeUpdatePosition is used for player position updates
 | 
				
			||||||
	OpCodeUpdatePosition = 2
 | 
						OpCodeUpdatePosition = 2
 | 
				
			||||||
 | 
						// OpCodePlayerState is for player object updates
 | 
				
			||||||
 | 
						OpCodePlayerState = 3
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Match is the object registered
 | 
					// Match is the object registered
 | 
				
			||||||
@ -72,7 +74,19 @@ func (m *Match) MatchJoinAttempt(ctx context.Context, logger runtime.Logger, db
 | 
				
			|||||||
	if _, ok := mState.presences[presence.GetUserId()]; ok {
 | 
						if _, ok := mState.presences[presence.GetUserId()]; ok {
 | 
				
			||||||
		return mState, false, "User already logged in."
 | 
							return mState, false, "User already logged in."
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							dataExist, err := entities.PlayerDataExists(ctx, nk, presence.GetUserId())
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								logger.Error(err.Error())
 | 
				
			||||||
 | 
								return mState, false, err.Error()
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if dataExist {
 | 
				
			||||||
			return mState, true, ""
 | 
								return mState, true, ""
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								return mState, false, "User does not have a character!"
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -89,12 +103,20 @@ func (m *Match) MatchJoin(ctx context.Context, logger runtime.Logger, db *sql.DB
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		// Add presence to map
 | 
							// Add presence to map
 | 
				
			||||||
		mState.presences[precense.GetUserId()] = precense
 | 
							mState.presences[precense.GetUserId()] = precense
 | 
				
			||||||
 | 
							player, loadPlayerErr := entities.LoadPlayer(ctx, nk, precense)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		player := entities.PlayerEntity{
 | 
							if loadPlayerErr != nil {
 | 
				
			||||||
 | 
								logger.Error(loadPlayerErr.Error())
 | 
				
			||||||
 | 
								player = &entities.PlayerEntity{
 | 
				
			||||||
				X:        16,
 | 
									X:        16,
 | 
				
			||||||
				Y:        16,
 | 
									Y:        16,
 | 
				
			||||||
 | 
									Name:     "ERROR",
 | 
				
			||||||
				Presence: precense,
 | 
									Presence: precense,
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								player.X = 16
 | 
				
			||||||
 | 
								player.Y = 16
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if jsonObj, err := player.GetPosJSON(); err != nil {
 | 
							if jsonObj, err := player.GetPosJSON(); err != nil {
 | 
				
			||||||
			logger.Error(err.Error())
 | 
								logger.Error(err.Error())
 | 
				
			||||||
@ -102,9 +124,16 @@ func (m *Match) MatchJoin(ctx context.Context, logger runtime.Logger, db *sql.DB
 | 
				
			|||||||
			if sendErr := dispatcher.BroadcastMessage(OpCodeUpdatePosition, jsonObj, []runtime.Presence{precense}, player.Presence, true); sendErr != nil {
 | 
								if sendErr := dispatcher.BroadcastMessage(OpCodeUpdatePosition, jsonObj, []runtime.Presence{precense}, player.Presence, true); sendErr != nil {
 | 
				
			||||||
				logger.Error(sendErr.Error())
 | 
									logger.Error(sendErr.Error())
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								stateJSON, _ := player.GetStateJSON()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// Send player state to clients
 | 
				
			||||||
 | 
								if sendErr := dispatcher.BroadcastMessage(OpCodePlayerState, stateJSON, mState.GetPrecenseList(), player.Presence, true); sendErr != nil {
 | 
				
			||||||
 | 
									logger.Error(sendErr.Error())
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		mState.players[precense.GetUserId()] = player
 | 
							mState.players[precense.GetUserId()] = *player
 | 
				
			||||||
 | 
							logger.Info(fmt.Sprintf("%s joined match '%s'!", player.Presence.GetUsername(), ctx.Value(runtime.RUNTIME_CTX_MATCH_ID).(string)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Get intial tile data around player
 | 
							// Get intial tile data around player
 | 
				
			||||||
		if regionData, err := mState.worldMap.GetJSONRegionAround(player.X, player.Y, maxRenderDistance); err != nil {
 | 
							if regionData, err := mState.worldMap.GetJSONRegionAround(player.X, player.Y, maxRenderDistance); err != nil {
 | 
				
			||||||
@ -116,6 +145,7 @@ func (m *Match) MatchJoin(ctx context.Context, logger runtime.Logger, db *sql.DB
 | 
				
			|||||||
				logger.Error(sendErr.Error())
 | 
									logger.Error(sendErr.Error())
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for _, otherPlayer := range mState.players {
 | 
							for _, otherPlayer := range mState.players {
 | 
				
			||||||
			// Broadcast player data to client
 | 
								// Broadcast player data to client
 | 
				
			||||||
			if jsonObj, err := otherPlayer.GetPosJSON(); err != nil {
 | 
								if jsonObj, err := otherPlayer.GetPosJSON(); err != nil {
 | 
				
			||||||
@ -158,18 +188,20 @@ func (m *Match) MatchLoop(ctx context.Context, logger runtime.Logger, db *sql.DB
 | 
				
			|||||||
	for _, message := range messages {
 | 
						for _, message := range messages {
 | 
				
			||||||
		if message.GetOpCode() == OpCodeUpdatePosition {
 | 
							if message.GetOpCode() == OpCodeUpdatePosition {
 | 
				
			||||||
			player := mState.players[message.GetUserId()]
 | 
								player := mState.players[message.GetUserId()]
 | 
				
			||||||
 | 
								if player.Presence != nil {
 | 
				
			||||||
				if response, err := player.ParsePositionRequest(message.GetData()); err == nil {
 | 
									if response, err := player.ParsePositionRequest(message.GetData()); err == nil {
 | 
				
			||||||
					player.UpdateBasedOnResponse(response)
 | 
										player.UpdateBasedOnResponse(response)
 | 
				
			||||||
					if jsonObject, err := player.GetPosJSON(); err == nil {
 | 
										if jsonObject, err := player.GetPosJSON(); err == nil {
 | 
				
			||||||
						dispatcher.BroadcastMessage(OpCodeUpdatePosition, jsonObject, mState.GetPrecenseList(), player.Presence, false)
 | 
											dispatcher.BroadcastMessage(OpCodeUpdatePosition, jsonObject, mState.GetPrecenseList(), player.Presence, false)
 | 
				
			||||||
					logger.Info("Yes")
 | 
					 | 
				
			||||||
					} else {
 | 
										} else {
 | 
				
			||||||
						logger.Error(fmt.Sprintf("Failed to get player json: %s", err.Error))
 | 
											logger.Error(fmt.Sprintf("Failed to get player json: %s", err.Error))
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					logger.Error(fmt.Sprintf("Failed to parse update pos request: %s", err.Error))
 | 
										logger.Error(fmt.Sprintf("Failed to parse update pos request: %s", err.Error))
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									logger.Warn(fmt.Sprintf("Attempted to update the position of a player (%s) that does not exist", message.GetUsername()))
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return mState
 | 
						return mState
 | 
				
			||||||
 | 
				
			|||||||
@ -1,15 +1,24 @@
 | 
				
			|||||||
package entities
 | 
					package entities
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
	"encoding/json"
 | 
						"encoding/json"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"github.com/heroiclabs/nakama-common/runtime"
 | 
						"github.com/heroiclabs/nakama-common/runtime"
 | 
				
			||||||
 | 
						"github.com/josephbmanley/family/server/plugin/gameworld"
 | 
				
			||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type PlayerSaveData struct {
 | 
				
			||||||
 | 
						Faction int
 | 
				
			||||||
 | 
						Name    string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// PlayerEntity is the go struct representing the player's location
 | 
					// PlayerEntity is the go struct representing the player's location
 | 
				
			||||||
type PlayerEntity struct {
 | 
					type PlayerEntity struct {
 | 
				
			||||||
	Presence runtime.Presence
 | 
						Presence runtime.Presence
 | 
				
			||||||
 | 
						Faction  gameworld.Faction
 | 
				
			||||||
 | 
						Name     string
 | 
				
			||||||
	X        float64
 | 
						X        float64
 | 
				
			||||||
	Y        float64
 | 
						Y        float64
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -20,6 +29,108 @@ type PlayerPosResponse struct {
 | 
				
			|||||||
	Y string
 | 
						Y string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// PlayerDataExists checks if precense has saved data
 | 
				
			||||||
 | 
					func PlayerDataExists(ctx context.Context, nk runtime.NakamaModule, userID string) (bool, error) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Reads := []*runtime.StorageRead{
 | 
				
			||||||
 | 
							&runtime.StorageRead{
 | 
				
			||||||
 | 
								Collection: "playerdata",
 | 
				
			||||||
 | 
								Key:        "data",
 | 
				
			||||||
 | 
								UserID:     userID,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						records, err := nk.StorageRead(ctx, Reads)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return false, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, record := range records {
 | 
				
			||||||
 | 
							if record.Key == "data" {
 | 
				
			||||||
 | 
								return true, nil
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return false, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// LoadPlayer creates player object
 | 
				
			||||||
 | 
					func LoadPlayer(ctx context.Context, nk runtime.NakamaModule, presence runtime.Presence) (*PlayerEntity, error) {
 | 
				
			||||||
 | 
						player := &PlayerEntity{Presence: presence}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Read storage
 | 
				
			||||||
 | 
						PlayerReads := []*runtime.StorageRead{
 | 
				
			||||||
 | 
							&runtime.StorageRead{
 | 
				
			||||||
 | 
								Collection: "playerdata",
 | 
				
			||||||
 | 
								Key:        "data",
 | 
				
			||||||
 | 
								UserID:     player.Presence.GetUserId(),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						records, err := nk.StorageRead(ctx, PlayerReads)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return player, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Load storage records into object
 | 
				
			||||||
 | 
						for _, record := range records {
 | 
				
			||||||
 | 
							switch record.Key {
 | 
				
			||||||
 | 
							case "data":
 | 
				
			||||||
 | 
								responseData := PlayerSaveData{}
 | 
				
			||||||
 | 
								err := json.Unmarshal([]byte(record.Value), &responseData)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return player, err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								player.Name = responseData.Name
 | 
				
			||||||
 | 
								player.Faction = gameworld.Faction(responseData.Faction)
 | 
				
			||||||
 | 
								player.X = 16.0
 | 
				
			||||||
 | 
								player.Y = 16.0
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return player, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// GetPosJSON returns the player's position as a JSON object
 | 
				
			||||||
 | 
					func (p *PlayerEntity) GetPosJSON() ([]byte, error) {
 | 
				
			||||||
 | 
						playerMap := map[string]string{
 | 
				
			||||||
 | 
							"player": p.Presence.GetUserId(),
 | 
				
			||||||
 | 
							"x":      fmt.Sprintf("%f", p.X),
 | 
				
			||||||
 | 
							"y":      fmt.Sprintf("%f", p.Y),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						jsonData, err := json.Marshal(playerMap)
 | 
				
			||||||
 | 
						return jsonData, err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Save passes the precensce id to SaveUserID
 | 
				
			||||||
 | 
					func (p *PlayerEntity) Save(ctx context.Context, nk runtime.NakamaModule) error {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return p.SaveUserID(ctx, nk, p.Presence.GetUserId())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SaveUserID saves player data to nakama
 | 
				
			||||||
 | 
					func (p *PlayerEntity) SaveUserID(ctx context.Context, nk runtime.NakamaModule, userID string) error {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						saveData := PlayerSaveData{
 | 
				
			||||||
 | 
							Name:    p.Name,
 | 
				
			||||||
 | 
							Faction: int(p.Faction),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						saveJSON, err := json.Marshal(saveData)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						PlayerWrites := []*runtime.StorageWrite{
 | 
				
			||||||
 | 
							&runtime.StorageWrite{
 | 
				
			||||||
 | 
								Collection: "playerdata",
 | 
				
			||||||
 | 
								Key:        "data",
 | 
				
			||||||
 | 
								Value:      string(saveJSON),
 | 
				
			||||||
 | 
								UserID:     userID,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_, err = nk.StorageWrite(ctx, PlayerWrites)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ParsePositionRequest parses data from client
 | 
					// ParsePositionRequest parses data from client
 | 
				
			||||||
func (p *PlayerEntity) ParsePositionRequest(data []byte) (PlayerPosResponse, error) {
 | 
					func (p *PlayerEntity) ParsePositionRequest(data []byte) (PlayerPosResponse, error) {
 | 
				
			||||||
	var response PlayerPosResponse
 | 
						var response PlayerPosResponse
 | 
				
			||||||
@ -43,12 +154,12 @@ func (p *PlayerEntity) UpdateBasedOnResponse(response PlayerPosResponse) error {
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetPosJSON returns the player's position as a JSON object
 | 
					// GetStateJSON builds a json object for player state
 | 
				
			||||||
func (p *PlayerEntity) GetPosJSON() ([]byte, error) {
 | 
					func (p *PlayerEntity) GetStateJSON() ([]byte, error) {
 | 
				
			||||||
	playerMap := map[string]string{
 | 
						playerMap := map[string]string{
 | 
				
			||||||
		"player":  p.Presence.GetUserId(),
 | 
							"player":  p.Presence.GetUserId(),
 | 
				
			||||||
		"x":      fmt.Sprintf("%f", p.X),
 | 
							"name":    p.Name,
 | 
				
			||||||
		"y":      fmt.Sprintf("%f", p.Y),
 | 
							"faction": strconv.Itoa(int(p.Faction)),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	jsonData, err := json.Marshal(playerMap)
 | 
						jsonData, err := json.Marshal(playerMap)
 | 
				
			||||||
	return jsonData, err
 | 
						return jsonData, err
 | 
				
			||||||
 | 
				
			|||||||
@ -20,5 +20,9 @@ func InitModule(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runti
 | 
				
			|||||||
		logger.Error("Unable to register: %v", err)
 | 
							logger.Error("Unable to register: %v", err)
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if err := initializer.RegisterRpc("create_character", rpc.CreateCharacter); err != nil {
 | 
				
			||||||
 | 
							logger.Error("Unable to register: %v", err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										10
									
								
								server/plugin/gameworld/gameworld.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					package gameworld
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Faction int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						FactionBurningWall = 1
 | 
				
			||||||
 | 
						FactionLunaki      = 2
 | 
				
			||||||
 | 
						FactionRegium      = 3
 | 
				
			||||||
 | 
						FactionElectus     = 4
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
@ -14,6 +14,7 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a
 | 
				
			|||||||
github.com/heroiclabs/nakama-common v1.5.1 h1:ViCm9AvYYdQOCSKEa34SuSQ80JyZOHl6ODawESWf2wk=
 | 
					github.com/heroiclabs/nakama-common v1.5.1 h1:ViCm9AvYYdQOCSKEa34SuSQ80JyZOHl6ODawESWf2wk=
 | 
				
			||||||
github.com/heroiclabs/nakama-common v1.5.1/go.mod h1:nZAXHdeo4SyPlCyf7pU9rCVizxEhBF74gt7teDe/EaQ=
 | 
					github.com/heroiclabs/nakama-common v1.5.1/go.mod h1:nZAXHdeo4SyPlCyf7pU9rCVizxEhBF74gt7teDe/EaQ=
 | 
				
			||||||
github.com/heroiclabs/nakama-common v1.7.2 h1:FQedePGCorBl3tXW4Ro8+XLGbEDQfGrT5Tb07j1UaLc=
 | 
					github.com/heroiclabs/nakama-common v1.7.2 h1:FQedePGCorBl3tXW4Ro8+XLGbEDQfGrT5Tb07j1UaLc=
 | 
				
			||||||
 | 
					github.com/heroiclabs/nakama-common v1.7.3 h1:HksdpzLdSzfbOGRlrHgZIz+dPXrM9oaWrIEZXnWW3eE=
 | 
				
			||||||
github.com/josephbmanley/family v0.0.0-20200815220504-0d9d05943cef h1:6oijVkew6eKI1fGE+YMaxmiNlp/hkN9wDpStoid9/ZI=
 | 
					github.com/josephbmanley/family v0.0.0-20200815220504-0d9d05943cef h1:6oijVkew6eKI1fGE+YMaxmiNlp/hkN9wDpStoid9/ZI=
 | 
				
			||||||
github.com/josephbmanley/family v0.0.0-20200816202226-abfb0f428423 h1:ynsJFMYkfs3JspzvLCfmPGJwdKY/4QeX457U0+y4J1I=
 | 
					github.com/josephbmanley/family v0.0.0-20200816202226-abfb0f428423 h1:ynsJFMYkfs3JspzvLCfmPGJwdKY/4QeX457U0+y4J1I=
 | 
				
			||||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
 | 
					github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
 | 
				
			||||||
 | 
				
			|||||||
@ -3,7 +3,11 @@ package rpc
 | 
				
			|||||||
import (
 | 
					import (
 | 
				
			||||||
	"context"
 | 
						"context"
 | 
				
			||||||
	"database/sql"
 | 
						"database/sql"
 | 
				
			||||||
 | 
						"encoding/json"
 | 
				
			||||||
 | 
						"errors"
 | 
				
			||||||
	"github.com/heroiclabs/nakama-common/runtime"
 | 
						"github.com/heroiclabs/nakama-common/runtime"
 | 
				
			||||||
 | 
						"github.com/josephbmanley/family/server/plugin/entities"
 | 
				
			||||||
 | 
						"github.com/josephbmanley/family/server/plugin/gameworld"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func getFirstWorld(ctx context.Context, logger runtime.Logger, nk runtime.NakamaModule) (string, error) {
 | 
					func getFirstWorld(ctx context.Context, logger runtime.Logger, nk runtime.NakamaModule) (string, error) {
 | 
				
			||||||
@ -47,3 +51,40 @@ func GetWorldId(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runti
 | 
				
			|||||||
	matchID, err := getFirstWorld(ctx, logger, nk)
 | 
						matchID, err := getFirstWorld(ctx, logger, nk)
 | 
				
			||||||
	return matchID, err
 | 
						return matchID, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func CreateCharacter(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, payload string) (string, error) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						userID, ok := ctx.Value(runtime.RUNTIME_CTX_USER_ID).(string)
 | 
				
			||||||
 | 
						if ok {
 | 
				
			||||||
 | 
							dataExist, err := entities.PlayerDataExists(ctx, nk, userID)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								logger.Error(err.Error())
 | 
				
			||||||
 | 
								return err.Error(), err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if dataExist {
 | 
				
			||||||
 | 
								return "Already Exists Exception", errors.New("user already has a character")
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								playerData := entities.PlayerSaveData{}
 | 
				
			||||||
 | 
								err := json.Unmarshal([]byte(payload), &playerData)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									logger.Error("Failed to load data from client: %s", err.Error())
 | 
				
			||||||
 | 
									return "Failed to load data from client!", err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								player := entities.PlayerEntity{
 | 
				
			||||||
 | 
									Name:    playerData.Name,
 | 
				
			||||||
 | 
									Faction: gameworld.Faction(playerData.Faction),
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								saveErr := player.SaveUserID(ctx, nk, userID)
 | 
				
			||||||
 | 
								if saveErr != nil {
 | 
				
			||||||
 | 
									logger.Error("Failed to write data to storage on create: %s", err.Error())
 | 
				
			||||||
 | 
									return "Failed to write data to storage!", err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								logger.Info("Created new character for: %s", userID)
 | 
				
			||||||
 | 
								return "Success!", nil
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							logger.Error("Missing User ID from context!")
 | 
				
			||||||
 | 
							return "", errors.New("Missing User ID from context!")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||