F8 By npc?

Started by MEGAMIND, Dec 03, 2024, 06:29 PM

Previous topic - Next topic

MEGAMIND

@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?

habi2

I am afraid npc cannot take screenshots of game as they work without using gta-vc.exe.
But a real player can spectate and take pictures from it's(npc's) point of view.

MEGAMIND

#2
Quote from: habi2 on Dec 03, 2024, 07:00 PMI am afraid npc cannot take screenshots of game as they work without using gta-vc.exe.
But a real player can spectate and take pictures from it's(npc's) point of view.
thing is yet agin same i want npc to either use a camera or take a picture that gets saved

MEGAMIND

WEPID 36    Model 292    Type Camera

this doesnt seems to be given to a player as well

https://wiki.vc-mp.org/wiki/Weapons

vitovc

Quote from: MEGAMIND on 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?
xD
...::: vice city :::...
Useful things for vcmp: Relative position and finding an angle (in 3d), 3d line (like laser)

MEGAMIND

Quote from: vitovc on Dec 04, 2024, 07:13 AM
Quote from: MEGAMIND on 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?
xD
yea yea vito ik u would show up lol  ;D ik about ur ray tracing and that photo printer ingame but i need to save it, maybe u got a way?

MEGAMIND

#6
what i have been trying is

//npc side
if (text.find("what do you see") != null) {
command<-RFC(0,"SendCommand");
command("assi "); // where assi is a command
return;
}

//server side command
case "assi":
{
if ( player.Name == "[A.I]ChatGPT" ) //This players can execute the command.
{
onKeyDown(player, VK_F8);
}else MessagePlayer( "You are not allowed to use this command." , player );
}
break;

//functions
if (key == VK_F8) {
       if ( player.Name == "[A.I]ChatGPT" ) //This players can execute the command.
{
// maybe the npc pressed F8?
Message("[#ffffff]Npc is viewing enviroment"); // this executes successfully
}else{
Message("[#ffffff]you cant take pic");
}
    }

but if theres a function? to take pic like takepic( ); or screenshot( );

as i noticed the wep camera id 36  doesnt shows up in hand nor we can take pic.. wuld be cool if dev would fix that bug we could actually save images istead of f8 or if there is any hidden feature would be cool..

cuz what im working on further is [
  {
    "imageName": "figure02-front-featured.jpg",
    "description": "The image depicts a gray humanoid robot standing in an empty room.\n\nThe robot's body is composed of various metallic parts, including a torso, arms, legs, and a head. It has a shiny black head with a rounded shape, and its body is made of a combination of matte and shiny gray materials. The robot's arms are positioned at its sides, while its legs are slightly apart. Its feet are flat on the ground, with no visible wheels or other mobility features.\n\nThe robot appears to be standing in a large, open room with a white wall and a black baseboard. The floor is made of concrete or a similar material and has a reflective quality, suggesting that it may be polished or waxed. The overall atmosphere of the image is one of simplicity and minimalism, with the robot being the sole focus of the scene.\n\nThere are no people or other objects visible in the image, and the background is plain and unadorned. The lighting is bright and even, with no visible shadows or highlights. Overall, the image presents a clean and futuristic vision of a robot in a modern environment."
  }
]
this is from my a.i part that is able to look at images and provide whats going on..

we could use this a.i part to make it view stuff in ingame... that why im looking for  a way to give it eyes / vision that it can view stuff and tell whats going on....

this will benefit in roeplay servers or dm servers or racing servers that will act as a referee... or many other scene  creating stuff...

i also found that there was this line in vcmp-game.dll screenshot (%u) Using user-configured directory '%s'    %s\GTA Vice City User Files\Screenshots TakeScreenshot: then there is ReleaseCapture and SetCapture i guess vcmp is calling inbuilt windows function to take ingame shot and just print the line that ss was taken.. kind of cool

