Quantcast

Jump to content

» «
Photo

MoonLoader — Development

23 replies to this topic
BH Team
  • BH Team

    FYP

  • Members
  • Joined: 08 Aug 2011
  • Russia

#1

Posted 02 July 2017 - 07:28 PM Edited by BH Team, 12 August 2017 - 05:04 PM.

Disclaimer: The text may contain mistakes because English is not my native language, and I'd be very grateful if someone sent me a PM to help me correct some of these mistakes.
 

moonloader.png

Development Guide

 
 
 
I highly recommend reading this topic before, if you don't familiar with MoonLoader yet.
Note: All links to the official MoonLoader wiki pages are translated via Google Translate.

THE BASICS
First of all, you need to have basic programming skills and some Lua language knowledge. If you are already familiar with programming, but don't know Lua, you can start from "Learn Lua in 15 Minutes" and official documentation.
In the case if you have no experience in programming at all, you may want to start with any book or online course of your choice, I personally can't recommend anything in this case, but any material recommended by the Lua community should be good enough.
This article is better for understanding if you already know Lua, but anyway it won't hurt even if you don't.

THE STANDARDS
Before we start talking directly about scripting, first we need to talk about standards. MoonLoader like any other good framework has its own standards that makes development more specific and efficient. So the standard is one of the things that you would like to know about development for MoonLoader.

Global Symbols
Global variables
All functions including opcodes
All events
If you are already familiar with SCM (CLEO), these lists can also be useful:
Functions based on opcodes that have difference from original opcodes
Removed opcodes that have alternatives
Missing opcodes that have no purpose in Lua

Directory Hierarchy
These directories are located in the game's root directory.
  • 'moonloader' - The main directory. It contains .lua and .luac scripts, the log file 'moonloader.log' and other subdirectories related to Lua scripts
  • 'moonloader\lib' - for libraries and modules
  • 'moonloader\config' - for configs of any kind, including configs in the form of Lua scripts
  • 'moonloader\resource' - for all the resources used by scripts (textures, models, etc)
  • 'moonloader\resource\txd' - .txd files loads from this directory using 'loadTextureDictionary' script function
Libraries
MoonLoader distro includes several lua libraries to help making some common tasks easier and standardized.
  • 'moonloader' - things related to MoonLoader
  • 'vkeys' - virtual keyboard key identifiers with helpful functions
  • 'bitex' - the standard module 'bit' extension
  • 'vector3d' - 3D vector class
  • 'matrix3x3' - 3D rotation matrix class
  • 'sampfuncs' - SAMPFUNCS plugin constants
  • 'game.models' - common game model identifiers (weapons, vehicles, skins, etc)
  • 'game.globals' - global SCM variables list
  • 'game.keys' - game control key identifiers
  • 'game.weapons' - weapon names and identifiers
Script Directives
Directives are functions that specifies various script properties. Every directive value of any script can be obtained via LuaScript object.
Directives must be set once in the global script scope, usually at the very beginning of the script. Though, using them is not necessary, but desirable.
  • script_name(string name) - specifies script name
  • script_author(string author) - specifies script author
  • script_authors(string author, …) - specifies multiple script authors
  • script_description(string description) - specifies description
  • script_version(string version) - specifies script version string
  • script_version_number(int version) - specifies script version number (eg, release number)
  • script_url(string url) - specifies script URL (can be not only a direct download link)
  • script_dependencies(string name, …) - specifies script external dependencies (eg, 'SA:MP', 'CLEO')
  • script_moonloader(int version) - specifies minimum required version of MoonLoader. Doesn't cause the script to terminate if the version doesn't match, but prints an error into the log
  • script_properties(string property, …) - specifies script properties that affect its execution
Code Style
All MoonLoader's global variables and constants are named in the UPPERCASE, all built-in functions and events are named in the lowerCamelCase, every event name starts with prefix 'on', types (classes) named in CamelCase, and built-in modules in lowercase (lua_thread is an exception). So, if you don't know what naming style you wish to use, the snake_case style might be your choice.

