[C++, PY] Multiple buy & Autostack

Indította 66Dragon99, 2020-10-10, 03:15:40

2020-10-10, 03:15:40 Utolsó szerkesztés: 2020-10-10, 03:22:47 Szerző: 66Dragon99
Biztonsági mentést csinálj!

A systemről röviden: ha mongyuk van 1 npc boltjában levő 1 db-s tárgy akk vételkor ki tudjuk választani, hogy pontosan hány darab tárgyat kívánunk megvenni egy kis ablak segítségével; az autostackot nem kell nagyon komplikáltan elmagyaráznom, mer kb az az mikor a megvett tárgyat egyből összerakja a leltárunkban a system
[spoiler=locale_game.txt legaljára új sorba]PICK_ITEM_TITLE Item Number[/spoiler]

[spoiler=root eix epk-ba ][spoiler=uipickitem.py]
Kód (a fájl kódolása utf8 és aneve legyen) Kijelölés

import wndMgr
import work as ui
import ime
import localeInfo
import re

class PickItemDialog(ui.ScriptWindow):
def __init__(self):
ui.ScriptWindow.__init__(self)

self.unitValue = 1
self.maxValue = 0
self.eventAccept = 0

def __del__(self):
ui.ScriptWindow.__del__(self)

def LoadDialog(self):
try:
pyScrLoader = ui.PythonScriptLoader()
pyScrLoader.LoadScriptFile(self, "UIScript/pickitemdialog.py")
except:
import exception
exception.Abort("PickItemDialog.LoadDialog.LoadScript")

try:
self.board = self.GetChild("board")
self.maxValueTextLine = self.GetChild("max_value")
self.pickValueEditLine = self.GetChild("money_value")
self.acceptButton = self.GetChild("accept_button")
self.cancelButton = self.GetChild("cancel_button")
except:
import exception
exception.Abort("PickItemDialog.LoadDialog.BindObject")

self.pickValueEditLine.SetReturnEvent(ui.__mem_func__(self.OnAccept))
self.pickValueEditLine.SetEscapeEvent(ui.__mem_func__(self.Close))
self.acceptButton.SetEvent(ui.__mem_func__(self.OnAccept))
self.cancelButton.SetEvent(ui.__mem_func__(self.Close))
self.board.SetCloseEvent(ui.__mem_func__(self.Close))

def Destroy(self):
self.ClearDictionary()
self.eventAccept = 0
self.maxValue = 0
self.pickValueEditLine = 0
self.acceptButton = 0
self.cancelButton = 0
self.board = None

def SetTitleName(self, text):
self.board.SetTitleName(text)

def SetAcceptEvent(self, event):
self.eventAccept = event

def SetMax(self, max):
self.pickValueEditLine.SetMax(max)

def Open(self, maxValue, unitValue=1):
width = self.GetWidth()
(mouseX, mouseY) = wndMgr.GetMousePosition()

if mouseX + width/2 > wndMgr.GetScreenWidth():
xPos = wndMgr.GetScreenWidth() - width
elif mouseX - width/2 < 0:
xPos = 0
else:
xPos = mouseX - width/2

self.SetPosition(xPos, mouseY - self.GetHeight() - 20)

self.maxValueTextLine.SetText(" / " + str(localeInfo.AddPointToNumberString(maxValue)))

self.pickValueEditLine.SetText(str(unitValue))
self.pickValueEditLine.SetFocus()

ime.SetCursorPosition(1)

self.unitValue = unitValue
self.maxValue = maxValue
self.Show()
self.SetTop()

def Close(self):
self.pickValueEditLine.KillFocus()
self.Hide()

def __ConvertMoneyText(self, text, powers=dict(k=10**3, m=10**6, b=10**9)):
"""
Format string value in thousands, millions or billions.

'1k' = 1.000
'100kk' = 100.000.000
'100m' = 100.000.000
'1b' = 1.000.000.000
'1kmb' = 1.000 (can't use multiple suffixes types)

:param text: string
:return: int
:date: 10.01.2020
:author: Vegas
"""