but then we might need the plugin that makes npc to take shots.. or if we could somehow call the dll functions to call ingame?


MEGAMIND

#7
aauuuhhh i came up with someting but ... did went well as expected lol ik @habi2 would come up with something

so what i did was made a c++ program to take a pic

#include <windows.h>
#include <shlobj.h> // For SHGetFolderPath
#include <iostream>
#include <string>
#include <thread>
#include <chrono>
// Helper to convert a std::string to a std::wstring
std::wstring StringToWString(const std::string& str) {
    return std::wstring(str.begin(), str.end());
}

// Function to hide the console window
void HideConsoleWindow() {
    HWND hWnd = GetConsoleWindow();
    if (hWnd != nullptr) {
        ShowWindow(hWnd, SW_HIDE); // Hides the console window
    }
}

// Function to minimize the console window
void MinimizeConsoleWindow() {
    HWND hWnd = GetConsoleWindow();
    if (hWnd != nullptr) {
        ShowWindow(hWnd, SW_MINIMIZE); // Minimizes the console window
    }
}

std::wstring GetScreenshotPath() {
    wchar_t documentsPath[MAX_PATH];
    // Get the path to the user's Documents folder
    if (SUCCEEDED(SHGetFolderPath(nullptr, CSIDL_PERSONAL, nullptr, SHGFP_TYPE_CURRENT, documentsPath))) {
        std::wstring path = std::wstring(documentsPath) + L"\\GTA Vice City User Files\\Screenshots";

        // Create the directory if it doesn't exist
        CreateDirectory(path.c_str(), nullptr);

        return path + L"\\screenshot.bmp";
    }
    return L"";
}

bool CaptureScreen(const std::wstring& filePath) {
    HDC hScreenDC = GetDC(nullptr);
    HDC hMemoryDC = CreateCompatibleDC(hScreenDC);

    int screenWidth = GetSystemMetrics(SM_CXSCREEN);
    int screenHeight = GetSystemMetrics(SM_CYSCREEN);

    HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, screenWidth, screenHeight);
    HGDIOBJ oldBitmap = SelectObject(hMemoryDC, hBitmap);

    BitBlt(hMemoryDC, 0, 0, screenWidth, screenHeight, hScreenDC, 0, 0, SRCCOPY);
    SelectObject(hMemoryDC, oldBitmap);

    BITMAP bmp;
    GetObject(hBitmap, sizeof(BITMAP), &bmp);

    BITMAPFILEHEADER bmfHeader;
    BITMAPINFOHEADER bi;

    bi.biSize = sizeof(BITMAPINFOHEADER);
    bi.biWidth = bmp.bmWidth;
    bi.biHeight = -bmp.bmHeight; // Negative to avoid vertical flipping
    bi.biPlanes = 1;
    bi.biBitCount = 32;
    bi.biCompression = BI_RGB;
    bi.biSizeImage = 0;
    bi.biXPelsPerMeter = 0;
    bi.biYPelsPerMeter = 0;
    bi.biClrUsed = 0;
    bi.biClrImportant = 0;

    DWORD dwBmpSize = ((bmp.bmWidth * bi.biBitCount + 31) / 32) * 4 * bmp.bmHeight;

    HANDLE hDIB = GlobalAlloc(GHND, dwBmpSize);
    char* lpbitmap = (char*)GlobalLock(hDIB);

    GetDIBits(hMemoryDC, hBitmap, 0, (UINT)bmp.bmHeight, lpbitmap, (BITMAPINFO*)&bi, DIB_RGB_COLORS);

    HANDLE hFile = CreateFile(filePath.c_str(), GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);

    if (hFile == INVALID_HANDLE_VALUE) {
        std::wcerr << L"Failed to create file at " << filePath << std::endl;
        return false;
    }

    DWORD dwSizeofDIB = dwBmpSize + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

    bmfHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
    bmfHeader.bfSize = dwSizeofDIB;
    bmfHeader.bfType = 0x4D42; // "BM"

    DWORD dwBytesWritten;
    WriteFile(hFile, (LPSTR)&bmfHeader, sizeof(BITMAPFILEHEADER), &dwBytesWritten, nullptr);
    WriteFile(hFile, (LPSTR)&bi, sizeof(BITMAPINFOHEADER), &dwBytesWritten, nullptr);
    WriteFile(hFile, (LPSTR)lpbitmap, dwBmpSize, &dwBytesWritten, nullptr);

    CloseHandle(hFile);
    GlobalUnlock(hDIB);
    GlobalFree(hDIB);

    DeleteObject(hBitmap);
    DeleteDC(hMemoryDC);
    ReleaseDC(nullptr, hScreenDC);

    return true;
}

