Loot and object destroying problem
#1

Hello SA-MP community,

Im trying to make a loot system with mapping certain objects such as the M4A1 in a place and when people press the C (or KEY_CROUCH) button they pick up the item that is near them.

The only thing that is going wrong is that the object is not being destroyed after i picked up (picking it up works etc), its being add to my inventory and i get the message that it has been added. so my question is: how do i make it so once the player picked it up the loot object gets destroyed? and also so the is player in range of point gets disabled when the player looted it by pressing the coruch button ©.

(i get no erros by the way)

pawn Код:
public OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
{
    if (newkeys & KEY_WALK)
    {
        ShowInventory(playerid);
        return 1;
    }
    if (KEY_CROUCH & oldkeys)
    {
        if(IsPlayerInRangeOfPoint(playerid, 1.0, 2384.59448, -1674.36279, 13.74557)) //co ords of where the M4A1 loot is located
        {
            AddItem(playerid,"M4A1",1);
            SendClientMessage(playerid, COLOR_GREEN, "* 1 M4A1 has been added to your inventory");
            DestroyObject(356); //the M4A1 object ID
        }
        else
        {
            return 1;
        }
    }
    return 1;
}
Thank you for your time!
Reply
#2

Hardcoding object ID isn't a good idea. Do something like
pawn Код:
static
    LootObjects[MAX_LOOTS] = { INVALID_OBJECT_ID, ... };

//when creating
LootObjects[0] = CreateObject(...);

//Then deleting
DestroyObject(LootObjects[0]);
Also, search on this forum for streamer. It'll save you some problems in future
Reply
#3

Could you make an example of the code you just gave me with the M4A1 and where to put it please? im fairly new to scripting so if you could do that it would mean allot to me ! thanks.
Reply
#4

All right. So, let's say you permit single loot item per dying player (just to simplyfy).

