Register for your free account! | Forgot your password?

Go Back   elitepvpers > Popular Games > Metin2 > Metin2 Private Server > Metin2 PServer Guides & Strategies
You last visited: Today at 00:50

  • Please register to post and access all features, it's quick, easy and FREE!

Advertisement



[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.

Reply
 
Old   #1

 
elite*gold: 83
Join Date: Nov 2013
Posts: 2,891
Received Thanks: 2,764
[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
rollback is offline  
Thanks
11 Users
Reply


Similar Threads Similar Threads
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 :)



All times are GMT +1. The time now is 00:52.


Powered by vBulletin®
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Terms of Service | Abuse
Copyright ©2026 elitepvpers All Rights Reserved.