Roll20 uses cookies to improve your experience on our site. Cookies enable you to enjoy certain features, social sharing functionality, and tailor message and display ads to your interests on our site and others. They also help us understand how our site is being used. By continuing to use our site, you consent to our use of cookies. Update your cookie preferences .
×
Create a free account

Ammunition Tracker adding ammo dispensing commands

January 01 (9 years ago)
Hi there, 

So I've just recently become a pro member, and have started to dabble a little bit with API's and I've come over a great addition to my Deathwatch campaign. Namely Tristan's Ammunition Tracker. However I have come to get slightly annoyed at the endless chat spam of ammo being dispensed for Semi-auto, and full-auto weapons in this game system. Hence I decided to try to add a few commands for multi-bullet dispensing (In this stated example this will be 3 bullets)
Now I have to admit it has been quite some time since I've done anything with scripting so I just figured adding a new command with the previous structure laid out for me by Tristan would do the trick. So I've added a bit of string which goes a little something like this: 

else if (msg.type == "api" && msg.content.indexOf("!bullets3") !== -3)
//This will unload all of the arrays, put them through the process of firing and finally re-package them again
{
var mainstring = msg.content.split(/\s+/);
var slotlocator = parseInt(mainstring[1])
var unloader = state.bullet.slotarray.indexOf(slotlocator)
log(slotlocator)
log(unloader)
if (state.bullet.slotarray[unloader] == null)
{
sendChat("Ammunition tracker", "/w " + msg.who + " This slot seems to be empty...")
}
else if(state.bullet.ownershiparray[unloader] != msg.who)
{
sendChat("Ammunition tracker", "/w " + msg.who + " This slot is owned by " + state.bullet.ownershiparray[unloader])
}
else
{
state.bullet.bulletarray[unloader]--;
log(msg.who + " uses 3 units of ammunition from their " + state.bullet.namearray[unloader] + ", they now have " + state.bullet.bulletarray[unloader] + " units of ammunition remaining!")
sendChat("Ammunition tracker", "/w " + msg.who + " you use 3 units of ammo, and now have " + state.bullet.bulletarray[unloader] + " remaining!")
}
}
 


However after adding this bit of code to the previous document, it does seem to get activated. However once I go into my game folder and try to set up my players weapon/ammo profiles, I just keep on getting the following message: (From Ammunition tracker):(GM) This slot seems to be empty..

The API output console has also given me null and -1,1,2 lines.

For whats it worth here's what I did to the entire API script as taken from Tristan B. I hope someone is able to guide me towards finding a way to add commands for multiple ammo unit expenditures so hopefully other folks will be able to use these commands as well in future games especially those that hold weapons with different firing solutions (Single /Semi-auto / Full-Auto.