match = re.search(r'(\d+)({:s}+)?'.format('+|'.join(powers.keys())), text, re.I)
if match:
moneyValue, suffixName = match.groups()
moneyValue = int(moneyValue)
if not suffixName:
return moneyValue

return moneyValue * (powers[suffixName[0]] ** len(suffixName))

return 0

def OnAccept(self):
text = self.pickValueEditLine.GetText()

if text:
moneyValue = min(self.__ConvertMoneyText(text), self.maxValue)

if moneyValue:
if self.eventAccept:
self.eventAccept(moneyValue)

self.Close()

[/spoiler]

[spoiler=uishop.py-ben levő dolgok]
#importok alá
import uiPickItem

#keresd (def __init__(self):)
self.itemBuyQuestionDialog = None


#rakd alá új sorba
self.dlgPickItem = None
      
#keresd (def LoadDialog(self):)
self.coinType = shop.SHOP_COIN_TYPE_GOLD
self.Refresh()


#rakd alá új sorba
dlgPickItem = uiPickItem.PickItemDialog()
dlgPickItem.LoadDialog()
dlgPickItem.Hide()
self.dlgPickItem = dlgPickItem

#Keresd (def Destroy(self):)
self.popup = None


#rakd alá új sorba
self.dlgPickItem.Destroy()
self.dlgPickItem = 0

      
#Keresd (def UnselectItemSlot(self, selectedSlotPos):)
net.SendShopBuyPacket(self.__GetRealIndex(selectedSlotPos))

#szerkeszd
if app.IsPressed(app.DIK_LCONTROL):
itemIndex = shop.GetItemID(selectedSlotPos)
item.SelectItem(itemIndex)
itemName = item.GetItemName()
self.dlgPickItem.SetTitleName(itemName)
self.dlgPickItem.SetAcceptEvent(ui.__mem_func__(self.OnPickItem))
self.dlgPickItem.Open(200)
self.dlgPickItem.SetMax(200)
self.dlgPickItem.itemGlobalSlotIndex = selectedSlotPos
else:
net.SendShopBuyPacket(self.__GetRealIndex(selectedSlotPos))

#rakd alá új sorba
def OnPickItem(self, count):
itemSlotIndex = self.dlgPickItem.itemGlobalSlotIndex
n = 0

while n < count:
net.SendShopBuyPacket(self.__GetRealIndex(itemSlotIndex))
n = n + 1


[/spoiler]
[spoiler=uitooltip.py]
#keresd
def SetShopItem(self, slotIndex):
[...]
self.AppendPrice(price)

#rakd alá új sorba
self.AppendSpace(5)
self.AppendTextLine("Multiple Buy: |Eemoji/key_ctrl|e + |Eemoji/key_rclick|e", self.CAN_LEVEL_UP_COLOR)
[/spoiler]
[/spoiler]


[spoiler=uiscriptbe]
hozz létre egy pickitemdialog.py nevű fájlt és ez kerüljön bele
Kód (utf8-as kódolással) Kijelölés
import uiScriptLocale
import localeInfo