HELLO, WORLD!
print("Hello, World!")
That's how the "Hello world" would look like in regular Lua.
In MoonLoader global script area is not intended for main script code. Instead, all main code must be inside the 'main' function.
So "Hello world" should look like this:
-- will print out string "Hello, World!" and script will be terminated
function main()
  print("Hello, World!")
end
But... Why?
Global script area is intended for defining script information, loading libraries and configs. All code within the global area executes right after script loads, but the 'main' function calls when the game gets loaded.
Function 'main' can be suspended for certain time interval using function 'wait' with value in milliseconds. Delay in script won't pause the whole game, only the delayed script thread will be paused.
And you can use infinite loops inside 'main' to implement actively-working script, here is an example:
-- specify script information
script_name("Restore health")
script_author("noname_noob")
-- load virtual key list
local vk = require "lib.vkeys"

function main()
  while true do -- infinite loop
    wait(0) -- delay is necessary in infinite loop, even zero
    if wasKeyPressed(vk.VK_1) and isPlayerPlaying(PLAYER_HANDLE) then -- if key '1' was pressed and player is available
      setCharHealth(PLAYER_PED, 100) -- set 100 health points to the player's character
    end
  end
end
The 'wait' delay may be used only inside the 'main' function (of course in nested calls too) and scripting threads. Delays can be used in any way, not only inside loops.
Script stops execution and completely unloads when exiting the 'main' function.
Next example shows how you can use sequence of delays and then stop script:
local vk = require "lib.vkeys"

function main()
  while true do
    wait(0)
    if wasKeyPressed(vk.VK_1) and isPlayerPlaying(PLAYER_HANDLE) then
      print('Restoring health... Please, wait.')
      wait(500)
      setCharHealth(PLAYER_PED, 100)
      print('Restore health: done.')
      print('Restoring armor...')
      wait(500)
      setCharHealth(PLAYER_PED, 100)
      print('Restore armor: done.')
      print('Terminating...')
      return -- exit from 'main'. Script will be stopped and unloaded
    end
  end
end
Events
Broadly speaking, events are functions that performed by themselves when some action happens. For example, when user starts a new game or new script gets loaded.
This example uses event 'onScriptMessage' to intercept 'print' messages from all scripts:
-- calls when any script prints out message with function 'print'
function onScriptMessage(msg, script)
  -- it is advisable to check that game is loaded
  if isPlayerPlaying(PLAYER_HANDLE) then
    printStringNow(script.name .. ": " .. msg, 2000) -- display message
  end
end
Script won't stop automatically if it has some events and doesn't have the 'main' function. But if you have both in your script and your function 'main' doesn't have infinite loop, you can use 'wait(-1)' to prevent script from automatical termination.
Also, delays cannot be used inside events, but you can use scripting threads to get over it.
In this way you can use delays inside events and prevent script termination using 'wait(-1)':
function onScriptMessage(msg, script)
  -- run a new scripting thread, passing message and script name
  lua_thread.create(process_script_message, msg, script.name) -- function 'process_script_message' will be called instantly in this line
  -- and will run until delay, then execution will be passed back to the event
  -- but the thread will continue to get processed and will continue exististence until it is exited
end

function process_script_message(msg, name)
  printStringNow(name, 1000)
  wait(1000)
  printStringNow(msg, 'Message:~n~' .. msg)
  -- function exits out = the thread is destroyed
end

function main()
  if getMoonloaderVersion() < 21 then return end
  -- if script is no longer performs any actions, but needs to handle events
  -- you can get over it in that way
  wait(-1) -- infinite delay will prevent script from automatically unloading
end
You can learn more about scripting threads on wiki.

Theoretically, this information is enough to start developing Lua-scripts for MoonLoader. Things described here is just a basic guide to get started, MoonLoader has a lot more concepts which you have to learn yourself.
I highly recommend install scripts "ML AutoReload" and "ML ReloadAll", they are very helpful in development, you might also want to install "SF Integration" and "ScriptManager" if you have SAMPFUNCS installed, they are very useful too.

SCRIPT COMPILATION
Lua scripts don't require compilation and it is better to keep scripts open source, but if you need, you can compile them using LuaJIT interpreter.
Download this archive and extract it anywhere, then just drag and drop your .lua script file onto compile.bat, the compiled script with extension .luac will appear next to original file. MoonLoader loads the .luac files in the same way as normal .lua.

