Skip to content

Commit e4d16a7

Browse files
committed
craftに対応
1 parent e5b161b commit e4d16a7

File tree

4 files changed

+143
-5
lines changed

4 files changed

+143
-5
lines changed

.github/workflows/docs.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,11 @@ jobs:
2828
- name: Build documentation
2929
run: |
3030
cd docs
31-
make html
31+
make github
3232
3333
- name: Deploy to GitHub Pages
3434
uses: peaceiris/actions-gh-pages@v3
3535
with:
3636
github_token: ${{ secrets.GITHUB_TOKEN }}
37-
publish_dir: ./docs/_build/html
37+
publish_dir: ./docs
3838
publish_branch: gh-pages

py2hackCraft/modules.py

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1920,3 +1920,137 @@ def get_block_by_color(self, color: str) -> Block:
19201920
self.client.send_call(self.uuid, "blockColor", [color])
19211921
block = Block(** json.loads(self.client.result))
19221922
return block
1923+
1924+
def _convert_recipe_pattern(self, recipe):
1925+
"""
1926+
Convert recipe pattern to comma-separated string format.
1927+
1928+
Handles two input formats:
1929+
1. String: "1,1,1,,2,,,2" -> returns as-is
1930+
2. List: [1,1,1,None,2,None,None,2] -> "1,1,1,,2,,,2"
1931+
1932+
Args:
1933+
recipe: Recipe pattern as string or list
1934+
1935+
Returns:
1936+
str: Comma-separated string pattern
1937+
1938+
Raises:
1939+
ValueError: If pattern is invalid
1940+
"""
1941+
# If already a string, validate and return
1942+
if isinstance(recipe, str):
1943+
if not recipe.strip():
1944+
raise ValueError("Pattern cannot be empty")
1945+
1946+
elements = recipe.split(",")
1947+
if len(elements) > 9:
1948+
raise ValueError(f"Pattern exceeds 3x3 grid size (max 9 elements, got {len(elements)})")
1949+
1950+
# Validate each non-empty element is a valid number or 'X'
1951+
for i, element in enumerate(elements):
1952+
trimmed = element.strip()
1953+
if trimmed:
1954+
# Allow 'X' or 'x' as AIR placeholder
1955+
if trimmed.upper() == 'X':
1956+
continue
1957+
try:
1958+
int(trimmed)
1959+
# Allow any integer (negative values are treated as AIR on server)
1960+
except ValueError as e:
1961+
if "invalid literal" in str(e):
1962+
raise ValueError(f"Invalid slot number at position {i}: '{element}' (use number or 'X' for empty)")
1963+
raise
1964+
1965+
return recipe
1966+
1967+
# List format
1968+
if isinstance(recipe, list):
1969+
if len(recipe) == 0:
1970+
raise ValueError("Pattern list cannot be empty")
1971+
1972+
if len(recipe) > 9:
1973+
raise ValueError(f"Pattern exceeds 3x3 grid size (max 9 elements, got {len(recipe)})")
1974+
1975+
# Validate and convert to string
1976+
result = []
1977+
for i, slot in enumerate(recipe):
1978+
if slot is None or slot == "":
1979+
result.append("")
1980+
elif isinstance(slot, str):
1981+
# Allow 'X' or 'x' as AIR placeholder, convert to -1
1982+
if slot.strip().upper() == 'X':
1983+
result.append("-1")
1984+
else:
1985+
raise ValueError(f"Invalid slot value at position {i}: '{slot}' (use number, None, or 'X')")
1986+
elif isinstance(slot, int):
1987+
# Allow any integer (negative values are treated as AIR on server)
1988+
result.append(str(slot))
1989+
else:
1990+
raise ValueError(f"Invalid slot value at position {i}: {slot}")
1991+
1992+
return ",".join(result)
1993+
1994+
raise ValueError("Recipe pattern must be a string or list")
1995+
1996+
def craft(self, recipe, qty=1, slot=None):
1997+
"""
1998+
ペットのインベントリにある材料を使ってアイテムをクラフトする。
1999+
2000+
引数:
2001+
recipe: レシピパターン(文字列またはリスト形式)
2002+
- 文字列形式: "1,1,1,X,2,X,X,2,X" (カンマ区切りのスロット番号、空は X または空文字)
2003+
- リスト形式: [1,1,1,"X",2,"X","X",2,"X"] または [1,1,1,None,2,None,None,2,None]
2004+
- スロット番号は0から始まる(0=スロット1)
2005+
- 負の数(-1など)も空気として扱われる
2006+
qty: クラフトする個数(デフォルト: 1)
2007+
slot: 結果を配置するスロット番号(デフォルト: None = 自動配置)
2008+
2009+
戻り値:
2010+
dict: クラフト結果(以下の構造)
2011+
{
2012+
"success": bool, # 成功したか
2013+
"result_item": str | None, # 作成されたアイテム名
2014+
"result_quantity": int | None,# 作成された個数
2015+
"requested_quantity": int, # リクエストした個数
2016+
"result_slot": int | None, # 配置されたスロット
2017+
"materials_consumed": dict, # 消費された材料
2018+
"game_mode": str, # ゲームモード
2019+
"error": dict | None # エラー情報
2020+
}
2021+
2022+
使用例:
2023+
>>> # パンをクラフト(スロット0に小麦3つ)
2024+
>>> result = entity.craft("0,0,0")
2025+
>>> if result["success"]:
2026+
>>> print(f"{result['result_item']}を{result['result_quantity']}個作ったよ!")
2027+
2028+
>>> # リスト形式でつるはしをクラフト
2029+
>>> result = entity.craft([3,3,3,"X",4,"X","X",4,"X"])
2030+
2031+
>>> # 複数個クラフトして、スロット10に配置
2032+
>>> result = entity.craft("0,0,0", qty=5, slot=10)
2033+
2034+
>>> # エラー処理
2035+
>>> result = entity.craft("0,0,0")
2036+
>>> if not result["success"]:
2037+
>>> error = result["error"]
2038+
>>> print(f"エラー: {error['message']}")
2039+
>>> if error["code"] == "INSUFFICIENT_MATERIALS":
2040+
>>> print("材料が足りないよ")
2041+
"""
2042+
# Convert recipe to string format
2043+
pattern = self._convert_recipe_pattern(recipe)
2044+
2045+
# Prepare arguments
2046+
args = [pattern, qty]
2047+
if slot is not None:
2048+
args.append(slot)
2049+
2050+
# Send craft request
2051+
self.client.send_call(self.uuid, "craft", args)
2052+
2053+
# Parse response
2054+
result = json.loads(self.client.result)
2055+
2056+
return result

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
setup(
44
name="py2hackCraft2",
5-
version="1.1.41",
5+
version="1.1.42",
66
packages=find_packages(),
77
install_requires=[
88
"websocket-client>=1.6.0",

test.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@
22
player = Player("o2nerocha")
33
player.login("localhost", 25570)
44

5-
hello = player.get_entity("hello")
5+
hello = player.get_entity("test")
66

7-
hello.teleport(LocationFactory.absolute(276, 62, 92))
7+
recip = [3,3,3,
8+
-1,4,-1,
9+
-1,4,-1]
810

11+
ret = hello.craft(recip, 2, 11)
12+
print(ret)

0 commit comments

Comments
 (0)