window = {
"name" : "PickItemDialog",
"x" : 100,
"y" : 100,
"style" : ("movable", "float",),
"width" : 170,
"height" : 90,
"children" :
(
{
"name" : "board",
"type" : "board_with_titlebar",
"x" : 0,
"y" : 0,
"width" : 170,
"height" : 90,
"title" : localeInfo.PICK_ITEM_TITLE,
"children" :
(
## Money Slot
{
"name" : "money_slot",
"type" : "image",
"x" : 20,
"y" : 34,
"image" : "d:/ymir work/ui/public/Parameter_Slot_02.sub",
"children" :
(
{
"name" : "money_value",
"type" : "editline",
"x" : 3,
"y" : 2,
"width" : 60,
"height" : 18,
"input_limit" : 6,
"only_number" : 0,
"text" : "1",
},
{
"name" : "max_value",
"type" : "text",
"x" : 63,
"y" : 3,
"text" : "/ 999999",
},
),
},
## Button
{
"name" : "accept_button",
"type" : "button",
"x" : 170/2 - 61 - 5,
"y" : 58,
"text" : uiScriptLocale.OK,
"default_image" : "d:/ymir work/ui/public/middle_button_01.sub",
"over_image" : "d:/ymir work/ui/public/middle_button_02.sub",
"down_image" : "d:/ymir work/ui/public/middle_button_03.sub",
},
{
"name" : "cancel_button",
"type" : "button",
"x" : 170/2 + 5,
"y" : 58,
"text" : uiScriptLocale.CANCEL,
"default_image" : "d:/ymir work/ui/public/middle_button_01.sub",
"over_image" : "d:/ymir work/ui/public/middle_button_02.sub",
"down_image" : "d:/ymir work/ui/public/middle_button_03.sub",
},
),
},
),
}

[/spoiler]

[spoiler=Forrásba]Szerverforrás:
game mappa:
shop.cpp
//keresd benne
(long long CShop::Buy(LPCHARACTER ch, BYTE pos))
else
{
if (item->IsDragonSoul())
item->AddToCharacter(ch, TItemPos(DRAGON_SOUL_INVENTORY, iEmptyPos));
item->AddToCharacter(ch, TItemPos(INVENTORY, iEmptyPos));

ITEM_MANAGER::instance().FlushDelayedSave(item);

if (item->GetVnum() >= 500219 && item->GetVnum() <= 500222)
LogManager::instance().GoldLog(ch->GetPlayerID(), item->GetID(), PERSONAL_SHOP_BUY, "", ch->IsGM() ? "Yes" : "No");

DBManager::instance().SendMoneyLog(MONEY_LOG_SHOP, item->GetVnum(), -dwPrice);
}

   
//szerkeszted így
else
{
if (item->IsDragonSoul())
item->AddToCharacter(ch, TItemPos(DRAGON_SOUL_INVENTORY, iEmptyPos));
else
{
WORD bCount = item->GetCount();

if (IS_SET(item->GetFlag(), ITEM_FLAG_STACKABLE))
{
for (WORD i = 0; i < INVENTORY_MAX_NUM; ++i)
{
LPITEM item2 = ch->GetInventoryItem(i);

if (!item2)
continue;

if (item2->GetVnum() == item->GetVnum())
{
int j;

for (j = 0; j < ITEM_SOCKET_MAX_NUM; ++j)
if (item2->GetSocket(j) != item->GetSocket(j))
break;

if (j != ITEM_SOCKET_MAX_NUM)
continue;

WORD bCount2 = MIN(ITEM_MAX_COUNT - item2->GetCount(), bCount);
bCount -= bCount2;
item2->SetCount(item2->GetCount() + bCount2);

if (bCount == 0)
break;
}
}

item->SetCount(bCount);
}

if (bCount > 0)
item->AddToCharacter(ch, TItemPos(INVENTORY, iEmptyPos));
else
M2_DESTROY_ITEM(item);
}

ITEM_MANAGER::instance().FlushDelayedSave(item);

if (item->GetVnum() >= 500219 && item->GetVnum() <= 500222)
LogManager::instance().GoldLog(ch->GetPlayerID(), item->GetID(), PERSONAL_SHOP_BUY, "", ch->IsGM() ? "Yes" : "No");

DBManager::instance().SendMoneyLog(MONEY_LOG_SHOP, item->GetVnum(), -dwPrice);
}

[/spoiler]

Sok sikert a dolog teszteléséhez, ha hibát találsz vagy valahogy folyton csak syserrt kapnál, akk ne habozz,itt a segítségkérő téma nyitása gomb!
http://www.kepfeltoltes.eu/view.php?filename=112lol.png lol értem már mér lett ratyi a metinpunk2077