Recoil:What do the blasters do and what do the phones do
The blaster is a lot dumber than you think. The phone is doing most of the work.
The blaster sends 20 bytes of data to the phone roughly 10 times a second. This data includes: -Currently assigned ID -Which buttons are currently being pressed and held down -Count of the number of times each button has been pressed in the past. The count rolls over after 15 presses. -Battery level -Shots remaining -Data about any hits that are hitting the blaster right now
There are 2 blocks of data about hits that are hitting the blaster right now. The 2 blocks contain 3 fields of data. I have no idea what the first field indicates. The second field contains the ID of the person who is hitting the blaster. The third field indicates how strong the hit signal is. I assume that the strength indicator is lower for hits from people that are farther away or lower in daylight, etc. You never see data in the second "hit by" block unless there is data in the first block. A lot of times, the second hit by block contains the same player ID as is in the first block. Another thing that's important to note is that the gun will never register a hit from its currently assigned ID. Two players using the same ID cannot hit each other.
If there are shots loaded into the blaster, the blaster will shoot until it runs out of shots. Pressing the reload button doesn't do anything. Same goes for power or the back / thumb / talk button.
You'll also notice that there is no health indicator in this data that the blaster is sending to the phone. It's up to the phone to process the hit data.
The phone assigns an ID to the blaster.
To reload, we have to send 2 commands to the blaster. The first command leaves the blaster in a state where it cannot shoot. In SimpleCoil, I send the blaster this first command when the player is eliminated and between games so that the player cannot shoot when they're not supposed to. The second command tells the blaster how many shots it has. You can load up to 255 shots. When the blaster receives this command, pulling the trigger will cause the blaster to shoot and it will shoot until it runs out again.
The phone can send configuration data to the blaster that tells the blaster to enable or disable the recoil feature. There's a different configuration that we can send the blaster that tells it how many shots to fire each time the trigger is pressed and held and how fast the rate of fire should be.
In SimpleCoil, I monitor how many times the buttons have been pressed. If I see a change in the number of times the reload button has been pressed, then I start the reload sequence. First I send the "start reload" command and wait until the Bluetooth stack tells us that the send has finished. Once the send command finishes, I start a timer for the 1.5 second cooldown. When the timer ends, we send the finish reload command telling the blaster to load 30 shots.
If I see a change in thumb button presses, I send a configuration to change the firing mode. There isn't a message that says, "change fire mode." Instead, I have to explicitly say, "1 shot per trigger pull" or "shoot until you run out at the highest rate of fire you can." Same goes for the power button. When I see a change in power button counts, I send a message saying "turn on recoil" or "turn off recoil."
Monitoring the counts of button presses works better for our purposes than checking to see if a button is currently being pressed. If I monitored that a button was currently being pressed and you pressed and held the thumb button then you'd end up toggling firing modes rapidly several times per second.
I also keep track of the shot count. When I see a change in shot counts, I play the "pew pew you're shooting" sound. I monitor trigger pull count and if the shot count is 0 when you pull the trigger, I play the "click, you're empty" sound.
When the blaster registers a hit, it's up to the phone to process the hit and decide if and what to do. In SimpleCoil, in a networked team game, I'll ignore hits from teammates. Otherwise, I subtract 1 from the health bar. SimpleCoil also ignores hits if the player is eliminated or if the game has ended. In network games, I send data to the player that is hitting you, letting them know that they are actually hitting their target. If the health bar hits 0, I send different data telling the other player's phone to increase their score by 1. If you are out, waiting to respawn, I send a different packet letting them know that they are hitting someone who is currently out of the game.
You could do whatever you want with this hit data. You could make it so that when you are being hit by a teammate, you are revived if you are dead, or heal, or gain more ammo.
If you wanted to severely limit the rate of fire, you could load 1 shot at a time. When the shot counter is back at 0, wait 1 second (or however long) then send the reload command. Then you'd have something close to the time it'd take for a bolt action rifle to be ready again. You could make it so that if players are hit by your player ID, they are dead in one shot.