Outside of any function, somewhere near top of your file put this - it will declare array (static keyword will make it "visible" only in file you're looking at, not in includes) of MAX_LOOTS size, with initial values in each field equal INVALID_OBJECT_ID.
pawn Код:
#define MAX_LOOTS 30
static
    LootObjects[MAX_LOOTS] = { INVALID_OBJECT_ID, ... };
Somewhere you are creating the object:
pawn Код:
public OnGamemodeIni()
{
//(...)
    LootObjects[0] = CreateObject(356, X, Y, Z, rX, rY, rZ);
//(...)
}
And then when crouching

pawn Код:
DestroyObject(LootObjects[0]);
Add more objects just changing the [0] to next numbers
Reply
#5

Sorry for the late response, and thanks allot !
Reply
#6

Wait im getting this error:

pawn Код:
(77) : error 017: undefined symbol "INVALID_OBJECT_ID"
with this code

pawn Код:
static LootObjects[MAX_LOOTS] = { INVALID_OBJECT_ID, ... };
Reply
#7

A good loot system is much more complex than this.
Reply
#8

Yeah i could inmagin that but as i said before im still learning pawno, anyway so what do i do for this error message?
Reply
#9

Solved.
Reply
#10

I would honestly start to learn the basics of dynamic system design first before attempting a loot system the good thing is the basic concept is applicable to almost everything you need to do in SAMP. This happens every time we try to deal with multiples of similar game elements such as objects, players, areas etc a loot system falls into this category as well so we need to use a common technique to handle and cross integrate these elements and this is where the basic dynamic system design comes into play I will make a example just for you.

pawn Код:
// Hearts - simple dynamic system concept
// Create and delete hearts

#include <a_samp>

// We'll use ZCMD
#include <zcmd>

// We always need to define how many elements a dynamic system contains
#define         MAX_HEARTS          1000

// Heart object for this dynamic system
#define         HEART_OBJECT        1240

// The drawdistance for hearts
#define         HEART_DRAW_DIST     150.0

// This is a bounds checking macro to make sure that referenced array elements are not out of bounds
#define HeartBounds(%0,%1); \
    if(%0 < 0 || %0 > MAX_HEARTS) \
    { \
        print(%1); \
        return 0; \
    }

// We need to define an enum which is basically the structure of the values that will be saved in the dynamic system
enum HEARTINFO
{
    HeartObject,
    Float:xPos,
    Float:yPos,
    Float:zPos,
}

// Create a new variable to store the heart information
new HeartData[MAX_HEARTS][HEARTINFO];

// When any dynamic system initializes we need to set any required default values in this case it is the heartobject which
// determines if the dynamic element exists
public OnFilterScriptInit()
{
    // Loop through each element
    for(new i = 0; i < MAX_HEARTS; i++)
    {
        // This marks the element as unused
        HeartData[i][HeartObject] = INVALID_OBJECT_ID;
    }
    return 1;
}

// Destroy any created hearts
public OnFilterScriptExit()
{
    for(new i = 0; i < MAX_HEARTS; i++)
    {
        if(HeartData[i][HeartObject] != INVALID_OBJECT_ID) DestroyObject(HeartData[i][HeartObject]);
    }
    return 1;

}

// Add a new heart
stock AddHeart(Float:x, Float:y, Float:z)
{
    // Loop through hearts for a free slot
    for(new i = 0; i < MAX_HEARTS; i++)
    {
        // Slot was not free continue
        if(HeartData[i][HeartObject] != INVALID_OBJECT_ID) continue;

        // We have a free slot create the new heart element
        HeartData[i][HeartObject] = CreateObject(HEART_OBJECT, x, y, z, 0.0, 0.0, 0.0, HEART_DRAW_DIST);

        // Set any additional data
        HeartData[i][xPos] = x;
        HeartData[i][yPos] = y;
        HeartData[i][zPos] = z;
       
        // Return the id of the heart that was created
        return HeartData[i][HeartObject];
    }
    // There are too many hearts
    print("ERROR: Tried to add too many hearts");
    return INVALID_OBJECT_ID;
}

// Remove a heart
stock RemoveHeart(hid)
{
    // Check the bounds to make sure they are valid
    HeartBounds(hid, "Bounds error: RemoveHeart");
   
    // Does the heart exist?
    if(HeartData[hid][HeartObject] != INVALID_OBJECT_ID)
    {
        // Destroy heart
        DestroyObject(HeartData[hid][HeartObject]);

        // We only need to reset the heart objectid this element can now be re-used
        HeartData[hid][HeartObject] = INVALID_OBJECT_ID;
        return 1;
    }
    // Return 0 heart did not exist
    return 0;
}

// Command for adding a heart
CMD:addheart(playerid, arg[])
{
    // Get the players position
    new Float:x, Float:y, Float:z;
    GetPlayerPos(playerid, x, y, z);
        // Z-Offset
    z += 2.0;
   
    // Adding the heart was not success
    if(AddHeart(x, y, z) == -1) return SendClientMessage(playerid, 0xFF0000FF, "There are too many hearts");

    // Successfully added!
    SendClientMessage(playerid, -1, "Added a new heart!");
    return 1;
}

// Remove heart
CMD:removeheart(playerid, arg[])
{
    // Remove was successful
    if(RemoveHeart(strval(arg))) return SendClientMessage(playerid, -1, "Heart Removed");
    // That heart does not exist!
    SendClientMessage(playerid, -1, "Heart does not exist");
    return 1;
}

// Checks if the player is near a heart
CMD:nearheart(playerid, arg[])
{
    // Count how many hearts the player is near
    new heartcount;

    // Loop throuugh hearts
    for(new i = 0; i < MAX_HEARTS; i++)
    {
        // Heart does not exist
        if(HeartData[i][HeartObject] == INVALID_OBJECT_ID) continue;

        // Player was in range of a heart increment the heart count
        if(IsPlayerInRangeOfPoint(playerid, 5.0, HeartData[i][xPos], HeartData[i][yPos], HeartData[i][zPos])) heartcount++;
    }

    // There were hearts found show the player how many
    if(heartcount)
    {
        new line[128];
        format(line, sizeof(line), "You are near %i hearts!", heartcount);
        SendClientMessage(playerid, -1, line);
    }
    else SendClientMessage(playerid, 0xFF0000FF, "You are not near any hearts!");
   
    return 1;
}
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)