Files
2026-10-09 18:23:57 +08:00

91 lines
3.8 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
#
# 医疗物品:自定义蓄力物品(custom_item_type: ranged_weapon)
# 右键按下开始蓄力,右键抬起触发 ItemReleaseUsingServerEvent;
# 蓄满才生效并消耗 1 个,未蓄满松开则取消(不生效、不消耗)。
import mod.server.extraServerApi as serverApi
compFactory = serverApi.GetEngineCompFactory()
PLASTER = "dn_sa_plaster:bow"
SPLINT = "dn_sa_splint:bow"
ALCOHOL_WIPES = "dn_sa_alcohol_wipes:bow"
BLOOD_BAG = "dn_sa:blood_bag"
BLOOD_BAG_EMPTY = "dn_sa:blood_bag_empty"
# 蓄满所需持有时长(tick,20 tick = 1 秒)
CHARGE_TICKS = 60
CHARGE_ITEMS = (PLASTER, SPLINT, ALCOHOL_WIPES)
HEAL_AMOUNT = 6.0 # 血袋回血量
DONATE_TOTAL = 6 # 空血袋总扣血量
DONATE_STEP = 1.0 # 每次扣血量
DONATE_INTERVAL = 0.5 # 扣血间隔秒数
class MedicalServer(serverApi.GetServerSystemCls()):
def __init__(self, namespace, name):
super(MedicalServer, self).__init__(namespace, name)
self.ListenForEvent(serverApi.GetEngineNamespace(), serverApi.GetEngineSystemName(),
"ItemReleaseUsingServerEvent", self, self.OnReleaseUsing)
self.ListenForEvent(serverApi.GetEngineNamespace(), serverApi.GetEngineSystemName(),
"PlayerEatFoodServerEvent", self, self.OnEatFood)
# ---------- 蓄力物品 ----------
def OnReleaseUsing(self, args):
playerId = args.get("playerId")
itemName = (args.get("itemDict") or {}).get("itemName")
if not playerId or itemName not in CHARGE_ITEMS:
return
# 已持有帧数 = 最大使用时长 - 剩余时长
maxUse = args.get("maxUseDuration") or 0
durationLeft = args.get("durationLeft") or 0
held = (maxUse - durationLeft) if maxUse > 0 else CHARGE_TICKS
# 未蓄满:取消本次使用
if held < CHARGE_TICKS:
args["cancel"] = True
return
# 蓄满:施加效果
effectComp = compFactory.CreateEffect(playerId)
if itemName == PLASTER:
effectComp.AddEffectToEntity("regeneration", 5, 0, False)
elif itemName == SPLINT:
effectComp.AddEffectToEntity("resistance", 10, 0, False)
elif itemName == ALCOHOL_WIPES:
effectComp.RemoveEffectFromEntity("poison")
# 消耗 1 个
self._ConsumeOne(playerId)
args["changeItem"] = True
def _ConsumeOne(self, playerId):
itemComp = compFactory.CreateItem(playerId)
slotId = itemComp.GetSelectSlotId()
itemDict = itemComp.GetPlayerItem(serverApi.GetMinecraftEnum().ItemPosType.INVENTORY, slotId, True)
if not itemDict:
return
count = itemDict.get("count", 1)
itemComp.SetInvItemNum(slotId, count - 1)
# ---------- 血袋 / 空血袋 ----------
def OnEatFood(self, args):
playerId = args.get("playerId")
itemName = (args.get("itemDict") or {}).get("itemName")
if not playerId:
return
if itemName == BLOOD_BAG:
self._AddHealth(playerId, HEAL_AMOUNT)
elif itemName == BLOOD_BAG_EMPTY:
for i in range(1, DONATE_TOTAL + 1):
self.AddTimer(DONATE_INTERVAL * i, self._AddHealth, playerId, -DONATE_STEP)
self.AddTimer(DONATE_INTERVAL * (DONATE_TOTAL + 1), self._GiveBloodBag, playerId)
def _AddHealth(self, playerId, delta):
attrType = serverApi.GetMinecraftEnum().AttrType.HEALTH
attrComp = compFactory.CreateAttr(playerId)
cur = attrComp.GetAttrValue(attrType)
limit = attrComp.GetAttrMaxValue(attrType)
attrComp.SetAttrValue(attrType, max(0.0, min(cur + delta, limit)))
def _GiveBloodBag(self, playerId):
itemDict = {"itemName": BLOOD_BAG, "count": 1, "auxValue": 0}
compFactory.CreateItem(playerId).SpawnItemToPlayerInv(itemDict, playerId, -1)