forked from braidstag/arduino-milestag
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmiles_tag_gun_logic.ino
131 lines (116 loc) · 4.19 KB
/
miles_tag_gun_logic.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
//milestag protocol 1 documented at http://www.lasertagparts.com/mtformat.htm
//milestag protocol 2 documented at http://www.lasertagparts.com/mtformat-2.htm
// we currently only implement MT1 as MT2 seems incomplete.
void serialQueue(int size, const char * fmt, ...) {
char* out = (char*) malloc(size);
va_list ap;
va_start(ap, fmt);
vsnprintf(out, size, fmt, ap);
Serial.println(out);
free(out);
va_end (ap);
}
void mt_parseIRMessage(unsigned long recvBuffer) {
if (!isEvenParity(recvBuffer)) {
serialQueue_s("C\n");
return;
}
//trim the 17th bit (parity) off to make things neater
recvBuffer = recvBuffer >> 1;
byte recv_TeamID = (recvBuffer & MT1_TEAM_MASK) >> MT1_TEAM_OFFSET;
byte DataByte2 = recvBuffer & 0xff;
if (recv_TeamID == SYSTEM_MESSAGE) {
byte recv_SystemMessage = (recvBuffer & SYSTEM_MESSAGE_MASK) >> SYSTEM_MESSAGE_SHIFT;
switch (recv_SystemMessage) {
case SYSTEM_MESSAGE_SET_TEAM_ID:
serialQueue(20, "Shot(SetTeam(%u))\n", DataByte2);
break;
case SYSTEM_MESSAGE_SET_PLAYER_ID:
serialQueue(22, "Shot(SetPlayer(%u))\n", DataByte2);
break;
case SYSTEM_MESSAGE_ADD_HEALTH:
serialQueue(22, "Shot(AddHealth(%u))\n", DataByte2);
break;
case SYSTEM_MESSAGE_ADD_CLIPS:
{
serialQueue(21, "Shot(AddClips(%u))\n", DataByte2);
break;
}
case SYSTEM_MESSAGE_GOD_GUN:
{
byte recv_GodGun = DataByte2;
switch (recv_GodGun) {
case GOD_GUN_KILL_PLAYER:
serialQueue_s("Shot(Killed())\n");
break;
case GOD_GUN_FULL_AMMO:
serialQueue_s("FA\n");
break;
case GOD_GUN_RESPAWN_PLAYER:
serialQueue_s("Shot(ReSpawn())\n");
break;
case GOD_GUN_PAUSE_PLAYER:
case GOD_GUN_START_GAME:
case GOD_GUN_INIT_PLAYER:
case GOD_GUN_END_PLAYER:
default:
serialQueue_s("Shot(UnknownGGM)\n");
break;
}
break;
}
case SYSTEM_MESSAGE_ADD_ROUNDS:
serialQueue(22, "Shot(AddRounds(%u))\n", DataByte2);
break;
case SYSTEM_MESSAGE_ADD_RPG_ROUNDS:
case SYSTEM_MESSAGE_SCORE_DATA_HEADER:
case SYSTEM_MESSAGE_SCORE_REQUEST:
default:
serialQueue(29, "Shot(UnknownSM(%lu))\n", recvBuffer);
break;
}
} else {
byte recv_PlayerID = (recvBuffer & MT1_PLAYER_MASK) >> MT1_PLAYER_OFFSET;
signed char damage = 0;
byte recv_PlayerWeaponHit = DataByte2;
switch (recv_PlayerWeaponHit) {
case 0:
{
damage = MT1_DAMAGE_RESURRECT_OPPONENT;
break;
}
case 1 ... 100:
{
damage = recv_PlayerWeaponHit;
break;
}
//No 'Base' Mode
/*case 101 ... 200:
{
recv_PlayerWeaponHit -= 100;
baseDamage = recv_PlayerWeaponHit;
}
case 255:
baseDamage = MT1_DAMAGE_RESURRECT_ENEMY_BASE;
*/
default:
serialQueue_s("Shot(UnknownDmg)\n");
break;
}
serialQueue_s("H");
serialQueue_i((int) recv_TeamID);
serialQueue_s(",");
serialQueue_i((int) recv_PlayerID);
serialQueue_s(",");
serialQueue_i((int) damage);
/*serialQueue_s(","); serialQueue_i((int) baseDamage);*/
serialQueue_s("\n");
}
}
void mt_fireShot() {
mt_fireShot(preConnectedTeamId, 1, 3);
}
void mt_fireShot(byte teamId, byte playerId, byte dmg) {
unsigned long shot = (teamId << MT1_TEAM_OFFSET) | (playerId << MT1_PLAYER_OFFSET) | dmg;
start_command(shot, teamId);
}