Menu

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.

Show posts Menu

Topics - MEGAMIND

#1
Community Plugins / VCMPAI Plugin
Apr 19, 2026, 05:04 PM

VCMP AI Plugin (Groq API Integration)

A VCMP (Vice City Multiplayer) plugin written in C++ using the VCMP SDK that allows your server to process player input and generate AI-powered responses using the Groq API.



Overview

This plugin makes it easy to integrate AI into your VCMP server without using Node.js, sockets, or complex external systems.

With a simple function call, you can:
  • Create AI chatbots
  • Control NPC behavior
  • Build interactive systems
  • Customize AI tone and personality

Features

  • Native C++ plugin (VCMP SDK)
  • Groq API integration
  • Simple function usage
  • No external dependencies
  • Custom AI tone support
  • Lightweight and efficient

Installation

  • Place the plugin (vcmpai32.dll or vcmpai64.dll) into your server plugins folder.
  • Start your server once — it will generate:

ai.cfg

  • Open ai.cfg and add your Groq API key.
Getting a Groq API Key

Example:
api_key=your_api_key_here

Restart your server after adding the key.

Usage

getChatGPTResponse(text, player.ID, tone)

Parameters:

  • text (string) 
    Input sent to the AI. Can include anything:

  • player.ID (integer) 
    Unique ID of the player requesting the response.

  • tone (string) 
    Controls how the AI responds (style/personality).

    Examples:
    • "friendly"
    • "sarcastic"
    • "game narrator"
    • "strict admin"
Example

getChatGPTResponse(
    "How can I earn money in this server?",
    player.ID,
    "friendly and helpful"
);

Use Cases

  • AI chatbots
  • NPC dialogue (can be used with habi2 NPC system)
  • Admin tools
  • Roleplay systems
  • Smart commands

Background

Previously, implementing AI required:
  • Node.js servers
  • WebSockets
  • Complex scripting

Now, it's just one function call.

Downloads & Source

Source GitHub

Download Plugin 32-bit 
Download Plugin 64-bit

Notes

  • Make sure your API key is valid
  • Invalid config = no AI response
  • Tone affects output heavily

Feedback

Share your ideas or suggestions below — I'll try to add improvements when I get time.



#2

VCMP AI Script Assistant is an advanced AI system designed to interpret VCMP wiki functions, documentation, and usage examples. It intelligently combines structured knowledge to generate custom scripts based on user queries, transforming ideas into functional VCMP code with accuracy and efficiency.

Examples



Launch

How it works?
You need to get an api key first from GROQ
 then you simply ask it anything.. it will display you your answers according to query (Dont expect it to be perfect) as its an A.I After each answer you will simply get a new asnwer to question after 30 sec so that the A.I model doesnt get hog and ban you evenutally  8)

I'll try my best to update it to more efficient and with good results when i get time..!

#3
Community Plugins / A.I Plugin
Apr 11, 2026, 12:25 PM

Well was way bored...! so i wrote an a.i written in cpp using vcmp sdk that includes groq api. The plugin welcomes anyone on there screen when they join server



The plugin will generate a ai.cfg in your server folder
Then you need to go at Groq API Key
Generate a key for free, include that key to ai.cfg and run your server...

Anyone having a cpp knowledge can make the use of this plugin for them selves for there servers and make the a.i according to them either connect it with @habi2 npc or make a chatbot or whatever...

Note:Keep in mind its not the same plugin that is used in Top Down City Server[The only first a.i based server] (Thats way more advanced)..!

Source Github

Download Plugin 32
Download Plugin 64

Share your ideas or suggestions below.. ill see if i get time to add them..!


#4
VCMP UPDATER URL DOWNLOADER a tool that downloads and installs the build version of vcmp, this tool was made due to an unexpected behaviour going on with vcmp official browser / or networks


Its virus free 0 viruses marked by Virustotal



#include <iostream>
#include <string>
#include <vector>
#include <windows.h>
#include <urlmon.h>
#include <shlobj.h>
#include <fstream>
#include <sstream>
#include <direct.h>

#pragma comment(lib, "urlmon.lib")
#pragma comment(lib, "shell32.lib")

struct VersionInfo {
    std::string version;
    std::string filename;
    std::string build;
};

class VCMPDownloader {
private:
    std::string baseUrl = "https://u04.thijn.ovh";
    std::string baseTargetPath;

public:
    VCMPDownloader() {
        // Get the base target path
        char appDataPath[MAX_PATH];
        if (SUCCEEDED(SHGetFolderPathA(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, appDataPath))) {
            baseTargetPath = std::string(appDataPath) + "\\Vice City Multiplayer\\";
        }
        else {
            baseTargetPath = "C:\\Users\\%username%\\AppData\\Local\\Vice City Multiplayer\\";
        }
    }

