Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Topics - habi
Tutorials / How to detect client side script error. ?
« on November 24th, 12:58 PM »
Just for the record, this is posted. In case someone in future needs this.

I had a client side script main.nut which was not working. Client side scripts not show errors in game.

If there is an error, download this program     sq.exe


Note: You need to copy this sq.exe to your main.nut folder
Bugs and Crashes / [Bug] Streams can be send without any target player
« on November 23rd, 07:22 AM »
The Stream class is not throwing error when its function SendStream is called with a null player.


What you were doing when the bug happened
I had a piece of code to send data streams to player and obtain report from them. I restarted server and when the function was called from Server console with FindPlayer function as one of the arguments, nothing happened. Then i understood that no player was connected. So this class is not throwing error.

What you think caused the bug
Stream class not checking inside, if player is not null
Bugs and Crashes / [Bug] Client side PlayerShoot function wrong values
« on November 18th, 08:24 AM »
In first person shoot with Ruger, the hitPosition given by the function mentioned in subject, is found to be inaccurate.


What you were doing when the bug happened
I was shooting player at head to get the co-ordinates of the body part. In third-person aiming, the values are satisfying with player's co-ordinates.
It is suspected that the hitPosition calculated by the client is as if the bullet is passed through the player and the bullet is hit on the wall behind and it is giving position of the wall.

What you think caused the bug
bug caused the bug.

Client side PlayerShoot event is not getting called with sniper rifle if the player is not local.


What you were doing when the bug happened
My client side script has a code to print something on Console if somebody shoots somebody making use of the Player::PlayerShoot function. On working with npcs, i found that the function is not getting called if weapon is sniper rifle.

Later i confirmed it by opening two game windows and making one player shoot another. It showed output only on one window where it was supposed to perform on both windows. At the same time, if the weapon is 27 (Ruger), outputs are shown in both windows.

What you think caused the bug
Client side PlayerShoot was not getting called for sniper rifles and shotguns for any players earlier. So the problem might be related to this previous issue.
Do anybody know how exactly aimdirection is calculated?
I have tried for two days:
Code: [Select]
function GetAimDir(aimPos, targetPos)
local x,y,z;
local angle = atan2( -(targetPos.x-aimPos.x), targetPos.y-aimPos.y ); //vcmp angle
local alpha=atan2( targetPos.z - aimPos.z, sqrt( pow( targetPos.y - aimPos.y, 2 ) + pow( targetPos.x - aimPos.x , 2 ) ) );
if(angle >0 ) //angle 0 to 3.14
//Quadrant can be North West or South West
if(angle <PI/2)
//Quadrant is North West
if( alpha > 0 )
y= -PI + alpha;
y= PI + alpha;
//Quadrant is South West
y= alpha;
//Quadrant can be North East or South East
if( angle > -PI/2 )
//Quadrant is North East
z= angle;
x= 0.0;
if( alpha > 0 )
y= -PI + alpha;
y= PI + alpha;
//Quadrant is South East
z= -PI-angle;
x= PI;
y= alpha;
return Vector(x,y,z);

But this is not exact. The bullet misses the point.

AimPos seems to be independent of player's Position. By altering packets, i found out that the player shoots a particular point if (AimPos, AimDir) are specified. Then changing position with former variables i.e. aimpos and aimdir same, still the player shoots the point.
However, if the position is too 'out of range', the player shoots somewhere else.

So the question is how is aim direction calculated, given the position to hit?

Update- Using aiming weapons like 27, using my code hits the target perfectly, the directions being calculated as above. But it hit somewhere when in normal firing (without aiming or right click). It hits near, but not exact.
General Discussion / Making npcs shoot x y z
« on November 5th, 08:02 PM »
I was standing infront of the Vercetti estate alone. Suddenly i thought, if there was an npc beside me and were it able to shoot !

So i digged into my old NPC project. Reluctant to change the carefully written codes but still quickly want to add two functions.

This is what i got

