Go to the documentation of this file.00001 '''
00002 base.Avatar implements the base ("proxy") component for player Avatars
00003 Anything that is not related to the world geometry or requires spatial relationship info
00004 is handled on base: hitpoints, proficiencies, stats & skills etc.
00005
00006 Anoria (c) Gsk 2010
00007 '''
00008
00009
00010 import BigWorld
00011
00012
00013 import Anoria
00014 from Actor import Actor
00015
00016 from Resources import ResourceDB as RDB
00017 from config import consts
00018 from config import event
00019 from config import request
00020
00021
00022
00023 class Avatar(BigWorld.Proxy, Actor):
00024
00025 def __init__( self ):
00026 print "Avatar_%d initializing base component" % (self.id)
00027
00028 BigWorld.Proxy.__init__( self )
00029 Actor.__init__(self)
00030 self.requestProc = { request.REQ_POINTS_ASSIGN:self.doProficienciesAssign }
00031 self.addEventProc(event.ENTITY_KILL, self.eventEntityKill)
00032
00033
00034
00035
00036
00037 def awardXp(self, Xp):
00038
00039 self.Xp += Xp
00040 nextRankXp = consts.XPTABLE[self.totalProficiencyPoints]
00041 xpPercent = ((float(self.Xp)/float(nextRankXp))*100.0)
00042 if xpPercent >= 100:
00043 print "Avatar.awardXp() Avatar %d gained a proficiency point!" % (self.id)
00044 self.client.rpcProcessEvent(self.id, event.PROFICIENCY_POINT_GAIN, 0)
00045 self.totalProficiencyPoints += 1
00046 self.unspentProficiencyPoints += 1
00047 xpPercent = 0
00048
00049 return xpPercent
00050
00051
00052
00053
00054
00055
00056 def eventEntityKill(self, sourceId, Xp):
00057 print "Avatar.entityKillEvent() Xp:", Xp
00058 xpPercent = self.awardXp(Xp)
00059 self.client.rpcProcessEvent(sourceId, event.ENTITY_KILL, xpPercent)
00060
00061
00062
00063
00064
00065
00066 def assignProficiencyPoints(self, listIndex, points):
00067 ''' assign a number of points to a proficiency, do all required effects processing and housekeeping
00068 @param listIndex determines the proficiency to assign to
00069 @param points is the number of proficiency points to assign '''
00070
00071 proficiencyName = consts.PROFICIENCY_CODES[listIndex]
00072
00073
00074
00075 self.proficienciesList[listIndex] += points
00076 rank = self.proficienciesList[listIndex]
00077 self.unspentProficiencyPoints -= points
00078
00079 try:
00080 pdef = RDB.proficiencies[proficiencyName]
00081 except:
00082 print 'undefined proficiency, cant do effects processing ', proficiencyName
00083 return
00084
00085 try:
00086 effectId = pdef.effects[rank]
00087 except:
00088 print ' no effect defined for proficiency %s at rank %d ' % (proficiencyName, rank)
00089 return
00090
00091 self.cell.rpcProcessStringEvent(self.id, event.APPLY_STATS_EFFECT, effectId)
00092
00093
00094
00095 def doProficienciesAssign(self, proficienciesList):
00096 ''' this is a client exposed function: very thoroughly validate the input list!
00097 @param proficieniesList: client side list containing all edits (=values > 0)'''
00098
00099
00100
00101 print 'doProficienciesAssign() ', proficienciesList
00102
00103
00104 if len(proficienciesList) != consts.NUM_PROFICIENCIES:
00105 print "POTENTIAL TAMPERING: doProficienciesAssign() invalid proficiency list length from avatar id=%d" % (self.id)
00106 return
00107
00108
00109 listTotalPoints=0
00110 for n in proficienciesList:
00111 listTotalPoints += n
00112
00113 if listTotalPoints > self.unspentProficiencyPoints:
00114 print "POTENTIAL TAMPERING: doProficienciesAssign() invalid proficiency edit list points total from avatar id=%d" % (self.id)
00115 return
00116
00117
00118
00119 maxRanks = 2 + self.totalProficiencyPoints/4
00120 i = -1
00121 for n in proficienciesList:
00122 i += 1
00123 if n > 0:
00124 if self.proficienciesList[i]+n <= maxRanks:
00125 self.assignProficiencyPoints(i, n)
00126 self.client.rpc_chatText("Proficiencies assigned.", 0)
00127 else:
00128 print "POTENTIAL TAMPERING: doProficienciesAssign() invalid points/proficiency from avatar id=%d" % (self.id)
00129
00130
00131
00132 def rpcClientRequest(self, reqCode, reqParams):
00133 print "Avatar.rpcClientRequest(): reqType=%s" % (request.REQUESTS[reqCode])
00134
00135
00136 func = None
00137 try:
00138 func = self.requestProc[reqCode]
00139 except:
00140 print 'ERROR in rpcClientRequest(): no handler for %s defined' % (request.REQUESTS[reqCode])
00141
00142 if func != None: func(reqParams)
00143
00144
00145
00146
00147
00148 def onLogOnAttempt(self, ip, port, password):
00149 print "Avatar.onLogOnAttempt(): ip=%s, port=%s, password=%s" % (ip, port, password)
00150 return BigWorld.LOG_ON_REJECT
00151
00152 def onEntitiesEnabled(self):
00153 ''' called once the client requests to receive cell updates: i.e the client is "online" '''
00154
00155 ''' Note: self.cellData is automatically initialised by the System upon base creation
00156 - per default its a dictionary initialised with the values from the entity.def file
00157 - we just overide position here '''
00158
00159 self.isPlayer = True
00160 self.cellData[ "position" ] = ( 0.0 , 105.43, -38.9 )
00161 self.cellData["modelName" ] = ""
00162 self.cellData["modelNumber" ] = 1
00163 self.createInDefaultSpace()
00164
00165
00166
00167
00168
00169 Anoria.SystemChatChannel.subscribe(self)
00170 self.client.rpc_chatText(RDB.strings[0], consts.SYSTEM_CHANNEL_ID)
00171 self.client.rpc_chatText("This currently is largely a tech preview with very little actual game play.", consts.SYSTEM_CHANNEL_ID)
00172 self.client.rpc_chatText("You can look around a little using standard mouse-look WSAD controls.", consts.SYSTEM_CHANNEL_ID)
00173 self.client.rpc_chatText("ENTER opens this chat console. Attack creatures or players by pressing [Q].", consts.SYSTEM_CHANNEL_ID)
00174 self.client.rpc_chatText("You will gain experience and proficiency points by killing creatures.", consts.SYSTEM_CHANNEL_ID)
00175 self.client.rpc_chatText("Assign the gained points ([P] key) to improve you base stats.", consts.SYSTEM_CHANNEL_ID)
00176
00177
00178 def onClientDeath( self ):
00179 " Client disconnect handler "
00180
00181 ''' NOTE: BigWorld disconnect sequence:
00182 - BigWorld calls proxy.onCientDeath()
00183 - we call self.destroyCellEntity()
00184 - BigWorld calls base.onLoseCell() (proxy inherits from base)
00185 '''
00186
00187 Anoria.SystemChatChannel.unsubscribe(self)
00188
00189
00190
00191 ''' gs: does this cause onLoseCell() further below to be called subsequently? (think so) '''
00192 self.destroyCellEntity()
00193
00194 def onGetCell(self):
00195 ''' called once our cell entity has been successfully created '''
00196 print "Avatar.onGetCell()"
00197
00198 def onLoseCell( self ):
00199 ''' called once our cell entity has been destroyed '''
00200 print "Avatar.onLoseCell(): cleaning up avatar"
00201
00202
00203
00204
00205
00206 self.destroy(deleteFromDB=False, writeToDB=True)
00207
00208 def cb_writeToDB(self, success, base):
00209 print "Avatar.cb_writeToDB(): success=%s" % (success)
00210
00211
00212