[Release] BonusAdder / LoopTimer (in eigenem Thread)
Discussion on [Release] BonusAdder / LoopTimer (in eigenem Thread) within the Metin2 PServer Guides & Strategies forum part of the Metin2 Private Server category.
[Release] BonusAdder / LoopTimer (in eigenem Thread)
constinfo.py:
Code:
BONUS_ADD_VNUMS = {
# vnum: bonusRange
71085: [0, 3]
}
MAX_BONUS_COUNT = 0
for vnum, bonusRange in BONUS_ADD_VNUMS.iteritems():
if (bonusRange[1] + 1) > MAX_BONUS_COUNT:
MAX_BONUS_COUNT = bonusRange[1] + 1
bonusadder.py:
Code:
import constInfo
import player
import item
import gc
from threading import Timer
class LoopTimer:
__timer = None
def __init__(self, interval, runnable, *args):
self.__timer = LoopTimer.__LoopTimer(interval, runnable, *args)
def __del__(self):
LoopTimer.__LoopTimer.__del__(self.__timer)
def Start(self):
if not self.IsRunning():
self.__timer.Start()
def Stop(self):
if self.IsRunning():
self.__timer.Stop()
def IsRunning(self):
return self.__timer.IsRunning()
class __LoopTimer:
__interval = None
__runnable = None
__args = None
__timer = None
__isAlive = None
def __init__(self, interval, runnable, *args):
self.__interval = interval
self.__runnable = runnable
self.__args = args
self.Stop()
def __del__(self):
self.Stop()
def __Run(self):
if self.__isAlive:
self.__runnable(*self.__args)
self.__StartNewTimer()
def __StartNewTimer(self):
self.__ClearTimer()
self.__timer = Timer(self.__interval, self.__Run)
self.__timer.setDaemon(True)
self.__timer.start()
def __ClearTimer(self):
if self.__timer:
self.__timer.cancel()
self.__timer = None
gc.collect()
def Start(self):
if not self.IsRunning():
self.__isAlive = True
self.__StartNewTimer()
def Stop(self):
if self.IsRunning():
self.__isAlive = False
self.__ClearTimer()
def IsRunning(self):
return self.__isAlive
class BonusAdder:
__destSlot = None
__destItemVnum = None
__wantedCount = None
__addStopReason = None
__loopTimer = None
#events
__onAddingChangeEvents = None
__onAddStopReasonChangeEvents = None
__onWantedCountChangeEvents = None
def __init__(self, destSlot, wantedCount):
#eventlists zuerst um nullpointer bei settern zu vermeiden
self.__onAddingChangeEvents = []
self.__onAddStopReasonChangeEvents = []
self.__onWantedCountChangeEvents = []
self.__destSlot = destSlot
self.__destItemVnum = player.GetItemIndex(self.__destSlot)
self.__SetWantedCount(wantedCount)
self.__SetAddStopReason(None)
self.__loopTimer = LoopTimer(0.05, lambda: self.__CheckAndAddAttribute())
def __del__(self):
LoopTimer.__del__(self.__loopTimer)
def StartAdding(self):
self.__SetAdding(True)
self.__SetAddStopReason(None)
def StopAdding(self, addStopReason = None):
if not addStopReason:
addStopReason = BonusAdder.__AddStopReasons.STOPPED_BY_USER
self.__SetAdding(False)
self.__SetAddStopReason(addStopReason)
def ToggleAdding(self):
if self.IsAdding():
self.StopAdding()
else:
self.StartAdding()
def IsAdding(self):
return self.__loopTimer.IsRunning()
def IncreaseWantedCount(self):
self.__SetWantedCount(self.__wantedCount + 1)
def DecreaseWantedCount(self):
self.__SetWantedCount(self.__wantedCount - 1)
def __SetWantedCount(self, wantedCount):
self.__wantedCount = max(1, min(wantedCount, constInfo.MAX_BONUS_COUNT))
for event in self.__onWantedCountChangeEvents:
event(self.__wantedCount)
def __SetAdding(self, v):
if v:
self.__loopTimer.Start()
else:
self.__loopTimer.Stop()
adding = self.IsAdding()
for event in self.__onAddingChangeEvents:
event(adding)
def __SetAddStopReason(self, addStopReason):
self.__addStopReason = addStopReason
for event in self.__onAddStopReasonChangeEvents:
event(self.__addStopReason)
def AddOnAddingChangeEvent(self, event):
if not event:
return
self.__onAddingChangeEvents.append(event)
def RemoveOnAddingChangeEvent(self, event):
self.__onAddingChangeEvents.remove(event)
def AddOnAddStopReasonChangeEvent(self, event):
if not event:
return
self.__onAddStopReasonChangeEvents.append(event)
def RemoveOnAddStopReasonChangeEvents(self, event):
self.__onAddStopReasonChangeEvents.remove(event)
def AddOnWantedCountChangeEvent(self, event):
if not event:
return
self.__onWantedCountChangeEvents.append(event)
def RemoveOnWantedCountChangeEvent(self, event):
self.__onWantedCountChangeEvents.remove(event)
def __CheckAndAddAttribute(self):
if self.__IsBonusCountReached():
self.StopAdding(BonusAdder.__AddStopReasons.BONUS_COUNT_REACHED)
return
if not self.__IsRightItemVnum():
self.StopAdding(BonusAdder.__AddStopReasons.WRONG_ITEM_VNUM)
return
if self.__GetAddItemCount() < 1:
self.StopAdding(BonusAdder.__AddStopReasons.NOT_ENOUGH_BONUS_ADDERS)
return
self.__AddAttribute()
def __AddAttribute(self):
net.SendItemUseToItemPacket(self.__GetAddItemSlot(), self.__destSlot)
def __IsBonusCountReached(self):
return self.__GetBonusCount() >= self.__wantedCount
def __IsRightItemVnum(self):
return player.GetItemIndex(self.__destSlot) == self.__destItemVnum
def __GetAddItemCount(self):
itemCount = 0
addItemSlot = self.__GetAddItemSlot()
while addItemSlot:
itemCount = itemCount + player.GetItemCount(addItemSlot)
addItemSlot = self.__GetAddItemSlot(addItemSlot)
return itemCount
def __GetAddItemVnum(self):
currentBonusCount = self.__GetBonusCount()
for vnum, bonusRange in constInfo.BONUS_ADD_VNUMS.iteritems():
if currentBonusCount >= bonusRange[0] and currentBonusCount <= bonusRange[1]:
return vnum
return None
def __GetAddItemSlot(self, startSlot = 0):
addItemVnum = self.__GetAddItemVnum()
for slotNum in xrange(startSlot, player.INVENTORY_PAGE_SIZE * 4):
if player.GetItemIndex(slotNum) == addItemVnum:
return slotNum
return None
def __GetBonusCount(self):
return BonusAdder.GetBonusCount(self.__destSlot)
@staticmethod
def GetMaxAddingBonusCount(destSlot, adderVnum):
currentBonusCount = BonusAdder.GetBonusCount(destSlot)
maxTotalBonusCount = BonusAdder.GetMaxTotalBonusCount(destSlot, adderVnum)
if not maxTotalBonusCount:
return None
return maxTotalBonusCount - currentBonusCount
@staticmethod
def GetMaxTotalBonusCount(destSlot, adderVnum):
currentBonusCount = BonusAdder.GetBonusCount(destSlot)
for vnum, bonusRange in constInfo.BONUS_ADD_VNUMS.iteritems():
if vnum == adderVnum:
if currentBonusCount >= bonusRange[0] and currentBonusCount <= bonusRange[1]:
return bonusRange[1] + 1
return None
@staticmethod
def GetBonusCount(slot):
bonusCount = 0
for bonusIndex in xrange(constInfo.MAX_BONUS_COUNT):
applyType, applyValue = player.GetItemAttribute(slot, bonusIndex)
if applyType != 0:
bonusCount = bonusCount + 1
return bonusCount
@staticmethod
def IsBonusAdder(vnum):
return vnum in constInfo.BONUS_ADD_VNUMS
@staticmethod
def CanAddBonus(destSlot, adderVnum):
destVnum = player.GetItemIndex(destSlot)
item.SelectItem(destVnum)
itemType = item.GetItemType()
if itemType != item.ITEM_TYPE_WEAPON and itemType != item.ITEM_TYPE_ARMOR:
return False
return BonusAdder.GetMaxAddingBonusCount(destSlot, adderVnum) >= 1
#ADD STOP REASONS
class __AddStopReasons:
class AddStopReason:
__errorCode = None
__message = None
def __init__(self, errorCode, message):
self.__errorCode = errorCode
self.__message = message
def __del__(self):
self.__errorCode = None
self.__message = None
def GetErrorCode(self):
return self.__errorCode
def GetMessage(self):
return self.__message
STOPPED_BY_USER = AddStopReason("STOPPED_BY_USER", "Hinzufügen wurde gestoppt.")
BONUS_COUNT_REACHED = AddStopReason("BONUS_COUNT_REACHED", "Gewünschte Bonianzahl wurde erreicht.")
WRONG_ITEM_VNUM = AddStopReason("WRONG_ITEM_VNUM", "Das Item auf dem Zielslot hat nicht die richtige Vnum.")
NOT_ENOUGH_BONUS_ADDERS = AddStopReason("NOT_ENOUGH_BONUS_ADDERS", "Du besitzt nicht genug Items, um weitere Boni hinzuzufügen.")
import uiCommon
import item
import chat
class BonusAdderGUI(uiCommon.QuestionDialog2):
__bonusAdder = None
def __init__(self, destSlot, draggedVnum):
uiCommon.QuestionDialog2.__init__(self)
#oldVnum = item.GetItemIndex()
item.SelectItem(player.GetItemIndex(destSlot))
itemName = item.GetItemName()
item.SelectItem(draggedVnum)
itemNameDragged = item.GetItemName()
#item.SelectItem(oldVnum)
self.__bonusAdder = BonusAdder(destSlot, BonusAdder.GetMaxTotalBonusCount(destSlot, draggedVnum))
self.__bonusAdder.AddOnAddStopReasonChangeEvent(lambda reason: self.__OnAddStopReasonChanged(reason))
self.SetText("Boni hinzufügen")
self.SetText1("Mit %s kannst du %s bis zu %d weitere Boni hinzufügen." % (itemNameDragged, itemName, BonusAdder.GetMaxAddingBonusCount(destSlot, draggedVnum)))
self.SetText2("Möchtest du die Boni hinzufügen?")
self.SetAcceptEvent(lambda: self.__OnAcceptClick())
self.SetCancelEvent(lambda: self.__OnDeclineClick())
def __del__(self):
BonusAdder.__del__(self.__bonusAdder)
def __OnAcceptClick(self):
self.__bonusAdder.StartAdding()
def __OnDeclineClick(self):
self.Close()
def __OnAddStopReasonChanged(self, reason):
if not reason:
return
chat.AppendChat(chat.CHAT_TYPE_INFO, reason.GetMessage())
self.Close()
Aufgerufen wird das ganze das mit dem Slot des Items, auf das hinzugefügt werden soll und der Vnum des Bonushinzufügers:
Code:
import bonusadder
if bonusadder.BonusAdder.IsBonusAdder(draggedVnum) and bonusadder.BonusAdder.CanAddBonus(destSlot, draggedVnum):
bonusadder.BonusAdderGUI(destSlot, draggedVnum).Open()
Vielleicht könnt ihr das ja gebrauchen, evtl. auch nur den LoopTimer
Garantie bei eigenem Schaden und nicht eigenem Schaden 07/06/2013 - Off Topic - 14 Replies Also ich habe ein Headset das an der Seite einen kleinen Riss im Plastik hat. Dies ist eigentlich meine Schuld (jedoch ist auch das Material sehr dünn und zerbrechlich...) Wenn man es ausfährt genau da:
http://i.epvpimg.com/VMDch.png
Nun geht der eine Kopfhöhrer nicht mehr.
http://i.epvpimg.com/RJ9xe.png
Jedoch funktioniert der andere und das Mikro noch einwandfrei. Hab ich jetzt wenigstens Garantie das die zumindest den Kopfhörer reparieren ? Diesen kleinen Bruch hab ich schon...
Neuer Thread zu eigenem Spiel 11/03/2012 - Main - 7 Replies Hey!!
Ich will jetzt nich spammen, aber wo kann/darf ich einen neuen Thread zu einem 2D ORPG erstellen, das ich selbst programmiert habe? Wir (Ich und mein Team) haben noch nicht sehr viele Spieler und ja, ich will den Leuten hier mal zeigen um was es bei diesem Spiel so geht und was sie davon halten... (falls ihr es euch mal angucken wollt: Website) Youtube-Channel
Danke, Niki :)