From c9870f5d66f2b439658945fbf2dcbf4c29e1445f Mon Sep 17 00:00:00 2001 From: Naruse <71993948+DevilProMT@users.noreply.github.com> Date: Mon, 18 Nov 2024 13:06:18 +0800 Subject: [PATCH] feat: Implement stigmata standard reroll --- database/save_data.py | 7 ++ .../game/inventory/inventory_manager.py | 12 +++ game_server/game/player/__init__.py | 11 ++- .../packet/handlers/GetEquipmentDataReq.py | 32 ++++++-- .../packet/handlers/RefineStigmataRuneReq.py | 74 +++++++++++++++++++ .../handlers/SelectNewStigmataRuneReq.py | 38 ++++++++++ game_server/resource/configdb/affix_list.py | 15 ++++ 7 files changed, 181 insertions(+), 8 deletions(-) create mode 100644 game_server/packet/handlers/RefineStigmataRuneReq.py create mode 100644 game_server/packet/handlers/SelectNewStigmataRuneReq.py create mode 100644 game_server/resource/configdb/affix_list.py diff --git a/database/save_data.py b/database/save_data.py index c8b359f..dc0630c 100644 --- a/database/save_data.py +++ b/database/save_data.py @@ -61,6 +61,13 @@ class SaveData: "Exp": get_item.exp, "SlotNum": get_item.slot_num, "IsLocked" : get_item.is_locked, + "RuneLists": [ + { + "RuneId":rune.rune_id, + "strengthPercent":rune.strength_percent + } + for rune in get_item.rune_list + ], "EquipAvatarID" : get_item.equip_avatar_id } } diff --git a/game_server/game/inventory/inventory_manager.py b/game_server/game/inventory/inventory_manager.py index 4b943f6..9b378f6 100644 --- a/game_server/game/inventory/inventory_manager.py +++ b/game_server/game/inventory/inventory_manager.py @@ -14,6 +14,16 @@ class Weapon: is_extracted : bool equip_avatar_id: int +@dataclasses.dataclass +class RuneList: + rune_id : int + strength_percent : int + +@dataclasses.dataclass +class RuneGroup: + unique_id : int + rune_list : list[RuneList] + @dataclasses.dataclass class Stigmata: item_id : int @@ -24,6 +34,8 @@ class Stigmata: promote_times : int is_locked : bool equip_avatar_id : int + rune_list : list[RuneList] = dataclasses.field(default_factory=list) + wait_select_rune_group_list: list[RuneGroup] = dataclasses.field(default_factory=list) @dataclasses.dataclass class InventoryManager: diff --git a/game_server/game/player/__init__.py b/game_server/game/player/__init__.py index 30e8268..0cf47a7 100644 --- a/game_server/game/player/__init__.py +++ b/game_server/game/player/__init__.py @@ -1,7 +1,7 @@ import dataclasses from database import mongo from game_server.game.avatar.avatar_manager import AvatarManager,Skill,AvatarSubSkill,AvatarTeamManager -from game_server.game.inventory.inventory_manager import InventoryManager,Material,Weapon,Stigmata +from game_server.game.inventory.inventory_manager import InventoryManager,Material,Weapon,Stigmata,RuneList,RuneGroup from game_server.game.elf.elf_manager import ElfManager,ElfSkill from game_server.game.enum.item_type import MainType @@ -107,7 +107,14 @@ class Player: refine_value=item['RefineValue'], promote_times=item['PromoteTimes'], is_locked=item['IsLocked'], - equip_avatar_id=item['EquipAvatarID'] + equip_avatar_id=item['EquipAvatarID'], + rune_list=[ + RuneList( + rune_id=rune['RuneId'], + strength_percent=rune['strengthPercent'] + ) + for rune in item['RuneLists'] + ] ) self.inventory.stigmata_items[item['UniqueID']] = stigmata diff --git a/game_server/packet/handlers/GetEquipmentDataReq.py b/game_server/packet/handlers/GetEquipmentDataReq.py index 71ce53f..1ba8e98 100644 --- a/game_server/packet/handlers/GetEquipmentDataReq.py +++ b/game_server/packet/handlers/GetEquipmentDataReq.py @@ -1,15 +1,14 @@ import betterproto from typing import List from game_server.net.session import Session -from game_server.resource import ResourceManager -from game_server.resource.configdb.weapon_data import WeaponData -from game_server.resource.configdb.stigmata_data import StigmataData from lib.proto import ( GetEquipmentDataReq, GetEquipmentDataRsp, Material, Weapon, Stigmata, + StigmataRuneGroup, + StigmataRune ) async def handle(session: Session, msg: GetEquipmentDataReq) -> betterproto.Message: @@ -23,7 +22,8 @@ async def handle(session: Session, msg: GetEquipmentDataReq) -> betterproto.Mess level=weapon.level, exp=weapon.exp, is_protected=weapon.is_locked, - is_extracted=weapon.is_extracted + is_extracted=weapon.is_extracted, + homology_level=3 ) for id, weapon in session.player.inventory.weapon_items.items() ], @@ -33,10 +33,30 @@ async def handle(session: Session, msg: GetEquipmentDataReq) -> betterproto.Mess id=stigmata.item_id, level=stigmata.level, exp=stigmata.exp, - slot_num=stigmata.slot_num, + slot_num=2, refine_value=stigmata.refine_value, promote_times=stigmata.promote_times, - is_protected=stigmata.is_locked + is_protected=stigmata.is_locked, + rune_list=[ + StigmataRune( + rune_id=rune.rune_id, + strength_percent=rune.strength_percent + ) + for rune in stigmata.rune_list + ], + wait_select_rune_group_list=[ + StigmataRuneGroup( + unique_id=index, + rune_list=[ + StigmataRune( + rune_id=rune.rune_id, + strength_percent=rune.strength_percent + ) + for rune in affix.rune_list + ] + ) + for index,affix in enumerate(stigmata.wait_select_rune_group_list, start=1) + ] ) for id, stigmata in session.player.inventory.stigmata_items.items() ], diff --git a/game_server/packet/handlers/RefineStigmataRuneReq.py b/game_server/packet/handlers/RefineStigmataRuneReq.py new file mode 100644 index 0000000..25e0028 --- /dev/null +++ b/game_server/packet/handlers/RefineStigmataRuneReq.py @@ -0,0 +1,74 @@ +import betterproto +import random +from game_server.net.session import Session +from game_server.resource import ResourceManager +from game_server.resource.configdb.affix_list import AffixListData +from game_server.game.inventory.inventory_manager import RuneList,RuneGroup +from lib.proto import ( + RefineStigmataRuneReq, + RefineStigmataRuneRsp, + StigmataRuneGroup, + StigmataRune, + StigmataRefineTimesType, + GetEquipmentDataReq +) + +def generate_affix_and_percentage(affix_ids): + affix_id1, affix_id2 = random.choice(affix_ids), random.choice(affix_ids) + percentage1, percentage2 = [ + random.randint(*r) for r in random.choices( + [(20, 50), (50, 70), (80, 100)], weights=[50, 40, 10], k=2 + ) + ] + return {"affix1": affix_id1, "percentage1": percentage1, "affix2": affix_id2, "percentage2": percentage2} + +async def handle(session: Session, msg: RefineStigmataRuneReq) -> betterproto.Message: + stigmata_data = session.player.inventory.stigmata_items.get(msg.unique_id) + affix_ids = [affix.affixID for affix in ResourceManager.instance().values(AffixListData)] + result = [] + if msg.times_type == StigmataRefineTimesType.STIGMATA_REFINE_TIMES_TEN.value: + result = [generate_affix_and_percentage(affix_ids) for _ in range(10)] + else: + result.append(generate_affix_and_percentage(affix_ids)) + stigmata_data.wait_select_rune_group_list = [] + stigmata_data.wait_select_rune_group_list.extend( + [ + RuneGroup( + unique_id=index, + rune_list=[ + RuneList( + rune_id=affix['affix1'], + strength_percent=affix['percentage1'] + ), + RuneList( + rune_id=affix['affix2'], + strength_percent=affix['percentage2'] + ) + ] + ) + for index, affix in enumerate(result, start=1) + ] + ) + + await session.process_packet(session.create_packet(GetEquipmentDataReq())) + + return RefineStigmataRuneRsp( + retcode=0, + rune_group_list=[ + StigmataRuneGroup( + unique_id=index, + rune_list=[ + StigmataRune( + rune_id=affix['affix1'], + strength_percent=affix['percentage1'] + ), + StigmataRune( + rune_id=affix['affix2'], + strength_percent=affix['percentage2'] + ), + ] + ) + for index, affix in enumerate(result, start=1) + ], + times_type=10 if msg.times_type > 0 else 1 + ) diff --git a/game_server/packet/handlers/SelectNewStigmataRuneReq.py b/game_server/packet/handlers/SelectNewStigmataRuneReq.py new file mode 100644 index 0000000..434896f --- /dev/null +++ b/game_server/packet/handlers/SelectNewStigmataRuneReq.py @@ -0,0 +1,38 @@ + +import betterproto +from game_server.net.session import Session +from game_server.game.inventory.inventory_manager import RuneList +from game_server.game.enum.data_type import DataType +from database import mongo +from lib.proto import ( + SelectNewStigmataRuneReq, + SelectNewStigmataRuneRsp, + GetEquipmentDataReq +) + +async def handle(session: Session, msg: SelectNewStigmataRuneReq) -> betterproto.Message: + stigmata_data = session.player.inventory.stigmata_items.get(msg.unique_id) + + if msg.select_unique_id > 0 and msg.is_select: + affix_data = [affix for affix in stigmata_data.wait_select_rune_group_list if msg.select_unique_id == affix.unique_id][0] + stigmata_data.rune_list = [] + stigmata_data.rune_list.extend( + [ + RuneList( + rune_id=rune.rune_id, + strength_percent=rune.strength_percent + ) + for rune in affix_data.rune_list + ] + ) + mongo.save(session,DataType.STIGMATA,[msg.unique_id]) + + stigmata_data.wait_select_rune_group_list = [] + await session.process_packet(session.create_packet(GetEquipmentDataReq())) + + return SelectNewStigmataRuneRsp( + retcode=0, + select_unique_id=msg.select_unique_id, + is_select=msg.is_select + ) + diff --git a/game_server/resource/configdb/affix_list.py b/game_server/resource/configdb/affix_list.py new file mode 100644 index 0000000..2bff477 --- /dev/null +++ b/game_server/resource/configdb/affix_list.py @@ -0,0 +1,15 @@ +from dataclasses import dataclass +from game_server.resource.base_resource import BaseResource +from game_server.resource.decorators import GameResource + +@dataclass +@GameResource("resources/ExcelOutputAsset/AffixList.json") +class AffixListData(BaseResource): + affixID: int + level: int + + def on_load(self) -> bool: + return self.level == 3 + + def get_index(self) -> str: + return str(self.affixID)