I have a problem with a function and an array since yesterday. It seems that lever ID is not declared or something...
Here is my code:
function tpp(leverID, from, to)
if item.uid == leverID and item.itemid == 1945 then
local count_players = #to
local store = {}
for i = 1, count_players do
local pid = getTopCreature(from[i]).uid
if (pid == 0 or not isPlayer(pid)) then
return doPlayerSendCancel(cid, 'You need ' .. count_players .. ' players to use this lever.')
end
store[i] = pid
end
for i = 1, count_players do
doSendMagicEffect(from[i], CONST_ME_POFF)
doTeleportThing(store[i], to[i], false)
doSendMagicEffect(to[i], CONST_ME_TELEPORT)
end
doTransformItem(item.uid, item.itemid + 1)
elseif item.uid == leverID and item.itemid == 1946 then
doTransformItem(item.uid, item.itemid -1)
end
end
function onUse(cid, item, fromPosition, itemEx, toPosition)
local pos = {
['pos_start'] = {
{['x'] = 1059, ['y'] = 1034, ['z'] = 7},
{['x'] = 1060, ['y'] = 1034, ['z'] = 7}
},
['pos_end'] = {
{['x'] = 1059, ['y'] = 1032, ['z'] = 7},
{['x'] = 1060, ['y'] = 1032, ['z'] = 7}
}
}
tpp(10150, pos['pos_start'], pos['pos_end'])
return true
end
I get the this error:
attempt to index global 'item' (a nil value)
I am new to lua. Can someone help me? Thanks!
Probably you forgot to pass 'item' variable to tpp() function when you called it from onUse() function.
Since there was no 'item variable in scope of tpp() function, or in its arguments, variable considered to be global, and there's no global variable with that name.
Related
Was wondering for a good way to retrieve a value from a table by using a path, like some sort of scope.
As example for a path, "SomePermissions/scope1/B", which gets the permissions from a table that looks like this
{
["SomePermissions"] = {
["scope1"] = {
["A"] = "special",
["B"] = true,
["C"] = false,
}
}
}
What is a good way to do it?
Here is the solution that I made for this: https://stackoverflow.com/a/73013693/11161500
There could be small improvements for it, like giving the function the possibility to specify what to split for. Or when "SomePermissions/scope1/" has that "/" since it splits it, there would be an empty string value.
This is something I came up with, except string_split and string_totable:
function string_totable( str )
local tbl = {}
for i = 1, string.len( str ) do
tbl[i] = string.sub( str, i, i )
end
return tbl
end
function string_split(str, separator, withpattern)
if ( separator == "" ) then return string_totable( str ) end
if ( withpattern == nil ) then withpattern = false end
local ret = {}
local current_pos = 1
for i = 1, string.len( str ) do
local start_pos, end_pos = string.find( str, separator, current_pos, not withpattern )
if ( not start_pos ) then break end
ret[ i ] = string.sub( str, current_pos, start_pos - 1 )
current_pos = end_pos + 1
end
ret[ #ret + 1 ] = string.sub( str, current_pos )
return ret
end
function GetTableValueByScope(tbl, path)
local pathParts = string_split(path, "/")
local enteredPaths = ""
local curLocation = tbl
for i=1,#pathParts do
if (curLocation[pathParts[i]] == nil) then
print("Entry \""..pathParts[i].."\" in \""..enteredPaths.."\", does not exist.")
return nil
end
if (i == #pathParts) then -- If last value in pathParts
return curLocation[pathParts[i]]
else
curLocation = curLocation[pathParts[i]]
enteredPaths = enteredPaths..pathParts[i].."/"
end
end
return curLocation
end
local exampleTable = {
["SomePermissions"] = {
["scope1"] = {
["A"] = "special",
["B"] = true,
["C"] = false,
}
}
}
print(GetTableValueByScope(exampleTable, "SomePermissions/scope1/B"))
-- Prints the value from "B".
print(GetTableValueByScope(exampleTable, "SomePermissions/scope1/ABC"))
-- Prints 'Entry "ABC" in "SomePermissions/scope1/", does not exist.'
local result = GetTableValueByScope(exampleTable, "SomePermissions/scope1")
-- "result" would now be "scope1" table.
-- The function returns a table, like that I can specifiy one scope and return the results within of what it found, and then call the function again with the next scope.
result = GetTableValueByScope(result, "B")
print(result)
-- Prints the value from "B".
I am using model.GetType().GetProperties() with foreach to compare properties of 2 object of same class.
like this
foreach (var item in kayit.GetType().GetProperties())
{
var g = item.GetValue(plu);
var b = item.GetValue(kayit);
if (g is string && b is string&& g!=b)
{
a += item.Name + "*";
}
else if (g is DateTime&& b is DateTime&& g!=b)
{
a += item.Name + "*";
}
}
But the problem is even if they have the same value g!=b returns a true all the time. I have used a break point to prove this and they are literally same thing. Actually I am taking the value putting it in textbox then creating another class after button click and comaring to see the changed properties. So even if I don't change anything it doesn't read the mas equals. Can someone help me about this please?
more info:
I get the plu from database and populate my control with it:
txtorder.Text = plu.OrderNo;
dtporder.Value = nulldate(plu.OrderDate);
dtp1fit.Value = nulldate(plu.FirstFitDate);
dtp1yorum.Value = nulldate(plu.FirstCritDate);
dtp2fit.Value = nulldate(plu.SecondFitDate);
dtp2yorum.Value = nulldate(plu.SecondCritDate);
dtpsizeset.Value = nulldate(plu.SizeSetDate);
dtpsizesetok.Value = nulldate(plu.SizeSetOkDate);
dtpkumasplan.Value = nulldate(plu.FabricOrderByPlan);
txtTedarikci.Text = plu.Fabric_Supplier;
dtpkumasFP.Value = nulldate(plu.FabricOrderByFD);
dtpfabarrive.Value = nulldate(plu.FabricArrive);
dtpbulk.Value = nulldate(plu.BulkFabricDate);
dtpbulkok.Value = nulldate(plu.BulkConfirmDate);
dtpaccessory.Value = nulldate(plu.AccessoriesDate);
dtpaccessoryarrive.Value = nulldate(plu.AccessoriesArriveDate);
dtpcutok.Value = nulldate(plu.ProductionStartConfirmation);
dtpcutstart.Value = nulldate(plu.ProductionStart);
dtpshipmentdate.Value = nulldate(plu.ShipmentDate);
dtpshipmentsample.Value = nulldate(plu.ShipmentSampleDate);
dtpshippedon.Value = nulldate(plu.Shippedon);
nulldate is just a method where I change null values to my default value.
And this is what I do after button click:
var kayit = new uretim();
kayit.OrderNo = txtorder.Text.ToUpper();
kayit.OrderDate = vdat(dtporder.Value);
kayit.FirstFitDate = vdat(dtp1fit.Value);
kayit.FirstCritDate = vdat(dtp1yorum.Value);
kayit.SecondFitDate = vdat(dtp2fit.Value);
kayit.SecondCritDate = vdat(dtp2yorum.Value);
kayit.SizeSetDate = vdat(dtpsizeset.Value);
kayit.SizeSetOkDate = vdat(dtpsizesetok.Value);
kayit.FabricOrderByPlan = vdat(dtpkumasplan.Value);
kayit.Fabric_Supplier = txtTedarikci.Text;
kayit.FabricOrderByFD = vdat(dtpkumasFP.Value);
kayit.FabricArrive = vdat(dtpfabarrive.Value);
kayit.BulkFabricDate = vdat(dtpbulk.Value);
kayit.BulkConfirmDate = vdat(dtpbulkok.Value);
kayit.AccessoriesDate = vdat(dtpaccessory.Value);
kayit.AccessoriesArriveDate = vdat(dtpaccessoryarrive.Value);
kayit.ProductionStartConfirmation = vdat(dtpcutok.Value);
kayit.ProductionStart = vdat(dtpcutstart.Value);
kayit.ShipmentDate = vdat(dtpshipmentdate.Value);
kayit.ShipmentSampleDate = vdat(dtpshipmentsample.Value);
kayit.Shippedon = vdat(dtpshippedon.Value);
kayit.Status = true;
kayit.WrittenDate = DateTime.Now;
kayit.GuidKey = plu.GuidKey != null ? plu.GuidKey : Guid.NewGuid().ToString("N");
I have proven by breakpoint that values are actually same. But the != check retruns a true.
When you are doing
g != b
compiler doesn't know that these objects are strings to compare so it compares their references. You can do:
g.Equals(b) //be carefull if one of them is null
or
g.ToString() != b.ToString()
EDIT
You can compare them after you check the type:
if (g is string && b is string)
{
if( g.ToString() != b.ToString() ){
}
}
I'm using the following code to play explosion animation, How can I removeSelf the animation when it finished the loop-count?
function showExplotion(event)
local sheetData = { width=32, height=32, numFrames=13, sheetContentWidth=128, sheetContentHeight=128 }
local mySheet = graphics.newImageSheet( "media/fire.png", sheetData )
local sequenceData = {
--{ name = "normalRun", start=1, count=13, loopCount = 1, time=800 }
{ name = "fastRun", frames={ 1,2,4,5,6,7,8,9,10,11,12,13 }, time=800, loopCount = 1 }
}
local animation = display.newSprite( mySheet, sequenceData )
animation.x = event.x
animation.y = event.y
animation:play()
end
you can add listener to your sprite animation to detect it's phase
function showExplotion(event)
local sheetData = { width=32, height=32, numFrames=13, sheetContentWidth=128, sheetContentHeight=128 }
local mySheet = graphics.newImageSheet( "media/fire.png", sheetData )
local sequenceData = {
--{ name = "normalRun", start=1, count=13, loopCount = 1, time=800 }
{ name = "fastRun", frames={ 1,2,4,5,6,7,8,9,10,11,12,13 }, time=800, loopCount = 1 }
}
local animation = display.newSprite( mySheet, sequenceData )
animation.x = event.x
animation.y = event.y
animation:play()
local function mySpriteListener( event )
if ( event.phase == "ended" ) then
animation:removeSelf()
animation = nil
end
end
animation:addEventListener( "sprite", mySpriteListener )
end
Hello guys here with another question, regarding sql server 2008 r2 this time about the merge, is it possible to have a case inside the update portion of the merge?
Because its telling me
Msg 156, Level 15, State 1, Line 9
Incorrect syntax near the keyword 'CASE'.
MERGE INTO PERSONAFISICA AS TARGET
USING dbo.#temp1 AS SOURCE
ON TARGET.RFC = SOURCE.RFC AND TARGET.APATERNO = SOURCE.APELLIDO_PATERNO AND
TARGET.AMATERNO = SOURCE.Apellido_Materno
WHEN MATCHED THEN
UPDATE SET
TARGET.NUM_CLIENTE = 0,
TARGET.NOMBRE1 = LEFT(SOURCE.Nombre,CHARINDEX(' ', SOURCE.NOMBRE + ' ') -1),
CASE
WHEN LEN(SOURCE.NOMBRE) - LEN(REPLACE(SOURCE.NOMBRE,' ','')) >= 1
THEN
TARGET.NOMBRE2 = SUBSTRING(SOURCE.NOMBRE, CHARINDEX(' ', SOURCE.NOMBRE)+1, LEN(SOURCE.NOMBRE))
ELSE '' END,
TARGET.APATERNO = SOURCE.Apellido_Paterno,
TARGET.AMTERNO = SOURCE.Apellido_Materno,
CASE
WHEN SOURCE.SEXO = 'F'
THEN TARGET.IDGENERO = 2
WHEN SOURCE.SEXO = 'M'
THEN TARGET.IDGENERO = 1
ELSE TARGET.IDGENERO = 0
END,
CASE
WHEN SOURCE.ESTADO_CIVIL = '0'
THEN TARGET.idestado_civil = 0
WHEN SOURCE.ESTADO_CIVIL = 'C'
THEN TARGET.idestado_civil = 1
WHEN SOURCE.ESTADO_CIVIL = 'D'
THEN TARGET.idestado_civil = 2
WHEN SOURCE.ESTADO_CIVIL = 'S'
THEN TARGET.idestado_civil = 3
WHEN SOURCE.ESTADO_CIVIL = 'V'
THEN TARGET.idestado_civil = 5
WHEN SOURCE.ESTADO_CIVIL = 'U'
THEN TARGET.idestado_civil = 6
ELSE TARGET.idestado_civil = 0
END,
TARGET.idregimen = 0,
TARGET.saludo = SOURCE.SALUDO,
TARGET.conyuge_nombre1 = '',
TARGET.conyuge_nombre2 = '',
TARGET.conyuge_apaterno = '',
TARGET.conyuge_nombre2 = '',
TARGET.dependiente = 0,
TARGET.edad_dependiente = '',
TARGET.ididentificacion = 0,
TARGET.fecha_nacimiento = '1800-01-01',
TARGET.rfc = SOURCE.RFC,
TARGET.CURP = '',
TARGET.idnacionalidad = 0,
TARGET.email = SOURCE.Email_Personal,
TARGET.idescolaridad = SOURCE.Escolaridad
WHEN NOT MATCHED THEN
INSERT (num_cliente, nombre1, nombre2, apaterno, amaterno, idgenero, idestado_civil,
idregimen, saludo, conyuge_nombre1, conyuge_nombre2, conyuge_apaterno, conyuge_amaterno, dependiente,
edad_dependiente, ididentificacion, fecha_nacimiento, rfc, curp, idnacionalidad, email, idescolaridad)
VALUES (0, LEFT(nombre,CHARINDEX(' ',nombre + ' ')-1) AS [Primer Nombre],
CASE WHEN LEN(nombre) - LEN(REPLACE(nombre,' ','')) >= 1 THEN SUBSTRING(nombre, CHARINDEX(' ', nombre)+1, LEN(nombre)) ELSE '' END AS [Segundo Nombre],
Apellido_Paterno,Apellido_Materno)
CASE
WHEN SEXO = 'F' THEN 2
WHEN SEXO = 'M' THEN 1
ELSE 0
END,
CASE
WHEN Estado_Civil = '0' THEN 0
WHEN Estado_Civil = 'C' THEN 1
WHEN Estado_Civil = 'D' THEN 2
WHEN Estado_Civil = 'S' THEN 3
WHEN Estado_Civil = 'V' THEN 5
WHEN Estado_Civil = 'U' THEN 6
ELSE 0
END, 0, Saludo,'','','','',0,'',0,'1800-01-01',RFC,'',0,Email_Personal,Escolaridad
You can't use a case in that way in an update. It needs to be like ...
UPDATE table
SET value1 = CASE
WHEN a.blah = b.blah THEN foo
WHEN a.blah > b.blah THEN bar
ELSE NULL
END,
value2 = 5,
......
I'm trying to create a simple addon for world of warcraft which records my kills.
I've already got'n quite far except there is a problem with the writing of a lua array.
The code I have so far
local CharacterDefaults = {
kills = {},
totalkills = 0
}
local killDefaults = {
DBtimeofday = 0,
DBplayer = 0,
DBenemyname = 0,
DBenemyid = 0,
DBzone = 0,
DBkilltype = 0
}
The next piece is inside a event which checks for overkill
if not KillCount then
KillCount = CharacterDefaults
end
if not KillCount.totalkills then
KillCount.totalkills = 0
end
KillCount.enemy[KillCount.totalkills] = destName
KillCount.kills[KillCount.totalkills] = killDefaults
KillCount.kills[KillCount.totalkills].DBtimeofday = stamp
KillCount.kills[KillCount.totalkills].DBzone = zone
KillCount.kills[KillCount.totalkills].DBkilltype = killtype
KillCount.kills[KillCount.totalkills].DBenemyid = unitId
KillCount.kills[KillCount.totalkills].DBenemyname = destName
KillCount.kills[KillCount.totalkills].DBplayer = playerName
KillCount.totalkills = KillCount.totalkills + 1
Ofcourse there's more code but this is the only important code (as far as I know).
If I look at this I would expect that for every new kill a new array part is made and the values are entered. However, for each kill I make in world of warcraft, every single item already in it will get the results of the last kill.
The lua variables saved file:
KillCount = {
["kills"] = {
{
["DBplayer"] = "MyName",
["DBzone"] = "Blackrock Depths",
["DBkilltype"] = 0,
["DBenemyname"] = "Grim Patron",
["DBenemyid"] = 9545,
["DBtimeofday"] = "11-09-22 10:45:23",
}, -- [1]
{
["DBplayer"] = "MyName",
["DBzone"] = "Blackrock Depths",
["DBkilltype"] = 0,
["DBenemyname"] = "Grim Patron",
["DBenemyid"] = 9545,
["DBtimeofday"] = "11-09-22 10:45:23",
}, -- [2]
[0] = {
["DBplayer"] = "MyName",
["DBzone"] = "Blackrock Depths",
["DBkilltype"] = 0,
["DBenemyname"] = "Grim Patron",
["DBenemyid"] = 9545,
["DBtimeofday"] = "11-09-22 10:45:23",
},
},
["totalkills"] = 3,
}
as you can see the [0] is the only one to be properly writen. Am I doing something wrong?
The problem is here:
KillCount.kills[KillCount.totalkills] = killDefaults
Everytime you kill, you're pointing KillCount.kills[KillCount.totalkills] to killDefaults then modifying killDefaults. The problem is, you are using the same killDefaults every time. So when you udpate the values of killDefaults later, it affects every reference to killDefaults that you have already created.
Try something like:
function GetDefaultKills()
return {
DBtimeofday = 0,
DBplayer = 0,
DBenemyname = 0,
DBenemyid = 0,
DBzone = 0,
DBkilltype = 0
};
end
KillCount.kills[KillCount.totalkills] = GetDefaultKills()