minor updates.
[asgard.git] / eventtype.py
blobbce3d5cde786ef081d9805c2c8747629b542df46
1 ########################################################
2 #Copyright (c) 2006 Russ Adams, Sean Eubanks, Asgard Contributors
3 #This file is part of Asgard.
5 #Asgard is free software; you can redistribute it and/or modify
6 #it under the terms of the GNU General Public License as published by
7 #the Free Software Foundation; either version 2 of the License, or
8 #(at your option) any later version.
10 #Asgard is distributed in the hope that it will be useful,
11 #but WITHOUT ANY WARRANTY; without even the implied warranty of
12 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 #GNU General Public License for more details.
15 #You should have received a copy of the GNU General Public License
16 #along with Asgard; if not, write to the Free Software
17 #Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 ########################################################
19 import math
20 import random
21 from transaction import *
22 from utilities import *
23 class EventType:
25 __name = ""
26 """ Name of EventType (i.e. "fire1", "ice1", "poison") """
28 __typeName = ""
29 """ Type of event (i.e. "ATTACK", "BLACK", "WHITE") """
31 __mpCost = 0
32 """ Amount of mp used for EventType. """
34 __affectDeath = False
35 """ Whether the EventType is capabable of affecting dead fighters. """
37 __afflictions = []
38 """ List of 2-tuples. Status Affliction name, whether or not the
39 status is being removed. """
41 __elementals = []
42 """ List of tuples. The tuples consist of an elemental name, i.e.
43 "fire", a value for base damage (i.e. -250), and an error (i.e. +/-
44 0.25). Formula: hpChange =
45 computeBaseError(computeMgkDmg(basedmg,exec.getWisdom/Will()),error) *
46 (1 - target.getElemModifier()). """
48 def __init__(self, eTree):
49 """ Construct an Eventtype object from an eventtype XML tree. """
51 # These are in every Eventtype!
52 self.__name = eTree.xpathEval("//name")[0].content
53 self.__typeName = eTree.xpathEval("//type")[0].content
54 self.__mpCost = int(eTree.xpathEval("//mpCost")[0].content)
55 self.__affectsDeath = (eTree.xpathEval("//affectsDeath")[0].content == "True")
57 # Retrieving any status afflictions
58 self.__afflictions = []
59 aTree = eTree.xpathEval("//status")
60 for a in aTree:
61 self.__afflictions.append((a.content,a.prop("remove")=="True"))
63 # Retrieving any elementals
64 self.__elementals = []
65 elemTree = eTree.xpathEval("//element")
66 for elem in elemTree:
67 n = elem.xpathEval("//name")[0].content
68 b = int(elem.prop("base"))
69 err = float(elem.prop("error"))
70 self.__elementals.append((n,b,err))
72 def getTypeName(self):
73 return self.__typeName
75 def setTypeName(self, tn):
76 self.__typeName = tn
78 def getName(self):
79 return self.__name
81 def setName(self, name):
82 self.__name = name
84 def getAfflictions(self):
85 return self.__afflictions
87 def setAfflictions(self, aff):
88 self.__afflictions = aff
90 def getElementals(self):
91 return self.__elementals
93 def setElementals(self, elem):
94 self.__elementals = elem
96 def getMpCost(self):
97 return self.__mpCost
99 def setMpCost(self, mpC):
100 self.__mpCost = mpC
102 def getAffectsDeath(self):
103 return self.__affectsDeath
105 def setAffectsDeath(self,affectsDeath):
106 self.__affectsDeath = affectsDeath
108 def detTransactions(self, exct, targets):
109 """ Runs algorithm/formula for event type name. No Fighter data
110 is actually modified in these routines. Generates a Transaction
111 list to be processed by Event.execute(). Event.execute() will
112 execute each Transaction which will in turn actually modify the
113 Fighter data. Please also note that this method may generate
114 Transaction for multiple targets. This method will implement
115 the following event type typeNames: ATTACK, BLACK, and
116 WHITE."""
118 transList = []
119 if self.__typeName == "ATTACK":
120 for t in targets:
122 if t.isAlive() or self.__affectsDeath:
124 # Hit/Miss?
125 numHits = computeHM(exct.getStat("dex").getCurrent(),t.getStat("agl").getCurrent())
126 # Auto-Kill!
127 if numHits == 5:
128 # hpChange is target's current hp
129 hpChange = t.getStat("hp").getCurrent()
130 # Non-lethal damage
131 else:
132 hpChange = numHits * (t.getDefense() - exct.getAttack())
133 if hpChange != 0:
134 for s in t.getStatus():
135 if s.getName() == "sleep":
136 t.removeStatus(s.getName())
137 transList.append(TransactionStatistic(t,"hp",int(hpChange)))
139 elif self.__typeName == "BLACK":
140 # mpCost transaction
141 transList.append(TransactionStatistic(exct,"mp",-1 * self.__mpCost))
142 for t in targets:
143 if t.isAlive() or self.__affectsDeath:
144 for e in self.__elementals:
145 # Compute base-error damage
146 be = computeBaseError(e[1],e[2])
147 # Compute <damage per target> = <base-error damage>/len(targets)
148 dmgPer = be/len(targets)
149 # Compute net damage according to executor's will
150 netDmg = dmgPer * math.log10(exct.getStat("wil").getCurrent() + 2)
151 # elemental mod(float) for target?
152 mod = t.getElemModifier(e[0])
153 # Compute hpChange for target
154 hpChange = netDmg * (1.0 - mod)
155 transList.append(TransactionStatistic(t,"hp",int(hpChange)))
157 for s in self.__afflictions:
158 if eventOccurs(t.getStatusModifier(s)):
159 transList.append(TransactionStatus(t,s[0],not s[1]))
162 elif self.__typeName == "WHITE":
163 # mpCost transaction
164 transList.append(TransactionStatistic(exct,"mp",-1 * self.__mpCost))
165 for t in targets:
166 if t.isAlive() or self.__affectsDeath:
167 for e in self.__elementals:
168 # Compute base-error damage
169 be = computeBaseError(e[1],e[2])
170 # Compute <damage per target> = <base-error damage>/len(targets)
171 dmgPer = be/len(targets)
172 # Compute net damage according to executor's wisdom
173 netDmg = dmgPer * math.log10(exct.getStat("wis").getCurrent() + 2)
174 # elemental mod(float) for target?
175 mod = t.getElemModifier(e[0])
176 # Compute hpChange for target
177 hpChange = netDmg * (1.0 - mod)
178 transList.append(TransactionStatistic(t,"hp",int(hpChange)))
179 for s in self.__afflictions:
180 if eventOccurs(t.getStatusModifier(s)):
181 transList.append(TransactionStatus(t,s[0],not s[1]))
183 return transList