RegisterServerEvent('XD')
AddEventHandler('XD', function()
print(source)
end)
TriggerServerEvent("XD")
is there a way to spoof your source from the server when you trigger an event.
i though of doing this when you trigger
TriggerServerEvent("XD", source = '200' -- [[this is the source the server will think you are]])
Lua is a language of reference. If Lua cannot see something, it cannot use it.
Typically, as a rule of thumb: if you do not define the variable, you cannot use it. There are exceptions to this, which are the functions that the global variable provides to you, like print.
We also see another issue: you try to define source like a table, but you don't give it a table to rest in.
There are two ways to solve this problem.
#1. Give source it's own argument
Remove source and add source as a argument to function(...)
Server:
RegisterServerEvent('XD')
AddEventHandler('XD', function(source)
print(source)
end)
Client:
TriggerServerEvent("XD", '200')
#2. Create a table for source to hang out in
To start with, give the TriggerServerEvent a nice cozy table.
TriggerServerEvent("XD", {} )
Then put source into it.
TriggerServerEvent("XD", { source = '200' })
Now, on the server, we need an argument for the table:
RegisterServerEvent('XD')
AddEventHandler('XD', function(args)
print(args)
end)
However, since args is a table, and we want source, we have to index it.
RegisterServerEvent('XD')
AddEventHandler('XD', function(args)
print(args.source) -- or args["source"]
end)
I'm new to erlang, and am running into an error with records in one of my modules. I'm emulating ships inside of a shipping_state, and I want to create a simple function that will print the ship id, name, and container cap of a certain ship, based on it's ID. I utilized list:keyfind, as I believe it will help, but perhaps I am not using it correctly. I have a .hrl file that contains the record declarations, and a .erl file with the function and initialization of my #shipping_state.
shipping.erl:
-module(shipping).
-compile(export_all).
-include_lib("./shipping.hrl").
get_ship(Shipping_State, Ship_ID) ->
{id, name, containercap} = list:keyfind(Ship_ID, 1, Shipping_State#shipping_state.ships).
shipping.hrl:
-record(ship, {id, name, container_cap}).
-record(container, {id, weight}).
-record(shipping_state,
{
ships = [],
containers = [],
ports = [],
ship_locations = [],
ship_inventory = maps:new(),
port_inventory = maps:new()
}
).
-record(port, {id, name, docks = [], container_cap}).
Result:
shipping:get_ship(shipping:init(),1).
** exception error: {badrecord,shipping_state}
in function shipping:get_ship/2 (shipping.erl, line 18)
I'd like to say that keyfind should work, and perhaps when I create the tuple {id, name, containercap}, something is wrong with the syntax there, but if I need to completely rethink how I would go about doing this problem, any assistance would be greatly appreciated.
Edit,
I've modified my code to follow Alexey's suggestions, however, there still appears to be the same error. Any further insights?
get_ship(Shipping_State, Ship_ID) ->
{ship, Id, Name, Containercap} = list:keyfind(Ship_ID, 2,
Shipping_State#shipping_state.ships),
io:format("id = ~w, name = ~s, container cap = ~w",[Id, Name, Containercap]).
See Internal Representation of Records: #ship{id=1,name="Santa Maria",container_cap=20} becomes {ship, 1, "Santa Maria", 20}, so the id is the 2nd element, not the first one.
{id, name, containercap} = ...
should be
#ship{id=Id, ...} = ...
or
{ship, Id, Name, Containercap} = ...
Your current code would only succeed if keyfind returned a tuple of 3 atoms.
The error {badrecord,shipping_state} is telling you that the code of get_ship expects its first argument to be a #shipping_state, but you pass {ok, #shipping_state{...}} (the result of init).
Records were added to the Erlang language because dealing with tuples fields by number was error-prone, especially as code changed during development and tuple fields were added, changed, or dropped. Don't use numbers to identify record fields, and don't treat records using their underlying tuple representation, as both work against the purpose of records and are unnecessary.
In your code, rather than using record field numbers with lists:keyfind/3, use the record names themselves. I've revised your get_ship/2 function to do this:
get_ship(Shipping_State, Ship_ID) ->
#ship{id=ID, name=Name, container_cap=ContainerCap} = lists:keyfind(Ship_ID, #ship.id, Shipping_State#shipping_state.ships),
io:format("id = ~w, name = ~s, container cap = ~w~n",[ID, Name, ContainerCap]).
The syntax #<record_name>.<record_field_name> provides the underlying record field number. In the lists:keyfind/3 call above, #ship.id provides the field number for the id field of the ship record. This will continue to work correctly even if you add fields to the record, and unlike a raw number it will cause a compilation error should you decide to drop that field from the record at some point.
If you load your record definitions into your shell using the rr command, you can see that #ship.id returns the expected field number:
1> rr("shipping.hrl").
[container,port,ship,shipping_state]
2> #ship.id.
2
With the additional repairs to your function above to handle the returned record correctly, it now works as expected, as this shell session shows:
3> {ok, ShippingState} = shipping:init().
{ok,{shipping_state,[{ship,1,"Santa Maria",20},
{ship,2,"Nina",20},
{ship,3,"Pinta",20},
{ship,4,"SS Minnow",20},
{ship,5,"Sir Leaks-A-Lot",20}],
[{container,1,200},
...
4> shipping:get_ship(ShippingState, 1).
id = 1, name = Santa Maria, container cap = 20
ok
Alexey's answer answers your question, in particular the 3rd point. I just want to suggest an improvement to your keyfind call. You need to pass the tuple index to it, but you can use record syntax to get that index without hard-coding it, like this:
list:keyfind(Ship_ID, #ship.id, Shipping_State#shipping_state.ships),
#ship.id returns the index of the id field, in this case 2. This makes it easier to read the code - no need to wonder what the constant 2 is for. Also, if for whatever reason you change the order of fields in the ship record, this code will still compile and do the right thing.
I have a Lua function where I build a table of value and attempt to add it to a global table with a named key.
The key name is pulled from the function arguments. Basically, it's a filename, and I'm pairing it up with data about the file.
Unfortunately, the global table always comes back nil. Here's my code: (let me know if you need to see more)
(Commented parts are other attempts, although many attempts have been deleted already)
Animator = Class{}
function Animator:init(atlasfile, stringatlasfriendlyname, totalanimationstates, numberofframesperstate, booleanstatictilesize)
-- Define the Animator's operation mode. Either static tile size or variable.
if booleanstatictilesize ~= false then
self.isTileSizeStatic = true
else
self.isTileSizeStatic = false
end
-- Define the total animation states (walking left, walking right, up down, etc.)
-- And then the total frames per state.
self.numAnimationStates = totalanimationstates or 1
self.numAnimationFrames = numberofframesperstate or 2
-- Assign the actual atlas file and give it a programmer-friendly name.
self.atlasname = stringatlasfriendlyname or removeFileExtension(atlasfile, 'animation')
generateAnimationQuads(atlasfile, self.atlasname, self.numAnimationStates, self.numAnimationFrames)
end
function generateAnimationQuads(atlasfile, atlasfriendlyname, states, frames)
spriteWidthDivider = atlasfile:getWidth() / frames
spriteHeightDivider = atlasfile:getHeight() / states
animationQuadArray = generateQuads(atlasfile, spriteWidthDivider, spriteHeightDivider)
animationSetValues = {atlasarray = animationQuadArray, width = spriteWidthDivider, height = spriteHeightDivider}
--gAnimationSets[#gAnimationSets+1] = atlasfriendlyname
gAnimationSets[atlasfriendlyname] = animationSetValues
--table.insert(gAnimationSets, atlasfriendlyname)
end
Note: when using print(atlasfriendlyname) and print(animationSetValues), neither are empty or nil. They both contain values.
For some reason, the line(s) that assign the key pair to gAnimationSets does not work.
gAnimationSets is defined a single time at the top of the program in main.lua, using
gAnimationSets = {}
Animator class is called during the init() function of a character class called Bug. And the Bug class is initialized in the init() function of StartState, which extends from BaseState, which simply defines dummy init(), enter(), update() etc. functions.
StartState is invoked in main.lua using the StateMachine class, where it is passed into StateMachine as a value of a global table declared in main.lua.
gAnimationSets is declared after the table of states and before invoking the state.
This is using the Love2D engine.
Sorry that I came here for help, I've been picking away at this for hours.
Edit: more testing.
Trying to print the animationQuadArray at the index gTextures['buganimation'] always returns nil. Huh?
Here's gTextures in Main.lua
gTextures = {
['background'] = love.graphics.newImage('graphics/background.png'),
['main'] = love.graphics.newImage('graphics/breakout.png'),
['arrows'] = love.graphics.newImage('graphics/arrows.png'),
['hearts'] = love.graphics.newImage('graphics/hearts.png'),
['particle'] = love.graphics.newImage('graphics/particle.png'),
['buganimation'] = love.graphics.newImage('graphics/buganimation.png')
}
Attempting to return gTextures['buganimation'] returns a file value as normal. It's not empty.
My brain is so fried right now I can't even remember why I came to edit this. I can't remember.
Global table in Main.lua, all other functions can't access it.
print(gTextures['buganimation']) works inside the function in question. So gTextures is absolutely accessible.
Table isn't empty. AnimationSetValues is not empty.
I'm adding second answer because both are correct in context.
I ended up switching IDE's to VS Code and now the original one works.
I was originally using Eclipse LDT with a Love2D interpreter and in that environment, my original answer is correct, but in VS Code, the original is also correct.
So Dimitry was right, they are equivalent, but something about my actual Eclipse setup was not allowing that syntax to work.
I switched to VS Code after I had another strange syntax problem with the interpreter where goto syntax was not recognized and gave a persistent error. The interpreter thought goto was the name of a variable.
So I switched, and now both things are fixed. I guess I just won't use LDT for now.
Solution: Lua syntax. Brain Fry Syndrome
I wrote:
animationSetValues = {atlasarray = animationQuadArray, width = spriteWidthDivider, height = spriteHeightDivider}
Should be:
animationSetValues = {['atlasfile']=atlasfile, ['atlasarray']=animationQuadArray, ['width']=spriteWidthDivider, ['height']=spriteHeightDivider}
Edit: I'm fully aware of how to use answers. This was posted here to reserve my spot for an answer so I could edit it later when I returned back home, which is exactly what I'm doing right now. I'll keep the old post for archival purposes.
Original:
I solved it. I apologize for not posting the solution right now. My brain is melted into gravy.
I will post it tomorrow. Just wanted to "answer" saying no need to help. Solved it.
Solution is basically, "oh it's just one of those Lua things". Wonderful. I'm having so much fun with this language - you can tell by my blank expression.
From the language without line endings or brackets, but forced print parentheses... ugh. I'm going back to C# when this class is done.
Actually I am writting a programming language in Lua. It was quite fun. I've wrote a bit of standard library (stack op and simple io). Then I've thought about labels. It would look like in assembly. While and for loop aren't funny in any bit so programming in that language can be quite challenging. Here are some requirements for this system:
Label stack (or array, dictionary) must be accessible from global context.
Jump instruction handler will be in separate file.
This is how my label-handling function look like:
function handleLabel(name,currentLine)
end
I have no idea how to implement this kind of magic. First I've thought about that:
LabelLineIDS = {}
Labels = {}
Labelamount = 1;
function handleLabel(name,currentLine)
LabelLineIDS[Labelamount]=currentline
Labels[Labelamount]=name
Labelamount=Labelamount+1
end
-- In file "jump.lua":
local function has_value (tab, val)
for index, value in ipairs(tab) do
if value == val then
return index
end
end
print ("Error: Label not defined.") -- Bail out.
os.exit(1)
end
local function _onlabel()
local labelName = globalparams --Globalparams variable contain parameters to each function, at the moment
--this will contain label name. It _can_ be nil.
return LabelLineIDS[has_value(Labels, labelName)]
end
CurrLine = _onlabel() --Currline - current line that get's parsed.
--1 command per one line.
But I'm unsure is this well written or even work. Can you give me idea how to parse labels in my programming language (and write jump functions)? Or if my code is pretty ok at the moment, can you help me to improve it?
Using line counter in my parser I've decided to implement gotos like we can see in BASIC. Thanks everyone for help.
I have a Map in Dart (originally loaded from JSON) that looks something like this:
somevar = {
'Title': 'Some object',
'items': [{'title': 'Item 1 Title'}, {'title': 'Item 2 Title'}]
}
For some reason somevar['items'] doesn't behave quite like a list.
I get Exception: NoSuchMethodError : method not found: 'iterator' if I attempt to iterate over the list.
I also get a similar error if I try somevar['items'].length
If I manually load this "list" like this: someList = new List(somevar['items']); then it works as expected.
Any idea why this is that case, and what I'm doing wrong? For me the natural expectation would be that a "list" parsed from JSON will behave exactly like the List() object.
Never mind, seems that I had a deeper issue in my code that cause my somevar variable to be null (even though it should have the map.
Anyway, I'm marking this as solved for now so not to waste anyone's time.