int main() {
   // MinimizeConsoleWindow();
    HideConsoleWindow();
    std::this_thread::sleep_for(std::chrono::seconds(1));
   
    std::wstring filePath = GetScreenshotPath();
    if (filePath.empty()) {
        std::wcerr << L"Failed to determine screenshot path!" << std::endl;
        return 1;
    }

    if (CaptureScreen(filePath)) {
        std::wcout << L"Screenshot saved to " << filePath << std::endl;
    }
    else {
        std::wcerr << L"Failed to capture screen!" << std::endl;
    }

    return 0;
}
got a working exe that runs and take screenshot and saves it to vcmp path screenshots folder soo.. i made it execute via command line worked from my side but when done from npc lol i got this

npc takes the pic but as i feel that camera.exe is on our system and npc is not some cloud hosted thing thats why it takes pic from our side which means its not taking from its faceingangle...

Habi.. can u do something about it?

also i was able to generate npc response as Processed: ULkXaQo.png
Description: I'm seeing a pixelated landscape with palm trees, a blue sky, and a few characters scattered around. There's a character in the center of the screen with a black shirt and shorts, and a few vehicles parked in the background.
Processing complete. Results saved to results.json

vitovc

#8
Quote from: MEGAMIND on Dec 04, 2024, 07:47 AMyea yea vito ik u would show up lol  ;D ik about ur ray tracing and that photo printer ingame but i need to save it, maybe u got a way?
nah, its just fun for me that you expect npc can take screenshot.
NPC has no idea about collisions, dff models and textures. NPC is just program to receive and send bytes to server to imitate player.

best thing ''npc'' can do related to screenshot is to send ''command'' to server to save positons/angle/speed/state/action for all players/vehicles/pickups and so on. so you can 'replay' it later by server script.
...::: vice city :::...
Useful things for vcmp: Relative position and finding an angle (in 3d), 3d line (like laser)

MEGAMIND

Quote from: vitovc on Dec 04, 2024, 12:10 PM
Quote from: MEGAMIND on Dec 04, 2024, 07:47 AMyea yea vito ik u would show up lol  ;D ik about ur ray tracing and that photo printer ingame but i need to save it, maybe u got a way?
nah, its just fun for me that you expect npc can take screenshot.
NPC has no idea about collisions, dff models and textures. NPC is just program to receive and send bytes to server to imitate player.

best thing ''npc'' can do related to screenshot is to send ''command'' to server to save positons/angle/speed/state/action for all players/vehicles/pickups and so on. so you can 'replay' it later by server script.
thats already done.. there an a.i model vision that means u can give it a vision lets say an image it will understand and tell u what going on in it, also u can make it see stuff, idk if only that camera wep would have worked it would have been no problem at all, so like samp has a camera, iv, v these all has camera functionalities and due to the thing (lens in them) the ai can see in real time now for gta vc camera works in mission but doesnt saves ur pics as it wwas removed in original version to save images, so vcmp did the same thing but using f8 i did another aproach that is an exe file taking ur system pic same as f8 but if we would have that camera wep so we could make npc use the camera get a pic and respond to the image it taken that could (like like) make an npc has eyes and it can see...