if( !_.has(state,'bullet') )
{
state.bullet= {
bulletarray: [],
namearray: [],
slotarray: [],
ownershiparray: []}
}
on("chat:message", function(msg)
{
if(msg.type == "api" && msg.content.indexOf("!bullets ") !== -1)
//This will unload all of the arrays, put them through the process of firing and finally re-package them again
{
var mainstring = msg.content.split(/\s+/);
var slotlocator = parseInt(mainstring[1])
var unloader = state.bullet.slotarray.indexOf(slotlocator)
log(slotlocator)
log(unloader)
if (state.bullet.slotarray[unloader] == null)
{
sendChat("Ammunition tracker", "/w " + msg.who + " This slot seems to be empty...")
}
else if(state.bullet.ownershiparray[unloader] != msg.who)
{
sendChat("Ammunition tracker", "/w " + msg.who + " This slot is owned by " + state.bullet.ownershiparray[unloader])
}
else
{
state.bullet.bulletarray[unloader]--;
log(msg.who + " uses one unit of ammunition from their " + state.bullet.namearray[unloader] + ", they now have " + state.bullet.bulletarray[unloader] + " units of ammunition remaining!")
sendChat("Ammunition tracker", "/w " + msg.who + " you use one unit of ammo, and now have " + state.bullet.bulletarray[unloader] + " remaining!")
}
}
else if (msg.type == "api" && msg.content.indexOf("!bullets3") !== -3)
//This will unload all of the arrays, put them through the process of firing and finally re-package them again
{
var mainstring = msg.content.split(/\s+/);
var slotlocator = parseInt(mainstring[1])
var unloader = state.bullet.slotarray.indexOf(slotlocator)
log(slotlocator)
log(unloader)
if (state.bullet.slotarray[unloader] == null)
{
sendChat("Ammunition tracker", "/w " + msg.who + " This slot seems to be empty...")
}
else if(state.bullet.ownershiparray[unloader] != msg.who)
{
sendChat("Ammunition tracker", "/w " + msg.who + " This slot is owned by " + state.bullet.ownershiparray[unloader])
}
else
{
state.bullet.bulletarray[unloader]--;
log(msg.who + " uses 3 units of ammunition from their " + state.bullet.namearray[unloader] + ", they now have " + state.bullet.bulletarray[unloader] + " units of ammunition remaining!")
sendChat("Ammunition tracker", "/w " + msg.who + " you use 3 units of ammo, and now have " + state.bullet.bulletarray[unloader] + " remaining!")
}
}
else if (msg.type == "api" && msg.content.indexOf("!btedit ") !== -1)
{
var splitt = msg.content.split(/\s+/), slotselected = splitt[1];
if (splitt[1] != null)
{
slotselected = parseInt(slotselected);
var newbullets = parseInt(splitt[2]);
if (newbullets != null)
{
var checkforslots = parseInt(splitt[1]);
checkforslots = state.bullet.slotarray.indexOf(slotselected);
if (checkforslots != -1)
{
state.bullet.bulletarray[checkforslots] = newbullets;
sendChat("Ammunition Tracker", "/w " + msg.who + "The weapon now has " + newbullets + " units of ammunition!");
}
else
{
sendChat("Ammunition Tracker", "/w " + msg.who + "Slot " + splitt[1] + " is currently empty");
log(splitt[1])
}
}
else
{
sendChat("Ammunition Tracker", "/w " + msg.who + "You must enter a new ammunition value for the slot!")
}
}
else
{
sendChat("Ammunition Tracker", "You must enter a slot number!")
}
}
else if (msg.type == "api" && msg.content == "!btmyslots")
{
var counter;
for (counter = 0; state.bullet.slotarray[counter] != null; counter++)
{
if (state.bullet.ownershiparray[counter] == msg.who)
{
sendChat("Ammunition Tracker", "/w " + msg.who + "Slot " + state.bullet.slotarray[counter] + ", " + state.bullet.namearray[counter] + ", " + state.bullet.bulletarray[counter] + " units of ammunition")
}
}
}
else if (msg.type == "api" && msg.content == "!bthelp")
{
var messagesent = msg.content.replace("!bthelp", "")
sendChat("Ammunition tracker", "/w " + msg.who + " Hello! This is the help message! To declare a new weapon type use !setgun *SLOT* *WEAPON_NAME* *AMMUNITION*. There can be no spaces. If a slot is occupied by another player, you will not be able to use that slot. Whenever you fire, type !bullets *SLOT*.Use !btdel *SLOT* to delete a slot.Use !btedit *SLOT* *NEW_AMMO_VALUE to edit the ammunition of a weapon. It is 100% necessary to have slots correctly written. ENJOY!")
}
else if (msg.type == "api" && msg.content.indexOf("!btdel ") !== -1)
{
splitthestring = msg.content.split(/\s+/);
var theslotselected = splitthestring[1];
var parsedslot = parseInt(splitthestring[1])
log(parsedslot);
var indexedslot = state.bullet.slotarray.indexOf(parsedslot)
log(indexedslot)
if (state.bullet.ownershiparray[indexedslot] != msg.who)
{
sendChat("Ammunition Tracker", "/w " + msg.who + "This slot does not belong to you!")
}
else
{
log(msg.who + " Deleted slot " + state.bullet.slotarray[indexedslot])
state.bullet.slotarray.splice(indexedslot, 1);
state.bullet.bulletarray.splice(indexedslot, 1);
state.bullet.namearray.splice(indexedslot, 1);
state.bullet.ownershiparray.splice(indexedslot, 1);
sendChat("Ammunition Tracker", "/w " + msg.who + "You have successfully deleted the contents of slot " + parsedslot)
log(state.bullet.ownershiparray[indexedslot])
log(state.bullet.bulletarray[indexedslot])
log(state.bullet.slotarray[indexedslot])
log(state.bullet.ownershiparray[indexedslot])
}
}
else if (msg.type == "api" && msg.content.indexOf("!setgun ") !== -1)
{
var splitstring= msg.content.split(/\s+/) ,
slots = parseInt(splitstring[1],10) || 0 ,
weaponname = splitstring[2] || 'Gun' ,
maximumbullets = parseInt(splitstring[3],10) || 10 ;
var checkifslotisoccupied = state.bullet.slotarray.indexOf(slots);
log(checkifslotisoccupied)
if (checkifslotisoccupied == -1)
{
findifslotisoccupied = state.bullet.slotarray.indexOf(slots);
state.bullet.slotarray.push(slots)
state.bullet.bulletarray.push(maximumbullets);
state.bullet.namearray.push(weaponname);
state.bullet.ownershiparray.push(msg.who);
log(msg.who)
log("The ammunition of " + weaponname + " in slot " + slots + " is currently " + maximumbullets)
sendChat("Ammunition Tracker", "/w " + msg.who + " Slot assignment completed successfully!")
}
else
{
sendChat("Ammunition Tracker", "/w " + msg.who + "Slot " + slots + " is currently occupied by " + state.bullet.ownershiparray[checkifslotisoccupied])
}
} //This ends !setgun
})
January 02 (9 years ago)
The Aaron
Pro
API Scripter
It's probably this:
 else if (msg.type == "api" && msg.content.indexOf("!bullets3") !== -3)
