- add MeshPort peer-to-peer overlay networking SDK, C++ integration, and Python bindings - add item actions quick use/split/delete/lock overlay window (mt_item_actions) - add shop name range and NPC name visibility settings to system display options - support battlepass ticket activation and month validation in mt_battlepass - support boss tracking teleport destination button in mt_bosses - support asynchronous account registration cancellation and pending login cancellation - update AVA2 item conversion for attr lock scrolls and battlepass tickets - update .gitignore for local build outputs and caches
154 lines
6.4 KiB
C++
154 lines
6.4 KiB
C++
// PORT: AVA2-style display options (ENABLE_GRAPHIC_ON_OFF effect level, HIDE_OBJECTS tree/cloud parts),
|
|
// client-only. The effect level is systemSetting.SetEffectLevel (CInstanceBase::__UpdateEffectShown deactivates
|
|
// attached effects); trees and clouds use the original background.SetVisiblePart; names and damage numbers
|
|
// are shortcuts to the original game options. See docs/AVA2-DISPLAY.md.
|
|
static const char c_szDisplayScript[] = R"PY(# -*- coding: utf-8 -*-
|
|
import background
|
|
import game
|
|
import grp
|
|
import systemSetting
|
|
import ui
|
|
import weakref
|
|
from mt_biolog import Action, Text, L
|
|
from mt_wiki import B
|
|
|
|
g_window=None
|
|
g_entry=None
|
|
CONFIG='mt_display.cfg'
|
|
LEVELS=(u'全部特效',u'只看怪物特效',u'只看玩家特效',u'只看自己特效',u'关闭全部特效')
|
|
LEVEL_HINTS=('显示所有角色的特效','隐藏其他玩家和NPC的特效,保留自己和怪物的','隐藏怪物和NPC的特效,保留玩家的',
|
|
'只保留自己的特效','连自己的特效也隐藏')
|
|
|
|
|
|
class Options(object):
|
|
def __init__(self):self.effect=0;self.tree=True;self.cloud=True;self.shopRange=0;self.npcNames=True
|
|
|
|
def Load(self,text):
|
|
words=text.split()
|
|
if len(words) not in (3,5) or not all(w.isdigit() and len(w)==1 for w in words):return
|
|
effect,tree,cloud=[int(w) for w in words[:3]]
|
|
shop,names=[int(w) for w in words[3:]] if len(words)==5 else (0,1)
|
|
if effect<len(LEVELS) and tree in (0,1) and cloud in (0,1) and shop<5 and names in (0,1):
|
|
self.effect=effect;self.tree=tree==1;self.cloud=cloud==1;self.shopRange=shop;self.npcNames=names==1
|
|
|
|
def Dump(self):return '%d %d %d %d %d'%(self.effect,int(self.tree),int(self.cloud),self.shopRange,int(self.npcNames))
|
|
|
|
def Apply(self):
|
|
systemSetting.SetEffectLevel(self.effect)
|
|
systemSetting.SetShopNamesRange(self.shopRange)
|
|
systemSetting.SetShopNameStatus(self.npcNames)
|
|
background.SetVisiblePart(background.PART_TREE,int(self.tree))
|
|
background.SetVisiblePart(background.PART_CLOUD,int(self.cloud))
|
|
|
|
|
|
def LoadConfig(options):
|
|
try:
|
|
f=open(CONFIG,'r');text=f.read();f.close();options.Load(text)
|
|
except (IOError,OSError):pass
|
|
|
|
|
|
def SaveConfig(options):
|
|
try:
|
|
f=open(CONFIG,'w');f.write(options.Dump());f.close()
|
|
except (IOError,OSError):pass
|
|
|
|
|
|
def Mark(text,on):return L(B(u'【%s】'%text if on else text))
|
|
|
|
|
|
class DisplayWindow(ui.Window):
|
|
def __init__(self,options):
|
|
ui.Window.__init__(self);self.SetWindowName('DisplayWindow');self.AddFlag('float');self.AddFlag('movable')
|
|
self.options=options;self.SetSize(332,456)
|
|
self.heading=Text(self,18,18,'显示设置',0xffffd68b)
|
|
self.closeButton=Action(self,256,6,60,'关闭',self.Hide)
|
|
self.effectText=Text(self,18,54,'特效',0xffc3b7a1)
|
|
self.levelButtons=[Action(self,18+(i%2)*152,76+(i//2)*52,144,'',lambda level=i:self.SetLevel(level)) for i in range(len(LEVELS))]
|
|
self.sceneText=Text(self,18,238,'场景和文字',0xffc3b7a1)
|
|
self.treeButton=Action(self,18,260,144,'',self.ToggleTree)
|
|
self.cloudButton=Action(self,170,260,144,'',self.ToggleCloud)
|
|
self.nameButton=Action(self,18,312,144,'',self.ToggleName)
|
|
self.damageButton=Action(self,170,312,144,'',self.ToggleDamage)
|
|
self.rangeButton=Action(self,18,364,144,'',self.NextRange)
|
|
self.npcButton=Action(self,170,364,144,'',self.ToggleNPC)
|
|
self.status=Text(self,18,428,'',0xffc3b7a1)
|
|
self.Refresh();self.Hide()
|
|
|
|
def Buttons(self):return [self.closeButton,self.treeButton,self.cloudButton,self.nameButton,self.damageButton,self.rangeButton,self.npcButton]+self.levelButtons
|
|
|
|
def Open(self):self.Refresh();self.SetCenterPosition();self.Show();self.SetTop()
|
|
|
|
def Changed(self):self.options.Apply();SaveConfig(self.options);self.Refresh()
|
|
|
|
def SetLevel(self,level):self.options.effect=level;self.Changed()
|
|
|
|
def ToggleTree(self):self.options.tree=not self.options.tree;self.Changed()
|
|
|
|
def ToggleCloud(self):self.options.cloud=not self.options.cloud;self.Changed()
|
|
|
|
def NextRange(self):self.options.shopRange=(self.options.shopRange+1)%5;self.Changed()
|
|
|
|
def ToggleNPC(self):self.options.npcNames=not self.options.npcNames;self.Changed()
|
|
|
|
# Names and damage numbers are the original game options (saved by the client config on exit).
|
|
def ToggleName(self):systemSetting.SetAlwaysShowNameFlag(not systemSetting.IsAlwaysShowName());self.Refresh()
|
|
|
|
def ToggleDamage(self):systemSetting.SetShowDamageFlag(not systemSetting.IsShowDamage());self.Refresh()
|
|
|
|
def Refresh(self):
|
|
o=self.options
|
|
for i,button in enumerate(self.levelButtons):button.SetText(Mark(LEVELS[i],i==o.effect))
|
|
self.treeButton.SetText(Mark(u'显示树木',o.tree));self.cloudButton.SetText(Mark(u'显示云',o.cloud))
|
|
self.nameButton.SetText(Mark(u'总是显示名字',systemSetting.IsAlwaysShowName()))
|
|
self.damageButton.SetText(Mark(u'显示伤害数字',systemSetting.IsShowDamage()))
|
|
self.rangeButton.SetText(L(B(u'摊位范围 %d 米'%((100,60,40,20,10)[o.shopRange]))))
|
|
self.npcButton.SetText(Mark(u'显示NPC名称',o.npcNames))
|
|
self.status.SetText(L(LEVEL_HINTS[o.effect]))
|
|
|
|
def OnRender(self):
|
|
x,y=self.GetGlobalPosition();grp.SetColor(0xf51b1916);grp.RenderBar(x,y,self.GetWidth(),self.GetHeight());grp.SetColor(0xff9b7b48);grp.RenderBox(x,y,self.GetWidth(),self.GetHeight())
|
|
|
|
def OnPressEscapeKey(self):self.Hide();return True
|
|
|
|
def Destroy(self):
|
|
self.Hide()
|
|
for b in self.Buttons():b.event=None
|
|
|
|
|
|
class Entry(Action):
|
|
def __init__(self,window):
|
|
Action.__init__(self,None,0,0,64,'显示',Toggle)
|
|
self.minimap=weakref.proxy(window.interface.wndMiniMap);self.SetWindowName('DisplayEntry');self.OnUpdate()
|
|
|
|
def OnUpdate(self):
|
|
x,y=self.minimap.GetGlobalPosition();self.SetPosition(max(4,x-68),y+252)
|
|
|
|
|
|
g_options=Options()
|
|
LoadConfig(g_options)
|
|
systemSetting.SetEffectLevel(g_options.effect)
|
|
|
|
|
|
def Toggle():
|
|
if g_window:
|
|
if g_window.IsShow():g_window.Hide()
|
|
else:g_window.Open()
|
|
|
|
|
|
_open=game.GameWindow.Open
|
|
_close=game.GameWindow.Close
|
|
|
|
def Open(self):
|
|
global g_window,g_entry
|
|
_open(self);g_options.Apply();g_window=DisplayWindow(g_options);g_entry=Entry(self)
|
|
|
|
def Close(self):
|
|
global g_window,g_entry
|
|
if g_entry:g_entry.Hide();g_entry.event=None;g_entry=None
|
|
if g_window:g_window.Destroy();g_window=None
|
|
_close(self)
|
|
|
|
game.GameWindow.Open=Open
|
|
game.GameWindow.Close=Close
|
|
)PY";
|