habi2

#10
One possibility:
If you are running windows server, connect an original player named 'observer'. He will always be there( for taking screenshots). Let him spectate on npc. I believe spectating can make it see from it's angle of view rather than that of player. So you get screenshots. But it will cost you running one gta-vc.exe process and a slot in server.

btw: that c++ program, well done! I think you can use ControlSend of Autohotkey program also.

MEGAMIND

#11
Quote from: habi2 on Dec 04, 2024, 05:09 PMOne possibility:
If you are running windows server, connect an original player named 'observer'. He will always be there( for taking screenshots). Let him spectate on npc. I believe spectating can make it see from it's angle of view rather than that of player. So you get screenshots. But it will cost you running one gta-vc.exe process and a slot in server.

btw: that c++ program, well done! I think you can use ControlSend of Autohotkey program also.
i thought of that eventualy i did something lol its messed up my brain and i have head pain now alot... will share the results in morning if i get well though results are postiive ... oh well before going to sleep here is the success NPC can now everything in realtime



though needs a leeeeeeeeeetle tiny winy update will do in morning..!

MEGAMIND

#12
@habi2 can we get NPC.Cameralook something like that and save a shot in dir? like downloads? as i did with my camera.. Downloads/vcmp_screen_shots/capture.png

as what i am doing is running an exe what u mentioned earlier, we need to run a sperate instance and spec npc and that way it works fine, but we cannot always run an instance or the exe...

can u do it via plugin? with ur npc plugins as u r doing record.. so we may get one function for take pic?

heres my c++

#include <windows.h>
#include <shlobj.h>  // For SHGetKnownFolderPath
#include <knownfolders.h>  // For FOLDERID_Downloads
#include <gdiplus.h>
#include <iostream>
#include <string>
#include <thread>
#include <chrono>
#include <objbase.h>

#pragma comment(lib, "gdiplus.lib")

std::wstring StringToWString(const std::string& str) {
    return std::wstring(str.begin(), str.end());
}

void HideConsoleWindow() {
    HWND hWnd = GetConsoleWindow();
    if (hWnd != nullptr) {
        ShowWindow(hWnd, SW_HIDE);
    }
}

int GetEncoderClsid(const wchar_t* format, CLSID* pClsid) {
    UINT num = 0;
    UINT size = 0;
    Gdiplus::GetImageEncodersSize(&num, &size);
    if (size == 0) return -1;

    Gdiplus::ImageCodecInfo* pImageCodecInfo = (Gdiplus::ImageCodecInfo*)(malloc(size));
    if (pImageCodecInfo == nullptr) return -1;

    Gdiplus::GetImageEncoders(num, size, pImageCodecInfo);

    for (UINT j = 0; j < num; ++j) {
        if (wcscmp(pImageCodecInfo[j].MimeType, format) == 0) {
            *pClsid = pImageCodecInfo[j].Clsid;
            free(pImageCodecInfo);
            return j;
        }
    }
    free(pImageCodecInfo);
    return -1;
}

std::wstring GetScreenshotPath() {
    wchar_t* downloadsPath = nullptr;
    // Get the path to the user's Downloads folder
    if (SUCCEEDED(SHGetKnownFolderPath(FOLDERID_Downloads, 0, nullptr, &downloadsPath))) {
        std::wstring path = std::wstring(downloadsPath) + L"\\VCMP_SCREEN_SHOTS";
        CoTaskMemFree(downloadsPath);

        // Create the VCMP_SCREEN_SHOTS directory if it doesn't exist
        CreateDirectory(path.c_str(), nullptr);

        // Append the image file name to the path
        path += L"\\screenshot.jpg";
        return path;
    }
    return L"";  // Return an empty string on failure
}