It should read:
else if (msg.type == "api" && msg.content.indexOf("!bullets3") !== -1)
Since at least as far back as the programming language C, functions that determine the string position have returned -1 to signify that they couldn't find the string, since 0 or higher could be a valid position and those older languages couldn't return different types from the same function (i.e. integer string indexes only, so no boolean (and most of them didn't have a boolean anyway..) ).


Additionally, you'll want to do something here:
        else
        {
            state.bullet.bulletarray[unloader]--;
            log(msg.who + " uses 3 units of ammunition from their " + state.bullet.namearray[unloader] + ", they now have " + state.bullet.bulletarray[unloader] + " units of ammunition remaining!")
            sendChat("Ammunition tracker", "/w " + msg.who + " you use 3 units of ammo, and now have " + state.bullet.bulletarray[unloader] + " remaining!")
        }
-- decrements the value of a variable, so this will only use 1 bullet.  You can certainly do:
state.bullet.bulletarray[unloader]-=3;
but this could end up with a negative number of bullets.  Something like this should work (though it could end up with 0 shots fired and 0 remaining, depending on how the rest of the script does things):
        else
        {
            var shotsFired = state.bullet.bulletarray[unloader]>=3 ? 3 : state.bullet.bulletarray[unloader];
            state.bullet.bulletarray[unloader]-=shotsFired;
            log(msg.who + " uses "+shotsFired+" units of ammunition from their " + state.bullet.namearray[unloader] + ", they now have " + state.bullet.bulletarray[unloader] + " units of ammunition remaining!")
            sendChat("Ammunition tracker", "/w " + msg.who + " you use "+shotsFired+" units of ammo, and now have " + state.bullet.bulletarray[unloader] + " remaining!")
        }

Let me know if that gets you going or if you have any other questions.  Once you're comfortable with that script, it would likely be better to just add a parameter for how many shots to take, rather than hard coding 3 or some other integer.  (I imagine you are already thinking that direction and are just experimenting at this point anyway!)

Happy Rolling!
January 02 (9 years ago)
Thanks Aaron your additions really did make the difference, unfortunately I doubt I have the skill to add a parameter to it (Even though I would really like to do just that) hence for now I am just going to be editing them in the hard code. Afterwards my players will only have to handle adding a singular command to their weapon specific macro's anyway. I'll probably have a look at it in the next month or so to see whether I can actually get a bit better into figuring out Java, it's just been ages for me since I had to work with it so to say I am rusty is understating it. 

Thanks though, you allowed me to do exactly what needed to be done. I am probably going to see if I can fine tune it a bit further along. Should I post my scripts at that time anyway since I figured it could be helpful for other players using ammunition trackers in games like modern d20, deathwatch, etc. etc. ?
January 02 (9 years ago)
Basically I just keep on adding this bit of coding and changing the 3 digits that are the same (In this case its 10) into whatever rate of fire I need it to be and it works perfectly so if anyone wants to use it, go right ahead!


else if (msg.type == "api" && msg.content.indexOf("!bullets10") !== -1)
//This will unload all of the arrays, put them through the process of firing and finally re-package them again
{
var mainstring = msg.content.split(/\s+/);
var slotlocator = parseInt(mainstring[1])
var unloader = state.bullet.slotarray.indexOf(slotlocator)
log(slotlocator)
log(unloader)
if (state.bullet.slotarray[unloader] == null)
{
sendChat("Ammunition tracker", "/w " + msg.who + " This slot seems to be empty...")
}
else if(state.bullet.ownershiparray[unloader] != msg.who)
{
sendChat("Ammunition tracker", "/w " + msg.who + " This slot is owned by " + state.bullet.ownershiparray[unloader])
}
else
{
var shotsFired = state.bullet.bulletarray[unloader]>=10 ? 10 : state.bullet.bulletarray[unloader];
state.bullet.bulletarray[unloader]-=shotsFired;
log(msg.who + " uses "+shotsFired+" units of ammunition from their " + state.bullet.namearray[unloader] + ", they now have " + state.bullet.bulletarray[unloader] + " units of ammunition remaining!")
sendChat("Ammunition tracker", "/w " + msg.who + " you use "+shotsFired+" units of ammo, and now have " + state.bullet.bulletarray[unloader] + " remaining!")
}
}