-
Notifications
You must be signed in to change notification settings - Fork 84
/
detonator.h
136 lines (112 loc) · 2.99 KB
/
detonator.h
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
132
133
134
135
136
#ifndef PROPS_DETONATOR_H
#define PROPS_DETONATOR_H
#include "prop_base.h"
#define PROP_TYPE Detonator
class Detonator : public PROP_INHERIT_PREFIX PropBase {
public:
Detonator() : PropBase() {}
const char* name() override { return "Detonator"; }
#ifdef DELAYED_OFF
bool powered_ = false;
void SetPower(bool on) { powered_ = on; }
#else
bool powered_ = true;
void SetPower(bool on) {}
#endif
bool armed_ = false;
enum NextAction {
NEXT_ACTION_NOTHING,
NEXT_ACTION_ARM,
NEXT_ACTION_BLOW,
};
NextAction next_action_ = NEXT_ACTION_NOTHING;
uint32_t time_base_;
uint32_t next_event_time_;
void SetNextAction(NextAction what, uint32_t when) {
time_base_ = millis();
next_event_time_ = when;
next_action_ = what;
}
void SetNextActionF(NextAction what, float when) {
SetNextAction(what, when * 1000);
}
void PollNextAction() {
if (millis() - time_base_ > next_event_time_) {
switch (next_action_) {
case NEXT_ACTION_NOTHING:
break;
case NEXT_ACTION_ARM:
armed_ = true;
// TODO: Should we have separate ARMING and ARMED states?
break;
case NEXT_ACTION_BLOW:
Off(OFF_BLAST);
break;
}
next_action_ = NEXT_ACTION_NOTHING;
}
}
void beginArm() {
SaberBase::SetLockup(SaberBase::LOCKUP_ARMED);
SaberBase::DoBeginLockup();
#ifdef ENABLE_AUDIO
float len = hybrid_font.GetCurrentEffectLength();
#else
float len = 1.6;
#endif
SetNextActionF(NEXT_ACTION_ARM, len);
}
void blast() {
SaberBase::DoEndLockup();
#ifdef ENABLE_AUDIO
float len = hybrid_font.GetCurrentEffectLength();
#else
float len = 0.0;
#endif
SaberBase::SetLockup(SaberBase::LOCKUP_NONE);
if (armed_) {
SetNextActionF(NEXT_ACTION_BLOW, len);
} else {
SetNextAction(NEXT_ACTION_NOTHING, 0);
}
}
void Loop() override {
PropBase::Loop();
PollNextAction();
}
#if NUM_BUTTONS >= 2
// Make clash do nothing
void Clash(bool stab, float strength) override {}
#endif
// Make swings do nothing
void DoMotion(const Vec3& motion, bool clear) override { }
bool Event2(enum BUTTON button, EVENT event, uint32_t modifiers) override {
switch (EVENTID(button, event, modifiers)) {
case EVENTID(BUTTON_POWER, EVENT_LATCH_ON, MODE_OFF):
armed_ = false;
SetPower(true);
On();
return true;
case EVENTID(BUTTON_POWER, EVENT_LATCH_OFF, MODE_ON):
case EVENTID(BUTTON_POWER, EVENT_LATCH_OFF, MODE_OFF):
SetPower(false);
Off();
return true;
case EVENTID(BUTTON_AUX2, EVENT_DOUBLE_CLICK, MODE_OFF):
if (powered_) rotate_presets();
return true;
case EVENTID(BUTTON_AUX2, EVENT_DOUBLE_CLICK, MODE_ON):
StartOrStopTrack();
return true;
case EVENTID(BUTTON_AUX2, EVENT_PRESSED, MODE_ON):
beginArm();
break;
case EVENTID(BUTTON_AUX2, EVENT_RELEASED, MODE_ON):
blast();
return armed_;
// TODO: Long click when off?
}
return false;
}
};
#endif