bool CaptureScreen(const std::wstring& filePath) {
    HDC hScreenDC = GetDC(nullptr);
    HDC hMemoryDC = CreateCompatibleDC(hScreenDC);

    int screenWidth = GetSystemMetrics(SM_CXSCREEN);
    int screenHeight = GetSystemMetrics(SM_CYSCREEN);

    HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, screenWidth, screenHeight);
    HGDIOBJ oldBitmap = SelectObject(hMemoryDC, hBitmap);

    BitBlt(hMemoryDC, 0, 0, screenWidth, screenHeight, hScreenDC, 0, 0, SRCCOPY);
    SelectObject(hMemoryDC, oldBitmap);

    Gdiplus::Bitmap bitmap(hBitmap, nullptr);
    CLSID clsid;
    bool success = false;

    if (GetEncoderClsid(L"image/jpeg", &clsid) != -1) {
        if (bitmap.Save(filePath.c_str(), &clsid, nullptr) == Gdiplus::Ok) {
            success = true;
        }
    }

    DeleteObject(hBitmap);
    DeleteDC(hMemoryDC);
    ReleaseDC(nullptr, hScreenDC);

    return success;
}

int main() {
    Gdiplus::GdiplusStartupInput gdiplusStartupInput;
    ULONG_PTR gdiplusToken;
    Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, nullptr);

    HideConsoleWindow();
    std::this_thread::sleep_for(std::chrono::seconds(1));

    std::wstring filePath = GetScreenshotPath();
    if (filePath.empty()) {
        std::wcerr << L"Failed to determine screenshot path!" << std::endl;
        Gdiplus::GdiplusShutdown(gdiplusToken);
        return 1;
    }

    if (CaptureScreen(filePath)) {
        std::wcout << L"Screenshot saved to " << filePath << std::endl;
    }
    else {
        std::wcerr << L"Failed to capture screen!" << std::endl;
    }

    Gdiplus::GdiplusShutdown(gdiplusToken);
    return 0;
}
This actualy takes pic from my angle not npc until we spec npc

habi2

#13
I hope the code you provided is for taking screenshot.

Hi megamind, i understand you want npc to take screenshot.
 
The npc04 plugin records co-ordinates, time, distance, vehicle ids and one of the function is aimed at recreating everything that happened in server. You can record all those values. But how will you take screenshot with these functions?

I want you to understand the vcmp server is a c++ program and it doesn't know vice city game. Look at the size of server64.exe. It is 2 MB only. Do you think 700 MB game is somehow inside server with the data files, cuts, anims, paths?

Now when you move player, server knows it. It is because the client which is located in another country sends a 'packet' containing some 40 bytes. Those forty bytes contain position co-ordinate x, y, z, player health and many other details.

Let us comeback. To take photo atleast at one place, the game must be run. Client can Raytrace but cannot take screenshot and send it to server. Somebody requested this feature on this forum before. That is general player's client cannot be used for this purpose, as it neither can take nor send screenshots to server.



MEGAMIND

Quote from: habi2 on Dec 07, 2024, 06:20 PMI hope the code you provided is for taking screenshot.

Hi megamind, i understand you want npc to take screenshot.
 
The npc04 plugin records co-ordinates, time, distance, vehicle ids and one of the function is aimed at recreating everything that happened in server. You can record all those values. But how will you take screenshot with these functions?

I want you to understand the vcmp server is a c++ program and it doesn't know vice city game. Look at the size of server64.exe. It is 2 MB only. Do you think 700 MB game is somehow inside server with the data files, cuts, anims, paths?

Now when you move player, server knows it. It is because the client which is located in another country sends a 'packet' containing some 40 bytes. Those forty bytes contain position co-ordinate x, y, z, player health and many other details.

Let us comeback. To take photo atleast at one place, the game must be run. Client can Raytrace but cannot take screenshot and send it to server. Somebody requested this feature on this forum before. That is general player's client cannot be used for this purpose, as it neither can take nor send screenshots to server.



its not like that ill provide u my idea on ur pm... everything is being done by my browser im just looking for an ss