Keeps 71502/71505/71508/71511 and skins 71234/71254 as costumes, stages the npc_mount models of races 32012/32028, writes mobs-server.tsv and lets install_items.py install mob rows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
80 lines
3.2 KiB
PHP
80 lines
3.2 KiB
PHP
// PORT: AVA2 mount costume + mount skin (ENABLE_MOUNT_COSTUME_SYSTEM / ENABLE_MOUNT_SKIN), as module mt_mount.
|
|
// The server swaps the horse race for the worn costume's value0 (metin2-server port_mount.cpp); this script
|
|
// registers the AVA2 npclist rows of the skin races (npclist.txt is read from the root pack only, so a patch
|
|
// pack cannot add them; RaceManager's __IsNewMountRace adds npc_mount to their search path), adds the mount
|
|
// and skin slots to the costume window under the sash slot, and renders the "MTMOUNT <code>" server
|
|
// messages that replace AVA2's locale strings 334 / 1097 / 1098. Models ship in the ava2items pack
|
|
// (tools/server/ava2-items, MOUNT_MOBS).
|
|
static const char c_szMountScript[] = R"PY(# -*- coding: utf-8 -*-
|
|
import chat
|
|
import chrmgr
|
|
import game
|
|
import item
|
|
import player
|
|
import ui
|
|
import uiInventory
|
|
|
|
L=player.AutoHuntLocalize
|
|
# AVA2 root/npclist.txt rows of the races MOUNT_MOBS ships.
|
|
RACES=((32012,"christmas_2017_sleddog_02"),(32028,"christmas_2020_alpaca"))
|
|
SRC_NAMES=(("christmas_2017_sleddog_02","christmas_2017_sleddog"),)
|
|
MESSAGES={'riding':'骑乘中无法更换坐骑时装。','need_mount':'需要先装备坐骑时装。','has_skin':'请先卸下坐骑外观。',
|
|
'need_horse':'需要先拥有马匹(马匹等级 1 以上)才能召唤坐骑。'}
|
|
# Costume window: left column under the sash slot (CostumeSlot coordinates; body is at 61,45).
|
|
SLOTS=((item.COSTUME_SLOT_MOUNT,(13,45)),(item.COSTUME_SLOT_MOUNT_SKIN,(13,82)))
|
|
|
|
for race,name in RACES:chrmgr.RegisterRaceName(race,name)
|
|
for name,src in SRC_NAMES:chrmgr.RegisterRaceSrcName(name,src)
|
|
|
|
|
|
def FindChild(node,name):
|
|
if node.get("name")==name:return node
|
|
for child in node.get("children",()):
|
|
found=FindChild(child,name)
|
|
if found:return found
|
|
return None
|
|
|
|
|
|
def PatchCostumeWindow(window):
|
|
base=FindChild(window,"Costume_Base");slot=FindChild(window,"CostumeSlot")
|
|
if not base or not slot:return
|
|
frames=[];slots=[]
|
|
for index,(x,y) in SLOTS:
|
|
frames.append({"name":"MountSlotBase%d"%index,"type":"image","x":slot["x"]+x,"y":slot["y"]+y,"image":"d:/ymir work/ui/public/Slot_Base.sub"})
|
|
slots.append({"index":index,"x":x,"y":y,"width":32,"height":32})
|
|
base["children"]=tuple(frames)+tuple(base.get("children",()))
|
|
slot["slot"]=tuple(slot["slot"])+tuple(slots)
|
|
|
|
|
|
_execfile=ui.execfile
|
|
|
|
def ExecFile(fileName,dict):
|
|
_execfile(fileName,dict)
|
|
name=fileName.replace("\\","/").split("/")[-1].lower()
|
|
if name=="costumewindow.py" and "window" in dict:PatchCostumeWindow(dict["window"])
|
|
|
|
ui.execfile=ExecFile
|
|
|
|
_refreshCostume=uiInventory.CostumeWindow.RefreshCostumeSlot
|
|
|
|
def RefreshCostumeSlot(self):
|
|
_refreshCostume(self)
|
|
for index,_ in SLOTS:self.wndEquip.SetItemSlot(index,player.GetItemIndex(index),0)
|
|
self.wndEquip.RefreshSlot()
|
|
|
|
uiInventory.CostumeWindow.RefreshCostumeSlot=RefreshCostumeSlot
|
|
|
|
|
|
_command=game.GameWindow.BINARY_ServerCommand_Run
|
|
|
|
def Command(self,line):
|
|
if line.startswith('MTMOUNT '):
|
|
words=line.split()
|
|
text=MESSAGES.get(words[1] if len(words)>1 else '')
|
|
if text:chat.AppendChat(chat.CHAT_TYPE_INFO,L(text))
|
|
return 1
|
|
return _command(self,line)
|
|
|
|
game.GameWindow.BINARY_ServerCommand_Run=Command
|
|
)PY";
|