forked from yihuai-gao/genius-invokation-gym
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
3b91069
commit f735eac
Showing
5 changed files
with
293 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
from typing import cast | ||
|
||
### import other status from card files | ||
from gisim.cards import get_character_status as import_cards_character_status | ||
from gisim.cards import get_combat_status as import_cards_combat_status | ||
from gisim.classes.enums import CharPos, ElementType, PlayerID, StatusType | ||
from gisim.classes.status import CharacterStatusEntity, CombatStatusEntity | ||
from gisim.env import INF_INT | ||
|
||
from .reaction_status import * | ||
|
||
### | ||
|
||
|
||
def get_combat_status( | ||
name: str, player_id: PlayerID, position: CharPos, remaining_round: int | ||
): | ||
name = name.replace(" ", "").replace("'", "") | ||
if not name.endswith("Status"): | ||
name += "Status" | ||
if name in globals(): | ||
status_class = globals()[name] | ||
status: CombatStatusEntity = status_class( | ||
player_id=player_id, position=position, remaining_round=remaining_round | ||
) | ||
return status | ||
else: | ||
return import_cards_combat_status(name, player_id, position, remaining_round) | ||
|
||
|
||
def get_character_status( | ||
name: str, player_id: PlayerID, position: CharPos, remaining_round: int | ||
): | ||
name = name.replace(" ", "") | ||
if not name.endswith("Status"): | ||
name += "Status" | ||
if name.endswith("InfusionStatus"): | ||
elem_char = name.replace("InfusionStatus", "").upper() | ||
element: ElementType = eval(f"ElementType.{elem_char}") | ||
status = ElementalInfusionStatus( | ||
name=name, | ||
player_id=player_id, | ||
position=position, | ||
remaining_round=remaining_round, | ||
element=element, | ||
) | ||
status = cast(CharacterStatusEntity, status) | ||
return status | ||
|
||
if name in globals(): | ||
status_class = globals()[name] | ||
status: CharacterStatusEntity = status_class( | ||
player_id=player_id, position=position, remaining_round=remaining_round | ||
) | ||
return status | ||
|
||
else: | ||
return import_cards_character_status(name, player_id, position, remaining_round) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,232 @@ | ||
from queue import PriorityQueue | ||
from typing import cast | ||
|
||
from gisim.classes.enums import CharPos, ElementType, PlayerID, StatusType | ||
from gisim.classes.message import DealDamageMsg, Message, RoundEndMsg | ||
from gisim.classes.status import CharacterStatusEntity, CombatStatusEntity | ||
from gisim.env import INF_INT | ||
|
||
|
||
class ElementalInfusionStatus(CharacterStatusEntity): | ||
"""元素附魔""" | ||
|
||
name: str | ||
element: ElementType | ||
description: str = "Convert physical damage into elemental damage" | ||
value: int = 0 | ||
active: bool = True | ||
remaining_usage: int = INF_INT | ||
|
||
def msg_handler(self, msg_queue: PriorityQueue): | ||
top_msg = msg_queue.queue[0] | ||
if self._uuid in top_msg.responded_entities: | ||
return False | ||
updated = False | ||
if isinstance(top_msg, DealDamageMsg): | ||
top_msg = cast(DealDamageMsg, top_msg) | ||
if top_msg.attacker == (self.player_id, self.position): | ||
for idx, target in enumerate(top_msg.targets): | ||
if target[2] == ElementType.NONE: | ||
print( | ||
f" Character Status Effect:\n {self.name}:{self.description}\n Origin DMG: {target[2]} -> {target[3]} + Add: 0\n {self.player_id.name}-{self.position}\n" | ||
) | ||
top_msg.targets[idx] = ( | ||
target[0], | ||
target[1], | ||
self.element, | ||
target[3], | ||
) | ||
updated = True | ||
|
||
if isinstance(top_msg, RoundEndMsg): | ||
top_msg = cast(RoundEndMsg, top_msg) | ||
assert ( | ||
self.remaining_round >= 1 | ||
), "Remaining round should not be lower than 1!" | ||
self.remaining_round -= 1 | ||
if self.remaining_round == 0: | ||
self.active = False | ||
if updated: | ||
top_msg.responded_entities.append(self._uuid) | ||
return updated | ||
|
||
|
||
###### Status generated by elemental reactions ###### | ||
|
||
|
||
class DendroCoreStatus(CombatStatusEntity): | ||
"""[Combat Status]When you deal Icon TCG PyroPyro DMG or Icon TCG ElectroElectro DMG to an opposing active character, | ||
DMG dealt +2. (1 Usage) | ||
""" | ||
|
||
name: str = "Dendro Core" | ||
description: str = """When you deal Icon TCG PyroPyro DMG or Icon TCG ElectroElectro DMG to an opposing active character, DMG dealt +2. (1 Usage)""" | ||
active: bool = True | ||
value: int = 0 | ||
remaining_round: int = INF_INT | ||
remaining_usage: int = 2 | ||
|
||
def msg_handler(self, msg_queue: PriorityQueue) -> bool: | ||
top_msg = msg_queue.queue[0] | ||
if isinstance(top_msg, DealDamageMsg): | ||
top_msg = cast(DealDamageMsg, top_msg) | ||
attacker_id, attacker_pos = top_msg.attacker | ||
if attacker_id == self.player_id: | ||
for idx, (target_id, target_pos, element_type, dmg_val) in enumerate( | ||
top_msg.targets | ||
): | ||
if element_type in [ElementType.PYRO, ElementType.ELECTRO]: | ||
print( | ||
f" Combat Status Effect By {self.player_id.name}:\n {self.name}:{self.description}\n Origin DMG: {element_type.name} -> {dmg_val} + {2}\n" | ||
) | ||
top_msg.targets[idx] = ( | ||
target_id, | ||
target_pos, | ||
element_type, | ||
dmg_val + 2, | ||
) | ||
self.remaining_usage -= 1 | ||
|
||
if self.remaining_usage == 0 or self.remaining_round == 0: | ||
self.active = False | ||
|
||
return False | ||
|
||
|
||
class CatalyzingFieldStatus(CombatStatusEntity): | ||
"""[Combat Status]When you deal Icon TCG ElectroElectro DMG or Icon TCG DendroDendro DMG to an opposing active character, | ||
DMG dealt +1. (3 Usages)""" | ||
|
||
name: str = "Catalyzing Field" | ||
description: str = """When you deal Icon TCG ElectroElectro DMG or Icon TCG DendroDendro DMG to an opposing active character, DMG dealt +1. (2 Usages)""" | ||
active: bool = True | ||
value: int = 0 | ||
remaining_round: int = INF_INT | ||
remaining_usage: int = 3 | ||
|
||
def msg_handler(self, msg_queue: PriorityQueue) -> bool: | ||
top_msg = msg_queue.queue[0] | ||
if isinstance(top_msg, DealDamageMsg): | ||
top_msg = cast(DealDamageMsg, top_msg) | ||
attacker_id, attacker_pos = top_msg.attacker | ||
if attacker_id == self.player_id: | ||
for idx, (target_id, target_pos, element_type, dmg_val) in enumerate( | ||
top_msg.targets | ||
): | ||
if element_type in [ElementType.DENDRO, ElementType.ELECTRO]: | ||
print( | ||
f" Combat Status Effect By {self.player_id.name}:\n {self.name}:{self.description}\n Origin DMG: {element_type.name} -> {dmg_val} + {2}\n" | ||
) | ||
top_msg.targets[idx] = ( | ||
target_id, | ||
target_pos, | ||
element_type, | ||
dmg_val + 1, | ||
) | ||
self.remaining_usage -= 1 | ||
|
||
if self.remaining_usage == 0 or self.remaining_round == 0: | ||
self.active = False | ||
|
||
return False | ||
|
||
|
||
class FrozenEffectStatus(CharacterStatusEntity): | ||
""" | ||
[Character Status]the target is unable to perform any Actions this round | ||
(Can be removed in advance after the target receives Physical or Pyro DMG, | ||
in which case they will take +2 DMG) | ||
""" | ||
|
||
name: str = "Frozen Effect" | ||
element: ElementType = ElementType.NONE | ||
description: str = """[Character Status]the target is unable to perform any Actions this round(Can be removed in advance after the target receives Physical or Pyro DMG, in which case they will take +2 DMG)""" | ||
value: int = 0 | ||
active: bool = True | ||
remaining_usage = 1 | ||
|
||
def msg_handler(self, msg_queue: PriorityQueue): | ||
top_msg = msg_queue.queue[0] | ||
updated = False | ||
if self._uuid in top_msg.responded_entities: | ||
return False | ||
|
||
if isinstance(top_msg, DealDamageMsg): | ||
top_msg = cast(DealDamageMsg, top_msg) | ||
if top_msg.damage_calculation_ended: | ||
return False | ||
for idx, (target_id, target_pos, element_type, dmg_val) in enumerate( | ||
top_msg.targets | ||
): | ||
if ( | ||
target_id == self.player_id | ||
and target_pos == self.position | ||
and element_type in [ElementType.NONE, ElementType.PYRO] | ||
): | ||
print( | ||
f" Character Status Effect:\n {self.name}:{self.description}\n Origin DMG: {element_type.name} -> {dmg_val} + Add: 2\n {self.player_id.name}-{self.position}\n" | ||
) | ||
|
||
top_msg.targets[idx] = ( | ||
target_id, | ||
target_pos, | ||
element_type, | ||
dmg_val + 2, | ||
) | ||
updated = True | ||
self.remaining_usage -= 1 | ||
|
||
if isinstance(top_msg, RoundEndMsg): | ||
self.remaining_round -= 1 | ||
if self.remaining_round == 0: | ||
self.active = False | ||
|
||
if updated: | ||
top_msg.responded_entities.append(self._uuid) | ||
return updated | ||
|
||
|
||
class ShieldStatus(CombatStatusEntity): | ||
"""Shield""" | ||
|
||
name: str = "Shield" | ||
description: str = "Shield" | ||
active: bool = True | ||
value: int = 0 | ||
remaining_round: int = INF_INT | ||
|
||
def msg_handler(self, msg_queue: PriorityQueue): | ||
top_msg = msg_queue.queue[0] | ||
updated = False | ||
|
||
if self._uuid in top_msg.responded_entities: | ||
return False | ||
|
||
if isinstance(top_msg, DealDamageMsg): | ||
top_msg = cast(DealDamageMsg, top_msg) | ||
|
||
for idx, (target_id, target_pos, element_type, dmg_val) in enumerate( | ||
top_msg.targets | ||
): | ||
if target_id == self.player_id and dmg_val > 0: | ||
print( | ||
f" Combat Status Effect By {self.player_id.name}:\n {self.name}:{self.description}\n Origin DMG: {element_type.name} -> {dmg_val} - {1}\n" | ||
) | ||
after_dmg = max(0, dmg_val - self.remaining_round) | ||
# 护盾只能抵消伤害,改挂元素还是得挂元素 | ||
|
||
top_msg.targets[idx] = ( | ||
target_id, | ||
target_pos, | ||
element_type, | ||
after_dmg, | ||
) | ||
self.remaining_usage = max(0, self.remaining_round - dmg_val) | ||
updated = True | ||
|
||
if self.remaining_usage == 0: | ||
self.active = False | ||
if updated: | ||
top_msg.responded_entities.append(self._uuid) | ||
|
||
return updated |