I have created a fivem server for a friend of mine, and i'm currently having an issue with garages. Currently trying to index a nil value of 'spawnpoint'
for i=1, #v.Vehicles, 1 do
if GetDistanceBetweenCoords(coords, v.Vehicles[i].Spawner.x, v.Vehicles[i].Spawner.y, v.Vehicles[i].Spawner.z, true) < Config.MarkerSize.x then
isInMarker = true
currentStation = k
currentPart = 'VehicleSpawner'
currentPartNum = i
end
if GetDistanceBetweenCoords(coords, v.Vehicles[i].SpawnPoint.x, v.Vehicles[i].SpawnPoint.y, v.Vehicles[i].SpawnPoint.z, true) < Config.MarkerSize.x then
isInMarker = true
currentStation = k
currentPart = 'VehicleSpawnPoint'
currentPartNum = i
end
end
As brianolive already said, it seems like not every v.Vehicle has a SpawnPoint. You can fix this for instance by proofing for existence of SpawnPoint.
if v.Vehicles[i].SpawnPoint and (
GetDistanceBetweenCoords(
coords, v.Vehicles[i].SpawnPoint.x, v.Vehicles[i].SpawnPoint.y,
v.Vehicles[i].SpawnPoint.z, true
) < Config.MarkerSize.x
) then
Related
I am trying to create a maze generation script using the module listed below. I'm having this strange problem were the grid variable has a value, but when return grid is called, it returns and empty table? Here is the code to the module script.
local ServerStorage = game:GetService("ServerStorage")
local cellTemplate = ServerStorage:WaitForChild("Cell")
local Maze = {}
local cellObject = {}
local grid = {}
Maze.Size = 25
Maze.CellWidth = 9
Maze.CellLength = 9
Maze.Offset = Vector3.new(0,0,0)
function Maze.new(x,z) -- Create a new cell
local newCell = {}
setmetatable(newCell,{ -- Allows us to create functions for a cell easier
__index = cellObject
})
newCell.X = math.clamp(x,1,Maze.Size)
newCell.Z = math.clamp(z,1,Maze.Size)
newCell.Visited = false
newCell.Model = cellTemplate:Clone()
newCell.Base = newCell.Model:WaitForChild("Base")
newCell.Model.Name = newCell.Model.Name.. "_".. newCell.X.. "-".. newCell.Z
newCell.Walls = {
["Forward"] = newCell.Model:WaitForChild("Forward");
["Backward"] = newCell.Model:WaitForChild("Backward");
["Left"] = newCell.Model:WaitForChild("Left");
["Right"] = newCell.Model:WaitForChild("Right");
}
if not grid[x] then grid[x] = {} end -- We might not have anything on that x axis yet; inserts it into the table
grid[x][z] = newCell
print(grid)
return newCell
end
function Maze.RenderAll() -- Render every cell; exists for more readibility
for _,cellRow in pairs(grid) do -- Loop through every cell row
for _,cell in pairs(cellRow) do -- Loop through every cell in the row
cell:Render() -- Render the cell
end
end
end
function Maze.Grid() -- Allows other scripts to get the grid but not modify it
return grid
end
function Maze.FilterUnvisited(cells) -- Takes in a table and returns one with only the cells in the table that are unvisited
local unvisited = {}
for _,cell in pairs(cells) do -- Loop through every cell in the table passed
if not cell.Visitied then -- The cell hasn't been visited
table.insert(unvisited,cell)
end
end
return unvisited
end
function Maze.GetCell(x,z)
local cell
if grid[x] and grid[x][z] then
cell = grid[x][z]
else
cell = nil
end
return cell
end
function cellObject:Render() -- Render the cell
self.Model:SetPrimaryPartCFrame(CFrame.new(Vector3.new(self.X * Maze.CellLength,0,self.Z * Maze.CellWidth) + Maze.Offset)) -- Move the cell to the correct position
if self.Visited then -- We have gone through the cell
self.Model.PrimaryPart.Color3 = Color3.new(0,1,0) -- Show that the cell has been visited; used for debugging
end
self.Model.Parent = workspace
end
function cellObject:Neighbours() -- Returns the cell's neigbours
local neighbours = {}
-- Order: Right Left Up Down
if grid[self.X + 1] and grid[self.X + 1][self.Z] then -- A cell with +1 X exists
table.insert(neighbours,grid[self.X + 1][self.Z])
end
if grid[self.X - 1] and grid[self.X - 1][self.Z] then -- A cell with -1 X exists
table.insert(neighbours,grid[self.X - 1][self.Z])
end
if grid[self.X][self.Z + 1] then -- A cell with +1 Z exists
table.insert(neighbours,grid[self.X][self.Z + 1])
end
if grid[self.X][self.Z - 1] then -- A cell with -1 Z exists
table.insert(neighbours,grid[self.X][self.Z - 1])
end
return neighbours
end
function cellObject:RandomNeighbour()
local neighbours = self:Neighbours() -- Gets the neigbours of the current cell
if #neighbours > 0 then
return neighbours[math.random(1,#neighbours)] -- Returns a random neigbour
else
return nil
end
end
function cellObject:WallArray() -- Returns an array of the walls instead of a table
local wallArray = {}
wallArray[1] = self.Walls.Forward
wallArray[2] = self.Walls.Right
wallArray[3] = self.Walls.Left
wallArray[4] = self.Walls.Backward
return wallArray
end
function cellObject:Join(cell) -- Joins 2 cells together
local wallPosition = self.Base.Position:Lerp(cell.Base.Position,.5) -- This will return the position of the wall (excluding the Y)
local cell1Array = self:WallArray()
local cell2Array = cell:WallArray()
for wallIndex,wall in pairs(cell1Array) do
if wall.Position.X == wallPosition.X and wall.Position.Z == wallPosition.Z then -- Its the right wall
wall.Transparency = 1
wall.CanCollide = false
cell2Array[4 - (wallIndex - 1)].Transparency = 1
cell2Array[4 - (wallIndex - 1)].CanCollide = false
break -- We don't need to loop anymore, since we've already removed the walls
end
end
end
function cellObject:Unjoin(cell) -- Unjoins 2 cells
local wallPosition = self.Base.Position:Lerp(cell.Base.Position,.5) -- This will return the position of the wall (excluding the Y)
local cell1Array = self:WallArray()
local cell2Array = cell:WallArray()
for wallIndex,wall in pairs(cell1Array) do
if wall.Position.X == wallPosition.X and wall.Position.Z == wallPosition.Z then -- Its the right wall
wall.Transparency = 0
wall.CanCollide = true
cell2Array[4 - (wallIndex - 1)].Transparency = 0
cell2Array[4 - (wallIndex - 1)].CanCollide = true
break -- We don't need to loop anymore, since we've already added the walls
end
end
end
return Maze
Below is the piece of code I'm having diffuculty with.
function Maze.Grid() -- Allows other scripts to get the grid but not modify it
return grid
end
I have tested printing the grid variable and it's not {} but when I call the function in the script below, I always get {}! I have no idea why this is.
Is this a bug in roblox or am I being stupid?
local ServerScriptService = game:GetService("ServerScriptService")
local Maze = require(ServerScriptService:WaitForChild("Maze"))
local latestX = 0
local latestZ = 0
function CreatePath(cell)
local nextCell = cell:RandomNextCell(false)
if nextCell then -- We have a cell next to the current one
print("Joining cells:",cell,nextCell)
cell:Join(nextCell)
cell.Visited = true
cell:Render()
wait(.01)
CreatePath(nextCell)
else -- It must be the end of the maze
print("Path generated!")
print("Maze end: ".. cell.Model.Name)
cell.Base.Color = Color3.new(1,0,0)
end
end
function GenerateMaze()
local cell = Maze.new(latestX + 1,latestZ + 1) -- Create a new cell
cell:Render() -- Render it
print("Created cell")
latestZ += 1
if latestZ > Maze.Size then -- It has exceeded the max size, move on to a new row
latestX += 1
latestZ = 0
end
if #Maze.Grid() < Maze.Size ^ 2 then
wait(.01)
GenerateMaze()
else
print("Grid completed, generating path...")
CreatePath(Maze.GetCell(1,1))
end
end
GenerateMaze()
You are returning a cached value, or well i don't find out other reason.
You may do (and it's not editable):
function Maze.Grid(i, l)
local passed = 1
local response = {}
for index, v in pairs(grid) do
response[index] = i and passed >= i and l and passed <= l and v or not (i or l) and v
-- basically get more than `i` if it, and minor than `l` if it passed
i = i + 1
end
return response
end
It should work, I don't tested it sorry.
I'm trying to use Julia to solve the common tile game 15 Puzzle using Julia using A* algorithm. I am quite new to the language and my style may seem very C like. When I try the following code, I run out of memory. I'm not sure if its related to the use of a pointer style in my structs or just bad design.
struct Node
parent
f::Int64
board::Array{Int64,1}
end
function findblank(A::Array{Int64,1})
x = size(A,1)
for i = 1:x
if A[i] == x
return i
end
end
return -1
end
function up(A::Array{Int64,1})
N = size(A,1)
Nsq = isqrt(N)
blank = findblank(A)
B = copy(A)
if blank / Nsq <= 1
return nothing
end
B[blank-Nsq],B[blank] = B[blank],B[blank-Nsq]
return B
end
function down(A::Array{Int64,1})
N = size(A,1)
Nsq = isqrt(N)
blank = findblank(A)
B = copy(A)
if (blank / Nsq) > (Nsq -1)
return nothing
end
B[blank+Nsq],B[blank] = B[blank],B[blank+Nsq]
return B
end
function left(A::Array{Int64,1})
N = size(A,1)
Nsq = isqrt(N)
blank = findblank(A)
B = copy(A)
if (blank % Nsq) == 1
return nothing
end
B[blank-1],B[blank] = B[blank],B[blank-1]
return B
end
function right(A::Array{Int64,1})
N = size(A,1)
Nsq = isqrt(N)
blank = findblank(A)
B = copy(A)
if (blank % Nsq) == 0
return nothing
end
B[blank+1],B[blank] = B[blank],B[blank+1]
return B
end
function manhattan(A::Array{Int64,1})
N = size(A,1)
Nsq = isqrt(N)
r = 0
for i in 1:N
if (A[i]==i || A[i]==N)
continue
end
row1 = floor((A[i]-1) / Nsq)
col1 = (A[i]-1) % Nsq
row2 = floor((i-1) / Nsq)
col2 = (i-1) % Nsq
r+= abs(row1 - row2) + abs(col1 - col2)
end
return r
end
# start = [1,2,3,4,5,6,7,9,8]
# start = [6,5,4,1,7,3,9,8,2] #26 moves
start = [7,8,4,11,12,14,10,15,16,5,3,13,2,1,9,6] # 50 moves
goal = [x for x in 1:length(start)]
# println("The manhattan distance of $start is $(manhattan(start))")
g = 0
f = g + manhattan(start)
pq = PriorityQueue()
actions = [up,down,left,right]
dd = Dict{Array{Int64,1},Int64}()
snode = Node(C_NULL,f,start)
enqueue!(pq,snode,f)
pos_seen = 0
moves = 0
while (!isempty(pq))
current = dequeue!(pq)
if haskey(dd,current.board)
continue
else
push!(dd, current.board =>current.f)
end
if (current.board == goal)
while(current.board != start)
println(current.board)
global moves +=1
current = current.parent[]
end
println(start)
println("$start solved in $moves moves after looking at $pos_seen positions")
break
end
global pos_seen+=1
global g+=1
for i in 1:4
nextmove = actions[i](current.board)
if (nextmove === nothing || nextmove == current.board || haskey(dd,nextmove))
continue
else
global f = g+manhattan(nextmove)
n = Node(Ref(current),f,nextmove)
enqueue!(pq,n,f)
end
end
end
println("END")
I'm talking about MovingGround:update(). It doesn't crash; It just doesn't do anything that's in the method.
I did other things in the method. I set the player pos to 100 100 but that didn't happen so there's (probably) no error in the method itself—at least not that makes it do nothing. The method just doesnt get called!! I think the question is pretty much says the rest! Sooooo.... Here's the code!
-- Grounds
Ground = {}
Ground.__index = Ground
function Ground:new(x,y,width,height)
grd = {}
setmetatable(grd, Ground)
grd.x = x
grd.y = y
grd.w = width
grd.h = height
grd.moving = false
return grd
end
function Ground:draw(r,g,b)
love.graphics.setColor(r,g,b)
love.graphics.rectangle("line",self.x,self.y,self.w,self.h)
end
function Ground:update()
end
MovingGround = {}
MovingGround.__index = MovingGround
function MovingGround:new(x,y,w,h,spdx,spdy,stepsx,stepsy)
grd = {}
setmetatable(grd, Ground)
grd.x = x
grd.y = y
grd.w = w
grd.h = h
grd.moving = true
grd.spdx = spdx
grd.spdy = spdy
grd.stepsxmax = stepsx
grd.stepsymax = stepsy
grd.stepsx = 0
grd.stepsy = 0
grd.xdir = 1
grd.ydir = 1
return grd
end
function MovingGround:draw(r,g,b)
love.graphics.setColor(r,g,b)
love.graphics.rectangle("line",self.x,self.y,self.w,self.h)
love.graphics.rectangle("fill",300,self.y,self.w,self.h)
end
function MovingGround:update()
if self.stepsx > self.stepsxmax or self.stepsx < 0 then self.spdx = -self.spdx self.dirx = -self.dirx end
if self.stepsy > self.stepsymax or self.stepsy < 0 then self.spdy = -self.spdy self.diry = -self.diry end
self.x = self.x + self.spdx
self.y = self.y + self.spdy
self.stepsx = self.stepsx + self.dirx
self.stepsy = self.stepsy + self.diry
end
-- Main
require"functions"
require"player"
require"grounds"
grounds= {}
width = love.graphics.getWidth()
height = love.graphics.getHeight()
function love.load()
test = Player:new(100,100,"w","a","s","d")
grounds[5] = Ground:new(2,2,25,595) --links
grounds[2] = Ground:new(2,2,795,25) --oben
grounds[3] = Ground:new(772,2,25,595) --rechts
grounds[4] = Ground:new(2,572,795,25) --unten
grounds[1] = MovingGround:new(50,400,100,20,0,3,0,15)
end
function love.draw()
test:draw(255,0,255)
love.graphics.print("y : " .. tostring(test.y),10,10)
love.graphics.print("x : " .. tostring(test.x),10,30)
love.graphics.print(test.spdy,10,60)
love.graphics.print(gd,10,90)
love.graphics.print(1000 / gd,10,150)
love.graphics.print(booltoString(test.onGround),10,120)
love.graphics.print(grounds[1].stepsy,10,210)
for i,v in ipairs(grounds) do
grounds[i]:draw(255,255,255)
end
end
function love.update(d)
gd = d
test:update(d)
for i,v in ipairs(grounds) do
grounds[i]:update()
end
end
function love.keypressed(key,code)
if key == "space" then test:jump(-700) end
end
I really recommend using a debugger to determine the cause of this issue. Here's a walkthrough:
Find a place where the update method is being called on a MovingGround object and set a breakpoint there.
Run your program with debugging enabled, until it reaches the breakpoint.
Step into the call to the update method. What method do you end up getting taken to? Is it the method you were expecting?
Now that you're inside of the update method, look at the metatable of self. Is the metatable MovingGround?
The metatable was set inside of MovingGround:new, so set a breakpoint at the beginning of MovingGround:new and restart the program. Run until it reaches the breakpoint.
Step forward (using "step over", not "step into") until you see that the metatable of grd has been set as you saw in step 4.
Look at the line that you just stepped over. What needs to be changed?
Spoiler: in MovingGround:new, the metatable is getting set to Ground instead of MovingGround.
You are supposed to pass in dt into any update function.
In this case, the function should be MovingGround:update(dt) (ground.lua) so that it updates every frame.
Similarly, in main.lua update function, the call should be grounds[i]:update(dt).
I'm having some issues with my webpage.
It was running really slow, so I read on the Internet that it might be a bad usage of SQL. So I commented the SQL lines that were more 'complex' and it started running smoothly again.
My question is: 'Is there a way to make this SQL request "lighter"?
#companies = Company.where('tbl_companys.state = "enabled"')
#companies = #companies.includes(:benefit).where("tbl_benefits.end_date >= {Date.today}" )
#companies = #companies.includes(:benefit).where(tbl_benefits: { state: 'enabled' })
has_benef_gastro = false
has_benef_hote = false
has_benef_ent = false
until has_benef_gastro == true
#esta_gastro = (#companies.where('id_category = "2-gastronomia"').shuffle)[0]
#benefit_gastro = Benefit.where('id_company = ? AND end_date >= ? AND state = "enabled"', #esta_gastro.id_company, Date.today).first
if #benefit_gastro.nil? == false
has_benef_gastro = true
end
end
until has_benef_hote == true
#esta_hotelero = (#companies.where('id_category = "1-hoteleria"').shuffle)[0]
#benefit_hote = Benefit.where('id_company = ? AND end_date >= ? AND state = "enabled"', #esta_hotelero.id_company, Date.today).first
if #benefit_hote.nil? == false
has_benef_gastro = true
end
end
until has_benef_ent == true
#esta_ent = (#companies.where('id_category = "3-entretenimiento"').shuffle)[0]
#benefit_ent = Benefit.where('id_company = ? AND end_date >= ? AND state = "enabled"', #esta_ent.id_company, Date.today).first
if #benefit_ent.nil? == false
has_benef_gastro = true
end
end
Thanks for your help !
You're shuffling the #esta_gastro, #esta_hotelero, #esta_ent, and the #benefit_ variables every time, which doesn't really make sense. It requires multiple new DB queries every single time you do a loop.
If you want to find a random selection, just create your sets outside of the loop, shuffle once (outside of the loop), and then iterate over those sets until you meet your criteria.
For example:
#esta_gastro = #companies.where('id_category = "2-gastronomia"').shuffle
#benefits = Benefit.where('end_date >= ? AND state = "enabled"', Date.today)
#benefit_gastro = nil
i = 0
until !#benefit_gastro.blank?
#benefit_gastro = #benefits.where('id_company = ?', #esta_gastro[i].id_company).first
i += 1
end
EDIT
If the whole goal is to get the #benefit_gastro defined, then I don't even think you need a loop. You could just define the #esta_gastro set and then use it find all the Benefits that correspond. Because #esta_gastro is shuffled, your #benefit_gastro will be random:
#esta_gastro = #companies.where('id_category = "2-gastronomia"').shuffle
#benefit_gastro = Benefit.where('end_date >= ? AND state = "enabled"', Date.today).where('id_company = ?', #esta_gastro.map(&:id)).limit(1)
I ended up doing a plain SQL request so I didn't had to struggle with some rails issues.
Thanks anyway !
This question already has answers here:
method for serializing lua tables
(5 answers)
Closed 8 years ago.
I would like to serialize a table so that I can insert it into a database and retrieve it later on. How would I do this?
maybe like this https://gist.github.com/rangercyh/5814003
local szStr = ""
function print_lua_table (lua_table, indent)
indent = indent or 0
for k, v in pairs(lua_table) do
if type(k) == "string" then
k = string.format("%q", k)
end
local szSuffix = ""
if type(v) == "table" then
szSuffix = "{"
end
local szPrefix = string.rep(" ", indent)
formatting = szPrefix.."["..k.."]".." = "..szSuffix
if type(v) == "table" then
szStr = szStr..formatting
print_lua_table(v, indent + 1)
szStr = szStr..szPrefix.."},"
else
local szValue = ""
if type(v) == "string" then
szValue = string.format("%q", v)
else
szValue = tostring(v)
end
szStr = szStr..formatting..szValue..","
end
end
end
How to serialize Lua value nicely?
local serialize
do
local num_fmt = '%.17g'
local NaN_serialized = { -- This idea was stolen from lua-nucleo
[num_fmt:format(1/0)] = '1/0',
[num_fmt:format(-1/0)] = '-1/0',
[num_fmt:format(0/0)] = '0/0'
}
local function serialize_table(t, indent)
indent = indent or ''
local new_indent = indent..'\t'
if next(t) == nil then
return '{}'
else
local lines = {}
local function add_line(key)
local ser_key = key
if type(key) ~= 'string' or not key:find'^[%a_][%w_]*$' then
ser_key = '['..serialize(key, new_indent)..']'
end
table.insert(lines,
ser_key..' = '..serialize(t[key], new_indent))
end
local other_keys = {}
local keys = setmetatable({number = {}, string = {}},
{__index = function() return other_keys end})
for k in pairs(t) do
table.insert(keys[type(k)], k)
end
table.sort(keys.number)
table.sort(keys.string)
for _, k in ipairs(keys.number) do
add_line(k)
end
for _, k in ipairs(keys.string) do
add_line(k)
end
for _, k in ipairs(other_keys) do
add_line(k)
end
return '{\n'..new_indent..table.concat(lines, ',\n'..new_indent)
..'\n'..indent..'}'
end
end
function serialize(v, indent)
if type(v) == 'string' then
return ('%q'):format(v)
elseif type(v) == 'boolean' then
return tostring(v)
elseif type(v) == 'nil' then
return tostring(v)
elseif type(v) == 'number' then
return (num_fmt:format(v):gsub('^.*', NaN_serialized))
elseif type(v) == 'table' then
return serialize_table(v, indent)
else
error('Can not serialize '..type(v))
end
end
end
-- What it can:
print(serialize(math.huge))
print(serialize'"What\'s up?"\n\t123')
print(serialize{{}, {{}}})
-- And what it can not:
local t = {}
local tt = {[t] = t}
print(serialize(tt)) -- tt is not a tree, so it was serialized incorrectly