New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
More weapon slots #56
Comments
Slots 0, 9, 10, and 11 are good for sentinel checks (you need three, two for normal use, and a third for when they are actually holding a weapon from a sentinel slot). |
So if I understand correctly, this could be used to easily add custom weapons or even change the order of a player's weapons? |
Custom weapons would be harder (I think, not sure how to do that but I have heard of it being done). It would be for changing weapon order, yes, and for allowing more weapons to (appear to) be held. So instead of just having EITHER an AK47 OR an M4 (because they share a slot, and you can only have one weapon per slot), you could have both at once. You can't actually give a player both, but with this you detect when they change which weapon they are holding and switch that out for the correct one. |
Yes, that's what I meant. And by custom weapons I mean like having two M4's but calling one something different and making it have different stats. This detection could make that pretty simple. |
Given that this include already handles the alternate stats - yes. |
Well, I assume so, I've not actually read the code, this was just a suggestion for all weapons, but I don't see any theoretical reason why it can't be used for more than all weapons. |
From my understanding, the basic idea is a system as represented in GTA:V. But in theory it can be used for more explicit things as I suggested, custom weapons. Ok, so we would need an array to store each player's weapons and a weapon change detector. For external use we could also add a callback to be called when a player changes weapons, it would send the player ID and the direction of the change (this could be used in other includes and such for custom weapons and such). By default when the weapon change is detected the array would be tested for valid weapons to the left or right respectively, if the weapon is valid change to it, if not loop to the first or last index, respectively. If there are no valid weapons simply give back the fist. Right? I might take the time out to do this myself... xD |
I don't know about ordering. Going by order given doesn't make much sense, because that ends up quite random if they are getting weapons by various means through a play session. Ordering by slot/id is better, but becomes slightly non-deterministic when multiple variants of the same weapon are involved. I would think that the simplest order would be to use the order the developer defines the weapons in. |
So purely by fluke, I was going through some really old folders, trying to clean up my hard disk a little bit, and came across this: /*enum E_Y_WEAPONS_DATA
{
E_Y_WEAPONS_DATA_NEXT
E_Y_WEAPONS_DATA_LAST
E_Y_WEAPONS_DATA_SLOT
E_Y_WEAPONS_DATA_NEXT
}*/
static stock const
YSI_g_scWeaponSlots[] =
{
0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
10, 10, 10, 10, 10, 10, 8, 8, 8, 2,
2, 2, 3, 3, 3, 4, 4, 5, 5, 4,
6, 6, 7, 7, 7, 7, 8, 12, 9, 9,
9, 11, 11, 11
};
// Store the ammo, -1 means does not have.
static stock
YSI_g_sWeapons[MAX_PLAYERS][47 - 3],
YSI_g_sSlots[MAX_PLAYERS],
YSI_g_sCurrentSet[MAX_PLAYERS][13],
PlayerArray:YSI_g_sHasConflict<MAX_PLAYERS>,
PlayerArray:YSI_g_sHasExtras<MAX_PLAYERS>;
hook OnPlayerConnect(playerid)
{
// Always have fists.
YSI_g_sSlots = 1;
// Have no other weapons though.
for (new i = 0; i != sizeof (YSI_g_sWeapons[]); ++i)
{
YSI_g_sWeapons[playerid][i] = -1;
}
for (new i = 0; i != sizeof (YSI_g_sCurrentSet[]); ++i)
{
YSI_g_sCurrentSet[playerid][i] = 0;
}
}
static stock Weapon_CountSlots(playerid)
{
new
count = 0,
slots = YSI_g_sSlots[playerid];
for (new j = 1; j != (1 << 13); j <<= 1)
{
if (slots & j)
{
++count;
}
}
return count;
}
static stock Weapon_DoRemove(playerid, weaponid)
{
new
w[13],
a[13];
// Get existing weapons (minus one).
for (new i = 0; i != 13; ++i)
{
GetPlayerWeaponData(playerid, i, w[i], a[i]);
if (w[i] == weaponid)
{
w[i] = 0;
}
}
// Get the current weapon and reset all.
new
s = GetPlayerWeapon(playerid);
ResetPlayerWeapons(playerid);
// Restore all weapons except the removed one.
for (new i = 0; i != 13; ++i)
{
if (w[i])
{
GivePlayerWeapon(playerid, w[i], a[i]);
}
}
if (s != weaponid)
{
SetPlayerArmedWeapon(playerid, s);
}
return 1;
}
static stock Weapon_CheckExtra(playerid)
{
// Check if we need (or no longer need) extra weapons to detect multiple
// weapons in the same slot while not having enough weapons naturally to do
// it cleanly.
if (PA_Get(YSI_g_sHasExtras, playerid))
{
// Has extras already - do we still need them.
new
count = 0,
slots = YSI_g_sSlots[playerid],
w[13],
a[13];
// Get existing weapons (minus one).
for (new i = 0, j = 1; i != 13; ++i, j <<= 1)
{
if (slots & j)
{
GetPlayerWeaponData(playerid, i, w[i], a[i]);
++count;
}
}
if (count < 3)
{
}
else
{
// No longer need extras.
if (
}
}
else
{
}
return 1;
}
static stock Weapon_DoGive(playerid, weaponid, id, ammo)
{
ammo = max(ammo, 0);
if (weaponid == WEAPON_SATCHEL)
{
// VERY special case - give them two weapons, neither of which are in
// shared slots. This means that a) we never need to check for slot
// conflicts and b) we don't need to check if we need extra hidden
// weapons to detect changing slots because there will be at least 3
// slots in use (so remove any extra weapons they may have).
if (PA_Get(YSI_g_sHasConflict, playerid))
{
// Has a conflict.
if (PA_Get(YSI_g_sHasExtras, playerid))
{
// Has extra weapons to make up the difference.
PA_Vet(YSI_g_sHasExtras, playerid);
if (YSI_g_sSlots[playerid] & (1 << 10))
{
Weapon_DoRemove(playerid, WEAPON_FLOWER);
}
else
{
Weapon_DoRemove(playerid, WEAPON_FLOWER);
}
}
}
return 1;
}
new
slot = YSI_g_scWeaponSlots[id];
if (YSI_g_sWeapons[playerid][id] == -1)
{
// Don't already have this weapon.
YSI_g_sWeapons[playerid][id] = ammo;
if (YSI_g_sSlots[playerid] & (1 << slot))
{
// Already have a different weapon in this slot.
PA_Let(YSI_g_sHasConflict, playerid);
// Now we need to work out if we need extra fake slots.
if (Weapon_CountSlots(playerid) < 3)
{
// We need at least three slots for this to work to detect when
// the player changes weapon in one direction or the other. One
// of these will always be slot 0, as that can never be empty.
// The other COULD be slot 10 or 12, but never both.
if (YSI_g_sSlots[playerid] & (1 << 10))
{
// Give them the detonator (they will have no satchels).
}
else
{
//
}
}
}
else
{
// Don't already have a weapon in this slot - just give them it.
GivePlayerWeapon(playerid, weaponid, ammo);
YSI_g_sCurrentSet[playerid][slot] = weaponid;
}
}
else
{
YSI_g_sWeapons[playerid][id] += ammo;
if (YSI_g_sCurrentSet[playerid][slot] == weaponid)
{
// They are currently holding the weapon, give them more ammo.
GivePlayerWeapon(playerid, weaponid, ammo);
}
// Now we need to work out if we no longer need extra fake slots.
}
// Make sure we know there is a weapon in this slot.
YSI_g_scWeaponSlots[id] |= (1 << slot);
return 1;
}
stock Weapon_Give(playerid, weaponid, ammo)
{
if (0 <= weaponid <= 18)
{
Weapon_DoGive(playerid, weaponid, weaponid, ammo);
}
else if (22 <= weaponid <= 46)
{
Weapon_DoGive(playerid, weaponid, weaponid - 3, ammo);
}
} |
This is something I thought of and mostly wrote years ago, but never released and subsequently lost. I realised that it was quite simple to bypass the weapon slot limit in the same way as I do classes in y_classes - just have three.
Say player is holding a weapon in slot 7, you give them another weapon from (say) slots 6 and 8 (in reality, fists and camera, or other mostly non-deadly weapons will be best). When you detect that they switched to the weapon in slot 6, you know that they changed weapons down, and you can give and arm the correct weapon. If they switch to the weapon in slot 8, they changed up, and again you give them the new weapon accordingly. That next weapon could be a different slot 7 weapon, or any other weapon at all. Just make sure that the sentinel weapons are also updated if required (e.g. giving them an actual slot 6 weapon will prevent the use of slot 6 for detecting a change).
You could get very clever and make those sentinel weapons ones they actually own, or make it so that instead of cycling through all weapons in one slot before moving on to the next slot, you cycle through one of each entirely before moving on to the next ones - would be harder to code, but would lead to less flickering.
The text was updated successfully, but these errors were encountered: