specahawk

Members
  • Content count

    12
  • Joined

  • Last visited

Community Reputation

15 Decent

1 Follower

About specahawk

  • Rank
    Square
  • Birthday 12/12/95

Details

  • Gang
    TheScorpions
  1. Create my own LUA compiler

    Lua does not compile to assembly (Except JIT), and knowing assembly is not a requirement. You will have to study about compilers, which includes lexers, parsers, grammars, ASTs etc. The answers here will be very helpful to you: https://stackoverflow.com/questions/1669/learning-to-write-a-compiler Lua's syntax in extended BNF is given here: http://www.lua.org/manual/5.1/manual.html#8 (Last section on the page)
  2. Hey @Tails, thanks for using bakaGaijin! I'm glad you're using it. It gives me a very nice feeling knowing that someone is using something I made. As for the first feature request, I'll make it so you can add destroy callbacks for when the host resource of an element stops. Expect it soon. As for the bug report, I'll have to run it myself to check what's wrong exactly. If you have a github account, please consider opening both of these are issues there, as I am not very active on these forums. https://github.com/luca-spopo/bakagaijin/issues It would also be great if you can send the example scripts where the bug occurs (remove the parts that are not relevant to the bug) in case I am not able to reproduce it.
  3. [SHOW] - MTA - Discord integration API

    You may have an older (LTS) version of note. Upgrade to 7+ and try OR Just remove the "callback =" part. (If it is a function definition, then in the first line of the function add "if (callback==nil) { callback = () =:> {} }", it's a default value for the parameter)
  4. [SHOW] - MTA - Discord integration API

    I love the code, it's very nice. Much better than the hack I put together. A few things I want to ask: The split function in util splits according to the separator, but do you escape the separator (like URL encode it maybe) anywhere? If the separator can be a part of the actual message then I have some snippet I made for this project to safely escape/unescape strings which I can send a pull request for. Also, I don't understand why you have separate resources for the events and the actual API. This is a design decision ofc, but is it worth running two separate Lua VMs?
  5. I brought you bakaGaijin and Ash Now I bring Discord integration with MTA scripts. MTA already has this for IRC Shoutout to the people who made the Sockets module, you're awesome. Features: -Scripts can echo messages to any Discord text channel of their choosing. -Any Discord channel can be set up to echo all messages to an ingame script. (Including the name of the person who said it, and his role) -One MTA server can send/receive to multiple Discord guilds. Example use: To show how this is useful, I made a small program to echo all global chat to a "global" Discord channel, and all team chats to individual "team" Discord channels. These Discord channels ofc echo messages back when someone posts. As proof of concept for commands, if a Discord user types "!ban name" then his role is checked, and if it includes Founder, the chat outputs "name was banned!" This is the client side script I used for this example: local SECRET_KEY = "15-A-53CR3T-K3Y" --The script works even if your server IP changes. You are mapped to a unique key. local function onopen(self) self:send(SECRET_KEY) --Your MTA server logs in addEventHandler("onResourceStop", resourceRoot, function() self:close() --Break off from Discord end) addEventHandler("onPlayerChat", getRootElement(), function(message, type) --Example hook to capture player chats local name = getPlayerName(source) local channel = "global" --Send to global channel if global chat if type==2 then channel = getTeamName(getPlayerTeam(source)) end --Or team channel if teamchat --Format to send messages is ("discord", channelName, message) self:send("discord", channel, name..": "..message) end) end function onmessage(self, data) local channelName, name, role, message = data[3], data[4], data[5], data[6] local orginal_message = message --The message we got from discord message = "("..role..") "..name..": "..message --Make it pretty if channelName=="global" then --Output to global chat or team chat outputChatBox("(DISCORD) "..message) else local team = getTeamFromName(channelName) local members = getPlayersInTeam(team) or {} local r, g, b = getTeamColor(team) --Color the output for lulz for _, player in ipairs(members) do outputChatBox( "(DISCORD) (TEAM) "..message, player, r, g, b) end end local commandExample = string.match(orginal_message, "^!ban (.+)") --If message started with !ban... if role=="Founders" and commandExample then -- ...and the person who said it had the right Role outputChatBox(commandExample.." was banned!", getRootElement(), 255, 0, 0) end end local function onclose() outputChatBox("The Discord link was closed") end local discord = Discord.new(onopen, onmessage, onclose) That's 41 lines of code, now let's see it in effect. I would love to hear what you think about it.
  6. [WIP] Ash - UI Framework (Better than dxGUI?)

    The orange cat image is 64 pixels tall upscaled to 128 pixels, so the source image is pixely in this case. The panes, buttons etc are not pixely. They are drawn using dx functions as usual. Thanks for the reply!
  7. https://luca-spopo.github.io/ash.html Made using bakaGaijin. I am not going to type everything here again, so just click the first link on top. Some teasers: https://youtu.be/qGYF3OFbGy8 https://youtu.be/pVPMER9JTiI https://youtu.be/Hm0xIc35BfA Before you ask: No, this does not use Javascript or CEF. It is a pure Lua implementation.
  8. Yes! I plan to add "read only mode" later if you don't want that behavior, but the right now it lets you. Thanks! The GitHub link is in there, I'll put it at the bottom where it's more visible.
  9. Hello community. This is my first decent post on the forums, so bear with me. Currently, if you want two resources to share some data, or call some functions from each other, there are two methods: -You could use exports to call functions in another resource. Such a function needs to be global, defined statically in meta.xml, and called using exports. In such a function call, only certain datatypes are transferred. Functions, etc are lost. Any tables transferred are passed by value not reference (You get a copy, so any changes you make do not change the actual table) and any information about metatables is lost. -You could use elements. Information can be shared and set using setElementData, and functions can be called by making the functions event handlers, and using triggerEvent instead of function calls. Again, function objects cannot be passed, tables are passed by value, and metatables are not applied. The syntax for these is also terrible and inconvenient. I bring to you, bakaGaijin. The one stop solution for all your inter resource communications. -Now, letting another resource use your function is as easy as: --This is the first resource, called "Resource1" bakaGaijin.SomeFunction = function() outputChatBox("Hello world") end --This is the second resource, called "Resource2" bakaGaijin("Resource1").SomeFunction() --Resource1 will output "Hello World" No need to edit the meta.xml file for every time you wish to export some thing. The sharing is done at runtime! The syntax to "export" something is: bakaGaijin.EXPORTED_NAME = SOME_VALUE SOME_VALUE can be anything, not just a function. So you can even expose your tables to other resources. Or constant literals, anything you want. --This is the first resource, called "Resource1" bakaGaijin.SomeTable = {1, 2, 3} --This is the second resource, called "Resource2" local table = bakaGaijin("Resource1").SomeTable for i, v in ipairs( table ) do outputChatBox(v) table[i] = 0 end Tables are passed BY REFERENCE. So any changes you make to the table are actually reflected on the one in the other resource. This means that after Resource2 has run, the table that was in Resource1 will have 0 for all it's values. (This assumes Resource2 was started after Resource1, for the table to exist first) Functions are not lost, and are transferred safely. So they can be used as parameters for other functions, can be returned by a function, stored in a table etc. Tables do not lose any values. Tables with functions in them (key or value) transfer while preserving the functions. Metatables are also not lost. Any __newindex or __index metamethods you set on a table will be active even when it is passed to another resource. (Caveat: Only the host resource that originally created the table can set it's metatable properly. I'll fix this in later versions of the resource) On top of that, it's fast. I've optimized it so that you will never even feel that you're working with different virtual machines at the same time. To use bakaGaijin, all you need to do is: 1) Export a function called "bakaGaijin_export" in your meta.xml file for the resource that wants to use bakaGaijin. 2) Make sure you download and start bakaGaijin before the resources that will use it. You can download bakaGaijin from https://github.com/Luca-spopo/bakaGaijin (If you're a developer, then folk the repo to show your appreciation! Contributions are welcome, just send me a pull request) 3) Append this line to your program: loadstring(exports["bakaGaijin"]:use())() OR add bakaGaijin.lua (provided in the folder bakaGaijin) to your meta.xml file as a script. (Before all other scripts) This: element = createElement() setElementData(element, "x", 200.001) --Used to give floating point errors at some point setElementData(element, "y", 100) --Also, the field names must be strings AFAIK exports["SomeResource"]:sendElementToMe(element) --The colon notation changes the signature of the function turns into this: local table = {x=200.001, y=100, 1, 2, 3, 4, = table} --Indices dont have to be strings, and recursion is allowed bakaGaijin("SomeResource").sendElementToMe(table) This also means that you can make and use Lua classes across resources. No need to include files made by other people into each one of your resource. So something like 50p's GUI classes https://forum.mtasa.com/viewtopic.php?f=108&t=24122&hilit=class can become an actual part of DxLib. (In fact, my current project is to use bakaGaijin to make my own dxGUI library) You can do some really cool shiz with bakaGaijin. Remember, the objects that you are exposing using bakaGaijin.blabla are only the "named" objects. Any objects belonging to the closure or a table in blabla are also accessible. Moreover, bakaGaijin.blabla itself is an object, and can be used as such. You can use it as a parameter if you want. Something like this is totally valid: --Resource1 loadstring(exports["bakaGaijin"]:use())() bakaGaijin.fun1 = function(a, b, c) bakaGaijin("Resource2").checkA(a) b.i = true bakaGaijin("Resouce2").checkB() assert(c==bakaGaijin.fun1) end --Resource2 loadstring(exports["bakaGaijin"]:use())() local a = function() end local b = {i = false} local c = bakaGaijin("Resource1").fun1 --Assuming Resource1 started first. bakaGaijin.checkA = function(par) local keyTest = {} keyTest[a] = false keyTest[par] = true assert(keyTest[a]) --True end function bakaGaijin.checkB(par) --This syntax also works, and is super cute. assert(b.i) --Resource1 set it to true, so it's true end c(a, b, c) --Calls the function in Resource1 Note that the length operator (#) does not work on exported tables, and I cannot make it work unless MTA upgrades to Lua 5.2 bakaGaijin provides a global function called len that should be used instead. len(table) will give the length of a table properly, even if it is an "exported" table. A word of caution: bakaGaijin has it's own garbage collector on top of Lua's garbage collector. Any object that goes from one resource to another is monitored for usage, and deleted when unused. So try to not load the garbage collector too much and dont use gaijin objects for things that will happen very often. In case you are wondering about the name, bakaGaijin means "Stupid Foreigner". The objects that are being sent to other resources are foreigners. Yes I know it's lame. I have included two resources called bakaGaijinTest1 and bakaGaijinTest2 on the github repo, run these alongside bakaGaijin and then type "/bakaTest" to see that everything works. You can open driver.lua and driver2.lua in these resources to see examples of how to do stuff, and to go through it's features. Have fun! Leave a reply if you like it. Or help me build the documentation or wiki or whatever. Link to source code: https://github.com/Luca-spopo/bakaGaijin
  10. [WIP]Custom shooting system

    Of couse. But i have some troubles with setting weapons fire rate... I just don't see any way to sync the visible shots and bullets with virtual one's. Any ideas? My idea could be absolutely terrible since I am new to this, but maybe don't let the "visible" shots fire at all, and make some particle effect follow the virtual shot?
  11. This is a question regarding the resource "editor", particularly importing definitions I have a custom element that consists of two markers. One cylinder and one arrow. I want the height of the arrow to depend on a "number" type property of the element called "length" (I want to denote a vertical line segment in the editor) posZ works as long as it is not property dependent. So this works: "Ship meshes"> "fronthitv" friendlyname="Front hit vertical line" instructions="-"> "position" type="coord3d" default="0,0,0" /> "length" type="number" default="10" /> type="cylinder" color="#0000ff" /> type="arrow" posZ="3" color="#0000ff" /> I cannot get "position" work, regardless of whether or not it is property dependent. "Ship meshes"> "fronthitv" friendlyname="Front hit vertical line" instructions="-"> "position" type="coord3d" default="0,0,0" /> "length" type="number" default="10" /> type="cylinder" color="#0000ff" /> type="arrow" position="0,0,3" color="#0000ff" /> The code above does not change the position of the arrow at all. It is still coinciding with the cylinder. What I want is something like this, but this doesn't work: "Ship meshes"> "fronthitv" friendlyname="Front hit vertical line" instructions="-"> "position" type="coord3d" default="0,0,0" /> "length" type="number" default="10" /> type="cylinder" color="#0000ff" /> type="arrow" posZ="!length!" color="#0000ff" /> The code above throws a bunch of errors. I tried opening the source code of the editor (and it was beautifully written). Apparantly posX, posY and posZ are converted to a table called "position" before they are processed further. I lightly searched the forums for any similar questions, but didn't find any. How should I go about solving (or circumventing) this problem? Please help me
  12. [WIP] Mass Map Mover with Rotation

    I tried finding a Map Mover that allows mass rotation about a given point, but couldn't find anything like that, so I decided to try making it myself. It currently only supports objects. I forgot about stuff like vehicles and markers and all those other things people can have in their maps D: I made it today, and I'm tired now, and I may or may not work on it again. Feel free to use it though. You can even download it and run it from your desktop while offline. CLICK (Right click, save link as) Or, if that doesn't work CLICK Made in Haxe, implemented using flash player.