    bool directoryExists(const std::string& path) {
        DWORD attrib = GetFileAttributesA(path.c_str());
        return (attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_DIRECTORY));
    }

    bool createDirectory(const std::string& path) {
        // Create all directories in the path
        std::string current;
        for (size_t i = 0; i < path.length(); i++) {
            current += path[i];
            if (path[i] == '\\' || i == path.length() - 1) {
                if (!directoryExists(current) && current != "C:" && current != "C:\\") {
                    if (!CreateDirectoryA(current.c_str(), NULL)) {
                        if (GetLastError() != ERROR_ALREADY_EXISTS) {
                            return false;
                        }
                    }
                }
            }
        }
        return true;
    }

    std::string downloadPage(const std::string& url) {
        std::string tempFile = "temp_page.html";

        // Download the HTML page
        std::cout << "Downloading version information..." << std::endl;
        if (URLDownloadToFileA(NULL, url.c_str(), tempFile.c_str(), 0, NULL) != S_OK) {
            std::cout << "Failed to download page from: " << url << std::endl;
            return "";
        }

        // Read the downloaded file
        std::ifstream file(tempFile);
        if (!file.is_open()) {
            std::cout << "Failed to open temporary file" << std::endl;
            return "";
        }

        std::stringstream buffer;
        buffer << file.rdbuf();
        file.close();

        // Delete temporary file
        DeleteFileA(tempFile.c_str());

        return buffer.str();
    }

    std::vector<VersionInfo> parseVersions(const std::string& html) {
        std::vector<VersionInfo> versions;
        size_t pos = 0;

        while ((pos = html.find("Version <a href=\"/files/", pos)) != std::string::npos) {
            // Extract filename
            size_t href_start = html.find("href=\"", pos) + 6;
            size_t href_end = html.find("\"", href_start);
            if (href_end == std::string::npos) break;

            std::string filepath = html.substr(href_start, href_end - href_start);

            // Extract version
            size_t version_start = html.find(">", href_end) + 1;
            size_t version_end = html.find("<", version_start);
            if (version_end == std::string::npos) break;

            std::string version = html.substr(version_start, version_end - version_start);

            // Extract build from filename
            std::string filename = filepath.substr(filepath.find_last_of("/") + 1);
            std::string build = filename.substr(6, 8); // Extract build ID

            versions.push_back({ version, filename, build });

            pos = version_end;
        }

        return versions;
    }

    bool downloadFile(const std::string& filename) {
        std::string url = baseUrl + "/files/" + filename;
        std::string localPath = filename;

        std::cout << "Downloading: " << filename << std::endl;

        if (URLDownloadToFileA(NULL, url.c_str(), localPath.c_str(), 0, NULL) == S_OK) {
            std::cout << "Download completed: " << filename << std::endl;
            return true;
        }
        else {
            std::cout << "Download failed: " << filename << std::endl;
            return false;
        }
    }

    std::string cleanVersionName(const std::string& version) {
        std::string clean = version;
        // Replace characters that are not valid in folder names
        for (size_t i = 0; i < clean.length(); i++) {
            if (clean[i] == ':' || clean[i] == '\\' || clean[i] == '/' ||
                clean[i] == '*' || clean[i] == '?' || clean[i] == '"' ||
                clean[i] == '<' || clean[i] == '>' || clean[i] == '|') {
                clean[i] = '_';
            }
        }
        return clean;
    }

    bool extractWithWinRAR(const std::string& archivePath, const std::string& version) {
        // Common WinRAR installation paths
        const char* winRARPaths[] = {
            "C:\\Program Files\\WinRAR\\WinRAR.exe",
            "C:\\Program Files (x86)\\WinRAR\\WinRAR.exe",
            "C:\\Program Files\\WinRAR\\Rar.exe",
            "C:\\Program Files (x86)\\WinRAR\\Rar.exe"
        };

        std::string winRARExe;
        bool foundWinRAR = false;

        // Find WinRAR installation
        for (int i = 0; i < 4; i++) {
            if (GetFileAttributesA(winRARPaths[i]) != INVALID_FILE_ATTRIBUTES) {
                winRARExe = winRARPaths[i];
                foundWinRAR = true;
                std::cout << "Found WinRAR at: " << winRARExe << std::endl;
                break;
            }
        }

        if (!foundWinRAR) {
            std::cout << "WinRAR not found in standard locations!" << std::endl;
            return false;
        }

        // Create version-specific folder
        std::string cleanVersion = cleanVersionName(version);
        std::string versionTargetPath = baseTargetPath + cleanVersion + "\\";

        // Create the version directory
        if (!directoryExists(versionTargetPath)) {
            std::cout << "Creating version directory: " << versionTargetPath << std::endl;
            if (!createDirectory(versionTargetPath)) {
                std::cout << "Failed to create version directory!" << std::endl;
                return false;
            }
        }

        // Build WinRAR command
        std::string command = "\"" + winRARExe + "\" x -y -s -ibck \"" + archivePath + "\" \"" + versionTargetPath + "\"";

        std::cout << "Extracting to version folder: " << versionTargetPath << std::endl;
        std::cout << "Command: " << command << std::endl;

        STARTUPINFOA si = { sizeof(si) };
        PROCESS_INFORMATION pi;
        si.dwFlags = STARTF_USESHOWWINDOW;
        si.wShowWindow = SW_HIDE;

        if (CreateProcessA(NULL, (LPSTR)command.c_str(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
            WaitForSingleObject(pi.hProcess, INFINITE);

            DWORD exitCode;
            GetExitCodeProcess(pi.hProcess, &exitCode);

            CloseHandle(pi.hProcess);
            CloseHandle(pi.hThread);

            if (exitCode == 0) {
                std::cout << "WinRAR extraction successful to version folder!" << std::endl;
                return true;
            }
            else {
                std::cout << "WinRAR extraction failed with exit code: " << exitCode << std::endl;
            }
        }
        else {
            std::cout << "Failed to start WinRAR process!" << std::endl;
        }

        return false;
    }

    bool extract7z(const std::string& archivePath, const std::string& version) {
        // Create version-specific folder
        std::string cleanVersion = cleanVersionName(version);
        std::string versionTargetPath = baseTargetPath + cleanVersion + "\\";

        // Create the version directory
        if (!directoryExists(versionTargetPath)) {
            std::cout << "Creating version directory: " << versionTargetPath << std::endl;
            if (!createDirectory(versionTargetPath)) {
                std::cout << "Failed to create version directory!" << std::endl;
                return false;
            }
        }

        // Use 7z.exe to extract
        std::string command = "7z x \"" + archivePath + "\" -o\"" + versionTargetPath + "\" -y";

        std::cout << "Extracting with 7-Zip to version folder: " << versionTargetPath << std::endl;

        STARTUPINFOA si = { sizeof(si) };
        PROCESS_INFORMATION pi;
        si.dwFlags = STARTF_USESHOWWINDOW;
        si.wShowWindow = SW_HIDE;

        if (CreateProcessA(NULL, (LPSTR)command.c_str(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
            WaitForSingleObject(pi.hProcess, INFINITE);

            DWORD exitCode;
            GetExitCodeProcess(pi.hProcess, &exitCode);

            CloseHandle(pi.hProcess);
            CloseHandle(pi.hThread);

            if (exitCode == 0) {
                std::cout << "7-Zip extraction successful to version folder!" << std::endl;
                return true;
            }
        }

        std::cout << "7-Zip extraction failed!" << std::endl;
        return false;
    }

    void showVersions(const std::vector<VersionInfo>& versions) {
        std::cout << "\nAvailable VC:MP Versions:\n";
        std::cout << "==========================\n";

        for (size_t i = 0; i < versions.size(); i++) {
            std::cout << i + 1 << ". " << versions[i].version << " (Build: " << versions[i].build << ")\n";
        }
    }

    void run() {
        std::cout << "VC:MP Downloader and Installer\n";
        std::cout << "==============================\n\n";

        // Create base target directory if it doesn't exist
        if (!directoryExists(baseTargetPath)) {
            std::cout << "Creating base directory: " << baseTargetPath << std::endl;
            if (!createDirectory(baseTargetPath)) {
                std::cout << "Failed to create base directory: " << baseTargetPath << std::endl;
                return;
            }
        }

        // Download and parse the page
        std::string html = downloadPage(baseUrl);

        if (html.empty()) {
            std::cout << "Failed to fetch version information!" << std::endl;
            std::cout << "Press Enter to exit...";
            std::cin.ignore();
            std::cin.get();
            return;
        }

        std::vector<VersionInfo> versions = parseVersions(html);

        if (versions.empty()) {
            std::cout << "No versions found!" << std::endl;
            std::cout << "Press Enter to exit...";
            std::cin.ignore();
            std::cin.get();
            return;
        }

        // Show available versions
        showVersions(versions);

        // Let user choose version
        int choice;
        std::cout << "\nEnter the number of the version to download (1-" << versions.size() << "): ";
        std::cin >> choice;

        if (choice < 1 || choice > versions.size()) {
            std::cout << "Invalid choice!" << std::endl;
            std::cout << "Press Enter to exit...";
            std::cin.ignore();
            std::cin.get();
            return;
        }

        VersionInfo selected = versions[choice - 1];

        std::cout << "\nSelected: " << selected.version << std::endl;
        std::cout << "File: " << selected.filename << std::endl;
        std::cout << "Base Path: " << baseTargetPath << std::endl;

        // Download the file
        if (!downloadFile(selected.filename)) {
            std::cout << "Press Enter to exit...";
            std::cin.ignore();
            std::cin.get();
            return;
        }

        // Extract the file to version-specific folder
        std::cout << "\nExtracting files to version folder..." << std::endl;

        bool extracted = false;

        // Try WinRAR first
        extracted = extractWithWinRAR(selected.filename, selected.version);

        // If WinRAR fails, try 7-Zip
        if (!extracted) {
            std::cout << "Trying 7-Zip extraction..." << std::endl;
            extracted = extract7z(selected.filename, selected.version);
        }

        // Clean up downloaded archive
        if (extracted) {
            std::cout << "Cleaning up..." << std::endl;
            if (DeleteFileA(selected.filename.c_str())) {
                std::cout << "Temporary file removed." << std::endl;
            }
            std::cout << "Installation completed successfully!" << std::endl;
            std::cout << "Version installed to: " << baseTargetPath << cleanVersionName(selected.version) << "\\" << std::endl;
        }
        else {
            std::cout << "Installation failed! Make sure WinRAR or 7-Zip is installed." << std::endl;
            std::cout << "Downloaded file kept as: " << selected.filename << std::endl;
        }

        std::cout << "Press Enter to exit...";
        std::cin.ignore();
        std::cin.get();
    }
};

int main() {
    VCMPDownloader downloader;
    downloader.run();
    return 0;
}

Github repo


How to use it?

Note:
Requires winrar or 7z
#5
Off-Topic General / VCMP ANDROID PROJECT
Jul 02, 2025, 08:09 PM
Well its been few months now and would like to share this with you guys... currently working alone on the project...

Donot expect a instant launch as theres tons of stuff left for it to be as vcmp...

Well im working on a vcmp port to android version of gta vc.. so far this is ehat it looks like..


theres alot more on the progress of the vxmp android port here idk what developers will think about it, but it would be much greate if we have the devs working on it... or atleast share me some devs stuff from the original vcmp.. so that the port becomes much easier.. other then from a long rewright of 20years...

also em lookin forward for beta testers and android gta vc modders (not the scm/cleo ones) to join me... in this project..

Kindly post in the topic weather ur interested in it or not..

Devs can contact me either in the topic, discord or forum mails..

Thanku..!
#6
Off-Topic General / 💲Vice Earn 💵
May 02, 2025, 06:32 PM

🎮 ViceEarn by Megamind – Earn Real Cash Playing GTA VC / 3 / SA

ViceEarn is a unique mod for GTA: Vice City developed by Megamind that lets players earn real-life money by completing in-game tasks and challenges.

🔹 What is ViceEarn?

ViceEarn transforms your GTA VC experience into a money-making opportunity. Instead of just playing for fun, this mod allows you to:
  •     Complete missions and objectives.
  •     Get rewarded with points or in-game currency.
  •     Convert those points into real cash via supported payout methods (like PayPal or UPI).

💰 How Do You Earn?

   
  • Download and install the mod from Official Website.
  •     Join the official Discord: https://discord.gg/MrF7fPH4DB
  •     Play GTA Vice City as normal.
  •     Complete tasks.
  •     Get rewarded based on your performance and time played.
  •     Cash out once you meet the withdrawal threshold.

🔗 Useful Links:

    🌐 Website: https://earnvc.netlify.app
    💬 Developer: Megamind (MEGAMIND#8033 on Discord)

#7
Well what i am trying to do is set a sprite on players head and rest of the players could see it

spriteppt_label <- {
    "gui_element" : GUISprite("vol.png", VectorScreen(-100, -100)), // Initially hidden, this will hold the GUI sprite element
    "position_3d" : Vector(-1736.89, -250.225, 14.8683), // The initial 3D position of the sprite
}

case 322:
local lplayer = World.FindLocalPlayer();
if (!lplayer) return; 
local lpos = lplayer.Position;
for (local i = 0; i < MAX_PLAYERS; ++i) {
    local player = World.FindPlayer(i); 
    if (player) {
        local spos = player.Position;  // Get this player's position

        // If this player is within 50 units of the local player
        if (Distance(lpos.X, lpos.Y, lpos.Z, spos.X, spos.Y, spos.Z) < 50) {
           
            // Recreate the sprite if it has been deleted
            if (::spriteppt_label.gui_element == null) {
                ::spriteppt_label.gui_element <- GUISprite("vol.png", VectorScreen(0, 0));  // Create sprite
                ::spriteppt_label.Size = VectorScreen(5, 5);  // Adjust sprite size as needed
            }

            // Update 3D position slightly above the player's head
            ::spriteppt_label.position_3d = spos + Vector(0, 0, 1.9);  // Offset by 1.9 units above the player's head

         
            local label_pos = GUI.WorldPosToScreen(::spriteppt_label.position_3d); 
            if (label_pos.Z < 1) {
                ::spriteppt_label.gui_element.Position = VectorScreen(label_pos.X, label_pos.Y);
            } else {
::spriteppt_label.gui_element.Position = VectorScreen(-100, -100);  // Move off-screen
            }
        } else {
            if (::spriteppt_label.gui_element != null) {
                ::spriteppt_label.gui_element <- null;
            }
        }
    }
}

break; case 323:
            ::spriteppt_label <- null;
            break;


This is what i am looking for



idk what wrong with it

@umar4911 @habi2 @vito @Sebastian
#8
as gui 3d label



yeup gpt got it badge too



u can place sprites anywhere in game as 3dlabel

#9
General Discussion / Masterlist fetch prob?
Jan 26, 2025, 11:33 AM
so thijn checkers says that my server is listed on thijn list but not main list



where as i see my server announced on both of the lists

thijn list :



main list:



so is it really a problem or thijns website has some issues?
#11
Off-Topic General / That you?
Jan 22, 2025, 01:39 PM
i saw 2 of u @habi2
#13
General Discussion / IRC down?
Jan 13, 2025, 12:32 PM
I know no one uses irc these days and i  belive irc is down as the ones below are down from a month now

https://www.mibbit.com/
https://www.kiwiirc.com/
http://irc.liberty-unleashed.co.uk/ as this used 6667

so those who have trouble connecting irc kindly move ur servers too

irc.libera.chat -> use 6697 for ports

Thankyou
#14
#15
ummm yeeeeaaaa watch first


Can be availed with new version of MEGAMIND'S VCMP BROWSER



[SCRIPT]  Translating text: i like vcmp
[SCRIPT]  [TRANSLATION SUCCESS]: me gusta vcmp
[SCRIPT]  MEGAMIND: i like vcmp
[SCRIPT]  Translating text: i like vcmp alot
[SCRIPT]  [TRANSLATION SUCCESS]: Ich mag vcmp sehr
#16


May this year bring you joy, success, and endless opportunities! 🥳🎈🌟
#17
General Discussion / F8 By npc?
Dec 03, 2024, 06:29 PM
@habi2 as we ourselves can take a pic using F8 how can we make npc to do so? bcz in real its not typing anything.. but chat though  ;D so what could be the way that it takes pic like f8 and the image gets saved?
#18
@habi2 what is default.map?

How did u made it ?

Kind of hardcoded as i was wondering it might be containing over all vc coords.. can u provide a detail topic on it?

Can we make our own default.map?

Is it really even needed? cuz my npc walks fine even without it!

can we extract data from this default.map file?

What are the more possiblities with it..?
#19
General Discussion / Radio for Player
Nov 27, 2024, 08:19 AM
it aint possible but is there a workaround for

CreateRadioStream( 15, "Vuelta", "http://redradioypc.com:8048/stream", true );
to

PlaySound( player.UniqueWorld ,radiourl, player.Pos ); // though its for sound ids

something like

PlayAudioStreamForPlayer
i remmember we used to play gta vc and we kill lots of npcs there used to be a police radio like they were talking to each other via radio that we could hear

it would be great if not official but someone comes up with an audio / radio  plugin or something
#20
Well idk how to explain it to you guys and i have no clue about how it happend all i did was quickly shutdown my server due to i was confused of its way of talking and its behaviour

this is irrelevant behaviour felt like it trying to finish everything at once and talking like random shit it was a crazy experience heres something else for u guys

those 3 spookie prompts



well idk if it will happen again but since yesterday and today whole day my server was passworded as i was working on this npc-ai and finally it has an a.i now yet needs to learn more about server, as for the command u can see it what it can do ill also drop a video on its progress.. the server will open by today in evening or perhaps tommorow