IDE
Atom was selected as an official IDE for MoonLoader, Notepad++ is also supported officially, but has less functionality. The best option is to choose one of these source code editors for effective development, but you can use any text editor that you like.

Atom:
Extension for Atom includes Lua syntax highlighting, smart autocompletion, real-time error checking. There is also fuzzy search for functions and opcodes - activated with hotkey Ctrl+Alt+A, to find function by opcode add prefix '@' before search query.
Installation:
Note: if you already have package 'language-lua' or 'linter-lua' installed in your Atom, disable or remove it to avoid conflicts.
1. Install and run Atom
2. Go to the settings window (menu File -> Settings or hotkey Ctr + ,)
3. Go to the "Install" tab
4. Enter "moonloader" in the search box and install first module from the results list
Note: if an error occurred during autoinstallation of "autocomplete-lua" just install it yourself by the same method.
1U5YKAtt.png ujghizst.png Af0Hyxyt.png VqQTP4Ut.png 6u0qCiMt.png

Notepad++:
Extension for Notepad++ has less functionality - it's includes basic autocompletion suggestions, additional keywords highlighting and tooltips for functions.
1. Install Notepad++ and run it at least once
2. Download the MoonLoader installer, run and install it with selected "Notepad++ extension" checkbox
3. Open Notepad++ and select the Lua language (menu Language -> L -> Lua)
lt22Uq1t.png iYsu2n1t.png

LINKS
Main Topic
MoonLoader Wiki Pages
Download Script Examples
  • Wesser, Blackbird88, Apu889 and 9 others like this

