summaryrefslogtreecommitdiff
path: root/src/spawn_fish.moon
blob: 5bc090b1b34a9820f33b6e61c2e845320bb36b15 (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
router = require("router")
ecs = require("ecs")
world = require("world")
win = require("window")
sprites = require("world.sprites")

class FishGraphicComponent extends world.GraphicsComponent
	@fish_size = 0.5
	@static = false
	@loctbl = {
		{-1,-1}
		{-1,1}
		{1,1}
		{1,1}
		{1,-1}
		{-1,-1}
	}
	buf_size: () =>
		6
	populate_buf: (geom_view, normal_view, offset) =>
		@buf = geom_view
		h = @@fish_size / 2
		--@lamp_offset = vec4(2.5,1.4,0,0)
		aspect = win.width / win.height
		--@lamp = world.level.add_lamp(vec4(0,0,0,0.1 * aspect) + @lamp_offset)
		for i = 1,6
			loctbl = @@loctbl[i]
			geom_view[i] = vec3(@@loctbl[i][1] * h, @@loctbl[i][2] * h, -1.5)
		uv = sprites.player_normal
		normal_view[1] = vec2(uv.s1,uv.t1)
		normal_view[2] = vec2(uv.s1,uv.t2)
		normal_view[3] = vec2(uv.s2,uv.t2)
		normal_view[4] = vec2(uv.s2,uv.t2)
		normal_view[5] = vec2(uv.s2,uv.t1)
		normal_view[6] = vec2(uv.s1,uv.t1)
	join: (entity) =>
		super(entity)
		aspect = win.width / win.height
		program = @.node("use_program")
		@pred = entity\get("pred")
		graphic = entity\get("graphic")
		assert(@pred, "Fish graphic must have a predicted component")
		@node\remove(program)
		@node\append(am.blend("alpha")\append(program))
		@ent = entity
		comp = @
	move: (pos) =>
		h = @@fish_size / 2
		--print("Calling move with", pos)
		--if @ent.state ~= "swimming"
		--	error("called move while not swimming")
		for i = 1,6
			@buf[i] = vec3(@@loctbl[i][1] * h, @@loctbl[i][2] * h, -0.13) + vec3(pos.x, pos.y, 0)

friction = 0.1
class FishPredictedComponent extends ecs.PredictedComponent
	new: (id) =>
		fish_speed = 0.00001
		super(id, {accel: vec2(0,0), vel: vec2(0,0), pos: vec2(0,0)}, "netc", {
				accel: () =>
					--print("ent state:", @cc.state)
					if @cc.state ~= "swimming"
						return vec2(0,0)
					localized = @net.properties.next_loc - @properties.pos
					--direction = math.atan(localized.y / localized.x)
					math.normalize(localized + @properties.vel) * fish_speed
				vel: () =>
					--print("Before calculating vel, properties was ", @properties)
					delta = world.sync_time! - @net.properties.next_loc_time
					--print("Delta time:", delta)
					(@properties.accel / friction) + ((@properties.vel - (@properties.accel / friction)) * math.exp(-friction * delta))
				pos: () =>
					if @properties.pos.x > 20
						error("Very far, stopping")
					delta = world.sync_time! - @net.properties.next_loc_time
					friction_loss = @properties.accel / friction
					(friction_loss * delta) - ((1/friction) * (@properties.vel - friction_loss) * (math.exp(-friction * delta))) + @properties.pos
		})
		@node = am.group!
	join: (entity) =>
		@net = entity\get("net")
		@gc = entity\get("graphic")
		@properties.pos = @net.properties.pos
		@cc = entity\get("control")
		@ent = entity
		print("Got graphic component:",@gc, @gc.node)
		print("And my node is", @node)
		@gc.node\append(@node)
		s = @
		@node\action(() =>
			s\forward!
		)
	forward: () =>
		super!
		if @ent.state == "catching"
			@gc.node.hidden=true
		else
			@gc\move(@properties.pos)

class Fish extends ecs.Entity
	new: (id, pos) =>
		@width = 40 -- TODO: randomize fish width
		components = {
			pred: FishPredictedComponent("pred")
			net: ecs.NetworkedComponent("net",{pos: pos, next_loc: pos, next_loc_time: am.current_time!})
			graphic: FishGraphicComponent("graphic")
			control: require("controllers.fish").FishControllerComponent()
			phys: world.PhysicsComponent("phys",{},"circle",{pos.x, pos.y, @width / 256})
		}
		super(id, components)
	destroy: (...) =>
		super(...)
		error("Where did fish go")

class SpawnFishComponent extends ecs.Component
	new: (id, properties, spawnrect) =>
		super(id, properties)
	
	join: (entity) =>
		graphic = entity\get("graphic")
		router = router.r!
		set_spawnable = () ->
			if router.state == "elected"
				graphic\action(() ->
					error("Spawn fish callback")
				)
		set_spawnable!
		router\onchange(set_spawnable)

{:Fish, :SpawnFishComponent}