Skip to content

Commit da5266f

Browse files
committed
em: Add ResetPoints Unit
1 parent 5f9294c commit da5266f

9 files changed

Lines changed: 285 additions & 39 deletions

Editor/Descriptors/EMAddPointsUnitDescriptor.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,11 @@ public EMAddPointsUnitDescriptor(EMAddPointsUnit target) : base(target)
2929

3030
protected override string DefinedSummary()
3131
{
32-
return "This node adds points for EMs.";
32+
return "This node takes an incoming point value and pulses values to that can be used to simulate adding points to a score reel. "
33+
+ "For example, an incoming point value of 500 will provide 5 pulses of 100.";
3334
}
3435

35-
protected override EditorTexture DefinedIcon() => EditorTexture.Single(Unity.Editor.Icons.PlayerVariable);
36+
protected override EditorTexture DefinedIcon() => EditorTexture.Single(Unity.Editor.Icons.Mech(Unity.Editor.IconSize.Large, Unity.Editor.IconColor.Orange));
3637

3738
protected override void DefinedPort(IUnitPort port, UnitPortDescription desc)
3839
{
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Visual Pinball Engine
2+
// Copyright (C) 2022 freezy and VPE Team
3+
//
4+
// This program is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// This program is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU General Public License
15+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
16+
17+
// ReSharper disable UnusedType.Global
18+
19+
using Unity.VisualScripting;
20+
21+
namespace VisualPinball.Unity.VisualScripting.Editor
22+
{
23+
[Descriptor(typeof(EMResetPointsUnit))]
24+
public class EMResetPointsUnitDescriptor : UnitDescriptor<EMResetPointsUnit>
25+
{
26+
public EMResetPointsUnitDescriptor(EMResetPointsUnit target) : base(target)
27+
{
28+
}
29+
30+
protected override string DefinedSummary()
31+
{
32+
return "This node takes an incoming point value and pulses values to that can be used to simulate the resetting of a score reel. "
33+
+ "For example, an incoming point value of 2041 will provide the following pulses: 3052, 4063, 5074, 6085, 7096, 8007, 9008, 0009, 0000";
34+
}
35+
36+
protected override EditorTexture DefinedIcon() => EditorTexture.Single(Unity.Editor.Icons.Mech(Unity.Editor.IconSize.Large, Unity.Editor.IconColor.Orange));
37+
38+
protected override void DefinedPort(IUnitPort port, UnitPortDescription desc)
39+
{
40+
base.DefinedPort(port, desc);
41+
42+
switch (port.key) {
43+
}
44+
}
45+
}
46+
}

Editor/Descriptors/EMResetPointsUnitDescriptor.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Editor/Widgets/EMAddPointsUnitWidget.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,6 @@
1616

1717
// ReSharper disable UnusedType.Global
1818

19-
using System;
20-
using System.Collections.Generic;
21-
using System.Linq;
2219
using Unity.VisualScripting;
2320

2421
namespace VisualPinball.Unity.VisualScripting.Editor
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Visual Pinball Engine
2+
// Copyright (C) 2022 freezy and VPE Team
3+
//
4+
// This program is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// This program is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU General Public License
15+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
16+
17+
// ReSharper disable UnusedType.Global
18+
19+
using Unity.VisualScripting;
20+
21+
namespace VisualPinball.Unity.VisualScripting.Editor
22+
{
23+
[Widget(typeof(EMResetPointsUnit))]
24+
public sealed class EMResetPointsUnitWidget : GleUnitWidget<EMResetPointsUnit>
25+
{
26+
public EMResetPointsUnitWidget(FlowCanvas canvas, EMResetPointsUnit unit) : base(canvas, unit)
27+
{
28+
}
29+
}
30+
}

Editor/Widgets/EMResetPointsUnitWidget.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Runtime/Nodes/EM/EMAddPointsUnit.cs

Lines changed: 10 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -20,26 +20,12 @@
2020

2121
namespace VisualPinball.Unity.VisualScripting
2222
{
23-
/*
24-
* Well, I think the node should be an "EM Add Points" node that would accept a "Point Value"
25-
* and a "Score Motor Value". It would send a signal directly to the point value's score reel
26-
* "coil" if the "Score Motor Value" was set to 0. If the "Score Motor Value" was 1-5 then
27-
* the "Point Value" along with the "Score Motor Value" would be sent to the Score Motor.
28-
* The score motor would then send series of pulsed signals to the "point value's" score reel
29-
* coil equal to the "Score Motor Value." The reels would have to be set up with a 9's
30-
* carry over ability (ie 00190 sent a pulse to the 10's coil would have to pulse the
31-
* 100's coil once to get to 200) If the score motor is in motion then all scores that occur
32-
* during this window need to not be scored (per @bord observations today).
33-
*/
34-
3523
[UnitShortTitle("EM Add Points")]
3624
[UnitTitle("EM Add Points")]
37-
[UnitSurtitle("Gamelogic Engine")]
38-
[UnitCategory("Visual Pinball")]
25+
[UnitSurtitle("EM")]
26+
[UnitCategory("Visual Pinball/EM")]
3927
public class EMAddPointsUnit : GleUnit
4028
{
41-
private Bool running = false;
42-
4329
[DoNotSerialize]
4430
[PortLabelHidden]
4531
public ControlInput InputTrigger;
@@ -66,6 +52,8 @@ public class EMAddPointsUnit : GleUnit
6652
[DoNotSerialize, PortLabel("Point Value"), Inspectable]
6753
public ValueOutput OutputPointValue { get; private set; }
6854

55+
private Bool running = false;
56+
6957
protected override void Definition()
7058
{
7159
InputTrigger = ControlInputCoroutine(nameof(InputTrigger), Process);
@@ -85,17 +73,7 @@ protected override void Definition()
8573

8674
private IEnumerator Process(Flow flow)
8775
{
88-
if (!AssertGle(flow)) {
89-
Debug.LogError("Cannot find GLE.");
90-
91-
yield return null;
92-
}
93-
else if (!AssertPlayer(flow)) {
94-
Debug.LogError("Cannot find player.");
95-
96-
yield return null;
97-
}
98-
else if (running) {
76+
if (running) {
9977
var points = flow.GetValue<int>(pointValue);
10078

10179
Debug.Log($"Score motor is already running. Ignoring {points} point(s).");
@@ -121,13 +99,13 @@ private IEnumerator Process(Flow flow)
12199

122100
var pointsPerPulse = points / pulses;
123101

124-
flow.SetValue(OutputPointValue, pointsPerPulse);
125-
126102
var seconds = flow.GetValue<float>(duration) / 6;
127103
var realtime = flow.GetValue<bool>(unscaledTime);
128104

129105
for (int loop = 0; loop < 6; loop++) {
130-
Debug.Log($"Waiting {seconds}s. ({loop + 1} of 6)");
106+
var outputPoints = loop < pulses ? pointsPerPulse : 0;
107+
108+
Debug.Log($"Pulse {loop + 1} of 6 - waiting {seconds} and triggering with {outputPoints} points");
131109

132110
if (realtime) {
133111
yield return new WaitForSecondsRealtime(seconds);
@@ -136,11 +114,9 @@ private IEnumerator Process(Flow flow)
136114
yield return new WaitForSeconds(seconds);
137115
}
138116

139-
if (loop < pulses) {
140-
Debug.Log($"Performing {pointsPerPulse} point(s) pulse. ({loop + 1} of {pulses})");
117+
flow.SetValue(OutputPointValue, outputPoints);
141118

142-
yield return pulse;
143-
}
119+
yield return pulse;
144120
}
145121

146122
Debug.Log("Stopping score motor");
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
// Visual Pinball Engine
2+
// Copyright (C) 2022 freezy and VPE Team
3+
//
4+
// This program is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// This program is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU General Public License
15+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
16+
17+
using System.Collections;
18+
using Unity.VisualScripting;
19+
using UnityEngine;
20+
21+
namespace VisualPinball.Unity.VisualScripting
22+
{
23+
[UnitShortTitle("EM Reset Points")]
24+
[UnitTitle("EM Reset Points")]
25+
[UnitSurtitle("EM")]
26+
[UnitCategory("Visual Pinball/EM")]
27+
public class EMResetPointsUnit : GleUnit
28+
{
29+
[DoNotSerialize]
30+
[PortLabelHidden]
31+
public ControlInput InputTrigger;
32+
33+
[DoNotSerialize]
34+
public ValueInput duration { get; private set; }
35+
36+
[DoNotSerialize]
37+
[PortLabel("Unscaled")]
38+
public ValueInput unscaledTime { get; private set; }
39+
40+
[DoNotSerialize]
41+
public ControlOutput started;
42+
43+
[DoNotSerialize]
44+
public ControlOutput stopped;
45+
46+
[DoNotSerialize]
47+
public ControlOutput pulse { get; private set; }
48+
49+
[DoNotSerialize]
50+
public ValueInput pointValue { get; private set; }
51+
52+
[DoNotSerialize, PortLabel("Point Value"), Inspectable]
53+
public ValueOutput OutputPointValue { get; private set; }
54+
55+
private Bool running = false;
56+
57+
protected override void Definition()
58+
{
59+
InputTrigger = ControlInputCoroutine(nameof(InputTrigger), Process);
60+
61+
pointValue = ValueInput(nameof(pointValue), 0);
62+
63+
duration = ValueInput(nameof(duration), .750f);
64+
unscaledTime = ValueInput(nameof(unscaledTime), false);
65+
66+
started = ControlOutput(nameof(started));
67+
stopped = ControlOutput(nameof(stopped));
68+
69+
pulse = ControlOutput(nameof(pulse));
70+
71+
OutputPointValue = ValueOutput<int>(nameof(OutputPointValue));
72+
}
73+
74+
private IEnumerator Process(Flow flow)
75+
{
76+
if (running) {
77+
var points = flow.GetValue<int>(pointValue);
78+
79+
Debug.Log($"Score motor is already running. Ignoring {points} point(s).");
80+
81+
yield return null;
82+
}
83+
else {
84+
Debug.Log("Starting score motor");
85+
86+
yield return started;
87+
88+
running = true;
89+
90+
var points = flow.GetValue<int>(pointValue);
91+
92+
var seconds = flow.GetValue<float>(duration) / 6;
93+
var realtime = flow.GetValue<bool>(unscaledTime);
94+
95+
while (points > 0) {
96+
for (int loop = 0; loop < 6; loop++) {
97+
points = AdvancePoints(points);
98+
99+
Debug.Log($"Pulse {loop + 1} of 6 - waiting {seconds} and triggering with {points} points");
100+
101+
if (realtime) {
102+
yield return new WaitForSecondsRealtime(seconds);
103+
}
104+
else {
105+
yield return new WaitForSeconds(seconds);
106+
}
107+
108+
flow.SetValue(OutputPointValue, points);
109+
110+
yield return pulse;
111+
}
112+
}
113+
114+
Debug.Log("Stopping score motor");
115+
116+
running = false;
117+
118+
yield return stopped;
119+
}
120+
}
121+
122+
private static int NumDigits(int n)
123+
{
124+
if (n < 0)
125+
{
126+
n = n == int.MinValue ? int.MaxValue : -n;
127+
}
128+
return n switch
129+
{
130+
< 10 => 1,
131+
< 100 => 2,
132+
< 1000 => 3,
133+
< 10000 => 4,
134+
< 100000 => 5,
135+
< 1000000 => 6,
136+
< 10000000 => 7,
137+
< 100000000 => 8,
138+
< 1000000000 => 9,
139+
_ => 10
140+
};
141+
}
142+
143+
private static int[] DigitArr(int n)
144+
{
145+
var result = new int[NumDigits(n)];
146+
for (var i = result.Length - 1; i >= 0; i--) {
147+
result[i] = n % 10;
148+
n /= 10;
149+
}
150+
return result;
151+
}
152+
153+
private static int AdvancePoints(int points) {
154+
var value = 0;
155+
156+
foreach (var i in DigitArr(points)) {
157+
value = (value * 10) + ((i > 0 && i < 9) ? (i + 1) : 0);
158+
}
159+
160+
return value;
161+
}
162+
}
163+
}

Runtime/Nodes/EM/EMResetPointsUnit.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)