aboutsummaryrefslogtreecommitdiff
path: root/src/client/init.moon
blob: 5aae780a3f46d8a13aaa514d0e0b091b246d6ced (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
net = require("net")
world = require("world")
ui = require("ui")
log = require("log")
ClientNetworkedComponent = require("ecs.client_networked")
GraphicsComponent = require("ecs.graphics")
PlayerGraphicComponent = require("ecs.player_graphic")
CharacterControllerComponent = require("ecs.char_controller")
PredictedComponent = require("ecs.predicted")
ScriptComponent = require("ecs.script")
player_movement = require("shared.player_movement")
game_menu = require("menu.game")

ecs = require("ecs")
sprites =require("sprites")

net.register_message("CreatePawn",{
	peerid: "string"
})
x = {}

net.register_message("Notify",{
	required: {
		message: "string"
	}
})

create_entity = (id, chunk) ->
	log.info("Creating entity of type" .. tostring(chunk.data.type), {"ecs","net","client"})
	ent = nil
	switch chunk.data.type
		when "level"
			--ent = ecs.Entity(id)
			log.info("TODO: What do we refresh with level data?",{"ecs","net","client"})
			--nents = #world.level.entities
			--net_comp = ClientNetworkedComponent("net",chunk.data)
			--ent\add(net_comp,"net")
			require(chunk.data.level_name).create(unpack(chunk.data.level_data))
			--assert(#world.level.entities == nents, "Entities created in level loading")
		when "player"
			ent = ecs.Entity(id)
			log.info("Creating player",{"ecs","net","client","player"})
			net_comp = ClientNetworkedComponent("net",chunk.data)
			ent\add(net_comp,"net")
			graphic = GraphicsComponent("graphic",{graphic: sprites.player})
			ent\add(graphic,"graphic")
			predicted = PredictedComponent("pred",{acc: {0,0,0}, vel: {0,0,0}, pos:{0,0,0}}, "net", player_movement)
			ent\add(predicted,"pred")
			-- If this is "our" pawn, move our view with it
			if chunk.data.peerid == world.network.peer.id
				controller = CharacterControllerComponent("controller",player_movement,"net")
				ent\add(controller,"controller")
				move_view = ScriptComponent("move_view",{
					script: () ->
						loc = predicted.properties.pos
						world.world_x = loc[1]
						world.world_y = loc[2]
						--graphic\moveto(vec3(loc[1],loc[2],loc[3]))
				})
				ent\add(move_view,"move_view")
			move_graphic = ScriptComponent("move_graphic", {
				script: () ->
					loc = predicted.properties.pos
					graphic\moveto(vec3(loc[1],loc[2],loc[3]))
			})
			ent\add(move_graphic, "move_graphic")

		else
			error("Tring to create unknown entity:" .. tostring(id) .. ":" .. tostring(data))
	--assert(ent.components.net, "Failed to find net component")
	return ent

x.initialize = () ->
	assert(world, "World must be available")
	assert(world.network, "Network must be initialized")
	localpawns = {}
	net = nil
	world.network\listen("CreatePawn", nil, (_, data) ->
		log.info("Creating pawn:" .. tostring(data), {"net","ecs","client"})
		unpacked = am.parse_json(data)
		ent_id = unpacked.id
		create_entity(ent_id, unpacked)
		--ent = ecs.Entity(ent_id)
		--net = ClientNetworkedComponent("net",unpacked.data)
		--ent\add(net,"net")
		--graphic = GraphicsComponent("graphic",{
			--graphic: sprites.player
		--})
		--ent\add(graphic,"graphic")
		--pred = PredictedComponent("pred",{acc:{0,0,0}, vel: {0,0,0}, pos: {0,0,0}}, "net", player_movement)
		--ent\add(pred, "pred")
	)
	world.network\listen("update","client update",(_, data) ->
		log.info("Updating:" .. tostring(data.id), {"net","ecs","client"})
		--log.info("Entities were:" .. tostring(world.level.entities),{"net","client","ecs"})
		log.debug("World entities are:" .. tostring(world.level.entities), {"ecs","client","net"})
		if not world.level.entities[data.id]
			log.error("Client instructed to update id " .. data.id .. " but no entity exists! Entities were:" .. tostring(world.level.entities),{"net","client","ecs"})
		ent = world.level.entities[data.id]
		net_component = ent\get(data.name)
		if not net_component
			error("Client instructed to update id " .. data.id .. " with network component named " .. tostring(data.name) .. " but no such component exists, entity was:" .. tostring(ent))
		net_component.properties = data
		if net_component == net
			print("Updating pawn net component")
		log.info("Successfully updated entity" .. tostring(data.id), {"ecs","client","net"})
	)
	entities_responded = false
	world.network\listen("RespondEntities","Respond entities",(_, data) ->
		-- this is a full refresh, we can wipe entities and build them from scratch.
		for _, ent in pairs(world.level.entities)
			ent\destroy!
		log.info("Wiping and re-creating entities:" .. tostring(data), {"ecs","net","client"})
		assert(type(data) == "table")
		for id, properties in pairs(data)
			assert(type(id) == "number")
			assert(type(properties) == "string")
			create_entity(id, am.parse_json(properties))
			log.info("Successfully created entity" .. tostring(id), {"ecs","net","client"})
		assert(#world.level.entities == #data, "Failed to create entities correctly")
	)
	world.network\send("RequestEntities", {})
	world.network\listen("RespondRole", "Respond role", (_, data) -> 
		-- By this time we're in the game, destory any entities laying around.
		for _, ent in pairs(world.level.entities)
			ent\destroy!
		log.info("Got role from server:" .. tostring(data), {"net","client"})
		game_menu.create_graphic(data)
		am.save_state("gameplay", data)
		-- Kinda hacky, but if we have a role, just disable net pumping
		-- to prevent errors on net.create()
		error("Preventing furhter network pumping!")
		net.pump = () ->
			log.info("Tried to pump net!",{"net","client"})
	)
	--world.network\send("RequestRole",{})
	log.info("Client fully initialized",{"net","client","graphic"})
	true
x