Computercraft: Can a coroutine do infinite loops? - lua

I'm trying to do a software which can handle other programs, to start a program I use os.run(...) inside a coroutine,
Here is my code:
--VARS
local os_ver = "0.1"
local w,h = term.getSize() --Terminal size
local bar_b_color, bar_f_color --Background and foreground colors (bar)
local menu_b_color, menu_f_color --Background and foreground colors (menu)
local bg_image, bg_color --Background image, color
local root_dir = "/MaOS/"
local sys_dir = root_dir .. "sys/"
local usr_dir = root_dir .. "usr/"
local start_txt = "START" --The text printed in start button
local menus_index --Gui's index of menus
local prog_name --Name of the sel. program
local prog_path --Path of the sel. program
local win, process
--LOAD APIS
os.loadAPI(sys_dir .. "apis/flib")
os.loadAPI(sys_dir .. "apis/stdlib")
os.loadAPI(sys_dir .. "apis/gui")
--BASE FUNCS
function init() --Loads settings
menu_b_color = tonumber(flib.getSetting(sys_dir .. "conf", "Background Menu Color"))
menu_f_color = tonumber(flib.getSetting(sys_dir .. "conf", "Foreground Menu Color"))
bar_b_color = tonumber(flib.getSetting(sys_dir .. "conf", "Background Bar Color"))
bar_f_color = tonumber(flib.getSetting(sys_dir .. "conf", "Foreground Bar Color"))
bg_image = paintutils.loadImage(flib.getSetting(sys_dir .. "conf", "Background Image Path"))
bg_color = tonumber(flib.getSetting(sys_dir .. "conf", "Background Color"))
end
--PRE-MAIN
init()
--TABLES
--Menu: [1] -> Menu informations
local menus = {
[1] = { --Start menu
[1] = {is_shown = false; parent=0; x = 1; xx = 11; y = 1; yy = 6; b_color = menu_b_color; f_color = menu_f_color};
[2] = {txt = " "; cmd = function() end};
[3] = {txt = " PROGRAMS >"; cmd = function()
loadPrograms()
gui.showMenu(menus_index, 3)
end};
[4] = {txt = " CUSTOMIZE "; cmd = function() launchShell("CUSTOMIZE", "/rom/programs/edit", sys_dir .. "conf") end};
[5] = {txt = " SHELL "; cmd = function() launchShell("SHELL", "/rom/programs/shell") end};
[6] = {txt = " EXIT >"; cmd = function() gui.showMenu(menus_index, 2) end};
[7] = {txt = " "; cmd = function()
win = window.create(term.current(),15,5,20,10, true)
process = coroutine.create(function() os.run({term = win}, sys_dir .. "programs/Ice-Browser") end)
coroutine.resume(process)
end}
};
[2] = { --Exit menu
[1] = {is_shown = false; parent=1; x = 12; xx = 23; y = 1; yy = 6; b_color = menu_b_color; f_color = menu_f_color};
[2] = {txt = " "; cmd = function() end};
[3] = {txt = " SHUTDOWN "; cmd = function() os.shutdown() end};
[4] = {txt = " REBOOT "; cmd = function() os.reboot() end};
[5] = {txt = " "; cmd = function() end}
};
[3] = { --Programs menus
[1] = {is_shown = false; parent=1; x = 12; xx = 25; y = 1; yy = 0; b_color = menu_b_color; f_color = menu_f_color};
[2] = {txt = " "; cmd = function() end};
};
[4] = { --Args menu
[1] = {is_shown = false; parent=3; x = 26; xx = 38; y = 1; yy = 5; b_color = menu_b_color; f_color = menu_f_color};
[2] = {txt = " "; cmd = function() end};
[3] = {txt = " RUN "; cmd = function() launchShell(prog_name, prog_path, nil) end};
[4] = {txt = " RUN WITH ARGS "; cmd = function() end};
[5] = {txt = " "; cmd = function() end};
}
}
--FUNCS
function loadPrograms() --Load programs
stdlib.clearTable(gui.menus[menus_index][3], 2)
local programs = flib.getFiles(sys_dir .. "programs/")
for _, program in pairs(programs) do
name = " " .. program
path = sys_dir .. "programs/" .. program
if string.len(name) > (menus[3][1].xx-menus[3][1].x) then
name = string.sub(name, 1, string.len(name)-4) .."... "
elseif string.len(name)-1 < (menus[3][1].xx-menus[3][1].x) then
for i=string.len(name),(menus[3][1].xx-menus[3][1].x),1 do
name = name .. " "
end
end
name = string.upper(name)
table.insert(gui.menus[menus_index][3], {txt = name; cmd = function() end})
end
table.insert(gui.menus[menus_index][3], {txt = " "; cmd = function() end})
gui.menus[menus_index][3][1].yy = table.getn(programs)+1
end
function drawScr() --Draw screen
--Draw bg
term.setBackgroundColor(bg_color)
term.clear()
paintutils.drawImage(bg_image, 1, 2)
--Draw bar
term.setBackgroundColor(bar_b_color)
term.setTextColor(bar_f_color)
term.setCursorPos(1, 1)
term.clearLine()
term.setCursorPos(w-#os_ver, 1)
print(os_ver)
term.setCursorPos(2, 1)
print(start_txt)
--Draw menus
gui.drawAllShownMenus()
if win ~= nil then win.redraw() end
end
function launchShell(title, path, arg)
local shell_tab = multishell.launch({shell = shell}, path, arg)
multishell.setTitle(shell_tab, title)
multishell.setFocus(shell_tab)
return shell_tab
end
--MAIN
multishell.setTitle(multishell.getCurrent(), "MaOS") --Set title of this shell
init()
menus_index = gui.loadMenuGroup(menus) --Load menus into gui
while true do
drawScr()
gui.handleMenuClick(2, 2+string.len(start_txt), 1, 1)
end
When I try to run "Ice-Browser", I immediately get the status, of the process, "suspended", that happens after drawning program.
The problem happens not when I don't use coroutines, that brings me to think, the problem is the coroutine.
My question is "Can a coroutine do infinite loops (while)"?
Thanks in advance

Ok, I resolved my problem, I didn't saw that the function os.pullEvent(...) yields the coroutine, thanks for the support

Related

Can't set the damage value(s) to insta-kill NPCs/Players in a Garry's Mod "Spartan Kick" addon

This is a uh usual change of what I post here on StackOverflow! Today I'm trying to edit someone's Garry's Mod Workshop Addon.
I wanted to make it a one-hit kill and it's a Spartan Kick.
Here is the code:
if( SERVER ) then
AddCSLuaFile( "shared.lua" );
end
if( CLIENT ) then
SWEP.Category = "Epic Kicks";
SWEP.PrintName = "Spartan Kick";
SWEP.WepSelectIcon = surface.GetTextureID("VGUI/entities/spartan_kick")
SWEP.Slot = 1;
SWEP.SlotPos = 4;
SWEP.DrawAmmo = false;
SWEP.DrawCrosshair = false;
end
SWEP.Author = "Shot846 (Original) + 2Epic4You (Modified)"
SWEP.Instructions = "A better Sparta Kick. Use sv_cheats 1 for slow-motion!"
SWEP.Contact = "..."
SWEP.Purpose = "THIS IS EDITED SPARTAAAAAAA!"
SWEP.ViewModelFOV = 75
SWEP.ViewModelFlip = false
SWEP.Spawnable = true
SWEP.AdminSpawnable = true
SWEP.NextStrike = 0;
SWEP.ViewModel = "models/weapons/v_kick.mdl"
SWEP.WorldModel = ""
-------------Primary Fire Attributes----------------------------------------
SWEP.Primary.Delay = 0.4 --In seconds
SWEP.Primary.Recoil = 0 --Gun Kick
SWEP.Primary.Damage = math.huge --Damage per Bullet
SWEP.Primary.NumShots = 1 --Number of shots per one fire
SWEP.Primary.Cone = 0 --Bullet Spread
SWEP.Primary.ClipSize = -1 --Use "-1 if there are no clips"
SWEP.Primary.DefaultClip = -1 --Number of shots in next clip
SWEP.Primary.Automatic = true --Pistol fire (false) or SMG fire (true)
SWEP.Primary.Ammo = "none" --Ammo Type
-------------Secondary Fire Attributes----------------------------------------
SWEP.Secondary.Delay = 0 --In seconds
SWEP.Secondary.Recoil = 0 --Gun Kick
SWEP.Secondary.Damage = math.huge --Damage per Bullet
SWEP.Secondary.NumShots = 1 --Number of shots per one fire
SWEP.Secondary.Cone = 0 --Bullet Spread
SWEP.Secondary.ClipSize = -1 --Use "-1 if there are no clips"
SWEP.Secondary.DefaultClip = -1 --Number of shots in next clip
SWEP.Secondary.Automatic = true --Pistol fire (false) or SMG fire (true)
SWEP.Secondary.Ammo = "none" --Ammo Type
-------------Precache Sounds----------------------------------------
util.PrecacheSound("player/skick/madness.mp3")
util.PrecacheSound("player/skick/foot_kickwall.wav")
util.PrecacheSound("player/skick/foot_kickbody.wav")
util.PrecacheSound("player/skick/sparta.mp3")
util.PrecacheSound("player/skick/kick1.wav")
util.PrecacheSound("player/skick/kick2.wav")
util.PrecacheSound("player/skick/kick3.wav")
util.PrecacheSound("player/skick/kick4.wav")
util.PrecacheSound("player/skick/kick5.wav")
util.PrecacheSound("player/skick/kick6.wav")
function SWEP:Initialize()
if( SERVER ) then
self:SetWeaponHoldType("normal");
end
self.Hit = {
Sound( "player/skick/foot_kickwall.wav" )};
self.FleshHit = {
Sound( "player/skick/kick1.wav" ),
Sound( "player/skick/kick2.wav" ),
Sound( "player/skick/kick3.wav" ),
Sound( "player/skick/kick4.wav" ),
Sound( "player/skick/kick5.wav" ),
Sound( "player/skick/kick6.wav" ) } ;
end
function SWEP:Precache()
end
function SWEP:Deploy()
self.Weapon:SendWeaponAnim( ACT_VM_IDLE );
return true;
end
function SWEP:PrimaryAttack()
if( CurTime() < self.NextStrike ) then return; end
self.Weapon:EmitSound("player/skick/sparta.mp3")
self.NextStrike = ( CurTime() + 3.5 );
timer.Simple( 1.80, function() self.AttackAnim(self) end)
timer.Simple( 2.40, function() self.Weapon:SendWeaponAnim( ACT_VM_IDLE ) end)
timer.Simple( 2.0, function() self.ShootBullets (self) end)
self.Owner:SetAnimation( PLAYER_ATTACK1 );
end
function SWEP:ShootBullets()
self.Weapon:EmitSound("player/skick/foot_swing.wav");
local trace = self.Owner:GetEyeTrace();
if trace.HitPos:Distance(self.Owner:GetShootPos()) <= 130 then
if( trace.Entity:IsPlayer() or trace.Entity:IsNPC() or trace.Entity:GetClass()=="prop_ragdoll" ) then
timer.Simple(0, function() game.ConsoleCommand("host_timescale 0.1\n") end)
timer.Simple(0.1, function() game.ConsoleCommand("host_timescale 1\n") end)
self.Owner:EmitSound( self.FleshHit[math.random(1,#self.FleshHit)] );
else
self.Owner:EmitSound( self.Hit[math.random(1,#self.Hit)] );
end
bullet = {}
bullet.Num = 5
bullet.Src = self.Owner:GetShootPos()
bullet.Dir = self.Owner:GetAimVector()
bullet.Spread = Vector(0.04, 0.04, 0.04)
bullet.Tracer = 0
bullet.Force = math.huge
bullet.Damage = math.huge
self.Owner:FireBullets(bullet)
end
if trace.Entity:GetClass() == "prop_door_rotating" then
trace.Entity:EmitSound(Sound("physics/wood/wood_box_impact_hard3.wav"))
trace.Entity:Fire("open", "", .001)
trace.Entity:Fire("unlock", "", .001)
local pos = trace.Entity:GetPos()
local ang = trace.Entity:GetAngles()
local model = trace.Entity:GetModel()
local skin = trace.Entity:GetSkin()
trace.Entity:SetNotSolid(true)
trace.Entity:SetNoDraw(true)
local function ResetDoor(door, fakedoor)
door:SetNotSolid(false)
door:SetNoDraw(false)
fakedoor:Remove()
end
local norm = (pos - self.Owner:GetPos()):Normalize()
local push = 1000000 * norm
local ent = ents.Create("prop_physics")
ent:SetPos(pos)
ent:SetAngles(ang)
ent:SetModel(model)
if(skin) then
ent:SetSkin(skin)
end
ent:Spawn()
timer.Simple(.01, ent.SetVelocity, ent, push)
timer.Simple(.01, ent:GetPhysicsObject().ApplyForceCenter, ent:GetPhysicsObject(), push)
timer.Simple(140, ResetDoor, trace.Entity, ent)
end
end
function SWEP:SecondaryAttack()
if( CurTime() < self.NextStrike ) then return; end
self.NextStrike = ( CurTime() + 0.75 );
timer.Simple( 0.00, function() self.AttackAnim(self) end)
timer.Simple( 0.75, function() self.Weapon:SendWeaponAnim( ACT_VM_IDLE ) end)
timer.Simple( 0.20, function() self.ShootBullets (self) end)
self.Owner:SetAnimation( PLAYER_ATTACK1 );
end
function SWEP:Reload()
if( CurTime() < self.NextStrike ) then return; end
self.Weapon:EmitSound("player/skick/madness.mp3")
self.NextStrike = ( CurTime() + 2.00 );
end
function SWEP:AttackAnim()
self.Weapon:SendWeaponAnim( ACT_VM_PRIMARYATTACK )
end
Yes it works however it isn't instantly killing the NPC I spawn.
What value do I need to change to make it insta-kill?
What I've tried:
Changing all damage values found to math.huge
What I've found:
I have found that it does still damage the NPC and the original value was 1000000 however it didn't insta-kill the NPC.
I've actually figured it out! After some extensive researching on the Wiki, I found out you can have bullet.Callback and so this is what I did:
bullet = {}
bullet.Num = 10
bullet.Src = self.Owner:GetShootPos()
bullet.Dir = self.Owner:GetAimVector()
bullet.Spread = Vector(0.04, 0.04, 0.04)
bullet.Tracer = 0
bullet.Force = 20000
bullet.Damage = 999999
bullet.Callback = function(attacker, tree, damageinfo)
if(trace.Entity:IsNPC()) then
trace.Entity:SetHealth(0)
elseif(trace.Entity:IsPlayer()) then
trace.Entity:Kill()
end
end
self.Owner:FireBullets(bullet)

Roblox Problem: Expected ')' (to close '(' at column 18), got '='

Hi I'm trying to make a flight script and I just need help with the ")" I honestly can't find where to put it. I know its a rookie mistake and I'm sorry for the waste of time. I have to over explain this and I'm sorry but I can't post any other way.
local camera = game.Workspace.CurrentCamera;
local character = game.Players.LocalPlayer.ChracaterAdded:Wait();
local F = game.Players.LocalPlayer.Backpack.Bold
local hrp = character:WaitForChild("HumanoidRootPart");
local humanoid = character:WaitForChild("Humanoid");
local animate = character:WaitForChild("Animate");
while (not character.Parent) do character.AncestryChanged:Wait(); end
local idleAnim = humanoid:LoadAnimation(script:WaitForChild("IdleAnim"));
local moveAnim = humanoid:LoadAnimation(script:WaitForChild("MoveAnim"));
local lastAnim = idleAnim;
local bodyGyro = Instance.new("BodyGyro");
bodyGyro.maxTorque = Vector3.new(1, 1, 1)*10^6;
bodyGyro.P = 10^6;
local bodyVel = Instance.new("BodyVelocity");
bodyVel.maxForce = Vector3.new(1, 1, 1)*10^6;
bodyVel.P = 10^4;
local isFlying = false;
local isJumping = false;
local movement = (forward = 0, backward = 0, right = 0, left = 0);
local FAD = F.Flying;
--------------Functions--------------
local function setFlying(flying)
isFlying = flying;
bodyGyro.Parent = isFlying and hrp or nil;
bodyVel.Parent = isFlying and hrp or nil;
bodyGyro.CFrame = hrp.CFrame;
bodyVel.Velocity = Vector3.new();
animate.Disabled = isFlying
if (isFlying) then
FAD.Transparency = 1
lastAnim = idleAnim;
lastAnim:Play();
else
FAD.Transparency = 0
lastAnim:Stop();
end
end
local function onUpdate(dt)
if (isFLying) then
local cf = camera.CFrame;
local direction = cf.rightVector*(movement.right - movement.left) + cf.lookVector*(movement.foward - movement.backward);
if (direction:Dot(direction) > 0) then
direction = direction.unit;
end
bodyGyro.CFrame = cf;
bodyVel.Velocity = direction * humanoid.WalkSpeed * 3
end
end
local function onJumpRequest()
if (not humanoid or humanoid:GetState() == Enum.HumanoidStateType.Dead) then
return;
end
if (isFlying) then
setFlying(false);
isJumping = false;
else if (isJumping) then
wait(0.5)setFlying(true);
end
end
local function onStateChange(old, new)
if (new == Enum.HumanoidStateType.Landed) then
isJumping = false;
elseif (new == Enum.HumanoidStateType.Jumping) then
isJumping = true;
end
end
local function movementBind(actionName, inputState, inputObject)
if (inputState == Enum.UserInputState.Begin) then
movement[actionName] = 1;
elseif (inputState == Enum.UserInputState.End) then
movement[actionName] = 0;
end
if (isFlying) then
local isMoving = movement.right + movement.left + movement.foward + movement.backward > 0;
local nextAnim = isMoving and moveAnim or idleAnim;
if (nextAnim ~= lastAnim) then
lastAnim:Stop();
lastAnim = nextAnim;
lastAnim:Play();
end
end
return Enum.ContextActionResult.Pass;
end
-------------Connections-------------
humanoid.StateChanged:Connect(onStageChange);
game:GetService("UserInputService").JumpRequest:Connect(onJumpRequest);
game:GetService("ContextActionService"):BindAction("forward", movementBind, false, Enum.PlayerActions.CharacterFoward);
game:GetService("ContextActionService"):BindAction("backward", movementBind, false, Enum.PlayerActions.CharacterBackard);
game:GetService("ContextActionService"):BindAction("left", movementBind, false, Enum.PlayerActions.CharacterLeft);
game:GetService("ContextActionService"):BindAction("right", movementBind, false, Enum.PlayerActions.CharacterRight);
game:GetService("RunService").RenderStepped:Connect(onUpdate)
In line 18, movement's value should be a dictionary, rather than variables inside the parentheses.
local movement = {forward = 0, backward = 0, right = 0, left = 0}

"no such file or directory" in preloader

I'm making a preloader for a large application. Today the error occurred "no such file or directory". This error occurs only on Android device. On the computer(in the simulator) works fine. All file names and directories to lowercase.
Code:
---------------------------------------------
---------------- Прелоадер ------------------
-- Сервис по загрузке текстур, звука --------
---------------------------------------------
TEXTURES = {} -- место в оперативной памяти для текстур
SOUNDS = {} -- место в оперативной памяти для звука
local Preloader = {}
local path = {
animations = "assets/images/animations/",
army_run = "assets/images/animations/army_run/",
area = "assets/images/area/",
access = "assets/images/area/access/",
artefacts = "assets/images/artefacts/",
castles = "assets/images/building/castles/",
mining = "assets/images/building/mining/",
flags = "assets/images/flags/",
interface = "assets/images/interface/",
marker = "assets/images/interface/marker/",
items = "assets/images/items/",
raw = "assets/images/raw/",
}
-- Место для путей к текстурам
Preloader.texture = {}
-- Место для путей к звуку
Preloader.sound = {}
-- Загрузка текстур в оперативную память
Preloader.loadingTextures = function(arr)
TEXTURES[arr.id] = {}
for i = 1, #arr do
local name = string.gsub(arr[i], '.*(.*)/', '')
TEXTURES[arr.id][name] = graphics.newTexture( { type="image", filename = arr[i] } )
TEXTURES[arr.id][name]:preload()
end
end
-- Загрузка звука в оперативную память
Preloader.loadingSounds = function()
for i = 1, #Preloader.sound do
sounds[Preloader.sound[i]] = audio.loadSound( "snd/"..Preloader.sound[i] )
end
end
-- Таймер
Preloader.getTimer = function()
return system.getTimer()
end
-- Окно загрузки
Preloader.screenLoader = nil
Preloader.loaderShow = function()
if(Preloader.screenLoader)then
return false
end
Preloader.screenLoader = display.newGroup()
Preloader.screenLoader.x = _W/2
Preloader.screenLoader.y = _H/2
local screen = display.newRect( 0, 0, _W, _H )
screen:setFillColor( 0, 0, 0 )
Preloader.screenLoader:insert(screen)
local imgLoad = "assets/images/animations/army_run/150.png"
local sheetLoad = graphics.newImageSheet( imgLoad, { width = 224, height = 224, numFrames = 8 } )
local animLoad = display.newSprite( Preloader.screenLoader, sheetLoad, { start = 1, count = 8, time = 800, loopCount=0 } )
animLoad.xScale, animLoad.yScale = _H*.001, _H*.001
animLoad.x, animLoad.y = 0, _H*-.07
animLoad:play()
-- Загрузка в процентах
tfLoader = display.newText( TEXTS.Preloader.loading..": 0%", 0, _H*.08, font, _H*.035 )
tfLoader:setTextColor( 1,1,1)
Preloader.screenLoader:insert(tfLoader)
Preloader.screenLoader.tf = tfLoader
-- Загрузка в этапах
stepLoader = display.newText( TEXTS.Preloader.start_load, 0, _H*.125, font, _H*.022 )
stepLoader:setTextColor( 160/255, 160/255, 160/255 )
Preloader.screenLoader:insert(stepLoader)
Preloader.screenLoader.step = stepLoader
end
-- Создание массивов с путями
Preloader.createPath = function()
for k, v in pairs(path) do
local i = 0
Preloader.texture[k] = { id = k }
for l in lfs.dir(v) do
if ( l ~= "." and l ~= ".." and l ~= "..." ) then
i = i + 1
Preloader.texture[k][i] = v..l
end
end
end
end
-- Запуск прелоадера и контроль процесса загрузки
Preloader.start = function()
-- Создаём шаги для загрузки
local loading_steps = {}
-- Шаг 1 - Загрузка путей
table.insert(loading_steps, function()
Preloader.createPath()
Preloader.screenLoader.step.text = TEXTS.Preloader.path_load..'...'
end)
-- Шаг 2 - Загрузка текстур интерфейса
table.insert(loading_steps, function()
Preloader.loadingTextures(Preloader.texture.interface)
Preloader.loadingTextures(Preloader.texture.marker)
Preloader.screenLoader.step.text = TEXTS.Preloader.interface_load..'...'
end)
-- Шаг 3 - Загрузка анимаций
table.insert(loading_steps, function()
Preloader.loadingTextures(Preloader.texture.animations)
Preloader.loadingTextures(Preloader.texture.army_run)
Preloader.screenLoader.step.text = TEXTS.Preloader.animations_load..'...'
end)
-- Шаг 4 - Создание карты
table.insert(loading_steps, function()
Preloader.loadingTextures(Preloader.texture.area)
Preloader.loadingTextures(Preloader.texture.access)
Preloader.loadingTextures(Preloader.texture.castles)
Preloader.loadingTextures(Preloader.texture.mining)
Preloader.screenLoader.step.text = TEXTS.Preloader.map_load..'...'
end)
-- Шаг 5 - Загрузка ресурсов
table.insert(loading_steps, function()
Preloader.loadingTextures(Preloader.texture.raw)
Preloader.loadingTextures(Preloader.texture.items)
Preloader.loadingTextures(Preloader.texture.artefacts)
Preloader.screenLoader.step.text = TEXTS.Preloader.res_load..'...'
end)
-- Шаг 6 - Загрузка параметров игрока
table.insert(loading_steps, function()
Preloader.loadingTextures(Preloader.texture.flags)
Preloader.screenLoader.step.text = TEXTS.Preloader.res_load..'...'
end)
local loading_steps_max = #loading_steps+1
local st = Preloader.getTimer()
Preloader.loaderShow()
local function mainHandler(e)
if(#loading_steps>0)then
loading_steps[1]()
table.remove(loading_steps, 1)
if(Preloader.screenLoader)then
local loading_p = math.floor((loading_steps_max - #loading_steps)*100/loading_steps_max)
Preloader.screenLoader.tf.text = TEXTS.Preloader.loading..': '..loading_p..'%'
end
return true
end
Preloader.loaderClose()
print('Time load: '..(Preloader.getTimer()-st)..'ms')
Runtime:removeEventListener("enterFrame", mainHandler)
end
Runtime:addEventListener("enterFrame", mainHandler)
end
-- Окончание загрузки
Preloader.loaderClose = function()
if(Preloader.screenLoader)then
if(Preloader.screenLoader.removeSelf)then
Preloader.screenLoader:removeSelf()
end
end
Preloader.screenLoader = nil
-- Переход на стартовую сцену
composer.gotoScene( start_scene, "fade", 0 )
end
-- Сборщик мусора
Preloader.garbage_collector = function()
for key in pairs(TEXTURES) do
for i=1, #TEXTURES[key] do
TEXTURES[key][i]:releaseSelf()
end
end
TEXTURES = {}
end
return Preloader
That's how I show images on stage:
M.dial = display.newImageRect( M.gr, TEXTURES.interface["btn_compas_comp.png"].filename, TEXTURES.interface["btn_compas_comp.png"].baseDir, 272, 272 )
M.dial.x, M.dial.y = X, Y
Thanks in advance friends.
1) All file names and directories to lowercase - I suggest to double-check this because Android filesystem is case sensitive.
2) Also check your build.settings to ensure that excludeFiles section doesn't include any of directories from your code
Edit: Another idea based on corona lfs doc - try following before loading:
local resourcesPath = system.pathForFile( "", system.ResourceDirectory )
-- Change current working directory
local success = lfs.chdir( resourcesPath ) --returns true on success
I guess that lfs doesn't point on resource directory by default. All your assets should be in this directory, but don't try to modify them - For security reasons, this directory is read-only and enforced by the operating system, not by Corona.
Edit 2: Solution that don't rely on current directory
Preloader.createPath = function()
for k, v in pairs(path) do
local i = 0
local pathForDirectory = system.pathForFile(v, system.ResourceDirectory)
Preloader.texture[k] = { id = k }
for l in lfs.dir(pathForDirectory) do
if ( l ~= "." and l ~= ".." and l ~= "..." ) then
i = i + 1
Preloader.texture[k][i] = v..l
end
end
end
end

Attempt to index local 'v' (a nil value)

I'm trying to edit a lua script to add on my Garry's Mod Server, but I get this error and I dont know what to do.
Error:
[ERROR] --/sh_worlditemspawner.lua:56: attempt to index local 'v' (a nil value)
Code:
local PLUGIN = PLUGIN
PLUGIN.name = "World Item Spawner"
PLUGIN.author = "Black Tea"
PLUGIN.desc = "World Item Spawner."
PLUGIN.itempoints = PLUGIN.itempoints or {}
PLUGIN.spawngroups = {
["default"] = {
{"bleach"},
},
["example"] = {
{"ration"},
},
["junks"] = {
{"junk_ws"},
{"junk_wj"},
{"junk_be"},
{"junk_bt"},
{"junk_p"},
{"junk_ss"},
{"junk_bl"},
{"junk_k"},
{"junk_p"},
{"junk_hp"},
{"junk_ec"},
{"junk_ej"},
}
}
PLUGIN.spawnrate = 30
PLUGIN.maxitems = 10
PLUGIN.itemsperspawn = 2
PLUGIN.spawneditems = PLUGIN.spawneditems or {}
if SERVER then
local spawntime = 1
function PLUGIN:Think()
if spawntime > CurTime() then return end
spawntime = CurTime() + self.spawnrate
for k, v in ipairs(self.spawneditems) do
if (!v:IsValid()) then
table.remove(self.spawneditems, k)
end
end
if #self.spawneditems >= self.maxitems then return end
for i = 1, self.itemsperspawn do
if #self.spawneditems >= self.maxitems then return end
local v = table.Random(self.itempoints)
if #self.spawneditems > self.maxitems then
return
end
local data = {}
data.start = v[1]
data.endpos = data.start + Vector(0, 0, 1)
data.filter = client
data.mins = Vector(-16, -16, 0)
data.maxs = Vector(16, 16, 16)
local trace = util.TraceHull(data)
if trace.Entity:IsValid() then
continue
end
local idat = table.Random(self.spawngroups[v[2]]) or self.spawngroup["default"]
local item = nut.item.Spawn(v[1] + Vector( math.Rand(-8,8), math.Rand(-8,8), 10 ), AngleRand(), idat[1], idat[2] or {})
table.insert( self.spawneditems, item )
end
end
function PLUGIN:LoadData()
self.itempoints = nut.util.ReadTable("itempoints")
end
function PLUGIN:SaveData()
for k, v in ipairs(self.spawneditems) do
v:Remove()
end
nut.util.WriteTable("itempoints", self.itempoints)
end
else
netstream.Hook("nut_DisplaySpawnPoints", function(data)
for k, v in pairs(data) do
local emitter = ParticleEmitter( v[1] )
local smoke = emitter:Add( "sprites/glow04_noz", v[1] )
smoke:SetVelocity( Vector( 0, 0, 1 ) )
smoke:SetDieTime(10)
smoke:SetStartAlpha(255)
smoke:SetEndAlpha(255)
smoke:SetStartSize(64)
smoke:SetEndSize(64)
smoke:SetColor(255,186,50)
smoke:SetAirResistance(300)
emitter:Finish()
end
end)
end
nut.command.Register({
adminOnly = true,
onRun = function(client, arguments)
local trace = client:GetEyeTraceNoCursor()
local hitpos = trace.HitPos + trace.HitNormal*5
local spawngroup = arguments[1] or "default"
table.insert( PLUGIN.itempoints, { hitpos, spawngroup } )
nut.util.Notify( "You added ".. spawngroup .. " item spawner." )
end
}, "itemspawnadd")
nut.command.Register({
adminOnly = true,
onRun = function(client, arguments)
local trace = client:GetEyeTraceNoCursor()
local hitpos = trace.HitPos + trace.HitNormal*5
local range = arguments[1] or 128
local mt = 0
for k, v in pairs( PLUGIN.itempoints ) do
local distance = v[1]:Distance( hitpos )
if distance <= tonumber(range) then
PLUGIN.itempoints[k] = nil
mt = mt + 1
end
end
nut.util.Notify( mt .. " item spawners has been removed.")
end
}, "itemspawnremove")
nut.command.Register({
adminOnly = true,
onRun = function(client, arguments)
if SERVER then
netstream.Start(client, "nut_DisplaySpawnPoints", PLUGIN.itempoints)
nut.util.Notify( "Displayed All Points for 10 secs." )
end
end
}, "itemspawndisplay")
This is because
table.Random(self.itempoints)
returns nil. Did you mean math.random? If you post code for that table.Random func I can give more info.

how to get array value in lua in not using id

i have this array in my lua...
local data = {}
data[1] = {}
data[1].title = "Crazy Song"
data[1].subtitle = "by Bruno Earth"
data[1].image = "note.png"
data[2] = {}
data[2].title = "Enter Sunman"
data[2].subtitle = "by Mentalica"
data[2].image = "note.png"
data[3] = {}
data[3].title = "Bitter Child of Mine"
data[3].subtitle = "by Gunz n bullets"
data[3].image = "note.png"
data[4] = {}
data[4].title = "Missed A thing"
data[4].subtitle = "by Ero-Smith"
data[4].image = "note.png"
data[5] = {}
data[5].title = "Pornstar"
data[5].subtitle = "by Nicklefront"
data[5].image = "note.png"
data[6] = {}
data[6].title = "Burner"
data[6].subtitle = "by Asher"
data[6].image = "note.png"
how can i get the array values by not using id on it. i just want to get the title for my conditional statement?
i try this in my code:
local getTitle = function(event)
print (".................")
print (event.target.id)
print (event.target.title)
end
but i got only this...
touch: began
touch: ended
.................
2
nil
how can i get and print the title of my array?
this is my code:
module(..., package.seeall)
display.setStatusBar( display.HiddenStatusBar )
function new()
local localGroup = display.newGroup()
local tableView = require("tableView")
local ui = require("ui")
--------------------------------------------------------------------------
local screenOffsetW, screenOffsetH = display.contentWidth - display.viewableContentWidth, display.contentHeight - display.viewableContentHeight
local songList
local backBtn
local detailScreenText
local background = display.newRect(0, 0, display.contentWidth, display.contentHeight)
background:setFillColor(0, 0, 0)
localGroup:insert(background)
local data = {}
--iPad: setup a color fill for selected items
local selected = display.newRect(0, 0, 50, 50) --add acolor fill to show the selected item
selected:setFillColor(67,141,241,180) --set the color fill to light blue
selected.isVisible = false --hide color fill until neede
-----------------------------------------------
data[1] = {}
data[1].title = "Crazy Song"
data[1].subtitle = "by Bruno Earth"
data[1].image = "note.png"
data[2] = {}
data[2].title = "Enter Sunman"
data[2].subtitle = "by Mentalica"
data[2].image = "note.png"
data[3] = {}
data[3].title = "Bitter Child of Mine"
data[3].subtitle = "by Gunz n bullets"
data[3].image = "note.png"
data[4] = {}
data[4].title = "Missed A thing"
data[4].subtitle = "by Ero-Smith"
data[4].image = "note.png"
data[5] = {}
data[5].title = "Pornstar"
data[5].subtitle = "by Nicklefront"
data[5].image = "note.png"
data[6] = {}
data[6].title = "Burner"
data[6].subtitle = "by Asher"
data[6].image = "note.png"
local topBoundary = display.screenOriginY + 40
local bottomBoundary = display.screenOriginY + 0
local getTitle = function(event)
print (".................")
print (event.target.id)
print (event.target.title)
end
songList = tableView.newList{
data=data,
default="listItemBg.png",
over="listItemBg_over.png",
onRelease=getTitle,
top=topBoundary,
bottom=bottomBoundary,
callback = function( row )
local g = display.newGroup()
local img = display.newImage(row.image)
g:insert(img)
img.x = math.floor(img.width*0.5 + 6)
img.y = math.floor(img.height*0.5)
local title = display.newText( row.title, 0, 0, native.systemFontBold, 16 )
title:setTextColor(0,0,0)
g:insert(title)
title.x = title.width*0.5 + img.width + 6
title.y = 30
local subtitle = display.newText( row.subtitle, 0, 0, native.systemFont, 14 )
subtitle:setTextColor(80,80,90)
g:insert(subtitle)
subtitle.x = subtitle.width*0.5 + img.width + 6
subtitle.y = title.y + title.height + 6
return g
end
}
localGroup:insert(songList)
local function scrollToTop()
songList:scrollTo(topBoundary-1)
end
local navBar = display.newImage("navBar.png")
navBar.x = display.contentWidth*.5
navBar.y = math.floor(display.screenOriginY + navBar.height*0.5)
localGroup:insert(navBar)
local navHeader = display.newText("Song Lists", 0, 0, native.systemFontBold, 16)
navHeader:setTextColor(255, 255, 255)
navHeader.x = display.contentWidth*.5
navHeader.y = navBar.y
localGroup:insert(navHeader)
--backBtn.alpha = 0
local listBackground = display.newRect( 0, 0, songList.width, songList.height )
listBackground:setFillColor(255,255,255)
songList:insert(1,listBackground)
--Setup the back button
function changeScene(e)
if e.phase == 'ended' then
print ("ok")
director:changeScene(e.target.scene, "fade")
print ("back!")
end
end
backBtn = display.newImage("backButton.png")
backBtn.x = math.floor(backBtn.width/2) + backBtn.width + screenOffsetW
backBtn.y = navBar.y
backBtn.scene = "menu"
backBtn:addEventListener("touch", changeScene)
return localGroup
end
i got it...
i do this
local getTitle = function(event)
print (".................")
local id = event.target.id
print (id)
print (data[id].title)
end

Resources