See the npc is shooting at certain x y z. The one function i made looks like this:
Code: [Select]
SendOnFootSyncData(576,-286.98, -592.451, 12.8423,2.29,100, 0, 17, 0.0, 0.0, 0.0,-284.302, -590.105, 14.4482,-3.14174, -0.222718, 0.851276);
SendOnFootSyncData(576(keys on foot fire),x, y, z, angle, 100(health), 0(armour), 17(colt), 0.0, 0.0, 0.0,-284.302, -590.105, 14.4482,-3.14174, -0.222718, 0.851276);
//The last values are aimpos and aimdir.
Code: [Select]
SendOnFootSyncData([integer] keys, [float] posX, [float] posY, [float] posZ, [float] angle, [integer] health, [integer] armour, [integer] weapon, [float]speedX, [float]speedY, [float]speedZ, [float]aimPosX, [float]aimPosY, [float]aimPosZ, [float]aimDirX, [float]aimDirY, [float]aimDirZ, isCrouching(from v1.3 only) );
Took 5 hours.

You can watch full video of npc shooting here(youtube)

You can also download the compiled program 'npcclient.exe'( See 'NPC implementation in VCMP 0.4 Servers' in Community Plugins for details ) here (version--call it 1.2 )

Changes(additions) to the source code of the project.
Code: [Select]

