cetragm 0.1.2__py3-none-any.whl → 0.1.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cetragm/bag.py +1 -1
- cetragm/controls.py +1 -1
- cetragm/draw.py +2 -2
- cetragm/game.py +1 -2
- cetragm/main.py +56 -22
- cetragm/player.py +2 -1
- cetragm/srs.py +161 -1
- {cetragm-0.1.2.dist-info → cetragm-0.1.5.dist-info}/METADATA +3 -4
- cetragm-0.1.5.dist-info/RECORD +17 -0
- cetragm-0.1.5.dist-info/entry_points.txt +4 -0
- cetragm-0.1.2.dist-info/RECORD +0 -17
- cetragm-0.1.2.dist-info/entry_points.txt +0 -4
- {cetragm-0.1.2.dist-info → cetragm-0.1.5.dist-info}/WHEEL +0 -0
- {cetragm-0.1.2.dist-info → cetragm-0.1.5.dist-info}/licenses/LICENSE +0 -0
cetragm/bag.py
CHANGED
cetragm/controls.py
CHANGED
cetragm/draw.py
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
# Module for drawing to the screen (stdout tomfuckery time!!!)
|
|
3
3
|
import sys
|
|
4
4
|
import shutil
|
|
5
|
-
from
|
|
6
|
-
from
|
|
5
|
+
from cetragm.tables import pieces, grades
|
|
6
|
+
from cetragm.game import collides
|
|
7
7
|
|
|
8
8
|
BLOCK = "██"
|
|
9
9
|
SHADOW = "▒▒"
|
cetragm/game.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# core logic like lock, gravity, and scoring
|
|
2
|
-
from
|
|
2
|
+
from cetragm.tables import pieces, ROT_180, ROT_CCW, ROT_CW
|
|
3
3
|
import math
|
|
4
4
|
|
|
5
5
|
def get_cells(piece): # {"name": "i", "pos": (0, 0), "rotation": "0"}
|
|
@@ -12,7 +12,6 @@ def get_cells(piece): # {"name": "i", "pos": (0, 0), "rotation": "0"}
|
|
|
12
12
|
return cells
|
|
13
13
|
|
|
14
14
|
def collides(piece, board):
|
|
15
|
-
# Check if the piece is colliding (will want to write a new one for srs.py)
|
|
16
15
|
for (x, y) in get_cells(piece):
|
|
17
16
|
if x < 0 or x >= len(board[0]) or y >= len(board):
|
|
18
17
|
return True
|
cetragm/main.py
CHANGED
|
@@ -6,11 +6,13 @@ import threading
|
|
|
6
6
|
import signal
|
|
7
7
|
import queue
|
|
8
8
|
|
|
9
|
-
from
|
|
10
|
-
from
|
|
11
|
-
from
|
|
12
|
-
from
|
|
13
|
-
from
|
|
9
|
+
from cetragm.draw import draw_board
|
|
10
|
+
from cetragm.game import lock_piece, collides
|
|
11
|
+
from cetragm.player import Player
|
|
12
|
+
from cetragm.bag import Bag
|
|
13
|
+
from cetragm.controls import InputHandler
|
|
14
|
+
from cetragm.srs import rotate_srs
|
|
15
|
+
from cetragm.tables import pieces
|
|
14
16
|
|
|
15
17
|
def sigint_handler(sig, frame):
|
|
16
18
|
sigint.set()
|
|
@@ -27,6 +29,24 @@ def setup_board(rows, cols):
|
|
|
27
29
|
board = [[[0] for _ in range(cols)] for _ in range(rows)]
|
|
28
30
|
return board
|
|
29
31
|
|
|
32
|
+
def is_grounded(active_piece, board):
|
|
33
|
+
if not active_piece:
|
|
34
|
+
return False
|
|
35
|
+
temp_pos = list(active_piece["pos"])
|
|
36
|
+
temp_pos[1] += 1
|
|
37
|
+
return collides({"name": active_piece["name"], "rotation": active_piece["rotation"], "pos": temp_pos}, board)
|
|
38
|
+
|
|
39
|
+
def get_minos(active_piece):
|
|
40
|
+
if not active_piece:
|
|
41
|
+
return set()
|
|
42
|
+
rot_matrix = pieces[active_piece["name"].lower()]["rotations"][active_piece["rotation"]]
|
|
43
|
+
minos = set()
|
|
44
|
+
for dy, row in enumerate(rot_matrix):
|
|
45
|
+
for dx, cell in enumerate(row):
|
|
46
|
+
if cell:
|
|
47
|
+
minos.add((active_piece["pos"][0] + dx, active_piece["pos"][1] + dy))
|
|
48
|
+
return minos
|
|
49
|
+
|
|
30
50
|
def lock_and_are(player, board, shared):
|
|
31
51
|
board, cleared, loss = lock_piece(player.active_piece, board, player)
|
|
32
52
|
shared["board"] = board
|
|
@@ -67,6 +87,7 @@ def lock_now(player, board, shared, bag):
|
|
|
67
87
|
player.fall_progress = 0.0
|
|
68
88
|
player.soft = 0
|
|
69
89
|
player.hold_lock = False
|
|
90
|
+
player.lock_resets = 0
|
|
70
91
|
return "active"
|
|
71
92
|
|
|
72
93
|
def input_handler(player, board, action, bag, shared, LOCK_DELAY, FRAME):
|
|
@@ -108,24 +129,18 @@ def input_handler(player, board, action, bag, shared, LOCK_DELAY, FRAME):
|
|
|
108
129
|
return lock_now(player, board, shared, bag)
|
|
109
130
|
|
|
110
131
|
elif action == "rotate_cw":
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
if collides(piece, board):
|
|
114
|
-
piece["rotation"] = old_rot
|
|
132
|
+
rotate_srs(player.active_piece, +1, board,
|
|
133
|
+
lambda n,r,p: collides({"name": n, "rotation": r, "pos": [p[0], p[1]]}, board))
|
|
115
134
|
return None
|
|
116
135
|
|
|
117
136
|
elif action == "rotate_ccw":
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
if collides(piece, board):
|
|
121
|
-
piece["rotation"] = old_rot
|
|
137
|
+
rotate_srs(player.active_piece, -1, board,
|
|
138
|
+
lambda n,r,p: collides({"name": n, "rotation": r, "pos": [p[0], p[1]]}, board))
|
|
122
139
|
return None
|
|
123
140
|
|
|
124
141
|
elif action == "rotate_180":
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
if collides(piece, board):
|
|
128
|
-
piece["rotation"] = old_rot
|
|
142
|
+
rotate_srs(player.active_piece, 2, board,
|
|
143
|
+
lambda n,r,p: collides({"name": n, "rotation": r, "pos": [p[0], p[1]]}, board))
|
|
129
144
|
return None
|
|
130
145
|
|
|
131
146
|
elif action == "hold":
|
|
@@ -135,11 +150,12 @@ def input_handler(player, board, action, bag, shared, LOCK_DELAY, FRAME):
|
|
|
135
150
|
player.hold_piece = player.active_piece["name"]
|
|
136
151
|
if not old:
|
|
137
152
|
player.active_piece = {"name": bag.get_piece(), "pos": [3, 0], "rotation": "0"}
|
|
138
|
-
player.fall_progress = 0.0
|
|
139
153
|
else:
|
|
140
154
|
player.active_piece = {"name": old, "pos": [3, 0], "rotation": "0"}
|
|
141
|
-
|
|
155
|
+
|
|
156
|
+
player.fall_progress = 0.0
|
|
142
157
|
player.hold_lock = True
|
|
158
|
+
player.lock_resets = 0
|
|
143
159
|
return None
|
|
144
160
|
|
|
145
161
|
return None
|
|
@@ -174,7 +190,7 @@ def render_loop(shared, player, bag, fps):
|
|
|
174
190
|
print("\x1b[H\x1b[31mRunning below 60fps!! Performance will be degraded\x1b[0m")
|
|
175
191
|
|
|
176
192
|
def game_loop(shared, player, bag, inputs, fps):
|
|
177
|
-
from
|
|
193
|
+
from cetragm.config import ARE_FRAMES, LINE_CLEAR_FRAMES, LOCK_DELAY_FRAMES
|
|
178
194
|
FRAME = 1.0 / fps
|
|
179
195
|
|
|
180
196
|
LOCK_DELAY = LOCK_DELAY_FRAMES * FRAME
|
|
@@ -190,6 +206,9 @@ def game_loop(shared, player, bag, inputs, fps):
|
|
|
190
206
|
if not hasattr(player, "fall_progress"):
|
|
191
207
|
player.fall_progress = 0.0
|
|
192
208
|
|
|
209
|
+
if not hasattr(player, "lock_resets"):
|
|
210
|
+
player.lock_resets = 0
|
|
211
|
+
|
|
193
212
|
while not sigint.is_set():
|
|
194
213
|
now = time.perf_counter()
|
|
195
214
|
dt = now - last_time
|
|
@@ -205,6 +224,9 @@ def game_loop(shared, player, bag, inputs, fps):
|
|
|
205
224
|
except queue.Empty:
|
|
206
225
|
break
|
|
207
226
|
|
|
227
|
+
was_grounded = is_grounded(player.active_piece, board)
|
|
228
|
+
old_minos = get_minos(player.active_piece)
|
|
229
|
+
|
|
208
230
|
new_state = input_handler(player, board, action, bag, shared, LOCK_DELAY, FRAME)
|
|
209
231
|
|
|
210
232
|
if new_state == "ground":
|
|
@@ -216,13 +238,23 @@ def game_loop(shared, player, bag, inputs, fps):
|
|
|
216
238
|
phase_timer = 0.0
|
|
217
239
|
continue
|
|
218
240
|
|
|
219
|
-
if new_state in ("line_clear", "are", "loss"):
|
|
241
|
+
if new_state in ("line_clear", "are", "loss", "active"):
|
|
220
242
|
state = new_state
|
|
221
243
|
phase_timer = 0.0
|
|
222
244
|
player.hold_lock = False
|
|
223
245
|
if state == "active":
|
|
224
|
-
player.
|
|
246
|
+
player.fall_progress = 0.0
|
|
225
247
|
break
|
|
248
|
+
|
|
249
|
+
new_minos = get_minos(player.active_piece)
|
|
250
|
+
if new_minos != old_minos and was_grounded:
|
|
251
|
+
now_grounded = is_grounded(player.active_piece, board)
|
|
252
|
+
if now_grounded:
|
|
253
|
+
player.lock_resets += 1
|
|
254
|
+
if player.lock_resets <= 15:
|
|
255
|
+
lock_timer = 0.0
|
|
256
|
+
else:
|
|
257
|
+
player.lock_resets = 0
|
|
226
258
|
|
|
227
259
|
player.check_grade()
|
|
228
260
|
|
|
@@ -277,6 +309,7 @@ def game_loop(shared, player, bag, inputs, fps):
|
|
|
277
309
|
player.active_piece = {"name": bag.get_piece(), "pos": [3, 0], "rotation": "0"}
|
|
278
310
|
player.fall_progress = 0.0
|
|
279
311
|
lock_timer = 0.0
|
|
312
|
+
player.lock_resets = 0
|
|
280
313
|
state = "active"
|
|
281
314
|
|
|
282
315
|
# first piece
|
|
@@ -284,6 +317,7 @@ def game_loop(shared, player, bag, inputs, fps):
|
|
|
284
317
|
player.active_piece = {"name": bag.get_piece(), "pos": [3, 0], "rotation": "0"} # and again
|
|
285
318
|
player.fall_progress = 0.0
|
|
286
319
|
lock_timer = 0.0
|
|
320
|
+
player.lock_resets = 0
|
|
287
321
|
state = "active"
|
|
288
322
|
|
|
289
323
|
elapsed_loop = time.perf_counter() - now
|
cetragm/player.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# module containing the Player class and its functions
|
|
2
2
|
|
|
3
3
|
import time
|
|
4
|
-
from
|
|
4
|
+
from cetragm.tables import thresholds, gravity
|
|
5
5
|
|
|
6
6
|
class Player:
|
|
7
7
|
def __init__(self):
|
|
@@ -23,6 +23,7 @@ class Player:
|
|
|
23
23
|
self.combo = 0
|
|
24
24
|
self.soft = 0
|
|
25
25
|
self.hold_lock = False
|
|
26
|
+
self.lock_resets = 0
|
|
26
27
|
self.fall_progress = 0.0
|
|
27
28
|
|
|
28
29
|
def upd_time(self):
|
cetragm/srs.py
CHANGED
|
@@ -1 +1,161 @@
|
|
|
1
|
-
# Definitions of the tomfuckery that is Super Rotation System (rotation and wallkicks)
|
|
1
|
+
# Definitions of the tomfuckery that is Super Rotation System (rotation and wallkicks)
|
|
2
|
+
|
|
3
|
+
from typing import Tuple, Callable, List, Dict
|
|
4
|
+
|
|
5
|
+
Pos = Tuple[int, int]
|
|
6
|
+
CollidesFn = Callable[[str, str, Pos], bool]
|
|
7
|
+
|
|
8
|
+
ROT_SEQ = ["0", "r", "2", "l"]
|
|
9
|
+
ROT_CW = {"0": "r", "r": "2", "2": "l", "l": "0"}
|
|
10
|
+
ROT_CCW = {"0": "l", "l": "2", "2": "r", "r": "0"}
|
|
11
|
+
ROT_180 = {"0": "2", "2": "0", "r": "l", "l": "r"}
|
|
12
|
+
JLSTZ_OFFSETS = {"0": (0,0), "r": (0,0), "2": (0,0), "l": (0,0)}
|
|
13
|
+
|
|
14
|
+
I_OFFSETS = {
|
|
15
|
+
"0": (-1, 0),
|
|
16
|
+
"r": (1, 0),
|
|
17
|
+
"2": (0, 1),
|
|
18
|
+
"l": (0, -1),
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
# These kick tables are not my values, they're from the Super Rotation System (or Tetris Guideline)
|
|
22
|
+
# Also they were originally inverted until the commit that added this comment so i made an LLM invert them because im too lazy
|
|
23
|
+
JLSTZ_KICKS = {
|
|
24
|
+
("0", "r"): [(0,0), (-1,0), (-1,-1), (0,2), (-1,2)],
|
|
25
|
+
("r", "0"): [(0,0), (1,0), (1,1), (0,-2), (1,-2)],
|
|
26
|
+
|
|
27
|
+
("r", "2"): [(0,0), (1,0), (1,1), (0,-2), (1,-2)],
|
|
28
|
+
("2", "r"): [(0,0), (-1,0), (-1,-1), (0,2), (-1,2)],
|
|
29
|
+
|
|
30
|
+
("2", "l"): [(0,0), (1,0), (1,-1), (0,2), (1,2)],
|
|
31
|
+
("l", "2"): [(0,0), (-1,0), (-1,1), (0,-2), (-1,-2)],
|
|
32
|
+
|
|
33
|
+
("l", "0"): [(0,0), (-1,0), (-1,1), (0,-2), (-1,-2)],
|
|
34
|
+
("0", "l"): [(0,0), (1,0), (1,-1), (0,2), (1,2)],
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
I_KICKS = {
|
|
38
|
+
("0", "r"): [(0,0), (-2,0), (1,0), (-2,1), (1,-2)],
|
|
39
|
+
("r", "0"): [(0,0), (2,0), (-1,0), (2,-1), (-1,2)],
|
|
40
|
+
|
|
41
|
+
("r", "2"): [(0,0), (-1,0), (2,0), (-1,-2), (2,1)],
|
|
42
|
+
("2", "r"): [(0,0), (1,0), (-2,0), (1,2), (-2,-1)],
|
|
43
|
+
|
|
44
|
+
("2", "l"): [(0,0), (2,0), (-1,0), (2,-1), (-1,2)],
|
|
45
|
+
("l", "2"): [(0,0), (-2,0), (1,0), (-2,1), (1,-2)],
|
|
46
|
+
|
|
47
|
+
("l", "0"): [(0,0), (1,0), (-2,0), (1,2), (-2,-1)],
|
|
48
|
+
("0", "l"): [(0,0), (-1,0), (2,0), (-1,-2), (2,1)],
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
O_KICKS = {
|
|
52
|
+
("0", "r"): [(0,0)],
|
|
53
|
+
("r", "2"): [(0,0)],
|
|
54
|
+
|
|
55
|
+
("2", "l"): [(0,0)],
|
|
56
|
+
("l", "0"): [(0,0)],
|
|
57
|
+
|
|
58
|
+
("r", "0"): [(0,0)],
|
|
59
|
+
("2", "r"): [(0,0)],
|
|
60
|
+
|
|
61
|
+
("l", "2"): [(0,0)],
|
|
62
|
+
("0", "l"): [(0,0)],
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
JLSTZ_KICKS_180 = {
|
|
66
|
+
("0","2"): [(0,0), (0,-1), (0,-2), (1,0), (-1,0), (1,-1), (-1,-1)],
|
|
67
|
+
("2","0"): [(0,0), (0,-1), (0,-2), (-1,0), (1,0), (-1,-1), (1,-1)],
|
|
68
|
+
("r","l"): [(0,0), (0,-1), (0,-2), (1,0), (-1,0), (1,-1), (-1,-1)],
|
|
69
|
+
("l","r"): [(0,0), (0,-1), (0,-2), (-1,0), (1,0), (-1,-1), (1,-1)],
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
I_KICKS_180 = {
|
|
73
|
+
("0","2"): [(0,0), (0,1), (0,-1), (1,0), (-1,0), (2,0), (-2,0)],
|
|
74
|
+
("2","0"): [(0,0), (0,1), (0,-1), (-1,0), (1,0), (-2,0), (2,0)],
|
|
75
|
+
("r","l"): [(0,0), (0,1), (0,-1), (1,0), (-1,0)],
|
|
76
|
+
("l","r"): [(0,0), (0,1), (0,-1), (-1,0), (1,0)],
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
def rotate_label(current: str, direction:int) -> str:
|
|
80
|
+
if direction == +1:
|
|
81
|
+
return ROT_CW[current]
|
|
82
|
+
if direction == -1:
|
|
83
|
+
return ROT_CCW[current]
|
|
84
|
+
if direction == 2:
|
|
85
|
+
return ROT_180[current]
|
|
86
|
+
return current
|
|
87
|
+
|
|
88
|
+
def _offset_for(name: str, rot: str) -> Pos:
|
|
89
|
+
n = name.lower()
|
|
90
|
+
if n == "i":
|
|
91
|
+
return I_OFFSETS[rot]
|
|
92
|
+
return JLSTZ_OFFSETS[rot]
|
|
93
|
+
|
|
94
|
+
def _kick_table(name: str):
|
|
95
|
+
n = name.lower()
|
|
96
|
+
if n == "i":
|
|
97
|
+
return I_KICKS
|
|
98
|
+
if n == "o":
|
|
99
|
+
return O_KICKS
|
|
100
|
+
return JLSTZ_KICKS
|
|
101
|
+
|
|
102
|
+
def _kick_table_180(name: str):
|
|
103
|
+
n = name.lower()
|
|
104
|
+
if n == "i":
|
|
105
|
+
return I_KICKS_180
|
|
106
|
+
if n == "o":
|
|
107
|
+
return O_KICKS
|
|
108
|
+
return JLSTZ_KICKS_180
|
|
109
|
+
|
|
110
|
+
def _get_kicks_for(name: str, fr: str, to: str, direction: int) -> List[Tuple[int,int]]:
|
|
111
|
+
table = _kick_table_180(name) if direction == 2 else _kick_table(name)
|
|
112
|
+
if (fr, to) in table:
|
|
113
|
+
return list(table[(fr,to)])
|
|
114
|
+
if (to, fr) in table:
|
|
115
|
+
return [(-dx, -dy) for dx, dy in table[(to, fr)]]
|
|
116
|
+
return [(0,0)]
|
|
117
|
+
|
|
118
|
+
def try_rotate_srs(
|
|
119
|
+
name: str,
|
|
120
|
+
pos: Pos,
|
|
121
|
+
rot_label: str,
|
|
122
|
+
direction: int,
|
|
123
|
+
board,
|
|
124
|
+
collides_fn: CollidesFn,
|
|
125
|
+
) -> Tuple[str, Pos, bool]: # false if no kick
|
|
126
|
+
name = name.lower()
|
|
127
|
+
if rot_label not in ROT_SEQ:
|
|
128
|
+
raise ValueError("invalid rotation")
|
|
129
|
+
if direction not in (1, -1, 2):
|
|
130
|
+
return rot_label, pos, False
|
|
131
|
+
|
|
132
|
+
to_label = rotate_label(rot_label, direction)
|
|
133
|
+
|
|
134
|
+
off_from = _offset_for(name, rot_label)
|
|
135
|
+
off_to = _offset_for(name, to_label)
|
|
136
|
+
delta_off = (off_from[0] - off_to[0], off_from[1] - off_to[1])
|
|
137
|
+
|
|
138
|
+
kicks = _get_kicks_for(name, rot_label, to_label, direction)
|
|
139
|
+
|
|
140
|
+
for dx, dy in kicks:
|
|
141
|
+
tx = pos[0] + dx + delta_off[0]
|
|
142
|
+
ty = pos[1] + dy + delta_off[1]
|
|
143
|
+
if not collides_fn(name, to_label, (tx, ty)):
|
|
144
|
+
return to_label, (tx, ty), True
|
|
145
|
+
return rot_label, pos, False
|
|
146
|
+
|
|
147
|
+
def rotate_srs(
|
|
148
|
+
piece: dict,
|
|
149
|
+
direction: int,
|
|
150
|
+
board,
|
|
151
|
+
collides_fn: CollidesFn,
|
|
152
|
+
) -> bool:
|
|
153
|
+
name = piece["name"]
|
|
154
|
+
pos = tuple(piece["pos"])
|
|
155
|
+
rot = piece["rotation"]
|
|
156
|
+
new_rot, new_pos, ok = try_rotate_srs(name, pos, rot, direction, board, collides_fn)
|
|
157
|
+
if ok:
|
|
158
|
+
piece["rotation"] = new_rot
|
|
159
|
+
piece["pos"] = [int(new_pos[0]), int(new_pos[1])]
|
|
160
|
+
return True
|
|
161
|
+
return False
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cetragm
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.5
|
|
4
4
|
Summary: Cetra Grand Master | An oddly familiar block stacker in the command line!
|
|
5
5
|
License-Expression: GPL-3.0-only
|
|
6
6
|
License-File: LICENSE
|
|
@@ -29,22 +29,21 @@ Features:
|
|
|
29
29
|
- Dynamic gravity (speed) as your level increases
|
|
30
30
|
- Scoring system
|
|
31
31
|
- Gameplay timer
|
|
32
|
-
- 7-bag piece drawing
|
|
32
|
+
- 7-bag piece drawing
|
|
33
33
|
- 5-piece next queue and level display
|
|
34
34
|
- Persistent TLS (or shadow piece)
|
|
35
35
|
- TGM's 20G gravity after level 500
|
|
36
36
|
- Proper ARE, lock delay, and line clear delay
|
|
37
37
|
- Real-time gravity (not tied to frame rates)
|
|
38
|
+
- The standard Super Rotation System and all its janky kicks!
|
|
38
39
|
|
|
39
40
|
Drawbacks:
|
|
40
41
|
- Requires manual ARR/DAS and can't press two keys at once
|
|
41
|
-
- Very sub-par rotation system
|
|
42
42
|
- Scoring is slightly off
|
|
43
43
|
- Lack of theming or menus at all, as well as a lose state
|
|
44
44
|
- No sound (background or effect)
|
|
45
45
|
|
|
46
46
|
To add by next week:
|
|
47
|
-
- The Super Rotation System and standard wallkicks
|
|
48
47
|
- T-spins and detection for them
|
|
49
48
|
- IHS and IRS (Inital Hold/Rotation System)
|
|
50
49
|
- Full menu with configuration
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
cetragm/__init__.py,sha256=okJMmUyau9oeoBfxhg6AYZn4nPvcTqLrAgzIDpUXMz8,382
|
|
2
|
+
cetragm/audio.py,sha256=-w9omAYlvbUPRHuOe0IOBCSbBnjaOM9MjQy6oRU-hgA,47
|
|
3
|
+
cetragm/bag.py,sha256=qPvDmKoduJPZuwz5DMhh9rp85MUEfUPuiFsqOfJNq2U,704
|
|
4
|
+
cetragm/config.py,sha256=tJjbKxtwIWb3AMmIyBUosWkyHFO0OEzpYbqO5PHxz84,550
|
|
5
|
+
cetragm/controls.py,sha256=iR-ZpudiE6J92FMZmOwZlZpcOUhxfc1bWvb18VR4Cbk,3165
|
|
6
|
+
cetragm/draw.py,sha256=F4GZhNAXhxyPCksY0Pq4wjJQ904pgqCrCZ2ZDfgZHlU,6459
|
|
7
|
+
cetragm/game.py,sha256=TkvIb_F3dmlChoOXOKH_vJVPEnnB7NjaIJdNpal7McM,3110
|
|
8
|
+
cetragm/main.py,sha256=h5x-ZU_9_gVBWSWUGyDwuW8ZnRZcfPmLGoOPx0UKfBE,11487
|
|
9
|
+
cetragm/player.py,sha256=9KL5cNDYCp98OB7AiVdKISCbnmSqMn0StM2Ve3OHWGE,2469
|
|
10
|
+
cetragm/srs.py,sha256=YXXTkidVUiM9G9QCptzcgJBzgDNdIGHNndFlTp2TK_4,4867
|
|
11
|
+
cetragm/tables.py,sha256=MCLD4tz5fO0YJJwEqdqmXegR24kzjWkzvZP5Ev6fQEQ,12220
|
|
12
|
+
cetragm/ui.txt,sha256=7wSQU8ht-5A2Fz5iFbuLTdzc1Cl6otcnqIRUw5_wZoM,2006
|
|
13
|
+
cetragm-0.1.5.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
14
|
+
cetragm-0.1.5.dist-info/WHEEL,sha256=Jb20R3Ili4n9P1fcwuLup21eQ5r9WXhs4_qy7VTrgPI,79
|
|
15
|
+
cetragm-0.1.5.dist-info/entry_points.txt,sha256=m6wjlRzXqvDPFceo250KJO4LDsEp_q2rBcCZa2lDcpo,73
|
|
16
|
+
cetragm-0.1.5.dist-info/METADATA,sha256=iu3N60i-sJt_saxw-_gDWGLnP7WF4mvl1Rrx4uGe1Is,3134
|
|
17
|
+
cetragm-0.1.5.dist-info/RECORD,,
|
cetragm-0.1.2.dist-info/RECORD
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
cetragm/__init__.py,sha256=okJMmUyau9oeoBfxhg6AYZn4nPvcTqLrAgzIDpUXMz8,382
|
|
2
|
-
cetragm/audio.py,sha256=-w9omAYlvbUPRHuOe0IOBCSbBnjaOM9MjQy6oRU-hgA,47
|
|
3
|
-
cetragm/bag.py,sha256=GOLle_p4uJIDAr81d6mT6ERK6g9N97tYTL53a5JExzA,700
|
|
4
|
-
cetragm/config.py,sha256=tJjbKxtwIWb3AMmIyBUosWkyHFO0OEzpYbqO5PHxz84,550
|
|
5
|
-
cetragm/controls.py,sha256=5KiPc2UlB-mdYik48F-qrhZPWwPjneGicoAcEWtcyrE,3161
|
|
6
|
-
cetragm/draw.py,sha256=t_kRyYDo6miDCKzVFUBmjyBA3BYbzxN49p_85DYpwcU,6451
|
|
7
|
-
cetragm/game.py,sha256=ko2ADM8q3AkXdEwQIwva4MFA2PCKOlaETjmp_Qbgwz0,3186
|
|
8
|
-
cetragm/main.py,sha256=8TChVoLKkSr13nMhxPMIkNBV13_Iw-fnubJWnZzPUUQ,9971
|
|
9
|
-
cetragm/player.py,sha256=BjmsyZ8XYMq8nn2T28Ze23Ey1GMv1LrzRw7OSFJYJb8,2436
|
|
10
|
-
cetragm/srs.py,sha256=AV-JXtGqX6bc9mvSSlSngL5squr4P_qYz7tbBghZBB0,86
|
|
11
|
-
cetragm/tables.py,sha256=MCLD4tz5fO0YJJwEqdqmXegR24kzjWkzvZP5Ev6fQEQ,12220
|
|
12
|
-
cetragm/ui.txt,sha256=7wSQU8ht-5A2Fz5iFbuLTdzc1Cl6otcnqIRUw5_wZoM,2006
|
|
13
|
-
cetragm-0.1.2.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
14
|
-
cetragm-0.1.2.dist-info/WHEEL,sha256=Jb20R3Ili4n9P1fcwuLup21eQ5r9WXhs4_qy7VTrgPI,79
|
|
15
|
-
cetragm-0.1.2.dist-info/entry_points.txt,sha256=8jMkTAJSkUBD_f2FGMlk9_AdrWzhj9Ohv8TKfA1kSuk,71
|
|
16
|
-
cetragm-0.1.2.dist-info/METADATA,sha256=ysMe2qfpxFpM96jXxsq3MomX6b77kIPe6Hk1zXtQFiU,3191
|
|
17
|
-
cetragm-0.1.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|