Making npcs shoot x y z

Started by habi, Nov 05, 2022, 08:02 PM

Previous topic - Next topic

habi

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:
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);
or
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.
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.
//NPCFunctions.cpp

//05-Nov-22
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);
    //Position
    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);

    //Speed
    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;
   
    SendNPCSyncData(&m_pOfSyncData);
    return 0;//0 because we are returning nothing!
}
//In function RegisterNPCFunctions
register_global_func(v, ::fn_SendOnFootSyncData, "SendOnFootSyncData", 18, "tiffffiiifffffffff");

//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.

Sebastian

#1
This is cool!
A nice add-on!

Ps: Is it possible to have a function,  server-side,  which updates a npc's angle?
I remember it existed in the first version of the plugin

habi

Yes.
Like we use streams to pass data, 'ClientMessage' function of server side can be used.

//Let's choose a number, say 100. And suppose we want to place player to angle 0.57;
ClientMessage("SetMyFacingAngle( 0.57 );", npc, 100, 100, 100 );

And on npc script,
function OnClientMessage(r,g,b,message)
{
if(r==100 && g==100 && b== 100)
{
local script = compilestring(message );
script();
}
}

This will make the npc change its angle!

Sebastian

Oh,  I see.  Cool!  Thanks!