-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathJACC.txt
196 lines (170 loc) · 7.13 KB
/
JACC.txt
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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
--@name Map Scanner and Artilery Controller
--@author Jagger
--@shared
--@include JLearn/lib/png.txt
if CLIENT then
local PNG_PATH = "arty_controller/" .. game.getMap() .. ".png"
local INF_PATH = "arty_controller/" .. game.getMap() .. ".txt"
local LOAD_PATH = "data/sf_filedata/" .. PNG_PATH
local MAP_MAT = nil
local MAP_SIZE = 512
local ALT_FLAT_THRESH = 128
local ALT_ANG_THRESH = 256
local ALT_LINE_SPACING = 250
local Png = require("lib/png.txt")
local function scanMap ()
if file.exists(PNG_PATH) then
print("Map file exists, loading...")
return 1
end
local function filter (ent) return true end
local function mixColors (c1, c2, ratio)
return c1*(1-ratio) + c2*ratio
end
print("Scanning map...")
-- Get the top of the map
local t = nil
local spos = chip():getPos() + Vector(0,0,10)
while 1 do
t = trace.trace(spos, spos+Vector(0,0,50000), filter, MASK.NPCWORLDSTATIC)
if t.HitSky == false then
spos = t.HitPos + Vector(0,0,1000)
else
break
end
end
-- Get the edges
spos = t.HitPos + Vector(0,0,-10)
-- (-x, +y) edge
t = trace.trace(spos, spos+Vector(-50000,0,0), filter, MASK.NPCWORLDSTATIC)
spos = t.HitPos + Vector(10,0,0)
t = trace.trace(spos, spos+Vector(0,50000,0), filter, MASK.NPCWORLDSTATIC)
spos = t.HitPos + Vector(0,-10,0)
local top_left = spos
-- (+x, -y) edge
t = trace.trace(spos, spos+Vector(50000,0,0), filter, MASK.NPCWORLDSTATIC)
spos = t.HitPos + Vector(-10,0,0)
t = trace.trace(spos, spos+Vector(0,-50000,0), filter, MASK.NPCWORLDSTATIC)
spos = t.HitPos + Vector(0,10,0)
local bot_right = spos
local map_size = bot_right - top_left
local x_inc = map_size[1] / MAP_SIZE
local y_inc = map_size[2] / MAP_SIZE
local map = {}
local rgb = {}
-- Scan the map and fill the map table
for y = 0, MAP_SIZE-1, 1 do
for x = 0, MAP_SIZE-1, 1 do
spos = top_left + Vector(x_inc*x, y_inc*y, 0)
t = trace.trace(spos, spos+Vector(0,0,-50000), filter, MASK.NPCWORLDSTATIC)
local point = {}
local hit_pos = t.HitPos
point.altitude = hit_pos[3]
point.color = render.traceSurfaceColor(hit_pos + Vector(0,0,1), hit_pos + Vector(0,0,-1))
point.slope = t.HitNormal:dot(Vector(0,0,1))
point.water = (bit.band(trace.pointContents(t.HitPos), CONTENTS.WATER) ~= 0)
if point.water == true then
t = trace.trace(spos, spos+Vector(0,0,-50000), filter, MASK.WATER)
point.depth = t.HitPos[3] - point.altitude
end
map[MAP_SIZE*y + x + 1] = point
if quotaAverage() > quotaMax()*0.80 then coroutine.yield() end
end
end
print("Processing...")
-- Process the map table and generate the RGB table
local idx = 1
for y = 0, MAP_SIZE-1, 1 do
for x = 0, MAP_SIZE-1, 1 do
local point = map[MAP_SIZE*y + x + 1]
-- Get all neighbors
local neighbors = {}
if y ~= MAP_SIZE-1 then
table.insert(neighbors, map[MAP_SIZE*(y+1) + (x) + 1])
end
if x ~= 0 then
table.insert(neighbors, map[MAP_SIZE*(y-1) + (x) + 1])
end
if x ~= MAP_SIZE-1 then
table.insert(neighbors, map[MAP_SIZE*(y) + (x+1) + 1])
end
if x ~= 0 then
table.insert(neighbors, map[MAP_SIZE*(y) + (x-1) + 1])
end
local alt_edge = false
local alt_line = false
-- For all neighbors, determine if altitude line should be drawn
for k, v in ipairs(neighbors) do
if not v then continue end
local alt_diff = point.altitude - v.altitude
if alt_diff > 0 then
if (alt_diff > ALT_ANG_THRESH and point.slope > 0.4) or (point.slope > 0.9 and alt_diff > ALT_FLAT_THRESH) then
alt_edge = true
elseif math.floor(point.altitude / ALT_LINE_SPACING) ~= math.floor(v.altitude / ALT_LINE_SPACING) then
alt_line = true
end
end
end
local color = map[MAP_SIZE*y + x + 1].color
if point.water then
if alt_line then
color = mixColors(color, Color(0, 229, 255), 0.6)
else
local mix = math.min(1, 0.6 + point.depth / 500)
color = mixColors(color, Color(19, 76, 168), mix)
end
elseif alt_edge then color = mixColors(color, Color(255, 114, 48), 0.9)
elseif alt_line then color = mixColors(color, Color(255, 196, 0), 0.7) end
rgb[idx] = math.round(color[1])
rgb[idx+1] = math.round(color[2])
rgb[idx+2] = math.round(color[3])
idx = idx + 3
if quotaAverage() > quotaMax()*0.80 then coroutine.yield() end
end
end
print("Writing...")
-- Ready the image for writing
local img = Png(MAP_SIZE,MAP_SIZE)
local block_size = MAP_SIZE
-- Generate the PNG
for i = 1, MAP_SIZE * MAP_SIZE * 3, block_size do
local pixels = {unpack(rgb, i, i+block_size-1)}
img:write(pixels)
if quotaAverage() > quotaMax()*0.80 then coroutine.yield() end
end
-- Write the file
file.createDir("arty_controller")
file.open(PNG_PATH, "w")
local image_data = img.output
block_size = 1024*3
for i = 1, #image_data, block_size do
local max_idx = math.min(#image_data, i+block_size-1)
local stream = table.concat({unpack(image_data, i, max_idx)})
file.append(PNG_PATH, stream)
if quotaAverage() > quotaMax()*0.80 then coroutine.yield() end
end
print("Done!")
return 1
end
render.createRenderTarget("myrendertarget")
local function renderMap ()
local cur_x, cur_y = render.cursorPos(player())
--render.setColor(Color(255, 255, 255, 255))
render.setMaterial(MAP_MAT)
render.drawTexturedRect(0,0,512,512)
render.setColor(Color(255, 0, 0, 100))
render.drawCircle(cur_x or 0, cur_y or 0, 10)
end
local scanMapRoutine = coroutine.wrap(scanMap)
hook.add("think", "scan_map", function()
if not scanMapRoutine() then
return
else
MAP_MAT = material.createFromImage(LOAD_PATH, "nocull smooth")
hook.add("render", "", renderMap)
hook.remove("think", "scan_map")
end
end)
end
if SERVER then
end