void SendNPCSyncData(ONFOOT_SYNC_DATA* m_pOfSyncData);
SQInteger fn_SendOnFootSyncData(HSQUIRRELVM v)
    if (!npc) {
        return 0;
    //i fff f i i i fff fff fff
    SQInteger dwKeys;
    sq_getinteger(v, 2, &dwKeys);
    SQFloat x, y, z;
    sq_getfloat(v, 3, &x);
    sq_getfloat(v, 4, &y);
    sq_getfloat(v, 5, &z);
    SQFloat fAngle;
    sq_getfloat(v, 6, &fAngle);

    SQInteger byteHealth;
    sq_getinteger(v, 7, &byteHealth);

    SQInteger byteArmour;
    sq_getinteger(v, 8, &byteArmour);

    SQInteger byteCurrentWeapon;
    sq_getinteger(v, 9, &byteCurrentWeapon);

    SQFloat vx, vy, vz;
    sq_getfloat(v, 10, &vx);
    sq_getfloat(v, 11, &vy);
    sq_getfloat(v, 12, &vz);

    //Aim Position
    SQFloat s, t, u;
    sq_getfloat(v, 13, &s);
    sq_getfloat(v, 14, &t);
    sq_getfloat(v, 15, &u);

    //Aim Direction
    SQFloat p, q, r;
    sq_getfloat(v, 16, &p);
    sq_getfloat(v, 17, &q);
    sq_getfloat(v, 18, &r);
    ONFOOT_SYNC_DATA m_pOfSyncData;
    m_pOfSyncData.byteArmour = (uint8_t)byteArmour;
    m_pOfSyncData.byteCurrentWeapon = (uint8_t)byteCurrentWeapon;
    m_pOfSyncData.byteHealth = (uint8_t)byteHealth;
    m_pOfSyncData.dwKeys = (uint32_t)dwKeys;
    m_pOfSyncData.fAngle = fAngle;
    m_pOfSyncData.IsAiming = ((dwKeys & 1)||(dwKeys &576) == 576);
    m_pOfSyncData.IsCrouching = (dwKeys & 288)==288;
    m_pOfSyncData.vecAimDir.X = p;
    m_pOfSyncData.vecAimDir.Y = q;
    m_pOfSyncData.vecAimDir.Z = r;

    m_pOfSyncData.vecAimPos.X = s;
    m_pOfSyncData.vecAimPos.Y = t;
    m_pOfSyncData.vecAimPos.Z = u;

    m_pOfSyncData.vecPos.X = x;
    m_pOfSyncData.vecPos.Y = y;
    m_pOfSyncData.vecPos.Z = z;

    m_pOfSyncData.vecSpeed.X = vx;
    m_pOfSyncData.vecSpeed.Y = vy;
    m_pOfSyncData.vecSpeed.Z = vz;
    return 0;//0 because we are returning nothing!
Code: [Select]
//In function RegisterNPCFunctions
register_global_func(v, ::fn_SendOnFootSyncData, "SendOnFootSyncData", 18, "tiffffiiifffffffff");

Code: [Select]
//minor change in main.cpp regarding version
CmdLine cmd("VCMP-Non Player Characters", ' ', "1.2",false);

Note: In the functions, using integers (eg. 0, 1, 2 ) in the places of [float] may not work. So if an angle is zero, giving it as '0' will not work.
Tutorials / [Guide][Squirrel][discord04relx] Creating a discord bot
« on June 18th, 08:07 PM »
Hello, in this tutorial we will learn how to set up a discord bot. This bot can be used to send messages to your discord channel as well as receive text messages from the channel.

We will be using Discord Plugin for squirrel created by Luckshaya

Step 1. Download the plugin and put in plugins/discord04rel64.dll
Step 2. (a). scripts/dcdbot.nut
Code: [Select]
//Copyright @ Luckshaya 2020
//modified by adding field targetchannelID, edited functions sendMessage and onMessage
sessions <- {};

class MyDiscord
eventFuncs = null;
session = null;
connID = null;

function constructor()
session = SqDiscord.CSession();
connID = session.ConnID;

sessions.rawset(connID, this);

eventFuncs = [

session.InternalCacheEnabled = true;

function Connect(token)

function sendMessage(channelID, message)
session.Message(channelID, message);
function sendMessage(message)
session.Message(targetchannelID, message);
print("Error. Use sendMessage(channelID, message) because targetchannelID was not set");

function sendEmbed(channelID, embed)
session.MessageEmbed(channelID, "", embed);

function onReady() {
print("Discord bot connection established successfully.");

function onMessage(message) {
if(!targetchannelID || targetchannelID==message.ChannelID)
print("[Discord]"+message.Member.User.Username+": "+message.Content);


function onError(code, message) {
print(format("%d - %s", code, message));

function onDisconnect() {
print("Discord session has disconnected.");

function onQuit() {
print("Discord session has quit.")

function onDiscordUpdate(connID, eventType, ...) {
if(sessions.rawin(connID)) {
local session = sessions.rawget(connID);
vargv.insert(0, session); //env
(b). scripts/main.nut
Code: [Select]
myDiscord <- MyDiscord();
myDiscord.Connect("------------YOUR TOKEN HERE----------------");
myDiscord.targetchannelID="---YOUR CHNNL ID HERE--"

The bot will automatically print the messages received from discord. To print those messages inside server (to every players), edit the function onMessage

To send message to the channel, use
Code: [Select]
myDiscord.sendMessage("---your message here--");

Part 2 - How to obtain TOKEN and CHNNL ID
1. Obtaining Channel ID
Obtaining channel id is relatively simple. Open discord in your browser and go to your favourite channel.
If the url when your channel is opened is, then the yyyy is the channel id.

2. Obtaining TOKEN
2. (a) Creating the bot
1. Head to Discord Developer Portal
Click on New Application

2. Enter a name for  Name of the bot and click Create

That's all there to do.
3. Click on the sidebar and select Bot.

Then click on Add Bot

You will see the message
A wild bot has appeared!
Scroll down and copy Application ID

2. (b) Obtaining token
In the same page, scroll down and you will see Token section. Click on Reset Token. Then click on Copy.

This is the ---YOUR TOKEN HERE----- mentioned in the scripts/main.nut. Note that it must be passed as a string.(enclosed in double quotes)
2. (c) Permission
If you want to change:
This will do for sending and receiving messages in the channel. Or if you want to change this number, use the calculator.
"Scroll down and you will see Bot Permissions Calculator. "

2. (d) Application ID
You obtained in step 1.3
2. (e) Adding bot to the server
1. Go toPut the Application ID in the place of APPLICATION_ID_HERE. If you have changed permission in 2.(c), change is required on proper place in the above url.

Select your server and click on Continue.
The bot will be added to your server

Tutorials / [Tutorial] The first VC-MP Server built as plugin
« on June 10th, 09:51 AM »
Hello everyone.
I wrote a vc-mp server not in squirrel, not in java, not in lua and not in python. This server is very simple and scripted in C.

Here it goes

Code: [Select]
#include "PluginAPI.h"
#include <stdio.h> //For printing text on console
#include <time.h> //For printing time on console
#include <string.h> //For calculating length of
#include <math.h> //For calculating distance between players
#define MAX_VEHICLES 1000
PluginFuncs* Server;
uint8_t fn_OnServerInitialise (void)
Server->SetServerName("Simple VC-MP Server");
Server->SetServerOption(vcmpServerOptionFriendlyFire, 0);
printf(" VCMP Server in C by habi, Banaqs (vehicles) \n");
printf("Date last scripted: 06 Jun 2022 \n");
printf("Creating Vehicles ...");

printf("Done\n");short wVehicleCount=0;
for(int i=1; i<MAX_VEHICLES;i++)
if(Server->CheckEntityExists(vcmpEntityPoolVehicle, i))
printf("Loaded %d vehicles\n", wVehicleCount);
printf("Commands: /veh /wthr /sttime /fix /flip\n");
printf("Commands (type 2): /heal\n");
printf("Commands: /credits /cmds\n");

return 1;
uint8_t fn_OnPlayerMessage(int32_t playerId, const char* message)
char* name = (char*)malloc(256);
vcmpError e=Server->GetPlayerName(playerId, name, 256);
if (e==0)
printf("[%u] %s: %s\n", playerId, name, message);
return 1;
void fn_OnPlayerConnect (int32_t playerId)
/* Credits: zishan, stackoverflow for time function*/
time_t mytime = time(NULL);
char* time_str = ctime(&mytime);
time_str[strlen(time_str) - 1] = '\0';

char* name = (char*)malloc(256);
vcmpError e = Server->GetPlayerName(playerId, name, 256);
if (e == 0)
char buffer[256];
int n = sprintf(buffer, "[%s] [%u] [%s] connected.", time_str, playerId, name);
if (n > 0)
void fn_OnPlayerDisconnect (int32_t playerId, vcmpDisconnectReason reason)
/* Credits: zishan, stackoverflow for time function */
time_t mytime = time(NULL);
char* time_str = ctime(&mytime);
time_str[strlen(time_str) - 1] = '\0';

char buffer[256];
int n=sprintf(buffer, "[%s] [%u] disconnected.", time_str, playerId);
if (n > 0)

uint8_t fn_OnPlayerCommand(int32_t playerId, const char* message)
int idx=0;
char* text=(char*)malloc(strlen(message)+1);
strcpy(text, message);
char* cmd;
cmd=strtok(text, " ");
if(!cmd)return 1;
if(strcmp(cmd, "credits")==0)
Server->SendClientMessage(playerId,0xFFFFFFFF,"Credits: habi, Banaqs (2014) for 200 vehicles");
}else if(strcmp(cmd, "cmds")==0)
Server->SendClientMessage(playerId, 0xFFFFFFFF, "/veh /wthr /sttime /fix /flip /heal /credits");
}else if(strcmp(cmd, "fix")==0)
int vehicleId=Server->GetPlayerVehicleId(playerId);
Server->SetVehicleHealth(vehicleId, 1000.0);
Server->SetVehicleDamageData(vehicleId, 0);
Server->SendClientMessage(playerId, 0xFFFFFFFF, "Fixed");
}else printf("You must be in a vehicle to use this command.\n");
}else if(strcmp(cmd, "flip")==0)
int vehicleId=Server->GetPlayerVehicleId(playerId);
float x, y, z;
Server->GetVehiclePosition(vehicleId, &x, &y, &z);
Server->SetVehiclePosition(vehicleId, x, y, z, 0);
Server->SendClientMessage(playerId, 0xFFFFFFFF, "Flipped");
}else printf("You must be in a vehicle to use this command.\n");
}else if(strcmp(cmd, "wthr")==0)
char* arg=strtok(NULL," ");
char* pEnd;
int id=(int)strtol(arg,&pEnd, 0);
if(id || id==0 &&strcmp(pEnd,"")==0)
for(int i=0;i<Server->GetMaxPlayers();i++)
Server->SendClientMessage(i, 0xFFFFFFFF,"Weather changed!");
}else Server->SendClientMessage(playerId, 0xFFFFFFFF, "Use: /wthr id");
}else if(strcmp(cmd, "sttime")==0)
char* hour=strtok(NULL, " ");
char* min=strtok(NULL, " ");
if(hour && min)
char* pEnd;int s=0;
int ihour=(int)strtol(hour,&pEnd, 0);
if(ihour || strcmp(pEnd, "")==0)
int imin=(int)strtol(min, &pEnd, 0);
if(imin || strcmp(pEnd,"")==0)
if(!s)Server->SendClientMessage(playerId, 0xFFFFFFFF, "Error, use /settime hr min");
}else Server->SendClientMessage(playerId, 0xFFFFFFFF, "Use: /sttime hr min");
}else if(strcmp(cmd, "heal")==0)
return 1;
float x, y, z;
Server->GetPlayerPosition(playerId, &x, &y, &z);
float p, q, r;
int closestplayerId=-1;float smallestdistance=2;
for(int i=0;i<Server->GetMaxPlayers();i++)
float distance=sqrt(pow(x-p,2)+pow(y-q,2)+pow(z-r,2));
Server->SetPlayerHealth(closestplayerId, 100.0);
Server->SendClientMessage(closestplayerId, 0xFFFFFFFF, "You have been healed.");
Server->SendClientMessage(playerId, 0xFFFFFFFF,"You must be near a player to heal him/her.");
}else if(strcmp(cmd, "veh")==0)
return 1;
char* arg=strtok(NULL," ");
char* pEnd;
short wVehicleId=(int)strtol(arg,&pEnd, 0);
if(Server->CheckEntityExists(vcmpEntityPoolVehicle, wVehicleId))
int iSomePlayerId=Server->GetVehicleOccupant(wVehicleId, 0);
float x,y,z;
Server->GetPlayerPosition(playerId, &x, &y, &z);
Server->SetVehiclePosition(wVehicleId, x, y, z,0);
Server->PutPlayerInVehicle(playerId,wVehicleId, 0, 0,1);
return 1;
Server->SendClientMessage(playerId, 0xFFFFFFFF, "Error: Invalid vehicle id");
}else Server->SendClientMessage(playerId, 0xFFFFFFFF, "Usage: /veh id");
return 1;
unsigned int VcmpPluginInit(PluginFuncs* pluginFuncs, PluginCallbacks* pluginCallbacks, PluginInfo* pluginInfo) {
if(!pluginFuncs)return 1;//Precaution

// Plugin information
pluginInfo->pluginVersion = 0x1;
pluginInfo->apiMajorVersion = PLUGIN_API_MAJOR;
pluginInfo->apiMinorVersion = PLUGIN_API_MINOR;

pluginCallbacks->OnServerInitialise = fn_OnServerInitialise;
pluginCallbacks->OnPlayerMessage = fn_OnPlayerMessage;
pluginCallbacks->OnPlayerConnect = fn_OnPlayerConnect;
pluginCallbacks->OnPlayerDisconnect = fn_OnPlayerDisconnect;
return 1;
General Discussion / About radio stations
« on June 5th, 08:54 AM »
There are a couple songs while inside vehicle. They are in a local language. I'm hearing it again and again all the time.

I checked mp3 folder inside Gta vice city and found nothing.

My question is if i'm with a friend and we are both in a vehicle, is he hearing the same music as me?
Off-Topic General / The programming loop and brain
« on May 26th, 09:46 AM »
Step 1: I run cmake --build. --config Release

Step 2: I go to Release folder and double click my program

Step 3: I inspect my program. Go to notepad++ make some changes and save. Then i go to Step 1 again.

Guys, i was repeating this for 6 hours last yesterday. And when i went outside into the streets, i realised how mechanical my mind has become.

Our brains are caught in this. Seeing a desire ( Aah how nice will my program become if I add this. Add that too. then that thing and then.. Is it better if... )

I wish i could throw this computer into some big garbage.

Did you guys ever feel like this?
Tutorials / [Tutorial-general-programming] Building a program from CMakelists.txt
« on May 22nd, 05:41 AM »
I am creating this tutorial for those who are stuck at wondering what is this "CMake stuff" is.

You might have seen "CMakeLists.txt" and other lot of files ("build", "out", "ALL_BUILD", "ZERO_CHECK", "Release", "CMakeCache" )

Actually, all these files are automatically creating by running "cmake" from command line

I will show you how.

However there are two problems
1. You need to download and install cmake(here Under Binary Distribution )
2. You need to install Visual Studio( It is called "Visual Studio Community". here )

I had installed the second thing more than 2 years ago. But now i code in notepad++ and for compiling cmake uses visual studio compiler which comes with "Visual Studio Community"
General Discussion / VC-MP Store Downloader
« on May 16th, 10:43 AM »
Application: here (windows x64 - v1.2 with GUI)

Usage:  (command line - basic usage)
Code: [Select]
store update
store install

What does this do?
If the store folder of Server is available online, program will download it and copy it to C:/Users/%username%/AppData/Roaming/VCMP/04beta/store/

How to add store of a server?
The masterlist is hosted at and can be manipulated through ( link at bottom see 'Links' )

How will i zip a server's store folder?
We accept only *.zip files. The contents of zip files must be the folders like 'script', 'sprites', 'sounds', 'skins', etc and various files

Where can i find the source of the project?
You can find source of project at  github:

Any screenshots of application?
A sample testing

Happy Gaming

Add store of a server

Where to upload store folder online?
Our program can download from direct download links. So you can upload store folder as a zip file in any online file hosting services which can generate direct download links ( and not links with download buttons ). Some sites i found are
1. If you have vps, you can get an file link easily
2. You need to create an account and add your files and copy the link.
3. Github releases. If you have a free github account, then create repository and add 'releases' - upload the file and you get link
4. Follow this website to learn to make a direct download link using Google Drive ( if you have a gmail account ) (Add &confirm=t to the end of the URL if the file is large) or Dropbox (faster download)

When link is ready, click on above 'Add store of a server'

Note: Any server's store can be deleted by passing url as "delete" without quotes on the website "Add store of a server" link above, so that it no longer appear in the program.
Tutorials / [Video Tutorial: NPC] Introduction and How to record player onfoot
« on April 24th, 07:29 PM »
Watch this 11 minute video to see our npcs ...

Written Tutorials

1. Creating an idle NPC

2. Recording player actions

3. Recording vehicle drivings

PS: I created three topics already. To avoid flooding of tutorial board, i will not be creating further new topics, but post/update+post in topics already posted.
General Discussion / Hi guys a new idea
« on April 14th, 02:33 PM »
I just got this idea and get captivated by it.
It is about making of a program, (an executable for windows and linux), say it's name snippet downloader for vcmp.

You open it and enter a command like
apt-get install speedometer
The 'apt-get' is mimicked from ubuntu style, we can change it to something.

Now, you type this command and then press enter.

The program connects to github and searches for project VCMP_speedometer. It finds it and open the 'direction file', say a file which tells our program
1. Which modules (xx04rel64) to use. If speedometer uses a new module which the creator has created it's name and location in github project.
Instructions to make changes to server.cfg
2. Suppose your snippet wants to add code to onPlayerEnterVehicle, the program reads your main.nut find onPlayerEnterVehicle and codes to it.
It is quite complicated, but possible.
3. Similarly we handle client side scripts and adding objects may also be possible.
4. Most importantly, the program must be able to revert back the changes.

The creators of snippets should make variables with names (if they are using global variables) such that it does not coincide with general variable names used in servers.
Have you got what i am telling. How many people agree with me?

So i will state it once again. i.e. no more script download - copy paste - index does not exist-.
Just open program type the name of the package and done.

So somebody(on our forum) must maintain a file online which contains the name of package and the url to it.
Hi i was just making a highlighter for notepad++.

Yes this highlights and autocompletes function and events.

I have not added, the usual functions like print, fget, format etc yet.

Download the files from my github

Put 'Vice City Multiplayer Server.udl.xml' in  % appdata % \ Notepad++ \ userDefineLangs
Put 'Vice City Multiplayer.xml' in C:\ Program Files \ Notepad++ \ autoCompletion
Restart Notepad++. Any files ending with '.nut' will be automatically highlighted. If not, select 'Vice City Multiplayer' from 'Language' Menu. (It is on bottom most )
(click to show/hide)
You can select highlight colours of your own by Language->User Defined Language->Define your language.. Then select "Vice City Multiplayer". (After editing just close the window, it will be saved automatically)

If you are interested, or want to contribute let me know. (or github - a pull request !)

Credits: [email protected] for basic squirrel language highlighter, habi for function and event definitions