Blue
  • Blue

    Blue Bloods' Guitarist

  • Facade Corporation
  • Joined: 09 Apr 2014
  • Portugal
  • Best Total Overhaul 2016 [Shine o' Vice] [Contribution]
    Best Workshop 2016 [Runner-up]

#2

Posted 02 July 2017 - 08:11 PM

You sir are a God.
  • deltaCJ likes this

Delatom
  • Delatom

    I enjoy Gaming & Nature, seeking for some insperation.

  • Members
  • Joined: 01 Aug 2017
  • None

#3

Posted 11 August 2017 - 11:04 AM

Helpful


Crspy
  • Crspy

    Kick

  • Members
  • Joined: 14 May 2015
  • None

#4

Posted 12 August 2017 - 07:41 PM

there's a little problem with atom , everything was installed just fine except this :

 

vePDPlQ.png

 

i am running atom as administrator anyway.


BH Team
  • BH Team

    FYP

  • Members
  • Joined: 08 Aug 2011
  • Russia

#5

Posted 13 August 2017 - 12:22 PM

Yes, this problem has been reported but devs haven't fixed it yet. Just install autocomplete-lua separately via Settings -> Install.

  • Crspy likes this

Crspy
  • Crspy

    Kick

  • Members
  • Joined: 14 May 2015
  • None

#6

Posted 14 August 2017 - 02:30 AM Edited by Crspy, 14 August 2017 - 09:50 AM.

It worked thanks. i like how the syntax is almost similar to C++  without the complexity.

 

I have a question though , is declaring my own functions and using them in the main function when i want is possible ?  something like this for example :  

function myrequest( models, address)
requestModel(models)
while not hasModelLoaded(models) do
	wait(0)
end
writeMemory(address, 4, models, false)
return
end

function main()
local random
local model
random = 0
while true do
	wait(100)
	if isPlayerPlaying(PLAYER_HANDLE) then
		if isCharInZone(PLAYER_PED, "SF") then
			printHelpString("player is in SF")
			math.randomseed(random)
			random = math.random(0,5)
			if random == 0 then model = 281
			elseif random == 1 then model = 340
			elseif random == 2 then model = 668
			elseif random == 3 then model = 699
			else model = 86
			end
	    myrequest(model,0x8A5AA8)
		end
	end
end
end

PS : indentation gets messy when the code is copy-pasted. :3


BH Team
  • BH Team

    FYP

  • Members
  • Joined: 08 Aug 2011
  • Russia

#7

Posted 14 August 2017 - 10:37 AM

Yes, you can do everything with functions that you want. There is no limitations to any Lua possibilities.

  • Crspy likes this

BigHomie
  • BigHomie

    Rat

  • Members
  • Joined: 03 May 2016
  • Germany

#8

Posted 15 August 2017 - 10:25 AM

As I understand, thread saving isn't available, but would there be some way to save the script's status?

BH Team
  • BH Team

    FYP

  • Members
  • Joined: 08 Aug 2011
  • Russia

#9

Posted 15 August 2017 - 02:07 PM Edited by BH Team, 15 August 2017 - 04:32 PM.

There is embedded savegame system built on events, if you need it for saving mission progress or something like that, that should be enough. For configs you can use built-in module 'inicfg', for other purposes there are functions encodeJson and decodeJson, and also serialization libraries by community.

  • Crspy likes this

Crspy
  • Crspy

    Kick

  • Members
  • Joined: 14 May 2015
  • None

#10

Posted 25 August 2017 - 02:11 PM Edited by Crspy, 25 August 2017 - 02:14 PM.

i don't know if that's a bug or not  but writing to memory addresses seems not working correctly

writeMemory(0x00457485, 3, 0x000090, 0)   -- object->__parent.physical.entity.placeable.m_pCoords->pos.z;      

^ this crashes the game while in cleo it works fine :

 

0A8C: write_memory 0x00457485 size 3 value 0x000090 virtual_protect 0


Jack
  • Jack

    Wanted Level Modifications

  • Feroci
  • Joined: 06 Dec 2011
  • Serbia

#11

Posted 25 August 2017 - 03:17 PM

i don't know if that's a bug or not  but writing to memory addresses seems not working correctly

writeMemory(0x00457485, 3, 0x000090, 0)   -- object->__parent.physical.entity.placeable.m_pCoords->pos.z;      

^ this crashes the game while in cleo it works fine :

 

0A8C: write_memory 0x00457485 size 3 value 0x000090 virtual_protect 0

Wrong size mate. It can not be 3. We have byte, word, dword...

Example with the default value:
- lua:

writeMemory(0x00457485, 2, 0x4289, 0)
writeMemory(0x00457487, 1, 0x38, 0)

- scm:
0A8C: write_memory 0x457485 size 2 value 0x4289 virtual_protect 0 //  [word]
0A8C: write_memory 0x457487 size 1 value 0x38 virtual_protect 0 //  [byte]

Crspy
  • Crspy

    Kick

  • Members
  • Joined: 14 May 2015
  • None

#12

Posted 26 August 2017 - 12:32 AM Edited by Crspy, 26 August 2017 - 12:47 AM.

 

i don't know if that's a bug or not  but writing to memory addresses seems not working correctly

writeMemory(0x00457485, 3, 0x000090, 0)   -- object->__parent.physical.entity.placeable.m_pCoords->pos.z;      

^ this crashes the game while in cleo it works fine :

 

0A8C: write_memory 0x00457485 size 3 value 0x000090 virtual_protect 0

Wrong size mate. It can not be 3. We have byte, word, dword...

Example with the default value:
- lua:

writeMemory(0x00457485, 2, 0x4289, 0)
writeMemory(0x00457487, 1, 0x38, 0)
- scm:
0A8C: write_memory 0x457485 size 2 value 0x4289 virtual_protect 0 //  [word]
0A8C: write_memory 0x457487 size 1 value 0x38 virtual_protect 0 //  [byte]

i know , i actually copied the line while testing multiple things on the same line to see how moonloader would react to it , it should have terminated the script but instead ... it let the script running and crash the game.

 

However, no matter what i do ,  nopping that part still crash the game while in cleo it works fine.


Veryzon
  • Veryzon

    Player Hater

  • Members
  • Joined: 15 Jun 2017
  • Brazil

#13

Posted 26 August 2017 - 02:02 AM Edited by Veryzon, 26 August 2017 - 09:27 PM.

CLEO's ReadMemory and WriteMemory opcodes can only access one, two or four bytes per time. To access any data type that's not according to these sizes, it should be accessed partionately. If you push 3 bytes to a read or written operation, probably CLEO will nopping the address then i would recommend you test wether the value has been read/written correctly.

 

Theory based on source code of CLEO 4.1/2.


BH Team
  • BH Team

    FYP

  • Members
  • Joined: 08 Aug 2011
  • Russia

#14

Posted 26 August 2017 - 01:56 PM Edited by BH Team, 26 August 2017 - 05:50 PM.

i don't know if that's a bug or not  but writing to memory addresses seems not working correctly

writeMemory(0x00457485, 3, 0x000090, 0)   -- object->__parent.physical.entity.placeable.m_pCoords->pos.z;      

^ this crashes the game while in cleo it works fine :
 
0A8C: write_memory 0x00457485 size 3 value 0x000090 virtual_protect 0

You write not 3 NOPs, you do write "nop 00 00", so that's why this causes crash. CLEO doesn't crash because it just ignores any size that isn't 1, 2 or 4 - https://github.com/c...System.cpp#L853
MoonLoader's writeMemory function doesn't ignore size 3, but will shrink the size value to 4 if it is bigger than 4.
 

i know , i actually copied the line while testing multiple things on the same line to see how moonloader would react to it , it should have terminated the script but instead ... it let the script running and crash the game. 
However, no matter what i do ,  nopping that part still crash the game while in cleo it works fine.

Nope. Your script does its job well - it writes to the memory what do you said to it and then passes workflow back to the game, then game reaches this code point and since you wrote incorrect values it's just crashes. This cannot be handled by MoonLoader because it is not script crashes the game, the game crashes itself because of memory corruption.
I even tested it with code writeMemory(0x00457485, 3, 0x909090, true) and it works fine.
 
Also you passes zero as 4-rd parameter, but argument type is boolean, so you need to pass false instead of 0 (I don't recommend doing that while you writing to the code memory). And also take a look at the built-in module "memory", it has some functions like memory.fill that is very useful for nopping code memory:
local memory = require 'memory'

function main()
  memory.fill(0x00457485, 0x90, 3, true)
end
  • Crspy likes this

Crspy
  • Crspy

    Kick

  • Members
  • Joined: 14 May 2015
  • None

#15

Posted 26 August 2017 - 05:33 PM

 

 Nope. Your script does its job well - it writes to the memory what do you said to it and then passes workflow back to the game, then game reaches this code point and since you wrote incorrect values it's just crashes. This cannot be handled by MoonLoader because it is not script crashes the game, the game crashes itself because of memory corruption.
I even tested it with code writeMemory(0x00457485, 3, 0x909090, true) and it works fine.
 
Also you passes zero as 4-rd parameter, but argument type is boolean, so you need to pass false instead of 0 (I don't recommend doing that while you writing to the code memory). And also take a look at the built-in module "memory", it has some functions like memory.fill that is very useful for nopping code memory:
local memory = require 'memory'

function main()
  memory.fill(0x00457485, 3, 0x90, true)
end

that's exactly what i wanted to know , thanks a lot :)


BH Team
  • BH Team

    FYP

  • Members
  • Joined: 08 Aug 2011
  • Russia

#16

Posted 28 August 2017 - 11:00 AM

@Crspy Sorry, I was incorrect about that CLEO's write_memory ignores all sizes that is not 1, 2 or 4. Actually CLEO doesn't ignore it, but it fills memory at address with single-byte value if size is not 1, 2 or 4.

so 0A8C: write_memory 0x1234567 size 9 value 0x90 virtual_protect 1 will write nine NOPs, but 0A8C: write_memory 0x1234567 size 4 value 0x90 virtual_protect 1 will write nop, 0x00, 0x00, 0x00.

I personally find it as a very bad solution because it is very unspecific.


jayd00
  • jayd00

    Rat

  • Members
  • Joined: 24 May 2008

#17

Posted 3 weeks ago

anyone can help me please;

bee511606328273.jpg

 

each time I open the Atom, it appear the "autocomplete-lua versión 0.8.2" it appear that error:

 

"Failed to install autocomplete-lua because Git was not found.
The autocomplete-lua package has module dependencies that cannot be installed without Git.
You need to install Git and add it to your path environment variable in order to install this package.
You can install Git by downloading, installing, and launching GitHub for Windows: https://windows.github.com
Run apm -v after installing Git to see what version has been detected."

 

​I already did everything as posible :S check the image, but still without working :/


BH Team
  • BH Team

    FYP

  • Members
  • Joined: 08 Aug 2011
  • Russia

#18

Posted 3 weeks ago Edited by BH Team, 3 weeks ago.

@jayd00

author of autocomplete-lua already know about this problem but haven't fixed it yet. currently to fix this you can install Git from here: https://git-scm.com/download/win

  • jayd00 likes this

janglapuk
  • janglapuk

    Player Hater

  • Members
  • Joined: 3 weeks ago
  • Indonesia

#19

Posted 3 weeks ago Edited by janglapuk, 3 weeks ago.

Hi,
 
This is very promised plugin for replacing the famous one.  :lol:
 
I didn't see any functions in related with map marker position, which in CLEO we can use 0AB6 opcode:

0AB6: store_target_marker_coords_to [email protected] [email protected] [email protected]

Are there some functions that I can use to achieve it?

 
---
 
Update:
After writing my own function based DK22Pac's plugin-sdk structs and CLEO4 source code:
 

function getTargetMarkerCoords()
    local frontEndMenuManager = ffi.cast('struct CMenuManager *', 0xBA6748)
    local radarTrace = ffi.cast('struct tRadarTrace *', 0xBA86F0)
 
    local blipIndex = bit.band(frontEndMenuManager.m_nTargetBlipIndex, 0xFFFF)
    local marker = radarTrace[blipIndex]
 
    local x, y, z = marker.m_fPositionX, marker.m_fPositionY, marker.m_fPositionZ
    local groundZ = getGroundZFor3dCoord(x, y, 9999.0)
 
    return x, y, groundZ
end
 
ffi.cdef([[
struct CMenuManager
{
    __int8 field_0;
    __int8 field_1[3];
    float               m_fStatsScrollSpeed;
    __int8 field_8;
    __int8 field_9[23];
    __int8 field_20;
    bool                m_bHudOn;
    __int8 field_22[2];
    __int32             m_dwRadarMode;
    __int8 field_28[4];
    __int32             m_nTargetBlipIndex;
} __attribute__ ((aligned (4)));
 
struct tRadarTrace
{
    unsigned int   m_dwColour;
    unsigned int   m_dwEntityHandle;
    float          m_fPositionX;
    float          m_fPositionY;
    float          m_fPositionZ;
    unsigned short m_nCounter;
    float          m_fSphereRadius;
    unsigned short m_nBlipSize;
    unsigned int *m_pEntryExit;
    unsigned char  m_nBlipSprite;
    unsigned char  m_bBright : 1;
    unsigned char  m_bTrackingBlip : 1;
    unsigned char  m_bShortRange : 1;
    unsigned char  m_bFriendly : 1;
    unsigned char  m_bBlipRemain : 1;
    unsigned char  m_bBlipFade : 1;
    unsigned char  m_nCoordBlipAppearance : 2;
    unsigned char  m_nBlipDisplayFlag : 2;
    unsigned char  m_nBlipType : 4;
} __attribute__ ((aligned (4)));
]])

and suddenly my IDE shows me autocomplete function with name getTargetBlipCoordinates()! Hell!  :miranda:


BH Team
  • BH Team

    FYP

  • Members
  • Joined: 08 Aug 2011
  • Russia

#20

Posted 3 weeks ago Edited by BH Team, 3 weeks ago.

:D yes, moonloader has this function. For the future, if you can't find something first of all check this page, there is lists with explanations of all opcodes that were removed


janglapuk
  • janglapuk

    Player Hater

  • Members
  • Joined: 3 weeks ago
  • Indonesia

#21

Posted 3 weeks ago Edited by janglapuk, 3 weeks ago.

Any updates for SA:MP 0.3.7-R2?

Its crashes (freeze) after using some samp* functions.

 

Edit:

I think crashes related with sampfuncs library, I hope it will be fixed soon.  :sigh:


BH Team
  • BH Team

    FYP

  • Members
  • Joined: 08 Aug 2011
  • Russia

#22

Posted 2 weeks ago Edited by BH Team, 2 weeks ago.

crash is related with sampfuncs, sampfuncs is not compatible with R2, and it won't be. so downgrade your samp client.


jayd00
  • jayd00

    Rat

  • Members
  • Joined: 24 May 2008

#23

Posted 2 weeks ago

someone can help me? I think, I still don't get how local && global variables work in LUA, probably this is noob question but I'm tired of searching answers and I can't figured why my script don't work as I expected...
Is a simple code; I write this one in cleo;

{$CLEO}
0000:
while true
const
    mTurismo    = #TURISMO
    mLocalCarVar   = [email protected]
end
if  0AB0:   key_pressed 0x50   // vk_P
then
    if 056E:   car mLocalCarVar defined
    then
        0ACA: show_text_box "destroying Car"
        00A6: destroy_car mLocalCarVar
        wait 100
    else
        gosub @loadModel   
        wait 100
        const
            LocalPosnX = [email protected]
            LocalPosnY = [email protected]
            LocalPosnZ = [email protected]
        end
        04C4: store_coords_to LocalPosnX LocalPosnY LocalPosnZ from_actor $PLAYER_ACTOR with_offset 0.0 4.0 1.0
        00A5: mLocalCarVar = create_car mTurismo at LocalPosnX LocalPosnY LocalPosnZ
        0ACA: show_text_box "Car created"
        wait 100
        0249: release_model mTurismo
        //01C3: remove_references_to_car mLocalCarVar
        wait 100   
    end
end
if  0AB0:   key_pressed 0x4F  // vk_O
then
    if 056E:   car mLocalCarVar defined
    then
        0ACA: show_text_box "remove references Car..."
        01C3: remove_references_to_car mLocalCarVar
        wait 100
    else
        0ACA: show_text_box "Car does not exist anymore..."
        wait 100
    end
end
 wait 0
end
     
:loadModel
0247: load_model mTurismo
while 8248:  not model mTurismo available
    wait 0
end
return

 works fine...
but when I try to use LUA;
 

 function main()
 local varCar
 local modelIdNumber = modelsID.TURISMO

 while true do
  if isPlayerPlaying(playerHandle) and isCharOnFoot(playerPed)
  then
   if isKeyDown(vk.VK_P)
   then
    if doesVehicleExist(varCar)
    then
     printHelpString("destroying Car...")
     deleteCar(varCar)
     wait(100)
    else
     myModelRequest(modelIdNumber)
     wait(100)
     local posnX, posnY, posnZ = getOffsetFromCharInWorldCoords(playerPed, 0.0, 4.0, 0.0)
     varCar = createCar(modelIdNumber, posnX, posnY, posnZ)
     local Zangle1 = getCharHeading(playerPed)
     setCarHeading(varCar, Zangle1)
     printHelpString("Car Created")
     wait(100)
     markModelAsNoLongerNeeded(modelIdNumber)
     --markCarAsNoLongerNeeded(varCar)
     wait(100)
    end
   end
   if isKeyDown(vk.VK_O)
   then
    if doesVehicleExist(varCar)
    then
     printHelpString("remove references Car...")
     markCarAsNoLongerNeeded(varCar)
     wait(100)
    else
     printHelpString("Car does not exist anymore...")
     wait(100)
    end
   end
  end
  wait(0)
 end
end
--[[Tesnting Functions]]--
function myModelRequest (modelIdNumber)
 requestModel(modelIdNumber)
 while not hasModelLoaded(modelIdNumber) do
  wait(0)
 end
 return
end

I got a problem with the Local Var of the Car, when I press the key "O" it seems that don't remove references as expected... this mean variable is global? or why?

can someone teach me a little bit about this?  thank you! ;)
and sorry for my english :p

  • guru_guru likes this

guru_guru
  • guru_guru

    pajaro culiao

  • Members
  • Joined: 22 Jul 2017
  • Chile

#24

Posted 2 weeks ago Edited by guru_guru, 2 weeks ago.

nevermind :p





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users