role_battle_attr.go 94 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134
  1. package model
  2. import (
  3. "rocommon/util"
  4. "roserver/baseserver/model"
  5. "roserver/baseserver/set"
  6. "roserver/serverproto"
  7. "sort"
  8. )
  9. func (this *Role) GetActorAttr(reqMsg *serverproto.CSActorAttrGetReq) {
  10. retCode := serverproto.ErrorCode_ERROR_FAIL
  11. if this.roleBattleAttr != nil {
  12. retCode = this.roleBattleAttr.GetActorAttr(reqMsg.ActorList, reqMsg.IsAllBattle, true)
  13. }
  14. if retCode != serverproto.ErrorCode_ERROR_OK {
  15. ackMsg := &serverproto.SCActorAttrGetAck{
  16. Error: int32(retCode),
  17. }
  18. this.ReplayGate(ackMsg, true)
  19. }
  20. }
  21. // 属性变更类型
  22. const (
  23. Attr_Change_None = 0
  24. Attr_Change_Fashion = 1 //时装数据变更
  25. Attr_Change_Card = 2 //卡片
  26. Attr_Change_Equip = 3 //装备
  27. Attr_Change_Skill = 4 //技能
  28. Attr_Change_AddPoint = 5 //属性点
  29. Attr_Change_Advance = 6 //进阶
  30. Attr_Change_Strength = 7 //突破
  31. Attr_Change_Pet = 8 //宠物继承给玩家属性
  32. Attr_Change_HeadFrame = 9 //头像框添加属性
  33. Attr_Change_Sake = 10 //收集屋藏品属性
  34. Attr_Change_Skill_Equip_Slot = 11 //神器槽位属性变更
  35. Attr_Change_Skill_Equip = 12 //神器槽位属性变更
  36. Attr_Change_Head = 13 //称号属性
  37. Attr_Change_Pet_Base = 20 //宠物自身
  38. Attr_Change_Pet_Bond = 21 //宠物羁绊属性
  39. Attr_Change_Pet_Equip = 22 //宠物印记(装备)
  40. Attr_Change_Pet_Skill = 23 //只涉及到宠物战力变更
  41. Attr_Change_Pet_Qiyue = 25 //契约属性
  42. Attr_Change_VipPrivilege = 50 // vip,同行证等特权添加属性处理
  43. )
  44. const s_AttrNum = 30
  45. type ProfessionData struct {
  46. hpRate float32
  47. spRate float32
  48. atkRate float32
  49. magicAtkRate float32
  50. defRate float32
  51. magicDefRate float32
  52. hitRate float32
  53. dodgeRate float32
  54. critRate float32
  55. tenacityRate float32
  56. attackSpeed float32
  57. }
  58. type ActorAttr struct {
  59. attrMag *RoleBattleAttr
  60. isMainHero bool
  61. isPet bool
  62. heroId int32 //英雄动态ID(宠物动态ID)
  63. heroConfigId int32
  64. level int32
  65. advLevel int32
  66. strengthLevel int32
  67. changeSetList set.Interface
  68. pData ProfessionData
  69. positionValue int32
  70. baseStr int32
  71. baseAgi int32
  72. baseInt int32
  73. baseVit int32
  74. baseDex int32
  75. baseLuk int32
  76. //基础二级属性
  77. attrs map[serverproto.Attr]float32
  78. triggerBuffList map[uint32]*serverproto.TriggerBuffData
  79. normalSKillList []*serverproto.KeyValueType
  80. useSkillList []*serverproto.KeyValueType
  81. additionalAttrs map[serverproto.Attr]float64
  82. extendAttrPercent map[serverproto.Attr]float32
  83. //attrPercent [s_AttrNum]float32
  84. attrPercent map[serverproto.Attr]float32
  85. //hero
  86. //计算后的属性
  87. curAddPointAttr map[serverproto.Attr]float32 //属性点
  88. curFashionAttr map[serverproto.Attr]float32 //时装
  89. curCardAttr map[serverproto.Attr]float32 //卡片
  90. curEquipAttr map[serverproto.Attr]float32 //装备
  91. curAdvanceAttr map[serverproto.Attr]float32 //进阶
  92. curStrengthAttr map[serverproto.Attr]float32 //强化
  93. curPetAttr map[serverproto.Attr]float32 //宠物继承给玩家
  94. curSkillAttr map[serverproto.Attr]float32 //技能升级添加属性
  95. curHeadFrameAttr map[serverproto.Attr]float32 //头像框解锁添加属性
  96. curSakeAttr map[serverproto.Attr]float32 //藏品添加属性
  97. curSkillEquipAttr map[serverproto.Attr]float32 //神器槽位属性
  98. curHeadAttr map[serverproto.Attr]float32 //称号属性
  99. curPrivilegeAttr map[serverproto.Attr]float32 //称号属性
  100. //pet
  101. curPetAttrForPetBase map[serverproto.Attr]float32 //宠物自身base(level + advLevel)
  102. curPetAttrForPetBond map[serverproto.Attr]float32 //来自宠物羁绊的属性
  103. curPetAttrForPetEquip map[serverproto.Attr]float32 //来自宠物印记的属性
  104. curPetAttrForPetQiyue map[serverproto.Attr]float32 //宠物契约继承属性
  105. //战力部分
  106. curAttrFightPower uint64 //根据属性计算的战力
  107. curSkillFightPower int64 //技能升级添加的战斗力
  108. curSkillEquipFightPower int64 //神器添加的战斗力
  109. }
  110. type PetActorAttr struct {
  111. //基础二级属性
  112. attrs map[serverproto.Attr]float32
  113. additionalAttrs map[serverproto.Attr]float32
  114. extendAttrPercent map[serverproto.Attr]float32
  115. //attrPercent [s_AttrNum]float32
  116. attrPercent map[serverproto.Attr]float32
  117. curEquipAttr map[serverproto.Attr]float32 //装备
  118. }
  119. func newActorAttr(mag *RoleBattleAttr, hId int32, heroConfigId int32, level int32, advLevel, strengthLevel int32) *ActorAttr {
  120. actorAttr := &ActorAttr{
  121. baseStr: 1,
  122. baseAgi: 1,
  123. baseInt: 1,
  124. baseVit: 1,
  125. baseDex: 1,
  126. baseLuk: 1,
  127. attrMag: mag,
  128. heroId: hId,
  129. heroConfigId: heroConfigId,
  130. level: level,
  131. attrs: map[serverproto.Attr]float32{},
  132. triggerBuffList: map[uint32]*serverproto.TriggerBuffData{},
  133. extendAttrPercent: map[serverproto.Attr]float32{},
  134. additionalAttrs: map[serverproto.Attr]float64{},
  135. attrPercent: map[serverproto.Attr]float32{},
  136. curAddPointAttr: map[serverproto.Attr]float32{},
  137. curFashionAttr: map[serverproto.Attr]float32{},
  138. curEquipAttr: map[serverproto.Attr]float32{},
  139. curCardAttr: map[serverproto.Attr]float32{},
  140. curAdvanceAttr: map[serverproto.Attr]float32{},
  141. curStrengthAttr: map[serverproto.Attr]float32{},
  142. curPetAttr: map[serverproto.Attr]float32{},
  143. curSkillAttr: map[serverproto.Attr]float32{},
  144. curHeadFrameAttr: map[serverproto.Attr]float32{},
  145. curSakeAttr: map[serverproto.Attr]float32{},
  146. curSkillEquipAttr: map[serverproto.Attr]float32{},
  147. curPrivilegeAttr: map[serverproto.Attr]float32{},
  148. curSkillFightPower: -1,
  149. curSkillEquipFightPower: -1,
  150. curPetAttrForPetQiyue: map[serverproto.Attr]float32{},
  151. }
  152. actorAttr.changeSetList = set.New(set.NonThreadSafe)
  153. if mag.role.GetRoleHero().IsMainHero(hId) {
  154. actorAttr.isMainHero = true
  155. actorAttr.initJobAttr()
  156. } else {
  157. if parterCfgData, ok := serverproto.ParterCfgLoader[heroConfigId]; ok {
  158. actorAttr.positionValue = parterCfgData.Position
  159. }
  160. }
  161. actorAttr.resetAttrList(actorAttr.level, advLevel, strengthLevel)
  162. return actorAttr
  163. }
  164. func newPetAttr(mag *RoleBattleAttr, petId int32, petConfigId int32, level, advLevel int32) *ActorAttr {
  165. actorAttr := &ActorAttr{
  166. attrMag: mag,
  167. heroId: petId,
  168. heroConfigId: petConfigId,
  169. level: level,
  170. advLevel: advLevel,
  171. attrs: map[serverproto.Attr]float32{},
  172. extendAttrPercent: map[serverproto.Attr]float32{},
  173. additionalAttrs: map[serverproto.Attr]float64{},
  174. attrPercent: map[serverproto.Attr]float32{},
  175. curEquipAttr: map[serverproto.Attr]float32{},
  176. curAdvanceAttr: map[serverproto.Attr]float32{},
  177. curPetAttrForPetBase: map[serverproto.Attr]float32{},
  178. curPetAttrForPetBond: map[serverproto.Attr]float32{},
  179. curPetAttrForPetEquip: map[serverproto.Attr]float32{},
  180. curSkillFightPower: -1,
  181. }
  182. actorAttr.changeSetList = set.New(set.NonThreadSafe)
  183. actorAttr.isPet = true
  184. //actorAttr.initJobAttr()
  185. //actorAttr.resetAttrList(actorAttr.level, advLevel, 0)
  186. return actorAttr
  187. }
  188. func (this *ActorAttr) getRole() *Role {
  189. return this.attrMag.role
  190. }
  191. func (this *ActorAttr) getFormulaValue(paramId int32) float32 {
  192. if paramData, ok := BattleFormulaList[paramId]; ok {
  193. return paramData.val
  194. }
  195. return 0
  196. }
  197. func (this *ActorAttr) initJobAttr() {
  198. if this.isMainHero {
  199. if jobData, ok := serverproto.JobCfgLoader[this.heroConfigId]; ok {
  200. this.pData.hpRate = float32(jobData.HpRate) * 0.0001
  201. this.pData.spRate = float32(jobData.SpRate) * 0.0001
  202. this.pData.atkRate = float32(jobData.AtkRate) * 0.0001
  203. this.pData.magicAtkRate = float32(jobData.MatkRate) * 0.0001
  204. this.pData.defRate = float32(jobData.DefRate) * 0.0001
  205. this.pData.magicDefRate = float32(jobData.MdefRate) * 0.0001
  206. this.pData.hitRate = float32(jobData.HitRate) * 0.0001
  207. this.pData.dodgeRate = float32(jobData.DodgeRate) * 0.0001
  208. this.pData.critRate = float32(jobData.CritRate) * 0.0001
  209. this.pData.tenacityRate = float32(jobData.TenRate) * 0.0001
  210. this.pData.attackSpeed = float32(jobData.Aspd)
  211. this.positionValue = jobData.Position
  212. }
  213. } else if this.isPet {
  214. if jobData, ok := serverproto.PetCfgLoader[this.heroConfigId]; ok {
  215. this.pData.hpRate = float32(jobData.HpRate) * 0.0001
  216. this.pData.spRate = float32(jobData.SpRate) * 0.0001
  217. this.pData.atkRate = float32(jobData.AtkRate) * 0.0001
  218. this.pData.magicAtkRate = float32(jobData.MatkRate) * 0.0001
  219. this.pData.defRate = float32(jobData.DefRate) * 0.0001
  220. this.pData.magicDefRate = float32(jobData.MdefRate) * 0.0001
  221. this.pData.hitRate = float32(jobData.HitRate) * 0.0001
  222. this.pData.dodgeRate = float32(jobData.DodgeRate) * 0.0001
  223. this.pData.critRate = float32(jobData.CritRate) * 0.0001
  224. this.pData.tenacityRate = float32(jobData.TenRate) * 0.0001
  225. }
  226. }
  227. }
  228. func (this *ActorAttr) resetAttrList(level int32, advLevel, strengthLevel int32) {
  229. this.level = level
  230. this.attrs = map[serverproto.Attr]float32{}
  231. if this.isMainHero {
  232. if attrData, ok := model.RoleAttrContainer[level]; ok {
  233. for _, data := range attrData.AttrSet {
  234. this.attrs[serverproto.Attr(data.Key)-serverproto.Attr_Life] = float32(data.Value)
  235. }
  236. }
  237. } else if this.isPet {
  238. if attrData, ok := model.RoleAttrContainer[level]; ok {
  239. for _, data := range attrData.AttrSet {
  240. this.attrs[serverproto.Attr(data.Key)-serverproto.Attr_Life] = float32(data.Value)
  241. }
  242. }
  243. } else {
  244. if attrData, ok := model.PartnerAttrContainer[this.heroConfigId]; ok {
  245. for _, data := range attrData.AttrSet {
  246. this.attrs[serverproto.Attr(data.Key)-serverproto.Attr_Life] = float32(data.Value)
  247. }
  248. }
  249. ////进阶属性
  250. //partnerCfgDta,ok := serverproto.ParterCfgLoader[this.heroConfigId]
  251. //if ok {
  252. // progressAttrData,ok := model.ProgressAttrContainer[partnerCfgDta.ParterJob]
  253. // if ok && advLevel > 0 {
  254. // for key,val :=range progressAttrData.AttrSet {
  255. // if key >= this.advLevel && key < advLevel {
  256. // for k,v := range val {
  257. // if k < int32(serverproto.Attr_STR_Percent) {
  258. // this.additionalAttrs[serverproto.Attr(k)] += float32(v)
  259. // }else{
  260. // attrId := serverproto.Attr(k)
  261. // if attrId >= serverproto.Attr_Nature_None_Damage_Percent &&
  262. // attrId <= serverproto.Attr_VariableSingTime_Percent {
  263. // this.extendAttrPercent[attrId] += float32(v)
  264. // }else{
  265. // this.attrPercent[attrId-serverproto.Attr_STR_Percent] += float32(v)
  266. // }
  267. // }
  268. // }
  269. // }
  270. // }
  271. // }
  272. //
  273. // //突破属性
  274. // convertAttrData, ok := model.StrengthAttrContainer[partnerCfgDta.ParterJob]
  275. // if ok && strengthLevel > 0 {
  276. // for key,val :=range convertAttrData.AttrSet {
  277. // if key >= this.strengthLevel && key < strengthLevel {
  278. // for k,v := range val {
  279. // if k < int32(serverproto.Attr_STR_Percent) {
  280. // this.additionalAttrs[serverproto.Attr(k)] += float32(v)
  281. // }else{
  282. // attrId := serverproto.Attr(k)
  283. // if attrId >= serverproto.Attr_Nature_None_Damage_Percent &&
  284. // attrId <= serverproto.Attr_VariableSingTime_Percent {
  285. // this.extendAttrPercent[attrId] += float32(v)
  286. // }else{
  287. // this.attrPercent[attrId-serverproto.Attr_STR_Percent] += float32(v)
  288. // }
  289. // }
  290. // }
  291. // }
  292. // }
  293. // }
  294. //}
  295. this.advLevel = advLevel
  296. this.strengthLevel = strengthLevel
  297. }
  298. }
  299. func (this *ActorAttr) isFront() bool {
  300. return this.positionValue <= 3
  301. }
  302. // first
  303. func (this *ActorAttr) STR() int32 {
  304. return this.baseStr + int32(this.GetAdditionalAttr(serverproto.Attr_Str))
  305. }
  306. func (this *ActorAttr) AGI() int32 {
  307. return this.baseAgi + int32(this.GetAdditionalAttr(serverproto.Attr_Agi))
  308. }
  309. func (this *ActorAttr) INT() int32 {
  310. return this.baseInt + int32(this.GetAdditionalAttr(serverproto.Attr_Int))
  311. }
  312. func (this *ActorAttr) VIT() int32 {
  313. return this.baseVit + int32(this.GetAdditionalAttr(serverproto.Attr_Vit))
  314. }
  315. func (this *ActorAttr) DEX() int32 {
  316. return this.baseDex + int32(this.GetAdditionalAttr(serverproto.Attr_Dex))
  317. }
  318. func (this *ActorAttr) LUK() int32 {
  319. return this.baseLuk + int32(this.GetAdditionalAttr(serverproto.Attr_Luk))
  320. }
  321. // second
  322. func (this *ActorAttr) Life() float64 {
  323. return this.calcSecondAttrForLife(serverproto.Attr_Life)
  324. }
  325. func (this *ActorAttr) Sp() float32 {
  326. return this.calcSecondAttr(serverproto.Attr_Sp)
  327. }
  328. func (this *ActorAttr) Attack() float32 {
  329. return this.calcSecondAttr(serverproto.Attr_Attack)
  330. }
  331. func (this *ActorAttr) MinAttack() float32 {
  332. return this.Attack()
  333. }
  334. func (this *ActorAttr) MagicAttack() float32 {
  335. return this.calcSecondAttr(serverproto.Attr_MagicAttack)
  336. }
  337. func (this *ActorAttr) MinMagicAttack() float32 {
  338. return this.MagicAttack()
  339. }
  340. func (this *ActorAttr) Defense() float32 {
  341. return this.calcSecondAttr(serverproto.Attr_Defense)
  342. }
  343. func (this *ActorAttr) MagicDefense() float32 {
  344. return this.calcSecondAttr(serverproto.Attr_MagicDefense)
  345. }
  346. func (this *ActorAttr) Dodge() float32 {
  347. return this.calcSecondAttr(serverproto.Attr_Dodge)
  348. }
  349. func (this *ActorAttr) Hit() float32 {
  350. return this.calcSecondAttr(serverproto.Attr_Hit)
  351. }
  352. func (this *ActorAttr) Crit() float32 {
  353. return this.calcSecondAttr(serverproto.Attr_Crit)
  354. }
  355. func (this *ActorAttr) Ten() float32 {
  356. return this.calcSecondAttr(serverproto.Attr_Ten)
  357. }
  358. func (this *ActorAttr) AttackSpeed() float32 {
  359. //return this.calcSecondAttr(serverproto.Attr_AttackSpeed)
  360. p1 := this.getFormulaValue(24)
  361. p2 := this.getFormulaValue(25)
  362. //tempSpeed := this.getBaseSecondAttr(serverproto.Attr_AttackSpeed) + this.GetAdditionalAttr(serverproto.Attr_AttackSpeed)
  363. //tempSpeed *= 1 + this.GetAdditionalAttrPercent(serverproto.Attr_AttackSpeed) + float32(this.AGI())*p1 + float32(this.DEX())*p2
  364. tempSpeed := this.getBaseSecondAttr(serverproto.Attr_AttackSpeed) + float32(this.GetAdditionalAttr(serverproto.Attr_AttackSpeed))
  365. tempSpeed += float32(this.AGI())*p1 + float32(this.DEX())*p2
  366. return tempSpeed
  367. }
  368. func (this *ActorAttr) CastAcce() float32 {
  369. return this.getBaseSecondAttr(serverproto.Attr_CastAcce)
  370. //return this.calcSecondAttr(serverproto.Attr_CastAcce)
  371. }
  372. // 暴击伤害百分比
  373. func (this *ActorAttr) CritDamagePercent() float32 {
  374. return this.GetAdditionalAttrPercent(serverproto.Attr_CritDamage_Percent)
  375. }
  376. // 忽视物防
  377. func (this *ActorAttr) Penetration() float32 {
  378. return this.GetAdditionalAttrPercent(serverproto.Attr_Penetration_Percent)
  379. }
  380. // 忽视魔防
  381. func (this *ActorAttr) MagicPenetration() float32 {
  382. return this.GetAdditionalAttrPercent(serverproto.Attr_Magic_Penetration_Percent)
  383. }
  384. // 防御百分比
  385. func (this *ActorAttr) DefPercent() float32 {
  386. return this.GetAdditionalAttrPercent(serverproto.Attr_Defense_Percent)
  387. }
  388. // 魔防百分比
  389. func (this *ActorAttr) MagicDefPercent() float32 {
  390. return this.GetAdditionalAttrPercent(serverproto.Attr_MagicDefense_Percent)
  391. }
  392. func (this *ActorAttr) baseLife() float32 {
  393. p0 := this.getFormulaValue(1)
  394. if this.isMainHero {
  395. tmpf1 := this.getAttr(serverproto.Attr_Life)
  396. tmpf2 := this.pData.hpRate
  397. tmpf3 := 1 + float32(this.VIT())*p0
  398. return tmpf1 * tmpf2 * tmpf3
  399. //return this.getAttr(serverproto.Attr_Life) * this.pData.hpRate * (1 + float32(this.VIT())*p0)
  400. } else {
  401. //<!--《伙伴生命成长公式》 伙伴基础血量=HP+A*(LV^2-1)+B*(LV-1)-->
  402. p1 := this.getFormulaValue(31)
  403. p2 := this.getFormulaValue(32)
  404. fLevel := float32(this.level)
  405. tempLife := this.getAttr(serverproto.Attr_Life) + p1*(fLevel*fLevel-1) + p2*(fLevel-1)
  406. tempLife = tempLife * (1 + float32(this.VIT())*p0)
  407. return tempLife
  408. }
  409. }
  410. func (this *ActorAttr) baseSp() float32 {
  411. p0 := this.getFormulaValue(2)
  412. if this.isMainHero {
  413. return this.getAttr(serverproto.Attr_Sp) * this.pData.spRate * (1 + float32(this.INT())*p0)
  414. } else {
  415. p1 := this.getFormulaValue(33)
  416. p2 := this.getFormulaValue(34)
  417. fLevel := float32(this.level)
  418. tempLife := this.getAttr(serverproto.Attr_Sp) + p1*(fLevel*fLevel-1) + p2*(fLevel-1)
  419. return tempLife * (1 + float32(this.INT())*p0)
  420. }
  421. }
  422. func (this *ActorAttr) baseAttack() float32 {
  423. fAttack := this.getAttr(serverproto.Attr_Attack)
  424. if this.isMainHero {
  425. fAttack *= this.pData.atkRate
  426. }
  427. if this.isFront() { //近战处理
  428. p1 := this.getFormulaValue(3)
  429. p2 := this.getFormulaValue(4)
  430. p3 := this.getFormulaValue(35)
  431. fStr := float32(this.STR())
  432. fDex := float32(this.DEX())
  433. fLuk := float32(this.LUK())
  434. iStr := int32(fStr * 0.1)
  435. fAttack += p1*(fStr+p3*fDex+p3*fLuk) + p2*float32(iStr*iStr)
  436. } else { //远程处理
  437. p1 := this.getFormulaValue(5)
  438. p2 := this.getFormulaValue(6)
  439. p3 := this.getFormulaValue(36)
  440. fStr := float32(this.STR())
  441. fDex := float32(this.DEX())
  442. fLuk := float32(this.LUK())
  443. iDex := int32(fDex * 0.1)
  444. fAttack += p1*(fDex+p3*fStr+p3*fLuk) + p2*float32(iDex*iDex)
  445. }
  446. return fAttack
  447. }
  448. func (this *ActorAttr) baseMagicAttack() float32 {
  449. p1 := this.getFormulaValue(7)
  450. p2 := this.getFormulaValue(8)
  451. fInt := float32(this.INT())
  452. iInt := int32(fInt * 0.1)
  453. magicAttack := this.getAttr(serverproto.Attr_MagicAttack)
  454. if this.isMainHero {
  455. magicAttack *= this.pData.magicAtkRate
  456. }
  457. magicAttack += fInt*p1 + p2*float32(iInt*iInt)
  458. return magicAttack
  459. }
  460. func (this *ActorAttr) baseDefense() float32 {
  461. p1 := this.getFormulaValue(9)
  462. defense := this.getAttr(serverproto.Attr_Defense)
  463. if this.isMainHero {
  464. defense *= this.pData.defRate
  465. }
  466. defense = defense + p1*float32(this.VIT())
  467. return defense
  468. }
  469. func (this *ActorAttr) baseMagicDefense() float32 {
  470. p1 := this.getFormulaValue(10)
  471. magicDefense := this.getAttr(serverproto.Attr_MagicDefense)
  472. if this.isMainHero {
  473. magicDefense *= this.pData.magicDefRate
  474. }
  475. magicDefense = magicDefense + p1*float32(this.INT())
  476. return magicDefense
  477. }
  478. func (this *ActorAttr) baseDodge() float32 {
  479. p1 := this.getFormulaValue(11)
  480. dodge := this.getAttr(serverproto.Attr_Dodge)
  481. if this.isMainHero {
  482. dodge *= this.pData.dodgeRate
  483. }
  484. dodge = dodge + p1*float32(this.AGI())
  485. return dodge
  486. }
  487. func (this *ActorAttr) baseHit() float32 {
  488. p1 := this.getFormulaValue(12)
  489. hit := this.getAttr(serverproto.Attr_Hit)
  490. if this.isMainHero {
  491. hit *= this.pData.hitRate
  492. }
  493. hit = hit + p1*float32(this.DEX())
  494. return hit
  495. }
  496. func (this *ActorAttr) baseCrit() float32 {
  497. p1 := this.getFormulaValue(13)
  498. crit := this.getAttr(serverproto.Attr_Crit)
  499. if this.isMainHero {
  500. crit *= this.pData.critRate
  501. }
  502. crit = crit + p1*float32(this.LUK())
  503. return crit
  504. }
  505. func (this *ActorAttr) baseTen() float32 {
  506. p1 := this.getFormulaValue(14)
  507. ten := this.getAttr(serverproto.Attr_Ten)
  508. if this.isMainHero {
  509. ten *= this.pData.tenacityRate
  510. }
  511. ten = ten + p1*float32(this.LUK())
  512. return ten
  513. }
  514. func (this *ActorAttr) baseAttackSpeed() float32 {
  515. if this.isMainHero {
  516. return this.pData.attackSpeed
  517. } else {
  518. return this.getAttr(serverproto.Attr_AttackSpeed)
  519. }
  520. }
  521. func (this *ActorAttr) baseCastAcce() float32 {
  522. p1 := this.getFormulaValue(28)
  523. return p1 * float32(this.DEX())
  524. }
  525. // 获得二级基础属性
  526. func (this *ActorAttr) getAttr(attrId serverproto.Attr) float32 {
  527. if attrId < serverproto.Attr_Life {
  528. return 0
  529. }
  530. return this.attrs[attrId-serverproto.Attr_Life]
  531. }
  532. func (this *ActorAttr) setBaseFirstAttr(attrId serverproto.Attr, val int32) {
  533. switch attrId {
  534. case serverproto.Attr_Str:
  535. this.baseStr = val
  536. case serverproto.Attr_Agi:
  537. this.baseAgi = val
  538. case serverproto.Attr_Int:
  539. this.baseInt = val
  540. case serverproto.Attr_Vit:
  541. this.baseVit = val
  542. case serverproto.Attr_Dex:
  543. this.baseDex = val
  544. case serverproto.Attr_Luk:
  545. this.baseLuk = val
  546. }
  547. }
  548. func (this *ActorAttr) getBaseFirstAttr(attrId serverproto.Attr) int32 {
  549. switch attrId {
  550. case serverproto.Attr_Str:
  551. return this.baseStr
  552. case serverproto.Attr_Agi:
  553. return this.baseAgi
  554. case serverproto.Attr_Int:
  555. return this.baseInt
  556. case serverproto.Attr_Vit:
  557. return this.baseVit
  558. case serverproto.Attr_Dex:
  559. return this.baseDex
  560. case serverproto.Attr_Luk:
  561. return this.baseLuk
  562. }
  563. return 0
  564. }
  565. func (this *ActorAttr) getBaseSecondAttr(attrId serverproto.Attr) float32 {
  566. switch attrId {
  567. case serverproto.Attr_Life:
  568. return this.baseLife()
  569. case serverproto.Attr_Sp:
  570. return this.baseSp()
  571. case serverproto.Attr_Attack:
  572. return this.baseAttack()
  573. case serverproto.Attr_MagicAttack:
  574. return this.baseMagicAttack()
  575. case serverproto.Attr_Defense:
  576. return this.baseDefense()
  577. case serverproto.Attr_MagicDefense:
  578. return this.baseMagicDefense()
  579. case serverproto.Attr_Dodge:
  580. return this.baseDodge()
  581. case serverproto.Attr_Hit:
  582. return this.baseHit()
  583. case serverproto.Attr_Crit:
  584. return this.baseCrit()
  585. case serverproto.Attr_Ten:
  586. return this.baseTen()
  587. case serverproto.Attr_AttackSpeed:
  588. return this.baseAttackSpeed()
  589. case serverproto.Attr_CastAcce:
  590. return this.baseCastAcce()
  591. }
  592. return 0
  593. }
  594. // life需要处理成64位
  595. func (this *ActorAttr) calcSecondAttrForLife(attrId serverproto.Attr) float64 {
  596. if attrId < serverproto.Attr_Life || attrId > serverproto.Attr_CastAcce {
  597. return 0
  598. }
  599. tmpf1 := float64(this.getBaseSecondAttr(attrId))
  600. tmpf2 := this.GetAdditionalAttr(attrId) * float64(1+this.GetAdditionalAttrPercent(attrId+30)*0.0001)
  601. return tmpf1 + tmpf2
  602. }
  603. func (this *ActorAttr) calcSecondAttr(attrId serverproto.Attr) float32 {
  604. if attrId < serverproto.Attr_Life || attrId > serverproto.Attr_CastAcce {
  605. return 0
  606. }
  607. tmpf1 := this.getBaseSecondAttr(attrId)
  608. tmpf2 := this.GetAdditionalAttr(attrId) * float64(1+this.GetAdditionalAttrPercent(attrId+30)*0.0001)
  609. return tmpf1 + float32(tmpf2)
  610. }
  611. func (this *ActorAttr) GetAdditionalAttr(attrId serverproto.Attr) float64 {
  612. if attrId < serverproto.Attr_Str || attrId > serverproto.Attr_RealHurt {
  613. return 0
  614. }
  615. return this.additionalAttrs[attrId]
  616. }
  617. func (this *ActorAttr) SetAdditionalAttr(attrId serverproto.Attr, val float64) {
  618. if attrId < serverproto.Attr_Str || attrId > serverproto.Attr_RealHurt {
  619. return
  620. }
  621. this.additionalAttrs[attrId] = val
  622. }
  623. func (this *ActorAttr) SetAdditionalAttrPercent(attrId serverproto.Attr, val float32) {
  624. if attrId < serverproto.Attr_STR_Percent {
  625. return
  626. }
  627. if attrId >= serverproto.Attr_Nature_None_Damage_Percent &&
  628. attrId <= serverproto.Attr_VariableSingTime_Percent {
  629. this.extendAttrPercent[attrId] = val
  630. } else {
  631. this.attrPercent[attrId-serverproto.Attr_STR_Percent] = val
  632. }
  633. }
  634. func (this *ActorAttr) GetAdditionalAttrPercent(attrId serverproto.Attr) float32 {
  635. if attrId < serverproto.Attr_STR_Percent {
  636. return 0
  637. }
  638. if attrId >= serverproto.Attr_Nature_None_Damage_Percent &&
  639. attrId <= serverproto.Attr_VariableSingTime_Percent {
  640. return this.extendAttrPercent[attrId]
  641. }
  642. return this.attrPercent[attrId-serverproto.Attr_STR_Percent]
  643. }
  644. func (this *ActorAttr) AdditionAttrPercentString() {
  645. type kvSt struct {
  646. attrKey serverproto.Attr
  647. attrVal float64
  648. }
  649. var kvList []kvSt
  650. for key, val := range this.attrPercent {
  651. util.InfoF("%v=%v", key+serverproto.Attr_STR_Percent, val)
  652. //kvList = append(kvList, kvSt{attrKey: key + serverproto.Attr_STR_Percent, attrVal: val / 100})
  653. }
  654. if this.isPet {
  655. for key, val := range this.additionalAttrs {
  656. kvList = append(kvList, kvSt{attrKey: key, attrVal: val})
  657. }
  658. }
  659. util.InfoF("=============")
  660. for key, val := range this.extendAttrPercent {
  661. //util.InfoF("%v=%v", key, val/100)
  662. kvList = append(kvList, kvSt{attrKey: key, attrVal: float64(val)})
  663. }
  664. sort.Slice(kvList, func(i, j int) bool {
  665. return kvList[i].attrKey < kvList[j].attrKey
  666. })
  667. for idx := 0; idx < len(kvList); idx++ {
  668. util.InfoF("%v=%v %v%%", kvList[idx].attrKey, kvList[idx].attrVal, kvList[idx].attrVal/100)
  669. }
  670. }
  671. func (this *ActorAttr) attrPrintString(attrList map[serverproto.Attr]float32) {
  672. type kvSt struct {
  673. attrKey serverproto.Attr
  674. attrVal float32
  675. }
  676. var kvList []kvSt
  677. for key, val := range attrList {
  678. //util.InfoF("%v=%v", key, val/100)
  679. kvList = append(kvList, kvSt{attrKey: key, attrVal: val})
  680. }
  681. sort.Slice(kvList, func(i, j int) bool {
  682. return kvList[i].attrKey < kvList[j].attrKey
  683. })
  684. for idx := 0; idx < len(kvList); idx++ {
  685. util.InfoF("%v=%v %v%%", kvList[idx].attrKey, kvList[idx].attrVal, kvList[idx].attrVal/100)
  686. }
  687. }
  688. func (this *ActorAttr) calcAttr(attrList map[serverproto.Attr]float32, curAttrList map[serverproto.Attr]float32) {
  689. for key := range attrList {
  690. deltaValue := attrList[key] - curAttrList[key]
  691. delete(curAttrList, key)
  692. if deltaValue == 0 {
  693. continue
  694. }
  695. if key < serverproto.Attr_STR_Percent {
  696. val := this.GetAdditionalAttr(key) + float64(deltaValue)
  697. this.SetAdditionalAttr(key, val)
  698. } else {
  699. val := this.GetAdditionalAttrPercent(key) + deltaValue
  700. this.SetAdditionalAttrPercent(key, val)
  701. }
  702. }
  703. //删除之前有但是现在没有的属性条目
  704. if len(curAttrList) > 0 {
  705. for key := range curAttrList {
  706. deltaValue := -curAttrList[key]
  707. if key < serverproto.Attr_STR_Percent {
  708. val := this.GetAdditionalAttr(key) + float64(deltaValue)
  709. this.SetAdditionalAttr(key, val)
  710. } else {
  711. val := this.GetAdditionalAttrPercent(key) + deltaValue
  712. this.SetAdditionalAttrPercent(key, val)
  713. }
  714. }
  715. }
  716. }
  717. func (this *ActorAttr) calActorAttr(heroData *serverproto.HeroData, attrList []*serverproto.KeyValueType,
  718. fashionData *serverproto.FashionData, attrChangeSt AttrChangeST) bool {
  719. if heroData == nil {
  720. //玩家自身角色
  721. heroData = this.getRole().GetRoleHero().GetHero(this.heroId)
  722. }
  723. if heroData == nil {
  724. return false
  725. }
  726. bChange := false
  727. if this.changeSetList.Size() > 0 {
  728. //主角英雄
  729. if this.isMainHero {
  730. changePoint := this.calcAddPointAttrs(heroData, attrList)
  731. changeSkill := this.calcSkillAttrs(heroData, attrChangeSt)
  732. changeEquip := this.calcEquipAttrs(heroData)
  733. changePrivilege := this.calcPrivilegeAttrs(heroData)
  734. //this.calcFashionAttr(fashionData)
  735. changPet := this.calcPetAttr(heroData, attrChangeSt)
  736. changeHeadFrame := this.calcHeadFrameAttrs(heroData, attrChangeSt)
  737. changeSkillEquip := this.calcSkillEquipSlotAttrs(heroData)
  738. if changePoint || changeSkill || changeEquip || changPet ||
  739. changeHeadFrame || changeSkillEquip || changePrivilege {
  740. bChange = true
  741. }
  742. } else {
  743. changePoint := this.calcAddPointAttrs(heroData, attrList)
  744. changeSkill := this.calcSkillAttrs(heroData, attrChangeSt)
  745. changAdv := this.calcAdvanceAttrs(heroData)
  746. changStr := this.calcStrengthAttr(heroData)
  747. changEquip := this.calcEquipAttrs(heroData)
  748. changPet := this.calcPetAttr(heroData, attrChangeSt)
  749. changeSkillEquip := this.calcSkillEquipSlotAttrs(heroData)
  750. if changePoint || changeSkill || changAdv || changStr || changEquip || changPet || changeSkillEquip {
  751. bChange = true
  752. }
  753. }
  754. changeCard := this.calcCardAttrs(heroData)
  755. changeFashion := this.calcFashionAttr(fashionData, heroData)
  756. changeSake := this.calcSakeAttr(heroData)
  757. changeHead := this.calcHeadAttr(heroData)
  758. if changeCard || changeFashion || changeSake || changeHead {
  759. bChange = true
  760. }
  761. }
  762. if this.changeSetList.Has(Attr_Change_Skill_Equip) {
  763. bChange = true
  764. }
  765. if bChange {
  766. ntfAttrType := &serverproto.ActorAttrType{
  767. IsHeroPet: true,
  768. ActorId: uint32(heroData.Id),
  769. }
  770. //util.InfoF("aaaaa3", this.attrPercent)
  771. //代码优化,避免频繁出现扩容操作
  772. ntfAttrType.AttrList = make([]*serverproto.KeyValueFloat32, 0, 16)
  773. this.attrMag.copyAttrToMsg(this, ntfAttrType)
  774. //计算战力
  775. //util.InfoF("aaaaaaa", ntfAttrType)
  776. //util.InfoF("aaaaaaa22", heroData)
  777. heroFightPower := this.calcActorFightPower(ntfAttrType.AttrList)
  778. this.getRole().GetRoleHero().BattleAttrChange(heroData, ntfAttrType, heroFightPower)
  779. if !attrChangeSt.IgnoreNotify {
  780. ntfMsg := &serverproto.SCActorAttrGetNtf{}
  781. ntfMsg.ActorAttrList = append(ntfMsg.ActorAttrList, ntfAttrType)
  782. this.attrMag.role.ReplayGate(ntfMsg, true)
  783. }
  784. }
  785. return bChange
  786. }
  787. // 计算属性
  788. // 属性点加成
  789. func (this *ActorAttr) calcAddPointAttrs(heroData *serverproto.HeroData, attrList []*serverproto.KeyValueType) bool {
  790. if heroData == nil {
  791. return false
  792. }
  793. //tmpList := this.changeSetList.List()
  794. //util.DebugF("tmpList=%v", tmpList)
  795. if !this.changeSetList.Has(Attr_Change_AddPoint) {
  796. return false
  797. }
  798. this.changeSetList.Remove(Attr_Change_AddPoint)
  799. if attrList == nil {
  800. attrList = heroData.AttrList
  801. }
  802. if len(attrList) <= 0 && heroData.BaseLevel <= 0 {
  803. return false
  804. }
  805. for idx := range attrList {
  806. key := serverproto.Attr(attrList[idx].Key)
  807. this.setBaseFirstAttr(key, 1+attrList[idx].Value)
  808. }
  809. return true
  810. }
  811. // 技能升级添加属性
  812. func (this *ActorAttr) calcSkillAttrs(heroData *serverproto.HeroData, attrChangeSt AttrChangeST) bool {
  813. if !this.changeSetList.Has(Attr_Change_Skill) {
  814. return false
  815. }
  816. this.changeSetList.Remove(Attr_Change_Skill)
  817. attrList := map[serverproto.Attr]float32{}
  818. //get attr
  819. if attrChangeSt.BSkillReset {
  820. //reset
  821. this.GetSkillAttr(heroData.Skill, attrList, attrChangeSt)
  822. this.calAttr(this.curSkillAttr, attrList)
  823. this.curSkillAttr = attrList
  824. this.curSkillFightPower = 0
  825. } else {
  826. this.GetSkillAttr(heroData.Skill, attrList, attrChangeSt)
  827. this.calAttr(this.curSkillAttr, attrList)
  828. this.curSkillAttr = attrList
  829. //level up
  830. //this.GetSkillAttr(heroData.Skill, attrList, attrChangeSt)
  831. //this.calAttrAdd(this.curSkillAttr, attrList)
  832. //fight power
  833. if this.curSkillFightPower < 0 {
  834. if this.isPet {
  835. this.curSkillFightPower =
  836. int64(this.attrMag.getPetTotalSkillFightPower(this.heroId))
  837. } else {
  838. this.curSkillFightPower =
  839. int64(this.attrMag.getHeroTotalSkillFightPower(this.heroId))
  840. }
  841. } else {
  842. skillCfg, ok := serverproto.SkillCfgLoader[attrChangeSt.SkillCfgId]
  843. if ok {
  844. this.curSkillFightPower += int64(skillCfg.AddFight)
  845. }
  846. }
  847. }
  848. return true
  849. }
  850. func (this *ActorAttr) calcHeadFrameAttrs(heroData *serverproto.HeroData, attrChangeSt AttrChangeST) bool {
  851. if !this.changeSetList.Has(Attr_Change_HeadFrame) {
  852. return false
  853. }
  854. this.changeSetList.Remove(Attr_Change_HeadFrame)
  855. attrList := map[serverproto.Attr]float32{}
  856. //get attr
  857. if attrChangeSt.HeadFrameId > 0 {
  858. this.GetHeadFrameAttr(attrList, attrChangeSt)
  859. if attrChangeSt.BHeadFrameDelete {
  860. this.calAttrDel(this.curHeadFrameAttr, attrList)
  861. } else {
  862. this.calAttrAdd(this.curHeadFrameAttr, attrList)
  863. }
  864. } else {
  865. this.GetHeadFrameAttr(attrList, attrChangeSt)
  866. this.calAttr(this.curHeadFrameAttr, attrList)
  867. this.curHeadFrameAttr = attrList
  868. }
  869. return true
  870. }
  871. // equip
  872. func (this *ActorAttr) calcEquipAttrs(heroData *serverproto.HeroData) bool {
  873. if !this.changeSetList.Has(Attr_Change_Equip) {
  874. return false
  875. }
  876. this.changeSetList.Remove(Attr_Change_Equip)
  877. attrList := map[serverproto.Attr]float32{}
  878. //get attr
  879. this.GetEquipAttr(heroData.Slot, attrList)
  880. this.calAttr(this.curEquipAttr, attrList)
  881. this.curEquipAttr = attrList
  882. return true
  883. }
  884. // 特权添加属性处理
  885. func (this *ActorAttr) calcPrivilegeAttrs(heroData *serverproto.HeroData) bool {
  886. if !this.changeSetList.Has(Attr_Change_VipPrivilege) {
  887. return false
  888. }
  889. this.changeSetList.Remove(Attr_Change_VipPrivilege)
  890. attrList := map[serverproto.Attr]float32{}
  891. this.GetPrivilegeAttr(attrList)
  892. this.calAttr(this.curPrivilegeAttr, attrList)
  893. this.curPrivilegeAttr = attrList
  894. return true
  895. }
  896. // card
  897. func (this *ActorAttr) calcCardAttrs(heroData *serverproto.HeroData) bool {
  898. if !this.changeSetList.Has(Attr_Change_Card) {
  899. return false
  900. }
  901. this.changeSetList.Remove(Attr_Change_Card)
  902. this.triggerBuffList = map[uint32]*serverproto.TriggerBuffData{}
  903. attrList := map[serverproto.Attr]float32{}
  904. //get attr
  905. for _, data := range heroData.Slot.SlotList {
  906. this.GetCardAttr(data, attrList)
  907. }
  908. //card suit attr(卡片祝福属性)
  909. this.getRole().GetRoleCard().GetCardSuitAttr(heroData, attrList)
  910. this.calAttr(this.curCardAttr, attrList)
  911. this.curCardAttr = attrList
  912. return true
  913. }
  914. // skill equip
  915. func (this *ActorAttr) calcSkillEquipSlotAttrs(heroData *serverproto.HeroData) bool {
  916. if !this.changeSetList.Has(Attr_Change_Skill_Equip_Slot) {
  917. return false
  918. }
  919. this.changeSetList.Remove(Attr_Change_Skill_Equip_Slot)
  920. if heroData.SkillEquipSlot == nil ||
  921. heroData.SkillEquipSlot.SlotList == nil {
  922. return false
  923. }
  924. attrList := map[serverproto.Attr]float32{}
  925. //get attr
  926. for _, data := range heroData.SkillEquipSlot.SlotList {
  927. if data.SkillEquipId <= 0 {
  928. continue
  929. }
  930. this.GetSkillEquipSlotAttr(data, attrList)
  931. }
  932. this.calAttr(this.curSkillEquipAttr, attrList)
  933. this.curSkillEquipAttr = attrList
  934. return true
  935. }
  936. // fashion
  937. func (this *ActorAttr) calcFashionAttr(fashionData *serverproto.FashionData, heroData *serverproto.HeroData) bool {
  938. if !this.changeSetList.Has(Attr_Change_Fashion) {
  939. return false
  940. }
  941. this.changeSetList.Remove(Attr_Change_Fashion)
  942. //attrList := map[serverproto.Attr]float32{}
  943. //this.GetFashionAttr(fashionData, heroData, attrList)
  944. //
  945. //this.calAttr(this.curFashionAttr, attrList)
  946. //this.curFashionAttr = attrList
  947. var heroJobType int32 = 0
  948. if !this.isMainHero {
  949. heroCfg, ok := serverproto.ParterCfgLoader[heroData.ConfigId]
  950. if !ok {
  951. return false
  952. }
  953. heroJobType = heroCfg.JobType
  954. }
  955. attrList := map[serverproto.Attr]float32{}
  956. if attrMapList, ok := this.attrMag.curGlobalFashionAttr[heroJobType]; ok {
  957. for key, val := range attrMapList {
  958. attrList[key] += val
  959. }
  960. }
  961. this.calAttr(this.curFashionAttr, attrList)
  962. this.curFashionAttr = attrList
  963. return true
  964. }
  965. // sake
  966. func (this *ActorAttr) calcSakeAttr(heroData *serverproto.HeroData) bool {
  967. if !this.changeSetList.Has(Attr_Change_Sake) {
  968. return false
  969. }
  970. this.changeSetList.Remove(Attr_Change_Sake)
  971. var heroJobType int32 = 0
  972. if !this.isMainHero {
  973. heroCfg, ok := serverproto.ParterCfgLoader[heroData.ConfigId]
  974. if !ok {
  975. return false
  976. }
  977. heroJobType = heroCfg.JobType
  978. }
  979. attrList := map[serverproto.Attr]float32{}
  980. if attrMapList, ok := this.attrMag.curGlobalSakeAttr[heroJobType]; ok {
  981. for key, val := range attrMapList {
  982. attrList[key] += val
  983. }
  984. }
  985. this.calAttr(this.curSakeAttr, attrList)
  986. this.curSakeAttr = attrList
  987. return true
  988. }
  989. // sake
  990. func (this *ActorAttr) calcHeadAttr(heroData *serverproto.HeroData) bool {
  991. if !this.changeSetList.Has(Attr_Change_Head) {
  992. return false
  993. }
  994. this.changeSetList.Remove(Attr_Change_Head)
  995. if this.attrMag == nil || this.attrMag.role == nil {
  996. return false
  997. }
  998. head := this.attrMag.role.roleHead
  999. if head == nil {
  1000. return false
  1001. }
  1002. attrList := map[serverproto.Attr]float32{}
  1003. state := int32(Head_Not_Activate)
  1004. for _, data := range head.headData {
  1005. if data.State <= state {
  1006. continue
  1007. }
  1008. db, ok := model.DbHeadData[data.HeadId]
  1009. if !ok {
  1010. continue
  1011. }
  1012. for _, kv := range db.Attr {
  1013. attrList[serverproto.Attr(kv.Key)] += float32(kv.Value)
  1014. }
  1015. }
  1016. this.calAttr(this.curHeadAttr, attrList)
  1017. this.curHeadAttr = attrList
  1018. return true
  1019. }
  1020. // hero advance
  1021. func (this *ActorAttr) calcAdvanceAttrs(heroData *serverproto.HeroData) bool {
  1022. if !this.changeSetList.Has(Attr_Change_Advance) {
  1023. return false
  1024. }
  1025. this.changeSetList.Remove(Attr_Change_Advance)
  1026. //get attr
  1027. attrList := map[serverproto.Attr]float32{}
  1028. this.GetAdvanceAttrs(heroData, attrList)
  1029. this.calAttr(this.curAdvanceAttr, attrList)
  1030. this.curAdvanceAttr = attrList
  1031. return true
  1032. }
  1033. // hero strength
  1034. func (this *ActorAttr) calcStrengthAttr(heroData *serverproto.HeroData) bool {
  1035. if !this.changeSetList.Has(Attr_Change_Strength) {
  1036. return false
  1037. }
  1038. this.changeSetList.Remove(Attr_Change_Strength)
  1039. //get attr
  1040. attrList := map[serverproto.Attr]float32{}
  1041. this.GetStrengthAttrs(heroData, attrList)
  1042. this.calAttr(this.curStrengthAttr, attrList)
  1043. this.curStrengthAttr = attrList
  1044. return true
  1045. }
  1046. // pet
  1047. func (this *ActorAttr) calcPetAttr(heroData *serverproto.HeroData, attrChangeSt AttrChangeST) bool {
  1048. if !this.changeSetList.Has(Attr_Change_Pet) {
  1049. return false
  1050. }
  1051. this.changeSetList.Remove(Attr_Change_Pet)
  1052. //get attr
  1053. attrList := map[serverproto.Attr]float32{}
  1054. this.GetPetAttrs(heroData, attrList, attrChangeSt)
  1055. util.DebugF("###hero inherit from pet=%v###", heroData.BattlePetId)
  1056. this.attrPrintString(attrList)
  1057. util.DebugF("###hero inherit from pet###\n")
  1058. this.calAttr(this.curPetAttr, attrList)
  1059. this.curPetAttr = attrList
  1060. return true
  1061. }
  1062. func (this *ActorAttr) calAttr(curAttr map[serverproto.Attr]float32, attrList map[serverproto.Attr]float32) {
  1063. for key := range attrList {
  1064. deltaValue := attrList[key] - curAttr[key]
  1065. delete(curAttr, key)
  1066. if deltaValue == 0 {
  1067. continue
  1068. }
  1069. if key >= serverproto.Attr_Life && key <= serverproto.Attr_RealHurt {
  1070. this.SetAdditionalAttr(key, this.GetAdditionalAttr(key)+float64(deltaValue))
  1071. } else if key >= serverproto.Attr_STR_Percent {
  1072. this.SetAdditionalAttrPercent(key, this.GetAdditionalAttrPercent(key)+deltaValue)
  1073. }
  1074. }
  1075. for key := range curAttr {
  1076. deltaValue := -curAttr[key]
  1077. delete(curAttr, key)
  1078. if deltaValue == 0 {
  1079. continue
  1080. }
  1081. if key >= serverproto.Attr_Life && key <= serverproto.Attr_RealHurt {
  1082. this.SetAdditionalAttr(key, this.GetAdditionalAttr(key)+float64(deltaValue))
  1083. } else if key >= serverproto.Attr_STR_Percent {
  1084. this.SetAdditionalAttrPercent(key, this.GetAdditionalAttrPercent(key)+deltaValue)
  1085. }
  1086. }
  1087. }
  1088. // 直接添加到总属性上
  1089. func (this *ActorAttr) calAttrAdd(curAttr map[serverproto.Attr]float32, attrList map[serverproto.Attr]float32) {
  1090. for key, val := range attrList {
  1091. deltaValue := val
  1092. curAttr[key] += deltaValue
  1093. if key >= serverproto.Attr_Life && key <= serverproto.Attr_RealHurt {
  1094. this.SetAdditionalAttr(key, this.GetAdditionalAttr(key)+float64(deltaValue))
  1095. } else if key >= serverproto.Attr_STR_Percent {
  1096. this.SetAdditionalAttrPercent(key, this.GetAdditionalAttrPercent(key)+deltaValue)
  1097. }
  1098. }
  1099. }
  1100. // 直接减到总属性上
  1101. func (this *ActorAttr) calAttrDel(curAttr map[serverproto.Attr]float32, attrList map[serverproto.Attr]float32) {
  1102. for key, val := range attrList {
  1103. deltaValue := -val
  1104. curAttr[key] += deltaValue
  1105. if key >= serverproto.Attr_Life && key <= serverproto.Attr_RealHurt {
  1106. this.SetAdditionalAttr(key, this.GetAdditionalAttr(key)+float64(deltaValue))
  1107. } else if key >= serverproto.Attr_STR_Percent {
  1108. this.SetAdditionalAttrPercent(key, this.GetAdditionalAttrPercent(key)+deltaValue)
  1109. }
  1110. }
  1111. }
  1112. // attr copy
  1113. func (this *ActorAttr) calAttrCopy(curAttr map[serverproto.Attr]float32, attrList map[serverproto.Attr]float32) {
  1114. for key, val := range curAttr {
  1115. attrList[key] += val
  1116. }
  1117. }
  1118. func (this *ActorAttr) GetSkillAttr(roleSkill *serverproto.RoleSkill,
  1119. baseAttrList map[serverproto.Attr]float32, attrChangeSt AttrChangeST) {
  1120. if roleSkill == nil {
  1121. return
  1122. }
  1123. for _, jobSkillList := range roleSkill.JobSkillList {
  1124. for _, skill := range jobSkillList.UnlockSkillList {
  1125. cfgData, ok := model.ConvertSkillAttr[skill.Key]
  1126. if !ok {
  1127. continue
  1128. }
  1129. for k, valList := range cfgData.AttrList {
  1130. //level
  1131. if k <= skill.Value {
  1132. for idx := 0; idx < len(valList); idx++ {
  1133. baseAttrList[serverproto.Attr(valList[idx].Key)] += float32(valList[idx].Value)
  1134. }
  1135. }
  1136. }
  1137. //上一阶技能属性
  1138. this.getSkillAttr(skill.Key, baseAttrList)
  1139. }
  1140. }
  1141. return
  1142. //init
  1143. //if len(this.curSkillAttr) <= 0 {
  1144. // for _, jobSkillList := range roleSkill.JobSkillList {
  1145. // for _, skill := range jobSkillList.UnlockSkillList {
  1146. // cfgData, ok := model.ConvertSkillAttr[skill.Key]
  1147. // if !ok {
  1148. // continue
  1149. // }
  1150. // for k, valList := range cfgData.AttrList {
  1151. // //level
  1152. // if k <= skill.Value {
  1153. // for idx := 0; idx < len(valList); idx++ {
  1154. // baseAttrList[serverproto.Attr(valList[idx].Key)] += float32(valList[idx].Value)
  1155. // }
  1156. // }
  1157. // }
  1158. // }
  1159. // }
  1160. //} else {
  1161. // if attrChangeSt.SkillCfgId <= 0 || attrChangeSt.OldSkillLevel == attrChangeSt.NewSkillLevel {
  1162. // return
  1163. // }
  1164. //
  1165. // cfgData, ok := model.ConvertSkillAttr[attrChangeSt.SkillCfgId]
  1166. // if !ok {
  1167. // return
  1168. // }
  1169. // for k, valList := range cfgData.AttrList {
  1170. // //level
  1171. // if k > attrChangeSt.OldSkillLevel && k <= attrChangeSt.NewSkillLevel {
  1172. // for idx := 0; idx < len(valList); idx++ {
  1173. // baseAttrList[serverproto.Attr(valList[idx].Key)] += float32(valList[idx].Value)
  1174. // }
  1175. // }
  1176. // }
  1177. //}
  1178. }
  1179. func (this *ActorAttr) getSkillAttr(skillId int32, baseAttrList map[serverproto.Attr]float32) {
  1180. if this.isMainHero {
  1181. //role
  1182. skillCfg, ok := serverproto.SkillTreeCfgLoader[skillId]
  1183. if !ok || skillCfg.BeforeSkill <= 0 {
  1184. return
  1185. }
  1186. cfgData, ok := model.ConvertSkillAttr[skillCfg.BeforeSkill]
  1187. if ok {
  1188. beforeSkill, ok := serverproto.SkillTreeCfgLoader[skillCfg.BeforeSkill]
  1189. if ok {
  1190. for k, valList := range cfgData.AttrList {
  1191. //level
  1192. if k <= beforeSkill.MaxLv {
  1193. for idx := 0; idx < len(valList); idx++ {
  1194. baseAttrList[serverproto.Attr(valList[idx].Key)] += float32(valList[idx].Value)
  1195. }
  1196. }
  1197. }
  1198. this.getSkillAttr(skillCfg.BeforeSkill, baseAttrList)
  1199. }
  1200. }
  1201. } else {
  1202. //partner
  1203. skillCfg, ok := serverproto.ParterSkillTreeCfgLoader[skillId]
  1204. if !ok || skillCfg.BeforeSkill <= 0 {
  1205. return
  1206. }
  1207. cfgData, ok := model.ConvertSkillAttr[skillCfg.BeforeSkill]
  1208. if ok {
  1209. beforeSkill, ok := serverproto.ParterSkillTreeCfgLoader[skillCfg.BeforeSkill]
  1210. if ok {
  1211. for k, valList := range cfgData.AttrList {
  1212. //level
  1213. if k <= beforeSkill.MaxLv {
  1214. for idx := 0; idx < len(valList); idx++ {
  1215. baseAttrList[serverproto.Attr(valList[idx].Key)] += float32(valList[idx].Value)
  1216. }
  1217. }
  1218. }
  1219. this.getSkillAttr(skillCfg.BeforeSkill, baseAttrList)
  1220. }
  1221. }
  1222. }
  1223. }
  1224. func (this *ActorAttr) GetHeadFrameAttr(baseAttrList map[serverproto.Attr]float32, attrChangeSt AttrChangeST) {
  1225. //init
  1226. if len(this.curHeadFrameAttr) <= 0 || attrChangeSt.HeadFrameId <= 0 {
  1227. nowTime := util.GetTimeSeconds()
  1228. headFrameDataList := this.attrMag.role.GetRoleBase().roleBase.Head_Info.HeadFrameList
  1229. for idx := 0; idx < len(headFrameDataList); idx++ {
  1230. cfgData, ok := model.ConvertHeadFrameAttr[headFrameDataList[idx].HeadFrameId]
  1231. if !ok {
  1232. continue
  1233. }
  1234. if headFrameDataList[idx].HeadFrameTime > 0 && headFrameDataList[idx].HeadFrameTime <= nowTime {
  1235. continue
  1236. }
  1237. for k, v := range cfgData.AttrList {
  1238. baseAttrList[serverproto.Attr(k)] += float32(v)
  1239. }
  1240. }
  1241. } else {
  1242. cfgData, ok := model.ConvertHeadFrameAttr[attrChangeSt.HeadFrameId]
  1243. if !ok {
  1244. return
  1245. }
  1246. for k, v := range cfgData.AttrList {
  1247. baseAttrList[serverproto.Attr(k)] += float32(v)
  1248. }
  1249. }
  1250. }
  1251. // 获取属性
  1252. func (this *ActorAttr) GetEquipAttr(slotData *serverproto.SlotData, baseAttrList map[serverproto.Attr]float32) {
  1253. var suitList = map[int32]int32{}
  1254. //最小精炼等级
  1255. var minRefineLevel int32 = 0
  1256. //套装处理
  1257. for _, data := range slotData.SlotList {
  1258. if data.EquipId <= 0 {
  1259. continue
  1260. }
  1261. cfgData, ok := model.EquipAttrContainer[data.EquipId]
  1262. if !ok {
  1263. continue
  1264. }
  1265. //套装数量统计
  1266. if cfgData.SuitId > 0 {
  1267. suitList[cfgData.SuitId]++
  1268. }
  1269. if minRefineLevel <= 0 {
  1270. minRefineLevel = data.Level
  1271. } else if data.Level < minRefineLevel {
  1272. minRefineLevel = data.Level
  1273. }
  1274. var refineDataResult float32 = 0
  1275. refineData, ok := serverproto.EquipRefineCfgLoader[data.Level]
  1276. if ok {
  1277. refineDataResult = float32(refineData.Result)
  1278. }
  1279. for _, data := range cfgData.AttrSet {
  1280. if data.Key <= 0 || data.Value <= 0 {
  1281. continue
  1282. }
  1283. if data.Key < int32(serverproto.Attr_STR_Percent) {
  1284. refineAdd := float32(data.Value) * (refineDataResult + 100) * 0.01
  1285. baseAttrList[serverproto.Attr(data.Key)] += refineAdd
  1286. }
  1287. }
  1288. }
  1289. //精炼等级全套属性处理
  1290. for i := minRefineLevel; i >= 1; i-- {
  1291. refineData, ok := model.EquipRefineContainer[i]
  1292. if !ok {
  1293. continue
  1294. }
  1295. for _, data := range refineData.AttrSet {
  1296. if data.Key >= int32(serverproto.Attr_STR_Percent) {
  1297. baseAttrList[serverproto.Attr(data.Key)] += float32(data.Value)
  1298. }
  1299. }
  1300. }
  1301. //装备套装属性处理
  1302. for suitId, suitCount := range suitList {
  1303. suitCfgData, ok := model.SuitAttrContainer[suitId]
  1304. if !ok {
  1305. continue
  1306. }
  1307. if suitCount >= 2 {
  1308. for key, value := range suitCfgData.AttrSet[0] {
  1309. baseAttrList[serverproto.Attr(key)] += float32(value)
  1310. }
  1311. }
  1312. if suitCount >= 4 {
  1313. for key, value := range suitCfgData.AttrSet[1] {
  1314. baseAttrList[serverproto.Attr(key)] += float32(value)
  1315. }
  1316. }
  1317. if suitCount >= 6 {
  1318. for key, value := range suitCfgData.AttrSet[2] {
  1319. baseAttrList[serverproto.Attr(key)] += float32(value)
  1320. }
  1321. }
  1322. }
  1323. //todo... 优化
  1324. for key, value := range baseAttrList {
  1325. if key >= serverproto.Attr_STR_Percent && key <= serverproto.Attr_RealHurt_Percent {
  1326. baseAttrList[key] = value * 0.0001
  1327. }
  1328. }
  1329. for key, value := range baseAttrList {
  1330. if key < serverproto.Attr_STR_Percent {
  1331. baseAttrList[key] = value * (1 + baseAttrList[key+30])
  1332. }
  1333. }
  1334. for key := range baseAttrList {
  1335. if key >= serverproto.Attr_STR_Percent && key <= serverproto.Attr_RealHurt_Percent {
  1336. baseAttrList[key] = 0
  1337. }
  1338. }
  1339. }
  1340. func (this *ActorAttr) GetPrivilegeAttr(baseAttrList map[serverproto.Attr]float32) {
  1341. // RO通行证购买后添加属性
  1342. if this.getRole().GetRoleRune() == nil {
  1343. return
  1344. }
  1345. if !this.getRole().GetRoleRune().runeBase.IsPassCheck {
  1346. return
  1347. }
  1348. for key, val := range model.ConvertPassCheckData.AttrList {
  1349. baseAttrList[serverproto.Attr(key)] += float32(val)
  1350. }
  1351. }
  1352. func (this *ActorAttr) GetCardAttr(slotDetail *serverproto.SlotDetailData, baseAttrList map[serverproto.Attr]float32) {
  1353. for _, data := range slotDetail.CardIdList {
  1354. convertData, ok := model.ConvertCardList[data]
  1355. if !ok {
  1356. return
  1357. }
  1358. if len(convertData.AttrList) > 0 {
  1359. for key, value := range convertData.AttrList {
  1360. if key < int32(serverproto.Attr_STR_Percent) {
  1361. baseAttrList[serverproto.Attr(key)] += value
  1362. } else {
  1363. //baseAttrList[serverproto.Attr(key)] += value * 0.0001
  1364. baseAttrList[serverproto.Attr(key)] += value
  1365. }
  1366. }
  1367. }
  1368. if len(convertData.TriggerBuffList) > 0 {
  1369. for _, data := range convertData.TriggerBuffList {
  1370. this.triggerBuffList[data.BuffId] = data
  1371. }
  1372. }
  1373. }
  1374. }
  1375. func (this *ActorAttr) GetSkillEquipSlotAttr(slotDetail *serverproto.SkillEquipSlotDetailData, baseAttrList map[serverproto.Attr]float32) {
  1376. convertData, ok := model.SkillEquipSlotAppendAttrContainer[slotDetail.SlotLevel]
  1377. if !ok {
  1378. return
  1379. }
  1380. var realHealHurt int32 = 0
  1381. if len(convertData) > 0 {
  1382. for key, value := range convertData {
  1383. if key < serverproto.Attr_STR_Percent {
  1384. baseAttrList[key] += value
  1385. if key == serverproto.Attr_RealHurt {
  1386. realHealHurt += int32(value)
  1387. }
  1388. } else {
  1389. //baseAttrList[serverproto.Attr(key)] += value * 0.0001
  1390. baseAttrList[key] += value
  1391. }
  1392. }
  1393. }
  1394. slotDetail.SlotAttrs = []*serverproto.KeyValueType{
  1395. &serverproto.KeyValueType{
  1396. Key: int32(serverproto.Attr_RealHurt), Value: realHealHurt}}
  1397. }
  1398. func (this *ActorAttr) GetFashionAttr(fashionData *serverproto.FashionData, heroData *serverproto.HeroData, baseAttrList map[serverproto.Attr]float32) {
  1399. if fashionData != nil {
  1400. //// 使用外层传入的系统数据进行计算(其他玩家)
  1401. //for _, fId := range fashionData.FashionUpList {
  1402. // attrDataList, ok := model.FashionAttrContainer[fId]
  1403. // if !ok {
  1404. // continue
  1405. // }
  1406. // for _, attr := range attrDataList.AttrSet {
  1407. // if attr.Key < int32(serverproto.Attr_STR_Percent) {
  1408. // baseAttrList[serverproto.Attr(attr.Key)] += float32(attr.Value)
  1409. // } else {
  1410. // baseAttrList[serverproto.Attr(attr.Key)] += float32(attr.Value) * 0.0001
  1411. // }
  1412. // }
  1413. //}
  1414. } else {
  1415. //玩家自己
  1416. heroCfg, ok := serverproto.ParterCfgLoader[heroData.ConfigId]
  1417. if !ok {
  1418. return
  1419. }
  1420. for _, data := range this.attrMag.role.GetRoleFashion().fashionData {
  1421. //attrDataList, ok := model.FashionAttrContainer[data]
  1422. //if !ok {
  1423. // continue
  1424. //}
  1425. for _, attr := range data.attrs {
  1426. if attr.JobType == 0 && this.attrMag.role.GetRoleHero().IsMainHero(heroData.Id) {
  1427. continue
  1428. }
  1429. if attr.JobType > 0 && attr.JobType != heroCfg.JobType {
  1430. continue
  1431. }
  1432. if attr.AttrId < int32(serverproto.Attr_STR_Percent) {
  1433. baseAttrList[serverproto.Attr(attr.AttrId)] += float32(attr.Value)
  1434. } else {
  1435. baseAttrList[serverproto.Attr(attr.AttrId)] += float32(attr.Value)
  1436. }
  1437. }
  1438. }
  1439. //套装属性
  1440. if this.attrMag.role.GetRoleHero().IsMainHero(heroData.Id) {
  1441. for idx := 0; idx < len(this.attrMag.role.GetRoleFashion().fashionSuitAttrs); idx++ {
  1442. attrItem := this.attrMag.role.GetRoleFashion().fashionSuitAttrs[idx]
  1443. if attrItem.Key < int32(serverproto.Attr_STR_Percent) {
  1444. baseAttrList[serverproto.Attr(attrItem.Key)] += float32(attrItem.Value)
  1445. } else {
  1446. baseAttrList[serverproto.Attr(attrItem.Key)] += float32(attrItem.Value)
  1447. }
  1448. }
  1449. }
  1450. //获得就添加属性
  1451. //for _, data := range this.attrMag.role.GetRoleFashion().fashionList {
  1452. // attrDataList, ok := model.FashionAttrContainer[data]
  1453. // if !ok {
  1454. // continue
  1455. // }
  1456. // for _, attr := range attrDataList.AttrSet {
  1457. // if attr.Key < int32(serverproto.Attr_STR_Percent) {
  1458. // baseAttrList[serverproto.Attr(attr.Key)] += float32(attr.Value)
  1459. // } else {
  1460. // baseAttrList[serverproto.Attr(attr.Key)] += float32(attr.Value)
  1461. // }
  1462. // }
  1463. //}
  1464. }
  1465. }
  1466. // 进阶(突破等级上限,角色通过专职来处理)
  1467. func (this *ActorAttr) GetAdvanceAttrs(heroData *serverproto.HeroData, baseAttrList map[serverproto.Attr]float32) {
  1468. if heroData.AdvanceLevel <= 0 {
  1469. return
  1470. }
  1471. partner, ok := serverproto.ParterCfgLoader[heroData.ConfigId]
  1472. if !ok {
  1473. return
  1474. }
  1475. stepCfgData, ok := model.ProgressAttrContainer[partner.ParterJob]
  1476. if !ok {
  1477. util.DebugF("[CalAttr] GetAdvanceAttrs data not found:%v", heroData.ConfigId)
  1478. return
  1479. }
  1480. for i := 0; i < int(heroData.AdvanceLevel); i++ {
  1481. if stepCfgData.AttrSet[int32(i)] == nil {
  1482. continue
  1483. }
  1484. for key, value := range stepCfgData.AttrSet[int32(i)] {
  1485. baseAttrList[serverproto.Attr(key)] += float32(value)
  1486. }
  1487. }
  1488. }
  1489. // 突破
  1490. func (this *ActorAttr) GetStrengthAttrs(heroData *serverproto.HeroData, baseAttrList map[serverproto.Attr]float32) {
  1491. if heroData.StrengthLevel <= 0 {
  1492. return
  1493. }
  1494. partner, ok := serverproto.ParterCfgLoader[heroData.ConfigId]
  1495. if !ok {
  1496. return
  1497. }
  1498. stepCfgData, ok := model.StrengthAttrContainer[partner.ParterJob]
  1499. if !ok {
  1500. util.DebugF("CalAttr GetStrengthAttrs data not found herocfgid=%v", heroData.ConfigId)
  1501. return
  1502. }
  1503. for i := 0; i < int(heroData.StrengthLevel); i++ {
  1504. if stepCfgData.AttrSet[int32(i)] == nil {
  1505. continue
  1506. }
  1507. for key, value := range stepCfgData.AttrSet[int32(i)] {
  1508. baseAttrList[serverproto.Attr(key)] += float32(value)
  1509. }
  1510. }
  1511. }
  1512. // 可能是上阵,也可能是下阵
  1513. func (this *ActorAttr) GetPetAttrs(heroData *serverproto.HeroData, baseAttrList map[serverproto.Attr]float32, attrChangeSt AttrChangeST) {
  1514. if heroData.BattlePetId <= 0 {
  1515. return
  1516. }
  1517. petDataInfo := this.attrMag.role.GetRolePet().getPet(heroData.BattlePetId)
  1518. if petDataInfo == nil {
  1519. return
  1520. }
  1521. petCfg, ok := serverproto.PetCfgLoader[petDataInfo.ConfigId]
  1522. if !ok {
  1523. return
  1524. }
  1525. petActorAttr := this.attrMag.getPetActorAttr(petDataInfo)
  1526. if petActorAttr == nil {
  1527. return
  1528. }
  1529. if len(petActorAttr.curPetAttrForPetBase) <= 0 { //初始化时需要先计算一次
  1530. this.attrMag.calcAttrPet([]*serverproto.PetData{petDataInfo}, attrChangeSt)
  1531. }
  1532. //base(level + advLevel)
  1533. this.petInheritAttrs(baseAttrList, petActorAttr.curPetAttrForPetBase, petCfg.ConversionRate)
  1534. //宠物羁绊属性
  1535. this.petInheritAttrs(baseAttrList, petActorAttr.curPetAttrForPetBond, petCfg.ConversionRate)
  1536. //宠物印记
  1537. this.petInheritAttrs(baseAttrList, petActorAttr.curPetAttrForPetEquip, petCfg.ConversionRate)
  1538. //宠物契约
  1539. this.petInheritAttrs(baseAttrList, petActorAttr.curPetAttrForPetQiyue, petCfg.ConversionRate)
  1540. }
  1541. func (this *ActorAttr) petInheritAttrs(dst map[serverproto.Attr]float32, src map[serverproto.Attr]float32, rate int32) {
  1542. for k, v := range src {
  1543. bFind := false
  1544. for idx := 0; idx < len(model.GlobalAttrPetNotInheritHeroList); idx++ {
  1545. if model.GlobalAttrPetNotInheritHeroList[idx] == k {
  1546. bFind = true
  1547. break
  1548. }
  1549. }
  1550. if bFind {
  1551. delete(dst, k)
  1552. continue
  1553. }
  1554. dst[k] += v * float32(rate) * 0.0001
  1555. }
  1556. }
  1557. func (this *ActorAttr) petInheritAttrsList(dst map[serverproto.Attr]float32, src []*serverproto.KeyValueFloat32, rate int32) {
  1558. for idx := 0; idx < len(src); idx++ {
  1559. k := serverproto.Attr(src[idx].Key)
  1560. v := src[idx].Value
  1561. bFind := false
  1562. for idx := 0; idx < len(model.GlobalAttrPetNotInheritHeroList); idx++ {
  1563. if model.GlobalAttrPetNotInheritHeroList[idx] == k {
  1564. bFind = true
  1565. break
  1566. }
  1567. }
  1568. if bFind {
  1569. delete(dst, k)
  1570. continue
  1571. }
  1572. dst[k] += v * float32(rate) * 0.0001
  1573. }
  1574. }
  1575. func (this *ActorAttr) getPetEquipAttrs(petData *serverproto.PetData, baseAttrList map[serverproto.Attr]float32) {
  1576. var suitList = map[int32]int32{} //[qulity][num]
  1577. for _, data := range petData.SlotEquipList {
  1578. if data.EquipId <= 0 {
  1579. continue
  1580. }
  1581. petEquipData := this.getRole().GetRolePet().GetPetEquip(data.EquipId)
  1582. if petEquipData == nil {
  1583. return
  1584. }
  1585. cfgData, ok := model.ConvertPetEquip[petEquipData.EquipCfgId]
  1586. if !ok {
  1587. return
  1588. }
  1589. levelCfgData, ok := cfgData.LevelUpList[petEquipData.Level]
  1590. if !ok {
  1591. return
  1592. }
  1593. for key, val := range levelCfgData.AttrList {
  1594. baseAttrList[serverproto.Attr(key)] += float32(val)
  1595. }
  1596. //印记套装
  1597. for idx := 1; idx <= int(cfgData.Quality); idx++ {
  1598. suitList[int32(idx)]++
  1599. }
  1600. //suitList[cfgData.Quality]++
  1601. }
  1602. //使用套装ID最大的一套(套装属性只针对印记)
  1603. for _, data := range model.ConvertPteEquipSuit {
  1604. bOk := true
  1605. for idx := 0; idx < len(data.ConditionList); idx++ {
  1606. if suitList[data.ConditionList[idx].Key] < data.ConditionList[idx].Value {
  1607. bOk = false
  1608. break
  1609. }
  1610. }
  1611. if bOk {
  1612. for key, val := range data.AttrList {
  1613. baseAttrList[serverproto.Attr(key)] += float32(val)
  1614. }
  1615. break
  1616. }
  1617. }
  1618. //for key, value := range baseAttrList {
  1619. // if key >= serverproto.Attr_STR_Percent && key <= serverproto.Attr_RealHurt_Percent {
  1620. // baseAttrList[key] = value
  1621. // }
  1622. //}
  1623. //for key, value := range baseAttrList {
  1624. // if key < serverproto.Attr_STR_Percent {
  1625. // baseAttrList[key] = value * (1 + baseAttrList[key+30])
  1626. // }
  1627. //}
  1628. //for key, _ := range baseAttrList {
  1629. // if key >= serverproto.Attr_STR_Percent && key <= serverproto.Attr_RealHurt_Percent {
  1630. // baseAttrList[key] = 0
  1631. // }
  1632. //}
  1633. }
  1634. func (this *ActorAttr) getPetQiyueAttrs(petData *serverproto.PetData, baseAttrList map[serverproto.Attr]float32) {
  1635. //判断当前宠物是否跟随玩家
  1636. if petData.HeroId <= 0 {
  1637. return
  1638. }
  1639. petQiyueCfg, ok := serverproto.PetCfgLoader[petData.ConfigId]
  1640. if !ok {
  1641. return
  1642. }
  1643. heroData := this.getRole().GetRoleHero().GetHero(petData.HeroId)
  1644. if heroData.PetQiyueData == nil || len(heroData.PetQiyueData.QiyueSlotList) <= 0 {
  1645. return
  1646. }
  1647. type petAttrTmp struct {
  1648. sameNatureType bool
  1649. contract int32 //继承万分比
  1650. outAttr *serverproto.ActorAttrType
  1651. totalSKillLevel int32
  1652. totalSkillLevelFactor int32
  1653. }
  1654. var petAttrTmpList []*petAttrTmp
  1655. sameNatureTypeNum := 0
  1656. for idx := 0; idx < len(heroData.PetQiyueData.QiyueSlotList); idx++ {
  1657. slotInfo := heroData.PetQiyueData.QiyueSlotList[idx]
  1658. if slotInfo.PetId > 0 && slotInfo.PetCfgId > 0 {
  1659. slotPetData := this.getRole().GetRolePet().getPet(slotInfo.PetId)
  1660. if slotPetData == nil {
  1661. continue
  1662. }
  1663. petCfg, ok := serverproto.PetCfgLoader[slotPetData.ConfigId]
  1664. if !ok {
  1665. continue
  1666. }
  1667. slotPetAttr := this.attrMag.getPetActorAttr(slotPetData)
  1668. if slotPetAttr == nil {
  1669. continue
  1670. }
  1671. if len(slotPetAttr.curPetAttrForPetBase) <= 0 {
  1672. this.attrMag.calcAttrPet([]*serverproto.PetData{slotPetData}, AttrChangeST{
  1673. ChangePetData: slotPetData,
  1674. IgnoreNotify: true,
  1675. })
  1676. }
  1677. //相同属性继承百分比处理
  1678. tmpAttr := &petAttrTmp{
  1679. contract: petCfg.Contract,
  1680. outAttr: &serverproto.ActorAttrType{
  1681. ActorId: slotPetData.Id,
  1682. },
  1683. }
  1684. this.attrMag.copyAttrToMsg(slotPetAttr, tmpAttr.outAttr)
  1685. if petCfg.NatureType == petQiyueCfg.NatureType {
  1686. sameNatureTypeNum++
  1687. tmpAttr.sameNatureType = true
  1688. }
  1689. //领悟次数增加百分比
  1690. tmpAttr.totalSKillLevel = this.getRole().GetRolePet().GetPetTotalSkillLevel(slotPetData)
  1691. tmpAttr.totalSkillLevelFactor = petCfg.Understand
  1692. petAttrTmpList = append(petAttrTmpList, tmpAttr)
  1693. }
  1694. }
  1695. //契约属性继承
  1696. for idx := 0; idx < len(petAttrTmpList); idx++ {
  1697. pet := petAttrTmpList[idx]
  1698. tmpContract := pet.contract
  1699. if pet.sameNatureType {
  1700. //相同属性百分比
  1701. tmpContract += model.GlobalPetQiyueNatureRate * int32(sameNatureTypeNum)
  1702. }
  1703. //领悟次数增加百分比
  1704. tmpContract += pet.totalSKillLevel * pet.totalSkillLevelFactor
  1705. this.petInheritAttrsList(baseAttrList, pet.outAttr.AttrList, tmpContract)
  1706. }
  1707. }
  1708. // for pet(宠物自身属性计算)
  1709. func (this *ActorAttr) calPetAttrForPetBase() bool {
  1710. //check is'nt a pet
  1711. if !this.isPet {
  1712. return false
  1713. }
  1714. if !this.changeSetList.Has(Attr_Change_Pet_Base) {
  1715. return false
  1716. }
  1717. this.changeSetList.Remove(Attr_Change_Pet_Base)
  1718. petCfgId := this.heroConfigId
  1719. petCfg, ok := serverproto.PetCfgLoader[petCfgId]
  1720. if !ok {
  1721. return false
  1722. }
  1723. progressData, ok := model.ConvertPetProgress[petCfgId]
  1724. if !ok {
  1725. return false
  1726. }
  1727. attrList := map[serverproto.Attr]float32{}
  1728. progressLevel := this.level
  1729. if len(model.GlobalPetAdvanceLimit) > 0 {
  1730. if progressLevel >= model.GlobalPetAdvanceLimit[0] {
  1731. progressLevel = model.GlobalPetAdvanceLimit[0]
  1732. }
  1733. }
  1734. var tmpBaseAttrList = map[serverproto.Attr]float32{}
  1735. tmpBaseAttrList[serverproto.Attr(serverproto.Attr_Life)] = float32(petCfg.Hp)
  1736. tmpBaseAttrList[serverproto.Attr(serverproto.Attr_Sp)] = float32(petCfg.Sp)
  1737. tmpBaseAttrList[serverproto.Attr(serverproto.Attr_Attack)] = float32(petCfg.Atk)
  1738. tmpBaseAttrList[serverproto.Attr(serverproto.Attr_MagicAttack)] = float32(petCfg.Matk)
  1739. tmpBaseAttrList[serverproto.Attr(serverproto.Attr_Defense)] = float32(petCfg.Def)
  1740. tmpBaseAttrList[serverproto.Attr(serverproto.Attr_MagicDefense)] = float32(petCfg.Mdef)
  1741. tmpBaseAttrList[serverproto.Attr(serverproto.Attr_Hit)] = float32(petCfg.Hit)
  1742. tmpBaseAttrList[serverproto.Attr(serverproto.Attr_Dodge)] = float32(petCfg.Dodge)
  1743. tmpBaseAttrList[serverproto.Attr(serverproto.Attr_Crit)] = float32(petCfg.Crit)
  1744. tmpBaseAttrList[serverproto.Attr(serverproto.Attr_Ten)] = float32(petCfg.Ten)
  1745. tmpBaseAttrList[serverproto.Attr(serverproto.Attr_AttackSpeed)] = float32(petCfg.AttackSpeed)
  1746. var tmpBaseRateList = map[serverproto.Attr]float32{}
  1747. tmpBaseRateList[serverproto.Attr(serverproto.Attr_Life)] = float32(petCfg.HpRate) * 0.0001
  1748. tmpBaseRateList[serverproto.Attr(serverproto.Attr_Sp)] = float32(petCfg.SpRate) * 0.0001
  1749. tmpBaseRateList[serverproto.Attr(serverproto.Attr_Attack)] = float32(petCfg.AtkRate) * 0.0001
  1750. tmpBaseRateList[serverproto.Attr(serverproto.Attr_MagicAttack)] = float32(petCfg.MatkRate) * 0.0001
  1751. tmpBaseRateList[serverproto.Attr(serverproto.Attr_Defense)] = float32(petCfg.DefRate) * 0.0001
  1752. tmpBaseRateList[serverproto.Attr(serverproto.Attr_MagicDefense)] = float32(petCfg.MdefRate) * 0.0001
  1753. tmpBaseRateList[serverproto.Attr(serverproto.Attr_Hit)] = float32(petCfg.HitRate) * 0.0001
  1754. tmpBaseRateList[serverproto.Attr(serverproto.Attr_Dodge)] = float32(petCfg.DodgeRate) * 0.0001
  1755. tmpBaseRateList[serverproto.Attr(serverproto.Attr_Crit)] = float32(petCfg.CritRate) * 0.0001
  1756. tmpBaseRateList[serverproto.Attr(serverproto.Attr_Ten)] = float32(petCfg.TenRate) * 0.0001
  1757. for k, v := range tmpBaseAttrList {
  1758. attrList[k] = v + v*float32(progressLevel-1)*tmpBaseRateList[k]
  1759. }
  1760. for advLevel := 1; advLevel <= int(this.advLevel); advLevel++ {
  1761. if len(model.GlobalPetAdvanceLimit) <= advLevel {
  1762. continue
  1763. }
  1764. for idx := 0; idx < len(progressData.ProgressList); idx++ {
  1765. if progressData.ProgressList[idx].ProgressLevel != int32(advLevel) {
  1766. continue
  1767. }
  1768. //进阶增加属性
  1769. for i := 0; i < len(progressData.ProgressList[idx].AttrList); i++ {
  1770. kv := progressData.ProgressList[idx].AttrList[i]
  1771. attrList[serverproto.Attr(kv.Key)] += float32(kv.Value)
  1772. }
  1773. //进阶后成长率变更对应的等级属性
  1774. progressLevel = this.level
  1775. if progressLevel >= model.GlobalPetAdvanceLimit[advLevel] {
  1776. progressLevel = model.GlobalPetAdvanceLimit[advLevel]
  1777. }
  1778. progressLevel -= model.GlobalPetAdvanceLimit[advLevel-1]
  1779. for i := 0; i < len(progressData.ProgressList[idx].RateList); i++ {
  1780. rate := progressData.ProgressList[idx].RateList[i]
  1781. attrList[serverproto.Attr(rate.Key)] +=
  1782. tmpBaseAttrList[serverproto.Attr(rate.Key)] * float32(progressLevel) * float32(rate.Value) * 0.0001
  1783. }
  1784. break
  1785. }
  1786. }
  1787. this.calAttr(this.curPetAttrForPetBase, attrList)
  1788. this.curPetAttrForPetBase = attrList
  1789. return true
  1790. }
  1791. func (this *ActorAttr) calPetAttrForPetEquip(petData *serverproto.PetData) bool {
  1792. if !this.isPet {
  1793. return false
  1794. }
  1795. if !this.changeSetList.Has(Attr_Change_Pet_Equip) {
  1796. return false
  1797. }
  1798. this.changeSetList.Remove(Attr_Change_Pet_Equip)
  1799. attrList := map[serverproto.Attr]float32{}
  1800. //get attr
  1801. this.getPetEquipAttrs(petData, attrList)
  1802. this.calAttr(this.curPetAttrForPetEquip, attrList)
  1803. this.curPetAttrForPetEquip = attrList
  1804. return true
  1805. }
  1806. func (this *ActorAttr) calPetAttrForPetBond(petData *serverproto.PetData) bool {
  1807. if !this.isPet {
  1808. return false
  1809. }
  1810. if !this.changeSetList.Has(Attr_Change_Pet_Bond) {
  1811. return false
  1812. }
  1813. this.changeSetList.Remove(Attr_Change_Pet_Bond)
  1814. attrList := map[serverproto.Attr]float32{}
  1815. if this.attrMag.role.GetRolePet().isBattle(petData) {
  1816. for k, v := range this.attrMag.curGlobalPetBondAttr {
  1817. attrList[k] += v
  1818. }
  1819. }
  1820. this.calAttr(this.curPetAttrForPetBond, attrList)
  1821. this.curPetAttrForPetBond = attrList
  1822. return true
  1823. }
  1824. func (this *ActorAttr) calPetAttrForPetSkill(petData *serverproto.PetData) bool {
  1825. if !this.changeSetList.Has(Attr_Change_Pet_Skill) {
  1826. return false
  1827. }
  1828. this.changeSetList.Remove(Attr_Change_Pet_Skill)
  1829. return true
  1830. }
  1831. func (this *ActorAttr) calPetAttrForPetQiyue(petData *serverproto.PetData) bool {
  1832. if !this.changeSetList.Has(Attr_Change_Pet_Qiyue) {
  1833. return false
  1834. }
  1835. this.changeSetList.Remove(Attr_Change_Pet_Qiyue)
  1836. attrList := map[serverproto.Attr]float32{}
  1837. //get attr
  1838. this.getPetQiyueAttrs(petData, attrList)
  1839. this.calAttr(this.curPetAttrForPetQiyue, attrList)
  1840. this.curPetAttrForPetQiyue = attrList
  1841. return true
  1842. }
  1843. func (this *ActorAttr) calcActorFightPower(attrList []*serverproto.KeyValueFloat32) uint64 {
  1844. var fightPower uint64 = 0
  1845. //attr fight power
  1846. var jobType int32 = -1
  1847. if this.isPet {
  1848. jobType = this.getRole().GetRolePet().GetPetJobType(uint32(this.heroId))
  1849. } else {
  1850. jobType = this.getRole().GetRoleHero().GetHeroJobType(this.heroId)
  1851. }
  1852. if jobType < 0 {
  1853. return fightPower
  1854. }
  1855. jobCfgData, ok := model.ConvertFightPower[jobType]
  1856. if !ok {
  1857. return fightPower
  1858. }
  1859. for _, attr := range attrList {
  1860. if attr.Key <= 0 || attr.Value <= 0 {
  1861. continue
  1862. }
  1863. if fightCof, ok := jobCfgData[attr.Key]; ok {
  1864. if fightCof >= 0 {
  1865. fightPower += uint64(int32(attr.Value) * fightCof)
  1866. }
  1867. }
  1868. }
  1869. this.curAttrFightPower = uint64(fightPower)
  1870. //skill fight power
  1871. //初始化技能升级添加战斗力
  1872. if this.isPet {
  1873. this.curSkillFightPower =
  1874. int64(this.attrMag.getPetTotalSkillFightPower(this.heroId))
  1875. } else {
  1876. this.curSkillFightPower =
  1877. int64(this.attrMag.getHeroTotalSkillFightPower(this.heroId))
  1878. }
  1879. //if this.curSkillFightPower < 0 {
  1880. // if this.isPet {
  1881. // this.curSkillFightPower =
  1882. // int64(this.attrMag.getPetTotalSkillFightPower(this.heroId))
  1883. // } else {
  1884. // this.curSkillFightPower =
  1885. // int64(this.attrMag.getHeroTotalSkillFightPower(this.heroId))
  1886. // }
  1887. //}
  1888. this.curSkillEquipFightPower = int64(this.attrMag.getSkillEquipFightPower(this.heroId))
  1889. fightPower += uint64(this.curSkillFightPower)
  1890. fightPower += uint64(this.curSkillEquipFightPower)
  1891. return fightPower
  1892. }
  1893. // 战斗属性计算
  1894. type RoleBattleAttr struct {
  1895. role *Role
  1896. bInitAttrCalc bool //玩家登陆时第一战斗时计算上阵单位属性
  1897. curTotalFightPower uint32 //当前玩家总战力
  1898. battleHeroActorList map[uint32]*serverproto.ActorData
  1899. //玩家英雄属性列表
  1900. roleActorAttrList map[int32]*ActorAttr
  1901. //玩家宠物属性列表
  1902. rolePetAttrList map[int32]*ActorAttr
  1903. //时装属性(多个英雄处理,所以这边单独分开)
  1904. curGlobalFashionAttr map[int32]map[serverproto.Attr]float32 //时装 [jobtype][attr][val]
  1905. bInitGlobalFashionAttr bool
  1906. //收集屋藏品属性(多个英雄处理,所以这边单独分开)
  1907. curGlobalSakeAttr map[int32]map[serverproto.Attr]float32 //[jobtype][attr][val]
  1908. bInitGlobalSakeAttr bool
  1909. //宠物羁绊属性(上阵所有宠物处理)
  1910. curGlobalPetBondAttr map[serverproto.Attr]float32 //[attr][val]
  1911. bInitGlobalPetBondAttr bool
  1912. }
  1913. func newRoleBattleAttr(r *Role) *RoleBattleAttr {
  1914. mag := &RoleBattleAttr{
  1915. role: r,
  1916. }
  1917. mag.rolePetAttrList = map[int32]*ActorAttr{}
  1918. mag.battleHeroActorList = map[uint32]*serverproto.ActorData{}
  1919. mag.roleActorAttrList = map[int32]*ActorAttr{}
  1920. mag.curGlobalFashionAttr = map[int32]map[serverproto.Attr]float32{}
  1921. mag.curGlobalSakeAttr = map[int32]map[serverproto.Attr]float32{}
  1922. mag.curGlobalPetBondAttr = map[serverproto.Attr]float32{}
  1923. return mag
  1924. }
  1925. // hero
  1926. func (this *RoleBattleAttr) getActorAttr(heroData *serverproto.HeroData) *ActorAttr {
  1927. actorAttr, ok := this.roleActorAttrList[heroData.Id]
  1928. if !ok {
  1929. actorAttr = newActorAttr(this, heroData.Id, heroData.ConfigId,
  1930. heroData.BaseLevel, heroData.AdvanceLevel, heroData.StrengthLevel)
  1931. this.roleActorAttrList[heroData.Id] = actorAttr
  1932. //技能初始化
  1933. this.HeroSkillChange(heroData)
  1934. actorAttr.changeSetList.Add(
  1935. Attr_Change_Fashion,
  1936. Attr_Change_Card,
  1937. Attr_Change_Equip,
  1938. Attr_Change_Skill,
  1939. Attr_Change_AddPoint,
  1940. Attr_Change_Advance,
  1941. Attr_Change_Strength,
  1942. Attr_Change_Pet,
  1943. Attr_Change_HeadFrame,
  1944. Attr_Change_Sake,
  1945. Attr_Change_Skill_Equip_Slot,
  1946. Attr_Change_VipPrivilege)
  1947. }
  1948. return actorAttr
  1949. }
  1950. // pet
  1951. func (this *RoleBattleAttr) getPetActorAttr(petData *serverproto.PetData) *ActorAttr {
  1952. actorAttr, ok := this.rolePetAttrList[int32(petData.Id)]
  1953. if !ok {
  1954. actorAttr = newPetAttr(this, int32(petData.Id), petData.ConfigId,
  1955. petData.Level, int32(petData.AdvanceLevel))
  1956. this.rolePetAttrList[int32(petData.Id)] = actorAttr
  1957. actorAttr.changeSetList.Add(
  1958. Attr_Change_Pet_Base,
  1959. Attr_Change_Pet_Equip,
  1960. Attr_Change_Pet_Bond,
  1961. Attr_Change_Pet_Qiyue)
  1962. }
  1963. return actorAttr
  1964. }
  1965. // 属性变更
  1966. type AttrChangeST struct {
  1967. IgnoreNotify bool //是否通知客户端属性变更(true不通知)
  1968. FightChangeNotNotify bool
  1969. ChangeType int
  1970. ForceChangeType int //强制需要重新计算的属性类型
  1971. ChangeHeroData *serverproto.HeroData
  1972. BNotCalc bool //true不计算 false计算
  1973. ChangeJobType []int32 //fashion,sake
  1974. IsPet bool //true:pet false:hero
  1975. ChangePetData *serverproto.PetData
  1976. //技能处理
  1977. BSkillReset bool
  1978. SkillCfgId int32
  1979. OldSkillLevel int32
  1980. NewSkillLevel int32
  1981. //头像框处理
  1982. BHeadFrameDelete bool
  1983. HeadFrameId int32
  1984. }
  1985. // 压制值计算
  1986. type RepressChangeST struct {
  1987. HeroData *serverproto.HeroData
  1988. BReset bool
  1989. SkillCfgId int32
  1990. OldSKillLevel int32
  1991. NewSKillLevel int32
  1992. }
  1993. // 技能变化
  1994. func (this *RoleBattleAttr) HeroSkillChange(heroData *serverproto.HeroData) {
  1995. if heroData == nil {
  1996. return
  1997. }
  1998. actorAttr, ok := this.roleActorAttrList[heroData.Id]
  1999. if !ok {
  2000. return
  2001. }
  2002. if len(actorAttr.normalSKillList) <= 0 {
  2003. for _, skill := range heroData.Skill.SkillList {
  2004. actorAttr.normalSKillList = append(actorAttr.normalSKillList, &serverproto.KeyValueType{
  2005. Key: skill.DefaultSkillId,
  2006. Value: 1,
  2007. })
  2008. actorAttr.useSkillList = append(actorAttr.useSkillList, &serverproto.KeyValueType{
  2009. Key: skill.SkillId,
  2010. Value: skill.Unlock,
  2011. })
  2012. }
  2013. } else {
  2014. actorAttr.useSkillList = actorAttr.useSkillList[:0]
  2015. for _, skill := range heroData.Skill.SkillList {
  2016. actorAttr.useSkillList = append(actorAttr.useSkillList, &serverproto.KeyValueType{
  2017. Key: skill.SkillId,
  2018. Value: skill.Unlock,
  2019. })
  2020. }
  2021. }
  2022. }
  2023. // 等级属性变更
  2024. func (this *RoleBattleAttr) ResetLevelAttrList(heroData *serverproto.HeroData) {
  2025. if heroData == nil {
  2026. return
  2027. }
  2028. actorAttr := this.getActorAttr(heroData)
  2029. actorAttr.resetAttrList(heroData.BaseLevel, heroData.AdvanceLevel, heroData.StrengthLevel)
  2030. this.AttrChange(AttrChangeST{
  2031. ChangeType: Attr_Change_AddPoint,
  2032. ChangeHeroData: heroData,
  2033. FightChangeNotNotify: !heroData.IsBattle,
  2034. })
  2035. }
  2036. // 更换职业属性变更
  2037. func (this *RoleBattleAttr) ResetJobAttrList(heroData *serverproto.HeroData) {
  2038. if heroData == nil {
  2039. return
  2040. }
  2041. actorAttr := this.getActorAttr(heroData)
  2042. actorAttr.heroConfigId = heroData.ConfigId
  2043. if actorAttr.isMainHero {
  2044. actorAttr.initJobAttr()
  2045. }
  2046. actorAttr.resetAttrList(heroData.BaseLevel, heroData.AdvanceLevel, heroData.StrengthLevel)
  2047. this.AttrChange(AttrChangeST{
  2048. ChangeType: Attr_Change_Skill,
  2049. ChangeHeroData: heroData,
  2050. BNotCalc: true,
  2051. })
  2052. this.AttrChange(AttrChangeST{
  2053. ChangeType: Attr_Change_AddPoint,
  2054. ChangeHeroData: heroData,
  2055. })
  2056. }
  2057. func (this *RoleBattleAttr) PartnerAdvanceAttrList(heroData *serverproto.HeroData) {
  2058. if heroData == nil {
  2059. return
  2060. }
  2061. //actorAttr := this.getActorAttr(heroData)
  2062. //actorAttr.resetAttrList(heroData.BaseLevel, heroData.AdvanceLevel, heroData.StrengthLevel)
  2063. this.AttrChange(AttrChangeST{
  2064. ChangeType: Attr_Change_Advance,
  2065. ChangeHeroData: heroData,
  2066. })
  2067. }
  2068. // 属性变更唯一对外接口
  2069. func (this *RoleBattleAttr) AttrChange(attrChangeSt AttrChangeST) {
  2070. if attrChangeSt.IsPet {
  2071. //pet
  2072. this.attrChangePet(attrChangeSt)
  2073. } else {
  2074. //hero
  2075. this.attrChangeHero(attrChangeSt)
  2076. }
  2077. //判断战力变化
  2078. if !attrChangeSt.FightChangeNotNotify {
  2079. this.checkFightPower(true)
  2080. }
  2081. }
  2082. func (this *RoleBattleAttr) attrChangeHero(attrChangeSt AttrChangeST) {
  2083. if attrChangeSt.ChangeHeroData == nil {
  2084. return
  2085. }
  2086. if !this.bInitGlobalFashionAttr {
  2087. this.getFashionAttr(nil)
  2088. }
  2089. if !this.bInitGlobalSakeAttr {
  2090. this.getSakeAttr(nil)
  2091. }
  2092. if !this.bInitGlobalPetBondAttr {
  2093. this.getPetBondAttr()
  2094. }
  2095. if attrChangeSt.ChangeType == Attr_Change_Fashion || attrChangeSt.ChangeType == Attr_Change_Sake {
  2096. if attrChangeSt.ChangeType == Attr_Change_Fashion {
  2097. this.getFashionAttr(nil)
  2098. } else if attrChangeSt.ChangeType == Attr_Change_Sake {
  2099. this.getSakeAttr(nil)
  2100. }
  2101. var calHeroList []*serverproto.HeroData
  2102. for idx := 0; idx < len(attrChangeSt.ChangeJobType); idx++ {
  2103. jobType := attrChangeSt.ChangeJobType[idx]
  2104. heroData := this.role.GetRoleHero().GetHeroByJobId(jobType)
  2105. if heroData == nil {
  2106. continue
  2107. }
  2108. bFind := false
  2109. for k := 0; k < len(calHeroList); k++ {
  2110. if calHeroList[k].Id == heroData.Id {
  2111. bFind = true
  2112. break
  2113. }
  2114. }
  2115. if !bFind {
  2116. actorAttr := this.getActorAttr(heroData)
  2117. if attrChangeSt.ChangeType > Attr_Change_None {
  2118. actorAttr.changeSetList.Add(attrChangeSt.ChangeType)
  2119. }
  2120. calHeroList = append(calHeroList, heroData)
  2121. if !attrChangeSt.BNotCalc {
  2122. this.calcAttrHero(heroData, AttrChangeST{})
  2123. }
  2124. }
  2125. }
  2126. } else {
  2127. actorAttr := this.getActorAttr(attrChangeSt.ChangeHeroData)
  2128. if attrChangeSt.ChangeType > Attr_Change_None {
  2129. actorAttr.changeSetList.Add(attrChangeSt.ChangeType)
  2130. }
  2131. if !attrChangeSt.BNotCalc {
  2132. this.calcAttrHero(attrChangeSt.ChangeHeroData, attrChangeSt)
  2133. }
  2134. }
  2135. }
  2136. func (this *RoleBattleAttr) attrChangePet(attrChangeSt AttrChangeST) {
  2137. if attrChangeSt.ChangePetData == nil &&
  2138. attrChangeSt.ChangeType != Attr_Change_Pet_Bond {
  2139. return
  2140. }
  2141. //init attr
  2142. var changePetDataList []*serverproto.PetData
  2143. if attrChangeSt.ChangeType == Attr_Change_Pet_Bond {
  2144. //reset attr
  2145. this.getPetBondAttr()
  2146. this.role.GetRoleHero().GetBattlePetList(&changePetDataList)
  2147. if attrChangeSt.ChangePetData != nil {
  2148. changePetDataList = append(changePetDataList, attrChangeSt.ChangePetData)
  2149. }
  2150. } else {
  2151. if !this.bInitGlobalPetBondAttr {
  2152. this.getPetBondAttr()
  2153. }
  2154. changePetDataList = append(changePetDataList, attrChangeSt.ChangePetData)
  2155. }
  2156. //battle pet list
  2157. for idx := 0; idx < len(changePetDataList); idx++ {
  2158. petActorAttr := this.getPetActorAttr(changePetDataList[idx])
  2159. if attrChangeSt.ChangeType > Attr_Change_None {
  2160. petActorAttr.changeSetList.Add(attrChangeSt.ChangeType)
  2161. }
  2162. if attrChangeSt.ForceChangeType > Attr_Change_None {
  2163. petActorAttr.changeSetList.Add(attrChangeSt.ForceChangeType)
  2164. }
  2165. }
  2166. if !attrChangeSt.BNotCalc {
  2167. outChangePetDataList := this.calcAttrPet(changePetDataList, attrChangeSt)
  2168. //当前宠物在契约槽内,需要处理契约宠物属性
  2169. //pet for qiyue
  2170. if attrChangeSt.ChangePetData != nil {
  2171. qiyuePetId, bQiyueSlot := this.role.GetRolePet().IsPetInQiyueSlot(attrChangeSt.ChangePetData.Id)
  2172. if bQiyueSlot {
  2173. this.attrChangePet(AttrChangeST{
  2174. IsPet: true,
  2175. ChangePetData: this.role.GetRolePet().getPet(qiyuePetId),
  2176. ChangeType: Attr_Change_Pet_Qiyue,
  2177. FightChangeNotNotify: true,
  2178. })
  2179. }
  2180. }
  2181. //pet fro hero
  2182. for idx := 0; idx < len(outChangePetDataList); idx++ {
  2183. //出阵宠物属性变更后,玩家属性继承处理
  2184. if this.role.GetRolePet().isBattle(outChangePetDataList[idx]) {
  2185. this.attrChangeHero(AttrChangeST{
  2186. IgnoreNotify: attrChangeSt.IgnoreNotify,
  2187. ChangeHeroData: this.role.GetRoleHero().GetHero(outChangePetDataList[idx].HeroId),
  2188. ChangeType: Attr_Change_Pet,
  2189. })
  2190. }
  2191. }
  2192. }
  2193. }
  2194. func (this *RoleBattleAttr) getHeroFightPower(heroData *serverproto.HeroData) int64 {
  2195. var fightPower int64 = 0
  2196. //battle hero
  2197. this.attrChangeHero(AttrChangeST{
  2198. IgnoreNotify: true,
  2199. ChangeType: Attr_Change_None,
  2200. ChangeHeroData: heroData,
  2201. })
  2202. actorAttr := this.getActorAttr(heroData)
  2203. if actorAttr != nil {
  2204. fightPower += int64(actorAttr.curAttrFightPower)
  2205. fightPower += actorAttr.curSkillFightPower
  2206. fightPower += actorAttr.curSkillEquipFightPower
  2207. }
  2208. return fightPower
  2209. }
  2210. func (this *RoleBattleAttr) getPetFightPower(petData *serverproto.PetData) int64 {
  2211. var fightPower int64 = 0
  2212. this.attrChangePet(AttrChangeST{
  2213. IgnoreNotify: true,
  2214. IsPet: true,
  2215. ChangeType: Attr_Change_None,
  2216. ChangePetData: petData,
  2217. })
  2218. petActorAttr := this.getPetActorAttr(petData)
  2219. if petActorAttr != nil {
  2220. fightPower += int64(petActorAttr.curAttrFightPower)
  2221. fightPower += petActorAttr.curSkillFightPower
  2222. }
  2223. return fightPower
  2224. }
  2225. // 获取当前所有技能对应的战力加成
  2226. func (this *RoleBattleAttr) getHeroTotalSkillFightPower(actorId int32) int32 {
  2227. var fightPower int32 = 0
  2228. heroData := this.role.GetRoleHero().GetHero(actorId)
  2229. if heroData == nil || heroData.Skill == nil {
  2230. return fightPower
  2231. }
  2232. isMainHero := this.role.GetRoleHero().IsMainHero(actorId)
  2233. for _, skillList := range heroData.Skill.JobSkillList {
  2234. for _, skill := range skillList.UnlockSkillList {
  2235. skillCfg, ok := serverproto.SkillCfgLoader[skill.Key]
  2236. if !ok {
  2237. continue
  2238. }
  2239. fightPower += skillCfg.AddFight * skill.Value
  2240. this.getHeroTotalSkillFightPower_1(skill.Key, isMainHero, &fightPower)
  2241. }
  2242. }
  2243. return fightPower
  2244. }
  2245. func (this *RoleBattleAttr) getHeroTotalSkillFightPower_1(skillId int32, isMainHero bool, fightPower *int32) {
  2246. if isMainHero {
  2247. //role
  2248. skillCfg, ok := serverproto.SkillTreeCfgLoader[skillId]
  2249. if !ok || skillCfg.BeforeSkill <= 0 {
  2250. return
  2251. }
  2252. beforeSkill, ok := serverproto.SkillTreeCfgLoader[skillCfg.BeforeSkill]
  2253. if ok {
  2254. beforeSkillCfg, ok := serverproto.SkillCfgLoader[skillCfg.BeforeSkill]
  2255. if ok {
  2256. *fightPower += beforeSkillCfg.AddFight * beforeSkill.MaxLv
  2257. }
  2258. this.getHeroTotalSkillFightPower_1(skillCfg.BeforeSkill, isMainHero, fightPower)
  2259. }
  2260. } else {
  2261. //partner
  2262. skillCfg, ok := serverproto.ParterSkillTreeCfgLoader[skillId]
  2263. if !ok || skillCfg.BeforeSkill <= 0 {
  2264. return
  2265. }
  2266. beforeSkill, ok := serverproto.ParterSkillTreeCfgLoader[skillCfg.BeforeSkill]
  2267. if ok {
  2268. beforeSkillCfg, ok := serverproto.SkillCfgLoader[skillCfg.BeforeSkill]
  2269. if ok {
  2270. *fightPower += beforeSkillCfg.AddFight * beforeSkill.MaxLv
  2271. }
  2272. this.getHeroTotalSkillFightPower_1(skillCfg.BeforeSkill, isMainHero, fightPower)
  2273. }
  2274. }
  2275. }
  2276. func (this *RoleBattleAttr) getPetTotalSkillFightPower(actorId int32) int32 {
  2277. var fightPower int32 = 0
  2278. petData := this.role.GetRolePet().getPet(uint32(actorId))
  2279. if petData == nil {
  2280. return fightPower
  2281. }
  2282. for _, skill := range petData.SkillList {
  2283. skillCfg, ok := serverproto.SkillCfgLoader[skill.ConfigId]
  2284. if !ok {
  2285. continue
  2286. }
  2287. fightPower += skillCfg.AddFight * skill.Level
  2288. }
  2289. return fightPower
  2290. }
  2291. func (this *RoleBattleAttr) getSkillEquipFightPower(heroId int32) int32 {
  2292. var fightPower int32 = 0
  2293. hero := this.role.GetRoleHero().GetHero(heroId)
  2294. if hero == nil ||
  2295. hero.SkillEquipSlot == nil ||
  2296. hero.SkillEquipSlot.SlotList == nil {
  2297. return fightPower
  2298. }
  2299. for _, slotDetail := range hero.SkillEquipSlot.SlotList {
  2300. powerMap, ok := model.SkillEquipAppendFightPowerContainer[slotDetail.SkillEquipConfigId]
  2301. if !ok {
  2302. break
  2303. }
  2304. power, ok1 := powerMap[slotDetail.SkillEquipStarLevel-1]
  2305. if !ok1 {
  2306. break
  2307. }
  2308. fightPower += power
  2309. }
  2310. return fightPower
  2311. }
  2312. func (this *RoleBattleAttr) checkFightPower(bNotify bool) *serverproto.FightPowerData {
  2313. util.InfoF("uid=%v RoleBattleAttr", this.role.GetUUid())
  2314. ntfMsg := &serverproto.SCFightPowerChagneNtf{
  2315. Data: &serverproto.FightPowerData{},
  2316. }
  2317. var heroList []*serverproto.HeroData
  2318. this.role.GetRoleHero().GetBattleHeroList(&heroList)
  2319. var totalFightPower int64 = 0
  2320. for _, heroData := range heroList {
  2321. if !heroData.IsBattle {
  2322. continue
  2323. }
  2324. heroFightPower := this.getHeroFightPower(heroData)
  2325. var petFightPower int64 = 0
  2326. //battle pet
  2327. if heroData.BattlePetId > 0 {
  2328. petData := this.role.GetRolePet().getPet(heroData.BattlePetId)
  2329. if petData != nil {
  2330. petFightPower = this.getPetFightPower(petData)
  2331. }
  2332. }
  2333. totalFightPower += heroFightPower / 10
  2334. totalFightPower += petFightPower / 10
  2335. ntfMsg.Data.SlotFightpower = append(ntfMsg.Data.SlotFightpower,
  2336. &serverproto.SlotFightPower{
  2337. HeroId: heroData.Id,
  2338. HeroFightPower: uint64(heroFightPower / 10),
  2339. PetFightPower: uint64(petFightPower / 10),
  2340. })
  2341. }
  2342. ntfMsg.Data.TotalFightpower = uint32(totalFightPower)
  2343. this.curTotalFightPower = ntfMsg.Data.TotalFightpower
  2344. this.role.GetRoleBase().SetFightPower(ntfMsg.Data.TotalFightpower)
  2345. TaskMagCheck(this.role, serverproto.TaskType_Eve_Fight_value, int32(ntfMsg.Data.TotalFightpower))
  2346. TaskMagCheck(this.role, serverproto.TaskType_Total_Power, int32(ntfMsg.Data.TotalFightpower))
  2347. if bNotify {
  2348. this.role.ReplayGate(ntfMsg, true)
  2349. util.InfoF("uid=%v SCFightPowerChangeNtf data=%v", this.role.GetUUid(), ntfMsg.Data)
  2350. }
  2351. //for _, data := range this.roleActorAttrList {
  2352. // util.DebugF("uid=%v checkFightPower heroid=%v selffight=%v", this.role.GetUUid(), data.heroId, (data.curAttrFightPower+uint64(data.curSkillFightPower))/10)
  2353. //}
  2354. //for _, data := range this.rolePetAttrList {
  2355. // util.DebugF("uid=%v checkFightPower petid=%v selffight=%v", this.role.GetUUid(), data.heroId, (data.curAttrFightPower+uint64(data.curSkillFightPower))/10)
  2356. //}
  2357. //util.DebugF("uid=%v totalFightPower=%v", this.role.GetUUid(), this.curTotalFightPower)
  2358. return ntfMsg.Data
  2359. }
  2360. func (this *RoleBattleAttr) syncActorData(out *serverproto.ActorBattleAttr, actorAttr *ActorAttr) {
  2361. return
  2362. out.Str = float32(actorAttr.STR())
  2363. out.Agi = float32(actorAttr.AGI())
  2364. out.Int = float32(actorAttr.INT())
  2365. out.Vit = float32(actorAttr.VIT())
  2366. out.Dex = float32(actorAttr.DEX())
  2367. out.Luk = float32(actorAttr.LUK())
  2368. //out.Life = actorAttr.Life()
  2369. out.Sp = actorAttr.Sp()
  2370. out.MinAttack = actorAttr.MinAttack()
  2371. out.Attack = actorAttr.Attack()
  2372. out.MinMagicAttack = actorAttr.MinMagicAttack()
  2373. out.MagicAttack = actorAttr.MagicAttack()
  2374. out.Defense = actorAttr.Defense()
  2375. out.MagicDefense = actorAttr.MagicDefense()
  2376. out.Crit = actorAttr.Crit()
  2377. out.CritDamagePercent = actorAttr.CritDamagePercent()
  2378. out.Dodge = actorAttr.Dodge()
  2379. out.Hit = actorAttr.Hit()
  2380. out.Ten = actorAttr.Ten()
  2381. out.AttackSpeed = actorAttr.AttackSpeed()
  2382. //out.RealHurt = actorAttr.GetAdditionalAttr(serverproto.Attr_RealHurt)
  2383. //attrPrintStr := "\nLife,SP=%v,%v " +
  2384. // "\nAttack,MagicAttack=%v,%v " +
  2385. // "\nDefense,MagicDefense=%v,%v " +
  2386. // "\nHit,Dodge=%v,%v " +
  2387. // "\nCrit,Ten=%v,%v " +
  2388. // "\nAttackSpeed=%v"
  2389. //util.InfoF(attrPrintStr, out.Life, out.Sp,
  2390. // out.MinAttack, out.MagicAttack,
  2391. // out.Defense, out.MagicDefense,
  2392. // out.Hit, out.Dodge,
  2393. // out.Crit, out.Ten,
  2394. // out.AttackSpeed)
  2395. util.InfoF("---------------------------------------------heroId=%v fightpower=%v", actorAttr.heroId, actorAttr.curSkillFightPower+int64(actorAttr.curAttrFightPower))
  2396. util.InfoF("Life,SP=%v,%v", out.Life, out.Sp)
  2397. util.InfoF("Attack,MagicAttack=%v,%v", out.MinAttack, out.MagicAttack)
  2398. util.InfoF("Defense,MagicDefense=%v,%v", out.Defense, out.MagicDefense)
  2399. util.InfoF("Hit,Dodge=%v,%v", out.Hit, out.Dodge)
  2400. util.InfoF("Crit,Ten=%v,%v", out.Crit, out.Ten)
  2401. util.InfoF("AttackSpeed=%v CastAcce=%v", out.AttackSpeed, actorAttr.CastAcce())
  2402. actorAttr.AdditionAttrPercentString()
  2403. util.InfoF("---------------------------------------------end\n\n")
  2404. out.DefPercent = actorAttr.DefPercent()
  2405. out.MagicDefPercent = actorAttr.MagicDefPercent()
  2406. //忽视物防
  2407. out.Penetration = actorAttr.Penetration()
  2408. //忽视魔防
  2409. out.MagicPenetration = actorAttr.MagicPenetration()
  2410. for idx := serverproto.Nature_NatureType_None; idx < serverproto.Nature_NatureType_Dark; idx++ {
  2411. idx1 := serverproto.Attr(int32(serverproto.Attr_Nature_None_Damage_Begin) + int32(idx))
  2412. val1 := actorAttr.GetAdditionalAttrPercent(idx1)
  2413. out.NatureDamagePercent = append(out.NatureDamagePercent, val1)
  2414. idx2 := serverproto.Attr(int32(serverproto.Attr_Nature_None_AntiDamage_Begin) + int32(idx))
  2415. val2 := actorAttr.GetAdditionalAttrPercent(idx2)
  2416. out.AntiNatureDamagePercent = append(out.AntiNatureDamagePercent, val2)
  2417. }
  2418. //触发型buff列表
  2419. if len(actorAttr.triggerBuffList) > 0 {
  2420. out.TriggerBuffList = out.TriggerBuffList[:0]
  2421. for _, data := range actorAttr.triggerBuffList {
  2422. out.TriggerBuffList = append(out.TriggerBuffList, data)
  2423. }
  2424. }
  2425. }
  2426. // 时装属性
  2427. func (this *RoleBattleAttr) getFashionAttr(heroData *serverproto.HeroData) {
  2428. if heroData == nil {
  2429. //玩家自身角色
  2430. heroData = this.role.GetRoleHero().GetMainHero()
  2431. if heroData == nil {
  2432. return
  2433. }
  2434. }
  2435. //heroCfg, ok := serverproto.ParterCfgLoader[heroData.ConfigId]
  2436. //if !ok {
  2437. // return
  2438. //}
  2439. this.bInitGlobalFashionAttr = true
  2440. var mainRoleAttrJobType int32 = 0
  2441. this.curGlobalFashionAttr = map[int32]map[serverproto.Attr]float32{}
  2442. for _, data := range this.role.GetRoleFashion().fashionData {
  2443. //attrDataList, ok := model.FashionAttrContainer[data]
  2444. //if !ok {
  2445. // continue
  2446. //}
  2447. for _, attr := range data.attrs {
  2448. //if attr.JobType == 0 && this.role.GetRoleHero().IsMainHero(heroData.Id) {
  2449. // continue
  2450. //}
  2451. //if attr.JobType > 0 && attr.JobType != heroCfg.JobType {
  2452. // continue
  2453. //}
  2454. if _, ok := this.curGlobalFashionAttr[attr.JobType]; !ok {
  2455. this.curGlobalFashionAttr[attr.JobType] = map[serverproto.Attr]float32{}
  2456. }
  2457. this.curGlobalFashionAttr[attr.JobType][serverproto.Attr(attr.AttrId)] += float32(attr.Value)
  2458. }
  2459. }
  2460. //套装属性
  2461. for idx := 0; idx < len(this.role.GetRoleFashion().fashionSuitAttrs); idx++ {
  2462. attr := this.role.GetRoleFashion().fashionSuitAttrs[idx]
  2463. if _, ok := this.curGlobalFashionAttr[mainRoleAttrJobType]; !ok {
  2464. this.curGlobalFashionAttr[mainRoleAttrJobType] = map[serverproto.Attr]float32{}
  2465. }
  2466. this.curGlobalFashionAttr[mainRoleAttrJobType][serverproto.Attr(attr.Key)] += float32(attr.Value)
  2467. }
  2468. }
  2469. // 收集屋藏品属性
  2470. func (this *RoleBattleAttr) getSakeAttr(heroData *serverproto.HeroData) {
  2471. if heroData == nil {
  2472. //玩家自身角色
  2473. heroData = this.role.GetRoleHero().GetMainHero()
  2474. if heroData == nil {
  2475. return
  2476. }
  2477. }
  2478. this.bInitGlobalSakeAttr = true
  2479. this.curGlobalSakeAttr = map[int32]map[serverproto.Attr]float32{}
  2480. for _, val := range this.role.GetRoleKeepSake().keepSake {
  2481. keepSakeCfg, ok := model.ConvertKeepSake[val.KeepSakeId]
  2482. if !ok {
  2483. continue
  2484. }
  2485. if len(keepSakeCfg.LevelDataList) <= 0 {
  2486. continue
  2487. }
  2488. //level attr
  2489. findIdx := -1
  2490. for key, sakeLevelData := range keepSakeCfg.LevelDataList {
  2491. if sakeLevelData.Level > val.KeepSakeLevel {
  2492. break
  2493. }
  2494. findIdx = key
  2495. }
  2496. if findIdx < 0 {
  2497. continue
  2498. }
  2499. //jobType add attr
  2500. for idx := 0; idx < len(keepSakeCfg.Job); idx++ {
  2501. jobType := keepSakeCfg.Job[idx]
  2502. if _, ok := this.curGlobalSakeAttr[jobType]; !ok {
  2503. this.curGlobalSakeAttr[jobType] = map[serverproto.Attr]float32{}
  2504. }
  2505. for k, v := range keepSakeCfg.LevelDataList[findIdx].AddAttr {
  2506. this.curGlobalSakeAttr[jobType][serverproto.Attr(k)] += float32(v)
  2507. }
  2508. }
  2509. }
  2510. }
  2511. // 宠物羁绊属性
  2512. func (this *RoleBattleAttr) getPetBondAttr() {
  2513. if this.role.GetRolePet() == nil {
  2514. return
  2515. }
  2516. this.bInitGlobalPetBondAttr = true
  2517. this.curGlobalPetBondAttr = map[serverproto.Attr]float32{}
  2518. for _, data := range this.role.GetRolePet().bondList {
  2519. cfgData, ok := model.ConvertBondFight[data.BondCfgId]
  2520. if !ok {
  2521. continue
  2522. }
  2523. if data.PetBondLevel >= 1 {
  2524. for _, val := range cfgData.Attr1List {
  2525. this.curGlobalPetBondAttr[serverproto.Attr(val.Key)] += float32(val.Value)
  2526. }
  2527. }
  2528. if data.PetBondLevel >= 2 {
  2529. for _, val := range cfgData.Attr2List {
  2530. this.curGlobalPetBondAttr[serverproto.Attr(val.Key)] += float32(val.Value)
  2531. }
  2532. }
  2533. if data.PetBondLevel >= 3 {
  2534. for _, val := range cfgData.Attr3List {
  2535. this.curGlobalPetBondAttr[serverproto.Attr(val.Key)] += float32(val.Value)
  2536. }
  2537. }
  2538. }
  2539. }
  2540. func (this *RoleBattleAttr) calcAttrHero(heroData *serverproto.HeroData, attrChangeSt AttrChangeST) map[uint32]*serverproto.ActorData {
  2541. //添加之前未初始化的英雄属性数据
  2542. if _, ok := this.roleActorAttrList[heroData.Id]; !ok {
  2543. this.attrChangeHero(AttrChangeST{
  2544. ChangeType: Attr_Change_None,
  2545. ChangeHeroData: heroData,
  2546. BNotCalc: true,
  2547. })
  2548. }
  2549. if actorAttr, ok := this.roleActorAttrList[heroData.Id]; ok {
  2550. //重新计算属性
  2551. bChange := actorAttr.calActorAttr(heroData, nil, nil, attrChangeSt)
  2552. actorData, ok := this.battleHeroActorList[uint32(actorAttr.heroId)]
  2553. if !ok {
  2554. actorData = &serverproto.ActorData{
  2555. Id: uint32(actorAttr.heroId),
  2556. IsPlayer: actorAttr.isMainHero,
  2557. BattleAttr: &serverproto.ActorBattleAttr{},
  2558. JobType: uint32(actorAttr.heroConfigId), //主角职业类型/hero配置ID
  2559. }
  2560. }
  2561. //战斗属性同步
  2562. if bChange {
  2563. this.syncActorData(actorData.BattleAttr, actorAttr)
  2564. this.battleHeroActorList[actorData.Id] = actorData
  2565. }
  2566. }
  2567. tempBattleHeroList := map[uint32]*serverproto.ActorData{}
  2568. tempBattleHeroList[uint32(heroData.Id)] = this.battleHeroActorList[uint32(heroData.Id)]
  2569. return tempBattleHeroList
  2570. }
  2571. func (this *RoleBattleAttr) calcAttrPet(petList []*serverproto.PetData, attrChangeSt AttrChangeST) (outList []*serverproto.PetData) {
  2572. for _, petData := range petList {
  2573. if _, ok := this.rolePetAttrList[int32(petData.Id)]; !ok {
  2574. this.attrChangePet(AttrChangeST{
  2575. ChangeType: Attr_Change_None,
  2576. ChangePetData: petData,
  2577. BNotCalc: true,
  2578. IsPet: true,
  2579. })
  2580. }
  2581. }
  2582. ntfMsg := &serverproto.SCActorAttrGetNtf{}
  2583. for idx := 0; idx < len(petList); idx++ {
  2584. if petAttr, ok := this.rolePetAttrList[int32(petList[idx].Id)]; ok {
  2585. //重新计算属性
  2586. petAttr.level = petList[idx].Level
  2587. petAttr.advLevel = int32(petList[idx].AdvanceLevel)
  2588. //pet base
  2589. changeBase := petAttr.calPetAttrForPetBase()
  2590. //pet equip(宠物印记/套装)
  2591. changePetEquip := petAttr.calPetAttrForPetEquip(petList[idx])
  2592. //pet bond(宠物羁绊)
  2593. changeBond := petAttr.calPetAttrForPetBond(petList[idx])
  2594. //skill for fight power
  2595. changeSkill := petAttr.calPetAttrForPetSkill(petList[idx])
  2596. //宠物契约
  2597. changeQiyue := petAttr.calPetAttrForPetQiyue(petList[idx])
  2598. if changeBase || changePetEquip || changeBond || changeSkill || changeQiyue {
  2599. actorAttrType := &serverproto.ActorAttrType{
  2600. ActorId: petList[idx].Id,
  2601. }
  2602. this.copyAttrToMsg(petAttr, actorAttrType)
  2603. ntfMsg.ActorAttrList = append(ntfMsg.ActorAttrList, actorAttrType)
  2604. //pet BattleAttrChange
  2605. //计算战力
  2606. heroFightPower := petAttr.calcActorFightPower(actorAttrType.AttrList)
  2607. this.role.GetRolePet().BattleAttrChange(petList[idx], actorAttrType, heroFightPower)
  2608. outList = append(outList, petList[idx])
  2609. //TODO
  2610. //pet equip(stone)
  2611. util.DebugF("------------------petbase=%v %v", petAttr.heroConfigId, petAttr.heroId)
  2612. petAttr.AdditionAttrPercentString()
  2613. util.DebugF("------------------petbase end\n\n")
  2614. if len(petAttr.curPetAttrForPetQiyue) > 0 {
  2615. type kvSt struct {
  2616. attrKey serverproto.Attr
  2617. attrVal float32
  2618. }
  2619. var kvList []kvSt
  2620. for key, val := range petAttr.curPetAttrForPetQiyue {
  2621. //util.InfoF("%v=%v", key, val/100)
  2622. kvList = append(kvList, kvSt{attrKey: key, attrVal: val})
  2623. }
  2624. sort.Slice(kvList, func(i, j int) bool {
  2625. return kvList[i].attrKey < kvList[j].attrKey
  2626. })
  2627. for idx := 0; idx < len(kvList); idx++ {
  2628. util.InfoF("%v=%v %v%%", kvList[idx].attrKey, kvList[idx].attrVal, kvList[idx].attrVal/100)
  2629. }
  2630. util.DebugF("------------------petbase endinherit\n\n")
  2631. }
  2632. }
  2633. }
  2634. }
  2635. if !attrChangeSt.IgnoreNotify && len(ntfMsg.ActorAttrList) > 0 {
  2636. this.role.ReplayGate(ntfMsg, true)
  2637. }
  2638. return
  2639. }
  2640. // 计算其他玩家战斗属性
  2641. func (this *RoleBattleAttr) CalcFightRoleInfoAttr(FightInfo *serverproto.FightRoleInfo) map[uint32]*serverproto.ActorData {
  2642. tempBattleHeroList := map[uint32]*serverproto.ActorData{}
  2643. for _, heroData := range FightInfo.HeroDataList {
  2644. otherActorAttr := newActorAttr(this, heroData.Id, heroData.ConfigId,
  2645. heroData.BaseLevel, heroData.AdvanceLevel, heroData.StrengthLevel)
  2646. if this.role.GetRoleHero().IsMainHero(heroData.Id) {
  2647. otherActorAttr.isMainHero = true
  2648. }
  2649. otherActorAttr.changeSetList.Add(Attr_Change_Fashion, Attr_Change_Card, Attr_Change_Equip,
  2650. Attr_Change_AddPoint, Attr_Change_Advance, Attr_Change_Strength, Attr_Change_Skill_Equip_Slot)
  2651. otherActorAttr.calActorAttr(heroData, FightInfo.AttrList, FightInfo.FashionData, AttrChangeST{})
  2652. actorData := &serverproto.ActorData{
  2653. Id: uint32(heroData.Id),
  2654. IsPlayer: otherActorAttr.isMainHero,
  2655. BattleAttr: &serverproto.ActorBattleAttr{},
  2656. JobType: uint32(heroData.ConfigId), //主角职业类型/hero配置ID
  2657. }
  2658. this.syncActorData(actorData.BattleAttr, otherActorAttr)
  2659. tempBattleHeroList[actorData.Id] = actorData
  2660. }
  2661. return tempBattleHeroList
  2662. }
  2663. // Role
  2664. // 获取英雄属性,宠物属性
  2665. func (this *RoleBattleAttr) GetActorAttr(actorList []*serverproto.ActorAttrType,
  2666. isAllBattle bool, bNotify bool) serverproto.ErrorCode {
  2667. //上阵单位属性(巡游阵容)
  2668. var calActorList []*serverproto.ActorAttrType
  2669. if isAllBattle {
  2670. for _, heroData := range this.role.GetRoleHero().heroList {
  2671. if !heroData.IsBattle {
  2672. continue
  2673. }
  2674. calActorList = append(calActorList, &serverproto.ActorAttrType{
  2675. IsHeroPet: true,
  2676. ActorId: uint32(heroData.Id),
  2677. })
  2678. if heroData.BattlePetId > 0 {
  2679. calActorList = append(calActorList, &serverproto.ActorAttrType{
  2680. ActorId: heroData.BattlePetId,
  2681. })
  2682. }
  2683. }
  2684. mainHeroData := this.role.GetRoleHero().GetMainHero()
  2685. if mainHeroData != nil {
  2686. calActorList = append(calActorList, &serverproto.ActorAttrType{
  2687. IsHeroPet: true,
  2688. ActorId: uint32(mainHeroData.Id),
  2689. })
  2690. if mainHeroData.BattlePetId > 0 {
  2691. calActorList = append(calActorList, &serverproto.ActorAttrType{
  2692. ActorId: mainHeroData.BattlePetId,
  2693. })
  2694. }
  2695. }
  2696. } else {
  2697. for idx := 0; idx < len(actorList); idx++ {
  2698. calActorList = append(calActorList, actorList[idx])
  2699. if actorList[idx].IsHeroPet {
  2700. //hero
  2701. heroData := this.role.GetRoleHero().GetHero(int32(actorList[idx].ActorId))
  2702. if heroData != nil && heroData.BattlePetId > 0 {
  2703. calActorList = append(calActorList, &serverproto.ActorAttrType{
  2704. ActorId: heroData.BattlePetId,
  2705. })
  2706. }
  2707. }
  2708. }
  2709. }
  2710. //cal attr
  2711. for idx := 0; idx < len(actorList); idx++ {
  2712. if actorList[idx].IsHeroPet {
  2713. //hero
  2714. heroData := this.role.GetRoleHero().GetHero(int32(actorList[idx].ActorId))
  2715. if heroData == nil {
  2716. continue
  2717. }
  2718. //cal attr
  2719. this.attrChangeHero(AttrChangeST{
  2720. IgnoreNotify: true,
  2721. ChangeType: Attr_Change_None,
  2722. ChangeHeroData: heroData,
  2723. })
  2724. //copy attr
  2725. actorAttr := this.getActorAttr(heroData)
  2726. this.copyAttrToMsg(actorAttr, actorList[idx])
  2727. } else {
  2728. //pet
  2729. petData := this.role.GetRolePet().getPet(actorList[idx].ActorId)
  2730. if petData == nil {
  2731. continue
  2732. }
  2733. //cal attr
  2734. this.attrChangePet(AttrChangeST{
  2735. IgnoreNotify: true,
  2736. IsPet: true,
  2737. ChangeType: Attr_Change_None,
  2738. ChangePetData: petData,
  2739. })
  2740. //copy attr
  2741. actorAttr := this.getPetActorAttr(petData)
  2742. this.copyAttrToMsg(actorAttr, actorList[idx])
  2743. }
  2744. }
  2745. if bNotify {
  2746. if this.bInitAttrCalc {
  2747. ackMsg := &serverproto.SCActorAttrGetAck{}
  2748. ackMsg.ActorAttrList = actorList
  2749. this.role.ReplayGate(ackMsg, true)
  2750. } else {
  2751. this.bInitAttrCalc = true
  2752. ntfMsg := &serverproto.SCActorAttrGetNtf{}
  2753. ntfMsg.ActorAttrList = actorList
  2754. this.role.ReplayGate(ntfMsg, true)
  2755. }
  2756. }
  2757. return serverproto.ErrorCode_ERROR_OK
  2758. }
  2759. // 获取actor契约属性
  2760. // 如果是宠物,则获取契约材料宠物给到契约宠物生成的属性
  2761. // 如果是英雄,则获取契约宠物继承到英雄的属性
  2762. func (this *RoleBattleAttr) GetActorQiyueAttr(actorList []*serverproto.ActorAttrType) {
  2763. for idx := 0; idx < len(actorList); idx++ {
  2764. if actorList[idx].IsHeroPet {
  2765. //TODO
  2766. // 暂时没有用到
  2767. } else {
  2768. //pet
  2769. petData := this.role.GetRolePet().getPet(actorList[idx].ActorId)
  2770. if petData == nil {
  2771. continue
  2772. }
  2773. //cal attr
  2774. this.attrChangePet(AttrChangeST{
  2775. IgnoreNotify: true,
  2776. IsPet: true,
  2777. ChangeType: Attr_Change_None,
  2778. ChangePetData: petData,
  2779. })
  2780. actorAttr := this.getPetActorAttr(petData)
  2781. for key, val := range actorAttr.curPetAttrForPetQiyue {
  2782. actorList[idx].AttrList = append(actorList[idx].AttrList, &serverproto.KeyValueFloat32{
  2783. Key: int32(key),
  2784. Value: val,
  2785. })
  2786. }
  2787. }
  2788. }
  2789. }
  2790. func (this *RoleBattleAttr) copyAttrToMsg(actorAttr *ActorAttr, outAttrType *serverproto.ActorAttrType) {
  2791. attrList := map[serverproto.Attr]float32{}
  2792. attrList64 := map[serverproto.Attr]float64{}
  2793. if actorAttr.isPet {
  2794. for key, val := range actorAttr.additionalAttrs {
  2795. attrList64[key] = val
  2796. }
  2797. } else {
  2798. attrList64[serverproto.Attr_Life] = actorAttr.Life()
  2799. attrList[serverproto.Attr_Sp] = actorAttr.Sp()
  2800. attrList[serverproto.Attr_Attack] = actorAttr.MinAttack()
  2801. attrList[serverproto.Attr_MagicAttack] = actorAttr.MinMagicAttack()
  2802. attrList[serverproto.Attr_Defense] = actorAttr.Defense()
  2803. attrList[serverproto.Attr_MagicDefense] = actorAttr.MagicDefense()
  2804. attrList[serverproto.Attr_Crit] = actorAttr.Crit()
  2805. attrList[serverproto.Attr_Dodge] = actorAttr.Dodge()
  2806. attrList[serverproto.Attr_Hit] = actorAttr.Hit()
  2807. attrList[serverproto.Attr_Ten] = actorAttr.Ten()
  2808. attrList[serverproto.Attr_AttackSpeed] = actorAttr.AttackSpeed()
  2809. attrList[serverproto.Attr_CastAcce] = actorAttr.CastAcce() * 1000
  2810. realHurt := actorAttr.GetAdditionalAttr(serverproto.Attr_RealHurt)
  2811. if realHurt > 0 {
  2812. attrList[serverproto.Attr_RealHurt] = float32(realHurt)
  2813. }
  2814. }
  2815. for key, val := range actorAttr.attrPercent {
  2816. attrList[key+serverproto.Attr_STR_Percent] = val
  2817. }
  2818. for key, val := range actorAttr.extendAttrPercent {
  2819. attrList[key] = val
  2820. }
  2821. for key, val := range attrList {
  2822. outAttrType.AttrList = append(outAttrType.AttrList, &serverproto.KeyValueFloat32{
  2823. Key: int32(key),
  2824. Value: val,
  2825. })
  2826. }
  2827. for key, val := range attrList64 {
  2828. if key == serverproto.Attr_Life {
  2829. outAttrType.AttrList = append(outAttrType.AttrList, &serverproto.KeyValueFloat32{
  2830. Key: int32(key),
  2831. Value: float32(val),
  2832. Value64: val,
  2833. })
  2834. } else {
  2835. outAttrType.AttrList = append(outAttrType.AttrList, &serverproto.KeyValueFloat32{
  2836. Key: int32(key),
  2837. Value: float32(val),
  2838. })
  2839. }
  2840. }
  2841. }
  2842. func (this *RoleBattleAttr) BattleAttrInit() {
  2843. if !this.bInitAttrCalc {
  2844. this.GetActorAttr(nil, true, true)
  2845. this.bInitAttrCalc = true
  2846. this.checkFightPower(true)
  2847. }
  2848. }
  2849. func (this *RoleBattleAttr) CopyData(outData *serverproto.FightPowerData) {
  2850. *outData = *(this.checkFightPower(false))
  2851. this.role.GetRoleHero().CalRepress(RepressChangeST{})
  2852. }