status.c 364 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297
  1. // Copyright (c) Athena Dev Teams - Licensed under GNU GPL
  2. // For more information, see LICENCE in the main folder
  3. #include "../common/cbasetypes.h"
  4. #include "../common/timer.h"
  5. #include "../common/nullpo.h"
  6. #include "../common/random.h"
  7. #include "../common/showmsg.h"
  8. #include "../common/malloc.h"
  9. #include "../common/utils.h"
  10. #include "../common/ers.h"
  11. #include "../common/strlib.h"
  12. #include "map.h"
  13. #include "path.h"
  14. #include "pc.h"
  15. #include "pet.h"
  16. #include "npc.h"
  17. #include "mob.h"
  18. #include "clif.h"
  19. #include "guild.h"
  20. #include "skill.h"
  21. #include "itemdb.h"
  22. #include "battle.h"
  23. #include "chrif.h"
  24. #include "skill.h"
  25. #include "status.h"
  26. #include "script.h"
  27. #include "unit.h"
  28. #include "homunculus.h"
  29. #include "mercenary.h"
  30. #include "elemental.h"
  31. #include "vending.h"
  32. #include <time.h>
  33. #include <stdio.h>
  34. #include <stdlib.h>
  35. #include <memory.h>
  36. #include <string.h>
  37. #include <math.h>
  38. //Regen related flags.
  39. enum e_regen
  40. {
  41. RGN_HP = 0x01,
  42. RGN_SP = 0x02,
  43. RGN_SHP = 0x04,
  44. RGN_SSP = 0x08,
  45. };
  46. static int max_weight_base[CLASS_COUNT];
  47. static int hp_coefficient[CLASS_COUNT];
  48. static int hp_coefficient2[CLASS_COUNT];
  49. static int hp_sigma_val[CLASS_COUNT][MAX_LEVEL+1];
  50. static int sp_coefficient[CLASS_COUNT];
  51. #ifdef RENEWAL_ASPD
  52. static int aspd_base[CLASS_COUNT][MAX_WEAPON_TYPE+1];
  53. #else
  54. static int aspd_base[CLASS_COUNT][MAX_WEAPON_TYPE]; //[blackhole89]
  55. #endif
  56. // bonus values and upgrade chances for refining equipment
  57. static struct {
  58. int chance[MAX_REFINE]; // success chance
  59. int bonus[MAX_REFINE]; // cumulative fixed bonus damage
  60. int randombonus_max[MAX_REFINE]; // cumulative maximum random bonus damage
  61. } refine_info[REFINE_TYPE_MAX];
  62. static int atkmods[3][MAX_WEAPON_TYPE]; //ATK weapon modification for size (size_fix.txt)
  63. static char job_bonus[CLASS_COUNT][MAX_LEVEL];
  64. static struct eri *sc_data_ers; //For sc_data entries
  65. static struct status_data dummy_status;
  66. int current_equip_item_index; //Contains inventory index of an equipped item. To pass it into the EQUP_SCRIPT [Lupus]
  67. int current_equip_card_id; //To prevent card-stacking (from jA) [Skotlex]
  68. //we need it for new cards 15 Feb 2005, to check if the combo cards are insrerted into the CURRENT weapon only
  69. //to avoid cards exploits
  70. static sc_type SkillStatusChangeTable[MAX_SKILL]; // skill -> status
  71. static int StatusIconChangeTable[SC_MAX]; // status -> "icon" (icon is a bit of a misnomer, since there exist values with no icon associated)
  72. static unsigned int StatusChangeFlagTable[SC_MAX]; // status -> flags
  73. static int StatusSkillChangeTable[SC_MAX]; // status -> skill
  74. static int StatusRelevantBLTypes[SI_MAX]; // "icon" -> enum bl_type (for clif_status_change to identify for which bl types to send packets)
  75. static unsigned int StatusChangeStateTable[SC_MAX]; // status -> flags
  76. /**
  77. * Returns the status change associated with a skill.
  78. * @param skill The skill to look up
  79. * @return The status registered for this skill
  80. **/
  81. sc_type status_skill2sc(int skill)
  82. {
  83. int idx = skill_get_index(skill);
  84. if( idx == 0 ) {
  85. ShowError("status_skill2sc: Unsupported skill id %d\n", skill);
  86. return SC_NONE;
  87. }
  88. return SkillStatusChangeTable[idx];
  89. }
  90. /**
  91. * Returns the FIRST skill (in order of definition in initChangeTables) to use a given status change.
  92. * Utilized for various duration lookups. Use with caution!
  93. * @param sc The status to look up
  94. * @return A skill associated with the status
  95. **/
  96. int status_sc2skill(sc_type sc)
  97. {
  98. if( sc < 0 || sc >= SC_MAX ) {
  99. ShowError("status_sc2skill: Unsupported status change id %d\n", sc);
  100. return 0;
  101. }
  102. return StatusSkillChangeTable[sc];
  103. }
  104. /**
  105. * Returns the status calculation flag associated with a given status change.
  106. * @param sc The status to look up
  107. * @return The scb_flag registered for this status (see enum scb_flag)
  108. **/
  109. unsigned int status_sc2scb_flag(sc_type sc)
  110. {
  111. if( sc < 0 || sc >= SC_MAX ) {
  112. ShowError("status_sc2scb_flag: Unsupported status change id %d\n", sc);
  113. return SCB_NONE;
  114. }
  115. return StatusChangeFlagTable[sc];
  116. }
  117. /**
  118. * Returns the bl types which require a status change packet to be sent for a given client status identifier.
  119. * @param type The client-side status identifier to look up (see enum si_type)
  120. * @return The bl types relevant to the type (see enum bl_type)
  121. **/
  122. int status_type2relevant_bl_types(int type)
  123. {
  124. if( type < 0 || type >= SI_MAX ) {
  125. ShowError("status_type2relevant_bl_types: Unsupported type %d\n", type);
  126. return SI_BLANK;
  127. }
  128. return StatusRelevantBLTypes[type];
  129. }
  130. #define add_sc(skill,sc) set_sc(skill,sc,SI_BLANK,SCB_NONE)
  131. // indicates that the status displays a visual effect for the affected unit, and should be sent to the client for all supported units
  132. #define set_sc_with_vfx(skill, sc, icon, flag) set_sc((skill), (sc), (icon), (flag)); if((icon) < SI_MAX) StatusRelevantBLTypes[(icon)] |= BL_SCEFFECT
  133. static void set_sc(uint16 skill_id, sc_type sc, int icon, unsigned int flag)
  134. {
  135. uint16 idx = skill_get_index(skill_id);
  136. if( idx == 0 ) {
  137. ShowError("set_sc: Unsupported skill id %d\n", skill_id);
  138. return;
  139. }
  140. if( sc < 0 || sc >= SC_MAX ) {
  141. ShowError("set_sc: Unsupported status change id %d\n", sc);
  142. return;
  143. }
  144. if( StatusSkillChangeTable[sc] == 0 )
  145. StatusSkillChangeTable[sc] = skill_id;
  146. if( StatusIconChangeTable[sc] == SI_BLANK )
  147. StatusIconChangeTable[sc] = icon;
  148. StatusChangeFlagTable[sc] |= flag;
  149. if( SkillStatusChangeTable[idx] == SC_NONE )
  150. SkillStatusChangeTable[idx] = sc;
  151. }
  152. void initChangeTables(void) {
  153. int i;
  154. for (i = 0; i < SC_MAX; i++)
  155. StatusIconChangeTable[i] = SI_BLANK;
  156. for (i = 0; i < MAX_SKILL; i++)
  157. SkillStatusChangeTable[i] = SC_NONE;
  158. for (i = 0; i < SI_MAX; i++)
  159. StatusRelevantBLTypes[i] = BL_PC;
  160. memset(StatusSkillChangeTable, 0, sizeof(StatusSkillChangeTable));
  161. memset(StatusChangeFlagTable, 0, sizeof(StatusChangeFlagTable));
  162. memset(StatusChangeStateTable, 0, sizeof(StatusChangeStateTable));
  163. //First we define the skill for common ailments. These are used in skill_additional_effect through sc cards. [Skotlex]
  164. set_sc( NPC_PETRIFYATTACK , SC_STONE , SI_BLANK , SCB_DEF_ELE|SCB_DEF|SCB_MDEF );
  165. set_sc( NPC_WIDEFREEZE , SC_FREEZE , SI_BLANK , SCB_DEF_ELE|SCB_DEF|SCB_MDEF );
  166. set_sc( NPC_STUNATTACK , SC_STUN , SI_BLANK , SCB_NONE );
  167. set_sc( NPC_SLEEPATTACK , SC_SLEEP , SI_BLANK , SCB_NONE );
  168. set_sc( NPC_POISON , SC_POISON , SI_BLANK , SCB_DEF2|SCB_REGEN );
  169. set_sc( NPC_CURSEATTACK , SC_CURSE , SI_BLANK , SCB_LUK|SCB_BATK|SCB_WATK|SCB_SPEED );
  170. set_sc( NPC_SILENCEATTACK , SC_SILENCE , SI_BLANK , SCB_NONE );
  171. set_sc( NPC_WIDECONFUSE , SC_CONFUSION , SI_BLANK , SCB_NONE );
  172. set_sc( NPC_BLINDATTACK , SC_BLIND , SI_BLANK , SCB_HIT|SCB_FLEE );
  173. set_sc( NPC_BLEEDING , SC_BLEEDING , SI_BLEEDING , SCB_REGEN );
  174. set_sc( NPC_POISON , SC_DPOISON , SI_BLANK , SCB_DEF2|SCB_REGEN );
  175. //The main status definitions
  176. add_sc( SM_BASH , SC_STUN );
  177. set_sc( SM_PROVOKE , SC_PROVOKE , SI_PROVOKE , SCB_DEF|SCB_DEF2|SCB_BATK|SCB_WATK );
  178. add_sc( SM_MAGNUM , SC_WATK_ELEMENT );
  179. set_sc( SM_ENDURE , SC_ENDURE , SI_ENDURE , SCB_MDEF|SCB_DSPD );
  180. add_sc( MG_SIGHT , SC_SIGHT );
  181. add_sc( MG_SAFETYWALL , SC_SAFETYWALL );
  182. add_sc( MG_FROSTDIVER , SC_FREEZE );
  183. add_sc( MG_STONECURSE , SC_STONE );
  184. add_sc( AL_RUWACH , SC_RUWACH );
  185. add_sc( AL_PNEUMA , SC_PNEUMA );
  186. set_sc( AL_INCAGI , SC_INCREASEAGI , SI_INCREASEAGI , SCB_AGI|SCB_SPEED );
  187. set_sc( AL_DECAGI , SC_DECREASEAGI , SI_DECREASEAGI , SCB_AGI|SCB_SPEED );
  188. set_sc( AL_CRUCIS , SC_SIGNUMCRUCIS , SI_SIGNUMCRUCIS , SCB_DEF );
  189. set_sc( AL_ANGELUS , SC_ANGELUS , SI_ANGELUS , SCB_DEF2 );
  190. set_sc( AL_BLESSING , SC_BLESSING , SI_BLESSING , SCB_STR|SCB_INT|SCB_DEX );
  191. set_sc( AC_CONCENTRATION , SC_CONCENTRATE , SI_CONCENTRATE , SCB_AGI|SCB_DEX );
  192. set_sc( TF_HIDING , SC_HIDING , SI_HIDING , SCB_SPEED );
  193. add_sc( TF_POISON , SC_POISON );
  194. set_sc( KN_TWOHANDQUICKEN , SC_TWOHANDQUICKEN , SI_TWOHANDQUICKEN , SCB_ASPD );
  195. add_sc( KN_AUTOCOUNTER , SC_AUTOCOUNTER );
  196. set_sc( PR_IMPOSITIO , SC_IMPOSITIO , SI_IMPOSITIO , SCB_WATK );
  197. set_sc( PR_SUFFRAGIUM , SC_SUFFRAGIUM , SI_SUFFRAGIUM , SCB_NONE );
  198. set_sc( PR_ASPERSIO , SC_ASPERSIO , SI_ASPERSIO , SCB_ATK_ELE );
  199. set_sc( PR_BENEDICTIO , SC_BENEDICTIO , SI_BENEDICTIO , SCB_DEF_ELE );
  200. set_sc( PR_SLOWPOISON , SC_SLOWPOISON , SI_SLOWPOISON , SCB_REGEN );
  201. set_sc( PR_KYRIE , SC_KYRIE , SI_KYRIE , SCB_NONE );
  202. set_sc( PR_MAGNIFICAT , SC_MAGNIFICAT , SI_MAGNIFICAT , SCB_REGEN );
  203. set_sc( PR_GLORIA , SC_GLORIA , SI_GLORIA , SCB_LUK );
  204. add_sc( PR_LEXDIVINA , SC_SILENCE );
  205. set_sc( PR_LEXAETERNA , SC_AETERNA , SI_AETERNA , SCB_NONE );
  206. add_sc( WZ_METEOR , SC_STUN );
  207. add_sc( WZ_VERMILION , SC_BLIND );
  208. add_sc( WZ_FROSTNOVA , SC_FREEZE );
  209. add_sc( WZ_STORMGUST , SC_FREEZE );
  210. set_sc( WZ_QUAGMIRE , SC_QUAGMIRE , SI_QUAGMIRE , SCB_AGI|SCB_DEX|SCB_ASPD|SCB_SPEED );
  211. set_sc( BS_ADRENALINE , SC_ADRENALINE , SI_ADRENALINE , SCB_ASPD );
  212. set_sc( BS_WEAPONPERFECT , SC_WEAPONPERFECTION, SI_WEAPONPERFECTION, SCB_NONE );
  213. set_sc( BS_OVERTHRUST , SC_OVERTHRUST , SI_OVERTHRUST , SCB_NONE );
  214. set_sc( BS_MAXIMIZE , SC_MAXIMIZEPOWER , SI_MAXIMIZEPOWER , SCB_REGEN );
  215. add_sc( HT_LANDMINE , SC_STUN );
  216. add_sc( HT_ANKLESNARE , SC_ANKLE );
  217. add_sc( HT_SANDMAN , SC_SLEEP );
  218. add_sc( HT_FLASHER , SC_BLIND );
  219. add_sc( HT_FREEZINGTRAP , SC_FREEZE );
  220. set_sc( AS_CLOAKING , SC_CLOAKING , SI_CLOAKING , SCB_CRI|SCB_SPEED );
  221. add_sc( AS_SONICBLOW , SC_STUN );
  222. set_sc( AS_ENCHANTPOISON , SC_ENCPOISON , SI_ENCPOISON , SCB_ATK_ELE );
  223. set_sc( AS_POISONREACT , SC_POISONREACT , SI_POISONREACT , SCB_NONE );
  224. add_sc( AS_VENOMDUST , SC_POISON );
  225. add_sc( AS_SPLASHER , SC_SPLASHER );
  226. set_sc( NV_TRICKDEAD , SC_TRICKDEAD , SI_TRICKDEAD , SCB_REGEN );
  227. set_sc( SM_AUTOBERSERK , SC_AUTOBERSERK , SI_AUTOBERSERK , SCB_NONE );
  228. add_sc( TF_SPRINKLESAND , SC_BLIND );
  229. add_sc( TF_THROWSTONE , SC_STUN );
  230. set_sc( MC_LOUD , SC_LOUD , SI_LOUD , SCB_STR );
  231. set_sc( MG_ENERGYCOAT , SC_ENERGYCOAT , SI_ENERGYCOAT , SCB_NONE );
  232. set_sc( NPC_EMOTION , SC_MODECHANGE , SI_BLANK , SCB_MODE );
  233. add_sc( NPC_EMOTION_ON , SC_MODECHANGE );
  234. set_sc( NPC_ATTRICHANGE , SC_ELEMENTALCHANGE , SI_ARMOR_PROPERTY , SCB_DEF_ELE );
  235. add_sc( NPC_CHANGEWATER , SC_ELEMENTALCHANGE );
  236. add_sc( NPC_CHANGEGROUND , SC_ELEMENTALCHANGE );
  237. add_sc( NPC_CHANGEFIRE , SC_ELEMENTALCHANGE );
  238. add_sc( NPC_CHANGEWIND , SC_ELEMENTALCHANGE );
  239. add_sc( NPC_CHANGEPOISON , SC_ELEMENTALCHANGE );
  240. add_sc( NPC_CHANGEHOLY , SC_ELEMENTALCHANGE );
  241. add_sc( NPC_CHANGEDARKNESS , SC_ELEMENTALCHANGE );
  242. add_sc( NPC_CHANGETELEKINESIS, SC_ELEMENTALCHANGE );
  243. add_sc( NPC_POISON , SC_POISON );
  244. add_sc( NPC_BLINDATTACK , SC_BLIND );
  245. add_sc( NPC_SILENCEATTACK , SC_SILENCE );
  246. add_sc( NPC_STUNATTACK , SC_STUN );
  247. add_sc( NPC_PETRIFYATTACK , SC_STONE );
  248. add_sc( NPC_CURSEATTACK , SC_CURSE );
  249. add_sc( NPC_SLEEPATTACK , SC_SLEEP );
  250. add_sc( NPC_MAGICALATTACK , SC_MAGICALATTACK );
  251. set_sc( NPC_KEEPING , SC_KEEPING , SI_BLANK , SCB_DEF );
  252. add_sc( NPC_DARKBLESSING , SC_COMA );
  253. set_sc( NPC_BARRIER , SC_BARRIER , SI_BLANK , SCB_MDEF|SCB_DEF );
  254. add_sc( NPC_DEFENDER , SC_ARMOR );
  255. add_sc( NPC_LICK , SC_STUN );
  256. set_sc( NPC_HALLUCINATION , SC_HALLUCINATION , SI_HALLUCINATION , SCB_NONE );
  257. add_sc( NPC_REBIRTH , SC_REBIRTH );
  258. add_sc( RG_RAID , SC_STUN );
  259. #ifdef RENEWAL
  260. add_sc( RG_RAID , SC_RAID );
  261. add_sc( RG_BACKSTAP , SC_STUN );
  262. #endif
  263. set_sc( RG_STRIPWEAPON , SC_STRIPWEAPON , SI_STRIPWEAPON , SCB_WATK );
  264. set_sc( RG_STRIPSHIELD , SC_STRIPSHIELD , SI_STRIPSHIELD , SCB_DEF );
  265. set_sc( RG_STRIPARMOR , SC_STRIPARMOR , SI_STRIPARMOR , SCB_VIT );
  266. set_sc( RG_STRIPHELM , SC_STRIPHELM , SI_STRIPHELM , SCB_INT );
  267. add_sc( AM_ACIDTERROR , SC_BLEEDING );
  268. set_sc( AM_CP_WEAPON , SC_CP_WEAPON , SI_CP_WEAPON , SCB_NONE );
  269. set_sc( AM_CP_SHIELD , SC_CP_SHIELD , SI_CP_SHIELD , SCB_NONE );
  270. set_sc( AM_CP_ARMOR , SC_CP_ARMOR , SI_CP_ARMOR , SCB_NONE );
  271. set_sc( AM_CP_HELM , SC_CP_HELM , SI_CP_HELM , SCB_NONE );
  272. set_sc( CR_AUTOGUARD , SC_AUTOGUARD , SI_AUTOGUARD , SCB_NONE );
  273. add_sc( CR_SHIELDCHARGE , SC_STUN );
  274. set_sc( CR_REFLECTSHIELD , SC_REFLECTSHIELD , SI_REFLECTSHIELD , SCB_NONE );
  275. add_sc( CR_HOLYCROSS , SC_BLIND );
  276. add_sc( CR_GRANDCROSS , SC_BLIND );
  277. add_sc( CR_DEVOTION , SC_DEVOTION );
  278. set_sc( CR_PROVIDENCE , SC_PROVIDENCE , SI_PROVIDENCE , SCB_ALL );
  279. set_sc( CR_DEFENDER , SC_DEFENDER , SI_DEFENDER , SCB_SPEED|SCB_ASPD );
  280. set_sc( CR_SPEARQUICKEN , SC_SPEARQUICKEN , SI_SPEARQUICKEN , SCB_ASPD|SCB_CRI|SCB_FLEE );
  281. set_sc( MO_STEELBODY , SC_STEELBODY , SI_STEELBODY , SCB_DEF|SCB_MDEF|SCB_ASPD|SCB_SPEED );
  282. add_sc( MO_BLADESTOP , SC_BLADESTOP_WAIT );
  283. add_sc( MO_BLADESTOP , SC_BLADESTOP );
  284. set_sc( MO_EXPLOSIONSPIRITS , SC_EXPLOSIONSPIRITS, SI_EXPLOSIONSPIRITS, SCB_CRI|SCB_REGEN );
  285. set_sc( MO_EXTREMITYFIST , SC_EXTREMITYFIST , SI_BLANK , SCB_REGEN );
  286. #ifdef RENEWAL
  287. set_sc( MO_EXTREMITYFIST , SC_EXTREMITYFIST2 , SI_EXTREMITYFIST , SCB_NONE );
  288. #endif
  289. add_sc( SA_MAGICROD , SC_MAGICROD );
  290. set_sc( SA_AUTOSPELL , SC_AUTOSPELL , SI_AUTOSPELL , SCB_NONE );
  291. set_sc( SA_FLAMELAUNCHER , SC_FIREWEAPON , SI_FIREWEAPON , SCB_ATK_ELE );
  292. set_sc( SA_FROSTWEAPON , SC_WATERWEAPON , SI_WATERWEAPON , SCB_ATK_ELE );
  293. set_sc( SA_LIGHTNINGLOADER , SC_WINDWEAPON , SI_WINDWEAPON , SCB_ATK_ELE );
  294. set_sc( SA_SEISMICWEAPON , SC_EARTHWEAPON , SI_EARTHWEAPON , SCB_ATK_ELE );
  295. set_sc( SA_VOLCANO , SC_VOLCANO , SI_LANDENDOW , SCB_WATK );
  296. set_sc( SA_DELUGE , SC_DELUGE , SI_LANDENDOW , SCB_MAXHP );
  297. set_sc( SA_VIOLENTGALE , SC_VIOLENTGALE , SI_LANDENDOW , SCB_FLEE );
  298. add_sc( SA_REVERSEORCISH , SC_ORCISH );
  299. add_sc( SA_COMA , SC_COMA );
  300. set_sc( BD_ENCORE , SC_DANCING , SI_BLANK , SCB_SPEED|SCB_REGEN );
  301. add_sc( BD_RICHMANKIM , SC_RICHMANKIM );
  302. set_sc( BD_ETERNALCHAOS , SC_ETERNALCHAOS , SI_BLANK , SCB_DEF2 );
  303. set_sc( BD_DRUMBATTLEFIELD , SC_DRUMBATTLE , SI_BLANK , SCB_WATK|SCB_DEF );
  304. set_sc( BD_RINGNIBELUNGEN , SC_NIBELUNGEN , SI_BLANK , SCB_WATK );
  305. add_sc( BD_ROKISWEIL , SC_ROKISWEIL );
  306. add_sc( BD_INTOABYSS , SC_INTOABYSS );
  307. set_sc( BD_SIEGFRIED , SC_SIEGFRIED , SI_BLANK , SCB_ALL );
  308. add_sc( BA_FROSTJOKER , SC_FREEZE );
  309. set_sc( BA_WHISTLE , SC_WHISTLE , SI_BLANK , SCB_FLEE|SCB_FLEE2 );
  310. set_sc( BA_ASSASSINCROSS , SC_ASSNCROS , SI_BLANK , SCB_ASPD );
  311. add_sc( BA_POEMBRAGI , SC_POEMBRAGI );
  312. set_sc( BA_APPLEIDUN , SC_APPLEIDUN , SI_BLANK , SCB_MAXHP );
  313. add_sc( DC_SCREAM , SC_STUN );
  314. set_sc( DC_HUMMING , SC_HUMMING , SI_BLANK , SCB_HIT );
  315. set_sc( DC_DONTFORGETME , SC_DONTFORGETME , SI_BLANK , SCB_SPEED|SCB_ASPD );
  316. set_sc( DC_FORTUNEKISS , SC_FORTUNE , SI_BLANK , SCB_CRI );
  317. set_sc( DC_SERVICEFORYOU , SC_SERVICE4U , SI_BLANK , SCB_ALL );
  318. add_sc( NPC_DARKCROSS , SC_BLIND );
  319. add_sc( NPC_GRANDDARKNESS , SC_BLIND );
  320. set_sc( NPC_STOP , SC_STOP , SI_STOP , SCB_NONE );
  321. set_sc( NPC_WEAPONBRAKER , SC_BROKENWEAPON , SI_BROKENWEAPON , SCB_NONE );
  322. set_sc( NPC_ARMORBRAKE , SC_BROKENARMOR , SI_BROKENARMOR , SCB_NONE );
  323. set_sc( NPC_CHANGEUNDEAD , SC_CHANGEUNDEAD , SI_UNDEAD , SCB_DEF_ELE );
  324. set_sc( NPC_POWERUP , SC_INCHITRATE , SI_BLANK , SCB_HIT );
  325. set_sc( NPC_AGIUP , SC_INCFLEERATE , SI_BLANK , SCB_FLEE );
  326. add_sc( NPC_INVISIBLE , SC_CLOAKING );
  327. set_sc( LK_AURABLADE , SC_AURABLADE , SI_AURABLADE , SCB_NONE );
  328. set_sc( LK_PARRYING , SC_PARRYING , SI_PARRYING , SCB_NONE );
  329. set_sc( LK_CONCENTRATION , SC_CONCENTRATION , SI_CONCENTRATION , SCB_BATK|SCB_WATK|SCB_HIT|SCB_DEF|SCB_DEF2|SCB_MDEF|SCB_DSPD );
  330. set_sc( LK_TENSIONRELAX , SC_TENSIONRELAX , SI_TENSIONRELAX , SCB_REGEN );
  331. set_sc( LK_BERSERK , SC_BERSERK , SI_BERSERK , SCB_DEF|SCB_DEF2|SCB_MDEF|SCB_MDEF2|SCB_FLEE|SCB_SPEED|SCB_ASPD|SCB_MAXHP|SCB_REGEN );
  332. set_sc( HP_ASSUMPTIO , SC_ASSUMPTIO , SI_ASSUMPTIO , SCB_NONE );
  333. add_sc( HP_BASILICA , SC_BASILICA );
  334. set_sc( HW_MAGICPOWER , SC_MAGICPOWER , SI_MAGICPOWER , SCB_MATK );
  335. add_sc( PA_SACRIFICE , SC_SACRIFICE );
  336. set_sc( PA_GOSPEL , SC_GOSPEL , SI_BLANK , SCB_SPEED|SCB_ASPD );
  337. add_sc( PA_GOSPEL , SC_SCRESIST );
  338. add_sc( CH_TIGERFIST , SC_STOP );
  339. set_sc( ASC_EDP , SC_EDP , SI_EDP , SCB_NONE );
  340. set_sc( SN_SIGHT , SC_TRUESIGHT , SI_TRUESIGHT , SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK|SCB_CRI|SCB_HIT );
  341. set_sc( SN_WINDWALK , SC_WINDWALK , SI_WINDWALK , SCB_FLEE|SCB_SPEED );
  342. set_sc( WS_MELTDOWN , SC_MELTDOWN , SI_MELTDOWN , SCB_NONE );
  343. set_sc( WS_CARTBOOST , SC_CARTBOOST , SI_CARTBOOST , SCB_SPEED );
  344. set_sc( ST_CHASEWALK , SC_CHASEWALK , SI_BLANK , SCB_SPEED );
  345. set_sc( ST_REJECTSWORD , SC_REJECTSWORD , SI_REJECTSWORD , SCB_NONE );
  346. add_sc( ST_REJECTSWORD , SC_AUTOCOUNTER );
  347. set_sc( CG_MARIONETTE , SC_MARIONETTE , SI_MARIONETTE , SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK );
  348. set_sc( CG_MARIONETTE , SC_MARIONETTE2 , SI_MARIONETTE2 , SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK );
  349. add_sc( LK_SPIRALPIERCE , SC_STOP );
  350. add_sc( LK_HEADCRUSH , SC_BLEEDING );
  351. set_sc( LK_JOINTBEAT , SC_JOINTBEAT , SI_JOINTBEAT , SCB_BATK|SCB_DEF2|SCB_SPEED|SCB_ASPD );
  352. add_sc( HW_NAPALMVULCAN , SC_CURSE );
  353. set_sc( PF_MINDBREAKER , SC_MINDBREAKER , SI_BLANK , SCB_MATK|SCB_MDEF2 );
  354. add_sc( PF_MEMORIZE , SC_MEMORIZE );
  355. add_sc( PF_FOGWALL , SC_FOGWALL );
  356. set_sc( PF_SPIDERWEB , SC_SPIDERWEB , SI_BLANK , SCB_FLEE );
  357. set_sc( WE_BABY , SC_BABY , SI_BABY , SCB_NONE );
  358. set_sc( TK_RUN , SC_RUN , SI_RUN , SCB_SPEED|SCB_DSPD );
  359. set_sc( TK_RUN , SC_SPURT , SI_SPURT , SCB_STR );
  360. set_sc( TK_READYSTORM , SC_READYSTORM , SI_READYSTORM , SCB_NONE );
  361. set_sc( TK_READYDOWN , SC_READYDOWN , SI_READYDOWN , SCB_NONE );
  362. add_sc( TK_DOWNKICK , SC_STUN );
  363. set_sc( TK_READYTURN , SC_READYTURN , SI_READYTURN , SCB_NONE );
  364. set_sc( TK_READYCOUNTER , SC_READYCOUNTER , SI_READYCOUNTER , SCB_NONE );
  365. set_sc( TK_DODGE , SC_DODGE , SI_DODGE , SCB_NONE );
  366. set_sc( TK_SPTIME , SC_EARTHSCROLL , SI_EARTHSCROLL , SCB_NONE );
  367. add_sc( TK_SEVENWIND , SC_SEVENWIND );
  368. set_sc( TK_SEVENWIND , SC_GHOSTWEAPON , SI_GHOSTWEAPON , SCB_ATK_ELE );
  369. set_sc( TK_SEVENWIND , SC_SHADOWWEAPON , SI_SHADOWWEAPON , SCB_ATK_ELE );
  370. set_sc( SG_SUN_WARM , SC_WARM , SI_WARM , SCB_NONE );
  371. add_sc( SG_MOON_WARM , SC_WARM );
  372. add_sc( SG_STAR_WARM , SC_WARM );
  373. set_sc( SG_SUN_COMFORT , SC_SUN_COMFORT , SI_SUN_COMFORT , SCB_DEF2 );
  374. set_sc( SG_MOON_COMFORT , SC_MOON_COMFORT , SI_MOON_COMFORT , SCB_FLEE );
  375. set_sc( SG_STAR_COMFORT , SC_STAR_COMFORT , SI_STAR_COMFORT , SCB_ASPD );
  376. add_sc( SG_FRIEND , SC_SKILLRATE_UP );
  377. set_sc( SG_KNOWLEDGE , SC_KNOWLEDGE , SI_BLANK , SCB_ALL );
  378. set_sc( SG_FUSION , SC_FUSION , SI_BLANK , SCB_SPEED );
  379. set_sc( BS_ADRENALINE2 , SC_ADRENALINE2 , SI_ADRENALINE2 , SCB_ASPD );
  380. set_sc( SL_KAIZEL , SC_KAIZEL , SI_KAIZEL , SCB_NONE );
  381. set_sc( SL_KAAHI , SC_KAAHI , SI_KAAHI , SCB_NONE );
  382. set_sc( SL_KAUPE , SC_KAUPE , SI_KAUPE , SCB_NONE );
  383. set_sc( SL_KAITE , SC_KAITE , SI_KAITE , SCB_NONE );
  384. add_sc( SL_STUN , SC_STUN );
  385. set_sc( SL_SWOO , SC_SWOO , SI_BLANK , SCB_SPEED );
  386. set_sc( SL_SKE , SC_SKE , SI_BLANK , SCB_BATK|SCB_WATK|SCB_DEF|SCB_DEF2 );
  387. set_sc( SL_SKA , SC_SKA , SI_BLANK , SCB_DEF|SCB_MDEF|SCB_ASPD );
  388. set_sc( SL_SMA , SC_SMA , SI_SMA , SCB_NONE );
  389. set_sc( SM_SELFPROVOKE , SC_PROVOKE , SI_PROVOKE , SCB_DEF|SCB_DEF2|SCB_BATK|SCB_WATK );
  390. set_sc( ST_PRESERVE , SC_PRESERVE , SI_PRESERVE , SCB_NONE );
  391. set_sc( PF_DOUBLECASTING , SC_DOUBLECAST , SI_DOUBLECAST , SCB_NONE );
  392. set_sc( HW_GRAVITATION , SC_GRAVITATION , SI_BLANK , SCB_ASPD );
  393. add_sc( WS_CARTTERMINATION , SC_STUN );
  394. set_sc( WS_OVERTHRUSTMAX , SC_MAXOVERTHRUST , SI_MAXOVERTHRUST , SCB_NONE );
  395. set_sc( CG_LONGINGFREEDOM , SC_LONGING , SI_BLANK , SCB_SPEED|SCB_ASPD );
  396. add_sc( CG_HERMODE , SC_HERMODE );
  397. set_sc( ITEM_ENCHANTARMS , SC_ENCHANTARMS , SI_BLANK , SCB_ATK_ELE );
  398. set_sc( SL_HIGH , SC_SPIRIT , SI_SPIRIT , SCB_ALL );
  399. set_sc( KN_ONEHAND , SC_ONEHAND , SI_ONEHAND , SCB_ASPD );
  400. set_sc( GS_FLING , SC_FLING , SI_BLANK , SCB_DEF|SCB_DEF2 );
  401. add_sc( GS_CRACKER , SC_STUN );
  402. add_sc( GS_DISARM , SC_STRIPWEAPON );
  403. add_sc( GS_PIERCINGSHOT , SC_BLEEDING );
  404. set_sc( GS_MADNESSCANCEL , SC_MADNESSCANCEL , SI_MADNESSCANCEL , SCB_BATK|SCB_ASPD );
  405. set_sc( GS_ADJUSTMENT , SC_ADJUSTMENT , SI_ADJUSTMENT , SCB_HIT|SCB_FLEE );
  406. set_sc( GS_INCREASING , SC_INCREASING , SI_ACCURACY , SCB_AGI|SCB_DEX|SCB_HIT );
  407. set_sc( GS_GATLINGFEVER , SC_GATLINGFEVER , SI_GATLINGFEVER , SCB_BATK|SCB_FLEE|SCB_SPEED|SCB_ASPD );
  408. set_sc( NJ_TATAMIGAESHI , SC_TATAMIGAESHI , SI_BLANK , SCB_NONE );
  409. set_sc( NJ_SUITON , SC_SUITON , SI_BLANK , SCB_AGI|SCB_SPEED );
  410. add_sc( NJ_HYOUSYOURAKU , SC_FREEZE );
  411. set_sc( NJ_NEN , SC_NEN , SI_NEN , SCB_STR|SCB_INT );
  412. set_sc( NJ_UTSUSEMI , SC_UTSUSEMI , SI_UTSUSEMI , SCB_NONE );
  413. set_sc( NJ_BUNSINJYUTSU , SC_BUNSINJYUTSU , SI_BUNSINJYUTSU , SCB_DYE );
  414. add_sc( NPC_ICEBREATH , SC_FREEZE );
  415. add_sc( NPC_ACIDBREATH , SC_POISON );
  416. add_sc( NPC_HELLJUDGEMENT , SC_CURSE );
  417. add_sc( NPC_WIDESILENCE , SC_SILENCE );
  418. add_sc( NPC_WIDEFREEZE , SC_FREEZE );
  419. add_sc( NPC_WIDEBLEEDING , SC_BLEEDING );
  420. add_sc( NPC_WIDESTONE , SC_STONE );
  421. add_sc( NPC_WIDECONFUSE , SC_CONFUSION );
  422. add_sc( NPC_WIDESLEEP , SC_SLEEP );
  423. add_sc( NPC_WIDESIGHT , SC_SIGHT );
  424. add_sc( NPC_EVILLAND , SC_BLIND );
  425. add_sc( NPC_MAGICMIRROR , SC_MAGICMIRROR );
  426. set_sc( NPC_SLOWCAST , SC_SLOWCAST , SI_SLOWCAST , SCB_NONE );
  427. set_sc( NPC_CRITICALWOUND , SC_CRITICALWOUND , SI_CRITICALWOUND , SCB_NONE );
  428. set_sc( NPC_STONESKIN , SC_ARMORCHANGE , SI_BLANK , SCB_DEF|SCB_MDEF );
  429. add_sc( NPC_ANTIMAGIC , SC_ARMORCHANGE );
  430. add_sc( NPC_WIDECURSE , SC_CURSE );
  431. add_sc( NPC_WIDESTUN , SC_STUN );
  432. set_sc( NPC_HELLPOWER , SC_HELLPOWER , SI_HELLPOWER , SCB_NONE );
  433. set_sc( NPC_WIDEHELLDIGNITY , SC_HELLPOWER , SI_HELLPOWER , SCB_NONE );
  434. set_sc( NPC_INVINCIBLE , SC_INVINCIBLE , SI_INVINCIBLE , SCB_SPEED );
  435. set_sc( NPC_INVINCIBLEOFF , SC_INVINCIBLEOFF , SI_BLANK , SCB_SPEED );
  436. set_sc( CASH_BLESSING , SC_BLESSING , SI_BLESSING , SCB_STR|SCB_INT|SCB_DEX );
  437. set_sc( CASH_INCAGI , SC_INCREASEAGI , SI_INCREASEAGI , SCB_AGI|SCB_SPEED );
  438. set_sc( CASH_ASSUMPTIO , SC_ASSUMPTIO , SI_ASSUMPTIO , SCB_NONE );
  439. set_sc( ALL_PARTYFLEE , SC_PARTYFLEE , SI_PARTYFLEE , SCB_NONE );
  440. set_sc( ALL_ODINS_POWER , SC_ODINS_POWER , SI_ODINS_POWER , SCB_MATK|SCB_BATK|SCB_MDEF|SCB_DEF );
  441. set_sc( CR_SHRINK , SC_SHRINK , SI_SHRINK , SCB_NONE );
  442. set_sc( RG_CLOSECONFINE , SC_CLOSECONFINE2 , SI_CLOSECONFINE2 , SCB_NONE );
  443. set_sc( RG_CLOSECONFINE , SC_CLOSECONFINE , SI_CLOSECONFINE , SCB_FLEE );
  444. set_sc( WZ_SIGHTBLASTER , SC_SIGHTBLASTER , SI_SIGHTBLASTER , SCB_NONE );
  445. set_sc( DC_WINKCHARM , SC_WINKCHARM , SI_WINKCHARM , SCB_NONE );
  446. add_sc( MO_BALKYOUNG , SC_STUN );
  447. add_sc( SA_ELEMENTWATER , SC_ELEMENTALCHANGE );
  448. add_sc( SA_ELEMENTFIRE , SC_ELEMENTALCHANGE );
  449. add_sc( SA_ELEMENTGROUND , SC_ELEMENTALCHANGE );
  450. add_sc( SA_ELEMENTWIND , SC_ELEMENTALCHANGE );
  451. set_sc( HLIF_AVOID , SC_AVOID , SI_BLANK , SCB_SPEED );
  452. set_sc( HLIF_CHANGE , SC_CHANGE , SI_BLANK , SCB_VIT|SCB_INT );
  453. set_sc( HFLI_FLEET , SC_FLEET , SI_BLANK , SCB_ASPD|SCB_BATK|SCB_WATK );
  454. set_sc( HFLI_SPEED , SC_SPEED , SI_BLANK , SCB_FLEE );
  455. set_sc( HAMI_DEFENCE , SC_DEFENCE , SI_BLANK , SCB_DEF );
  456. set_sc( HAMI_BLOODLUST , SC_BLOODLUST , SI_BLANK , SCB_BATK|SCB_WATK );
  457. // Homunculus S
  458. add_sc(MH_STAHL_HORN, SC_STUN);
  459. set_sc(MH_ANGRIFFS_MODUS, SC_ANGRIFFS_MODUS, SI_ANGRIFFS_MODUS, SCB_BATK | SCB_DEF | SCB_FLEE | SCB_MAXHP);
  460. set_sc(MH_GOLDENE_FERSE, SC_GOLDENE_FERSE, SI_GOLDENE_FERSE, SCB_ASPD|SCB_MAXHP);
  461. add_sc( MH_STEINWAND, SC_SAFETYWALL );
  462. add_sc(MH_ERASER_CUTTER, SC_ERASER_CUTTER);
  463. set_sc(MH_OVERED_BOOST, SC_OVERED_BOOST, SI_BLANK, SCB_FLEE|SCB_ASPD);
  464. add_sc(MH_LIGHT_OF_REGENE, SC_LIGHT_OF_REGENE);
  465. set_sc(MH_VOLCANIC_ASH, SC_ASH, SI_VOLCANIC_ASH, SCB_DEF|SCB_DEF2|SCB_HIT|SCB_BATK|SCB_FLEE);
  466. set_sc(MH_GRANITIC_ARMOR, SC_GRANITIC_ARMOR, SI_GRANITIC_ARMOR, SCB_NONE);
  467. set_sc(MH_MAGMA_FLOW, SC_MAGMA_FLOW, SI_MAGMA_FLOW, SCB_NONE);
  468. set_sc(MH_PYROCLASTIC, SC_PYROCLASTIC, SI_PYROCLASTIC, SCB_BATK|SCB_ATK_ELE);
  469. add_sc(MH_LAVA_SLIDE, SC_BURNING);
  470. set_sc(MH_NEEDLE_OF_PARALYZE, SC_PARALYSIS, SI_NEEDLE_OF_PARALYZE, SCB_DEF2);
  471. add_sc(MH_POISON_MIST, SC_BLIND);
  472. set_sc(MH_PAIN_KILLER, SC_PAIN_KILLER, SI_PAIN_KILLER, SCB_ASPD);
  473. add_sc(MH_STYLE_CHANGE, SC_STYLE_CHANGE);
  474. set_sc( MH_TINDER_BREAKER , SC_CLOSECONFINE2 , SI_CLOSECONFINE2 , SCB_NONE );
  475. set_sc( MH_TINDER_BREAKER , SC_CLOSECONFINE , SI_CLOSECONFINE , SCB_FLEE );
  476. add_sc( MER_CRASH , SC_STUN );
  477. set_sc( MER_PROVOKE , SC_PROVOKE , SI_PROVOKE , SCB_DEF|SCB_DEF2|SCB_BATK|SCB_WATK );
  478. add_sc( MS_MAGNUM , SC_WATK_ELEMENT );
  479. add_sc( MER_SIGHT , SC_SIGHT );
  480. set_sc( MER_DECAGI , SC_DECREASEAGI , SI_DECREASEAGI , SCB_AGI|SCB_SPEED );
  481. set_sc( MER_MAGNIFICAT , SC_MAGNIFICAT , SI_MAGNIFICAT , SCB_REGEN );
  482. add_sc( MER_LEXDIVINA , SC_SILENCE );
  483. add_sc( MA_LANDMINE , SC_STUN );
  484. add_sc( MA_SANDMAN , SC_SLEEP );
  485. add_sc( MA_FREEZINGTRAP , SC_FREEZE );
  486. set_sc( MER_AUTOBERSERK , SC_AUTOBERSERK , SI_AUTOBERSERK , SCB_NONE );
  487. set_sc( ML_AUTOGUARD , SC_AUTOGUARD , SI_AUTOGUARD , SCB_NONE );
  488. set_sc( MS_REFLECTSHIELD , SC_REFLECTSHIELD , SI_REFLECTSHIELD , SCB_NONE );
  489. set_sc( ML_DEFENDER , SC_DEFENDER , SI_DEFENDER , SCB_SPEED|SCB_ASPD );
  490. set_sc( MS_PARRYING , SC_PARRYING , SI_PARRYING , SCB_NONE );
  491. set_sc( MS_BERSERK , SC_BERSERK , SI_BERSERK , SCB_DEF|SCB_DEF2|SCB_MDEF|SCB_MDEF2|SCB_FLEE|SCB_SPEED|SCB_ASPD|SCB_MAXHP|SCB_REGEN );
  492. add_sc( ML_SPIRALPIERCE , SC_STOP );
  493. set_sc( MER_QUICKEN , SC_MERC_QUICKEN , SI_BLANK , SCB_ASPD );
  494. add_sc( ML_DEVOTION , SC_DEVOTION );
  495. set_sc( MER_KYRIE , SC_KYRIE , SI_KYRIE , SCB_NONE );
  496. set_sc( MER_BLESSING , SC_BLESSING , SI_BLESSING , SCB_STR|SCB_INT|SCB_DEX );
  497. set_sc( MER_INCAGI , SC_INCREASEAGI , SI_INCREASEAGI , SCB_AGI|SCB_SPEED );
  498. set_sc( GD_LEADERSHIP , SC_LEADERSHIP , SI_BLANK , SCB_STR );
  499. set_sc( GD_GLORYWOUNDS , SC_GLORYWOUNDS , SI_BLANK , SCB_VIT );
  500. set_sc( GD_SOULCOLD , SC_SOULCOLD , SI_BLANK , SCB_AGI );
  501. set_sc( GD_HAWKEYES , SC_HAWKEYES , SI_BLANK , SCB_DEX );
  502. set_sc( GD_BATTLEORDER , SC_BATTLEORDERS , SI_BLANK , SCB_STR|SCB_INT|SCB_DEX );
  503. set_sc( GD_REGENERATION , SC_REGENERATION , SI_BLANK , SCB_REGEN );
  504. /**
  505. * Rune Knight
  506. **/
  507. set_sc( RK_ENCHANTBLADE , SC_ENCHANTBLADE , SI_ENCHANTBLADE , SCB_NONE );
  508. set_sc( RK_DRAGONHOWLING , SC_FEAR , SI_BLANK , SCB_FLEE|SCB_HIT );
  509. set_sc( RK_DEATHBOUND , SC_DEATHBOUND , SI_DEATHBOUND , SCB_NONE );
  510. set_sc( RK_WINDCUTTER , SC_FEAR , SI_BLANK , SCB_FLEE|SCB_HIT );
  511. add_sc( RK_DRAGONBREATH , SC_BURNING );
  512. set_sc( RK_MILLENNIUMSHIELD , SC_MILLENNIUMSHIELD , SI_REUSE_MILLENNIUMSHIELD , SCB_NONE );
  513. set_sc( RK_REFRESH , SC_REFRESH , SI_REFRESH , SCB_NONE );
  514. set_sc( RK_GIANTGROWTH , SC_GIANTGROWTH , SI_GIANTGROWTH , SCB_STR );
  515. set_sc( RK_STONEHARDSKIN , SC_STONEHARDSKIN , SI_STONEHARDSKIN , SCB_NONE );
  516. set_sc( RK_VITALITYACTIVATION, SC_VITALITYACTIVATION, SI_VITALITYACTIVATION, SCB_REGEN );
  517. set_sc( RK_FIGHTINGSPIRIT , SC_FIGHTINGSPIRIT , SI_FIGHTINGSPIRIT , SCB_WATK|SCB_ASPD );
  518. set_sc( RK_ABUNDANCE , SC_ABUNDANCE , SI_ABUNDANCE , SCB_NONE );
  519. set_sc( RK_CRUSHSTRIKE , SC_CRUSHSTRIKE , SI_CRUSHSTRIKE , SCB_NONE );
  520. /**
  521. * GC Guillotine Cross
  522. **/
  523. set_sc_with_vfx( GC_VENOMIMPRESS , SC_VENOMIMPRESS , SI_VENOMIMPRESS , SCB_NONE );
  524. set_sc( GC_POISONINGWEAPON , SC_POISONINGWEAPON , SI_POISONINGWEAPON , SCB_NONE );
  525. set_sc( GC_WEAPONBLOCKING , SC_WEAPONBLOCKING , SI_WEAPONBLOCKING , SCB_NONE );
  526. set_sc( GC_CLOAKINGEXCEED , SC_CLOAKINGEXCEED , SI_CLOAKINGEXCEED , SCB_SPEED );
  527. set_sc( GC_HALLUCINATIONWALK , SC_HALLUCINATIONWALK, SI_HALLUCINATIONWALK, SCB_FLEE );
  528. set_sc( GC_ROLLINGCUTTER , SC_ROLLINGCUTTER , SI_ROLLINGCUTTER , SCB_NONE );
  529. /**
  530. * Arch Bishop
  531. **/
  532. set_sc( AB_ADORAMUS , SC_ADORAMUS , SI_ADORAMUS , SCB_AGI|SCB_SPEED );
  533. add_sc( AB_CLEMENTIA , SC_BLESSING );
  534. add_sc( AB_CANTO , SC_INCREASEAGI );
  535. set_sc( AB_EPICLESIS , SC_EPICLESIS , SI_EPICLESIS , SCB_MAXHP );
  536. add_sc( AB_PRAEFATIO , SC_KYRIE );
  537. set_sc_with_vfx( AB_ORATIO , SC_ORATIO , SI_ORATIO , SCB_NONE );
  538. set_sc( AB_LAUDAAGNUS , SC_LAUDAAGNUS , SI_LAUDAAGNUS , SCB_VIT );
  539. set_sc( AB_LAUDARAMUS , SC_LAUDARAMUS , SI_LAUDARAMUS , SCB_LUK );
  540. set_sc( AB_RENOVATIO , SC_RENOVATIO , SI_RENOVATIO , SCB_REGEN );
  541. set_sc( AB_EXPIATIO , SC_EXPIATIO , SI_EXPIATIO , SCB_ATK_ELE );
  542. set_sc( AB_DUPLELIGHT , SC_DUPLELIGHT , SI_DUPLELIGHT , SCB_NONE );
  543. set_sc( AB_SECRAMENT , SC_SECRAMENT , SI_SECRAMENT , SCB_NONE );
  544. /**
  545. * Warlock
  546. **/
  547. add_sc( WL_WHITEIMPRISON , SC_WHITEIMPRISON );
  548. set_sc_with_vfx( WL_FROSTMISTY , SC_FREEZING , SI_FROSTMISTY , SCB_ASPD|SCB_SPEED|SCB_DEF|SCB_DEF2 );
  549. set_sc( WL_MARSHOFABYSS , SC_MARSHOFABYSS , SI_MARSHOFABYSS , SCB_SPEED|SCB_FLEE|SCB_DEF|SCB_MDEF );
  550. set_sc(WL_RECOGNIZEDSPELL , SC_RECOGNIZEDSPELL , SI_RECOGNIZEDSPELL , SCB_MATK);
  551. set_sc( WL_STASIS , SC_STASIS , SI_STASIS , SCB_NONE );
  552. /**
  553. * Ranger
  554. **/
  555. set_sc( RA_FEARBREEZE , SC_FEARBREEZE , SI_FEARBREEZE , SCB_NONE );
  556. set_sc( RA_ELECTRICSHOCKER , SC_ELECTRICSHOCKER , SI_ELECTRICSHOCKER , SCB_NONE );
  557. set_sc( RA_WUGDASH , SC_WUGDASH , SI_WUGDASH , SCB_SPEED );
  558. set_sc( RA_CAMOUFLAGE , SC_CAMOUFLAGE , SI_CAMOUFLAGE , SCB_SPEED );
  559. add_sc( RA_MAGENTATRAP , SC_ELEMENTALCHANGE );
  560. add_sc( RA_COBALTTRAP , SC_ELEMENTALCHANGE );
  561. add_sc( RA_MAIZETRAP , SC_ELEMENTALCHANGE );
  562. add_sc( RA_VERDURETRAP , SC_ELEMENTALCHANGE );
  563. add_sc( RA_FIRINGTRAP , SC_BURNING );
  564. set_sc_with_vfx( RA_ICEBOUNDTRAP , SC_FREEZING , SI_FROSTMISTY , SCB_NONE );
  565. /**
  566. * Mechanic
  567. **/
  568. set_sc( NC_ACCELERATION , SC_ACCELERATION , SI_ACCELERATION , SCB_SPEED );
  569. set_sc( NC_HOVERING , SC_HOVERING , SI_HOVERING , SCB_SPEED );
  570. set_sc( NC_SHAPESHIFT , SC_SHAPESHIFT , SI_SHAPESHIFT , SCB_DEF_ELE );
  571. set_sc( NC_INFRAREDSCAN , SC_INFRAREDSCAN , SI_INFRAREDSCAN , SCB_FLEE );
  572. set_sc( NC_ANALYZE , SC_ANALYZE , SI_ANALYZE , SCB_DEF|SCB_DEF2|SCB_MDEF|SCB_MDEF2 );
  573. set_sc( NC_MAGNETICFIELD , SC_MAGNETICFIELD , SI_MAGNETICFIELD , SCB_NONE );
  574. set_sc( NC_NEUTRALBARRIER , SC_NEUTRALBARRIER , SI_NEUTRALBARRIER , SCB_NONE );
  575. set_sc( NC_STEALTHFIELD , SC_STEALTHFIELD , SI_STEALTHFIELD , SCB_NONE );
  576. /**
  577. * Royal Guard
  578. **/
  579. set_sc( LG_REFLECTDAMAGE , SC_REFLECTDAMAGE , SI_LG_REFLECTDAMAGE, SCB_NONE );
  580. set_sc( LG_FORCEOFVANGUARD , SC_FORCEOFVANGUARD , SI_FORCEOFVANGUARD , SCB_MAXHP|SCB_DEF );
  581. set_sc( LG_EXEEDBREAK , SC_EXEEDBREAK , SI_EXEEDBREAK , SCB_NONE );
  582. set_sc( LG_PRESTIGE , SC_PRESTIGE , SI_PRESTIGE , SCB_DEF );
  583. set_sc( LG_BANDING , SC_BANDING , SI_BANDING , SCB_DEF2|SCB_WATK );// Renewal: atk2 & def2
  584. set_sc( LG_PIETY , SC_BENEDICTIO , SI_BENEDICTIO , SCB_DEF_ELE );
  585. set_sc( LG_EARTHDRIVE , SC_EARTHDRIVE , SI_EARTHDRIVE , SCB_DEF|SCB_ASPD );
  586. set_sc( LG_INSPIRATION , SC_INSPIRATION , SI_INSPIRATION , SCB_MAXHP|SCB_WATK|SCB_HIT|SCB_VIT|SCB_AGI|SCB_STR|SCB_DEX|SCB_INT|SCB_LUK);
  587. set_sc( LG_SHIELDSPELL , SC_SHIELDSPELL_DEF , SI_SHIELDSPELL_DEF , SCB_WATK );
  588. set_sc( LG_SHIELDSPELL , SC_SHIELDSPELL_REF , SI_SHIELDSPELL_REF , SCB_DEF );
  589. /**
  590. * Shadow Chaser
  591. **/
  592. set_sc( SC_REPRODUCE , SC__REPRODUCE , SI_REPRODUCE , SCB_NONE );
  593. set_sc( SC_AUTOSHADOWSPELL , SC__AUTOSHADOWSPELL, SI_AUTOSHADOWSPELL , SCB_NONE );
  594. set_sc( SC_SHADOWFORM , SC__SHADOWFORM , SI_SHADOWFORM , SCB_NONE );
  595. set_sc( SC_BODYPAINT , SC__BODYPAINT , SI_BODYPAINT , SCB_ASPD );
  596. set_sc( SC_INVISIBILITY , SC__INVISIBILITY , SI_INVISIBILITY , SCB_ASPD|SCB_CRI|SCB_ATK_ELE );
  597. set_sc( SC_DEADLYINFECT , SC__DEADLYINFECT , SI_DEADLYINFECT , SCB_NONE );
  598. set_sc( SC_ENERVATION , SC__ENERVATION , SI_ENERVATION , SCB_BATK );
  599. set_sc( SC_GROOMY , SC__GROOMY , SI_GROOMY , SCB_ASPD|SCB_HIT|SCB_SPEED );
  600. set_sc( SC_IGNORANCE , SC__IGNORANCE , SI_IGNORANCE , SCB_NONE );
  601. set_sc( SC_LAZINESS , SC__LAZINESS , SI_LAZINESS , SCB_FLEE );
  602. set_sc( SC_UNLUCKY , SC__UNLUCKY , SI_UNLUCKY , SCB_CRI|SCB_FLEE2 );
  603. set_sc( SC_WEAKNESS , SC__WEAKNESS , SI_WEAKNESS , SCB_FLEE2|SCB_MAXHP );
  604. set_sc( SC_STRIPACCESSARY , SC__STRIPACCESSORY , SI_STRIPACCESSARY , SCB_DEX|SCB_INT|SCB_LUK );
  605. set_sc_with_vfx( SC_MANHOLE , SC__MANHOLE , SI_MANHOLE , SCB_NONE );
  606. add_sc( SC_CHAOSPANIC , SC_CONFUSION );
  607. set_sc_with_vfx( SC_BLOODYLUST , SC__BLOODYLUST , SI_BLOODYLUST , SCB_DEF | SCB_DEF2 | SCB_MDEF | SCB_MDEF2 | SCB_FLEE | SCB_SPEED | SCB_ASPD | SCB_MAXHP | SCB_REGEN );
  608. /**
  609. * Sura
  610. **/
  611. add_sc( SR_DRAGONCOMBO , SC_STUN );
  612. add_sc( SR_EARTHSHAKER , SC_STUN );
  613. set_sc( SR_CRESCENTELBOW , SC_CRESCENTELBOW , SI_CRESCENTELBOW , SCB_NONE );
  614. set_sc_with_vfx( SR_CURSEDCIRCLE , SC_CURSEDCIRCLE_TARGET, SI_CURSEDCIRCLE_TARGET , SCB_NONE );
  615. set_sc( SR_LIGHTNINGWALK , SC_LIGHTNINGWALK , SI_LIGHTNINGWALK , SCB_NONE );
  616. set_sc( SR_RAISINGDRAGON , SC_RAISINGDRAGON , SI_RAISINGDRAGON , SCB_REGEN|SCB_MAXHP|SCB_MAXSP );
  617. set_sc( SR_GENTLETOUCH_ENERGYGAIN, SC_GT_ENERGYGAIN , SI_GENTLETOUCH_ENERGYGAIN, SCB_NONE );
  618. set_sc( SR_GENTLETOUCH_CHANGE , SC_GT_CHANGE , SI_GENTLETOUCH_CHANGE , SCB_ASPD|SCB_MDEF|SCB_MAXHP );
  619. set_sc( SR_GENTLETOUCH_REVITALIZE, SC_GT_REVITALIZE , SI_GENTLETOUCH_REVITALIZE, SCB_MAXHP|SCB_REGEN );
  620. /**
  621. * Wanderer / Minstrel
  622. **/
  623. set_sc( WA_SWING_DANCE , SC_SWINGDANCE , SI_SWINGDANCE , SCB_SPEED|SCB_ASPD );
  624. set_sc( WA_SYMPHONY_OF_LOVER , SC_SYMPHONYOFLOVER , SI_SYMPHONYOFLOVERS , SCB_MDEF );
  625. set_sc( WA_MOONLIT_SERENADE , SC_MOONLITSERENADE , SI_MOONLITSERENADE , SCB_MATK );
  626. set_sc( MI_RUSH_WINDMILL , SC_RUSHWINDMILL , SI_RUSHWINDMILL , SCB_BATK );
  627. set_sc( MI_ECHOSONG , SC_ECHOSONG , SI_ECHOSONG , SCB_DEF2 );
  628. set_sc( MI_HARMONIZE , SC_HARMONIZE , SI_HARMONIZE , SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK );
  629. set_sc_with_vfx( WM_POEMOFNETHERWORLD , SC_NETHERWORLD , SI_NETHERWORLD , SCB_NONE );
  630. set_sc_with_vfx( WM_VOICEOFSIREN , SC_VOICEOFSIREN , SI_VOICEOFSIREN , SCB_NONE );
  631. set_sc_with_vfx( WM_LULLABY_DEEPSLEEP , SC_DEEPSLEEP , SI_DEEPSLEEP , SCB_NONE );
  632. set_sc( WM_SIRCLEOFNATURE , SC_SIRCLEOFNATURE , SI_SIRCLEOFNATURE , SCB_NONE );
  633. set_sc( WM_GLOOMYDAY , SC_GLOOMYDAY , SI_GLOOMYDAY , SCB_FLEE|SCB_ASPD );
  634. set_sc( WM_SONG_OF_MANA , SC_SONGOFMANA , SI_SONGOFMANA , SCB_NONE );
  635. set_sc( WM_DANCE_WITH_WUG , SC_DANCEWITHWUG , SI_DANCEWITHWUG , SCB_ASPD );
  636. set_sc( WM_SATURDAY_NIGHT_FEVER , SC_SATURDAYNIGHTFEVER , SI_SATURDAYNIGHTFEVER , SCB_BATK|SCB_DEF|SCB_FLEE|SCB_REGEN );
  637. set_sc( WM_LERADS_DEW , SC_LERADSDEW , SI_LERADSDEW , SCB_MAXHP );
  638. set_sc( WM_MELODYOFSINK , SC_MELODYOFSINK , SI_MELODYOFSINK , SCB_BATK|SCB_MATK );
  639. set_sc( WM_BEYOND_OF_WARCRY , SC_BEYONDOFWARCRY , SI_WARCRYOFBEYOND , SCB_BATK|SCB_MATK );
  640. set_sc( WM_UNLIMITED_HUMMING_VOICE, SC_UNLIMITEDHUMMINGVOICE, SI_UNLIMITEDHUMMINGVOICE, SCB_NONE );
  641. /**
  642. * Sorcerer
  643. **/
  644. set_sc( SO_FIREWALK , SC_PROPERTYWALK , SI_PROPERTYWALK , SCB_NONE );
  645. set_sc( SO_ELECTRICWALK , SC_PROPERTYWALK , SI_PROPERTYWALK , SCB_NONE );
  646. set_sc( SO_SPELLFIST , SC_SPELLFIST , SI_SPELLFIST , SCB_NONE );
  647. set_sc_with_vfx( SO_DIAMONDDUST , SC_CRYSTALIZE , SI_COLD , SCB_NONE ); // it does show the snow icon on mobs but doesn't affect it.
  648. add_sc( SO_CLOUD_KILL , SC_POISON );
  649. set_sc( SO_STRIKING , SC_STRIKING , SI_STRIKING , SCB_WATK|SCB_CRI );
  650. set_sc( SO_WARMER , SC_WARMER , SI_WARMER , SCB_NONE );
  651. set_sc( SO_VACUUM_EXTREME , SC_VACUUM_EXTREME , SI_VACUUM_EXTREME , SCB_NONE );
  652. set_sc( SO_ARRULLO , SC_DEEPSLEEP , SI_DEEPSLEEP , SCB_NONE );
  653. set_sc( SO_FIRE_INSIGNIA , SC_FIRE_INSIGNIA , SI_FIRE_INSIGNIA , SCB_MATK | SCB_BATK | SCB_WATK | SCB_ATK_ELE | SCB_REGEN );
  654. set_sc( SO_WATER_INSIGNIA , SC_WATER_INSIGNIA , SI_WATER_INSIGNIA , SCB_WATK | SCB_ATK_ELE | SCB_REGEN );
  655. set_sc( SO_WIND_INSIGNIA , SC_WIND_INSIGNIA , SI_WIND_INSIGNIA , SCB_WATK | SCB_ATK_ELE | SCB_REGEN );
  656. set_sc( SO_EARTH_INSIGNIA , SC_EARTH_INSIGNIA , SI_EARTH_INSIGNIA , SCB_MDEF|SCB_DEF|SCB_MAXHP|SCB_MAXSP|SCB_WATK | SCB_ATK_ELE | SCB_REGEN );
  657. /**
  658. * Genetic
  659. **/
  660. set_sc( GN_CARTBOOST , SC_GN_CARTBOOST, SI_CARTSBOOST , SCB_SPEED );
  661. set_sc( GN_THORNS_TRAP , SC_THORNSTRAP , SI_THORNTRAP , SCB_NONE );
  662. set_sc_with_vfx( GN_BLOOD_SUCKER , SC_BLOODSUCKER , SI_BLOODSUCKER , SCB_NONE );
  663. set_sc( GN_WALLOFTHORN , SC_STOP , SI_BLANK , SCB_NONE );
  664. set_sc( GN_FIRE_EXPANSION_SMOKE_POWDER, SC_SMOKEPOWDER , SI_FIRE_EXPANSION_SMOKE_POWDER, SCB_NONE );
  665. set_sc( GN_FIRE_EXPANSION_TEAR_GAS , SC_TEARGAS , SI_FIRE_EXPANSION_TEAR_GAS , SCB_NONE );
  666. set_sc( GN_MANDRAGORA , SC_MANDRAGORA , SI_MANDRAGORA , SCB_INT );
  667. // Elemental Spirit summoner's 'side' status changes.
  668. set_sc( EL_CIRCLE_OF_FIRE , SC_CIRCLE_OF_FIRE_OPTION, SI_CIRCLE_OF_FIRE_OPTION, SCB_NONE );
  669. set_sc( EL_FIRE_CLOAK , SC_FIRE_CLOAK_OPTION , SI_FIRE_CLOAK_OPTION , SCB_ALL );
  670. set_sc( EL_WATER_SCREEN , SC_WATER_SCREEN_OPTION , SI_WATER_SCREEN_OPTION , SCB_NONE );
  671. set_sc( EL_WATER_DROP , SC_WATER_DROP_OPTION , SI_WATER_DROP_OPTION , SCB_ALL );
  672. set_sc( EL_WATER_BARRIER , SC_WATER_BARRIER , SI_WATER_BARRIER , SCB_MDEF|SCB_WATK|SCB_MATK|SCB_FLEE );
  673. set_sc( EL_WIND_STEP , SC_WIND_STEP_OPTION , SI_WIND_STEP_OPTION , SCB_SPEED|SCB_FLEE );
  674. set_sc( EL_WIND_CURTAIN , SC_WIND_CURTAIN_OPTION , SI_WIND_CURTAIN_OPTION , SCB_ALL );
  675. set_sc( EL_ZEPHYR , SC_ZEPHYR , SI_ZEPHYR , SCB_FLEE );
  676. set_sc( EL_SOLID_SKIN , SC_SOLID_SKIN_OPTION , SI_SOLID_SKIN_OPTION , SCB_DEF|SCB_MAXHP );
  677. set_sc( EL_STONE_SHIELD , SC_STONE_SHIELD_OPTION , SI_STONE_SHIELD_OPTION , SCB_ALL );
  678. set_sc( EL_POWER_OF_GAIA , SC_POWER_OF_GAIA , SI_POWER_OF_GAIA , SCB_MAXHP|SCB_DEF|SCB_SPEED );
  679. set_sc( EL_PYROTECHNIC , SC_PYROTECHNIC_OPTION , SI_PYROTECHNIC_OPTION , SCB_WATK );
  680. set_sc( EL_HEATER , SC_HEATER_OPTION , SI_HEATER_OPTION , SCB_WATK );
  681. set_sc( EL_TROPIC , SC_TROPIC_OPTION , SI_TROPIC_OPTION , SCB_WATK );
  682. set_sc( EL_AQUAPLAY , SC_AQUAPLAY_OPTION , SI_AQUAPLAY_OPTION , SCB_MATK );
  683. set_sc( EL_COOLER , SC_COOLER_OPTION , SI_COOLER_OPTION , SCB_MATK );
  684. set_sc( EL_CHILLY_AIR , SC_CHILLY_AIR_OPTION , SI_CHILLY_AIR_OPTION , SCB_MATK );
  685. set_sc( EL_GUST , SC_GUST_OPTION , SI_GUST_OPTION , SCB_ASPD );
  686. set_sc( EL_BLAST , SC_BLAST_OPTION , SI_BLAST_OPTION , SCB_ASPD );
  687. set_sc( EL_WILD_STORM , SC_WILD_STORM_OPTION , SI_WILD_STORM_OPTION , SCB_ASPD );
  688. set_sc( EL_PETROLOGY , SC_PETROLOGY_OPTION , SI_PETROLOGY_OPTION , SCB_MAXHP );
  689. set_sc( EL_CURSED_SOIL , SC_CURSED_SOIL_OPTION , SI_CURSED_SOIL_OPTION , SCB_NONE );
  690. set_sc( EL_UPHEAVAL , SC_UPHEAVAL_OPTION , SI_UPHEAVAL_OPTION , SCB_NONE );
  691. set_sc( EL_TIDAL_WEAPON , SC_TIDAL_WEAPON_OPTION , SI_TIDAL_WEAPON_OPTION , SCB_ALL );
  692. set_sc( EL_ROCK_CRUSHER , SC_ROCK_CRUSHER , SI_ROCK_CRUSHER , SCB_DEF );
  693. set_sc( EL_ROCK_CRUSHER_ATK, SC_ROCK_CRUSHER_ATK , SI_ROCK_CRUSHER_ATK , SCB_SPEED );
  694. add_sc( KO_YAMIKUMO , SC_HIDING );
  695. set_sc_with_vfx( KO_JYUMONJIKIRI , SC_JYUMONJIKIRI , SI_KO_JYUMONJIKIRI , SCB_NONE );
  696. add_sc( KO_MAKIBISHI , SC_STUN );
  697. set_sc( KO_MEIKYOUSISUI , SC_MEIKYOUSISUI , SI_MEIKYOUSISUI , SCB_NONE );
  698. set_sc( KO_KYOUGAKU , SC_KYOUGAKU , SI_KYOUGAKU , SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK );
  699. add_sc( KO_JYUSATSU , SC_CURSE );
  700. set_sc( KO_ZENKAI , SC_ZENKAI , SI_ZENKAI , SCB_NONE );
  701. set_sc( KO_IZAYOI , SC_IZAYOI , SI_IZAYOI , SCB_MATK );
  702. set_sc( KG_KYOMU , SC_KYOMU , SI_KYOMU , SCB_NONE );
  703. set_sc( KG_KAGEMUSYA , SC_KAGEMUSYA , SI_KAGEMUSYA , SCB_NONE );
  704. set_sc( KG_KAGEHUMI , SC_KAGEHUMI , SI_KG_KAGEHUMI , SCB_NONE );
  705. set_sc( OB_ZANGETSU , SC_ZANGETSU , SI_ZANGETSU , SCB_MATK|SCB_BATK );
  706. set_sc_with_vfx( OB_AKAITSUKI , SC_AKAITSUKI , SI_AKAITSUKI , SCB_NONE );
  707. set_sc( OB_OBOROGENSOU , SC_GENSOU , SI_GENSOU , SCB_NONE );
  708. // Storing the target job rather than simply SC_SPIRIT simplifies code later on.
  709. SkillStatusChangeTable[SL_ALCHEMIST] = (sc_type)MAPID_ALCHEMIST,
  710. SkillStatusChangeTable[SL_MONK] = (sc_type)MAPID_MONK,
  711. SkillStatusChangeTable[SL_STAR] = (sc_type)MAPID_STAR_GLADIATOR,
  712. SkillStatusChangeTable[SL_SAGE] = (sc_type)MAPID_SAGE,
  713. SkillStatusChangeTable[SL_CRUSADER] = (sc_type)MAPID_CRUSADER,
  714. SkillStatusChangeTable[SL_SUPERNOVICE] = (sc_type)MAPID_SUPER_NOVICE,
  715. SkillStatusChangeTable[SL_KNIGHT] = (sc_type)MAPID_KNIGHT,
  716. SkillStatusChangeTable[SL_WIZARD] = (sc_type)MAPID_WIZARD,
  717. SkillStatusChangeTable[SL_PRIEST] = (sc_type)MAPID_PRIEST,
  718. SkillStatusChangeTable[SL_BARDDANCER] = (sc_type)MAPID_BARDDANCER,
  719. SkillStatusChangeTable[SL_ROGUE] = (sc_type)MAPID_ROGUE,
  720. SkillStatusChangeTable[SL_ASSASIN] = (sc_type)MAPID_ASSASSIN,
  721. SkillStatusChangeTable[SL_BLACKSMITH] = (sc_type)MAPID_BLACKSMITH,
  722. SkillStatusChangeTable[SL_HUNTER] = (sc_type)MAPID_HUNTER,
  723. SkillStatusChangeTable[SL_SOULLINKER] = (sc_type)MAPID_SOUL_LINKER,
  724. //Status that don't have a skill associated.
  725. StatusIconChangeTable[SC_WEIGHT50] = SI_WEIGHT50;
  726. StatusIconChangeTable[SC_WEIGHT90] = SI_WEIGHT90;
  727. StatusIconChangeTable[SC_ASPDPOTION0] = SI_ASPDPOTION0;
  728. StatusIconChangeTable[SC_ASPDPOTION1] = SI_ASPDPOTION1;
  729. StatusIconChangeTable[SC_ASPDPOTION2] = SI_ASPDPOTION2;
  730. StatusIconChangeTable[SC_ASPDPOTION3] = SI_ASPDPOTIONINFINITY;
  731. StatusIconChangeTable[SC_SPEEDUP0] = SI_MOVHASTE_HORSE;
  732. StatusIconChangeTable[SC_SPEEDUP1] = SI_SPEEDPOTION1;
  733. StatusIconChangeTable[SC_INCSTR] = SI_INCSTR;
  734. StatusIconChangeTable[SC_MIRACLE] = SI_SPIRIT;
  735. StatusIconChangeTable[SC_INTRAVISION] = SI_INTRAVISION;
  736. StatusIconChangeTable[SC_STRFOOD] = SI_FOODSTR;
  737. StatusIconChangeTable[SC_AGIFOOD] = SI_FOODAGI;
  738. StatusIconChangeTable[SC_VITFOOD] = SI_FOODVIT;
  739. StatusIconChangeTable[SC_INTFOOD] = SI_FOODINT;
  740. StatusIconChangeTable[SC_DEXFOOD] = SI_FOODDEX;
  741. StatusIconChangeTable[SC_LUKFOOD] = SI_FOODLUK;
  742. StatusIconChangeTable[SC_FLEEFOOD]= SI_FOODFLEE;
  743. StatusIconChangeTable[SC_HITFOOD] = SI_FOODHIT;
  744. StatusIconChangeTable[SC_MANU_ATK] = SI_MANU_ATK;
  745. StatusIconChangeTable[SC_MANU_DEF] = SI_MANU_DEF;
  746. StatusIconChangeTable[SC_SPL_ATK] = SI_SPL_ATK;
  747. StatusIconChangeTable[SC_SPL_DEF] = SI_SPL_DEF;
  748. StatusIconChangeTable[SC_MANU_MATK] = SI_MANU_MATK;
  749. StatusIconChangeTable[SC_SPL_MATK] = SI_SPL_MATK;
  750. StatusIconChangeTable[SC_ATKPOTION] = SI_PLUSATTACKPOWER;
  751. StatusIconChangeTable[SC_MATKPOTION] = SI_PLUSMAGICPOWER;
  752. //Cash Items
  753. StatusIconChangeTable[SC_FOOD_STR_CASH] = SI_FOOD_STR_CASH;
  754. StatusIconChangeTable[SC_FOOD_AGI_CASH] = SI_FOOD_AGI_CASH;
  755. StatusIconChangeTable[SC_FOOD_VIT_CASH] = SI_FOOD_VIT_CASH;
  756. StatusIconChangeTable[SC_FOOD_DEX_CASH] = SI_FOOD_DEX_CASH;
  757. StatusIconChangeTable[SC_FOOD_INT_CASH] = SI_FOOD_INT_CASH;
  758. StatusIconChangeTable[SC_FOOD_LUK_CASH] = SI_FOOD_LUK_CASH;
  759. StatusIconChangeTable[SC_EXPBOOST] = SI_EXPBOOST;
  760. StatusIconChangeTable[SC_ITEMBOOST] = SI_ITEMBOOST;
  761. StatusIconChangeTable[SC_JEXPBOOST] = SI_CASH_PLUSONLYJOBEXP;
  762. StatusIconChangeTable[SC_LIFEINSURANCE] = SI_LIFEINSURANCE;
  763. StatusIconChangeTable[SC_BOSSMAPINFO] = SI_BOSSMAPINFO;
  764. StatusIconChangeTable[SC_DEF_RATE] = SI_DEF_RATE;
  765. StatusIconChangeTable[SC_MDEF_RATE] = SI_MDEF_RATE;
  766. StatusIconChangeTable[SC_INCCRI] = SI_INCCRI;
  767. StatusIconChangeTable[SC_INCFLEE2] = SI_PLUSAVOIDVALUE;
  768. StatusIconChangeTable[SC_INCHEALRATE] = SI_INCHEALRATE;
  769. StatusIconChangeTable[SC_S_LIFEPOTION] = SI_S_LIFEPOTION;
  770. StatusIconChangeTable[SC_L_LIFEPOTION] = SI_L_LIFEPOTION;
  771. StatusIconChangeTable[SC_SPCOST_RATE] = SI_ATKER_BLOOD;
  772. StatusIconChangeTable[SC_COMMONSC_RESIST] = SI_TARGET_BLOOD;
  773. // Mercenary Bonus Effects
  774. StatusIconChangeTable[SC_MERC_FLEEUP] = SI_MERC_FLEEUP;
  775. StatusIconChangeTable[SC_MERC_ATKUP] = SI_MERC_ATKUP;
  776. StatusIconChangeTable[SC_MERC_HPUP] = SI_MERC_HPUP;
  777. StatusIconChangeTable[SC_MERC_SPUP] = SI_MERC_SPUP;
  778. StatusIconChangeTable[SC_MERC_HITUP] = SI_MERC_HITUP;
  779. // Warlock Spheres
  780. StatusIconChangeTable[SC_SPHERE_1] = SI_SPHERE_1;
  781. StatusIconChangeTable[SC_SPHERE_2] = SI_SPHERE_2;
  782. StatusIconChangeTable[SC_SPHERE_3] = SI_SPHERE_3;
  783. StatusIconChangeTable[SC_SPHERE_4] = SI_SPHERE_4;
  784. StatusIconChangeTable[SC_SPHERE_5] = SI_SPHERE_5;
  785. // Warlock Preserved spells
  786. StatusIconChangeTable[SC_SPELLBOOK1] = SI_SPELLBOOK1;
  787. StatusIconChangeTable[SC_SPELLBOOK2] = SI_SPELLBOOK2;
  788. StatusIconChangeTable[SC_SPELLBOOK3] = SI_SPELLBOOK3;
  789. StatusIconChangeTable[SC_SPELLBOOK4] = SI_SPELLBOOK4;
  790. StatusIconChangeTable[SC_SPELLBOOK5] = SI_SPELLBOOK5;
  791. StatusIconChangeTable[SC_SPELLBOOK6] = SI_SPELLBOOK6;
  792. StatusIconChangeTable[SC_MAXSPELLBOOK] = SI_SPELLBOOK7;
  793. StatusIconChangeTable[SC_NEUTRALBARRIER_MASTER] = SI_NEUTRALBARRIER_MASTER;
  794. StatusIconChangeTable[SC_STEALTHFIELD_MASTER] = SI_STEALTHFIELD_MASTER;
  795. StatusIconChangeTable[SC_OVERHEAT] = SI_OVERHEAT;
  796. StatusIconChangeTable[SC_OVERHEAT_LIMITPOINT] = SI_OVERHEAT_LIMITPOINT;
  797. StatusIconChangeTable[SC_HALLUCINATIONWALK_POSTDELAY] = SI_HALLUCINATIONWALK_POSTDELAY;
  798. StatusIconChangeTable[SC_TOXIN] = SI_TOXIN;
  799. StatusIconChangeTable[SC_PARALYSE] = SI_PARALYSE;
  800. StatusIconChangeTable[SC_VENOMBLEED] = SI_VENOMBLEED;
  801. StatusIconChangeTable[SC_MAGICMUSHROOM] = SI_MAGICMUSHROOM;
  802. StatusIconChangeTable[SC_DEATHHURT] = SI_DEATHHURT;
  803. StatusIconChangeTable[SC_PYREXIA] = SI_PYREXIA;
  804. StatusIconChangeTable[SC_OBLIVIONCURSE] = SI_OBLIVIONCURSE;
  805. StatusIconChangeTable[SC_LEECHESEND] = SI_LEECHESEND;
  806. StatusIconChangeTable[SC_SHIELDSPELL_DEF] = SI_SHIELDSPELL_DEF;
  807. StatusIconChangeTable[SC_SHIELDSPELL_MDEF] = SI_SHIELDSPELL_MDEF;
  808. StatusIconChangeTable[SC_SHIELDSPELL_REF] = SI_SHIELDSPELL_REF;
  809. StatusIconChangeTable[SC_BANDING_DEFENCE] = SI_BANDING_DEFENCE;
  810. StatusIconChangeTable[SC_GLOOMYDAY_SK] = SI_GLOOMYDAY;
  811. StatusIconChangeTable[SC_CURSEDCIRCLE_ATKER] = SI_CURSEDCIRCLE_ATKER;
  812. StatusIconChangeTable[SC_STOMACHACHE] = SI_STOMACHACHE;
  813. StatusIconChangeTable[SC_MYSTERIOUS_POWDER] = SI_MYSTERIOUS_POWDER;
  814. StatusIconChangeTable[SC_MELON_BOMB] = SI_MELON_BOMB;
  815. StatusIconChangeTable[SC_BANANA_BOMB] = SI_BANANA_BOMB;
  816. StatusIconChangeTable[SC_BANANA_BOMB_SITDOWN] = SI_BANANA_BOMB_SITDOWN_POSTDELAY;
  817. //Genetics New Food Items Status Icons
  818. StatusIconChangeTable[SC_SAVAGE_STEAK] = SI_SAVAGE_STEAK;
  819. StatusIconChangeTable[SC_COCKTAIL_WARG_BLOOD] = SI_COCKTAIL_WARG_BLOOD;
  820. StatusIconChangeTable[SC_MINOR_BBQ] = SI_MINOR_BBQ;
  821. StatusIconChangeTable[SC_SIROMA_ICE_TEA] = SI_SIROMA_ICE_TEA;
  822. StatusIconChangeTable[SC_DROCERA_HERB_STEAMED] = SI_DROCERA_HERB_STEAMED;
  823. StatusIconChangeTable[SC_PUTTI_TAILS_NOODLES] = SI_PUTTI_TAILS_NOODLES;
  824. StatusIconChangeTable[SC_BOOST500] |= SI_BOOST500;
  825. StatusIconChangeTable[SC_FULL_SWING_K] |= SI_FULL_SWING_K;
  826. StatusIconChangeTable[SC_MANA_PLUS] |= SI_MANA_PLUS;
  827. StatusIconChangeTable[SC_MUSTLE_M] |= SI_MUSTLE_M;
  828. StatusIconChangeTable[SC_LIFE_FORCE_F] |= SI_LIFE_FORCE_F;
  829. StatusIconChangeTable[SC_EXTRACT_WHITE_POTION_Z] |= SI_EXTRACT_WHITE_POTION_Z;
  830. StatusIconChangeTable[SC_VITATA_500] |= SI_VITATA_500;
  831. StatusIconChangeTable[SC_EXTRACT_SALAMINE_JUICE] |= SI_EXTRACT_SALAMINE_JUICE;
  832. // Elemental Spirit's 'side' status change icons.
  833. StatusIconChangeTable[SC_CIRCLE_OF_FIRE] = SI_CIRCLE_OF_FIRE;
  834. StatusIconChangeTable[SC_FIRE_CLOAK] = SI_FIRE_CLOAK;
  835. StatusIconChangeTable[SC_WATER_SCREEN] = SI_WATER_SCREEN;
  836. StatusIconChangeTable[SC_WATER_DROP] = SI_WATER_DROP;
  837. StatusIconChangeTable[SC_WIND_STEP] = SI_WIND_STEP;
  838. StatusIconChangeTable[SC_WIND_CURTAIN] = SI_WIND_CURTAIN;
  839. StatusIconChangeTable[SC_SOLID_SKIN] = SI_SOLID_SKIN;
  840. StatusIconChangeTable[SC_STONE_SHIELD] = SI_STONE_SHIELD;
  841. StatusIconChangeTable[SC_PYROTECHNIC] = SI_PYROTECHNIC;
  842. StatusIconChangeTable[SC_HEATER] = SI_HEATER;
  843. StatusIconChangeTable[SC_TROPIC] = SI_TROPIC;
  844. StatusIconChangeTable[SC_AQUAPLAY] = SI_AQUAPLAY;
  845. StatusIconChangeTable[SC_COOLER] = SI_COOLER;
  846. StatusIconChangeTable[SC_CHILLY_AIR] = SI_CHILLY_AIR;
  847. StatusIconChangeTable[SC_GUST] = SI_GUST;
  848. StatusIconChangeTable[SC_BLAST] = SI_BLAST;
  849. StatusIconChangeTable[SC_WILD_STORM] = SI_WILD_STORM;
  850. StatusIconChangeTable[SC_PETROLOGY] = SI_PETROLOGY;
  851. StatusIconChangeTable[SC_CURSED_SOIL] = SI_CURSED_SOIL;
  852. StatusIconChangeTable[SC_UPHEAVAL] = SI_UPHEAVAL;
  853. StatusIconChangeTable[SC_PUSH_CART] = SI_ON_PUSH_CART;
  854. //Other SC which are not necessarily associated to skills.
  855. StatusChangeFlagTable[SC_ASPDPOTION0] = SCB_ASPD;
  856. StatusChangeFlagTable[SC_ASPDPOTION1] = SCB_ASPD;
  857. StatusChangeFlagTable[SC_ASPDPOTION2] = SCB_ASPD;
  858. StatusChangeFlagTable[SC_ASPDPOTION3] = SCB_ASPD;
  859. StatusChangeFlagTable[SC_SPEEDUP0] = SCB_SPEED;
  860. StatusChangeFlagTable[SC_SPEEDUP1] = SCB_SPEED;
  861. StatusChangeFlagTable[SC_ATKPOTION] = SCB_BATK;
  862. StatusChangeFlagTable[SC_MATKPOTION] = SCB_MATK;
  863. StatusChangeFlagTable[SC_INCALLSTATUS] |= SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK;
  864. StatusChangeFlagTable[SC_INCSTR] |= SCB_STR;
  865. StatusChangeFlagTable[SC_INCAGI] |= SCB_AGI;
  866. StatusChangeFlagTable[SC_INCVIT] |= SCB_VIT;
  867. StatusChangeFlagTable[SC_INCINT] |= SCB_INT;
  868. StatusChangeFlagTable[SC_INCDEX] |= SCB_DEX;
  869. StatusChangeFlagTable[SC_INCLUK] |= SCB_LUK;
  870. StatusChangeFlagTable[SC_INCHIT] |= SCB_HIT;
  871. StatusChangeFlagTable[SC_INCHITRATE] |= SCB_HIT;
  872. StatusChangeFlagTable[SC_INCFLEE] |= SCB_FLEE;
  873. StatusChangeFlagTable[SC_INCFLEERATE] |= SCB_FLEE;
  874. StatusChangeFlagTable[SC_INCCRI] |= SCB_CRI;
  875. StatusChangeFlagTable[SC_INCASPDRATE] |= SCB_ASPD;
  876. StatusChangeFlagTable[SC_INCFLEE2] |= SCB_FLEE2;
  877. StatusChangeFlagTable[SC_INCMHPRATE] |= SCB_MAXHP;
  878. StatusChangeFlagTable[SC_INCMSPRATE] |= SCB_MAXSP;
  879. StatusChangeFlagTable[SC_INCMHP] |= SCB_MAXHP;
  880. StatusChangeFlagTable[SC_INCMSP] |= SCB_MAXSP;
  881. StatusChangeFlagTable[SC_INCATKRATE] |= SCB_BATK|SCB_WATK;
  882. StatusChangeFlagTable[SC_INCMATKRATE] |= SCB_MATK;
  883. StatusChangeFlagTable[SC_INCDEFRATE] |= SCB_DEF;
  884. StatusChangeFlagTable[SC_STRFOOD] |= SCB_STR;
  885. StatusChangeFlagTable[SC_AGIFOOD] |= SCB_AGI;
  886. StatusChangeFlagTable[SC_VITFOOD] |= SCB_VIT;
  887. StatusChangeFlagTable[SC_INTFOOD] |= SCB_INT;
  888. StatusChangeFlagTable[SC_DEXFOOD] |= SCB_DEX;
  889. StatusChangeFlagTable[SC_LUKFOOD] |= SCB_LUK;
  890. StatusChangeFlagTable[SC_HITFOOD] |= SCB_HIT;
  891. StatusChangeFlagTable[SC_FLEEFOOD] |= SCB_FLEE;
  892. StatusChangeFlagTable[SC_BATKFOOD] |= SCB_BATK;
  893. StatusChangeFlagTable[SC_WATKFOOD] |= SCB_WATK;
  894. StatusChangeFlagTable[SC_MATKFOOD] |= SCB_MATK;
  895. StatusChangeFlagTable[SC_ARMOR_ELEMENT] |= SCB_ALL;
  896. StatusChangeFlagTable[SC_ARMOR_RESIST] |= SCB_ALL;
  897. StatusChangeFlagTable[SC_SPCOST_RATE] |= SCB_ALL;
  898. StatusChangeFlagTable[SC_WALKSPEED] |= SCB_SPEED;
  899. StatusChangeFlagTable[SC_ITEMSCRIPT] |= SCB_ALL;
  900. // Cash Items
  901. StatusChangeFlagTable[SC_FOOD_STR_CASH] = SCB_STR;
  902. StatusChangeFlagTable[SC_FOOD_AGI_CASH] = SCB_AGI;
  903. StatusChangeFlagTable[SC_FOOD_VIT_CASH] = SCB_VIT;
  904. StatusChangeFlagTable[SC_FOOD_DEX_CASH] = SCB_DEX;
  905. StatusChangeFlagTable[SC_FOOD_INT_CASH] = SCB_INT;
  906. StatusChangeFlagTable[SC_FOOD_LUK_CASH] = SCB_LUK;
  907. // Mercenary Bonus Effects
  908. StatusChangeFlagTable[SC_MERC_FLEEUP] |= SCB_FLEE;
  909. StatusChangeFlagTable[SC_MERC_ATKUP] |= SCB_WATK;
  910. StatusChangeFlagTable[SC_MERC_HPUP] |= SCB_MAXHP;
  911. StatusChangeFlagTable[SC_MERC_SPUP] |= SCB_MAXSP;
  912. StatusChangeFlagTable[SC_MERC_HITUP] |= SCB_HIT;
  913. // Guillotine Cross Poison Effects
  914. StatusChangeFlagTable[SC_PARALYSE] |= SCB_ASPD|SCB_FLEE|SCB_SPEED;
  915. StatusChangeFlagTable[SC_DEATHHURT] |= SCB_REGEN;
  916. StatusChangeFlagTable[SC_VENOMBLEED] |= SCB_MAXHP;
  917. StatusChangeFlagTable[SC_OBLIVIONCURSE] |= SCB_REGEN;
  918. StatusChangeFlagTable[SC_SAVAGE_STEAK] |= SCB_STR;
  919. StatusChangeFlagTable[SC_COCKTAIL_WARG_BLOOD] |= SCB_INT;
  920. StatusChangeFlagTable[SC_MINOR_BBQ] |= SCB_VIT;
  921. StatusChangeFlagTable[SC_SIROMA_ICE_TEA] |= SCB_DEX;
  922. StatusChangeFlagTable[SC_DROCERA_HERB_STEAMED] |= SCB_AGI;
  923. StatusChangeFlagTable[SC_PUTTI_TAILS_NOODLES] |= SCB_LUK;
  924. StatusChangeFlagTable[SC_BOOST500] |= SCB_ASPD;
  925. StatusChangeFlagTable[SC_FULL_SWING_K] |= SCB_BATK;
  926. StatusChangeFlagTable[SC_MANA_PLUS] |= SCB_MATK;
  927. StatusChangeFlagTable[SC_MUSTLE_M] |= SCB_MAXHP;
  928. StatusChangeFlagTable[SC_LIFE_FORCE_F] |= SCB_MAXSP;
  929. StatusChangeFlagTable[SC_EXTRACT_WHITE_POTION_Z] |= SCB_REGEN;
  930. StatusChangeFlagTable[SC_VITATA_500] |= SCB_REGEN;
  931. StatusChangeFlagTable[SC_EXTRACT_SALAMINE_JUICE] |= SCB_ASPD;
  932. #ifdef RENEWAL_EDP
  933. // renewal EDP increases your weapon atk
  934. StatusChangeFlagTable[SC_EDP] |= SCB_WATK;
  935. #endif
  936. if( !battle_config.display_hallucination ) //Disable Hallucination.
  937. StatusIconChangeTable[SC_HALLUCINATION] = SI_BLANK;
  938. /* StatusChangeState (SCS_) NOMOVE */
  939. StatusChangeStateTable[SC_ANKLE] |= SCS_NOMOVE;
  940. StatusChangeStateTable[SC_AUTOCOUNTER] |= SCS_NOMOVE;
  941. StatusChangeStateTable[SC_TRICKDEAD] |= SCS_NOMOVE;
  942. StatusChangeStateTable[SC_BLADESTOP] |= SCS_NOMOVE;
  943. StatusChangeStateTable[SC_BLADESTOP_WAIT] |= SCS_NOMOVE;
  944. StatusChangeStateTable[SC_GOSPEL] |= SCS_NOMOVE|SCS_NOMOVECOND;
  945. StatusChangeStateTable[SC_BASILICA] |= SCS_NOMOVE|SCS_NOMOVECOND;
  946. StatusChangeStateTable[SC_STOP] |= SCS_NOMOVE;
  947. StatusChangeStateTable[SC_CLOSECONFINE] |= SCS_NOMOVE;
  948. StatusChangeStateTable[SC_CLOSECONFINE2] |= SCS_NOMOVE;
  949. StatusChangeStateTable[SC_MADNESSCANCEL] |= SCS_NOMOVE;
  950. StatusChangeStateTable[SC_GRAVITATION] |= SCS_NOMOVE|SCS_NOMOVECOND;
  951. StatusChangeStateTable[SC_WHITEIMPRISON] |= SCS_NOMOVE;
  952. StatusChangeStateTable[SC_ELECTRICSHOCKER] |= SCS_NOMOVE;
  953. StatusChangeStateTable[SC_BITE] |= SCS_NOMOVE;
  954. StatusChangeStateTable[SC_THORNSTRAP] |= SCS_NOMOVE;
  955. StatusChangeStateTable[SC_MAGNETICFIELD] |= SCS_NOMOVE;
  956. StatusChangeStateTable[SC__MANHOLE] |= SCS_NOMOVE;
  957. StatusChangeStateTable[SC_CURSEDCIRCLE_ATKER] |= SCS_NOMOVE;
  958. StatusChangeStateTable[SC_CURSEDCIRCLE_TARGET] |= SCS_NOMOVE;
  959. StatusChangeStateTable[SC_CRYSTALIZE] |= SCS_NOMOVE|SCS_NOMOVECOND;
  960. StatusChangeStateTable[SC_NETHERWORLD] |= SCS_NOMOVE;
  961. StatusChangeStateTable[SC_CAMOUFLAGE] |= SCS_NOMOVE|SCS_NOMOVECOND;
  962. StatusChangeStateTable[SC_MEIKYOUSISUI] |= SCS_NOMOVE;
  963. StatusChangeStateTable[SC_KAGEHUMI] |= SCS_NOMOVE;
  964. StatusChangeStateTable[SC_KYOUGAKU] |= SCS_NOMOVE;
  965. /* StatusChangeState (SCS_) NOPICKUPITEMS */
  966. StatusChangeStateTable[SC_HIDING] |= SCS_NOPICKITEM;
  967. StatusChangeStateTable[SC_CLOAKING] |= SCS_NOPICKITEM;
  968. StatusChangeStateTable[SC_TRICKDEAD] |= SCS_NOPICKITEM;
  969. StatusChangeStateTable[SC_BLADESTOP] |= SCS_NOPICKITEM;
  970. StatusChangeStateTable[SC_CLOAKINGEXCEED] |= SCS_NOPICKITEM;
  971. StatusChangeStateTable[SC_NOCHAT] |= SCS_NOPICKITEM|SCS_NOPICKITEMCOND;
  972. /* StatusChangeState (SCS_) NODROPITEMS */
  973. StatusChangeStateTable[SC_AUTOCOUNTER] |= SCS_NODROPITEM;
  974. StatusChangeStateTable[SC_BLADESTOP] |= SCS_NODROPITEM;
  975. StatusChangeStateTable[SC_NOCHAT] |= SCS_NODROPITEM|SCS_NODROPITEMCOND;
  976. /* StatusChangeState (SCS_) NOCAST (skills) */
  977. StatusChangeStateTable[SC_SILENCE] |= SCS_NOCAST;
  978. StatusChangeStateTable[SC_STEELBODY] |= SCS_NOCAST;
  979. StatusChangeStateTable[SC_BERSERK] |= SCS_NOCAST;
  980. StatusChangeStateTable[SC__BLOODYLUST] |= SCS_NOCAST;
  981. StatusChangeStateTable[SC_OBLIVIONCURSE] |= SCS_NOCAST;
  982. StatusChangeStateTable[SC_WHITEIMPRISON] |= SCS_NOCAST;
  983. StatusChangeStateTable[SC__INVISIBILITY] |= SCS_NOCAST;
  984. StatusChangeStateTable[SC_CRYSTALIZE] |= SCS_NOCAST|SCS_NOCASTCOND;
  985. StatusChangeStateTable[SC__IGNORANCE] |= SCS_NOCAST;
  986. StatusChangeStateTable[SC_DEEPSLEEP] |= SCS_NOCAST;
  987. StatusChangeStateTable[SC_SATURDAYNIGHTFEVER] |= SCS_NOCAST;
  988. StatusChangeStateTable[SC_CURSEDCIRCLE_TARGET] |= SCS_NOCAST;
  989. StatusChangeStateTable[SC_SILENCE] |= SCS_NOCAST;
  990. //Homon S
  991. StatusChangeStateTable[SC_PARALYSIS] |= SCS_NOMOVE;
  992. }
  993. static void initDummyData(void)
  994. {
  995. memset(&dummy_status, 0, sizeof(dummy_status));
  996. dummy_status.hp =
  997. dummy_status.max_hp =
  998. dummy_status.max_sp =
  999. dummy_status.str =
  1000. dummy_status.agi =
  1001. dummy_status.vit =
  1002. dummy_status.int_ =
  1003. dummy_status.dex =
  1004. dummy_status.luk =
  1005. dummy_status.hit = 1;
  1006. dummy_status.speed = 2000;
  1007. dummy_status.adelay = 4000;
  1008. dummy_status.amotion = 2000;
  1009. dummy_status.dmotion = 2000;
  1010. dummy_status.ele_lv = 1; //Min elemental level.
  1011. dummy_status.mode = MD_CANMOVE;
  1012. }
  1013. //For copying a status_data structure from b to a, without overwriting current Hp and Sp
  1014. static inline void status_cpy(struct status_data* a, const struct status_data* b)
  1015. {
  1016. memcpy((void*)&a->max_hp, (const void*)&b->max_hp, sizeof(struct status_data)-(sizeof(a->hp)+sizeof(a->sp)));
  1017. }
  1018. //Sets HP to given value. Flag is the flag passed to status_heal in case
  1019. //final value is higher than current (use 2 to make a healing effect display
  1020. //on players) It will always succeed (overrides Berserk block), but it can't kill.
  1021. int status_set_hp(struct block_list *bl, unsigned int hp, int flag)
  1022. {
  1023. struct status_data *status;
  1024. if (hp < 1) return 0;
  1025. status = status_get_status_data(bl);
  1026. if (status == &dummy_status)
  1027. return 0;
  1028. if (hp > status->max_hp) hp = status->max_hp;
  1029. if (hp == status->hp) return 0;
  1030. if (hp > status->hp)
  1031. return status_heal(bl, hp - status->hp, 0, 1|flag);
  1032. return status_zap(bl, status->hp - hp, 0);
  1033. }
  1034. //Sets SP to given value. Flag is the flag passed to status_heal in case
  1035. //final value is higher than current (use 2 to make a healing effect display
  1036. //on players)
  1037. int status_set_sp(struct block_list *bl, unsigned int sp, int flag)
  1038. {
  1039. struct status_data *status;
  1040. status = status_get_status_data(bl);
  1041. if (status == &dummy_status)
  1042. return 0;
  1043. if (sp > status->max_sp) sp = status->max_sp;
  1044. if (sp == status->sp) return 0;
  1045. if (sp > status->sp)
  1046. return status_heal(bl, 0, sp - status->sp, 1|flag);
  1047. return status_zap(bl, 0, status->sp - sp);
  1048. }
  1049. int status_charge(struct block_list* bl, int hp, int sp)
  1050. {
  1051. if(!(bl->type&BL_CONSUME))
  1052. return hp+sp; //Assume all was charged so there are no 'not enough' fails.
  1053. return status_damage(NULL, bl, hp, sp, 0, 3);
  1054. }
  1055. //Inflicts damage on the target with the according walkdelay.
  1056. //If flag&1, damage is passive and does not triggers cancelling status changes.
  1057. //If flag&2, fail if target does not has enough to substract.
  1058. //If flag&4, if killed, mob must not give exp/loot.
  1059. //flag will be set to &8 when damaging sp of a dead character
  1060. int status_damage(struct block_list *src,struct block_list *target,int hp, int sp, int walkdelay, int flag)
  1061. {
  1062. struct status_data *status;
  1063. struct status_change *sc;
  1064. if(sp && !(target->type&BL_CONSUME))
  1065. sp = 0; //Not a valid SP target.
  1066. if (hp < 0) { //Assume absorbed damage.
  1067. status_heal(target, -hp, 0, 1);
  1068. hp = 0;
  1069. }
  1070. if (sp < 0) {
  1071. status_heal(target, 0, -sp, 1);
  1072. sp = 0;
  1073. }
  1074. if (target->type == BL_SKILL)
  1075. return skill_unit_ondamaged((struct skill_unit *)target, src, hp, gettick());
  1076. status = status_get_status_data(target);
  1077. if( status == &dummy_status )
  1078. return 0;
  1079. if ((unsigned int)hp >= status->hp) {
  1080. if (flag&2) return 0;
  1081. hp = status->hp;
  1082. }
  1083. if ((unsigned int)sp > status->sp) {
  1084. if (flag&2) return 0;
  1085. sp = status->sp;
  1086. }
  1087. if (!hp && !sp)
  1088. return 0;
  1089. if( !status->hp )
  1090. flag |= 8;
  1091. // Let through. battle.c/skill.c have the whole logic of when it's possible or
  1092. // not to hurt someone (and this check breaks pet catching) [Skotlex]
  1093. // if (!target->prev && !(flag&2))
  1094. // return 0; //Cannot damage a bl not on a map, except when "charging" hp/sp
  1095. sc = status_get_sc(target);
  1096. if( hp && battle_config.invincible_nodamage && src && sc && sc->data[SC_INVINCIBLE] && !sc->data[SC_INVINCIBLEOFF] )
  1097. hp = 1;
  1098. if( hp && !(flag&1) ) {
  1099. if( sc ) {
  1100. struct status_change_entry *sce;
  1101. if (sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
  1102. status_change_end(target, SC_STONE, INVALID_TIMER);
  1103. status_change_end(target, SC_FREEZE, INVALID_TIMER);
  1104. status_change_end(target, SC_SLEEP, INVALID_TIMER);
  1105. status_change_end(target, SC_WINKCHARM, INVALID_TIMER);
  1106. status_change_end(target, SC_CONFUSION, INVALID_TIMER);
  1107. status_change_end(target, SC_TRICKDEAD, INVALID_TIMER);
  1108. status_change_end(target, SC_HIDING, INVALID_TIMER);
  1109. status_change_end(target, SC_CLOAKING, INVALID_TIMER);
  1110. status_change_end(target, SC_CHASEWALK, INVALID_TIMER);
  1111. status_change_end(target, SC_CAMOUFLAGE, INVALID_TIMER);
  1112. status_change_end(target, SC__INVISIBILITY, INVALID_TIMER);
  1113. status_change_end(target, SC_DEEPSLEEP, INVALID_TIMER);
  1114. if ((sce=sc->data[SC_ENDURE]) && !sce->val4) {
  1115. //Endure count is only reduced by non-players on non-gvg maps.
  1116. //val4 signals infinite endure. [Skotlex]
  1117. if (src && src->type != BL_PC && !map_flag_gvg(target->m) && !map[target->m].flag.battleground && --(sce->val2) < 0)
  1118. status_change_end(target, SC_ENDURE, INVALID_TIMER);
  1119. }
  1120. if ((sce=sc->data[SC_GRAVITATION]) && sce->val3 == BCT_SELF) {
  1121. struct skill_unit_group* sg = skill_id2group(sce->val4);
  1122. if (sg) {
  1123. skill_delunitgroup(sg);
  1124. sce->val4 = 0;
  1125. status_change_end(target, SC_GRAVITATION, INVALID_TIMER);
  1126. }
  1127. }
  1128. if(sc->data[SC_DANCING] && (unsigned int)hp > status->max_hp>>2)
  1129. status_change_end(target, SC_DANCING, INVALID_TIMER);
  1130. if(sc->data[SC_CLOAKINGEXCEED] && --(sc->data[SC_CLOAKINGEXCEED]->val2) <= 0)
  1131. status_change_end(target, SC_CLOAKINGEXCEED, INVALID_TIMER);
  1132. if(sc->data[SC_KAGEMUSYA] && --(sc->data[SC_KAGEMUSYA]->val3) <= 0)
  1133. status_change_end(target, SC_KAGEMUSYA, INVALID_TIMER);
  1134. }
  1135. unit_skillcastcancel(target, 2);
  1136. }
  1137. status->hp-= hp;
  1138. status->sp-= sp;
  1139. if (sc && hp && status->hp) {
  1140. if (sc->data[SC_AUTOBERSERK] &&
  1141. (!sc->data[SC_PROVOKE] || !sc->data[SC_PROVOKE]->val2) &&
  1142. status->hp < status->max_hp>>2)
  1143. sc_start4(target,SC_PROVOKE,100,10,1,0,0,0);
  1144. if (sc->data[SC_BERSERK] && status->hp <= 100)
  1145. status_change_end(target, SC_BERSERK, INVALID_TIMER);
  1146. if( sc->data[SC_RAISINGDRAGON] && status->hp <= 1000 )
  1147. status_change_end(target, SC_RAISINGDRAGON, INVALID_TIMER);
  1148. if (sc->data[SC_SATURDAYNIGHTFEVER] && status->hp <= 100)
  1149. status_change_end(target, SC_SATURDAYNIGHTFEVER, INVALID_TIMER);
  1150. if (sc->data[SC__BLOODYLUST] && status->hp <= 100)
  1151. status_change_end(target, SC__BLOODYLUST, INVALID_TIMER);
  1152. }
  1153. switch (target->type) {
  1154. case BL_PC: pc_damage((TBL_PC*)target,src,hp,sp); break;
  1155. case BL_MOB: mob_damage((TBL_MOB*)target, src, hp); break;
  1156. case BL_HOM: merc_damage((TBL_HOM*)target); break;
  1157. case BL_MER: mercenary_heal((TBL_MER*)target,hp,sp); break;
  1158. case BL_ELEM: elemental_heal((TBL_ELEM*)target,hp,sp); break;
  1159. }
  1160. if( src && target->type == BL_PC && ((TBL_PC*)target)->disguise ) {// stop walking when attacked in disguise to prevent walk-delay bug
  1161. unit_stop_walking( target, 1 );
  1162. }
  1163. if( status->hp || (flag&8) )
  1164. { //Still lives or has been dead before this damage.
  1165. if (walkdelay)
  1166. unit_set_walkdelay(target, gettick(), walkdelay, 0);
  1167. return hp+sp;
  1168. }
  1169. status->hp = 1; //To let the dead function cast skills and all that.
  1170. //NOTE: These dead functions should return: [Skotlex]
  1171. //0: Death cancelled, auto-revived.
  1172. //Non-zero: Standard death. Clear status, cancel move/attack, etc
  1173. //&2: Also remove object from map.
  1174. //&4: Also delete object from memory.
  1175. switch (target->type) {
  1176. case BL_PC: flag = pc_dead((TBL_PC*)target,src); break;
  1177. case BL_MOB: flag = mob_dead((TBL_MOB*)target, src, flag&4?3:0); break;
  1178. case BL_HOM: flag = merc_hom_dead((TBL_HOM*)target); break;
  1179. case BL_MER: flag = mercenary_dead((TBL_MER*)target); break;
  1180. case BL_ELEM: flag = elemental_dead((TBL_ELEM*)target); break;
  1181. default: //Unhandled case, do nothing to object.
  1182. flag = 0;
  1183. break;
  1184. }
  1185. if(!flag) //Death cancelled.
  1186. return hp+sp;
  1187. //Normal death
  1188. status->hp = 0;
  1189. if (battle_config.clear_unit_ondeath &&
  1190. battle_config.clear_unit_ondeath&target->type)
  1191. skill_clear_unitgroup(target);
  1192. if(target->type&BL_REGEN)
  1193. { //Reset regen ticks.
  1194. struct regen_data *regen = status_get_regen_data(target);
  1195. if (regen) {
  1196. memset(&regen->tick, 0, sizeof(regen->tick));
  1197. if (regen->sregen)
  1198. memset(&regen->sregen->tick, 0, sizeof(regen->sregen->tick));
  1199. if (regen->ssregen)
  1200. memset(&regen->ssregen->tick, 0, sizeof(regen->ssregen->tick));
  1201. }
  1202. }
  1203. if( sc && sc->data[SC_KAIZEL] && !map_flag_gvg(target->m) )
  1204. { //flag&8 = disable Kaizel
  1205. int time = skill_get_time2(SL_KAIZEL,sc->data[SC_KAIZEL]->val1);
  1206. //Look for Osiris Card's bonus effect on the character and revive 100% or revive normally
  1207. if ( target->type == BL_PC && BL_CAST(BL_PC,target)->special_state.restart_full_recover )
  1208. status_revive(target, 100, 100);
  1209. else
  1210. status_revive(target, sc->data[SC_KAIZEL]->val2, 0);
  1211. status_change_clear(target,0);
  1212. clif_skill_nodamage(target,target,ALL_RESURRECTION,1,1);
  1213. sc_start(target,status_skill2sc(PR_KYRIE),100,10,time);
  1214. if( target->type == BL_MOB )
  1215. ((TBL_MOB*)target)->state.rebirth = 1;
  1216. return hp+sp;
  1217. }
  1218. if(target->type == BL_PC){
  1219. TBL_PC *sd = BL_CAST(BL_PC,target);
  1220. TBL_HOM *hd = sd->hd;
  1221. if(hd && hd->sc.data[SC_LIGHT_OF_REGENE]){
  1222. clif_skillcasting(&hd->bl, hd->bl.id, target->id, 0,0, MH_LIGHT_OF_REGENE, skill_get_ele(MH_LIGHT_OF_REGENE, 1), 10); //just to display usage
  1223. clif_skill_nodamage(&sd->bl, target, ALL_RESURRECTION, 1, status_revive(&sd->bl,10*hd->sc.data[SC_LIGHT_OF_REGENE]->val1,0));
  1224. status_change_end(&sd->hd->bl,SC_LIGHT_OF_REGENE,INVALID_TIMER);
  1225. return hp + sp;
  1226. }
  1227. }
  1228. if (target->type == BL_MOB && sc && sc->data[SC_REBIRTH] && !((TBL_MOB*) target)->state.rebirth) {// Ensure the monster has not already rebirthed before doing so.
  1229. status_revive(target, sc->data[SC_REBIRTH]->val2, 0);
  1230. status_change_clear(target,0);
  1231. ((TBL_MOB*)target)->state.rebirth = 1;
  1232. return hp+sp;
  1233. }
  1234. status_change_clear(target,0);
  1235. if(flag&4) //Delete from memory. (also invokes map removal code)
  1236. unit_free(target,CLR_DEAD);
  1237. else
  1238. if(flag&2) //remove from map
  1239. unit_remove_map(target,CLR_DEAD);
  1240. else
  1241. { //Some death states that would normally be handled by unit_remove_map
  1242. unit_stop_attack(target);
  1243. unit_stop_walking(target,1);
  1244. unit_skillcastcancel(target,0);
  1245. clif_clearunit_area(target,CLR_DEAD);
  1246. skill_unit_move(target,gettick(),4);
  1247. skill_cleartimerskill(target);
  1248. }
  1249. return hp+sp;
  1250. }
  1251. //Heals a character. If flag&1, this is forced healing (otherwise stuff like Berserk can block it)
  1252. //If flag&2, when the player is healed, show the HP/SP heal effect.
  1253. int status_heal(struct block_list *bl,int hp,int sp, int flag)
  1254. {
  1255. struct status_data *status;
  1256. struct status_change *sc;
  1257. status = status_get_status_data(bl);
  1258. if (status == &dummy_status || !status->hp)
  1259. return 0;
  1260. sc = status_get_sc(bl);
  1261. if (sc && !sc->count)
  1262. sc = NULL;
  1263. if (hp < 0) {
  1264. if (hp == INT_MIN) hp++; //-INT_MIN == INT_MIN in some architectures!
  1265. status_damage(NULL, bl, -hp, 0, 0, 1);
  1266. hp = 0;
  1267. }
  1268. if(hp) {
  1269. if( sc && (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST]) ) {
  1270. if( flag&1 )
  1271. flag &= ~2;
  1272. else
  1273. hp = 0;
  1274. }
  1275. if((unsigned int)hp > status->max_hp - status->hp)
  1276. hp = status->max_hp - status->hp;
  1277. }
  1278. if(sp < 0) {
  1279. if (sp==INT_MIN) sp++;
  1280. status_damage(NULL, bl, 0, -sp, 0, 1);
  1281. sp = 0;
  1282. }
  1283. if(sp) {
  1284. if((unsigned int)sp > status->max_sp - status->sp)
  1285. sp = status->max_sp - status->sp;
  1286. }
  1287. if(!sp && !hp) return 0;
  1288. status->hp+= hp;
  1289. status->sp+= sp;
  1290. if(hp && sc &&
  1291. sc->data[SC_AUTOBERSERK] &&
  1292. sc->data[SC_PROVOKE] &&
  1293. sc->data[SC_PROVOKE]->val2==1 &&
  1294. status->hp>=status->max_hp>>2
  1295. ) //End auto berserk.
  1296. status_change_end(bl, SC_PROVOKE, INVALID_TIMER);
  1297. // send hp update to client
  1298. switch(bl->type) {
  1299. case BL_PC: pc_heal((TBL_PC*)bl,hp,sp,flag&2?1:0); break;
  1300. case BL_MOB: mob_heal((TBL_MOB*)bl,hp); break;
  1301. case BL_HOM: merc_hom_heal((TBL_HOM*)bl); break;
  1302. case BL_MER: mercenary_heal((TBL_MER*)bl,hp,sp); break;
  1303. case BL_ELEM: elemental_heal((TBL_ELEM*)bl,hp,sp); break;
  1304. }
  1305. return hp+sp;
  1306. }
  1307. //Does percentual non-flinching damage/heal. If mob is killed this way,
  1308. //no exp/drops will be awarded if there is no src (or src is target)
  1309. //If rates are > 0, percent is of current HP/SP
  1310. //If rates are < 0, percent is of max HP/SP
  1311. //If !flag, this is heal, otherwise it is damage.
  1312. //Furthermore, if flag==2, then the target must not die from the substraction.
  1313. int status_percent_change(struct block_list *src,struct block_list *target,signed char hp_rate, signed char sp_rate, int flag)
  1314. {
  1315. struct status_data *status;
  1316. unsigned int hp =0, sp = 0;
  1317. status = status_get_status_data(target);
  1318. //It's safe now [MarkZD]
  1319. if (hp_rate > 99)
  1320. hp = status->hp;
  1321. else if (hp_rate > 0)
  1322. hp = status->hp>10000?
  1323. hp_rate*(status->hp/100):
  1324. ((int64)hp_rate*status->hp)/100;
  1325. else if (hp_rate < -99)
  1326. hp = status->max_hp;
  1327. else if (hp_rate < 0)
  1328. hp = status->max_hp>10000?
  1329. (-hp_rate)*(status->max_hp/100):
  1330. ((int64)-hp_rate*status->max_hp)/100;
  1331. if (hp_rate && !hp)
  1332. hp = 1;
  1333. if (flag == 2 && hp >= status->hp)
  1334. hp = status->hp-1; //Must not kill target.
  1335. if (sp_rate > 99)
  1336. sp = status->sp;
  1337. else if (sp_rate > 0)
  1338. sp = ((int64)sp_rate*status->sp)/100;
  1339. else if (sp_rate < -99)
  1340. sp = status->max_sp;
  1341. else if (sp_rate < 0)
  1342. sp = ((int64)-sp_rate)*status->max_sp/100;
  1343. if (sp_rate && !sp)
  1344. sp = 1;
  1345. //Ugly check in case damage dealt is too much for the received args of
  1346. //status_heal / status_damage. [Skotlex]
  1347. if (hp > INT_MAX) {
  1348. hp -= INT_MAX;
  1349. if (flag)
  1350. status_damage(src, target, INT_MAX, 0, 0, (!src||src==target?5:1));
  1351. else
  1352. status_heal(target, INT_MAX, 0, 0);
  1353. }
  1354. if (sp > INT_MAX) {
  1355. sp -= INT_MAX;
  1356. if (flag)
  1357. status_damage(src, target, 0, INT_MAX, 0, (!src||src==target?5:1));
  1358. else
  1359. status_heal(target, 0, INT_MAX, 0);
  1360. }
  1361. if (flag)
  1362. return status_damage(src, target, hp, sp, 0, (!src||src==target?5:1));
  1363. return status_heal(target, hp, sp, 0);
  1364. }
  1365. int status_revive(struct block_list *bl, unsigned char per_hp, unsigned char per_sp)
  1366. {
  1367. struct status_data *status;
  1368. unsigned int hp, sp;
  1369. if (!status_isdead(bl)) return 0;
  1370. status = status_get_status_data(bl);
  1371. if (status == &dummy_status)
  1372. return 0; //Invalid target.
  1373. hp = (int64)status->max_hp * per_hp/100;
  1374. sp = (int64)status->max_sp * per_sp/100;
  1375. if(hp > status->max_hp - status->hp)
  1376. hp = status->max_hp - status->hp;
  1377. else if (per_hp && !hp)
  1378. hp = 1;
  1379. if(sp > status->max_sp - status->sp)
  1380. sp = status->max_sp - status->sp;
  1381. else if (per_sp && !sp)
  1382. sp = 1;
  1383. status->hp += hp;
  1384. status->sp += sp;
  1385. if (bl->prev) //Animation only if character is already on a map.
  1386. clif_resurrection(bl, 1);
  1387. switch (bl->type) {
  1388. case BL_PC: pc_revive((TBL_PC*)bl, hp, sp); break;
  1389. case BL_MOB: mob_revive((TBL_MOB*)bl, hp); break;
  1390. case BL_HOM: merc_hom_revive((TBL_HOM*)bl, hp, sp); break;
  1391. }
  1392. return 1;
  1393. }
  1394. /*==========================================
  1395. * Checks whether the src can use the skill on the target,
  1396. * taking into account status/option of both source/target. [Skotlex]
  1397. * flag:
  1398. * 0 - Trying to use skill on target.
  1399. * 1 - Cast bar is done.
  1400. * 2 - Skill already pulled off, check is due to ground-based skills or splash-damage ones.
  1401. * src MAY be null to indicate we shouldn't check it, this is a ground-based skill attack.
  1402. * target MAY Be null, in which case the checks are only to see
  1403. * whether the source can cast or not the skill on the ground.
  1404. *------------------------------------------*/
  1405. int status_check_skilluse(struct block_list *src, struct block_list *target, uint16 skill_id, int flag)
  1406. {
  1407. struct status_data *status;
  1408. struct status_change *sc=NULL, *tsc;
  1409. int hide_flag;
  1410. status = src?status_get_status_data(src):&dummy_status;
  1411. if (src && src->type != BL_PC && status_isdead(src))
  1412. return 0;
  1413. if (!skill_id) { //Normal attack checks.
  1414. if (!(status->mode&MD_CANATTACK))
  1415. return 0; //This mode is only needed for melee attacking.
  1416. //Dead state is not checked for skills as some skills can be used
  1417. //on dead characters, said checks are left to skill.c [Skotlex]
  1418. if (target && status_isdead(target))
  1419. return 0;
  1420. if( src && (sc = status_get_sc(src)) && sc->data[SC_CRYSTALIZE] && src->type != BL_MOB)
  1421. return 0;
  1422. }
  1423. switch( skill_id ) {
  1424. case PA_PRESSURE:
  1425. if( flag && target ) {
  1426. //Gloria Avoids pretty much everything....
  1427. tsc = status_get_sc(target);
  1428. if(tsc && tsc->option&OPTION_HIDE)
  1429. return 0;
  1430. }
  1431. break;
  1432. case GN_WALLOFTHORN:
  1433. if( target && status_isdead(target) )
  1434. return 0;
  1435. break;
  1436. case AL_TELEPORT:
  1437. //Should fail when used on top of Land Protector [Skotlex]
  1438. if (src && map_getcell(src->m, src->x, src->y, CELL_CHKLANDPROTECTOR)
  1439. && !(status->mode&MD_BOSS)
  1440. && (src->type != BL_PC || ((TBL_PC*)src)->skillitem != skill_id))
  1441. return 0;
  1442. break;
  1443. default:
  1444. break;
  1445. }
  1446. if ( src ) sc = status_get_sc(src);
  1447. if( sc && sc->count ) {
  1448. if (skill_id != RK_REFRESH && sc->opt1 >0 && (sc->opt1 != OPT1_CRYSTALIZE && src->type != BL_MOB) && sc->opt1 != OPT1_BURNING && skill_id != SR_GENTLETOUCH_CURE) { //Stuned/Frozen/etc
  1449. if (flag != 1) //Can't cast, casted stuff can't damage.
  1450. return 0;
  1451. if (!(skill_get_inf(skill_id)&INF_GROUND_SKILL))
  1452. return 0; //Targetted spells can't come off.
  1453. }
  1454. if (
  1455. (sc->data[SC_TRICKDEAD] && skill_id != NV_TRICKDEAD)
  1456. || (sc->data[SC_AUTOCOUNTER] && !flag)
  1457. || (sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_SELF && skill_id != PA_GOSPEL)
  1458. || (sc->data[SC_GRAVITATION] && sc->data[SC_GRAVITATION]->val3 == BCT_SELF && flag != 2)
  1459. )
  1460. return 0;
  1461. if (sc->data[SC_WINKCHARM] && target && !flag) { //Prevents skill usage
  1462. if( unit_bl2ud(src) && (unit_bl2ud(src))->walktimer == INVALID_TIMER )
  1463. unit_walktobl(src, map_id2bl(sc->data[SC_WINKCHARM]->val2), 3, 1);
  1464. clif_emotion(src, E_LV);
  1465. return 0;
  1466. }
  1467. if (sc->data[SC_BLADESTOP]) {
  1468. switch (sc->data[SC_BLADESTOP]->val1)
  1469. {
  1470. case 5: if (skill_id == MO_EXTREMITYFIST) break;
  1471. case 4: if (skill_id == MO_CHAINCOMBO) break;
  1472. case 3: if (skill_id == MO_INVESTIGATE) break;
  1473. case 2: if (skill_id == MO_FINGEROFFENSIVE) break;
  1474. default: return 0;
  1475. }
  1476. }
  1477. if (sc->data[SC_DANCING] && flag!=2) {
  1478. if( src->type == BL_PC && skill_id >= WA_SWING_DANCE && skill_id <= WM_UNLIMITED_HUMMING_VOICE )
  1479. { // Lvl 5 Lesson or higher allow you use 3rd job skills while dancing.v
  1480. if( pc_checkskill((TBL_PC*)src,WM_LESSON) < 5 )
  1481. return 0;
  1482. } else if(sc->data[SC_LONGING]) { //Allow everything except dancing/re-dancing. [Skotlex]
  1483. if (skill_id == BD_ENCORE ||
  1484. skill_get_inf2(skill_id)&(INF2_SONG_DANCE|INF2_ENSEMBLE_SKILL)
  1485. )
  1486. return 0;
  1487. } else {
  1488. switch (skill_id) {
  1489. case BD_ADAPTATION:
  1490. case CG_LONGINGFREEDOM:
  1491. case BA_MUSICALSTRIKE:
  1492. case DC_THROWARROW:
  1493. break;
  1494. default:
  1495. return 0;
  1496. }
  1497. }
  1498. if ((sc->data[SC_DANCING]->val1&0xFFFF) == CG_HERMODE && skill_id == BD_ADAPTATION)
  1499. return 0; //Can't amp out of Wand of Hermode :/ [Skotlex]
  1500. }
  1501. if (skill_id && //Do not block item-casted skills.
  1502. (src->type != BL_PC || ((TBL_PC*)src)->skillitem != skill_id)
  1503. ) { //Skills blocked through status changes...
  1504. if (!flag && ( //Blocked only from using the skill (stuff like autospell may still go through
  1505. sc->cant.cast ||
  1506. (sc->data[SC_MARIONETTE] && skill_id != CG_MARIONETTE) || //Only skill you can use is marionette again to cancel it
  1507. (sc->data[SC_MARIONETTE2] && skill_id == CG_MARIONETTE) || //Cannot use marionette if you are being buffed by another
  1508. (sc->data[SC_STASIS] && skill_block_check(src, SC_STASIS, skill_id)) ||
  1509. (sc->data[SC_KAGEHUMI] && skill_block_check(src, SC_KAGEHUMI, skill_id))
  1510. ))
  1511. return 0;
  1512. //Skill blocking.
  1513. if (
  1514. (sc->data[SC_VOLCANO] && skill_id == WZ_ICEWALL) ||
  1515. (sc->data[SC_ROKISWEIL] && skill_id != BD_ADAPTATION) ||
  1516. (sc->data[SC_HERMODE] && skill_get_inf(skill_id) & INF_SUPPORT_SKILL) ||
  1517. (sc->data[SC_NOCHAT] && sc->data[SC_NOCHAT]->val1&MANNER_NOSKILL)
  1518. )
  1519. return 0;
  1520. if( sc->data[SC__MANHOLE] || ((tsc = status_get_sc(target)) && tsc->data[SC__MANHOLE]) ) {
  1521. switch(skill_id) {//##TODO## make this a flag in skill_db?
  1522. // Skills that can be used even under Man Hole effects.
  1523. case SC_SHADOWFORM:
  1524. case SC_STRIPACCESSARY:
  1525. break;
  1526. default:
  1527. return 0;
  1528. }
  1529. }
  1530. }
  1531. }
  1532. if (sc && sc->option)
  1533. {
  1534. if (sc->option&OPTION_HIDE)
  1535. switch (skill_id) { //Usable skills while hiding.
  1536. case TF_HIDING:
  1537. case AS_GRIMTOOTH:
  1538. case RG_BACKSTAP:
  1539. case RG_RAID:
  1540. case NJ_SHADOWJUMP:
  1541. case NJ_KIRIKAGE:
  1542. case KO_YAMIKUMO:
  1543. break;
  1544. default:
  1545. //Non players can use all skills while hidden.
  1546. if (!skill_id || src->type == BL_PC)
  1547. return 0;
  1548. }
  1549. if (sc->option&OPTION_CHASEWALK && skill_id != ST_CHASEWALK)
  1550. return 0;
  1551. if(sc->option&OPTION_MOUNTING)
  1552. return 0;//New mounts can't attack nor use skills in the client; this check makes it cheat-safe [Ind]
  1553. }
  1554. if (target == NULL || target == src) //No further checking needed.
  1555. return 1;
  1556. tsc = status_get_sc(target);
  1557. if(tsc && tsc->count) {
  1558. /* attacks in invincible are capped to 1 damage and handled in batte.c; allow spell break and eske for sealed shrine GDB when in INVINCIBLE state. */
  1559. if( tsc->data[SC_INVINCIBLE] && !tsc->data[SC_INVINCIBLEOFF] && skill_id && !(skill_id&(SA_SPELLBREAKER|SL_SKE)) )
  1560. return 0;
  1561. if(!skill_id && tsc->data[SC_TRICKDEAD])
  1562. return 0;
  1563. if((skill_id == WZ_STORMGUST || skill_id == WZ_FROSTNOVA || skill_id == NJ_HYOUSYOURAKU)
  1564. && tsc->data[SC_FREEZE])
  1565. return 0;
  1566. if(skill_id == PR_LEXAETERNA && (tsc->data[SC_FREEZE] || (tsc->data[SC_STONE] && tsc->opt1 == OPT1_STONE)))
  1567. return 0;
  1568. }
  1569. //If targetting, cloak+hide protect you, otherwise only hiding does.
  1570. hide_flag = flag?OPTION_HIDE:(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK);
  1571. //You cannot hide from ground skills.
  1572. if( skill_get_ele(skill_id,1) == ELE_EARTH ) //TODO: Need Skill Lv here :/
  1573. hide_flag &= ~OPTION_HIDE;
  1574. switch( target->type ) {
  1575. case BL_PC: {
  1576. struct map_session_data *sd = (TBL_PC*) target;
  1577. bool is_boss = (status->mode&MD_BOSS);
  1578. bool is_detect = ((status->mode&MD_DETECTOR)?true:false);//god-knows-why gcc doesn't shut up until this happens
  1579. if (pc_isinvisible(sd))
  1580. return 0;
  1581. if (tsc->option&hide_flag && !is_boss &&
  1582. ((sd->special_state.perfect_hiding || !is_detect) ||
  1583. (tsc->data[SC_CLOAKINGEXCEED] && is_detect)))
  1584. return 0;
  1585. if( tsc->data[SC_CAMOUFLAGE] && !(is_boss || is_detect) && !skill_id )
  1586. return 0;
  1587. if( tsc->data[SC_STEALTHFIELD] && !is_boss )
  1588. return 0;
  1589. }
  1590. break;
  1591. case BL_ITEM: //Allow targetting of items to pick'em up (or in the case of mobs, to loot them).
  1592. //TODO: Would be nice if this could be used to judge whether the player can or not pick up the item it targets. [Skotlex]
  1593. if (status->mode&MD_LOOTER)
  1594. return 1;
  1595. return 0;
  1596. case BL_HOM:
  1597. case BL_MER:
  1598. case BL_ELEM:
  1599. if( target->type == BL_HOM && skill_id && battle_config.hom_setting&0x1 && skill_get_inf(skill_id)&INF_SUPPORT_SKILL && battle_get_master(target) != src )
  1600. return 0; // Can't use support skills on Homunculus (only Master/Self)
  1601. if( target->type == BL_MER && (skill_id == PR_ASPERSIO || (skill_id >= SA_FLAMELAUNCHER && skill_id <= SA_SEISMICWEAPON)) && battle_get_master(target) != src )
  1602. return 0; // Can't use Weapon endow skills on Mercenary (only Master)
  1603. if( skill_id == AM_POTIONPITCHER && ( target->type == BL_MER || target->type == BL_ELEM) )
  1604. return 0; // Can't use Potion Pitcher on Mercenaries
  1605. default:
  1606. //Check for chase-walk/hiding/cloaking opponents.
  1607. if( tsc ) {
  1608. if( tsc->option&hide_flag && !(status->mode&(MD_BOSS|MD_DETECTOR)))
  1609. return 0;
  1610. if( tsc->data[SC_STEALTHFIELD] && !(status->mode&MD_BOSS) )
  1611. return 0;
  1612. }
  1613. }
  1614. return 1;
  1615. }
  1616. //Checks whether the source can see and chase target.
  1617. int status_check_visibility(struct block_list *src, struct block_list *target)
  1618. {
  1619. int view_range;
  1620. struct status_data* status = status_get_status_data(src);
  1621. struct status_change* tsc = status_get_sc(target);
  1622. switch (src->type) {
  1623. case BL_MOB:
  1624. view_range = ((TBL_MOB*)src)->min_chase;
  1625. break;
  1626. case BL_PET:
  1627. view_range = ((TBL_PET*)src)->db->range2;
  1628. break;
  1629. default:
  1630. view_range = AREA_SIZE;
  1631. }
  1632. if (src->m != target->m || !check_distance_bl(src, target, view_range))
  1633. return 0;
  1634. if( tsc && tsc->data[SC_STEALTHFIELD] )
  1635. return 0;
  1636. switch (target->type)
  1637. { //Check for chase-walk/hiding/cloaking opponents.
  1638. case BL_PC:
  1639. if ( tsc->data[SC_CLOAKINGEXCEED] && !(status->mode&MD_BOSS) )
  1640. return 0;
  1641. if( (tsc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) || tsc->data[SC__INVISIBILITY] || tsc->data[SC_CAMOUFLAGE]) && !(status->mode&MD_BOSS) &&
  1642. ( ((TBL_PC*)target)->special_state.perfect_hiding || !(status->mode&MD_DETECTOR) ) )
  1643. return 0;
  1644. break;
  1645. default:
  1646. if( tsc && (tsc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) || tsc->data[SC__INVISIBILITY] || tsc->data[SC_CAMOUFLAGE]) && !(status->mode&(MD_BOSS|MD_DETECTOR)) )
  1647. return 0;
  1648. }
  1649. return 1;
  1650. }
  1651. // Basic ASPD value
  1652. int status_base_amotion_pc(struct map_session_data* sd, struct status_data* status)
  1653. {
  1654. int amotion;
  1655. #ifdef RENEWAL_ASPD
  1656. short mod = -1;
  1657. switch( sd->weapontype2 ){ // adjustment for dual weilding
  1658. case W_DAGGER: mod = 0; break; // 0, 1, 1
  1659. case W_1HSWORD:
  1660. case W_1HAXE: mod = 1;
  1661. if( (sd->class_&MAPID_THIRDMASK) == MAPID_GUILLOTINE_CROSS ) // 0, 2, 3
  1662. mod = sd->weapontype2 / W_1HSWORD + W_1HSWORD / sd->weapontype2 ;
  1663. }
  1664. amotion = ( sd->status.weapon < MAX_WEAPON_TYPE && mod < 0 )
  1665. ? (aspd_base[pc_class2idx(sd->status.class_)][sd->status.weapon]) // single weapon
  1666. : ((aspd_base[pc_class2idx(sd->status.class_)][sd->weapontype2] // dual-wield
  1667. + aspd_base[pc_class2idx(sd->status.class_)][sd->weapontype2]) * 6 / 10 + 10 * mod
  1668. - aspd_base[pc_class2idx(sd->status.class_)][sd->weapontype2]
  1669. + aspd_base[pc_class2idx(sd->status.class_)][sd->weapontype1]);
  1670. if ( sd->status.shield )
  1671. amotion += ( 2000 - aspd_base[pc_class2idx(sd->status.class_)][W_FIST] ) +
  1672. ( aspd_base[pc_class2idx(sd->status.class_)][MAX_WEAPON_TYPE] - 2000 );
  1673. #else
  1674. // base weapon delay
  1675. amotion = (sd->status.weapon < MAX_WEAPON_TYPE)
  1676. ? (aspd_base[pc_class2idx(sd->status.class_)][sd->status.weapon]) // single weapon
  1677. : (aspd_base[pc_class2idx(sd->status.class_)][sd->weapontype1] + aspd_base[pc_class2idx(sd->status.class_)][sd->weapontype2])*7/10; // dual-wield
  1678. // percentual delay reduction from stats
  1679. amotion -= amotion * (4*status->agi + status->dex)/1000;
  1680. #endif
  1681. // raw delay adjustment from bAspd bonus
  1682. amotion += sd->bonus.aspd_add;
  1683. return amotion;
  1684. }
  1685. static unsigned short status_base_atk(const struct block_list *bl, const struct status_data *status)
  1686. {
  1687. int flag = 0, str, dex,
  1688. #ifdef RENEWAL
  1689. rstr,
  1690. #endif
  1691. dstr;
  1692. if(!(bl->type&battle_config.enable_baseatk))
  1693. return 0;
  1694. if (bl->type == BL_PC)
  1695. switch(((TBL_PC*)bl)->status.weapon){
  1696. case W_BOW:
  1697. case W_MUSICAL:
  1698. case W_WHIP:
  1699. case W_REVOLVER:
  1700. case W_RIFLE:
  1701. case W_GATLING:
  1702. case W_SHOTGUN:
  1703. case W_GRENADE:
  1704. flag = 1;
  1705. }
  1706. if (flag) {
  1707. #ifdef RENEWAL
  1708. rstr =
  1709. #endif
  1710. str = status->dex;
  1711. dex = status->str;
  1712. } else {
  1713. #ifdef RENEWAL
  1714. rstr =
  1715. #endif
  1716. str = status->str;
  1717. dex = status->dex;
  1718. }
  1719. //Normally only players have base-atk, but homunc have a different batk
  1720. // equation, hinting that perhaps non-players should use this for batk.
  1721. // [Skotlex]
  1722. dstr = str/10;
  1723. str += dstr*dstr;
  1724. if (bl->type == BL_PC)
  1725. #ifdef RENEWAL
  1726. str = (rstr*10 + dex*10/5 + status->luk*10/3 + ((TBL_PC*)bl)->status.base_level*10/4)/10;
  1727. #else
  1728. str+= dex/5 + status->luk/5;
  1729. #endif
  1730. return cap_value(str, 0, USHRT_MAX);
  1731. }
  1732. #ifndef RENEWAL
  1733. static inline unsigned short status_base_matk_min(const struct status_data* status){ return status->int_+(status->int_/7)*(status->int_/7); }
  1734. static inline unsigned short status_base_matk_max(const struct status_data* status){ return status->int_+(status->int_/5)*(status->int_/5); }
  1735. #else
  1736. unsigned short status_base_matk(const struct status_data* status, int level){ return status->int_+(status->int_/2)+(status->dex/5)+(status->luk/3)+(level/4); }
  1737. #endif
  1738. //Fills in the misc data that can be calculated from the other status info (except for level)
  1739. void status_calc_misc(struct block_list *bl, struct status_data *status, int level)
  1740. {
  1741. //Non players get the value set, players need to stack with previous bonuses.
  1742. if( bl->type != BL_PC )
  1743. status->batk =
  1744. status->hit = status->flee =
  1745. status->def2 = status->mdef2 =
  1746. status->cri = status->flee2 = 0;
  1747. #ifdef RENEWAL // renewal formulas
  1748. status->matk_min = status->matk_max = status_base_matk(status, level);
  1749. status->hit += level + status->dex + status->luk/3 + 175; //base level + ( every 1 dex = +1 hit ) + (every 3 luk = +1 hit) + 175
  1750. status->flee += level + status->agi + status->luk/5 + 100; //base level + ( every 1 agi = +1 flee ) + (every 5 luk = +1 flee) + 100
  1751. status->def2 += (int)(((float)level + status->vit)/2 + ((float)status->agi/5)); //base level + (every 2 vit = +1 def) + (every 5 agi = +1 def)
  1752. status->mdef2 += (int)(status->int_ + ((float)level/4) + ((float)status->dex/5) + ((float)status->vit/5)); //(every 4 base level = +1 mdef) + (every 1 int = +1 mdef) + (every 5 dex = +1 mdef) + (every 5 vit = +1 mdef)
  1753. #else
  1754. status->matk_min = status_base_matk_min(status);
  1755. status->matk_max = status_base_matk_max(status);
  1756. status->hit += level + status->dex;
  1757. status->flee += level + status->agi;
  1758. status->def2 += status->vit;
  1759. status->mdef2 += status->int_ + (status->vit>>1);
  1760. #endif
  1761. if( bl->type&battle_config.enable_critical )
  1762. status->cri += 10 + (status->luk*10/3); //(every 1 luk = +0.3 critical)
  1763. else
  1764. status->cri = 0;
  1765. if (bl->type&battle_config.enable_perfect_flee)
  1766. status->flee2 += status->luk + 10; //(every 10 luk = +1 perfect flee)
  1767. else
  1768. status->flee2 = 0;
  1769. if (status->batk) {
  1770. int temp = status->batk + status_base_atk(bl, status);
  1771. status->batk = cap_value(temp, 0, USHRT_MAX);
  1772. } else
  1773. status->batk = status_base_atk(bl, status);
  1774. if (status->cri)
  1775. switch (bl->type) {
  1776. case BL_MOB:
  1777. if(battle_config.mob_critical_rate != 100)
  1778. status->cri = status->cri*battle_config.mob_critical_rate/100;
  1779. if(!status->cri && battle_config.mob_critical_rate)
  1780. status->cri = 10;
  1781. break;
  1782. case BL_PC:
  1783. //Players don't have a critical adjustment setting as of yet.
  1784. break;
  1785. default:
  1786. if(battle_config.critical_rate != 100)
  1787. status->cri = status->cri*battle_config.critical_rate/100;
  1788. if (!status->cri && battle_config.critical_rate)
  1789. status->cri = 10;
  1790. }
  1791. if(bl->type&BL_REGEN)
  1792. status_calc_regen(bl, status, status_get_regen_data(bl));
  1793. }
  1794. //Skotlex: Calculates the initial status for the given mob
  1795. //first will only be false when the mob leveled up or got a GuardUp level.
  1796. int status_calc_mob_(struct mob_data* md, bool first)
  1797. {
  1798. struct status_data *status;
  1799. struct block_list *mbl = NULL;
  1800. int flag=0;
  1801. if(first)
  1802. { //Set basic level on respawn.
  1803. if (md->level > 0 && md->level <= MAX_LEVEL && md->level != md->db->lv)
  1804. ;
  1805. else
  1806. md->level = md->db->lv;
  1807. }
  1808. //Check if we need custom base-status
  1809. if (battle_config.mobs_level_up && md->level > md->db->lv)
  1810. flag|=1;
  1811. if (md->special_state.size)
  1812. flag|=2;
  1813. if (md->guardian_data && md->guardian_data->guardup_lv)
  1814. flag|=4;
  1815. if (md->class_ == MOBID_EMPERIUM)
  1816. flag|=4;
  1817. if (battle_config.slaves_inherit_speed && md->master_id)
  1818. flag|=8;
  1819. if (md->master_id && md->special_state.ai>1)
  1820. flag|=16;
  1821. if (!flag)
  1822. { //No special status required.
  1823. if (md->base_status) {
  1824. aFree(md->base_status);
  1825. md->base_status = NULL;
  1826. }
  1827. if(first)
  1828. memcpy(&md->status, &md->db->status, sizeof(struct status_data));
  1829. return 0;
  1830. }
  1831. if (!md->base_status)
  1832. md->base_status = (struct status_data*)aCalloc(1, sizeof(struct status_data));
  1833. status = md->base_status;
  1834. memcpy(status, &md->db->status, sizeof(struct status_data));
  1835. if (flag&(8|16))
  1836. mbl = map_id2bl(md->master_id);
  1837. if (flag&8 && mbl) {
  1838. struct status_data *mstatus = status_get_base_status(mbl);
  1839. if (mstatus &&
  1840. battle_config.slaves_inherit_speed&(mstatus->mode&MD_CANMOVE?1:2))
  1841. status->speed = mstatus->speed;
  1842. if( status->speed < 2 ) /* minimum for the unit to function properly */
  1843. status->speed = 2;
  1844. }
  1845. if (flag&16 && mbl)
  1846. { //Max HP setting from Summon Flora/marine Sphere
  1847. struct unit_data *ud = unit_bl2ud(mbl);
  1848. //Remove special AI when this is used by regular mobs.
  1849. if (mbl->type == BL_MOB && !((TBL_MOB*)mbl)->special_state.ai)
  1850. md->special_state.ai = 0;
  1851. if (ud)
  1852. { // different levels of HP according to skill level
  1853. if (ud->skill_id == AM_SPHEREMINE) {
  1854. status->max_hp = 2000 + 400*ud->skill_lv;
  1855. } else if(ud->skill_id == KO_ZANZOU){
  1856. status->max_hp = 3000 + 3000 * ud->skill_lv;
  1857. } else { //AM_CANNIBALIZE
  1858. status->max_hp = 1500 + 200*ud->skill_lv + 10*status_get_lv(mbl);
  1859. status->mode|= MD_CANATTACK|MD_AGGRESSIVE;
  1860. }
  1861. status->hp = status->max_hp;
  1862. }
  1863. }
  1864. if (flag&1)
  1865. { // increase from mobs leveling up [Valaris]
  1866. int diff = md->level - md->db->lv;
  1867. status->str+= diff;
  1868. status->agi+= diff;
  1869. status->vit+= diff;
  1870. status->int_+= diff;
  1871. status->dex+= diff;
  1872. status->luk+= diff;
  1873. status->max_hp += diff*status->vit;
  1874. status->max_sp += diff*status->int_;
  1875. status->hp = status->max_hp;
  1876. status->sp = status->max_sp;
  1877. status->speed -= cap_value(diff, 0, status->speed - 10);
  1878. }
  1879. if (flag&2 && battle_config.mob_size_influence)
  1880. { // change for sized monsters [Valaris]
  1881. if (md->special_state.size==SZ_MEDIUM) {
  1882. status->max_hp>>=1;
  1883. status->max_sp>>=1;
  1884. if (!status->max_hp) status->max_hp = 1;
  1885. if (!status->max_sp) status->max_sp = 1;
  1886. status->hp=status->max_hp;
  1887. status->sp=status->max_sp;
  1888. status->str>>=1;
  1889. status->agi>>=1;
  1890. status->vit>>=1;
  1891. status->int_>>=1;
  1892. status->dex>>=1;
  1893. status->luk>>=1;
  1894. if (!status->str) status->str = 1;
  1895. if (!status->agi) status->agi = 1;
  1896. if (!status->vit) status->vit = 1;
  1897. if (!status->int_) status->int_ = 1;
  1898. if (!status->dex) status->dex = 1;
  1899. if (!status->luk) status->luk = 1;
  1900. } else if (md->special_state.size==SZ_BIG) {
  1901. status->max_hp<<=1;
  1902. status->max_sp<<=1;
  1903. status->hp=status->max_hp;
  1904. status->sp=status->max_sp;
  1905. status->str<<=1;
  1906. status->agi<<=1;
  1907. status->vit<<=1;
  1908. status->int_<<=1;
  1909. status->dex<<=1;
  1910. status->luk<<=1;
  1911. }
  1912. }
  1913. status_calc_misc(&md->bl, status, md->level);
  1914. if(flag&4)
  1915. { // Strengthen Guardians - custom value +10% / lv
  1916. struct guild_castle *gc;
  1917. gc=guild_mapname2gc(map[md->bl.m].name);
  1918. if (!gc)
  1919. ShowError("status_calc_mob: No castle set at map %s\n", map[md->bl.m].name);
  1920. else
  1921. if(gc->castle_id < 24 || md->class_ == MOBID_EMPERIUM) {
  1922. #ifdef RENEWAL
  1923. status->max_hp += 50 * gc->defense;
  1924. status->max_sp += 70 * gc->defense;
  1925. #else
  1926. status->max_hp += 1000 * gc->defense;
  1927. status->max_sp += 200 * gc->defense;
  1928. #endif
  1929. status->hp = status->max_hp;
  1930. status->sp = status->max_sp;
  1931. status->def += (gc->defense+2)/3;
  1932. status->mdef += (gc->defense+2)/3;
  1933. }
  1934. if(md->class_ != MOBID_EMPERIUM) {
  1935. status->batk += status->batk * 10*md->guardian_data->guardup_lv/100;
  1936. status->rhw.atk += status->rhw.atk * 10*md->guardian_data->guardup_lv/100;
  1937. status->rhw.atk2 += status->rhw.atk2 * 10*md->guardian_data->guardup_lv/100;
  1938. status->aspd_rate -= 100*md->guardian_data->guardup_lv;
  1939. }
  1940. }
  1941. if( first ) //Initial battle status
  1942. memcpy(&md->status, status, sizeof(struct status_data));
  1943. return 1;
  1944. }
  1945. //Skotlex: Calculates the stats of the given pet.
  1946. int status_calc_pet_(struct pet_data *pd, bool first)
  1947. {
  1948. nullpo_ret(pd);
  1949. if (first) {
  1950. memcpy(&pd->status, &pd->db->status, sizeof(struct status_data));
  1951. pd->status.mode = MD_CANMOVE; // pets discard all modes, except walking
  1952. pd->status.speed = pd->petDB->speed;
  1953. if(battle_config.pet_attack_support || battle_config.pet_damage_support)
  1954. {// attack support requires the pet to be able to attack
  1955. pd->status.mode|= MD_CANATTACK;
  1956. }
  1957. }
  1958. if (battle_config.pet_lv_rate && pd->msd)
  1959. {
  1960. struct map_session_data *sd = pd->msd;
  1961. int lv;
  1962. lv =sd->status.base_level*battle_config.pet_lv_rate/100;
  1963. if (lv < 0)
  1964. lv = 1;
  1965. if (lv != pd->pet.level || first)
  1966. {
  1967. struct status_data *bstat = &pd->db->status, *status = &pd->status;
  1968. pd->pet.level = lv;
  1969. if (!first) //Lv Up animation
  1970. clif_misceffect(&pd->bl, 0);
  1971. status->rhw.atk = (bstat->rhw.atk*lv)/pd->db->lv;
  1972. status->rhw.atk2 = (bstat->rhw.atk2*lv)/pd->db->lv;
  1973. status->str = (bstat->str*lv)/pd->db->lv;
  1974. status->agi = (bstat->agi*lv)/pd->db->lv;
  1975. status->vit = (bstat->vit*lv)/pd->db->lv;
  1976. status->int_ = (bstat->int_*lv)/pd->db->lv;
  1977. status->dex = (bstat->dex*lv)/pd->db->lv;
  1978. status->luk = (bstat->luk*lv)/pd->db->lv;
  1979. status->rhw.atk = cap_value(status->rhw.atk, 1, battle_config.pet_max_atk1);
  1980. status->rhw.atk2 = cap_value(status->rhw.atk2, 2, battle_config.pet_max_atk2);
  1981. status->str = cap_value(status->str,1,battle_config.pet_max_stats);
  1982. status->agi = cap_value(status->agi,1,battle_config.pet_max_stats);
  1983. status->vit = cap_value(status->vit,1,battle_config.pet_max_stats);
  1984. status->int_= cap_value(status->int_,1,battle_config.pet_max_stats);
  1985. status->dex = cap_value(status->dex,1,battle_config.pet_max_stats);
  1986. status->luk = cap_value(status->luk,1,battle_config.pet_max_stats);
  1987. status_calc_misc(&pd->bl, &pd->status, lv);
  1988. if (!first) //Not done the first time because the pet is not visible yet
  1989. clif_send_petstatus(sd);
  1990. }
  1991. } else if (first) {
  1992. status_calc_misc(&pd->bl, &pd->status, pd->db->lv);
  1993. if (!battle_config.pet_lv_rate && pd->pet.level != pd->db->lv)
  1994. pd->pet.level = pd->db->lv;
  1995. }
  1996. //Support rate modifier (1000 = 100%)
  1997. pd->rate_fix = 1000*(pd->pet.intimate - battle_config.pet_support_min_friendly)/(1000- battle_config.pet_support_min_friendly) +500;
  1998. if(battle_config.pet_support_rate != 100)
  1999. pd->rate_fix = pd->rate_fix*battle_config.pet_support_rate/100;
  2000. return 1;
  2001. }
  2002. /// Helper function for status_base_pc_maxhp(), used to pre-calculate the hp_sigma_val[] array
  2003. static void status_calc_sigma(void)
  2004. {
  2005. int i,j;
  2006. for(i = 0; i < CLASS_COUNT; i++)
  2007. {
  2008. unsigned int k = 0;
  2009. hp_sigma_val[i][0] = hp_sigma_val[i][1] = 0;
  2010. for(j = 2; j <= MAX_LEVEL; j++)
  2011. {
  2012. k += (hp_coefficient[i]*j + 50) / 100;
  2013. hp_sigma_val[i][j] = k;
  2014. if (k >= INT_MAX)
  2015. break; //Overflow protection. [Skotlex]
  2016. }
  2017. for(; j <= MAX_LEVEL; j++)
  2018. hp_sigma_val[i][j] = INT_MAX;
  2019. }
  2020. }
  2021. /// Calculates base MaxHP value according to class and base level
  2022. /// The recursive equation used to calculate level bonus is (using integer operations)
  2023. /// f(0) = 35 | f(x+1) = f(x) + A + (x + B)*C/D
  2024. /// which reduces to something close to
  2025. /// f(x) = 35 + x*(A + B*C/D) + sum(i=2..x){ i*C/D }
  2026. static unsigned int status_base_pc_maxhp(struct map_session_data* sd, struct status_data* status)
  2027. {
  2028. uint64 val = pc_class2idx(sd->status.class_);
  2029. val = 35 + sd->status.base_level*(int64)hp_coefficient2[val]/100 + hp_sigma_val[val][sd->status.base_level];
  2030. if((sd->class_&MAPID_UPPERMASK) == MAPID_NINJA || (sd->class_&MAPID_UPPERMASK) == MAPID_GUNSLINGER)
  2031. val += 100; //Since their HP can't be approximated well enough without this.
  2032. if((sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= 90 && pc_famerank(sd->status.char_id, MAPID_TAEKWON))
  2033. val *= 3; //Triple max HP for top ranking Taekwons over level 90.
  2034. if((sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE && sd->status.base_level >= 99)
  2035. val += 2000; //Supernovice lvl99 hp bonus.
  2036. val += val * status->vit/100; // +1% per each point of VIT
  2037. if (sd->class_&JOBL_UPPER)
  2038. val += val * 25/100; //Trans classes get a 25% hp bonus
  2039. else if (sd->class_&JOBL_BABY)
  2040. val -= val * 30/100; //Baby classes get a 30% hp penalty
  2041. return (unsigned int)val;
  2042. }
  2043. static unsigned int status_base_pc_maxsp(struct map_session_data* sd, struct status_data *status)
  2044. {
  2045. uint64 val;
  2046. val = 10 + sd->status.base_level*(int64)sp_coefficient[pc_class2idx(sd->status.class_)]/100;
  2047. val += val * status->int_/100;
  2048. if (sd->class_&JOBL_UPPER)
  2049. val += val * 25/100;
  2050. else if (sd->class_&JOBL_BABY)
  2051. val -= val * 30/100;
  2052. if ((sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= 90 && pc_famerank(sd->status.char_id, MAPID_TAEKWON))
  2053. val *= 3; //Triple max SP for top ranking Taekwons over level 90.
  2054. return (unsigned int)val;
  2055. }
  2056. //Calculates player data from scratch without counting SC adjustments.
  2057. //Should be invoked whenever players raise stats, learn passive skills or change equipment.
  2058. int status_calc_pc_(struct map_session_data* sd, bool first)
  2059. {
  2060. static int calculating = 0; //Check for recursive call preemption. [Skotlex]
  2061. struct status_data *status; // pointer to the player's base status
  2062. const struct status_change *sc = &sd->sc;
  2063. struct s_skill b_skill[MAX_SKILL]; // previous skill tree
  2064. int b_weight, b_max_weight, b_cart_weight_max, // previous weight
  2065. i, index, skill,refinedef=0;
  2066. int64 i64;
  2067. if (++calculating > 10) //Too many recursive calls!
  2068. return -1;
  2069. // remember player-specific values that are currently being shown to the client (for refresh purposes)
  2070. memcpy(b_skill, &sd->status.skill, sizeof(b_skill));
  2071. b_weight = sd->weight;
  2072. b_max_weight = sd->max_weight;
  2073. b_cart_weight_max = sd->cart_weight_max;
  2074. pc_calc_skilltree(sd); // SkillTree calculation
  2075. sd->max_weight = max_weight_base[pc_class2idx(sd->status.class_)]+sd->status.str*300;
  2076. if(first) {
  2077. //Load Hp/SP from char-received data.
  2078. sd->battle_status.hp = sd->status.hp;
  2079. sd->battle_status.sp = sd->status.sp;
  2080. sd->regen.sregen = &sd->sregen;
  2081. sd->regen.ssregen = &sd->ssregen;
  2082. sd->weight=0;
  2083. for(i=0;i<MAX_INVENTORY;i++){
  2084. if(sd->status.inventory[i].nameid==0 || sd->inventory_data[i] == NULL)
  2085. continue;
  2086. sd->weight += sd->inventory_data[i]->weight*sd->status.inventory[i].amount;
  2087. }
  2088. sd->cart_weight=0;
  2089. sd->cart_num=0;
  2090. for(i=0;i<MAX_CART;i++){
  2091. if(sd->status.cart[i].nameid==0)
  2092. continue;
  2093. sd->cart_weight+=itemdb_weight(sd->status.cart[i].nameid)*sd->status.cart[i].amount;
  2094. sd->cart_num++;
  2095. }
  2096. }
  2097. status = &sd->base_status;
  2098. // these are not zeroed. [zzo]
  2099. sd->hprate=100;
  2100. sd->sprate=100;
  2101. sd->castrate=100;
  2102. sd->delayrate=100;
  2103. sd->dsprate=100;
  2104. sd->hprecov_rate = 100;
  2105. sd->sprecov_rate = 100;
  2106. sd->matk_rate = 100;
  2107. sd->critical_rate = sd->hit_rate = sd->flee_rate = sd->flee2_rate = 100;
  2108. sd->def_rate = sd->def2_rate = sd->mdef_rate = sd->mdef2_rate = 100;
  2109. sd->regen.state.block = 0;
  2110. // zeroed arrays, order follows the order in pc.h.
  2111. // add new arrays to the end of zeroed area in pc.h (see comments) and size here. [zzo]
  2112. memset (sd->param_bonus, 0, sizeof(sd->param_bonus)
  2113. + sizeof(sd->param_equip)
  2114. + sizeof(sd->subele)
  2115. + sizeof(sd->subrace)
  2116. + sizeof(sd->subrace2)
  2117. + sizeof(sd->subsize)
  2118. + sizeof(sd->reseff)
  2119. + sizeof(sd->weapon_coma_ele)
  2120. + sizeof(sd->weapon_coma_race)
  2121. + sizeof(sd->weapon_atk)
  2122. + sizeof(sd->weapon_atk_rate)
  2123. + sizeof(sd->arrow_addele)
  2124. + sizeof(sd->arrow_addrace)
  2125. + sizeof(sd->arrow_addsize)
  2126. + sizeof(sd->magic_addele)
  2127. + sizeof(sd->magic_addrace)
  2128. + sizeof(sd->magic_addsize)
  2129. + sizeof(sd->magic_atk_ele)
  2130. + sizeof(sd->critaddrace)
  2131. + sizeof(sd->expaddrace)
  2132. + sizeof(sd->ignore_mdef)
  2133. + sizeof(sd->ignore_def)
  2134. + sizeof(sd->itemgrouphealrate)
  2135. + sizeof(sd->sp_gain_race)
  2136. + sizeof(sd->sp_gain_race_attack)
  2137. + sizeof(sd->hp_gain_race_attack)
  2138. );
  2139. memset (&sd->right_weapon.overrefine, 0, sizeof(sd->right_weapon) - sizeof(sd->right_weapon.atkmods));
  2140. memset (&sd->left_weapon.overrefine, 0, sizeof(sd->left_weapon) - sizeof(sd->left_weapon.atkmods));
  2141. if (sd->special_state.intravision && !sd->sc.data[SC_INTRAVISION]) //Clear intravision as long as nothing else is using it
  2142. clif_status_load(&sd->bl, SI_INTRAVISION, 0);
  2143. memset(&sd->special_state,0,sizeof(sd->special_state));
  2144. memset(&status->max_hp, 0, sizeof(struct status_data)-(sizeof(status->hp)+sizeof(status->sp)));
  2145. //FIXME: Most of these stuff should be calculated once, but how do I fix the memset above to do that? [Skotlex]
  2146. status->speed = DEFAULT_WALK_SPEED;
  2147. //Give them all modes except these (useful for clones)
  2148. status->mode = MD_MASK&~(MD_BOSS|MD_PLANT|MD_DETECTOR|MD_ANGRY|MD_TARGETWEAK);
  2149. status->size = (sd->class_&JOBL_BABY)?SZ_SMALL:SZ_MEDIUM;
  2150. if (battle_config.character_size && pc_isriding(sd)) { //[Lupus]
  2151. if (sd->class_&JOBL_BABY) {
  2152. if (battle_config.character_size&SZ_BIG)
  2153. status->size++;
  2154. } else
  2155. if(battle_config.character_size&SZ_MEDIUM)
  2156. status->size++;
  2157. }
  2158. status->aspd_rate = 1000;
  2159. status->ele_lv = 1;
  2160. status->race = RC_DEMIHUMAN;
  2161. //zero up structures...
  2162. memset(&sd->autospell,0,sizeof(sd->autospell)
  2163. + sizeof(sd->autospell2)
  2164. + sizeof(sd->autospell3)
  2165. + sizeof(sd->addeff)
  2166. + sizeof(sd->addeff2)
  2167. + sizeof(sd->addeff3)
  2168. + sizeof(sd->skillatk)
  2169. + sizeof(sd->skillusesprate)
  2170. + sizeof(sd->skillusesp)
  2171. + sizeof(sd->skillheal)
  2172. + sizeof(sd->skillheal2)
  2173. + sizeof(sd->hp_loss)
  2174. + sizeof(sd->sp_loss)
  2175. + sizeof(sd->hp_regen)
  2176. + sizeof(sd->sp_regen)
  2177. + sizeof(sd->skillblown)
  2178. + sizeof(sd->skillcast)
  2179. + sizeof(sd->add_def)
  2180. + sizeof(sd->add_mdef)
  2181. + sizeof(sd->add_mdmg)
  2182. + sizeof(sd->add_drop)
  2183. + sizeof(sd->itemhealrate)
  2184. + sizeof(sd->subele2)
  2185. + sizeof(sd->skillcooldown)
  2186. + sizeof(sd->skillfixcast)
  2187. + sizeof(sd->skillvarcast)
  2188. );
  2189. memset (&sd->bonus, 0,sizeof(sd->bonus));
  2190. // Autobonus
  2191. pc_delautobonus(sd,sd->autobonus,ARRAYLENGTH(sd->autobonus),true);
  2192. pc_delautobonus(sd,sd->autobonus2,ARRAYLENGTH(sd->autobonus2),true);
  2193. pc_delautobonus(sd,sd->autobonus3,ARRAYLENGTH(sd->autobonus3),true);
  2194. // Parse equipment.
  2195. for(i=0;i<EQI_MAX-1;i++) {
  2196. current_equip_item_index = index = sd->equip_index[i]; //We pass INDEX to current_equip_item_index - for EQUIP_SCRIPT (new cards solution) [Lupus]
  2197. if(index < 0)
  2198. continue;
  2199. if(i == EQI_HAND_R && sd->equip_index[EQI_HAND_L] == index)
  2200. continue;
  2201. if(i == EQI_HEAD_MID && sd->equip_index[EQI_HEAD_LOW] == index)
  2202. continue;
  2203. if(i == EQI_HEAD_TOP && (sd->equip_index[EQI_HEAD_MID] == index || sd->equip_index[EQI_HEAD_LOW] == index))
  2204. continue;
  2205. if(i == EQI_COSTUME_MID && sd->equip_index[EQI_COSTUME_LOW] == index)
  2206. continue;
  2207. if(i == EQI_COSTUME_TOP && (sd->equip_index[EQI_COSTUME_MID] == index || sd->equip_index[EQI_COSTUME_LOW] == index))
  2208. continue;
  2209. if(!sd->inventory_data[index])
  2210. continue;
  2211. status->def += sd->inventory_data[index]->def;
  2212. if(first && sd->inventory_data[index]->equip_script)
  2213. { //Execute equip-script on login
  2214. run_script(sd->inventory_data[index]->equip_script,0,sd->bl.id,0);
  2215. if (!calculating)
  2216. return 1;
  2217. }
  2218. // sanitize the refine level in case someone decreased the value inbetween
  2219. if (sd->status.inventory[index].refine > MAX_REFINE)
  2220. sd->status.inventory[index].refine = MAX_REFINE;
  2221. if(sd->inventory_data[index]->type == IT_WEAPON) {
  2222. int r,wlv = sd->inventory_data[index]->wlv;
  2223. struct weapon_data *wd;
  2224. struct weapon_atk *wa;
  2225. if (wlv >= REFINE_TYPE_MAX)
  2226. wlv = REFINE_TYPE_MAX - 1;
  2227. if(i == EQI_HAND_L && sd->status.inventory[index].equip == EQP_HAND_L) {
  2228. wd = &sd->left_weapon; // Left-hand weapon
  2229. wa = &status->lhw;
  2230. } else {
  2231. wd = &sd->right_weapon;
  2232. wa = &status->rhw;
  2233. }
  2234. wa->atk += sd->inventory_data[index]->atk;
  2235. if ( (r = sd->status.inventory[index].refine) )
  2236. wa->atk2 = refine_info[wlv].bonus[r-1] / 100;
  2237. #ifdef RENEWAL
  2238. wa->matk += sd->inventory_data[index]->matk;
  2239. wa->wlv = wlv;
  2240. if( r ) // renewal magic attack refine bonus
  2241. wa->matk += refine_info[wlv].bonus[r-1] / 100;
  2242. #endif
  2243. //Overrefine bonus.
  2244. if (r)
  2245. wd->overrefine = refine_info[wlv].randombonus_max[r-1] / 100;
  2246. wa->range += sd->inventory_data[index]->range;
  2247. if(sd->inventory_data[index]->script) {
  2248. if (wd == &sd->left_weapon) {
  2249. sd->state.lr_flag = 1;
  2250. run_script(sd->inventory_data[index]->script,0,sd->bl.id,0);
  2251. sd->state.lr_flag = 0;
  2252. } else
  2253. run_script(sd->inventory_data[index]->script,0,sd->bl.id,0);
  2254. if (!calculating) //Abort, run_script retriggered this. [Skotlex]
  2255. return 1;
  2256. }
  2257. if(sd->status.inventory[index].card[0]==CARD0_FORGE)
  2258. { // Forged weapon
  2259. wd->star += (sd->status.inventory[index].card[1]>>8);
  2260. if(wd->star >= 15) wd->star = 40; // 3 Star Crumbs now give +40 dmg
  2261. if(pc_famerank(MakeDWord(sd->status.inventory[index].card[2],sd->status.inventory[index].card[3]) ,MAPID_BLACKSMITH))
  2262. wd->star += 10;
  2263. if (!wa->ele) //Do not overwrite element from previous bonuses.
  2264. wa->ele = (sd->status.inventory[index].card[1]&0x0f);
  2265. }
  2266. }
  2267. else if(sd->inventory_data[index]->type == IT_ARMOR) {
  2268. int r;
  2269. if ( (r = sd->status.inventory[index].refine) )
  2270. refinedef += refine_info[REFINE_TYPE_ARMOR].bonus[r-1];
  2271. if(sd->inventory_data[index]->script) {
  2272. if( i == EQI_HAND_L ) //Shield
  2273. sd->state.lr_flag = 3;
  2274. run_script(sd->inventory_data[index]->script,0,sd->bl.id,0);
  2275. if( i == EQI_HAND_L ) //Shield
  2276. sd->state.lr_flag = 0;
  2277. if (!calculating) //Abort, run_script retriggered this. [Skotlex]
  2278. return 1;
  2279. }
  2280. }
  2281. }
  2282. if(sd->equip_index[EQI_AMMO] >= 0){
  2283. index = sd->equip_index[EQI_AMMO];
  2284. if(sd->inventory_data[index]){ // Arrows
  2285. sd->bonus.arrow_atk += sd->inventory_data[index]->atk;
  2286. sd->state.lr_flag = 2;
  2287. if( !itemdb_is_GNthrowable(sd->inventory_data[index]->nameid) ) //don't run scripts on throwable items
  2288. run_script(sd->inventory_data[index]->script,0,sd->bl.id,0);
  2289. sd->state.lr_flag = 0;
  2290. if (!calculating) //Abort, run_script retriggered status_calc_pc. [Skotlex]
  2291. return 1;
  2292. }
  2293. }
  2294. /* we've got combos to process */
  2295. if( sd->combos.count ) {
  2296. for( i = 0; i < sd->combos.count; i++ ) {
  2297. run_script(sd->combos.bonus[i],0,sd->bl.id,0);
  2298. if (!calculating) //Abort, run_script retriggered this.
  2299. return 1;
  2300. }
  2301. }
  2302. //Store equipment script bonuses
  2303. memcpy(sd->param_equip,sd->param_bonus,sizeof(sd->param_equip));
  2304. memset(sd->param_bonus, 0, sizeof(sd->param_bonus));
  2305. status->def += (refinedef+50)/100;
  2306. //Parse Cards
  2307. for(i=0;i<EQI_MAX-1;i++) {
  2308. current_equip_item_index = index = sd->equip_index[i]; //We pass INDEX to current_equip_item_index - for EQUIP_SCRIPT (new cards solution) [Lupus]
  2309. if(index < 0)
  2310. continue;
  2311. if(i == EQI_HAND_R && sd->equip_index[EQI_HAND_L] == index)
  2312. continue;
  2313. if(i == EQI_HEAD_MID && sd->equip_index[EQI_HEAD_LOW] == index)
  2314. continue;
  2315. if(i == EQI_HEAD_TOP && (sd->equip_index[EQI_HEAD_MID] == index || sd->equip_index[EQI_HEAD_LOW] == index))
  2316. continue;
  2317. if(sd->inventory_data[index]) {
  2318. int j,c;
  2319. struct item_data *data;
  2320. //Card script execution.
  2321. if(itemdb_isspecial(sd->status.inventory[index].card[0]))
  2322. continue;
  2323. for(j=0;j<MAX_SLOTS;j++){ // Uses MAX_SLOTS to support Soul Bound system [Inkfish]
  2324. current_equip_card_id= c= sd->status.inventory[index].card[j];
  2325. if(!c)
  2326. continue;
  2327. data = itemdb_exists(c);
  2328. if(!data)
  2329. continue;
  2330. if(first && data->equip_script)
  2331. { //Execute equip-script on login
  2332. run_script(data->equip_script,0,sd->bl.id,0);
  2333. if (!calculating)
  2334. return 1;
  2335. }
  2336. if(!data->script)
  2337. continue;
  2338. if(data->flag.no_equip) { //Card restriction checks.
  2339. if(map[sd->bl.m].flag.restricted && data->flag.no_equip&(8*map[sd->bl.m].zone))
  2340. continue;
  2341. if(!map_flag_vs(sd->bl.m) && data->flag.no_equip&1)
  2342. continue;
  2343. if(map[sd->bl.m].flag.pvp && data->flag.no_equip&2)
  2344. continue;
  2345. if(map_flag_gvg(sd->bl.m) && data->flag.no_equip&4)
  2346. continue;
  2347. if(map[sd->bl.m].flag.battleground && data->flag.no_equip&8)
  2348. continue;
  2349. }
  2350. if(i == EQI_HAND_L && sd->status.inventory[index].equip == EQP_HAND_L)
  2351. { //Left hand status.
  2352. sd->state.lr_flag = 1;
  2353. run_script(data->script,0,sd->bl.id,0);
  2354. sd->state.lr_flag = 0;
  2355. } else
  2356. run_script(data->script,0,sd->bl.id,0);
  2357. if (!calculating) //Abort, run_script his function. [Skotlex]
  2358. return 1;
  2359. }
  2360. }
  2361. }
  2362. if( sc->count && sc->data[SC_ITEMSCRIPT] )
  2363. {
  2364. struct item_data *data = itemdb_exists(sc->data[SC_ITEMSCRIPT]->val1);
  2365. if( data && data->script )
  2366. run_script(data->script,0,sd->bl.id,0);
  2367. }
  2368. if( sd->pd )
  2369. { // Pet Bonus
  2370. struct pet_data *pd = sd->pd;
  2371. if( pd && pd->petDB && pd->petDB->equip_script && pd->pet.intimate >= battle_config.pet_equip_min_friendly )
  2372. run_script(pd->petDB->equip_script,0,sd->bl.id,0);
  2373. if( pd && pd->pet.intimate > 0 && (!battle_config.pet_equip_required || pd->pet.equip > 0) && pd->state.skillbonus == 1 && pd->bonus )
  2374. pc_bonus(sd,pd->bonus->type, pd->bonus->val);
  2375. }
  2376. //param_bonus now holds card bonuses.
  2377. if(status->rhw.range < 1) status->rhw.range = 1;
  2378. if(status->lhw.range < 1) status->lhw.range = 1;
  2379. if(status->rhw.range < status->lhw.range)
  2380. status->rhw.range = status->lhw.range;
  2381. sd->bonus.double_rate += sd->bonus.double_add_rate;
  2382. sd->bonus.perfect_hit += sd->bonus.perfect_hit_add;
  2383. sd->bonus.splash_range += sd->bonus.splash_add_range;
  2384. // Damage modifiers from weapon type
  2385. sd->right_weapon.atkmods[0] = atkmods[0][sd->weapontype1];
  2386. sd->right_weapon.atkmods[1] = atkmods[1][sd->weapontype1];
  2387. sd->right_weapon.atkmods[2] = atkmods[2][sd->weapontype1];
  2388. sd->left_weapon.atkmods[0] = atkmods[0][sd->weapontype2];
  2389. sd->left_weapon.atkmods[1] = atkmods[1][sd->weapontype2];
  2390. sd->left_weapon.atkmods[2] = atkmods[2][sd->weapontype2];
  2391. if(pc_isriding(sd) &&
  2392. (sd->status.weapon==W_1HSPEAR || sd->status.weapon==W_2HSPEAR))
  2393. { //When Riding with spear, damage modifier to mid-class becomes
  2394. //same as versus large size.
  2395. sd->right_weapon.atkmods[1] = sd->right_weapon.atkmods[2];
  2396. sd->left_weapon.atkmods[1] = sd->left_weapon.atkmods[2];
  2397. }
  2398. // ----- STATS CALCULATION -----
  2399. // Job bonuses
  2400. index = pc_class2idx(sd->status.class_);
  2401. for(i=0;i<(int)sd->status.job_level && i<MAX_LEVEL;i++){
  2402. if(!job_bonus[index][i])
  2403. continue;
  2404. switch(job_bonus[index][i]) {
  2405. case 1: status->str++; break;
  2406. case 2: status->agi++; break;
  2407. case 3: status->vit++; break;
  2408. case 4: status->int_++; break;
  2409. case 5: status->dex++; break;
  2410. case 6: status->luk++; break;
  2411. }
  2412. }
  2413. // If a Super Novice has never died and is at least joblv 70, he gets all stats +10
  2414. if((sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE && sd->die_counter == 0 && sd->status.job_level >= 70){
  2415. status->str += 10;
  2416. status->agi += 10;
  2417. status->vit += 10;
  2418. status->int_+= 10;
  2419. status->dex += 10;
  2420. status->luk += 10;
  2421. }
  2422. // Absolute modifiers from passive skills
  2423. if(pc_checkskill(sd,BS_HILTBINDING)>0)
  2424. status->str++;
  2425. if((skill=pc_checkskill(sd,SA_DRAGONOLOGY))>0)
  2426. status->int_ += (skill+1)/2; // +1 INT / 2 lv
  2427. if((skill=pc_checkskill(sd,AC_OWL))>0)
  2428. status->dex += skill;
  2429. if((skill = pc_checkskill(sd,RA_RESEARCHTRAP))>0)
  2430. status->int_ += skill;
  2431. // Bonuses from cards and equipment as well as base stat, remember to avoid overflows.
  2432. i = status->str + sd->status.str + sd->param_bonus[0] + sd->param_equip[0];
  2433. status->str = cap_value(i,0,USHRT_MAX);
  2434. i = status->agi + sd->status.agi + sd->param_bonus[1] + sd->param_equip[1];
  2435. status->agi = cap_value(i,0,USHRT_MAX);
  2436. i = status->vit + sd->status.vit + sd->param_bonus[2] + sd->param_equip[2];
  2437. status->vit = cap_value(i,0,USHRT_MAX);
  2438. i = status->int_+ sd->status.int_+ sd->param_bonus[3] + sd->param_equip[3];
  2439. status->int_ = cap_value(i,0,USHRT_MAX);
  2440. i = status->dex + sd->status.dex + sd->param_bonus[4] + sd->param_equip[4];
  2441. status->dex = cap_value(i,0,USHRT_MAX);
  2442. i = status->luk + sd->status.luk + sd->param_bonus[5] + sd->param_equip[5];
  2443. status->luk = cap_value(i,0,USHRT_MAX);
  2444. // ------ BASE ATTACK CALCULATION ------
  2445. // Base batk value is set on status_calc_misc
  2446. // weapon-type bonus (FIXME: Why is the weapon_atk bonus applied to base attack?)
  2447. if (sd->status.weapon < MAX_WEAPON_TYPE && sd->weapon_atk[sd->status.weapon])
  2448. status->batk += sd->weapon_atk[sd->status.weapon];
  2449. // Absolute modifiers from passive skills
  2450. if((skill=pc_checkskill(sd,BS_HILTBINDING))>0)
  2451. status->batk += 4;
  2452. // ----- HP MAX CALCULATION -----
  2453. // Basic MaxHP value
  2454. //We hold the standard Max HP here to make it faster to recalculate on vit changes.
  2455. sd->status.max_hp = status_base_pc_maxhp(sd,status);
  2456. //This is done to handle underflows from negative Max HP bonuses
  2457. i64 = sd->status.max_hp + (int)status->max_hp;
  2458. status->max_hp = (unsigned int)cap_value(i64, 0, INT_MAX);
  2459. // Absolute modifiers from passive skills
  2460. if((skill=pc_checkskill(sd,CR_TRUST))>0)
  2461. status->max_hp += skill*200;
  2462. // Apply relative modifiers from equipment
  2463. if(sd->hprate < 0)
  2464. sd->hprate = 0;
  2465. if(sd->hprate!=100)
  2466. status->max_hp = (int64)status->max_hp * sd->hprate/100;
  2467. if(battle_config.hp_rate != 100)
  2468. status->max_hp = (int64)status->max_hp * battle_config.hp_rate/100;
  2469. if(status->max_hp > (unsigned int)battle_config.max_hp)
  2470. status->max_hp = battle_config.max_hp;
  2471. else if(!status->max_hp)
  2472. status->max_hp = 1;
  2473. // ----- SP MAX CALCULATION -----
  2474. // Basic MaxSP value
  2475. sd->status.max_sp = status_base_pc_maxsp(sd,status);
  2476. //This is done to handle underflows from negative Max SP bonuses
  2477. i64 = sd->status.max_sp + (int)status->max_sp;
  2478. status->max_sp = (unsigned int)cap_value(i64, 0, INT_MAX);
  2479. // Absolute modifiers from passive skills
  2480. if((skill=pc_checkskill(sd,SL_KAINA))>0)
  2481. status->max_sp += 30*skill;
  2482. if((skill=pc_checkskill(sd,HP_MEDITATIO))>0)
  2483. status->max_sp += (int64)status->max_sp * skill/100;
  2484. if((skill=pc_checkskill(sd,HW_SOULDRAIN))>0)
  2485. status->max_sp += (int64)status->max_sp * 2*skill/100;
  2486. if( (skill = pc_checkskill(sd,RA_RESEARCHTRAP)) > 0 )
  2487. status->max_sp += 200 + 20 * skill;
  2488. if( (skill = pc_checkskill(sd,WM_LESSON)) > 0 )
  2489. status->max_sp += 30 * skill;
  2490. // Apply relative modifiers from equipment
  2491. if(sd->sprate < 0)
  2492. sd->sprate = 0;
  2493. if(sd->sprate!=100)
  2494. status->max_sp = (int64)status->max_sp * sd->sprate/100;
  2495. if(battle_config.sp_rate != 100)
  2496. status->max_sp = (int64)status->max_sp * battle_config.sp_rate/100;
  2497. if(status->max_sp > (unsigned int)battle_config.max_sp)
  2498. status->max_sp = battle_config.max_sp;
  2499. else if(!status->max_sp)
  2500. status->max_sp = 1;
  2501. // ----- RESPAWN HP/SP -----
  2502. //
  2503. //Calc respawn hp and store it on base_status
  2504. if (sd->special_state.restart_full_recover)
  2505. {
  2506. status->hp = status->max_hp;
  2507. status->sp = status->max_sp;
  2508. } else {
  2509. if((sd->class_&MAPID_BASEMASK) == MAPID_NOVICE && !(sd->class_&JOBL_2)
  2510. && battle_config.restart_hp_rate < 50)
  2511. status->hp = status->max_hp>>1;
  2512. else
  2513. status->hp = (int64)status->max_hp * battle_config.restart_hp_rate/100;
  2514. if(!status->hp)
  2515. status->hp = 1;
  2516. status->sp = (int64)status->max_sp * battle_config.restart_sp_rate /100;
  2517. if( !status->sp ) /* the minimum for the respawn setting is SP:1 */
  2518. status->sp = 1;
  2519. }
  2520. // ----- MISC CALCULATION -----
  2521. status_calc_misc(&sd->bl, status, sd->status.base_level);
  2522. //Equipment modifiers for misc settings
  2523. if(sd->matk_rate < 0)
  2524. sd->matk_rate = 0;
  2525. if(sd->matk_rate != 100){
  2526. status->matk_max = status->matk_max * sd->matk_rate/100;
  2527. status->matk_min = status->matk_min * sd->matk_rate/100;
  2528. }
  2529. if(sd->hit_rate < 0)
  2530. sd->hit_rate = 0;
  2531. if(sd->hit_rate != 100)
  2532. status->hit = status->hit * sd->hit_rate/100;
  2533. if(sd->flee_rate < 0)
  2534. sd->flee_rate = 0;
  2535. if(sd->flee_rate != 100)
  2536. status->flee = status->flee * sd->flee_rate/100;
  2537. if(sd->def2_rate < 0)
  2538. sd->def2_rate = 0;
  2539. if(sd->def2_rate != 100)
  2540. status->def2 = status->def2 * sd->def2_rate/100;
  2541. if(sd->mdef2_rate < 0)
  2542. sd->mdef2_rate = 0;
  2543. if(sd->mdef2_rate != 100)
  2544. status->mdef2 = status->mdef2 * sd->mdef2_rate/100;
  2545. if(sd->critical_rate < 0)
  2546. sd->critical_rate = 0;
  2547. if(sd->critical_rate != 100)
  2548. status->cri = status->cri * sd->critical_rate/100;
  2549. if(sd->flee2_rate < 0)
  2550. sd->flee2_rate = 0;
  2551. if(sd->flee2_rate != 100)
  2552. status->flee2 = status->flee2 * sd->flee2_rate/100;
  2553. // ----- HIT CALCULATION -----
  2554. // Absolute modifiers from passive skills
  2555. if((skill=pc_checkskill(sd,BS_WEAPONRESEARCH))>0)
  2556. status->hit += skill*2;
  2557. if((skill=pc_checkskill(sd,AC_VULTURE))>0){
  2558. #ifndef RENEWAL
  2559. status->hit += skill;
  2560. #endif
  2561. if(sd->status.weapon == W_BOW)
  2562. status->rhw.range += skill;
  2563. }
  2564. if(sd->status.weapon >= W_REVOLVER && sd->status.weapon <= W_GRENADE)
  2565. {
  2566. if((skill=pc_checkskill(sd,GS_SINGLEACTION))>0)
  2567. status->hit += 2*skill;
  2568. if((skill=pc_checkskill(sd,GS_SNAKEEYE))>0) {
  2569. status->hit += skill;
  2570. status->rhw.range += skill;
  2571. }
  2572. }
  2573. // ----- FLEE CALCULATION -----
  2574. // Absolute modifiers from passive skills
  2575. if((skill=pc_checkskill(sd,TF_MISS))>0)
  2576. status->flee += skill*(sd->class_&JOBL_2 && (sd->class_&MAPID_BASEMASK) == MAPID_THIEF? 4 : 3);
  2577. if((skill=pc_checkskill(sd,MO_DODGE))>0)
  2578. status->flee += (skill*3)>>1;
  2579. // ----- EQUIPMENT-DEF CALCULATION -----
  2580. // Apply relative modifiers from equipment
  2581. if(sd->def_rate < 0)
  2582. sd->def_rate = 0;
  2583. if(sd->def_rate != 100) {
  2584. i = status->def * sd->def_rate/100;
  2585. status->def = cap_value(i, DEFTYPE_MIN, DEFTYPE_MAX);
  2586. }
  2587. #ifndef RENEWAL
  2588. if (!battle_config.weapon_defense_type && status->def > battle_config.max_def)
  2589. {
  2590. status->def2 += battle_config.over_def_bonus*(status->def -battle_config.max_def);
  2591. status->def = (unsigned char)battle_config.max_def;
  2592. }
  2593. #endif
  2594. // ----- EQUIPMENT-MDEF CALCULATION -----
  2595. // Apply relative modifiers from equipment
  2596. if(sd->mdef_rate < 0)
  2597. sd->mdef_rate = 0;
  2598. if(sd->mdef_rate != 100) {
  2599. i = status->mdef * sd->mdef_rate/100;
  2600. status->mdef = cap_value(i, DEFTYPE_MIN, DEFTYPE_MAX);
  2601. }
  2602. #ifndef RENEWAL
  2603. if (!battle_config.magic_defense_type && status->mdef > battle_config.max_def)
  2604. {
  2605. status->mdef2 += battle_config.over_def_bonus*(status->mdef -battle_config.max_def);
  2606. status->mdef = (signed char)battle_config.max_def;
  2607. }
  2608. #endif
  2609. // ----- ASPD CALCULATION -----
  2610. // Unlike other stats, ASPD rate modifiers from skills/SCs/items/etc are first all added together, then the final modifier is applied
  2611. // Basic ASPD value
  2612. i = status_base_amotion_pc(sd,status);
  2613. status->amotion = cap_value(i,((sd->class_&JOBL_THIRD) ? battle_config.max_third_aspd : battle_config.max_aspd),2000);
  2614. // Relative modifiers from passive skills
  2615. #ifndef RENEWAL_ASPD
  2616. if((skill=pc_checkskill(sd,SA_ADVANCEDBOOK))>0 && sd->status.weapon == W_BOOK)
  2617. status->aspd_rate -= 5*skill;
  2618. if((skill = pc_checkskill(sd,SG_DEVIL)) > 0 && !pc_nextjobexp(sd))
  2619. status->aspd_rate -= 30*skill;
  2620. if((skill=pc_checkskill(sd,GS_SINGLEACTION))>0 &&
  2621. (sd->status.weapon >= W_REVOLVER && sd->status.weapon <= W_GRENADE))
  2622. status->aspd_rate -= ((skill+1)/2) * 10;
  2623. if(pc_isriding(sd))
  2624. status->aspd_rate += 500-100*pc_checkskill(sd,KN_CAVALIERMASTERY);
  2625. else if(pc_isridingdragon(sd))
  2626. status->aspd_rate += 250-50*pc_checkskill(sd,RK_DRAGONTRAINING);
  2627. #else // needs more info
  2628. if((skill=pc_checkskill(sd,SA_ADVANCEDBOOK))>0 && sd->status.weapon == W_BOOK)
  2629. status->aspd_rate += 5*skill;
  2630. if((skill = pc_checkskill(sd,SG_DEVIL)) > 0 && !pc_nextjobexp(sd))
  2631. status->aspd_rate += 30*skill;
  2632. if((skill=pc_checkskill(sd,GS_SINGLEACTION))>0 &&
  2633. (sd->status.weapon >= W_REVOLVER && sd->status.weapon <= W_GRENADE))
  2634. status->aspd_rate += ((skill+1)/2) * 10;
  2635. if(pc_isriding(sd))
  2636. status->aspd_rate -= 500-100*pc_checkskill(sd,KN_CAVALIERMASTERY);
  2637. else if(pc_isridingdragon(sd))
  2638. status->aspd_rate -= 250-50*pc_checkskill(sd,RK_DRAGONTRAINING);
  2639. #endif
  2640. status->adelay = 2*status->amotion;
  2641. // ----- DMOTION -----
  2642. //
  2643. i = 800-status->agi*4;
  2644. status->dmotion = cap_value(i, 400, 800);
  2645. if(battle_config.pc_damage_delay_rate != 100)
  2646. status->dmotion = status->dmotion*battle_config.pc_damage_delay_rate/100;
  2647. // ----- MISC CALCULATIONS -----
  2648. // Weight
  2649. if((skill=pc_checkskill(sd,MC_INCCARRY))>0)
  2650. sd->max_weight += 2000*skill;
  2651. if(pc_isriding(sd) && pc_checkskill(sd,KN_RIDING)>0)
  2652. sd->max_weight += 10000;
  2653. else if(pc_isridingdragon(sd))
  2654. sd->max_weight += 5000+2000*pc_checkskill(sd,RK_DRAGONTRAINING);
  2655. if(sc->data[SC_KNOWLEDGE])
  2656. sd->max_weight += sd->max_weight*sc->data[SC_KNOWLEDGE]->val1/10;
  2657. if((skill=pc_checkskill(sd,ALL_INCCARRY))>0)
  2658. sd->max_weight += 2000*skill;
  2659. sd->cart_weight_max = battle_config.max_cart_weight + (pc_checkskill(sd, GN_REMODELING_CART)*5000);
  2660. if (pc_checkskill(sd,SM_MOVINGRECOVERY)>0)
  2661. sd->regen.state.walk = 1;
  2662. else
  2663. sd->regen.state.walk = 0;
  2664. // Skill SP cost
  2665. if((skill=pc_checkskill(sd,HP_MANARECHARGE))>0 )
  2666. sd->dsprate -= 4*skill;
  2667. if(sc->data[SC_SERVICE4U])
  2668. sd->dsprate -= sc->data[SC_SERVICE4U]->val3;
  2669. if(sc->data[SC_SPCOST_RATE])
  2670. sd->dsprate -= sc->data[SC_SPCOST_RATE]->val1;
  2671. //Underflow protections.
  2672. if(sd->dsprate < 0)
  2673. sd->dsprate = 0;
  2674. if(sd->castrate < 0)
  2675. sd->castrate = 0;
  2676. if(sd->delayrate < 0)
  2677. sd->delayrate = 0;
  2678. if(sd->hprecov_rate < 0)
  2679. sd->hprecov_rate = 0;
  2680. if(sd->sprecov_rate < 0)
  2681. sd->sprecov_rate = 0;
  2682. // Anti-element and anti-race
  2683. if((skill=pc_checkskill(sd,CR_TRUST))>0)
  2684. sd->subele[ELE_HOLY] += skill*5;
  2685. if((skill=pc_checkskill(sd,BS_SKINTEMPER))>0) {
  2686. sd->subele[ELE_NEUTRAL] += skill;
  2687. sd->subele[ELE_FIRE] += skill*4;
  2688. }
  2689. if((skill=pc_checkskill(sd,NC_RESEARCHFE))>0) {
  2690. sd->subele[ELE_EARTH] += skill*10;
  2691. sd->subele[ELE_FIRE] += skill*10;
  2692. }
  2693. if((skill=pc_checkskill(sd,SA_DRAGONOLOGY))>0 ){
  2694. skill = skill*4;
  2695. sd->right_weapon.addrace[RC_DRAGON]+=skill;
  2696. sd->left_weapon.addrace[RC_DRAGON]+=skill;
  2697. sd->magic_addrace[RC_DRAGON]+=skill;
  2698. sd->subrace[RC_DRAGON]+=skill;
  2699. }
  2700. if(sc->count){
  2701. if(sc->data[SC_CONCENTRATE]) { //Update the card-bonus data
  2702. sc->data[SC_CONCENTRATE]->val3 = sd->param_bonus[1]; //Agi
  2703. sc->data[SC_CONCENTRATE]->val4 = sd->param_bonus[4]; //Dex
  2704. }
  2705. if(sc->data[SC_SIEGFRIED]){
  2706. i = sc->data[SC_SIEGFRIED]->val2;
  2707. sd->subele[ELE_WATER] += i;
  2708. sd->subele[ELE_EARTH] += i;
  2709. sd->subele[ELE_FIRE] += i;
  2710. sd->subele[ELE_WIND] += i;
  2711. sd->subele[ELE_POISON] += i;
  2712. sd->subele[ELE_HOLY] += i;
  2713. sd->subele[ELE_DARK] += i;
  2714. sd->subele[ELE_GHOST] += i;
  2715. sd->subele[ELE_UNDEAD] += i;
  2716. }
  2717. if(sc->data[SC_PROVIDENCE]){
  2718. sd->subele[ELE_HOLY] += sc->data[SC_PROVIDENCE]->val2;
  2719. sd->subrace[RC_DEMON] += sc->data[SC_PROVIDENCE]->val2;
  2720. }
  2721. if(sc->data[SC_ARMOR_ELEMENT]) { //This status change should grant card-type elemental resist.
  2722. sd->subele[ELE_WATER] += sc->data[SC_ARMOR_ELEMENT]->val1;
  2723. sd->subele[ELE_EARTH] += sc->data[SC_ARMOR_ELEMENT]->val2;
  2724. sd->subele[ELE_FIRE] += sc->data[SC_ARMOR_ELEMENT]->val3;
  2725. sd->subele[ELE_WIND] += sc->data[SC_ARMOR_ELEMENT]->val4;
  2726. }
  2727. if(sc->data[SC_ARMOR_RESIST]) { // Undead Scroll
  2728. sd->subele[ELE_WATER] += sc->data[SC_ARMOR_RESIST]->val1;
  2729. sd->subele[ELE_EARTH] += sc->data[SC_ARMOR_RESIST]->val2;
  2730. sd->subele[ELE_FIRE] += sc->data[SC_ARMOR_RESIST]->val3;
  2731. sd->subele[ELE_WIND] += sc->data[SC_ARMOR_RESIST]->val4;
  2732. }
  2733. if( sc->data[SC_FIRE_CLOAK_OPTION] ) {
  2734. i = sc->data[SC_FIRE_CLOAK_OPTION]->val2;
  2735. sd->subele[ELE_FIRE] += i;
  2736. sd->subele[ELE_WATER] -= i;
  2737. }
  2738. if( sc->data[SC_WATER_DROP_OPTION] ) {
  2739. i = sc->data[SC_WATER_DROP_OPTION]->val2;
  2740. sd->subele[ELE_WATER] += i;
  2741. sd->subele[ELE_WIND] -= i;
  2742. }
  2743. if( sc->data[SC_WIND_CURTAIN_OPTION] ) {
  2744. i = sc->data[SC_WIND_CURTAIN_OPTION]->val2;
  2745. sd->subele[ELE_WIND] += i;
  2746. sd->subele[ELE_EARTH] -= i;
  2747. }
  2748. if( sc->data[SC_STONE_SHIELD_OPTION] ) {
  2749. i = sc->data[SC_STONE_SHIELD_OPTION]->val2;
  2750. sd->subele[ELE_EARTH] += i;
  2751. sd->subele[ELE_FIRE] -= i;
  2752. }
  2753. if( sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 3 )
  2754. sd->magic_addele[ELE_FIRE] += 25;
  2755. if( sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 3 )
  2756. sd->magic_addele[ELE_WATER] += 25;
  2757. if( sc->data[SC_WIND_INSIGNIA] && sc->data[SC_WIND_INSIGNIA]->val1 == 3 )
  2758. sd->magic_addele[ELE_WIND] += 25;
  2759. if( sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 3 )
  2760. sd->magic_addele[ELE_EARTH] += 25;
  2761. }
  2762. status_cpy(&sd->battle_status, status);
  2763. // ----- CLIENT-SIDE REFRESH -----
  2764. if(!sd->bl.prev) {
  2765. //Will update on LoadEndAck
  2766. calculating = 0;
  2767. return 0;
  2768. }
  2769. if(memcmp(b_skill,sd->status.skill,sizeof(sd->status.skill)))
  2770. clif_skillinfoblock(sd);
  2771. if(b_weight != sd->weight)
  2772. clif_updatestatus(sd,SP_WEIGHT);
  2773. if(b_max_weight != sd->max_weight) {
  2774. clif_updatestatus(sd,SP_MAXWEIGHT);
  2775. pc_updateweightstatus(sd);
  2776. }
  2777. if( b_cart_weight_max != sd->cart_weight_max ) {
  2778. clif_updatestatus(sd,SP_CARTINFO);
  2779. }
  2780. calculating = 0;
  2781. return 0;
  2782. }
  2783. int status_calc_mercenary_(struct mercenary_data *md, bool first)
  2784. {
  2785. struct status_data *status = &md->base_status;
  2786. struct s_mercenary *merc = &md->mercenary;
  2787. if( first )
  2788. {
  2789. memcpy(status, &md->db->status, sizeof(struct status_data));
  2790. status->mode = MD_CANMOVE|MD_CANATTACK;
  2791. status->hp = status->max_hp;
  2792. status->sp = status->max_sp;
  2793. md->battle_status.hp = merc->hp;
  2794. md->battle_status.sp = merc->sp;
  2795. }
  2796. status_calc_misc(&md->bl, status, md->db->lv);
  2797. status_cpy(&md->battle_status, status);
  2798. return 0;
  2799. }
  2800. int status_calc_homunculus_(struct homun_data *hd, bool first)
  2801. {
  2802. struct status_data *status = &hd->base_status;
  2803. struct s_homunculus *hom = &hd->homunculus;
  2804. int skill;
  2805. int amotion;
  2806. status->str = hom->str / 10;
  2807. status->agi = hom->agi / 10;
  2808. status->vit = hom->vit / 10;
  2809. status->dex = hom->dex / 10;
  2810. status->int_ = hom->int_ / 10;
  2811. status->luk = hom->luk / 10;
  2812. if (first) { //[orn]
  2813. const struct s_homunculus_db *db = hd->homunculusDB;
  2814. status->def_ele = db->element;
  2815. status->ele_lv = 1;
  2816. status->race = db->race;
  2817. status->size = (hom->class_ == db->evo_class)?db->evo_size:db->base_size;
  2818. status->rhw.range = 1 + status->size;
  2819. status->mode = MD_CANMOVE|MD_CANATTACK;
  2820. status->speed = DEFAULT_WALK_SPEED;
  2821. if (battle_config.hom_setting&0x8 && hd->master)
  2822. status->speed = status_get_speed(&hd->master->bl);
  2823. status->hp = 1;
  2824. status->sp = 1;
  2825. }
  2826. skill = hom->level/10 + status->vit/5;
  2827. status->def = cap_value(skill, 0, 99);
  2828. skill = hom->level/10 + status->int_/5;
  2829. status->mdef = cap_value(skill, 0, 99);
  2830. status->max_hp = hom->max_hp ;
  2831. status->max_sp = hom->max_sp ;
  2832. merc_hom_calc_skilltree(hd, 0);
  2833. if((skill=merc_hom_checkskill(hd,HAMI_SKIN)) > 0)
  2834. status->def += skill * 4;
  2835. if((skill = merc_hom_checkskill(hd,HVAN_INSTRUCT)) > 0)
  2836. {
  2837. status->int_ += 1 +skill/2 +skill/4 +skill/5;
  2838. status->str += 1 +skill/3 +skill/3 +skill/4;
  2839. }
  2840. if((skill=merc_hom_checkskill(hd,HAMI_SKIN)) > 0)
  2841. status->max_hp += skill * 2 * status->max_hp / 100;
  2842. if((skill = merc_hom_checkskill(hd,HLIF_BRAIN)) > 0)
  2843. status->max_sp += (1 +skill/2 -skill/4 +skill/5) * status->max_sp / 100 ;
  2844. if (first) {
  2845. hd->battle_status.hp = hom->hp ;
  2846. hd->battle_status.sp = hom->sp ;
  2847. }
  2848. status->rhw.atk = status->dex;
  2849. status->rhw.atk2 = status->str + hom->level;
  2850. status->aspd_rate = 1000;
  2851. amotion = (1000 -4*status->agi -status->dex) * hd->homunculusDB->baseASPD/1000;
  2852. status->amotion = cap_value(amotion,battle_config.max_aspd,2000);
  2853. status->adelay = status->amotion; //It seems adelay = amotion for Homunculus.
  2854. status_calc_misc(&hd->bl, status, hom->level);
  2855. #ifdef RENEWAL
  2856. status->matk_max = status->matk_min;
  2857. #endif
  2858. status_cpy(&hd->battle_status, status);
  2859. return 1;
  2860. }
  2861. int status_calc_elemental_(struct elemental_data *ed, bool first) {
  2862. struct status_data *status = &ed->base_status;
  2863. struct s_elemental *ele = &ed->elemental;
  2864. struct map_session_data *sd = ed->master;
  2865. if( !sd )
  2866. return 0;
  2867. if( first ) {
  2868. memcpy(status, &ed->db->status, sizeof(struct status_data));
  2869. if( !ele->mode )
  2870. status->mode = EL_MODE_PASSIVE;
  2871. else
  2872. status->mode = ele->mode;
  2873. status_calc_misc(&ed->bl, status, 0);
  2874. status->max_hp = ele->max_hp;
  2875. status->max_sp = ele->max_sp;
  2876. status->hp = ele->hp;
  2877. status->sp = ele->sp;
  2878. status->rhw.atk = ele->atk;
  2879. status->rhw.atk2 = ele->atk2;
  2880. status->matk_min += ele->matk;
  2881. status->def += ele->def;
  2882. status->mdef += ele->mdef;
  2883. status->flee = ele->flee;
  2884. status->hit = ele->hit;
  2885. memcpy(&ed->battle_status,status,sizeof(struct status_data));
  2886. } else {
  2887. status_calc_misc(&ed->bl, status, 0);
  2888. status_cpy(&ed->battle_status, status);
  2889. }
  2890. return 0;
  2891. }
  2892. int status_calc_npc_(struct npc_data *nd, bool first) {
  2893. struct status_data *status = &nd->status;
  2894. if (!nd)
  2895. return 0;
  2896. if (first) {
  2897. status->hp = 1;
  2898. status->sp = 1;
  2899. status->max_hp = 1;
  2900. status->max_sp = 1;
  2901. status->def_ele = ELE_NEUTRAL;
  2902. status->ele_lv = 1;
  2903. status->race = RC_DEMIHUMAN;
  2904. status->size = nd->size;
  2905. status->rhw.range = 1 + status->size;
  2906. status->mode = (MD_CANMOVE|MD_CANATTACK);
  2907. status->speed = nd->speed;
  2908. }
  2909. status->str = nd->stat_point;
  2910. status->agi = nd->stat_point;
  2911. status->vit = nd->stat_point;
  2912. status->int_= nd->stat_point;
  2913. status->dex = nd->stat_point;
  2914. status->luk = nd->stat_point;
  2915. status_calc_misc(&nd->bl, status, nd->level);
  2916. status_cpy(&nd->status, status);
  2917. return 0;
  2918. }
  2919. static unsigned short status_calc_str(struct block_list *,struct status_change *,int);
  2920. static unsigned short status_calc_agi(struct block_list *,struct status_change *,int);
  2921. static unsigned short status_calc_vit(struct block_list *,struct status_change *,int);
  2922. static unsigned short status_calc_int(struct block_list *,struct status_change *,int);
  2923. static unsigned short status_calc_dex(struct block_list *,struct status_change *,int);
  2924. static unsigned short status_calc_luk(struct block_list *,struct status_change *,int);
  2925. static unsigned short status_calc_batk(struct block_list *,struct status_change *,int);
  2926. static unsigned short status_calc_watk(struct block_list *,struct status_change *,int);
  2927. static unsigned short status_calc_matk(struct block_list *,struct status_change *,int);
  2928. static signed short status_calc_hit(struct block_list *,struct status_change *,int);
  2929. static signed short status_calc_critical(struct block_list *,struct status_change *,int);
  2930. static signed short status_calc_flee(struct block_list *,struct status_change *,int);
  2931. static signed short status_calc_flee2(struct block_list *,struct status_change *,int);
  2932. static defType status_calc_def(struct block_list *bl, struct status_change *sc, int);
  2933. static signed short status_calc_def2(struct block_list *,struct status_change *,int);
  2934. static defType status_calc_mdef(struct block_list *bl, struct status_change *sc, int);
  2935. static signed short status_calc_mdef2(struct block_list *,struct status_change *,int);
  2936. static unsigned short status_calc_speed(struct block_list *,struct status_change *,int);
  2937. static short status_calc_aspd_rate(struct block_list *,struct status_change *,int);
  2938. static unsigned short status_calc_dmotion(struct block_list *bl, struct status_change *sc, int dmotion);
  2939. #ifdef RENEWAL_ASPD
  2940. static short status_calc_aspd(struct block_list *bl, struct status_change *sc, short flag);
  2941. #endif
  2942. static short status_calc_fix_aspd(struct block_list *bl, struct status_change *sc, int);
  2943. static unsigned int status_calc_maxhp(struct block_list *,struct status_change *, uint64);
  2944. static unsigned int status_calc_maxsp(struct block_list *,struct status_change *,unsigned int);
  2945. static unsigned char status_calc_element(struct block_list *bl, struct status_change *sc, int element);
  2946. static unsigned char status_calc_element_lv(struct block_list *bl, struct status_change *sc, int lv);
  2947. static unsigned short status_calc_mode(struct block_list *bl, struct status_change *sc, int mode);
  2948. #ifdef RENEWAL
  2949. static unsigned short status_calc_ematk(struct block_list *,struct status_change *,int);
  2950. #endif
  2951. //Calculates base regen values.
  2952. void status_calc_regen(struct block_list *bl, struct status_data *status, struct regen_data *regen)
  2953. {
  2954. struct map_session_data *sd;
  2955. int val, skill, reg_flag;
  2956. if( !(bl->type&BL_REGEN) || !regen )
  2957. return;
  2958. sd = BL_CAST(BL_PC,bl);
  2959. val = 1 + (status->vit/5) + (status->max_hp/200);
  2960. if( sd && sd->hprecov_rate != 100 )
  2961. val = val*sd->hprecov_rate/100;
  2962. reg_flag = bl->type == BL_PC ? 0 : 1;
  2963. regen->hp = cap_value(val, reg_flag, SHRT_MAX);
  2964. val = 1 + (status->int_/6) + (status->max_sp/100);
  2965. if( status->int_ >= 120 )
  2966. val += ((status->int_-120)>>1) + 4;
  2967. if( sd && sd->sprecov_rate != 100 )
  2968. val = val*sd->sprecov_rate/100;
  2969. regen->sp = cap_value(val, reg_flag, SHRT_MAX);
  2970. if( sd )
  2971. {
  2972. struct regen_data_sub *sregen;
  2973. if( (skill=pc_checkskill(sd,HP_MEDITATIO)) > 0 )
  2974. {
  2975. val = regen->sp*(100+3*skill)/100;
  2976. regen->sp = cap_value(val, 1, SHRT_MAX);
  2977. }
  2978. //Only players have skill/sitting skill regen for now.
  2979. sregen = regen->sregen;
  2980. val = 0;
  2981. if( (skill=pc_checkskill(sd,SM_RECOVERY)) > 0 )
  2982. val += skill*5 + skill*status->max_hp/500;
  2983. sregen->hp = cap_value(val, 0, SHRT_MAX);
  2984. val = 0;
  2985. if( (skill=pc_checkskill(sd,MG_SRECOVERY)) > 0 )
  2986. val += skill*3 + skill*status->max_sp/500;
  2987. if( (skill=pc_checkskill(sd,NJ_NINPOU)) > 0 )
  2988. val += skill*3 + skill*status->max_sp/500;
  2989. if( (skill=pc_checkskill(sd,WM_LESSON)) > 0 )
  2990. val += 3 + 3 * skill;
  2991. sregen->sp = cap_value(val, 0, SHRT_MAX);
  2992. // Skill-related recovery (only when sit)
  2993. sregen = regen->ssregen;
  2994. val = 0;
  2995. if( (skill=pc_checkskill(sd,MO_SPIRITSRECOVERY)) > 0 )
  2996. val += skill*4 + skill*status->max_hp/500;
  2997. if( (skill=pc_checkskill(sd,TK_HPTIME)) > 0 && sd->state.rest )
  2998. val += skill*30 + skill*status->max_hp/500;
  2999. sregen->hp = cap_value(val, 0, SHRT_MAX);
  3000. val = 0;
  3001. if( (skill=pc_checkskill(sd,TK_SPTIME)) > 0 && sd->state.rest )
  3002. {
  3003. val += skill*3 + skill*status->max_sp/500;
  3004. if ((skill=pc_checkskill(sd,SL_KAINA)) > 0) //Power up Enjoyable Rest
  3005. val += (30+10*skill)*val/100;
  3006. }
  3007. if( (skill=pc_checkskill(sd,MO_SPIRITSRECOVERY)) > 0 )
  3008. val += skill*2 + skill*status->max_sp/500;
  3009. sregen->sp = cap_value(val, 0, SHRT_MAX);
  3010. }
  3011. if( bl->type == BL_HOM ) {
  3012. struct homun_data *hd = (TBL_HOM*)bl;
  3013. if( (skill = merc_hom_checkskill(hd,HAMI_SKIN)) > 0 ) {
  3014. val = regen->hp*(100+5*skill)/100;
  3015. regen->hp = cap_value(val, 1, SHRT_MAX);
  3016. }
  3017. if( (skill = merc_hom_checkskill(hd,HLIF_BRAIN)) > 0 ) {
  3018. val = regen->sp*(100+3*skill)/100;
  3019. regen->sp = cap_value(val, 1, SHRT_MAX);
  3020. }
  3021. } else if( bl->type == BL_MER ) {
  3022. val = (status->max_hp * status->vit / 10000 + 1) * 6;
  3023. regen->hp = cap_value(val, 1, SHRT_MAX);
  3024. val = (status->max_sp * (status->int_ + 10) / 750) + 1;
  3025. regen->sp = cap_value(val, 1, SHRT_MAX);
  3026. } else if( bl->type == BL_ELEM ) {
  3027. val = (status->max_hp * status->vit / 10000 + 1) * 6;
  3028. regen->hp = cap_value(val, 1, SHRT_MAX);
  3029. val = (status->max_sp * (status->int_ + 10) / 750) + 1;
  3030. regen->sp = cap_value(val, 1, SHRT_MAX);
  3031. }
  3032. }
  3033. //Calculates SC related regen rates.
  3034. void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, struct status_change *sc)
  3035. {
  3036. if (!(bl->type&BL_REGEN) || !regen)
  3037. return;
  3038. regen->flag = RGN_HP|RGN_SP;
  3039. if(regen->sregen)
  3040. {
  3041. if (regen->sregen->hp)
  3042. regen->flag|=RGN_SHP;
  3043. if (regen->sregen->sp)
  3044. regen->flag|=RGN_SSP;
  3045. regen->sregen->rate.hp = regen->sregen->rate.sp = 1;
  3046. }
  3047. if (regen->ssregen)
  3048. {
  3049. if (regen->ssregen->hp)
  3050. regen->flag|=RGN_SHP;
  3051. if (regen->ssregen->sp)
  3052. regen->flag|=RGN_SSP;
  3053. regen->ssregen->rate.hp = regen->ssregen->rate.sp = 1;
  3054. }
  3055. regen->rate.hp = regen->rate.sp = 1;
  3056. if (!sc || !sc->count)
  3057. return;
  3058. if (
  3059. (sc->data[SC_POISON] && !sc->data[SC_SLOWPOISON])
  3060. || (sc->data[SC_DPOISON] && !sc->data[SC_SLOWPOISON])
  3061. || sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST]
  3062. || sc->data[SC_TRICKDEAD]
  3063. || sc->data[SC_BLEEDING]
  3064. || sc->data[SC_MAGICMUSHROOM]
  3065. || sc->data[SC_RAISINGDRAGON]
  3066. || sc->data[SC_SATURDAYNIGHTFEVER]
  3067. ) //No regen
  3068. regen->flag = 0;
  3069. if (
  3070. sc->data[SC_DANCING] || sc->data[SC_OBLIVIONCURSE] || sc->data[SC_MAXIMIZEPOWER]
  3071. || (
  3072. (bl->type == BL_PC && ((TBL_PC*)bl)->class_&MAPID_UPPERMASK) == MAPID_MONK &&
  3073. (sc->data[SC_EXTREMITYFIST] || (sc->data[SC_EXPLOSIONSPIRITS] && (!sc->data[SC_SPIRIT] || sc->data[SC_SPIRIT]->val2 != SL_MONK)))
  3074. )
  3075. ) //No natural SP regen
  3076. regen->flag &=~RGN_SP;
  3077. if(
  3078. sc->data[SC_TENSIONRELAX]
  3079. ) {
  3080. regen->rate.hp += 2;
  3081. if (regen->sregen)
  3082. regen->sregen->rate.hp += 3;
  3083. }
  3084. if (sc->data[SC_MAGNIFICAT])
  3085. {
  3086. regen->rate.hp += 1;
  3087. regen->rate.sp += 1;
  3088. }
  3089. if (sc->data[SC_REGENERATION])
  3090. {
  3091. const struct status_change_entry *sce = sc->data[SC_REGENERATION];
  3092. if (!sce->val4)
  3093. {
  3094. regen->rate.hp += sce->val2;
  3095. regen->rate.sp += sce->val3;
  3096. } else
  3097. regen->flag&=~sce->val4; //Remove regen as specified by val4
  3098. }
  3099. if(sc->data[SC_GT_REVITALIZE]){
  3100. regen->hp = cap_value(regen->hp*sc->data[SC_GT_REVITALIZE]->val3/100, 1, SHRT_MAX);
  3101. regen->state.walk= 1;
  3102. }
  3103. if ((sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 1) //if insignia lvl 1
  3104. || (sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 1)
  3105. || (sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 1)
  3106. || (sc->data[SC_WIND_INSIGNIA] && sc->data[SC_WIND_INSIGNIA]->val1 == 1))
  3107. regen->rate.hp *= 2;
  3108. }
  3109. void status_calc_state( struct block_list *bl, struct status_change *sc, enum scs_flag flag, bool start ) {
  3110. /* no sc at all, we can zero without any extra weight over our conciousness */
  3111. if( !sc->count ) {
  3112. memset(&sc->cant, 0, sizeof (sc->cant));
  3113. return;
  3114. }
  3115. /* can move? */
  3116. if( flag&SCS_NOMOVE ) {
  3117. if( !(flag&SCS_NOMOVECOND) ) {
  3118. sc->cant.move += ( start ? 1 : -1 );
  3119. } else if(
  3120. (sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_SELF) // cannot move while gospel is in effect
  3121. || (sc->data[SC_BASILICA] && sc->data[SC_BASILICA]->val4 == bl->id) // Basilica caster cannot move
  3122. || (sc->data[SC_GRAVITATION] && sc->data[SC_GRAVITATION]->val3 == BCT_SELF)
  3123. || (sc->data[SC_CRYSTALIZE] && bl->type != BL_MOB)
  3124. || (sc->data[SC_CAMOUFLAGE] && sc->data[SC_CAMOUFLAGE]->val1 < 3
  3125. && !(sc->data[SC_CAMOUFLAGE]->val3&1))
  3126. ) {
  3127. sc->cant.move += ( start ? 1 : -1 );
  3128. }
  3129. }
  3130. /* can't use skills */
  3131. if( flag&SCS_NOCAST ) {
  3132. if( !(flag&SCS_NOCASTCOND) ) {
  3133. sc->cant.cast += ( start ? 1 : -1 );
  3134. } else if( (sc->data[SC_CRYSTALIZE] && bl->type != BL_MOB) ){
  3135. sc->cant.cast += ( start ? 1 : -1 );
  3136. }
  3137. }
  3138. /* player-only states */
  3139. if( bl->type == BL_PC ) {
  3140. /* can pick items? */
  3141. if( flag&SCS_NOPICKITEM ) {
  3142. if( !(flag&SCS_NOPICKITEMCOND) ) {
  3143. sc->cant.pickup += ( start ? 1 : -1 );
  3144. } else if( (sc->data[SC_NOCHAT] && sc->data[SC_NOCHAT]->val1&MANNER_NOITEM) ) {
  3145. sc->cant.pickup += ( start ? 1 : -1 );
  3146. }
  3147. }
  3148. /* can drop items? */
  3149. if( flag&SCS_NODROPITEM ) {
  3150. if( !(flag&SCS_NODROPITEMCOND) ) {
  3151. sc->cant.drop += ( start ? 1 : -1 );
  3152. } else if( (sc->data[SC_NOCHAT] && sc->data[SC_NOCHAT]->val1&MANNER_NOITEM) ) {
  3153. sc->cant.drop += ( start ? 1 : -1 );
  3154. }
  3155. }
  3156. }
  3157. return;
  3158. }
  3159. /// Recalculates parts of an object's battle status according to the specified flags.
  3160. /// @param flag bitfield of values from enum scb_flag
  3161. void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
  3162. {
  3163. const struct status_data *b_status = status_get_base_status(bl);
  3164. struct status_data *status = status_get_status_data(bl);
  3165. struct status_change *sc = status_get_sc(bl);
  3166. TBL_PC *sd = BL_CAST(BL_PC,bl);
  3167. int temp;
  3168. if (!b_status || !status)
  3169. return;
  3170. if((!(bl->type&BL_REGEN)) && (!sc || !sc->count)) { //No difference.
  3171. status_cpy(status, b_status);
  3172. return;
  3173. }
  3174. if(flag&SCB_STR) {
  3175. status->str = status_calc_str(bl, sc, b_status->str);
  3176. flag|=SCB_BATK;
  3177. if( bl->type&BL_HOM )
  3178. flag |= SCB_WATK;
  3179. }
  3180. if(flag&SCB_AGI) {
  3181. status->agi = status_calc_agi(bl, sc, b_status->agi);
  3182. flag|=SCB_FLEE
  3183. #ifdef RENEWAL
  3184. |SCB_DEF2
  3185. #endif
  3186. ;
  3187. if( bl->type&(BL_PC|BL_HOM) )
  3188. flag |= SCB_ASPD|SCB_DSPD;
  3189. }
  3190. if(flag&SCB_VIT) {
  3191. status->vit = status_calc_vit(bl, sc, b_status->vit);
  3192. flag|=SCB_DEF2|SCB_MDEF2;
  3193. if( bl->type&(BL_PC|BL_HOM|BL_MER|BL_ELEM) )
  3194. flag |= SCB_MAXHP;
  3195. if( bl->type&BL_HOM )
  3196. flag |= SCB_DEF;
  3197. }
  3198. if(flag&SCB_INT) {
  3199. status->int_ = status_calc_int(bl, sc, b_status->int_);
  3200. flag|=SCB_MATK|SCB_MDEF2;
  3201. if( bl->type&(BL_PC|BL_HOM|BL_MER|BL_ELEM) )
  3202. flag |= SCB_MAXSP;
  3203. if( bl->type&BL_HOM )
  3204. flag |= SCB_MDEF;
  3205. }
  3206. if(flag&SCB_DEX) {
  3207. status->dex = status_calc_dex(bl, sc, b_status->dex);
  3208. flag|=SCB_BATK|SCB_HIT
  3209. #ifdef RENEWAL
  3210. |SCB_MATK|SCB_MDEF2
  3211. #endif
  3212. ;
  3213. if( bl->type&(BL_PC|BL_HOM) )
  3214. flag |= SCB_ASPD;
  3215. if( bl->type&BL_HOM )
  3216. flag |= SCB_WATK;
  3217. }
  3218. if(flag&SCB_LUK) {
  3219. status->luk = status_calc_luk(bl, sc, b_status->luk);
  3220. flag|=SCB_BATK|SCB_CRI|SCB_FLEE2
  3221. #ifdef RENEWAL
  3222. |SCB_MATK|SCB_HIT|SCB_FLEE
  3223. #endif
  3224. ;
  3225. }
  3226. if(flag&SCB_BATK && b_status->batk) {
  3227. status->batk = status_base_atk(bl,status);
  3228. temp = b_status->batk - status_base_atk(bl,b_status);
  3229. if (temp)
  3230. {
  3231. temp += status->batk;
  3232. status->batk = cap_value(temp, 0, USHRT_MAX);
  3233. }
  3234. status->batk = status_calc_batk(bl, sc, status->batk);
  3235. }
  3236. if(flag&SCB_WATK) {
  3237. status->rhw.atk = status_calc_watk(bl, sc, b_status->rhw.atk);
  3238. if (!sd) //Should not affect weapon refine bonus
  3239. status->rhw.atk2 = status_calc_watk(bl, sc, b_status->rhw.atk2);
  3240. if(b_status->lhw.atk) {
  3241. if (sd) {
  3242. sd->state.lr_flag = 1;
  3243. status->lhw.atk = status_calc_watk(bl, sc, b_status->lhw.atk);
  3244. sd->state.lr_flag = 0;
  3245. } else {
  3246. status->lhw.atk = status_calc_watk(bl, sc, b_status->lhw.atk);
  3247. status->lhw.atk2= status_calc_watk(bl, sc, b_status->lhw.atk2);
  3248. }
  3249. }
  3250. if( bl->type&BL_HOM )
  3251. {
  3252. status->rhw.atk += (status->dex - b_status->dex);
  3253. status->rhw.atk2 += (status->str - b_status->str);
  3254. if( status->rhw.atk2 < status->rhw.atk )
  3255. status->rhw.atk2 = status->rhw.atk;
  3256. }
  3257. }
  3258. if(flag&SCB_HIT) {
  3259. if (status->dex == b_status->dex
  3260. #ifdef RENEWAL
  3261. && status->luk == b_status->luk
  3262. #endif
  3263. )
  3264. status->hit = status_calc_hit(bl, sc, b_status->hit);
  3265. else
  3266. status->hit = status_calc_hit(bl, sc, b_status->hit + (status->dex - b_status->dex)
  3267. #ifdef RENEWAL
  3268. + (status->luk/3 - b_status->luk/3)
  3269. #endif
  3270. );
  3271. }
  3272. if(flag&SCB_FLEE) {
  3273. if (status->agi == b_status->agi
  3274. #ifdef RENEWAL
  3275. && status->luk == b_status->luk
  3276. #endif
  3277. )
  3278. status->flee = status_calc_flee(bl, sc, b_status->flee);
  3279. else
  3280. status->flee = status_calc_flee(bl, sc, b_status->flee +(status->agi - b_status->agi)
  3281. #ifdef RENEWAL
  3282. + (status->luk/5 - b_status->luk/5)
  3283. #endif
  3284. );
  3285. }
  3286. if(flag&SCB_DEF)
  3287. {
  3288. status->def = status_calc_def(bl, sc, b_status->def);
  3289. if( bl->type&BL_HOM )
  3290. status->def += (status->vit/5 - b_status->vit/5);
  3291. }
  3292. if(flag&SCB_DEF2) {
  3293. if (status->vit == b_status->vit
  3294. #ifdef RENEWAL
  3295. && status->agi == b_status->agi
  3296. #endif
  3297. )
  3298. status->def2 = status_calc_def2(bl, sc, b_status->def2);
  3299. else
  3300. status->def2 = status_calc_def2(bl, sc, b_status->def2
  3301. #ifdef RENEWAL
  3302. + (int)( ((float)status->vit/2 - (float)b_status->vit/2) + ((float)status->agi/5 - (float)b_status->agi/5) )
  3303. #else
  3304. + (status->vit - b_status->vit)
  3305. #endif
  3306. );
  3307. }
  3308. if(flag&SCB_MDEF)
  3309. {
  3310. status->mdef = status_calc_mdef(bl, sc, b_status->mdef);
  3311. if( bl->type&BL_HOM )
  3312. status->mdef += (status->int_/5 - b_status->int_/5);
  3313. }
  3314. if(flag&SCB_MDEF2) {
  3315. if (status->int_ == b_status->int_ && status->vit == b_status->vit
  3316. #ifdef RENEWAL
  3317. && status->dex == b_status->dex
  3318. #endif
  3319. )
  3320. status->mdef2 = status_calc_mdef2(bl, sc, b_status->mdef2);
  3321. else
  3322. status->mdef2 = status_calc_mdef2(bl, sc, b_status->mdef2 +(status->int_ - b_status->int_)
  3323. #ifdef RENEWAL
  3324. + (int)( ((float)status->dex/5 - (float)b_status->dex/5) + ((float)status->vit/5 - (float)b_status->vit/5) )
  3325. #else
  3326. + ((status->vit - b_status->vit)>>1)
  3327. #endif
  3328. );
  3329. }
  3330. if(flag&SCB_SPEED) {
  3331. struct unit_data *ud = unit_bl2ud(bl);
  3332. status->speed = status_calc_speed(bl, sc, b_status->speed);
  3333. //Re-walk to adjust speed (we do not check if walktimer != INVALID_TIMER
  3334. //because if you step on something while walking, the moment this
  3335. //piece of code triggers the walk-timer is set on INVALID_TIMER) [Skotlex]
  3336. if (ud)
  3337. ud->state.change_walk_target = ud->state.speed_changed = 1;
  3338. if( bl->type&BL_PC && status->speed < battle_config.max_walk_speed )
  3339. status->speed = battle_config.max_walk_speed;
  3340. if( bl->type&BL_HOM && battle_config.hom_setting&0x8 && ((TBL_HOM*)bl)->master)
  3341. status->speed = status_get_speed(&((TBL_HOM*)bl)->master->bl);
  3342. }
  3343. if(flag&SCB_CRI && b_status->cri) {
  3344. if (status->luk == b_status->luk)
  3345. status->cri = status_calc_critical(bl, sc, b_status->cri);
  3346. else
  3347. status->cri = status_calc_critical(bl, sc, b_status->cri + 3*(status->luk - b_status->luk));
  3348. /**
  3349. * after status_calc_critical so the bonus is applied despite if you have or not a sc bugreport:5240
  3350. **/
  3351. if( bl->type == BL_PC && ((TBL_PC*)bl)->status.weapon == W_KATAR )
  3352. status->cri <<= 1;
  3353. }
  3354. if(flag&SCB_FLEE2 && b_status->flee2) {
  3355. if (status->luk == b_status->luk)
  3356. status->flee2 = status_calc_flee2(bl, sc, b_status->flee2);
  3357. else
  3358. status->flee2 = status_calc_flee2(bl, sc, b_status->flee2 +(status->luk - b_status->luk));
  3359. }
  3360. if(flag&SCB_ATK_ELE) {
  3361. status->rhw.ele = status_calc_attack_element(bl, sc, b_status->rhw.ele);
  3362. if (sd) sd->state.lr_flag = 1;
  3363. status->lhw.ele = status_calc_attack_element(bl, sc, b_status->lhw.ele);
  3364. if (sd) sd->state.lr_flag = 0;
  3365. }
  3366. if(flag&SCB_DEF_ELE) {
  3367. status->def_ele = status_calc_element(bl, sc, b_status->def_ele);
  3368. status->ele_lv = status_calc_element_lv(bl, sc, b_status->ele_lv);
  3369. }
  3370. if(flag&SCB_MODE)
  3371. {
  3372. status->mode = status_calc_mode(bl, sc, b_status->mode);
  3373. //Since mode changed, reset their state.
  3374. if (!(status->mode&MD_CANATTACK))
  3375. unit_stop_attack(bl);
  3376. if (!(status->mode&MD_CANMOVE))
  3377. unit_stop_walking(bl,1);
  3378. }
  3379. // No status changes alter these yet.
  3380. // if(flag&SCB_SIZE)
  3381. // if(flag&SCB_RACE)
  3382. // if(flag&SCB_RANGE)
  3383. if(flag&SCB_MAXHP) {
  3384. if( bl->type&BL_PC )
  3385. {
  3386. status->max_hp = status_base_pc_maxhp(sd,status);
  3387. status->max_hp += b_status->max_hp - sd->status.max_hp;
  3388. status->max_hp = status_calc_maxhp(bl, sc, status->max_hp);
  3389. if( status->max_hp > (unsigned int)battle_config.max_hp )
  3390. status->max_hp = (unsigned int)battle_config.max_hp;
  3391. }
  3392. else
  3393. {
  3394. status->max_hp = status_calc_maxhp(bl, sc, b_status->max_hp);
  3395. }
  3396. if( status->hp > status->max_hp ) //FIXME: Should perhaps a status_zap should be issued?
  3397. {
  3398. status->hp = status->max_hp;
  3399. if( sd ) clif_updatestatus(sd,SP_HP);
  3400. }
  3401. }
  3402. if(flag&SCB_MAXSP) {
  3403. if( bl->type&BL_PC )
  3404. {
  3405. status->max_sp = status_base_pc_maxsp(sd,status);
  3406. status->max_sp += b_status->max_sp - sd->status.max_sp;
  3407. status->max_sp = status_calc_maxsp(&sd->bl, &sd->sc, status->max_sp);
  3408. if( status->max_sp > (unsigned int)battle_config.max_sp )
  3409. status->max_sp = (unsigned int)battle_config.max_sp;
  3410. }
  3411. else
  3412. {
  3413. status->max_sp = status_calc_maxsp(bl, sc, b_status->max_sp);
  3414. }
  3415. if( status->sp > status->max_sp )
  3416. {
  3417. status->sp = status->max_sp;
  3418. if( sd ) clif_updatestatus(sd,SP_SP);
  3419. }
  3420. }
  3421. if(flag&SCB_MATK) {
  3422. #ifndef RENEWAL
  3423. status->matk_min = status_base_matk_min(status) + (sd?sd->bonus.ematk:0);
  3424. status->matk_max = status_base_matk_max(status) + (sd?sd->bonus.ematk:0);
  3425. #else
  3426. /**
  3427. * RE MATK Formula (from irowiki:http://irowiki.org/wiki/MATK)
  3428. * MATK = (sMATK + wMATK + eMATK) * Multiplicative Modifiers
  3429. **/
  3430. status->matk_min = status->matk_max = status_base_matk(status, status_get_lv(bl));
  3431. if( bl->type&BL_PC ){
  3432. // Any +MATK you get from skills and cards, including cards in weapon, is added here.
  3433. if( sd->bonus.ematk > 0 ){
  3434. status->matk_max += sd->bonus.ematk;
  3435. status->matk_min += sd->bonus.ematk;
  3436. }
  3437. status->matk_min = status_calc_ematk(bl, sc, status->matk_min);
  3438. status->matk_max = status_calc_ematk(bl, sc, status->matk_max);
  3439. //This is the only portion in MATK that varies depending on the weapon level and refinement rate.
  3440. if( status->rhw.matk > 0 ){
  3441. int wMatk = status->rhw.matk;
  3442. int variance = wMatk * status->rhw.wlv / 10;
  3443. status->matk_min += wMatk - variance;
  3444. status->matk_max += wMatk + variance;
  3445. }
  3446. }
  3447. #endif
  3448. if (bl->type&BL_PC && sd->matk_rate != 100) {
  3449. status->matk_max = status->matk_max * sd->matk_rate/100;
  3450. status->matk_min = status->matk_min * sd->matk_rate/100;
  3451. }
  3452. status->matk_min = status_calc_matk(bl, sc, status->matk_min);
  3453. status->matk_max = status_calc_matk(bl, sc, status->matk_max);
  3454. if ((bl->type&BL_HOM && battle_config.hom_setting&0x20) //Hom Min Matk is always the same as Max Matk
  3455. || sc->data[SC_RECOGNIZEDSPELL])
  3456. status->matk_min = status->matk_max;
  3457. #ifdef RENEWAL
  3458. if( sd && sd->right_weapon.overrefine > 0){
  3459. status->matk_min++;
  3460. status->matk_max += sd->right_weapon.overrefine - 1;
  3461. }
  3462. #endif
  3463. }
  3464. if(flag&SCB_ASPD) {
  3465. int amotion;
  3466. if( bl->type&BL_PC )
  3467. {
  3468. amotion = status_base_amotion_pc(sd,status);
  3469. #ifndef RENEWAL_ASPD
  3470. status->aspd_rate = status_calc_aspd_rate(bl, sc, b_status->aspd_rate);
  3471. if(status->aspd_rate != 1000)
  3472. amotion = amotion*status->aspd_rate/1000;
  3473. #else
  3474. // aspd = baseaspd + floor(sqrt((agi^2/2) + (dex^2/5))/4 + (potskillbonus*agi/200))
  3475. amotion -= (int)(sqrt( (pow(status->agi, 2) / 2) + (pow(status->dex, 2) / 5) ) / 4 + (status_calc_aspd(bl, sc, 1) * status->agi / 200)) * 10;
  3476. if( (status_calc_aspd(bl, sc, 2) + status->aspd_rate2) != 0 ) // RE ASPD percertage modifier
  3477. amotion -= ( amotion - ((sd->class_&JOBL_THIRD) ? battle_config.max_third_aspd : battle_config.max_aspd) )
  3478. * (status_calc_aspd(bl, sc, 2) + status->aspd_rate2) / 100;
  3479. if(status->aspd_rate != 1000) // absolute percentage modifier
  3480. amotion = ( 200 - (200-amotion/10) * status->aspd_rate / 1000 ) * 10;
  3481. #endif
  3482. amotion = status_calc_fix_aspd(bl, sc, amotion);
  3483. status->amotion = cap_value(amotion,((sd->class_&JOBL_THIRD) ? battle_config.max_third_aspd : battle_config.max_aspd),2000);
  3484. status->adelay = 2*status->amotion;
  3485. }
  3486. else
  3487. if( bl->type&BL_HOM )
  3488. {
  3489. amotion = (1000 -4*status->agi -status->dex) * ((TBL_HOM*)bl)->homunculusDB->baseASPD/1000;
  3490. status->aspd_rate = status_calc_aspd_rate(bl, sc, b_status->aspd_rate);
  3491. if(status->aspd_rate != 1000)
  3492. amotion = amotion*status->aspd_rate/1000;
  3493. amotion = status_calc_fix_aspd(bl, sc, amotion);
  3494. status->amotion = cap_value(amotion,battle_config.max_aspd,2000);
  3495. status->adelay = status->amotion;
  3496. }
  3497. else // mercenary and mobs
  3498. {
  3499. amotion = b_status->amotion;
  3500. status->aspd_rate = status_calc_aspd_rate(bl, sc, b_status->aspd_rate);
  3501. if(status->aspd_rate != 1000)
  3502. amotion = amotion*status->aspd_rate/1000;
  3503. amotion = status_calc_fix_aspd(bl, sc, amotion);
  3504. status->amotion = cap_value(amotion, battle_config.monster_max_aspd, 2000);
  3505. temp = b_status->adelay*status->aspd_rate/1000;
  3506. status->adelay = cap_value(temp, battle_config.monster_max_aspd*2, 4000);
  3507. }
  3508. }
  3509. if(flag&SCB_DSPD) {
  3510. int dmotion;
  3511. if( bl->type&BL_PC )
  3512. {
  3513. if (b_status->agi == status->agi)
  3514. status->dmotion = status_calc_dmotion(bl, sc, b_status->dmotion);
  3515. else {
  3516. dmotion = 800-status->agi*4;
  3517. status->dmotion = cap_value(dmotion, 400, 800);
  3518. if(battle_config.pc_damage_delay_rate != 100)
  3519. status->dmotion = status->dmotion*battle_config.pc_damage_delay_rate/100;
  3520. //It's safe to ignore b_status->dmotion since no bonus affects it.
  3521. status->dmotion = status_calc_dmotion(bl, sc, status->dmotion);
  3522. }
  3523. }
  3524. else
  3525. if( bl->type&BL_HOM )
  3526. {
  3527. dmotion = 800-status->agi*4;
  3528. status->dmotion = cap_value(dmotion, 400, 800);
  3529. status->dmotion = status_calc_dmotion(bl, sc, b_status->dmotion);
  3530. }
  3531. else // mercenary and mobs
  3532. {
  3533. status->dmotion = status_calc_dmotion(bl, sc, b_status->dmotion);
  3534. }
  3535. }
  3536. if(flag&(SCB_VIT|SCB_MAXHP|SCB_INT|SCB_MAXSP) && bl->type&BL_REGEN)
  3537. status_calc_regen(bl, status, status_get_regen_data(bl));
  3538. if(flag&SCB_REGEN && bl->type&BL_REGEN)
  3539. status_calc_regen_rate(bl, status_get_regen_data(bl), sc);
  3540. }
  3541. /// Recalculates parts of an object's base status and battle status according to the specified flags.
  3542. /// Also sends updates to the client wherever applicable.
  3543. /// @param flag bitfield of values from enum scb_flag
  3544. /// @param first if true, will cause status_calc_* functions to run their base status initialization code
  3545. void status_calc_bl_(struct block_list* bl, enum scb_flag flag, bool first)
  3546. {
  3547. struct status_data b_status; // previous battle status
  3548. struct status_data* status; // pointer to current battle status
  3549. // remember previous values
  3550. status = status_get_status_data(bl);
  3551. memcpy(&b_status, status, sizeof(struct status_data));
  3552. if( flag&SCB_BASE ) {// calculate the object's base status too
  3553. switch( bl->type ) {
  3554. case BL_PC: status_calc_pc_(BL_CAST(BL_PC,bl), first); break;
  3555. case BL_MOB: status_calc_mob_(BL_CAST(BL_MOB,bl), first); break;
  3556. case BL_PET: status_calc_pet_(BL_CAST(BL_PET,bl), first); break;
  3557. case BL_HOM: status_calc_homunculus_(BL_CAST(BL_HOM,bl), first); break;
  3558. case BL_MER: status_calc_mercenary_(BL_CAST(BL_MER,bl), first); break;
  3559. case BL_ELEM: status_calc_elemental_(BL_CAST(BL_ELEM,bl), first); break;
  3560. case BL_NPC: status_calc_npc_(BL_CAST(BL_NPC,bl), first); break;
  3561. }
  3562. }
  3563. if( bl->type == BL_PET )
  3564. return; // pets are not affected by statuses
  3565. if( first && bl->type == BL_MOB )
  3566. return; // assume there will be no statuses active
  3567. status_calc_bl_main(bl, flag);
  3568. if( first && bl->type == BL_HOM )
  3569. return; // client update handled by caller
  3570. // compare against new values and send client updates
  3571. if( bl->type == BL_PC )
  3572. {
  3573. TBL_PC* sd = BL_CAST(BL_PC, bl);
  3574. if(b_status.str != status->str)
  3575. clif_updatestatus(sd,SP_STR);
  3576. if(b_status.agi != status->agi)
  3577. clif_updatestatus(sd,SP_AGI);
  3578. if(b_status.vit != status->vit)
  3579. clif_updatestatus(sd,SP_VIT);
  3580. if(b_status.int_ != status->int_)
  3581. clif_updatestatus(sd,SP_INT);
  3582. if(b_status.dex != status->dex)
  3583. clif_updatestatus(sd,SP_DEX);
  3584. if(b_status.luk != status->luk)
  3585. clif_updatestatus(sd,SP_LUK);
  3586. if(b_status.hit != status->hit)
  3587. clif_updatestatus(sd,SP_HIT);
  3588. if(b_status.flee != status->flee)
  3589. clif_updatestatus(sd,SP_FLEE1);
  3590. if(b_status.amotion != status->amotion)
  3591. clif_updatestatus(sd,SP_ASPD);
  3592. if(b_status.speed != status->speed)
  3593. clif_updatestatus(sd,SP_SPEED);
  3594. if(b_status.batk != status->batk
  3595. #ifndef RENEWAL
  3596. || b_status.rhw.atk != status->rhw.atk || b_status.lhw.atk != status->lhw.atk
  3597. #endif
  3598. )
  3599. clif_updatestatus(sd,SP_ATK1);
  3600. if(b_status.def != status->def){
  3601. clif_updatestatus(sd,SP_DEF1);
  3602. #ifdef RENEWAL
  3603. clif_updatestatus(sd,SP_DEF2);
  3604. #endif
  3605. }
  3606. if(b_status.rhw.atk2 != status->rhw.atk2 || b_status.lhw.atk2 != status->lhw.atk2
  3607. #ifdef RENEWAL
  3608. || b_status.rhw.atk != status->rhw.atk || b_status.lhw.atk != status->lhw.atk
  3609. #endif
  3610. )
  3611. clif_updatestatus(sd,SP_ATK2);
  3612. if(b_status.def2 != status->def2){
  3613. clif_updatestatus(sd,SP_DEF2);
  3614. #ifdef RENEWAL
  3615. clif_updatestatus(sd,SP_DEF1);
  3616. #endif
  3617. }
  3618. if(b_status.flee2 != status->flee2)
  3619. clif_updatestatus(sd,SP_FLEE2);
  3620. if(b_status.cri != status->cri)
  3621. clif_updatestatus(sd,SP_CRITICAL);
  3622. #ifndef RENEWAL
  3623. if(b_status.matk_max != status->matk_max)
  3624. clif_updatestatus(sd,SP_MATK1);
  3625. if(b_status.matk_min != status->matk_min)
  3626. clif_updatestatus(sd,SP_MATK2);
  3627. #else
  3628. if(b_status.matk_max != status->matk_max || b_status.matk_min != status->matk_min){
  3629. clif_updatestatus(sd,SP_MATK2);
  3630. clif_updatestatus(sd,SP_MATK1);
  3631. }
  3632. #endif
  3633. if(b_status.mdef != status->mdef){
  3634. clif_updatestatus(sd,SP_MDEF1);
  3635. #ifdef RENEWAL
  3636. clif_updatestatus(sd,SP_MDEF2);
  3637. #endif
  3638. }
  3639. if(b_status.mdef2 != status->mdef2){
  3640. clif_updatestatus(sd,SP_MDEF2);
  3641. #ifdef RENEWAL
  3642. clif_updatestatus(sd,SP_MDEF1);
  3643. #endif
  3644. }
  3645. if(b_status.rhw.range != status->rhw.range)
  3646. clif_updatestatus(sd,SP_ATTACKRANGE);
  3647. if(b_status.max_hp != status->max_hp)
  3648. clif_updatestatus(sd,SP_MAXHP);
  3649. if(b_status.max_sp != status->max_sp)
  3650. clif_updatestatus(sd,SP_MAXSP);
  3651. if(b_status.hp != status->hp)
  3652. clif_updatestatus(sd,SP_HP);
  3653. if(b_status.sp != status->sp)
  3654. clif_updatestatus(sd,SP_SP);
  3655. } else if( bl->type == BL_HOM ) {
  3656. TBL_HOM* hd = BL_CAST(BL_HOM, bl);
  3657. if( hd->master && memcmp(&b_status, status, sizeof(struct status_data)) != 0 )
  3658. clif_hominfo(hd->master,hd,0);
  3659. } else if( bl->type == BL_MER ) {
  3660. TBL_MER* md = BL_CAST(BL_MER, bl);
  3661. if( b_status.rhw.atk != status->rhw.atk || b_status.rhw.atk2 != status->rhw.atk2 )
  3662. clif_mercenary_updatestatus(md->master, SP_ATK1);
  3663. if( b_status.matk_max != status->matk_max )
  3664. clif_mercenary_updatestatus(md->master, SP_MATK1);
  3665. if( b_status.hit != status->hit )
  3666. clif_mercenary_updatestatus(md->master, SP_HIT);
  3667. if( b_status.cri != status->cri )
  3668. clif_mercenary_updatestatus(md->master, SP_CRITICAL);
  3669. if( b_status.def != status->def )
  3670. clif_mercenary_updatestatus(md->master, SP_DEF1);
  3671. if( b_status.mdef != status->mdef )
  3672. clif_mercenary_updatestatus(md->master, SP_MDEF1);
  3673. if( b_status.flee != status->flee )
  3674. clif_mercenary_updatestatus(md->master, SP_MERCFLEE);
  3675. if( b_status.amotion != status->amotion )
  3676. clif_mercenary_updatestatus(md->master, SP_ASPD);
  3677. if( b_status.max_hp != status->max_hp )
  3678. clif_mercenary_updatestatus(md->master, SP_MAXHP);
  3679. if( b_status.max_sp != status->max_sp )
  3680. clif_mercenary_updatestatus(md->master, SP_MAXSP);
  3681. if( b_status.hp != status->hp )
  3682. clif_mercenary_updatestatus(md->master, SP_HP);
  3683. if( b_status.sp != status->sp )
  3684. clif_mercenary_updatestatus(md->master, SP_SP);
  3685. } else if( bl->type == BL_ELEM ) {
  3686. TBL_ELEM* ed = BL_CAST(BL_ELEM, bl);
  3687. if( b_status.max_hp != status->max_hp )
  3688. clif_elemental_updatestatus(ed->master, SP_MAXHP);
  3689. if( b_status.max_sp != status->max_sp )
  3690. clif_elemental_updatestatus(ed->master, SP_MAXSP);
  3691. if( b_status.hp != status->hp )
  3692. clif_elemental_updatestatus(ed->master, SP_HP);
  3693. if( b_status.sp != status->sp )
  3694. clif_mercenary_updatestatus(ed->master, SP_SP);
  3695. }
  3696. }
  3697. /*==========================================
  3698. * Apply shared stat mods from status changes [DracoRPG]
  3699. *------------------------------------------*/
  3700. static unsigned short status_calc_str(struct block_list *bl, struct status_change *sc, int str)
  3701. {
  3702. if(!sc || !sc->count)
  3703. return cap_value(str,0,USHRT_MAX);
  3704. if(sc->data[SC_HARMONIZE]) {
  3705. str -= sc->data[SC_HARMONIZE]->val2;
  3706. return (unsigned short)cap_value(str,0,USHRT_MAX);
  3707. }
  3708. if(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH && str < 50)
  3709. return 50;
  3710. if(sc->data[SC_INCALLSTATUS])
  3711. str += sc->data[SC_INCALLSTATUS]->val1;
  3712. if(sc->data[SC_INCSTR])
  3713. str += sc->data[SC_INCSTR]->val1;
  3714. if(sc->data[SC_STRFOOD])
  3715. str += sc->data[SC_STRFOOD]->val1;
  3716. if(sc->data[SC_FOOD_STR_CASH])
  3717. str += sc->data[SC_FOOD_STR_CASH]->val1;
  3718. if(sc->data[SC_BATTLEORDERS])
  3719. str += 5;
  3720. if(sc->data[SC_LEADERSHIP])
  3721. str += sc->data[SC_LEADERSHIP]->val1;
  3722. if(sc->data[SC_LOUD])
  3723. str += 4;
  3724. if(sc->data[SC_TRUESIGHT])
  3725. str += 5;
  3726. if(sc->data[SC_SPURT])
  3727. str += 10;
  3728. if(sc->data[SC_NEN])
  3729. str += sc->data[SC_NEN]->val1;
  3730. if(sc->data[SC_BLESSING]){
  3731. if(sc->data[SC_BLESSING]->val2)
  3732. str += sc->data[SC_BLESSING]->val2;
  3733. else
  3734. str >>= 1;
  3735. }
  3736. if(sc->data[SC_MARIONETTE])
  3737. str -= ((sc->data[SC_MARIONETTE]->val3)>>16)&0xFF;
  3738. if(sc->data[SC_MARIONETTE2])
  3739. str += ((sc->data[SC_MARIONETTE2]->val3)>>16)&0xFF;
  3740. if(sc->data[SC_GIANTGROWTH])
  3741. str += 30;
  3742. if(sc->data[SC_SAVAGE_STEAK])
  3743. str += sc->data[SC_SAVAGE_STEAK]->val1;
  3744. if(sc->data[SC_INSPIRATION])
  3745. str += sc->data[SC_INSPIRATION]->val3;
  3746. if(sc->data[SC_STOMACHACHE])
  3747. str -= sc->data[SC_STOMACHACHE]->val1;
  3748. if(sc->data[SC_KYOUGAKU])
  3749. str -= sc->data[SC_KYOUGAKU]->val2;
  3750. return (unsigned short)cap_value(str,0,USHRT_MAX);
  3751. }
  3752. static unsigned short status_calc_agi(struct block_list *bl, struct status_change *sc, int agi)
  3753. {
  3754. if(!sc || !sc->count)
  3755. return cap_value(agi,0,USHRT_MAX);
  3756. if(sc->data[SC_HARMONIZE]) {
  3757. agi -= sc->data[SC_HARMONIZE]->val2;
  3758. return (unsigned short)cap_value(agi,0,USHRT_MAX);
  3759. }
  3760. if(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH && agi < 50)
  3761. return 50;
  3762. if(sc->data[SC_CONCENTRATE] && !sc->data[SC_QUAGMIRE])
  3763. agi += (agi-sc->data[SC_CONCENTRATE]->val3)*sc->data[SC_CONCENTRATE]->val2/100;
  3764. if(sc->data[SC_INCALLSTATUS])
  3765. agi += sc->data[SC_INCALLSTATUS]->val1;
  3766. if(sc->data[SC_INCAGI])
  3767. agi += sc->data[SC_INCAGI]->val1;
  3768. if(sc->data[SC_AGIFOOD])
  3769. agi += sc->data[SC_AGIFOOD]->val1;
  3770. if(sc->data[SC_FOOD_AGI_CASH])
  3771. agi += sc->data[SC_FOOD_AGI_CASH]->val1;
  3772. if(sc->data[SC_SOULCOLD])
  3773. agi += sc->data[SC_SOULCOLD]->val1;
  3774. if(sc->data[SC_TRUESIGHT])
  3775. agi += 5;
  3776. if(sc->data[SC_INCREASEAGI])
  3777. agi += sc->data[SC_INCREASEAGI]->val2;
  3778. if(sc->data[SC_INCREASING])
  3779. agi += 4; // added based on skill updates [Reddozen]
  3780. if(sc->data[SC_DECREASEAGI])
  3781. agi -= sc->data[SC_DECREASEAGI]->val2;
  3782. if(sc->data[SC_QUAGMIRE])
  3783. agi -= sc->data[SC_QUAGMIRE]->val2;
  3784. if(sc->data[SC_SUITON] && sc->data[SC_SUITON]->val3)
  3785. agi -= sc->data[SC_SUITON]->val2;
  3786. if(sc->data[SC_MARIONETTE])
  3787. agi -= ((sc->data[SC_MARIONETTE]->val3)>>8)&0xFF;
  3788. if(sc->data[SC_MARIONETTE2])
  3789. agi += ((sc->data[SC_MARIONETTE2]->val3)>>8)&0xFF;
  3790. if(sc->data[SC_ADORAMUS])
  3791. agi -= sc->data[SC_ADORAMUS]->val2;
  3792. if(sc->data[SC_DROCERA_HERB_STEAMED])
  3793. agi += sc->data[SC_DROCERA_HERB_STEAMED]->val1;
  3794. if(sc->data[SC_INSPIRATION])
  3795. agi += sc->data[SC_INSPIRATION]->val3;
  3796. if(sc->data[SC_STOMACHACHE])
  3797. agi -= sc->data[SC_STOMACHACHE]->val1;
  3798. if(sc->data[SC_KYOUGAKU])
  3799. agi -= sc->data[SC_KYOUGAKU]->val2;
  3800. return (unsigned short)cap_value(agi,0,USHRT_MAX);
  3801. }
  3802. static unsigned short status_calc_vit(struct block_list *bl, struct status_change *sc, int vit)
  3803. {
  3804. if(!sc || !sc->count)
  3805. return cap_value(vit,0,USHRT_MAX);
  3806. if(sc->data[SC_HARMONIZE]) {
  3807. vit -= sc->data[SC_HARMONIZE]->val2;
  3808. return (unsigned short)cap_value(vit,0,USHRT_MAX);
  3809. }
  3810. if(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH && vit < 50)
  3811. return 50;
  3812. if(sc->data[SC_INCALLSTATUS])
  3813. vit += sc->data[SC_INCALLSTATUS]->val1;
  3814. if(sc->data[SC_INCVIT])
  3815. vit += sc->data[SC_INCVIT]->val1;
  3816. if(sc->data[SC_VITFOOD])
  3817. vit += sc->data[SC_VITFOOD]->val1;
  3818. if(sc->data[SC_FOOD_VIT_CASH])
  3819. vit += sc->data[SC_FOOD_VIT_CASH]->val1;
  3820. if(sc->data[SC_CHANGE])
  3821. vit += sc->data[SC_CHANGE]->val2;
  3822. if(sc->data[SC_GLORYWOUNDS])
  3823. vit += sc->data[SC_GLORYWOUNDS]->val1;
  3824. if(sc->data[SC_TRUESIGHT])
  3825. vit += 5;
  3826. if(sc->data[SC_MARIONETTE])
  3827. vit -= sc->data[SC_MARIONETTE]->val3&0xFF;
  3828. if(sc->data[SC_MARIONETTE2])
  3829. vit += sc->data[SC_MARIONETTE2]->val3&0xFF;
  3830. if(sc->data[SC_LAUDAAGNUS])
  3831. vit += 4 + sc->data[SC_LAUDAAGNUS]->val1;
  3832. if(sc->data[SC_MINOR_BBQ])
  3833. vit += sc->data[SC_MINOR_BBQ]->val1;
  3834. if(sc->data[SC_INSPIRATION])
  3835. vit += sc->data[SC_INSPIRATION]->val3;
  3836. if(sc->data[SC_STOMACHACHE])
  3837. vit -= sc->data[SC_STOMACHACHE]->val1;
  3838. if(sc->data[SC_KYOUGAKU])
  3839. vit -= sc->data[SC_KYOUGAKU]->val2;
  3840. if(sc->data[SC_STRIPARMOR])
  3841. vit -= vit * sc->data[SC_STRIPARMOR]->val2/100;
  3842. return (unsigned short)cap_value(vit,0,USHRT_MAX);
  3843. }
  3844. static unsigned short status_calc_int(struct block_list *bl, struct status_change *sc, int int_)
  3845. {
  3846. if(!sc || !sc->count)
  3847. return cap_value(int_,0,USHRT_MAX);
  3848. if(sc->data[SC_HARMONIZE]) {
  3849. int_ -= sc->data[SC_HARMONIZE]->val2;
  3850. return (unsigned short)cap_value(int_,0,USHRT_MAX);
  3851. }
  3852. if(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH && int_ < 50)
  3853. return 50;
  3854. if(sc->data[SC_INCALLSTATUS])
  3855. int_ += sc->data[SC_INCALLSTATUS]->val1;
  3856. if(sc->data[SC_INCINT])
  3857. int_ += sc->data[SC_INCINT]->val1;
  3858. if(sc->data[SC_INTFOOD])
  3859. int_ += sc->data[SC_INTFOOD]->val1;
  3860. if(sc->data[SC_FOOD_INT_CASH])
  3861. int_ += sc->data[SC_FOOD_INT_CASH]->val1;
  3862. if(sc->data[SC_CHANGE])
  3863. int_ += sc->data[SC_CHANGE]->val3;
  3864. if(sc->data[SC_BATTLEORDERS])
  3865. int_ += 5;
  3866. if(sc->data[SC_TRUESIGHT])
  3867. int_ += 5;
  3868. if(sc->data[SC_BLESSING]){
  3869. if (sc->data[SC_BLESSING]->val2)
  3870. int_ += sc->data[SC_BLESSING]->val2;
  3871. else
  3872. int_ >>= 1;
  3873. }
  3874. if(sc->data[SC_NEN])
  3875. int_ += sc->data[SC_NEN]->val1;
  3876. if(sc->data[SC_MARIONETTE])
  3877. int_ -= ((sc->data[SC_MARIONETTE]->val4)>>16)&0xFF;
  3878. if(sc->data[SC_MARIONETTE2])
  3879. int_ += ((sc->data[SC_MARIONETTE2]->val4)>>16)&0xFF;
  3880. if(sc->data[SC_MANDRAGORA])
  3881. int_ -= 5 + 5 * sc->data[SC_MANDRAGORA]->val1;
  3882. if(sc->data[SC_COCKTAIL_WARG_BLOOD])
  3883. int_ += sc->data[SC_COCKTAIL_WARG_BLOOD]->val1;
  3884. if(sc->data[SC_INSPIRATION])
  3885. int_ += sc->data[SC_INSPIRATION]->val3;
  3886. if(sc->data[SC_STOMACHACHE])
  3887. int_ -= sc->data[SC_STOMACHACHE]->val1;
  3888. if(sc->data[SC_KYOUGAKU])
  3889. int_ -= sc->data[SC_KYOUGAKU]->val2;
  3890. if(sc->data[SC_STRIPHELM])
  3891. int_ -= int_ * sc->data[SC_STRIPHELM]->val2/100;
  3892. if(sc->data[SC__STRIPACCESSORY])
  3893. int_ -= int_ * sc->data[SC__STRIPACCESSORY]->val2 / 100;
  3894. return (unsigned short)cap_value(int_,0,USHRT_MAX);
  3895. }
  3896. static unsigned short status_calc_dex(struct block_list *bl, struct status_change *sc, int dex)
  3897. {
  3898. if(!sc || !sc->count)
  3899. return cap_value(dex,0,USHRT_MAX);
  3900. if(sc->data[SC_HARMONIZE]) {
  3901. dex -= sc->data[SC_HARMONIZE]->val2;
  3902. return (unsigned short)cap_value(dex,0,USHRT_MAX);
  3903. }
  3904. if(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH && dex < 50)
  3905. return 50;
  3906. if(sc->data[SC_CONCENTRATE] && !sc->data[SC_QUAGMIRE])
  3907. dex += (dex-sc->data[SC_CONCENTRATE]->val4)*sc->data[SC_CONCENTRATE]->val2/100;
  3908. if(sc->data[SC_INCALLSTATUS])
  3909. dex += sc->data[SC_INCALLSTATUS]->val1;
  3910. if(sc->data[SC_INCDEX])
  3911. dex += sc->data[SC_INCDEX]->val1;
  3912. if(sc->data[SC_DEXFOOD])
  3913. dex += sc->data[SC_DEXFOOD]->val1;
  3914. if(sc->data[SC_FOOD_DEX_CASH])
  3915. dex += sc->data[SC_FOOD_DEX_CASH]->val1;
  3916. if(sc->data[SC_BATTLEORDERS])
  3917. dex += 5;
  3918. if(sc->data[SC_HAWKEYES])
  3919. dex += sc->data[SC_HAWKEYES]->val1;
  3920. if(sc->data[SC_TRUESIGHT])
  3921. dex += 5;
  3922. if(sc->data[SC_QUAGMIRE])
  3923. dex -= sc->data[SC_QUAGMIRE]->val2;
  3924. if(sc->data[SC_BLESSING]){
  3925. if (sc->data[SC_BLESSING]->val2)
  3926. dex += sc->data[SC_BLESSING]->val2;
  3927. else
  3928. dex >>= 1;
  3929. }
  3930. if(sc->data[SC_INCREASING])
  3931. dex += 4; // added based on skill updates [Reddozen]
  3932. if(sc->data[SC_MARIONETTE])
  3933. dex -= ((sc->data[SC_MARIONETTE]->val4)>>8)&0xFF;
  3934. if(sc->data[SC_MARIONETTE2])
  3935. dex += ((sc->data[SC_MARIONETTE2]->val4)>>8)&0xFF;
  3936. if(sc->data[SC_SIROMA_ICE_TEA])
  3937. dex += sc->data[SC_SIROMA_ICE_TEA]->val1;
  3938. if(sc->data[SC_INSPIRATION])
  3939. dex += sc->data[SC_INSPIRATION]->val3;
  3940. if(sc->data[SC_STOMACHACHE])
  3941. dex -= sc->data[SC_STOMACHACHE]->val1;
  3942. if(sc->data[SC_KYOUGAKU])
  3943. dex -= sc->data[SC_KYOUGAKU]->val2;
  3944. if(sc->data[SC__STRIPACCESSORY])
  3945. dex -= dex * sc->data[SC__STRIPACCESSORY]->val2 / 100;
  3946. return (unsigned short)cap_value(dex,0,USHRT_MAX);
  3947. }
  3948. static unsigned short status_calc_luk(struct block_list *bl, struct status_change *sc, int luk)
  3949. {
  3950. if(!sc || !sc->count)
  3951. return cap_value(luk,0,USHRT_MAX);
  3952. if(sc->data[SC_HARMONIZE]) {
  3953. luk -= sc->data[SC_HARMONIZE]->val2;
  3954. return (unsigned short)cap_value(luk,0,USHRT_MAX);
  3955. }
  3956. if(sc->data[SC_CURSE])
  3957. return 0;
  3958. if(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH && luk < 50)
  3959. return 50;
  3960. if(sc->data[SC_INCALLSTATUS])
  3961. luk += sc->data[SC_INCALLSTATUS]->val1;
  3962. if(sc->data[SC_INCLUK])
  3963. luk += sc->data[SC_INCLUK]->val1;
  3964. if(sc->data[SC_LUKFOOD])
  3965. luk += sc->data[SC_LUKFOOD]->val1;
  3966. if(sc->data[SC_FOOD_LUK_CASH])
  3967. luk += sc->data[SC_FOOD_LUK_CASH]->val1;
  3968. if(sc->data[SC_TRUESIGHT])
  3969. luk += 5;
  3970. if(sc->data[SC_GLORIA])
  3971. luk += 30;
  3972. if(sc->data[SC_MARIONETTE])
  3973. luk -= sc->data[SC_MARIONETTE]->val4&0xFF;
  3974. if(sc->data[SC_MARIONETTE2])
  3975. luk += sc->data[SC_MARIONETTE2]->val4&0xFF;
  3976. if(sc->data[SC_PUTTI_TAILS_NOODLES])
  3977. luk += sc->data[SC_PUTTI_TAILS_NOODLES]->val1;
  3978. if(sc->data[SC_INSPIRATION])
  3979. luk += sc->data[SC_INSPIRATION]->val3;
  3980. if(sc->data[SC_STOMACHACHE])
  3981. luk -= sc->data[SC_STOMACHACHE]->val1;
  3982. if(sc->data[SC_KYOUGAKU])
  3983. luk -= sc->data[SC_KYOUGAKU]->val2;
  3984. if(sc->data[SC_LAUDARAMUS])
  3985. luk += 4 + sc->data[SC_LAUDARAMUS]->val1;
  3986. if(sc->data[SC__STRIPACCESSORY])
  3987. luk -= luk * sc->data[SC__STRIPACCESSORY]->val2 / 100;
  3988. if(sc->data[SC_BANANA_BOMB])
  3989. luk -= luk * sc->data[SC_BANANA_BOMB]->val1 / 100;
  3990. return (unsigned short)cap_value(luk,0,USHRT_MAX);
  3991. }
  3992. static unsigned short status_calc_batk(struct block_list *bl, struct status_change *sc, int batk)
  3993. {
  3994. if(!sc || !sc->count)
  3995. return cap_value(batk,0,USHRT_MAX);
  3996. if(sc->data[SC_ATKPOTION])
  3997. batk += sc->data[SC_ATKPOTION]->val1;
  3998. if(sc->data[SC_BATKFOOD])
  3999. batk += sc->data[SC_BATKFOOD]->val1;
  4000. if(sc->data[SC_GATLINGFEVER])
  4001. batk += sc->data[SC_GATLINGFEVER]->val3;
  4002. if(sc->data[SC_MADNESSCANCEL])
  4003. batk += 100;
  4004. if(sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 2)
  4005. batk += 50;
  4006. if(bl->type == BL_ELEM
  4007. && ((sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 1)
  4008. || (sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 1)
  4009. || (sc->data[SC_WIND_INSIGNIA] && sc->data[SC_WIND_INSIGNIA]->val1 == 1)
  4010. || (sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 1))
  4011. )
  4012. batk += batk / 5;
  4013. if(sc->data[SC_FULL_SWING_K])
  4014. batk += sc->data[SC_FULL_SWING_K]->val1;
  4015. if(sc->data[SC_ODINS_POWER])
  4016. batk += 70;
  4017. if(sc->data[SC_ASH] && (bl->type==BL_MOB)){
  4018. if(status_get_element(bl) == ELE_WATER) //water type
  4019. batk /= 2;
  4020. }
  4021. if(sc->data[SC_PYROCLASTIC])
  4022. batk += sc->data[SC_PYROCLASTIC]->val2;
  4023. if (sc->data[SC_ANGRIFFS_MODUS])
  4024. batk += sc->data[SC_ANGRIFFS_MODUS]->val2;
  4025. if(sc->data[SC_INCATKRATE])
  4026. batk += batk * sc->data[SC_INCATKRATE]->val1/100;
  4027. if(sc->data[SC_PROVOKE])
  4028. batk += batk * sc->data[SC_PROVOKE]->val3/100;
  4029. if(sc->data[SC_CONCENTRATION])
  4030. batk += batk * sc->data[SC_CONCENTRATION]->val2/100;
  4031. if(sc->data[SC_SKE])
  4032. batk += batk * 3;
  4033. if(sc->data[SC_BLOODLUST])
  4034. batk += batk * sc->data[SC_BLOODLUST]->val2/100;
  4035. if(sc->data[SC_JOINTBEAT] && sc->data[SC_JOINTBEAT]->val2&BREAK_WAIST)
  4036. batk -= batk * 25/100;
  4037. if(sc->data[SC_CURSE])
  4038. batk -= batk * 25/100;
  4039. //Curse shouldn't effect on this? <- Curse OR Bleeding??
  4040. // if(sc->data[SC_BLEEDING])
  4041. // batk -= batk * 25/100;
  4042. if(sc->data[SC_FLEET])
  4043. batk += batk * sc->data[SC_FLEET]->val3/100;
  4044. if(sc->data[SC__ENERVATION])
  4045. batk -= batk * sc->data[SC__ENERVATION]->val2 / 100;
  4046. if(sc->data[SC_RUSHWINDMILL])
  4047. batk += batk * sc->data[SC_RUSHWINDMILL]->val2/100;
  4048. if(sc->data[SC_SATURDAYNIGHTFEVER])
  4049. batk += 100 * sc->data[SC_SATURDAYNIGHTFEVER]->val1;
  4050. if(sc->data[SC_MELODYOFSINK])
  4051. batk -= batk * sc->data[SC_MELODYOFSINK]->val3/100;
  4052. if(sc->data[SC_BEYONDOFWARCRY])
  4053. batk += batk * sc->data[SC_BEYONDOFWARCRY]->val3/100;
  4054. if( sc->data[SC_ZANGETSU] )
  4055. batk += batk * sc->data[SC_ZANGETSU]->val2 / 100;
  4056. return (unsigned short)cap_value(batk,0,USHRT_MAX);
  4057. }
  4058. static unsigned short status_calc_watk(struct block_list *bl, struct status_change *sc, int watk)
  4059. {
  4060. if(!sc || !sc->count)
  4061. return cap_value(watk,0,USHRT_MAX);
  4062. if(sc->data[SC_IMPOSITIO])
  4063. watk += sc->data[SC_IMPOSITIO]->val2;
  4064. if(sc->data[SC_WATKFOOD])
  4065. watk += sc->data[SC_WATKFOOD]->val1;
  4066. if(sc->data[SC_DRUMBATTLE])
  4067. watk += sc->data[SC_DRUMBATTLE]->val2;
  4068. if(sc->data[SC_VOLCANO])
  4069. watk += sc->data[SC_VOLCANO]->val2;
  4070. if(sc->data[SC_MERC_ATKUP])
  4071. watk += sc->data[SC_MERC_ATKUP]->val2;
  4072. if(sc->data[SC_FIGHTINGSPIRIT])
  4073. watk += sc->data[SC_FIGHTINGSPIRIT]->val1;
  4074. if(sc->data[SC_STRIKING])
  4075. watk += sc->data[SC_STRIKING]->val2;
  4076. if(sc->data[SC_SHIELDSPELL_DEF] && sc->data[SC_SHIELDSPELL_DEF]->val1 == 3)
  4077. watk += sc->data[SC_SHIELDSPELL_DEF]->val2;
  4078. if(sc->data[SC_INSPIRATION])
  4079. watk += sc->data[SC_INSPIRATION]->val2;
  4080. if( sc->data[SC_BANDING] && sc->data[SC_BANDING]->val2 > 0 )
  4081. watk += (10 + 10 * sc->data[SC_BANDING]->val1) * (sc->data[SC_BANDING]->val2);
  4082. if( sc->data[SC_TROPIC_OPTION] )
  4083. watk += sc->data[SC_TROPIC_OPTION]->val2;
  4084. if( sc->data[SC_HEATER_OPTION] )
  4085. watk += sc->data[SC_HEATER_OPTION]->val2;
  4086. if( sc->data[SC_WATER_BARRIER] )
  4087. watk -= sc->data[SC_WATER_BARRIER]->val3;
  4088. if( sc->data[SC_PYROTECHNIC_OPTION] )
  4089. watk += sc->data[SC_PYROTECHNIC_OPTION]->val2;
  4090. if(sc->data[SC_NIBELUNGEN]) {
  4091. if (bl->type != BL_PC)
  4092. watk += sc->data[SC_NIBELUNGEN]->val2;
  4093. else {
  4094. #ifndef RENEWAL
  4095. TBL_PC *sd = (TBL_PC*)bl;
  4096. int index = sd->equip_index[sd->state.lr_flag?EQI_HAND_L:EQI_HAND_R];
  4097. if(index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->wlv == 4)
  4098. #endif
  4099. watk += sc->data[SC_NIBELUNGEN]->val2;
  4100. }
  4101. }
  4102. if(sc->data[SC_INCATKRATE])
  4103. watk += watk * sc->data[SC_INCATKRATE]->val1/100;
  4104. if(sc->data[SC_PROVOKE])
  4105. watk += watk * sc->data[SC_PROVOKE]->val3/100;
  4106. if(sc->data[SC_CONCENTRATION])
  4107. watk += watk * sc->data[SC_CONCENTRATION]->val2/100;
  4108. if(sc->data[SC_SKE])
  4109. watk += watk * 3;
  4110. if(sc->data[SC__ENERVATION])
  4111. watk -= watk * sc->data[SC__ENERVATION]->val2 / 100;
  4112. if(sc->data[SC_FLEET])
  4113. watk += watk * sc->data[SC_FLEET]->val3/100;
  4114. if(sc->data[SC_CURSE])
  4115. watk -= watk * 25/100;
  4116. if(sc->data[SC_STRIPWEAPON])
  4117. watk -= watk * sc->data[SC_STRIPWEAPON]->val2/100;
  4118. if(sc->data[SC__ENERVATION])
  4119. watk -= watk * sc->data[SC__ENERVATION]->val2 / 100;
  4120. if((sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 2)
  4121. || (sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 2)
  4122. || (sc->data[SC_WIND_INSIGNIA] && sc->data[SC_WIND_INSIGNIA]->val1 == 2)
  4123. || (sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 2)
  4124. )
  4125. watk += watk / 10;
  4126. if( sc && sc->data[SC_TIDAL_WEAPON] )
  4127. watk += watk * sc->data[SC_TIDAL_WEAPON]->val2 / 100;
  4128. if(sc->data[SC_ANGRIFFS_MODUS])
  4129. watk += watk * sc->data[SC_ANGRIFFS_MODUS]->val2/100;
  4130. #ifdef RENEWAL_EDP
  4131. if( sc->data[SC_EDP] )
  4132. watk = watk * (100 + sc->data[SC_EDP]->val1 * 80) / 100;
  4133. #endif
  4134. return (unsigned short)cap_value(watk,0,USHRT_MAX);
  4135. }
  4136. #ifdef RENEWAL
  4137. static unsigned short status_calc_ematk(struct block_list *bl, struct status_change *sc, int matk)
  4138. {
  4139. if (!sc || !sc->count)
  4140. return cap_value(matk,0,USHRT_MAX);
  4141. if (sc->data[SC_MATKPOTION])
  4142. matk += sc->data[SC_MATKPOTION]->val1;
  4143. if (sc->data[SC_MATKFOOD])
  4144. matk += sc->data[SC_MATKFOOD]->val1;
  4145. if(sc->data[SC_MANA_PLUS])
  4146. matk += sc->data[SC_MANA_PLUS]->val1;
  4147. if(sc->data[SC_AQUAPLAY_OPTION])
  4148. matk += sc->data[SC_AQUAPLAY_OPTION]->val2;
  4149. if(sc->data[SC_CHILLY_AIR_OPTION])
  4150. matk += sc->data[SC_CHILLY_AIR_OPTION]->val2;
  4151. if(sc->data[SC_WATER_BARRIER])
  4152. matk -= sc->data[SC_WATER_BARRIER]->val3;
  4153. if(sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 3)
  4154. matk += 50;
  4155. if(sc->data[SC_ODINS_POWER])
  4156. matk += 40 + 30 * sc->data[SC_ODINS_POWER]->val1; //70 lvl1, 100lvl2
  4157. if(sc->data[SC_IZAYOI])
  4158. matk += 50 * sc->data[SC_IZAYOI]->val1;
  4159. return (unsigned short)cap_value(matk,0,USHRT_MAX);
  4160. }
  4161. #endif
  4162. static unsigned short status_calc_matk(struct block_list *bl, struct status_change *sc, int matk)
  4163. {
  4164. if(!sc || !sc->count)
  4165. return cap_value(matk,0,USHRT_MAX);
  4166. #ifndef RENEWAL
  4167. // take note fixed value first before % modifiers
  4168. if (sc->data[SC_MATKPOTION])
  4169. matk += sc->data[SC_MATKPOTION]->val1;
  4170. if (sc->data[SC_MATKFOOD])
  4171. matk += sc->data[SC_MATKFOOD]->val1;
  4172. if (sc->data[SC_MANA_PLUS])
  4173. matk += sc->data[SC_MANA_PLUS]->val1;
  4174. if (sc->data[SC_AQUAPLAY_OPTION])
  4175. matk += sc->data[SC_AQUAPLAY_OPTION]->val2;
  4176. if (sc->data[SC_CHILLY_AIR_OPTION])
  4177. matk += sc->data[SC_CHILLY_AIR_OPTION]->val2;
  4178. if (sc->data[SC_WATER_BARRIER])
  4179. matk -= sc->data[SC_WATER_BARRIER]->val3;
  4180. if (sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 3)
  4181. matk += 50;
  4182. if (sc->data[SC_ODINS_POWER])
  4183. matk += 40 + 30 * sc->data[SC_ODINS_POWER]->val1; //70 lvl1, 100lvl2
  4184. if (sc->data[SC_IZAYOI])
  4185. matk += 50 * sc->data[SC_IZAYOI]->val1;
  4186. #endif
  4187. if (sc->data[SC_MAGICPOWER])
  4188. matk += matk * sc->data[SC_MAGICPOWER]->val3/100;
  4189. if (sc->data[SC_MINDBREAKER])
  4190. matk += matk * sc->data[SC_MINDBREAKER]->val2/100;
  4191. if (sc->data[SC_INCMATKRATE])
  4192. matk += matk * sc->data[SC_INCMATKRATE]->val1/100;
  4193. if (sc->data[SC_MOONLITSERENADE])
  4194. matk += matk * sc->data[SC_MOONLITSERENADE]->val2/100;
  4195. if (sc->data[SC_MELODYOFSINK])
  4196. matk += matk * sc->data[SC_MELODYOFSINK]->val3/100;
  4197. if (sc->data[SC_BEYONDOFWARCRY])
  4198. matk -= matk * sc->data[SC_BEYONDOFWARCRY]->val3/100;
  4199. if( sc->data[SC_ZANGETSU] )
  4200. matk += matk * sc->data[SC_ZANGETSU]->val2 / 100;
  4201. return (unsigned short)cap_value(matk,0,USHRT_MAX);
  4202. }
  4203. static signed short status_calc_critical(struct block_list *bl, struct status_change *sc, int critical) {
  4204. if(!sc || !sc->count)
  4205. return cap_value(critical,10,SHRT_MAX);
  4206. if (sc->data[SC_INCCRI])
  4207. critical += sc->data[SC_INCCRI]->val2;
  4208. if (sc->data[SC_EXPLOSIONSPIRITS])
  4209. critical += sc->data[SC_EXPLOSIONSPIRITS]->val2;
  4210. if (sc->data[SC_FORTUNE])
  4211. critical += sc->data[SC_FORTUNE]->val2;
  4212. if (sc->data[SC_TRUESIGHT])
  4213. critical += sc->data[SC_TRUESIGHT]->val2;
  4214. if(sc->data[SC_CLOAKING])
  4215. critical += critical;
  4216. if(sc->data[SC_STRIKING])
  4217. critical += sc->data[SC_STRIKING]->val1;
  4218. #ifdef RENEWAL
  4219. if (sc->data[SC_SPEARQUICKEN])
  4220. critical += 3*sc->data[SC_SPEARQUICKEN]->val1*10;
  4221. #endif
  4222. if(sc->data[SC__INVISIBILITY])
  4223. critical += critical * sc->data[SC__INVISIBILITY]->val3 / 100;
  4224. if(sc->data[SC__UNLUCKY])
  4225. critical -= critical * sc->data[SC__UNLUCKY]->val2 / 100;
  4226. return (short)cap_value(critical,10,SHRT_MAX);
  4227. }
  4228. static signed short status_calc_hit(struct block_list *bl, struct status_change *sc, int hit)
  4229. {
  4230. if(!sc || !sc->count)
  4231. return cap_value(hit,1,SHRT_MAX);
  4232. if(sc->data[SC_INCHIT])
  4233. hit += sc->data[SC_INCHIT]->val1;
  4234. if(sc->data[SC_HITFOOD])
  4235. hit += sc->data[SC_HITFOOD]->val1;
  4236. if(sc->data[SC_TRUESIGHT])
  4237. hit += sc->data[SC_TRUESIGHT]->val3;
  4238. if(sc->data[SC_HUMMING])
  4239. hit += sc->data[SC_HUMMING]->val2;
  4240. if(sc->data[SC_CONCENTRATION])
  4241. hit += sc->data[SC_CONCENTRATION]->val3;
  4242. if(sc->data[SC_INSPIRATION])
  4243. hit += 5 * sc->data[SC_INSPIRATION]->val1;
  4244. if(sc->data[SC_ADJUSTMENT])
  4245. hit -= 30;
  4246. if(sc->data[SC_INCREASING])
  4247. hit += 20; // RockmanEXE; changed based on updated [Reddozen]
  4248. if(sc->data[SC_MERC_HITUP])
  4249. hit += sc->data[SC_MERC_HITUP]->val2;
  4250. if(sc->data[SC_INCHITRATE])
  4251. hit += hit * sc->data[SC_INCHITRATE]->val1/100;
  4252. if(sc->data[SC_BLIND])
  4253. hit -= hit * 25/100;
  4254. if(sc->data[SC__GROOMY])
  4255. hit -= hit * sc->data[SC__GROOMY]->val3 / 100;
  4256. if(sc->data[SC_FEAR])
  4257. hit -= hit * 20 / 100;
  4258. if (sc->data[SC_ASH])
  4259. hit /= 2;
  4260. return (short)cap_value(hit,1,SHRT_MAX);
  4261. }
  4262. static signed short status_calc_flee(struct block_list *bl, struct status_change *sc, int flee)
  4263. {
  4264. if( bl->type == BL_PC )
  4265. {
  4266. if( map_flag_gvg(bl->m) )
  4267. flee -= flee * battle_config.gvg_flee_penalty/100;
  4268. else if( map[bl->m].flag.battleground )
  4269. flee -= flee * battle_config.bg_flee_penalty/100;
  4270. }
  4271. if(!sc || !sc->count)
  4272. return cap_value(flee,1,SHRT_MAX);
  4273. if(sc->data[SC_INCFLEE])
  4274. flee += sc->data[SC_INCFLEE]->val1;
  4275. if(sc->data[SC_FLEEFOOD])
  4276. flee += sc->data[SC_FLEEFOOD]->val1;
  4277. if(sc->data[SC_WHISTLE])
  4278. flee += sc->data[SC_WHISTLE]->val2;
  4279. if(sc->data[SC_WINDWALK])
  4280. flee += sc->data[SC_WINDWALK]->val2;
  4281. if(sc->data[SC_VIOLENTGALE])
  4282. flee += sc->data[SC_VIOLENTGALE]->val2;
  4283. if(sc->data[SC_MOON_COMFORT]) //SG skill [Komurka]
  4284. flee += sc->data[SC_MOON_COMFORT]->val2;
  4285. if(sc->data[SC_CLOSECONFINE])
  4286. flee += 10;
  4287. if (sc->data[SC_ANGRIFFS_MODUS])
  4288. flee -= sc->data[SC_ANGRIFFS_MODUS]->val3;
  4289. if (sc->data[SC_OVERED_BOOST])
  4290. flee = max(flee,sc->data[SC_OVERED_BOOST]->val2);
  4291. if(sc->data[SC_ADJUSTMENT])
  4292. flee += 30;
  4293. if(sc->data[SC_SPEED])
  4294. flee += 10 + sc->data[SC_SPEED]->val1 * 10;
  4295. if(sc->data[SC_GATLINGFEVER])
  4296. flee -= sc->data[SC_GATLINGFEVER]->val4;
  4297. if(sc->data[SC_PARTYFLEE])
  4298. flee += sc->data[SC_PARTYFLEE]->val1 * 10;
  4299. if(sc->data[SC_MERC_FLEEUP])
  4300. flee += sc->data[SC_MERC_FLEEUP]->val2;
  4301. if( sc->data[SC_HALLUCINATIONWALK] )
  4302. flee += sc->data[SC_HALLUCINATIONWALK]->val2;
  4303. if( sc->data[SC_WATER_BARRIER] )
  4304. flee -= sc->data[SC_WATER_BARRIER]->val3;
  4305. if( sc->data[SC_MARSHOFABYSS] )
  4306. flee -= (9 * sc->data[SC_MARSHOFABYSS]->val3 / 10 + sc->data[SC_MARSHOFABYSS]->val2 / 10) * (bl->type == BL_MOB ? 2 : 1);
  4307. #ifdef RENEWAL
  4308. if( sc->data[SC_SPEARQUICKEN] )
  4309. flee += 2 * sc->data[SC_SPEARQUICKEN]->val1;
  4310. #endif
  4311. if(sc->data[SC_INCFLEERATE])
  4312. flee += flee * sc->data[SC_INCFLEERATE]->val1/100;
  4313. if(sc->data[SC_SPIDERWEB] && sc->data[SC_SPIDERWEB]->val1)
  4314. flee -= flee * 50/100;
  4315. if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST])
  4316. flee -= flee * 50/100;
  4317. if(sc->data[SC_BLIND])
  4318. flee -= flee * 25/100;
  4319. if(sc->data[SC_FEAR])
  4320. flee -= flee * 20 / 100;
  4321. if(sc->data[SC_PARALYSE])
  4322. flee -= flee * 10 / 100; // 10% Flee reduction
  4323. if(sc->data[SC_INFRAREDSCAN])
  4324. flee -= flee * 30 / 100;
  4325. if( sc->data[SC__LAZINESS] )
  4326. flee -= flee * sc->data[SC__LAZINESS]->val3 / 100;
  4327. if( sc->data[SC_GLOOMYDAY] )
  4328. flee -= flee * sc->data[SC_GLOOMYDAY]->val2 / 100;
  4329. if( sc->data[SC_SATURDAYNIGHTFEVER] )
  4330. flee -= flee * (40 + 10 * sc->data[SC_SATURDAYNIGHTFEVER]->val1) / 100;
  4331. if( sc->data[SC_WIND_STEP_OPTION] )
  4332. flee += flee * sc->data[SC_WIND_STEP_OPTION]->val2 / 100;
  4333. if( sc->data[SC_ZEPHYR] )
  4334. flee += flee * sc->data[SC_ZEPHYR]->val2 / 100;
  4335. if(sc->data[SC_ASH] && (bl->type==BL_MOB)){ //mob
  4336. if(status_get_element(bl) == ELE_WATER) //water type
  4337. flee /= 2;
  4338. }
  4339. return (short)cap_value(flee,1,SHRT_MAX);
  4340. }
  4341. static signed short status_calc_flee2(struct block_list *bl, struct status_change *sc, int flee2)
  4342. {
  4343. if(!sc || !sc->count)
  4344. return cap_value(flee2,10,SHRT_MAX);
  4345. if(sc->data[SC_INCFLEE2])
  4346. flee2 += sc->data[SC_INCFLEE2]->val2;
  4347. if(sc->data[SC_WHISTLE])
  4348. flee2 += sc->data[SC_WHISTLE]->val3*10;
  4349. if(sc->data[SC__UNLUCKY])
  4350. flee2 -= flee2 * sc->data[SC__UNLUCKY]->val2 / 100;
  4351. return (short)cap_value(flee2,10,SHRT_MAX);
  4352. }
  4353. static defType status_calc_def(struct block_list *bl, struct status_change *sc, int def) {
  4354. if(!sc || !sc->count)
  4355. return (defType)cap_value(def,DEFTYPE_MIN,DEFTYPE_MAX);
  4356. if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST])
  4357. return 0;
  4358. if(sc->data[SC_SKA])
  4359. return sc->data[SC_SKA]->val3;
  4360. if(sc->data[SC_BARRIER])
  4361. return 100;
  4362. if(sc->data[SC_KEEPING])
  4363. return 90;
  4364. #ifndef RENEWAL // does not provide 90 DEF in renewal mode
  4365. if(sc->data[SC_STEELBODY])
  4366. return 90;
  4367. #endif
  4368. if(sc->data[SC_ARMORCHANGE])
  4369. def += sc->data[SC_ARMORCHANGE]->val2;
  4370. if(sc->data[SC_DRUMBATTLE])
  4371. def += sc->data[SC_DRUMBATTLE]->val3;
  4372. if(sc->data[SC_DEFENCE]) //[orn]
  4373. def += sc->data[SC_DEFENCE]->val2 ;
  4374. if(sc->data[SC_INCDEFRATE])
  4375. def += def * sc->data[SC_INCDEFRATE]->val1/100;
  4376. if(sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 2)
  4377. def += 50;
  4378. if(sc->data[SC_ODINS_POWER])
  4379. def -= 20;
  4380. if( sc->data[SC_ANGRIFFS_MODUS] )
  4381. def -= 30 + 20 * sc->data[SC_ANGRIFFS_MODUS]->val1;
  4382. if(sc->data[SC_STONEHARDSKIN])// Final DEF increase divided by 10 since were using classic (pre-renewal) mechanics. [Rytech]
  4383. def += sc->data[SC_STONEHARDSKIN]->val1;
  4384. if(sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
  4385. def >>=1;
  4386. if(sc->data[SC_FREEZE])
  4387. def >>=1;
  4388. if(sc->data[SC_SIGNUMCRUCIS])
  4389. def -= def * sc->data[SC_SIGNUMCRUCIS]->val2/100;
  4390. if(sc->data[SC_CONCENTRATION])
  4391. def -= def * sc->data[SC_CONCENTRATION]->val4/100;
  4392. if(sc->data[SC_SKE])
  4393. def >>=1;
  4394. if(sc->data[SC_PROVOKE] && bl->type != BL_PC) // Provoke doesn't alter player defense->
  4395. def -= def * sc->data[SC_PROVOKE]->val4/100;
  4396. if(sc->data[SC_STRIPSHIELD])
  4397. def -= def * sc->data[SC_STRIPSHIELD]->val2/100;
  4398. if (sc->data[SC_FLING])
  4399. def -= def * (sc->data[SC_FLING]->val2)/100;
  4400. if( sc->data[SC_FREEZING] )
  4401. def -= def * 10 / 100;
  4402. if( sc->data[SC_MARSHOFABYSS] )
  4403. def -= def * ( 6 + 6 * sc->data[SC_MARSHOFABYSS]->val3/10 + (bl->type == BL_MOB ? 5 : 3) * sc->data[SC_MARSHOFABYSS]->val2/36 ) / 100;
  4404. if( sc->data[SC_ANALYZE] )
  4405. def -= def * ( 14 * sc->data[SC_ANALYZE]->val1 ) / 100;
  4406. if( sc->data[SC_FORCEOFVANGUARD] )
  4407. def += def * 2 * sc->data[SC_FORCEOFVANGUARD]->val1 / 100;
  4408. if(sc->data[SC_SATURDAYNIGHTFEVER])
  4409. def -= def * (10 + 10 * sc->data[SC_SATURDAYNIGHTFEVER]->val1) / 100;
  4410. if(sc->data[SC_EARTHDRIVE])
  4411. def -= def * 25 / 100;
  4412. if( sc->data[SC_ROCK_CRUSHER] )
  4413. def -= def * sc->data[SC_ROCK_CRUSHER]->val2 / 100;
  4414. if( sc->data[SC_POWER_OF_GAIA] )
  4415. def += def * sc->data[SC_POWER_OF_GAIA]->val2 / 100;
  4416. if( sc->data[SC_PRESTIGE] )
  4417. def += def * sc->data[SC_PRESTIGE]->val1 / 100;
  4418. if(sc->data[SC_ASH] && (bl->type==BL_MOB)){
  4419. if(status_get_race(bl)==RC_PLANT)
  4420. def /= 2;
  4421. }
  4422. return (defType)cap_value(def,DEFTYPE_MIN,DEFTYPE_MAX);;
  4423. }
  4424. static signed short status_calc_def2(struct block_list *bl, struct status_change *sc, int def2)
  4425. {
  4426. if(!sc || !sc->count)
  4427. #ifdef RENEWAL
  4428. return (short)cap_value(def2,SHRT_MIN,SHRT_MAX);
  4429. #else
  4430. return (short)cap_value(def2,1,SHRT_MAX);
  4431. #endif
  4432. if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST])
  4433. return 0;
  4434. if(sc->data[SC_ETERNALCHAOS])
  4435. return 0;
  4436. if(sc->data[SC_SUN_COMFORT])
  4437. def2 += sc->data[SC_SUN_COMFORT]->val2;
  4438. if( sc->data[SC_SHIELDSPELL_REF] && sc->data[SC_SHIELDSPELL_REF]->val1 == 1 )
  4439. def2 += sc->data[SC_SHIELDSPELL_REF]->val2;
  4440. if( sc->data[SC_BANDING] && sc->data[SC_BANDING]->val2 > 0 )
  4441. def2 += (5 + sc->data[SC_BANDING]->val1) * (sc->data[SC_BANDING]->val2);
  4442. if(sc->data[SC_ANGELUS])
  4443. #ifdef RENEWAL //in renewal only the VIT stat bonus is boosted by angelus
  4444. def2 += status_get_vit(bl) / 2 * sc->data[SC_ANGELUS]->val2/100;
  4445. #else
  4446. def2 += def2 * sc->data[SC_ANGELUS]->val2/100;
  4447. #endif
  4448. if(sc->data[SC_CONCENTRATION])
  4449. def2 -= def2 * sc->data[SC_CONCENTRATION]->val4/100;
  4450. if(sc->data[SC_POISON])
  4451. def2 -= def2 * 25/100;
  4452. if(sc->data[SC_DPOISON])
  4453. def2 -= def2 * 25/100;
  4454. if(sc->data[SC_SKE])
  4455. def2 -= def2 * 50/100;
  4456. if(sc->data[SC_PROVOKE])
  4457. def2 -= def2 * sc->data[SC_PROVOKE]->val4/100;
  4458. if(sc->data[SC_JOINTBEAT])
  4459. def2 -= def2 * ( sc->data[SC_JOINTBEAT]->val2&BREAK_SHOULDER ? 50 : 0 ) / 100
  4460. + def2 * ( sc->data[SC_JOINTBEAT]->val2&BREAK_WAIST ? 25 : 0 ) / 100;
  4461. if(sc->data[SC_FLING])
  4462. def2 -= def2 * (sc->data[SC_FLING]->val3)/100;
  4463. if( sc->data[SC_FREEZING] )
  4464. def2 -= def2 * 3 / 10;
  4465. if(sc->data[SC_ANALYZE])
  4466. def2 -= def2 * ( 14 * sc->data[SC_ANALYZE]->val1 ) / 100;
  4467. if( sc->data[SC_ECHOSONG] )
  4468. def2 += def2 * sc->data[SC_ECHOSONG]->val2/100;
  4469. if(sc->data[SC_ASH] && (bl->type==BL_MOB)){
  4470. if(status_get_race(bl)==RC_PLANT)
  4471. def2 /= 2;
  4472. }
  4473. if (sc->data[SC_PARALYSIS])
  4474. def2 -= def2 * sc->data[SC_PARALYSIS]->val2 / 100;
  4475. #ifdef RENEWAL
  4476. return (short)cap_value(def2,SHRT_MIN,SHRT_MAX);
  4477. #else
  4478. return (short)cap_value(def2,1,SHRT_MAX);
  4479. #endif
  4480. }
  4481. static defType status_calc_mdef(struct block_list *bl, struct status_change *sc, int mdef) {
  4482. if(!sc || !sc->count)
  4483. return (defType)cap_value(mdef,DEFTYPE_MIN,DEFTYPE_MAX);
  4484. if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST])
  4485. return 0;
  4486. if(sc->data[SC_BARRIER])
  4487. return 100;
  4488. #ifndef RENEWAL // no longer provides 90 MDEF in renewal mode
  4489. if(sc->data[SC_STEELBODY])
  4490. return 90;
  4491. #endif
  4492. if(sc->data[SC_ARMORCHANGE])
  4493. mdef += sc->data[SC_ARMORCHANGE]->val3;
  4494. if(sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 3)
  4495. mdef += 50;
  4496. if(sc->data[SC_ENDURE])// It has been confirmed that eddga card grants 1 MDEF, not 0, not 10, but 1.
  4497. mdef += (sc->data[SC_ENDURE]->val4 == 0) ? sc->data[SC_ENDURE]->val1 : 1;
  4498. if(sc->data[SC_CONCENTRATION])
  4499. mdef += 1; //Skill info says it adds a fixed 1 Mdef point.
  4500. if(sc->data[SC_STONEHARDSKIN])// Final MDEF increase divided by 10 since were using classic (pre-renewal) mechanics. [Rytech]
  4501. mdef += sc->data[SC_STONEHARDSKIN]->val1;
  4502. if(sc->data[SC_WATER_BARRIER])
  4503. mdef += sc->data[SC_WATER_BARRIER]->val2;
  4504. if(sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
  4505. mdef += 25*mdef/100;
  4506. if(sc->data[SC_FREEZE])
  4507. mdef += 25*mdef/100;
  4508. if( sc->data[SC_MARSHOFABYSS] )
  4509. mdef -= mdef * ( 6 + 6 * sc->data[SC_MARSHOFABYSS]->val3/10 + (bl->type == BL_MOB ? 5 : 3) * sc->data[SC_MARSHOFABYSS]->val2/36 ) / 100;
  4510. if(sc->data[SC_ANALYZE])
  4511. mdef -= mdef * ( 14 * sc->data[SC_ANALYZE]->val1 ) / 100;
  4512. if(sc->data[SC_SYMPHONYOFLOVER])
  4513. mdef += mdef * sc->data[SC_SYMPHONYOFLOVER]->val2 / 100;
  4514. if(sc->data[SC_GT_CHANGE] && sc->data[SC_GT_CHANGE]->val4)
  4515. mdef -= mdef * sc->data[SC_GT_CHANGE]->val4 / 100;
  4516. if (sc->data[SC_ODINS_POWER])
  4517. mdef -= 20 * sc->data[SC_ODINS_POWER]->val1;
  4518. return (defType)cap_value(mdef,DEFTYPE_MIN,DEFTYPE_MAX);
  4519. }
  4520. static signed short status_calc_mdef2(struct block_list *bl, struct status_change *sc, int mdef2)
  4521. {
  4522. if(!sc || !sc->count)
  4523. #ifdef RENEWAL
  4524. return (short)cap_value(mdef2,SHRT_MIN,SHRT_MAX);
  4525. #else
  4526. return (short)cap_value(mdef2,1,SHRT_MAX);
  4527. #endif
  4528. if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST])
  4529. return 0;
  4530. if(sc->data[SC_SKA])
  4531. return 90;
  4532. if(sc->data[SC_MINDBREAKER])
  4533. mdef2 -= mdef2 * sc->data[SC_MINDBREAKER]->val3/100;
  4534. if(sc->data[SC_ANALYZE])
  4535. mdef2 -= mdef2 * ( 14 * sc->data[SC_ANALYZE]->val1 ) / 100;
  4536. #ifdef RENEWAL
  4537. return (short)cap_value(mdef2,SHRT_MIN,SHRT_MAX);
  4538. #else
  4539. return (short)cap_value(mdef2,1,SHRT_MAX);
  4540. #endif
  4541. }
  4542. static unsigned short status_calc_speed(struct block_list *bl, struct status_change *sc, int speed)
  4543. {
  4544. TBL_PC* sd = BL_CAST(BL_PC, bl);
  4545. int speed_rate;
  4546. if( sc == NULL )
  4547. return cap_value(speed,10,USHRT_MAX);
  4548. if( sd && sd->ud.skilltimer != INVALID_TIMER && (pc_checkskill(sd,SA_FREECAST) > 0 || sd->ud.skill_id == LG_EXEEDBREAK) )
  4549. {
  4550. if( sd->ud.skill_id == LG_EXEEDBREAK )
  4551. speed_rate = 100 + 60 - (sd->ud.skill_lv * 10);
  4552. else
  4553. speed_rate = 175 - 5 * pc_checkskill(sd,SA_FREECAST);
  4554. }
  4555. else
  4556. {
  4557. speed_rate = 100;
  4558. //GetMoveHasteValue2()
  4559. {
  4560. int val = 0;
  4561. if( sc->data[SC_FUSION] )
  4562. val = 25;
  4563. else if( sd ) {
  4564. if( pc_isriding(sd) || sd->sc.option&(OPTION_DRAGON|OPTION_MOUNTING) )
  4565. val = 25;//Same bonus
  4566. else if( pc_isridingwug(sd) )
  4567. val = 15 + 5 * pc_checkskill(sd, RA_WUGRIDER);
  4568. else if( pc_ismadogear(sd) ) {
  4569. val = (- 10 * (5 - pc_checkskill(sd,NC_MADOLICENCE)));
  4570. if( sc->data[SC_ACCELERATION] )
  4571. val += 25;
  4572. }
  4573. }
  4574. speed_rate -= val;
  4575. }
  4576. //GetMoveSlowValue()
  4577. {
  4578. int val = 0;
  4579. if( sd && sc->data[SC_HIDING] && pc_checkskill(sd,RG_TUNNELDRIVE) > 0 )
  4580. val = 120 - 6 * pc_checkskill(sd,RG_TUNNELDRIVE);
  4581. else
  4582. if( sd && sc->data[SC_CHASEWALK] && sc->data[SC_CHASEWALK]->val3 < 0 )
  4583. val = sc->data[SC_CHASEWALK]->val3;
  4584. else
  4585. {
  4586. // Longing for Freedom cancels song/dance penalty
  4587. if( sc->data[SC_LONGING] )
  4588. val = max( val, 50 - 10 * sc->data[SC_LONGING]->val1 );
  4589. else
  4590. if( sd && sc->data[SC_DANCING] )
  4591. val = max( val, 500 - (40 + 10 * (sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_BARDDANCER)) * pc_checkskill(sd,(sd->status.sex?BA_MUSICALLESSON:DC_DANCINGLESSON)) );
  4592. if( sc->data[SC_DECREASEAGI] )
  4593. val = max( val, 25 );
  4594. if( sc->data[SC_QUAGMIRE] || sc->data[SC_HALLUCINATIONWALK_POSTDELAY] || (sc->data[SC_GLOOMYDAY] && sc->data[SC_GLOOMYDAY]->val4) )
  4595. val = max( val, 50 );
  4596. if( sc->data[SC_DONTFORGETME] )
  4597. val = max( val, sc->data[SC_DONTFORGETME]->val3 );
  4598. if( sc->data[SC_CURSE] )
  4599. val = max( val, 300 );
  4600. if( sc->data[SC_CHASEWALK] )
  4601. val = max( val, sc->data[SC_CHASEWALK]->val3 );
  4602. if( sc->data[SC_WEDDING] )
  4603. val = max( val, 100 );
  4604. if( sc->data[SC_JOINTBEAT] && sc->data[SC_JOINTBEAT]->val2&(BREAK_ANKLE|BREAK_KNEE) )
  4605. val = max( val, (sc->data[SC_JOINTBEAT]->val2&BREAK_ANKLE ? 50 : 0) + (sc->data[SC_JOINTBEAT]->val2&BREAK_KNEE ? 30 : 0) );
  4606. if( sc->data[SC_CLOAKING] && (sc->data[SC_CLOAKING]->val4&1) == 0 )
  4607. val = max( val, sc->data[SC_CLOAKING]->val1 < 3 ? 300 : 30 - 3 * sc->data[SC_CLOAKING]->val1 );
  4608. if( sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_ENEMY )
  4609. val = max( val, 75 );
  4610. if( sc->data[SC_SLOWDOWN] ) // Slow Potion
  4611. val = max( val, 100 );
  4612. if( sc->data[SC_GATLINGFEVER] )
  4613. val = max( val, 100 );
  4614. if( sc->data[SC_SUITON] )
  4615. val = max( val, sc->data[SC_SUITON]->val3 );
  4616. if( sc->data[SC_SWOO] )
  4617. val = max( val, 300 );
  4618. if( sc->data[SC_FREEZING] )
  4619. val = max( val, 70 );
  4620. if( sc->data[SC_MARSHOFABYSS] )
  4621. val = max( val, 40 + 10 * sc->data[SC_MARSHOFABYSS]->val1 );
  4622. if( sc->data[SC_CAMOUFLAGE] && (sc->data[SC_CAMOUFLAGE]->val3&1) == 0 )
  4623. val = max( val, sc->data[SC_CAMOUFLAGE]->val1 < 3 ? 0 : 25 * (5 - sc->data[SC_CAMOUFLAGE]->val1) );
  4624. if( sc->data[SC__GROOMY] )
  4625. val = max( val, sc->data[SC__GROOMY]->val2);
  4626. if( sc->data[SC_STEALTHFIELD_MASTER] )
  4627. val = max( val, 30 );
  4628. if( sc->data[SC_BANDING_DEFENCE] )
  4629. val = max( val, sc->data[SC_BANDING_DEFENCE]->val1 );//+90% walking speed.
  4630. if( sc->data[SC_ROCK_CRUSHER_ATK] )
  4631. val = max( val, sc->data[SC_ROCK_CRUSHER_ATK]->val2 );
  4632. if( sc->data[SC_POWER_OF_GAIA] )
  4633. val = max( val, sc->data[SC_POWER_OF_GAIA]->val2 );
  4634. if( sc->data[SC_MELON_BOMB] )
  4635. val = max( val, sc->data[SC_MELON_BOMB]->val1 );
  4636. if( sd && sd->bonus.speed_rate + sd->bonus.speed_add_rate > 0 ) // permanent item-based speedup
  4637. val = max( val, sd->bonus.speed_rate + sd->bonus.speed_add_rate );
  4638. }
  4639. speed_rate += val;
  4640. }
  4641. //GetMoveHasteValue1()
  4642. {
  4643. int val = 0;
  4644. if( sc->data[SC_SPEEDUP1] ) //FIXME: used both by NPC_AGIUP and Speed Potion script
  4645. val = max( val, 50 );
  4646. if( sc->data[SC_INCREASEAGI] )
  4647. val = max( val, 25 );
  4648. if( sc->data[SC_WINDWALK] )
  4649. val = max( val, 2 * sc->data[SC_WINDWALK]->val1 );
  4650. if( sc->data[SC_CARTBOOST] )
  4651. val = max( val, 20 );
  4652. if( sd && (sd->class_&MAPID_UPPERMASK) == MAPID_ASSASSIN && pc_checkskill(sd,TF_MISS) > 0 )
  4653. val = max( val, 1 * pc_checkskill(sd,TF_MISS) );
  4654. if( sc->data[SC_CLOAKING] && (sc->data[SC_CLOAKING]->val4&1) == 1 )
  4655. val = max( val, sc->data[SC_CLOAKING]->val1 >= 10 ? 25 : 3 * sc->data[SC_CLOAKING]->val1 - 3 );
  4656. if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST])
  4657. val = max( val, 25 );
  4658. if( sc->data[SC_RUN] )
  4659. val = max( val, 55 );
  4660. if( sc->data[SC_AVOID] )
  4661. val = max( val, 10 * sc->data[SC_AVOID]->val1 );
  4662. if( sc->data[SC_INVINCIBLE] && !sc->data[SC_INVINCIBLEOFF] )
  4663. val = max( val, 75 );
  4664. if( sc->data[SC_CLOAKINGEXCEED] )
  4665. val = max( val, sc->data[SC_CLOAKINGEXCEED]->val3);
  4666. if( sc->data[SC_HOVERING] )
  4667. val = max( val, 10 );
  4668. if( sc->data[SC_GN_CARTBOOST] )
  4669. val = max( val, sc->data[SC_GN_CARTBOOST]->val2 );
  4670. if( sc->data[SC_SWINGDANCE] )
  4671. val = max( val, sc->data[SC_SWINGDANCE]->val2 );
  4672. if( sc->data[SC_WIND_STEP_OPTION] )
  4673. val = max( val, sc->data[SC_WIND_STEP_OPTION]->val2 );
  4674. //FIXME: official items use a single bonus for this [ultramage]
  4675. if( sc->data[SC_SPEEDUP0] ) // temporary item-based speedup
  4676. val = max( val, 25 );
  4677. if( sd && sd->bonus.speed_rate + sd->bonus.speed_add_rate < 0 ) // permanent item-based speedup
  4678. val = max( val, -(sd->bonus.speed_rate + sd->bonus.speed_add_rate) );
  4679. speed_rate -= val;
  4680. }
  4681. if( speed_rate < 40 )
  4682. speed_rate = 40;
  4683. }
  4684. //GetSpeed()
  4685. {
  4686. if( sd && pc_iscarton(sd) )
  4687. speed += speed * (50 - 5 * pc_checkskill(sd,MC_PUSHCART)) / 100;
  4688. if( sc->data[SC_PARALYSE] )
  4689. speed += speed * 50 / 100;
  4690. if( speed_rate != 100 )
  4691. speed = speed * speed_rate / 100;
  4692. if( sc->data[SC_STEELBODY] )
  4693. speed = 200;
  4694. if( sc->data[SC_DEFENDER] )
  4695. speed = max(speed, 200);
  4696. if( sc->data[SC_WALKSPEED] && sc->data[SC_WALKSPEED]->val1 > 0 ) // ChangeSpeed
  4697. speed = speed * 100 / sc->data[SC_WALKSPEED]->val1;
  4698. }
  4699. return (short)cap_value(speed,10,USHRT_MAX);
  4700. }
  4701. #ifdef RENEWAL_ASPD
  4702. // flag&1 - fixed value [malufett]
  4703. // flag&2 - percentage value
  4704. static short status_calc_aspd(struct block_list *bl, struct status_change *sc, short flag)
  4705. {
  4706. int i, pots = 0, skills1 = 0, skills2 = 0;
  4707. if(!sc || !sc->count)
  4708. return 0;
  4709. if(sc->data[i=SC_ASPDPOTION3] ||
  4710. sc->data[i=SC_ASPDPOTION2] ||
  4711. sc->data[i=SC_ASPDPOTION1] ||
  4712. sc->data[i=SC_ASPDPOTION0])
  4713. pots += sc->data[i]->val1;
  4714. if( !sc->data[SC_QUAGMIRE] ){
  4715. if(sc->data[SC_STAR_COMFORT])
  4716. skills1 = 5; // needs more info
  4717. if(sc->data[SC_TWOHANDQUICKEN] && skills1 < 7)
  4718. skills1 = 7;
  4719. if(sc->data[SC_ONEHAND] && skills1 < 7) skills1 = 7;
  4720. if(sc->data[SC_MERC_QUICKEN] && skills1 < 7) // needs more info
  4721. skills1 = 7;
  4722. if(sc->data[SC_ADRENALINE2] && skills1 < 6)
  4723. skills1 = 6;
  4724. if(sc->data[SC_ADRENALINE] && skills1 < 7)
  4725. skills1 = 7;
  4726. if(sc->data[SC_SPEARQUICKEN] && skills1 < 7)
  4727. skills1 = 7;
  4728. if(sc->data[SC_GATLINGFEVER] && skills1 < 9) // needs more info
  4729. skills1 = 9;
  4730. if(sc->data[SC_FLEET] && skills1 < 5)
  4731. skills1 = 5;
  4732. if(sc->data[SC_ASSNCROS] &&
  4733. skills1 < 5+1*sc->data[SC_ASSNCROS]->val1) // needs more info
  4734. {
  4735. if (bl->type!=BL_PC)
  4736. skills1 = 4+1*sc->data[SC_ASSNCROS]->val1;
  4737. else
  4738. switch(((TBL_PC*)bl)->status.weapon)
  4739. {
  4740. case W_BOW:
  4741. case W_REVOLVER:
  4742. case W_RIFLE:
  4743. case W_GATLING:
  4744. case W_SHOTGUN:
  4745. case W_GRENADE:
  4746. break;
  4747. default:
  4748. skills1 = 5+1*sc->data[SC_ASSNCROS]->val1;
  4749. }
  4750. }
  4751. }
  4752. if((sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST]) && skills1 < 15)
  4753. skills1 = 15;
  4754. else if(sc->data[SC_MADNESSCANCEL] && skills1 < 15) // needs more info
  4755. skills1 = 15;
  4756. if(sc->data[SC_DONTFORGETME])
  4757. skills2 -= sc->data[SC_DONTFORGETME]->val2; // needs more info
  4758. if(sc->data[SC_LONGING])
  4759. skills2 -= sc->data[SC_LONGING]->val2; // needs more info
  4760. if(sc->data[SC_STEELBODY])
  4761. skills2 -= 25;
  4762. if(sc->data[SC_SKA])
  4763. skills2 -= 25;
  4764. if(sc->data[SC_DEFENDER])
  4765. skills2 -= sc->data[SC_DEFENDER]->val4; // needs more info
  4766. if(sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_ENEMY) // needs more info
  4767. skills2 -= 25;
  4768. if(sc->data[SC_GRAVITATION])
  4769. skills2 -= sc->data[SC_GRAVITATION]->val2; // needs more info
  4770. if(sc->data[SC_JOINTBEAT]) { // needs more info
  4771. if( sc->data[SC_JOINTBEAT]->val2&BREAK_WRIST )
  4772. skills2 -= 25;
  4773. if( sc->data[SC_JOINTBEAT]->val2&BREAK_KNEE )
  4774. skills2 -= 10;
  4775. }
  4776. if( sc->data[SC_FREEZING] )
  4777. skills2 -= 30;
  4778. if( sc->data[SC_HALLUCINATIONWALK_POSTDELAY] )
  4779. skills2 -= 50;
  4780. if( sc->data[SC_PARALYSE] )
  4781. skills2 -= 10;
  4782. if( sc->data[SC__BODYPAINT] )
  4783. skills2 -= 2 + 5 * sc->data[SC__BODYPAINT]->val1;
  4784. if( sc->data[SC__INVISIBILITY] )
  4785. skills2 -= sc->data[SC__INVISIBILITY]->val2 ;
  4786. if( sc->data[SC__GROOMY] )
  4787. skills2 -= sc->data[SC__GROOMY]->val2;
  4788. if( sc->data[SC_SWINGDANCE] )
  4789. skills2 += sc->data[SC_SWINGDANCE]->val2;
  4790. if( sc->data[SC_DANCEWITHWUG] )
  4791. skills2 += sc->data[SC_DANCEWITHWUG]->val3;
  4792. if( sc->data[SC_GLOOMYDAY] )
  4793. skills2 -= sc->data[SC_GLOOMYDAY]->val3;
  4794. if( sc->data[SC_EARTHDRIVE] )
  4795. skills2 -= 25;
  4796. if( sc->data[SC_GT_CHANGE] )
  4797. skills2 += sc->data[SC_GT_CHANGE]->val3;
  4798. if( sc->data[SC_MELON_BOMB] )
  4799. skills2 -= sc->data[SC_MELON_BOMB]->val1;
  4800. if( sc->data[SC_BOOST500] )
  4801. skills2 += sc->data[SC_BOOST500]->val1;
  4802. if( sc->data[SC_EXTRACT_SALAMINE_JUICE] )
  4803. skills2 += sc->data[SC_EXTRACT_SALAMINE_JUICE]->val1;
  4804. if( sc->data[SC_INCASPDRATE] )
  4805. skills2 += sc->data[SC_INCASPDRATE]->val1;
  4806. return ( flag&1? (skills1 + pots) : skills2 );
  4807. }
  4808. #endif
  4809. static short status_calc_fix_aspd(struct block_list *bl, struct status_change *sc, int aspd) {
  4810. if (!sc || !sc->count)
  4811. return cap_value(aspd, 0, 2000);
  4812. if (!sc->data[SC_QUAGMIRE]) {
  4813. if (sc->data[SC_OVERED_BOOST])
  4814. aspd = 2000 - sc->data[SC_OVERED_BOOST]->val3*10;
  4815. }
  4816. if ((sc->data[SC_GUST_OPTION] || sc->data[SC_BLAST_OPTION]
  4817. || sc->data[SC_WILD_STORM_OPTION]))
  4818. aspd -= 50; // +5 ASPD
  4819. if( sc && sc->data[SC_FIGHTINGSPIRIT] && sc->data[SC_FIGHTINGSPIRIT]->val2 )
  4820. aspd -= (bl->type==BL_PC?pc_checkskill((TBL_PC *)bl, RK_RUNEMASTERY):10) / 10 * 40;
  4821. return cap_value(aspd, 0, 2000); // will be recap for proper bl anyway
  4822. }
  4823. /// Calculates an object's ASPD modifier (alters the base amotion value).
  4824. /// Note that the scale of aspd_rate is 1000 = 100%.
  4825. static short status_calc_aspd_rate(struct block_list *bl, struct status_change *sc, int aspd_rate)
  4826. {
  4827. int i;
  4828. if(!sc || !sc->count)
  4829. return cap_value(aspd_rate,0,SHRT_MAX);
  4830. if( !sc->data[SC_QUAGMIRE] ){
  4831. int max = 0;
  4832. if(sc->data[SC_STAR_COMFORT])
  4833. max = sc->data[SC_STAR_COMFORT]->val2;
  4834. if(sc->data[SC_TWOHANDQUICKEN] &&
  4835. max < sc->data[SC_TWOHANDQUICKEN]->val2)
  4836. max = sc->data[SC_TWOHANDQUICKEN]->val2;
  4837. if(sc->data[SC_ONEHAND] &&
  4838. max < sc->data[SC_ONEHAND]->val2)
  4839. max = sc->data[SC_ONEHAND]->val2;
  4840. if(sc->data[SC_MERC_QUICKEN] &&
  4841. max < sc->data[SC_MERC_QUICKEN]->val2)
  4842. max = sc->data[SC_MERC_QUICKEN]->val2;
  4843. if(sc->data[SC_ADRENALINE2] &&
  4844. max < sc->data[SC_ADRENALINE2]->val3)
  4845. max = sc->data[SC_ADRENALINE2]->val3;
  4846. if(sc->data[SC_ADRENALINE] &&
  4847. max < sc->data[SC_ADRENALINE]->val3)
  4848. max = sc->data[SC_ADRENALINE]->val3;
  4849. if(sc->data[SC_SPEARQUICKEN] &&
  4850. max < sc->data[SC_SPEARQUICKEN]->val2)
  4851. max = sc->data[SC_SPEARQUICKEN]->val2;
  4852. if(sc->data[SC_GATLINGFEVER] &&
  4853. max < sc->data[SC_GATLINGFEVER]->val2)
  4854. max = sc->data[SC_GATLINGFEVER]->val2;
  4855. if(sc->data[SC_FLEET] &&
  4856. max < sc->data[SC_FLEET]->val2)
  4857. max = sc->data[SC_FLEET]->val2;
  4858. if(sc->data[SC_ASSNCROS] &&
  4859. max < sc->data[SC_ASSNCROS]->val2)
  4860. {
  4861. if (bl->type!=BL_PC)
  4862. max = sc->data[SC_ASSNCROS]->val2;
  4863. else
  4864. switch(((TBL_PC*)bl)->status.weapon)
  4865. {
  4866. case W_BOW:
  4867. case W_REVOLVER:
  4868. case W_RIFLE:
  4869. case W_GATLING:
  4870. case W_SHOTGUN:
  4871. case W_GRENADE:
  4872. break;
  4873. default:
  4874. max = sc->data[SC_ASSNCROS]->val2;
  4875. }
  4876. }
  4877. aspd_rate -= max;
  4878. if((sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST]))
  4879. aspd_rate -= 300;
  4880. else if(sc->data[SC_MADNESSCANCEL])
  4881. aspd_rate -= 200;
  4882. }
  4883. if( sc->data[i=SC_ASPDPOTION3] ||
  4884. sc->data[i=SC_ASPDPOTION2] ||
  4885. sc->data[i=SC_ASPDPOTION1] ||
  4886. sc->data[i=SC_ASPDPOTION0] )
  4887. aspd_rate -= sc->data[i]->val2;
  4888. if(sc->data[SC_DONTFORGETME])
  4889. aspd_rate += 10 * sc->data[SC_DONTFORGETME]->val2;
  4890. if(sc->data[SC_LONGING])
  4891. aspd_rate += sc->data[SC_LONGING]->val2;
  4892. if(sc->data[SC_STEELBODY])
  4893. aspd_rate += 250;
  4894. if(sc->data[SC_SKA])
  4895. aspd_rate += 250;
  4896. if(sc->data[SC_DEFENDER])
  4897. aspd_rate += sc->data[SC_DEFENDER]->val4;
  4898. if(sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_ENEMY)
  4899. aspd_rate += 250;
  4900. if(sc->data[SC_GRAVITATION])
  4901. aspd_rate += sc->data[SC_GRAVITATION]->val2;
  4902. if(sc->data[SC_JOINTBEAT]) {
  4903. if( sc->data[SC_JOINTBEAT]->val2&BREAK_WRIST )
  4904. aspd_rate += 250;
  4905. if( sc->data[SC_JOINTBEAT]->val2&BREAK_KNEE )
  4906. aspd_rate += 100;
  4907. }
  4908. if( sc->data[SC_FREEZING] )
  4909. aspd_rate += 300;
  4910. if( sc->data[SC_HALLUCINATIONWALK_POSTDELAY] )
  4911. aspd_rate += 500;
  4912. if( sc->data[SC_FIGHTINGSPIRIT] && sc->data[SC_FIGHTINGSPIRIT]->val2 )
  4913. aspd_rate -= sc->data[SC_FIGHTINGSPIRIT]->val2;
  4914. if( sc->data[SC_PARALYSE] )
  4915. aspd_rate += 100;
  4916. if( sc->data[SC__BODYPAINT] )
  4917. aspd_rate += 200 + 50 * sc->data[SC__BODYPAINT]->val1;
  4918. if( sc->data[SC__INVISIBILITY] )
  4919. aspd_rate += sc->data[SC__INVISIBILITY]->val2 * 10 ;
  4920. if( sc->data[SC__GROOMY] )
  4921. aspd_rate += sc->data[SC__GROOMY]->val2 * 10;
  4922. if( sc->data[SC_SWINGDANCE] )
  4923. aspd_rate -= sc->data[SC_SWINGDANCE]->val2 * 10;
  4924. if( sc->data[SC_DANCEWITHWUG] )
  4925. aspd_rate -= sc->data[SC_DANCEWITHWUG]->val3 * 10;
  4926. if( sc->data[SC_GLOOMYDAY] )
  4927. aspd_rate += sc->data[SC_GLOOMYDAY]->val3 * 10;
  4928. if( sc->data[SC_EARTHDRIVE] )
  4929. aspd_rate += 250;
  4930. if( sc->data[SC_GT_CHANGE] )
  4931. aspd_rate -= sc->data[SC_GT_CHANGE]->val3 * 10;
  4932. if( sc->data[SC_MELON_BOMB] )
  4933. aspd_rate += sc->data[SC_MELON_BOMB]->val1 * 10;
  4934. if( sc->data[SC_BOOST500] )
  4935. aspd_rate -= sc->data[SC_BOOST500]->val1 *10;
  4936. if( sc->data[SC_EXTRACT_SALAMINE_JUICE] )
  4937. aspd_rate -= sc->data[SC_EXTRACT_SALAMINE_JUICE]->val1 * 10;
  4938. if( sc->data[SC_INCASPDRATE] )
  4939. aspd_rate -= sc->data[SC_INCASPDRATE]->val1 * 10;
  4940. if( sc->data[SC_PAIN_KILLER])
  4941. aspd_rate += sc->data[SC_PAIN_KILLER]->val2 * 10;
  4942. if( sc->data[SC_GOLDENE_FERSE])
  4943. aspd_rate -= sc->data[SC_GOLDENE_FERSE]->val3 * 10;
  4944. return (short)cap_value(aspd_rate,0,SHRT_MAX);
  4945. }
  4946. static unsigned short status_calc_dmotion(struct block_list *bl, struct status_change *sc, int dmotion)
  4947. {
  4948. if( !sc || !sc->count || map_flag_gvg(bl->m) || map[bl->m].flag.battleground )
  4949. return cap_value(dmotion,0,USHRT_MAX);
  4950. /**
  4951. * It has been confirmed on official servers that MvP mobs have no dmotion even without endure
  4952. **/
  4953. if( sc->data[SC_ENDURE] || ( bl->type == BL_MOB && (((TBL_MOB*)bl)->status.mode&MD_BOSS) ) )
  4954. return 0;
  4955. if( sc->data[SC_CONCENTRATION] )
  4956. return 0;
  4957. if( sc->data[SC_RUN] || sc->data[SC_WUGDASH] )
  4958. return 0;
  4959. return (unsigned short)cap_value(dmotion,0,USHRT_MAX);
  4960. }
  4961. static unsigned int status_calc_maxhp(struct block_list *bl, struct status_change *sc, uint64 maxhp)
  4962. {
  4963. if(!sc || !sc->count)
  4964. return (unsigned int)cap_value(maxhp,1,UINT_MAX);
  4965. if(sc->data[SC_INCMHPRATE])
  4966. maxhp += maxhp * sc->data[SC_INCMHPRATE]->val1/100;
  4967. if(sc->data[SC_INCMHP])
  4968. maxhp += (sc->data[SC_INCMHP]->val1);
  4969. if(sc->data[SC_APPLEIDUN])
  4970. maxhp += maxhp * sc->data[SC_APPLEIDUN]->val2/100;
  4971. if(sc->data[SC_DELUGE])
  4972. maxhp += maxhp * sc->data[SC_DELUGE]->val2/100;
  4973. if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST])
  4974. maxhp += maxhp * 2;
  4975. if(sc->data[SC_MARIONETTE])
  4976. maxhp -= 1000;
  4977. if(sc->data[SC_SOLID_SKIN_OPTION])
  4978. maxhp += 2000;// Fix amount.
  4979. if(sc->data[SC_POWER_OF_GAIA])
  4980. maxhp += 3000;
  4981. if(sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 2)
  4982. maxhp += 500;
  4983. if(sc->data[SC_MERC_HPUP])
  4984. maxhp += maxhp * sc->data[SC_MERC_HPUP]->val2/100;
  4985. if(sc->data[SC_EPICLESIS])
  4986. maxhp += maxhp * 5 * sc->data[SC_EPICLESIS]->val1 / 100;
  4987. if(sc->data[SC_VENOMBLEED])
  4988. maxhp -= maxhp * 15 / 100;
  4989. if(sc->data[SC__WEAKNESS])
  4990. maxhp -= maxhp * sc->data[SC__WEAKNESS]->val2 / 100;
  4991. if(sc->data[SC_LERADSDEW])
  4992. maxhp += maxhp * sc->data[SC_LERADSDEW]->val3 / 100;
  4993. if(sc->data[SC_FORCEOFVANGUARD])
  4994. maxhp += maxhp * 3 * sc->data[SC_FORCEOFVANGUARD]->val1 / 100;
  4995. if(sc->data[SC_INSPIRATION]) //Custom value.
  4996. maxhp += maxhp * 3 * sc->data[SC_INSPIRATION]->val1 / 100;
  4997. if(sc->data[SC_RAISINGDRAGON])
  4998. maxhp += maxhp * (2 + sc->data[SC_RAISINGDRAGON]->val1) / 100;
  4999. if(sc->data[SC_GT_CHANGE]) // Max HP decrease: [Skill Level x 4] %
  5000. maxhp -= maxhp * (4 * sc->data[SC_GT_CHANGE]->val1) / 100;
  5001. if(sc->data[SC_GT_REVITALIZE])// Max HP increase: [Skill Level x 2] %
  5002. maxhp += maxhp * (2 * sc->data[SC_GT_REVITALIZE]->val1) / 100;
  5003. if(sc->data[SC_MUSTLE_M])
  5004. maxhp += maxhp * sc->data[SC_MUSTLE_M]->val1/100;
  5005. if(sc->data[SC_MYSTERIOUS_POWDER])
  5006. maxhp -= sc->data[SC_MYSTERIOUS_POWDER]->val1 / 100;
  5007. if(sc->data[SC_PETROLOGY_OPTION])
  5008. maxhp += maxhp * sc->data[SC_PETROLOGY_OPTION]->val2 / 100;
  5009. if (sc->data[SC_ANGRIFFS_MODUS])
  5010. maxhp += maxhp * 5 * sc->data[SC_ANGRIFFS_MODUS]->val1 /100;
  5011. if (sc->data[SC_GOLDENE_FERSE])
  5012. maxhp += maxhp * sc->data[SC_GOLDENE_FERSE]->val2 / 100;
  5013. return (unsigned int)cap_value(maxhp,1,UINT_MAX);
  5014. }
  5015. static unsigned int status_calc_maxsp(struct block_list *bl, struct status_change *sc, unsigned int maxsp)
  5016. {
  5017. if(!sc || !sc->count)
  5018. return cap_value(maxsp,1,UINT_MAX);
  5019. if(sc->data[SC_INCMSPRATE])
  5020. maxsp += maxsp * sc->data[SC_INCMSPRATE]->val1/100;
  5021. if(sc->data[SC_INCMSP])
  5022. maxsp += (sc->data[SC_INCMSP]->val1);
  5023. if(sc->data[SC_SERVICE4U])
  5024. maxsp += maxsp * sc->data[SC_SERVICE4U]->val2/100;
  5025. if(sc->data[SC_MERC_SPUP])
  5026. maxsp += maxsp * sc->data[SC_MERC_SPUP]->val2/100;
  5027. if(sc->data[SC_RAISINGDRAGON])
  5028. maxsp += maxsp * (2 + sc->data[SC_RAISINGDRAGON]->val1) / 100;
  5029. if(sc->data[SC_LIFE_FORCE_F])
  5030. maxsp += maxsp * sc->data[SC_LIFE_FORCE_F]->val1/100;
  5031. if(sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 3)
  5032. maxsp += 50;
  5033. return cap_value(maxsp,1,UINT_MAX);
  5034. }
  5035. static unsigned char status_calc_element(struct block_list *bl, struct status_change *sc, int element)
  5036. {
  5037. if(!sc || !sc->count)
  5038. return element;
  5039. if(sc->data[SC_FREEZE])
  5040. return ELE_WATER;
  5041. if(sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
  5042. return ELE_EARTH;
  5043. if(sc->data[SC_BENEDICTIO])
  5044. return ELE_HOLY;
  5045. if(sc->data[SC_CHANGEUNDEAD])
  5046. return ELE_UNDEAD;
  5047. if(sc->data[SC_ELEMENTALCHANGE])
  5048. return sc->data[SC_ELEMENTALCHANGE]->val2;
  5049. if(sc->data[SC_SHAPESHIFT])
  5050. return sc->data[SC_SHAPESHIFT]->val2;
  5051. return (unsigned char)cap_value(element,0,UCHAR_MAX);
  5052. }
  5053. static unsigned char status_calc_element_lv(struct block_list *bl, struct status_change *sc, int lv)
  5054. {
  5055. if(!sc || !sc->count)
  5056. return lv;
  5057. if(sc->data[SC_FREEZE])
  5058. return 1;
  5059. if(sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
  5060. return 1;
  5061. if(sc->data[SC_BENEDICTIO])
  5062. return 1;
  5063. if(sc->data[SC_CHANGEUNDEAD])
  5064. return 1;
  5065. if(sc->data[SC_ELEMENTALCHANGE])
  5066. return sc->data[SC_ELEMENTALCHANGE]->val1;
  5067. if(sc->data[SC_SHAPESHIFT])
  5068. return 1;
  5069. if(sc->data[SC__INVISIBILITY])
  5070. return 1;
  5071. return (unsigned char)cap_value(lv,1,4);
  5072. }
  5073. unsigned char status_calc_attack_element(struct block_list *bl, struct status_change *sc, int element)
  5074. {
  5075. if(!sc || !sc->count)
  5076. return element;
  5077. if(sc->data[SC_ENCHANTARMS])
  5078. return sc->data[SC_ENCHANTARMS]->val2;
  5079. if(sc->data[SC_WATERWEAPON]
  5080. || (sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 2) )
  5081. return ELE_WATER;
  5082. if(sc->data[SC_EARTHWEAPON]
  5083. || (sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 2) )
  5084. return ELE_EARTH;
  5085. if(sc->data[SC_FIREWEAPON]
  5086. || (sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 2) )
  5087. return ELE_FIRE;
  5088. if(sc->data[SC_WINDWEAPON]
  5089. || (sc->data[SC_WIND_INSIGNIA] && sc->data[SC_WIND_INSIGNIA]->val1 == 2) )
  5090. return ELE_WIND;
  5091. if(sc->data[SC_ENCPOISON])
  5092. return ELE_POISON;
  5093. if(sc->data[SC_ASPERSIO])
  5094. return ELE_HOLY;
  5095. if(sc->data[SC_SHADOWWEAPON])
  5096. return ELE_DARK;
  5097. if(sc->data[SC_GHOSTWEAPON] || sc->data[SC__INVISIBILITY])
  5098. return ELE_GHOST;
  5099. if(sc->data[SC_TIDAL_WEAPON_OPTION] || sc->data[SC_TIDAL_WEAPON] )
  5100. return ELE_WATER;
  5101. if(sc->data[SC_PYROCLASTIC])
  5102. return ELE_FIRE;
  5103. return (unsigned char)cap_value(element,0,UCHAR_MAX);
  5104. }
  5105. static unsigned short status_calc_mode(struct block_list *bl, struct status_change *sc, int mode)
  5106. {
  5107. if(!sc || !sc->count)
  5108. return mode;
  5109. if(sc->data[SC_MODECHANGE]) {
  5110. if (sc->data[SC_MODECHANGE]->val2)
  5111. mode = sc->data[SC_MODECHANGE]->val2; //Set mode
  5112. if (sc->data[SC_MODECHANGE]->val3)
  5113. mode|= sc->data[SC_MODECHANGE]->val3; //Add mode
  5114. if (sc->data[SC_MODECHANGE]->val4)
  5115. mode&=~sc->data[SC_MODECHANGE]->val4; //Del mode
  5116. }
  5117. return cap_value(mode,0,USHRT_MAX);
  5118. }
  5119. const char* status_get_name(struct block_list *bl) {
  5120. nullpo_ret(bl);
  5121. switch (bl->type) {
  5122. case BL_PC: return ((TBL_PC *)bl)->fakename[0] != '\0' ? ((TBL_PC*)bl)->fakename : ((TBL_PC*)bl)->status.name;
  5123. case BL_MOB: return ((TBL_MOB*)bl)->name;
  5124. case BL_PET: return ((TBL_PET*)bl)->pet.name;
  5125. case BL_HOM: return ((TBL_HOM*)bl)->homunculus.name;
  5126. case BL_NPC: return ((TBL_NPC*)bl)->name;
  5127. }
  5128. return "Unknown";
  5129. }
  5130. /*==========================================
  5131. * Get the class of the current bl
  5132. * return
  5133. * 0 = fail
  5134. * class_id = success
  5135. *------------------------------------------*/
  5136. int status_get_class(struct block_list *bl) {
  5137. nullpo_ret(bl);
  5138. switch( bl->type ) {
  5139. case BL_PC: return ((TBL_PC*)bl)->status.class_;
  5140. case BL_MOB: return ((TBL_MOB*)bl)->vd->class_; //Class used on all code should be the view class of the mob.
  5141. case BL_PET: return ((TBL_PET*)bl)->pet.class_;
  5142. case BL_HOM: return ((TBL_HOM*)bl)->homunculus.class_;
  5143. case BL_MER: return ((TBL_MER*)bl)->mercenary.class_;
  5144. case BL_NPC: return ((TBL_NPC*)bl)->class_;
  5145. case BL_ELEM: return ((TBL_ELEM*)bl)->elemental.class_;
  5146. }
  5147. return 0;
  5148. }
  5149. /*==========================================
  5150. * Get the base level of the current bl
  5151. * return
  5152. * 1 = fail
  5153. * level = success
  5154. *------------------------------------------*/
  5155. int status_get_lv(struct block_list *bl) {
  5156. nullpo_ret(bl);
  5157. switch (bl->type) {
  5158. case BL_PC: return ((TBL_PC*)bl)->status.base_level;
  5159. case BL_MOB: return ((TBL_MOB*)bl)->level;
  5160. case BL_PET: return ((TBL_PET*)bl)->pet.level;
  5161. case BL_HOM: return ((TBL_HOM*)bl)->homunculus.level;
  5162. case BL_MER: return ((TBL_MER*)bl)->db->lv;
  5163. case BL_ELEM: return ((TBL_ELEM*)bl)->db->lv;
  5164. case BL_NPC: return ((TBL_NPC*)bl)->level;
  5165. }
  5166. return 1;
  5167. }
  5168. struct regen_data *status_get_regen_data(struct block_list *bl)
  5169. {
  5170. nullpo_retr(NULL, bl);
  5171. switch (bl->type) {
  5172. case BL_PC: return &((TBL_PC*)bl)->regen;
  5173. case BL_HOM: return &((TBL_HOM*)bl)->regen;
  5174. case BL_MER: return &((TBL_MER*)bl)->regen;
  5175. case BL_ELEM: return &((TBL_ELEM*)bl)->regen;
  5176. default:
  5177. return NULL;
  5178. }
  5179. }
  5180. struct status_data *status_get_status_data(struct block_list *bl)
  5181. {
  5182. nullpo_retr(&dummy_status, bl);
  5183. switch (bl->type) {
  5184. case BL_PC: return &((TBL_PC*)bl)->battle_status;
  5185. case BL_MOB: return &((TBL_MOB*)bl)->status;
  5186. case BL_PET: return &((TBL_PET*)bl)->status;
  5187. case BL_HOM: return &((TBL_HOM*)bl)->battle_status;
  5188. case BL_MER: return &((TBL_MER*)bl)->battle_status;
  5189. case BL_ELEM: return &((TBL_ELEM*)bl)->battle_status;
  5190. case BL_NPC: return ((mobdb_checkid(((TBL_NPC*)bl)->class_) == 0) ? &((TBL_NPC*)bl)->status : &dummy_status);
  5191. default:
  5192. return &dummy_status;
  5193. }
  5194. }
  5195. struct status_data *status_get_base_status(struct block_list *bl)
  5196. {
  5197. nullpo_retr(NULL, bl);
  5198. switch (bl->type) {
  5199. case BL_PC: return &((TBL_PC*)bl)->base_status;
  5200. case BL_MOB: return ((TBL_MOB*)bl)->base_status ? ((TBL_MOB*)bl)->base_status : &((TBL_MOB*)bl)->db->status;
  5201. case BL_PET: return &((TBL_PET*)bl)->db->status;
  5202. case BL_HOM: return &((TBL_HOM*)bl)->base_status;
  5203. case BL_MER: return &((TBL_MER*)bl)->base_status;
  5204. case BL_ELEM: return &((TBL_ELEM*)bl)->base_status;
  5205. case BL_NPC: return ((mobdb_checkid(((TBL_NPC*)bl)->class_) == 0) ? &((TBL_NPC*)bl)->status : NULL);
  5206. default:
  5207. return NULL;
  5208. }
  5209. }
  5210. defType status_get_def(struct block_list *bl) {
  5211. struct unit_data *ud;
  5212. struct status_data *status = status_get_status_data(bl);
  5213. int def = status?status->def:0;
  5214. ud = unit_bl2ud(bl);
  5215. if (ud && ud->skilltimer != INVALID_TIMER)
  5216. def -= def * skill_get_castdef(ud->skill_id)/100;
  5217. return cap_value(def, DEFTYPE_MIN, DEFTYPE_MAX);
  5218. }
  5219. unsigned short status_get_speed(struct block_list *bl)
  5220. {
  5221. if(bl->type==BL_NPC)//Only BL with speed data but no status_data [Skotlex]
  5222. return ((struct npc_data *)bl)->speed;
  5223. return status_get_status_data(bl)->speed;
  5224. }
  5225. int status_get_party_id(struct block_list *bl) {
  5226. nullpo_ret(bl);
  5227. switch (bl->type) {
  5228. case BL_PC:
  5229. return ((TBL_PC*)bl)->status.party_id;
  5230. case BL_PET:
  5231. if (((TBL_PET*)bl)->msd)
  5232. return ((TBL_PET*)bl)->msd->status.party_id;
  5233. break;
  5234. case BL_MOB: {
  5235. struct mob_data *md=(TBL_MOB*)bl;
  5236. if( md->master_id > 0 ) {
  5237. struct map_session_data *msd;
  5238. if (md->special_state.ai && (msd = map_id2sd(md->master_id)) != NULL)
  5239. return msd->status.party_id;
  5240. return -md->master_id;
  5241. }
  5242. }
  5243. break;
  5244. case BL_HOM:
  5245. if (((TBL_HOM*)bl)->master)
  5246. return ((TBL_HOM*)bl)->master->status.party_id;
  5247. break;
  5248. case BL_MER:
  5249. if (((TBL_MER*)bl)->master)
  5250. return ((TBL_MER*)bl)->master->status.party_id;
  5251. break;
  5252. case BL_SKILL:
  5253. return ((TBL_SKILL*)bl)->group->party_id;
  5254. case BL_ELEM:
  5255. if (((TBL_ELEM*)bl)->master)
  5256. return ((TBL_ELEM*)bl)->master->status.party_id;
  5257. break;
  5258. }
  5259. return 0;
  5260. }
  5261. int status_get_guild_id(struct block_list *bl) {
  5262. nullpo_ret(bl);
  5263. switch (bl->type) {
  5264. case BL_PC:
  5265. return ((TBL_PC*)bl)->status.guild_id;
  5266. case BL_PET:
  5267. if (((TBL_PET*)bl)->msd)
  5268. return ((TBL_PET*)bl)->msd->status.guild_id;
  5269. break;
  5270. case BL_MOB: {
  5271. struct map_session_data *msd;
  5272. struct mob_data *md = (struct mob_data *)bl;
  5273. if (md->guardian_data) //Guardian's guild [Skotlex]
  5274. return md->guardian_data->guild_id;
  5275. if (md->special_state.ai && (msd = map_id2sd(md->master_id)) != NULL)
  5276. return msd->status.guild_id; //Alchemist's mobs [Skotlex]
  5277. }
  5278. break;
  5279. case BL_HOM:
  5280. if (((TBL_HOM*)bl)->master)
  5281. return ((TBL_HOM*)bl)->master->status.guild_id;
  5282. break;
  5283. case BL_MER:
  5284. if (((TBL_MER*)bl)->master)
  5285. return ((TBL_MER*)bl)->master->status.guild_id;
  5286. break;
  5287. case BL_NPC:
  5288. if (((TBL_NPC*)bl)->subtype == SCRIPT)
  5289. return ((TBL_NPC*)bl)->u.scr.guild_id;
  5290. break;
  5291. case BL_SKILL:
  5292. return ((TBL_SKILL*)bl)->group->guild_id;
  5293. case BL_ELEM:
  5294. if (((TBL_ELEM*)bl)->master)
  5295. return ((TBL_ELEM*)bl)->master->status.guild_id;
  5296. break;
  5297. }
  5298. return 0;
  5299. }
  5300. int status_get_emblem_id(struct block_list *bl) {
  5301. nullpo_ret(bl);
  5302. switch (bl->type) {
  5303. case BL_PC:
  5304. return ((TBL_PC*)bl)->guild_emblem_id;
  5305. case BL_PET:
  5306. if (((TBL_PET*)bl)->msd)
  5307. return ((TBL_PET*)bl)->msd->guild_emblem_id;
  5308. break;
  5309. case BL_MOB: {
  5310. struct map_session_data *msd;
  5311. struct mob_data *md = (struct mob_data *)bl;
  5312. if (md->guardian_data) //Guardian's guild [Skotlex]
  5313. return md->guardian_data->emblem_id;
  5314. if (md->special_state.ai && (msd = map_id2sd(md->master_id)) != NULL)
  5315. return msd->guild_emblem_id; //Alchemist's mobs [Skotlex]
  5316. }
  5317. break;
  5318. case BL_HOM:
  5319. if (((TBL_HOM*)bl)->master)
  5320. return ((TBL_HOM*)bl)->master->guild_emblem_id;
  5321. break;
  5322. case BL_MER:
  5323. if (((TBL_MER*)bl)->master)
  5324. return ((TBL_MER*)bl)->master->guild_emblem_id;
  5325. break;
  5326. case BL_NPC:
  5327. if (((TBL_NPC*)bl)->subtype == SCRIPT && ((TBL_NPC*)bl)->u.scr.guild_id > 0) {
  5328. struct guild *g = guild_search(((TBL_NPC*)bl)->u.scr.guild_id);
  5329. if (g)
  5330. return g->emblem_id;
  5331. }
  5332. break;
  5333. case BL_ELEM:
  5334. if (((TBL_ELEM*)bl)->master)
  5335. return ((TBL_ELEM*)bl)->master->guild_emblem_id;
  5336. break;
  5337. }
  5338. return 0;
  5339. }
  5340. int status_get_mexp(struct block_list *bl)
  5341. {
  5342. nullpo_ret(bl);
  5343. if(bl->type==BL_MOB)
  5344. return ((struct mob_data *)bl)->db->mexp;
  5345. if(bl->type==BL_PET)
  5346. return ((struct pet_data *)bl)->db->mexp;
  5347. return 0;
  5348. }
  5349. int status_get_race2(struct block_list *bl)
  5350. {
  5351. nullpo_ret(bl);
  5352. if(bl->type == BL_MOB)
  5353. return ((struct mob_data *)bl)->db->race2;
  5354. if(bl->type==BL_PET)
  5355. return ((struct pet_data *)bl)->db->race2;
  5356. return 0;
  5357. }
  5358. int status_isdead(struct block_list *bl)
  5359. {
  5360. nullpo_ret(bl);
  5361. return status_get_status_data(bl)->hp == 0;
  5362. }
  5363. int status_isimmune(struct block_list *bl)
  5364. {
  5365. struct status_change *sc =status_get_sc(bl);
  5366. if (sc && sc->data[SC_HERMODE])
  5367. return 100;
  5368. if (bl->type == BL_PC &&
  5369. ((TBL_PC*)bl)->special_state.no_magic_damage >= battle_config.gtb_sc_immunity)
  5370. return ((TBL_PC*)bl)->special_state.no_magic_damage;
  5371. return 0;
  5372. }
  5373. struct view_data* status_get_viewdata(struct block_list *bl)
  5374. {
  5375. nullpo_retr(NULL, bl);
  5376. switch (bl->type) {
  5377. case BL_PC: return &((TBL_PC*)bl)->vd;
  5378. case BL_MOB: return ((TBL_MOB*)bl)->vd;
  5379. case BL_PET: return &((TBL_PET*)bl)->vd;
  5380. case BL_NPC: return ((TBL_NPC*)bl)->vd;
  5381. case BL_HOM: return ((TBL_HOM*)bl)->vd;
  5382. case BL_MER: return ((TBL_MER*)bl)->vd;
  5383. case BL_ELEM: return ((TBL_ELEM*)bl)->vd;
  5384. }
  5385. return NULL;
  5386. }
  5387. void status_set_viewdata(struct block_list *bl, int class_)
  5388. {
  5389. struct view_data* vd;
  5390. nullpo_retv(bl);
  5391. if (mobdb_checkid(class_) || mob_is_clone(class_))
  5392. vd = mob_get_viewdata(class_);
  5393. else if (npcdb_checkid(class_) || (bl->type == BL_NPC && class_ == WARP_CLASS))
  5394. vd = npc_get_viewdata(class_);
  5395. else if (homdb_checkid(class_))
  5396. vd = merc_get_hom_viewdata(class_);
  5397. else if (merc_class(class_))
  5398. vd = merc_get_viewdata(class_);
  5399. else if (elemental_class(class_))
  5400. vd = elemental_get_viewdata(class_);
  5401. else
  5402. vd = NULL;
  5403. switch (bl->type) {
  5404. case BL_PC:
  5405. {
  5406. TBL_PC* sd = (TBL_PC*)bl;
  5407. if (pcdb_checkid(class_)) {
  5408. if (sd->sc.option&OPTION_WEDDING)
  5409. class_ = JOB_WEDDING;
  5410. else if (sd->sc.option&OPTION_SUMMER)
  5411. class_ = JOB_SUMMER;
  5412. else if (sd->sc.option&OPTION_XMAS)
  5413. class_ = JOB_XMAS;
  5414. else if (sd->sc.option&OPTION_RIDING) {
  5415. switch (class_) { //Adapt class to a Mounted one.
  5416. case JOB_KNIGHT:
  5417. class_ = JOB_KNIGHT2;
  5418. break;
  5419. case JOB_CRUSADER:
  5420. class_ = JOB_CRUSADER2;
  5421. break;
  5422. case JOB_LORD_KNIGHT:
  5423. class_ = JOB_LORD_KNIGHT2;
  5424. break;
  5425. case JOB_PALADIN:
  5426. class_ = JOB_PALADIN2;
  5427. break;
  5428. case JOB_BABY_KNIGHT:
  5429. class_ = JOB_BABY_KNIGHT2;
  5430. break;
  5431. case JOB_BABY_CRUSADER:
  5432. class_ = JOB_BABY_CRUSADER2;
  5433. break;
  5434. }
  5435. }
  5436. sd->vd.class_ = class_;
  5437. clif_get_weapon_view(sd, &sd->vd.weapon, &sd->vd.shield);
  5438. sd->vd.head_top = sd->status.head_top;
  5439. sd->vd.head_mid = sd->status.head_mid;
  5440. sd->vd.head_bottom = sd->status.head_bottom;
  5441. sd->vd.hair_style = cap_value(sd->status.hair,0,battle_config.max_hair_style);
  5442. sd->vd.hair_color = cap_value(sd->status.hair_color,0,battle_config.max_hair_color);
  5443. sd->vd.cloth_color = cap_value(sd->status.clothes_color,0,battle_config.max_cloth_color);
  5444. sd->vd.sex = sd->status.sex;
  5445. } else if (vd)
  5446. memcpy(&sd->vd, vd, sizeof(struct view_data));
  5447. else
  5448. ShowError("status_set_viewdata (PC): No view data for class %d\n", class_);
  5449. }
  5450. break;
  5451. case BL_MOB:
  5452. {
  5453. TBL_MOB* md = (TBL_MOB*)bl;
  5454. if (vd)
  5455. md->vd = vd;
  5456. else
  5457. ShowError("status_set_viewdata (MOB): No view data for class %d\n", class_);
  5458. }
  5459. break;
  5460. case BL_PET:
  5461. {
  5462. TBL_PET* pd = (TBL_PET*)bl;
  5463. if (vd) {
  5464. memcpy(&pd->vd, vd, sizeof(struct view_data));
  5465. if (!pcdb_checkid(vd->class_)) {
  5466. pd->vd.hair_style = battle_config.pet_hair_style;
  5467. if(pd->pet.equip) {
  5468. pd->vd.head_bottom = itemdb_viewid(pd->pet.equip);
  5469. if (!pd->vd.head_bottom)
  5470. pd->vd.head_bottom = pd->pet.equip;
  5471. }
  5472. }
  5473. } else
  5474. ShowError("status_set_viewdata (PET): No view data for class %d\n", class_);
  5475. }
  5476. break;
  5477. case BL_NPC:
  5478. {
  5479. TBL_NPC* nd = (TBL_NPC*)bl;
  5480. if (vd)
  5481. nd->vd = vd;
  5482. else
  5483. ShowError("status_set_viewdata (NPC): No view data for class %d\n", class_);
  5484. }
  5485. break;
  5486. case BL_HOM: //[blackhole89]
  5487. {
  5488. struct homun_data *hd = (struct homun_data*)bl;
  5489. if (vd)
  5490. hd->vd = vd;
  5491. else
  5492. ShowError("status_set_viewdata (HOMUNCULUS): No view data for class %d\n", class_);
  5493. }
  5494. break;
  5495. case BL_MER:
  5496. {
  5497. struct mercenary_data *md = (struct mercenary_data*)bl;
  5498. if (vd)
  5499. md->vd = vd;
  5500. else
  5501. ShowError("status_set_viewdata (MERCENARY): No view data for class %d\n", class_);
  5502. }
  5503. break;
  5504. case BL_ELEM:
  5505. {
  5506. struct elemental_data *ed = (struct elemental_data*)bl;
  5507. if (vd)
  5508. ed->vd = vd;
  5509. else
  5510. ShowError("status_set_viewdata (ELEMENTAL): No view data for class %d\n", class_);
  5511. }
  5512. break;
  5513. }
  5514. vd = status_get_viewdata(bl);
  5515. if (vd && vd->cloth_color && (
  5516. (vd->class_==JOB_WEDDING && battle_config.wedding_ignorepalette)
  5517. || (vd->class_==JOB_XMAS && battle_config.xmas_ignorepalette)
  5518. || (vd->class_==JOB_SUMMER && battle_config.summer_ignorepalette)
  5519. ))
  5520. vd->cloth_color = 0;
  5521. }
  5522. /// Returns the status_change data of bl or NULL if it doesn't exist.
  5523. struct status_change *status_get_sc(struct block_list *bl) {
  5524. if( bl )
  5525. switch (bl->type) {
  5526. case BL_PC: return &((TBL_PC*)bl)->sc;
  5527. case BL_MOB: return &((TBL_MOB*)bl)->sc;
  5528. case BL_NPC: return &((TBL_NPC*)bl)->sc;
  5529. case BL_HOM: return &((TBL_HOM*)bl)->sc;
  5530. case BL_MER: return &((TBL_MER*)bl)->sc;
  5531. case BL_ELEM: return &((TBL_ELEM*)bl)->sc;
  5532. }
  5533. return NULL;
  5534. }
  5535. void status_change_init(struct block_list *bl)
  5536. {
  5537. struct status_change *sc = status_get_sc(bl);
  5538. nullpo_retv(sc);
  5539. memset(sc, 0, sizeof (struct status_change));
  5540. }
  5541. //Applies SC defense to a given status change.
  5542. //Returns the adjusted duration based on flag values.
  5543. //the flag values are the same as in status_change_start.
  5544. int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int tick, int flag)
  5545. {
  5546. int sc_def = 0, tick_def = 0;
  5547. struct status_data* status;
  5548. struct status_change* sc;
  5549. struct map_session_data *sd;
  5550. nullpo_ret(bl);
  5551. //Status that are blocked by Golden Thief Bug card or Wand of Hermod
  5552. if (status_isimmune(bl))
  5553. switch (type) {
  5554. case SC_DECREASEAGI:
  5555. case SC_SILENCE:
  5556. case SC_COMA:
  5557. case SC_INCREASEAGI:
  5558. case SC_BLESSING:
  5559. case SC_SLOWPOISON:
  5560. case SC_IMPOSITIO:
  5561. case SC_AETERNA:
  5562. case SC_SUFFRAGIUM:
  5563. case SC_BENEDICTIO:
  5564. case SC_PROVIDENCE:
  5565. case SC_KYRIE:
  5566. case SC_ASSUMPTIO:
  5567. case SC_ANGELUS:
  5568. case SC_MAGNIFICAT:
  5569. case SC_GLORIA:
  5570. case SC_WINDWALK:
  5571. case SC_MAGICROD:
  5572. case SC_HALLUCINATION:
  5573. case SC_STONE:
  5574. case SC_QUAGMIRE:
  5575. case SC_SUITON:
  5576. case SC_SWINGDANCE:
  5577. case SC__ENERVATION:
  5578. case SC__GROOMY:
  5579. case SC__IGNORANCE:
  5580. case SC__LAZINESS:
  5581. case SC__UNLUCKY:
  5582. case SC__WEAKNESS:
  5583. case SC__BLOODYLUST:
  5584. return 0;
  5585. }
  5586. sd = BL_CAST(BL_PC,bl);
  5587. status = status_get_status_data(bl);
  5588. sc = status_get_sc(bl);
  5589. if( sc && !sc->count )
  5590. sc = NULL;
  5591. switch (type) {
  5592. case SC_STUN:
  5593. case SC_POISON:
  5594. if( sc && sc->data[SC__UNLUCKY] )
  5595. return tick;
  5596. case SC_DPOISON:
  5597. case SC_SILENCE:
  5598. case SC_BLEEDING:
  5599. sc_def = 3 +status->vit;
  5600. break;
  5601. case SC_SLEEP:
  5602. sc_def = 3 +status->int_;
  5603. break;
  5604. case SC_DEEPSLEEP:
  5605. tick_def = status->int_ / 10 + status_get_lv(bl) * 65 / 1000; // Seems to be -1 sec every 10 int and -5% chance every 10 int.
  5606. sc_def = 5 * status->int_ /10;
  5607. break;
  5608. case SC_DECREASEAGI:
  5609. case SC_ADORAMUS://Arch Bishop
  5610. if (sd) tick>>=1; //Half duration for players.
  5611. case SC_STONE:
  5612. case SC_FREEZE:
  5613. sc_def = 3 +status->mdef;
  5614. break;
  5615. case SC_CURSE:
  5616. //Special property: inmunity when luk is greater than level or zero
  5617. if (status->luk > status_get_lv(bl) || status->luk == 0)
  5618. return 0;
  5619. else
  5620. sc_def = 3 +status->luk;
  5621. tick_def = status->vit;
  5622. break;
  5623. case SC_BLIND:
  5624. if( sc && sc->data[SC__UNLUCKY] )
  5625. return tick;
  5626. sc_def = 3 +(status->vit + status->int_)/2;
  5627. break;
  5628. case SC_CONFUSION:
  5629. sc_def = 3 +(status->str + status->int_)/2;
  5630. break;
  5631. case SC_ANKLE:
  5632. if(status->mode&MD_BOSS) // Lasts 5 times less on bosses
  5633. tick /= 5;
  5634. sc_def = status->agi / 2;
  5635. break;
  5636. case SC_MAGICMIRROR:
  5637. case SC_ARMORCHANGE:
  5638. if (sd) //Duration greatly reduced for players.
  5639. tick /= 15;
  5640. //No defense against it (buff).
  5641. rate -= (status_get_lv(bl) / 5 + status->vit / 4 + status->agi / 10)*100; // Lineal Reduction of Rate
  5642. break;
  5643. case SC_MARSHOFABYSS:
  5644. //5 second (Fixed) + 25 second - {( INT + LUK ) / 20 second }
  5645. tick -= (status->int_ + status->luk) / 20 * 1000;
  5646. break;
  5647. case SC_STASIS:
  5648. //5 second (fixed) + { Stasis Skill level * 5 - (Target�s VIT + DEX) / 20 }
  5649. tick -= (status->vit + status->dex) / 20 * 1000;
  5650. break;
  5651. case SC_WHITEIMPRISON:
  5652. if( tick == 5000 ) // 100% on caster
  5653. break;
  5654. if( bl->type == BL_PC )
  5655. tick -= (status_get_lv(bl) / 5 + status->vit / 4 + status->agi / 10)*100;
  5656. else
  5657. tick -= (status->vit + status->luk) / 20 * 1000;
  5658. break;
  5659. case SC_BURNING:
  5660. // From iROwiki : http://forums.irowiki.org/showpost.php?p=577240&postcount=583
  5661. tick -= 50*status->luk + 60*status->int_ + 170*status->vit;
  5662. tick = max(tick,10000); // Minimum Duration 10s.
  5663. break;
  5664. case SC_FREEZING:
  5665. tick -= 1000 * ((status->vit + status->dex) / 20);
  5666. tick = max(tick,10000); // Minimum Duration 10s.
  5667. break;
  5668. case SC_OBLIVIONCURSE: // 100% - (100 - 0.8 x INT)
  5669. sc_def = 100 - ( 100 - status->int_* 8 / 10 );
  5670. sc_def = max(sc_def, 5); // minimum of 5%
  5671. break;
  5672. case SC_BITE: // {(Base Success chance) - (Target's AGI / 4)}
  5673. rate -= status->agi*1000/4;
  5674. rate = max(rate,50000); // minimum of 50%
  5675. break;
  5676. case SC_ELECTRICSHOCKER:
  5677. if( bl->type == BL_MOB )
  5678. tick -= 1000 * (status->agi/10);
  5679. break;
  5680. case SC_CRYSTALIZE:
  5681. tick -= (1000*(status->vit/10))+(status_get_lv(bl)/50);
  5682. break;
  5683. case SC_MANDRAGORA:
  5684. sc_def = (status->vit+status->luk)/5;
  5685. break;
  5686. case SC_KYOUGAKU:
  5687. tick -= 30*status->int_;
  5688. break;
  5689. case SC_PARALYSIS:
  5690. tick -= 50 * (status->vit + status->luk); //(1000/20);
  5691. break;
  5692. default:
  5693. //Effect that cannot be reduced? Likely a buff.
  5694. if (!(rnd()%10000 < rate))
  5695. return 0;
  5696. return tick?tick:1;
  5697. }
  5698. if (sd) {
  5699. if (battle_config.pc_sc_def_rate != 100)
  5700. sc_def = sc_def*battle_config.pc_sc_def_rate/100;
  5701. if (sc_def < battle_config.pc_max_sc_def)
  5702. sc_def += (battle_config.pc_max_sc_def - sc_def)*
  5703. status->luk/battle_config.pc_luk_sc_def;
  5704. else
  5705. sc_def = battle_config.pc_max_sc_def;
  5706. if (tick_def) {
  5707. if (battle_config.pc_sc_def_rate != 100)
  5708. tick_def = tick_def*battle_config.pc_sc_def_rate/100;
  5709. }
  5710. } else {
  5711. if (battle_config.mob_sc_def_rate != 100)
  5712. sc_def = sc_def*battle_config.mob_sc_def_rate/100;
  5713. if (sc_def < battle_config.mob_max_sc_def)
  5714. sc_def += (battle_config.mob_max_sc_def - sc_def)*
  5715. status->luk/battle_config.mob_luk_sc_def;
  5716. else
  5717. sc_def = battle_config.mob_max_sc_def;
  5718. if (tick_def) {
  5719. if (battle_config.mob_sc_def_rate != 100)
  5720. tick_def = tick_def*battle_config.mob_sc_def_rate/100;
  5721. }
  5722. }
  5723. if (sc) {
  5724. if (sc->data[SC_SCRESIST])
  5725. sc_def += sc->data[SC_SCRESIST]->val1; //Status resist
  5726. else if (sc->data[SC_SIEGFRIED])
  5727. sc_def += sc->data[SC_SIEGFRIED]->val3; //Status resistance.
  5728. }
  5729. //When no tick def, reduction is the same for both.
  5730. if( !tick_def && type != SC_STONE ) //Recent tests show duration of petrify isn't reduced by MDEF. [Inkfish]
  5731. tick_def = sc_def;
  5732. //Natural resistance
  5733. if (!(flag&8)) {
  5734. rate -= rate*sc_def/100;
  5735. //Item resistance (only applies to rate%)
  5736. if(sd && SC_COMMON_MIN <= type && type <= SC_COMMON_MAX)
  5737. {
  5738. if( sd->reseff[type-SC_COMMON_MIN] > 0 )
  5739. rate -= rate*sd->reseff[type-SC_COMMON_MIN]/10000;
  5740. if( sd->sc.data[SC_COMMONSC_RESIST] )
  5741. rate -= rate*sd->sc.data[SC_COMMONSC_RESIST]->val1/100;
  5742. }
  5743. }
  5744. if (!(rnd()%10000 < rate))
  5745. return 0;
  5746. //Why would a status start with no duration? Presume it has
  5747. //duration defined elsewhere.
  5748. if (!tick) return 1;
  5749. //Rate reduction
  5750. if (flag&2)
  5751. return tick;
  5752. tick -= tick*tick_def/100;
  5753. // Changed to 5 seconds according to recent tests [Playtester]
  5754. if (type == SC_ANKLE && tick < 5000)
  5755. tick = 5000;
  5756. return tick<=0?0:tick;
  5757. }
  5758. /*==========================================
  5759. * Starts a status change.
  5760. * 'type' = type, 'val1~4' depend on the type.
  5761. * 'rate' = base success rate. 10000 = 100%
  5762. * 'tick' is base duration
  5763. * 'flag':
  5764. * &1: Cannot be avoided (it has to start)
  5765. * &2: Tick should not be reduced (by vit, luk, lv, etc)
  5766. * &4: sc_data loaded, no value has to be altered.
  5767. * &8: rate should not be reduced
  5768. *------------------------------------------*/
  5769. int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val1,int val2,int val3,int val4,int tick,int flag)
  5770. {
  5771. struct map_session_data *sd = NULL;
  5772. struct status_change* sc;
  5773. struct status_change_entry* sce;
  5774. struct status_data *status;
  5775. struct view_data *vd;
  5776. int opt_flag, calc_flag, undead_flag, val_flag = 0, tick_time = 0;
  5777. bool sc_isnew = true;
  5778. nullpo_ret(bl);
  5779. sc = status_get_sc(bl);
  5780. status = status_get_status_data(bl);
  5781. if( type <= SC_NONE || type >= SC_MAX )
  5782. {
  5783. ShowError("status_change_start: invalid status change (%d)!\n", type);
  5784. return 0;
  5785. }
  5786. if( !sc )
  5787. return 0; //Unable to receive status changes
  5788. if( status_isdead(bl) && type != SC_NOCHAT ) // SC_NOCHAT should work even on dead characters
  5789. return 0;
  5790. if( bl->type == BL_MOB)
  5791. {
  5792. struct mob_data *md = BL_CAST(BL_MOB,bl);
  5793. if(md && (md->class_ == MOBID_EMPERIUM || mob_is_battleground(md)) && type != SC_SAFETYWALL && type != SC_PNEUMA)
  5794. return 0; //Emperium/BG Monsters can't be afflicted by status changes
  5795. // if(md && mob_is_gvg(md) && status_sc2scb_flag(type)&SCB_MAXHP)
  5796. // return 0; //prevent status addinh hp to gvg mob (like bloodylust=hp*3 etc...
  5797. }
  5798. if( sc->data[SC_REFRESH] ) {
  5799. if( type >= SC_COMMON_MIN && type <= SC_COMMON_MAX) // Confirmed.
  5800. return 0; // Immune to status ailements
  5801. switch( type ) {
  5802. case SC_QUAGMIRE://Tester said it protects against this and decrease agi.
  5803. case SC_DECREASEAGI:
  5804. case SC_BURNING:
  5805. case SC_FREEZING:
  5806. //case SC_WHITEIMPRISON://Need confirm. Protected against this in the past. [Rytech]
  5807. case SC_MARSHOFABYSS:
  5808. case SC_TOXIN:
  5809. case SC_PARALYSE:
  5810. case SC_VENOMBLEED:
  5811. case SC_MAGICMUSHROOM:
  5812. case SC_DEATHHURT:
  5813. case SC_PYREXIA:
  5814. case SC_OBLIVIONCURSE:
  5815. case SC_LEECHESEND:
  5816. case SC_CRYSTALIZE: ////08/31/2011 - Class Balance Changes
  5817. case SC_DEEPSLEEP:
  5818. case SC_MANDRAGORA:
  5819. return 0;
  5820. }
  5821. }
  5822. else if( sc->data[SC_INSPIRATION] ) {
  5823. if( type >= SC_COMMON_MIN && type <= SC_COMMON_MAX )
  5824. return 0; // Immune to status ailements
  5825. switch( type ) {
  5826. case SC_DEEPSLEEP:
  5827. case SC_SATURDAYNIGHTFEVER:
  5828. case SC_PYREXIA:
  5829. case SC_DEATHHURT:
  5830. case SC_MAGICMUSHROOM:
  5831. case SC_VENOMBLEED:
  5832. case SC_TOXIN:
  5833. case SC_OBLIVIONCURSE:
  5834. case SC_LEECHESEND:
  5835. case SC__ENERVATION:
  5836. case SC__GROOMY:
  5837. case SC__LAZINESS:
  5838. case SC__UNLUCKY:
  5839. case SC__WEAKNESS:
  5840. case SC__BODYPAINT:
  5841. case SC__IGNORANCE:
  5842. return 0;
  5843. }
  5844. }
  5845. sd = BL_CAST(BL_PC, bl);
  5846. //Adjust tick according to status resistances
  5847. if( !(flag&(1|4)) )
  5848. {
  5849. tick = status_get_sc_def(bl, type, rate, tick, flag);
  5850. if( !tick ) return 0;
  5851. }
  5852. undead_flag = battle_check_undead(status->race,status->def_ele);
  5853. //Check for inmunities / sc fails
  5854. switch (type) {
  5855. case SC_ANGRIFFS_MODUS:
  5856. case SC_GOLDENE_FERSE:
  5857. if ((type==SC_GOLDENE_FERSE && sc->data[SC_ANGRIFFS_MODUS])
  5858. || (type==SC_ANGRIFFS_MODUS && sc->data[SC_GOLDENE_FERSE])
  5859. )
  5860. return 0;
  5861. case SC_STONE:
  5862. if(sc->data[SC_POWER_OF_GAIA])
  5863. return 0;
  5864. case SC_FREEZE:
  5865. //Undead are immune to Freeze/Stone
  5866. if (undead_flag && !(flag&1))
  5867. return 0;
  5868. case SC_DEEPSLEEP:
  5869. case SC_SLEEP:
  5870. case SC_STUN:
  5871. case SC_FREEZING:
  5872. case SC_CRYSTALIZE:
  5873. if (sc->opt1)
  5874. return 0; //Cannot override other opt1 status changes. [Skotlex]
  5875. if((type == SC_FREEZE || type == SC_FREEZING || type == SC_CRYSTALIZE) && sc->data[SC_WARMER])
  5876. return 0; //Immune to Frozen and Freezing status if under Warmer status. [Jobbie]
  5877. break;
  5878. //There all like berserk, do not everlap each other
  5879. case SC__BLOODYLUST:
  5880. if(!sd) return 0; //should only affect player
  5881. case SC_BERSERK:
  5882. if (((type == SC_BERSERK) && (sc->data[SC_SATURDAYNIGHTFEVER] || sc->data[SC__BLOODYLUST]))
  5883. || ((type == SC__BLOODYLUST) && (sc->data[SC_SATURDAYNIGHTFEVER] || sc->data[SC_BERSERK]))
  5884. )
  5885. return 0;
  5886. break;
  5887. case SC_BURNING:
  5888. if(sc->opt1 || sc->data[SC_FREEZING])
  5889. return 0;
  5890. break;
  5891. case SC_SIGNUMCRUCIS:
  5892. //Only affects demons and undead element (but not players)
  5893. if((!undead_flag && status->race!=RC_DEMON) || bl->type == BL_PC)
  5894. return 0;
  5895. break;
  5896. case SC_AETERNA:
  5897. if( (sc->data[SC_STONE] && sc->opt1 == OPT1_STONE) || sc->data[SC_FREEZE] )
  5898. return 0;
  5899. break;
  5900. case SC_KYRIE:
  5901. if (bl->type == BL_MOB)
  5902. return 0;
  5903. break;
  5904. case SC_OVERTHRUST:
  5905. if (sc->data[SC_MAXOVERTHRUST])
  5906. return 0; //Overthrust can't take effect if under Max Overthrust. [Skotlex]
  5907. case SC_MAXOVERTHRUST:
  5908. if( sc->option&OPTION_MADOGEAR )
  5909. return 0;//Overthrust and Overthrust Max cannot be used on Mado Gear [Ind]
  5910. break;
  5911. case SC_ADRENALINE:
  5912. if(sd && !pc_check_weapontype(sd,skill_get_weapontype(BS_ADRENALINE)))
  5913. return 0;
  5914. if (sc->data[SC_QUAGMIRE] ||
  5915. sc->data[SC_DECREASEAGI] ||
  5916. sc->option&OPTION_MADOGEAR //Adrenaline doesn't affect Mado Gear [Ind]
  5917. )
  5918. return 0;
  5919. break;
  5920. case SC_ADRENALINE2:
  5921. if(sd && !pc_check_weapontype(sd,skill_get_weapontype(BS_ADRENALINE2)))
  5922. return 0;
  5923. if (sc->data[SC_QUAGMIRE] ||
  5924. sc->data[SC_DECREASEAGI]
  5925. )
  5926. return 0;
  5927. break;
  5928. case SC_MAGNIFICAT:
  5929. if( sc->option&OPTION_MADOGEAR ) //Mado is immune to magnificat
  5930. return 0;
  5931. break;
  5932. case SC_ONEHAND:
  5933. case SC_MERC_QUICKEN:
  5934. case SC_TWOHANDQUICKEN:
  5935. if(sc->data[SC_DECREASEAGI])
  5936. return 0;
  5937. case SC_INCREASEAGI:
  5938. if(sd && pc_issit(sd)){
  5939. pc_setstand(sd);
  5940. }
  5941. case SC_CONCENTRATE:
  5942. case SC_SPEARQUICKEN:
  5943. case SC_TRUESIGHT:
  5944. case SC_WINDWALK:
  5945. case SC_CARTBOOST:
  5946. case SC_ASSNCROS:
  5947. if (sc->data[SC_QUAGMIRE])
  5948. return 0;
  5949. if(sc->option&OPTION_MADOGEAR)
  5950. return 0;//Mado is immune to increase agi, wind walk, cart boost, etc (others above) [Ind]
  5951. break;
  5952. case SC_CLOAKING:
  5953. //Avoid cloaking with no wall and low skill level. [Skotlex]
  5954. //Due to the cloaking card, we have to check the wall versus to known
  5955. //skill level rather than the used one. [Skotlex]
  5956. //if (sd && val1 < 3 && skill_check_cloaking(bl,NULL))
  5957. if( sd && pc_checkskill(sd, AS_CLOAKING) < 3 && !skill_check_cloaking(bl,NULL) )
  5958. return 0;
  5959. break;
  5960. case SC_MODECHANGE:
  5961. {
  5962. int mode;
  5963. struct status_data *bstatus = status_get_base_status(bl);
  5964. if (!bstatus) return 0;
  5965. if (sc->data[type])
  5966. { //Pile up with previous values.
  5967. if(!val2) val2 = sc->data[type]->val2;
  5968. val3 |= sc->data[type]->val3;
  5969. val4 |= sc->data[type]->val4;
  5970. }
  5971. mode = val2?val2:bstatus->mode; //Base mode
  5972. if (val4) mode&=~val4; //Del mode
  5973. if (val3) mode|= val3; //Add mode
  5974. if (mode == bstatus->mode) { //No change.
  5975. if (sc->data[type]) //Abort previous status
  5976. return status_change_end(bl, type, INVALID_TIMER);
  5977. return 0;
  5978. }
  5979. }
  5980. break;
  5981. //Strip skills, need to divest something or it fails.
  5982. case SC_STRIPWEAPON:
  5983. if (sd && !(flag&4)) { //apply sc anyway if loading saved sc_data
  5984. int i;
  5985. opt_flag = 0; //Reuse to check success condition.
  5986. if(sd->bonus.unstripable_equip&EQP_WEAPON)
  5987. return 0;
  5988. i = sd->equip_index[EQI_HAND_L];
  5989. if (i>=0 && sd->inventory_data[i] && sd->inventory_data[i]->type == IT_WEAPON) {
  5990. opt_flag|=1;
  5991. pc_unequipitem(sd,i,3); //L-hand weapon
  5992. }
  5993. i = sd->equip_index[EQI_HAND_R];
  5994. if (i>=0 && sd->inventory_data[i] && sd->inventory_data[i]->type == IT_WEAPON) {
  5995. opt_flag|=2;
  5996. pc_unequipitem(sd,i,3);
  5997. }
  5998. if (!opt_flag) return 0;
  5999. }
  6000. if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
  6001. break;
  6002. case SC_STRIPSHIELD:
  6003. if( val2 == 1 ) val2 = 0; //GX effect. Do not take shield off..
  6004. else
  6005. if (sd && !(flag&4)) {
  6006. int i;
  6007. if(sd->bonus.unstripable_equip&EQP_SHIELD)
  6008. return 0;
  6009. i = sd->equip_index[EQI_HAND_L];
  6010. if ( i < 0 || !sd->inventory_data[i] || sd->inventory_data[i]->type != IT_ARMOR )
  6011. return 0;
  6012. pc_unequipitem(sd,i,3);
  6013. }
  6014. if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
  6015. break;
  6016. case SC_STRIPARMOR:
  6017. if (sd && !(flag&4)) {
  6018. int i;
  6019. if(sd->bonus.unstripable_equip&EQP_ARMOR)
  6020. return 0;
  6021. i = sd->equip_index[EQI_ARMOR];
  6022. if ( i < 0 || !sd->inventory_data[i] )
  6023. return 0;
  6024. pc_unequipitem(sd,i,3);
  6025. }
  6026. if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
  6027. break;
  6028. case SC_STRIPHELM:
  6029. if (sd && !(flag&4)) {
  6030. int i;
  6031. if(sd->bonus.unstripable_equip&EQP_HELM)
  6032. return 0;
  6033. i = sd->equip_index[EQI_HEAD_TOP];
  6034. if ( i < 0 || !sd->inventory_data[i] )
  6035. return 0;
  6036. pc_unequipitem(sd,i,3);
  6037. }
  6038. if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
  6039. break;
  6040. case SC_MERC_FLEEUP:
  6041. case SC_MERC_ATKUP:
  6042. case SC_MERC_HPUP:
  6043. case SC_MERC_SPUP:
  6044. case SC_MERC_HITUP:
  6045. if( bl->type != BL_MER )
  6046. return 0; // Stats only for Mercenaries
  6047. break;
  6048. case SC_STRFOOD:
  6049. if (sc->data[SC_FOOD_STR_CASH] && sc->data[SC_FOOD_STR_CASH]->val1 > val1)
  6050. return 0;
  6051. break;
  6052. case SC_AGIFOOD:
  6053. if (sc->data[SC_FOOD_AGI_CASH] && sc->data[SC_FOOD_AGI_CASH]->val1 > val1)
  6054. return 0;
  6055. break;
  6056. case SC_VITFOOD:
  6057. if (sc->data[SC_FOOD_VIT_CASH] && sc->data[SC_FOOD_VIT_CASH]->val1 > val1)
  6058. return 0;
  6059. break;
  6060. case SC_INTFOOD:
  6061. if (sc->data[SC_FOOD_INT_CASH] && sc->data[SC_FOOD_INT_CASH]->val1 > val1)
  6062. return 0;
  6063. break;
  6064. case SC_DEXFOOD:
  6065. if (sc->data[SC_FOOD_DEX_CASH] && sc->data[SC_FOOD_DEX_CASH]->val1 > val1)
  6066. return 0;
  6067. break;
  6068. case SC_LUKFOOD:
  6069. if (sc->data[SC_FOOD_LUK_CASH] && sc->data[SC_FOOD_LUK_CASH]->val1 > val1)
  6070. return 0;
  6071. break;
  6072. case SC_FOOD_STR_CASH:
  6073. if (sc->data[SC_STRFOOD] && sc->data[SC_STRFOOD]->val1 > val1)
  6074. return 0;
  6075. break;
  6076. case SC_FOOD_AGI_CASH:
  6077. if (sc->data[SC_AGIFOOD] && sc->data[SC_AGIFOOD]->val1 > val1)
  6078. return 0;
  6079. break;
  6080. case SC_FOOD_VIT_CASH:
  6081. if (sc->data[SC_VITFOOD] && sc->data[SC_VITFOOD]->val1 > val1)
  6082. return 0;
  6083. break;
  6084. case SC_FOOD_INT_CASH:
  6085. if (sc->data[SC_INTFOOD] && sc->data[SC_INTFOOD]->val1 > val1)
  6086. return 0;
  6087. break;
  6088. case SC_FOOD_DEX_CASH:
  6089. if (sc->data[SC_DEXFOOD] && sc->data[SC_DEXFOOD]->val1 > val1)
  6090. return 0;
  6091. break;
  6092. case SC_FOOD_LUK_CASH:
  6093. if (sc->data[SC_LUKFOOD] && sc->data[SC_LUKFOOD]->val1 > val1)
  6094. return 0;
  6095. break;
  6096. case SC_CAMOUFLAGE:
  6097. if( sd && pc_checkskill(sd, RA_CAMOUFLAGE) < 3 && !skill_check_camouflage(bl,NULL) )
  6098. return 0;
  6099. break;
  6100. case SC__STRIPACCESSORY:
  6101. if( sd ) {
  6102. int i = -1;
  6103. if( !(sd->bonus.unstripable_equip&EQI_ACC_L) ) {
  6104. i = sd->equip_index[EQI_ACC_L];
  6105. if( i >= 0 && sd->inventory_data[i] && sd->inventory_data[i]->type == IT_ARMOR )
  6106. pc_unequipitem(sd,i,3); //L-Accessory
  6107. } if( !(sd->bonus.unstripable_equip&EQI_ACC_R) ) {
  6108. i = sd->equip_index[EQI_ACC_R];
  6109. if( i >= 0 && sd->inventory_data[i] && sd->inventory_data[i]->type == IT_ARMOR )
  6110. pc_unequipitem(sd,i,3); //R-Accessory
  6111. }
  6112. if( i < 0 )
  6113. return 0;
  6114. }
  6115. if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
  6116. break;
  6117. case SC_TOXIN:
  6118. case SC_PARALYSE:
  6119. case SC_VENOMBLEED:
  6120. case SC_MAGICMUSHROOM:
  6121. case SC_DEATHHURT:
  6122. case SC_PYREXIA:
  6123. case SC_OBLIVIONCURSE:
  6124. case SC_LEECHESEND:
  6125. { // it doesn't stack or even renewed
  6126. int i = SC_TOXIN;
  6127. for(; i<= SC_LEECHESEND; i++)
  6128. if(sc->data[i]) return 0;
  6129. }
  6130. break;
  6131. case SC_SATURDAYNIGHTFEVER:
  6132. if (sc->data[SC_BERSERK] || sc->data[SC_INSPIRATION] || sc->data[SC__BLOODYLUST])
  6133. return 0;
  6134. break;
  6135. }
  6136. //Check for BOSS resistances
  6137. if(status->mode&MD_BOSS && !(flag&1)) {
  6138. if (type>=SC_COMMON_MIN && type <= SC_COMMON_MAX)
  6139. return 0;
  6140. switch (type) {
  6141. case SC_BLESSING:
  6142. case SC_DECREASEAGI:
  6143. case SC_PROVOKE:
  6144. case SC_COMA:
  6145. case SC_GRAVITATION:
  6146. case SC_SUITON:
  6147. case SC_RICHMANKIM:
  6148. case SC_ROKISWEIL:
  6149. case SC_FOGWALL:
  6150. case SC_FREEZING:
  6151. case SC_BURNING:
  6152. case SC_MARSHOFABYSS:
  6153. case SC_ADORAMUS:
  6154. case SC_PARALYSIS:
  6155. case SC_DEEPSLEEP:
  6156. case SC_CRYSTALIZE:
  6157. // Exploit prevention - kRO Fix
  6158. case SC_PYREXIA:
  6159. case SC_DEATHHURT:
  6160. case SC_TOXIN:
  6161. case SC_PARALYSE:
  6162. case SC_VENOMBLEED:
  6163. case SC_MAGICMUSHROOM:
  6164. case SC_OBLIVIONCURSE:
  6165. case SC_LEECHESEND:
  6166. // Ranger Effects
  6167. case SC_BITE:
  6168. case SC_ELECTRICSHOCKER:
  6169. case SC_MAGNETICFIELD:
  6170. return 0;
  6171. }
  6172. }
  6173. //Before overlapping fail, one must check for status cured.
  6174. switch (type) {
  6175. case SC_BLESSING:
  6176. //TO-DO Blessing and Agi up should do 1 damage against players on Undead Status, even on PvM
  6177. //but cannot be plagiarized (this requires aegis investigation on packets and official behavior) [Brainstorm]
  6178. if ((!undead_flag && status->race!=RC_DEMON) || bl->type == BL_PC) {
  6179. status_change_end(bl, SC_CURSE, INVALID_TIMER);
  6180. if (sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
  6181. status_change_end(bl, SC_STONE, INVALID_TIMER);
  6182. }
  6183. break;
  6184. case SC_INCREASEAGI:
  6185. status_change_end(bl, SC_DECREASEAGI, INVALID_TIMER);
  6186. break;
  6187. case SC_QUAGMIRE:
  6188. status_change_end(bl, SC_CONCENTRATE, INVALID_TIMER);
  6189. status_change_end(bl, SC_TRUESIGHT, INVALID_TIMER);
  6190. status_change_end(bl, SC_WINDWALK, INVALID_TIMER);
  6191. //Also blocks the ones below...
  6192. case SC_DECREASEAGI:
  6193. status_change_end(bl, SC_CARTBOOST, INVALID_TIMER);
  6194. //Also blocks the ones below...
  6195. case SC_DONTFORGETME:
  6196. status_change_end(bl, SC_INCREASEAGI, INVALID_TIMER);
  6197. status_change_end(bl, SC_ADRENALINE, INVALID_TIMER);
  6198. status_change_end(bl, SC_ADRENALINE2, INVALID_TIMER);
  6199. status_change_end(bl, SC_SPEARQUICKEN, INVALID_TIMER);
  6200. status_change_end(bl, SC_TWOHANDQUICKEN, INVALID_TIMER);
  6201. status_change_end(bl, SC_ONEHAND, INVALID_TIMER);
  6202. status_change_end(bl, SC_MERC_QUICKEN, INVALID_TIMER);
  6203. status_change_end(bl, SC_ACCELERATION, INVALID_TIMER);
  6204. break;
  6205. case SC_ONEHAND:
  6206. //Removes the Aspd potion effect, as reported by Vicious. [Skotlex]
  6207. status_change_end(bl, SC_ASPDPOTION0, INVALID_TIMER);
  6208. status_change_end(bl, SC_ASPDPOTION1, INVALID_TIMER);
  6209. status_change_end(bl, SC_ASPDPOTION2, INVALID_TIMER);
  6210. status_change_end(bl, SC_ASPDPOTION3, INVALID_TIMER);
  6211. break;
  6212. case SC_MAXOVERTHRUST:
  6213. //Cancels Normal Overthrust. [Skotlex]
  6214. status_change_end(bl, SC_OVERTHRUST, INVALID_TIMER);
  6215. break;
  6216. case SC_KYRIE:
  6217. //Cancels Assumptio
  6218. status_change_end(bl, SC_ASSUMPTIO, INVALID_TIMER);
  6219. break;
  6220. case SC_DELUGE:
  6221. if (sc->data[SC_FOGWALL] && sc->data[SC_BLIND])
  6222. status_change_end(bl, SC_BLIND, INVALID_TIMER);
  6223. break;
  6224. case SC_SILENCE:
  6225. if (sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_SELF)
  6226. status_change_end(bl, SC_GOSPEL, INVALID_TIMER);
  6227. break;
  6228. case SC_HIDING:
  6229. status_change_end(bl, SC_CLOSECONFINE, INVALID_TIMER);
  6230. status_change_end(bl, SC_CLOSECONFINE2, INVALID_TIMER);
  6231. break;
  6232. case SC__BLOODYLUST:
  6233. case SC_BERSERK:
  6234. if(battle_config.berserk_cancels_buffs) {
  6235. status_change_end(bl, SC_ONEHAND, INVALID_TIMER);
  6236. status_change_end(bl, SC_TWOHANDQUICKEN, INVALID_TIMER);
  6237. status_change_end(bl, SC_CONCENTRATION, INVALID_TIMER);
  6238. status_change_end(bl, SC_PARRYING, INVALID_TIMER);
  6239. status_change_end(bl, SC_AURABLADE, INVALID_TIMER);
  6240. status_change_end(bl, SC_MERC_QUICKEN, INVALID_TIMER);
  6241. }
  6242. #ifdef RENEWAL
  6243. else {
  6244. status_change_end(bl, SC_TWOHANDQUICKEN, INVALID_TIMER);
  6245. }
  6246. #endif
  6247. break;
  6248. case SC_ASSUMPTIO:
  6249. status_change_end(bl, SC_KYRIE, INVALID_TIMER);
  6250. status_change_end(bl, SC_KAITE, INVALID_TIMER);
  6251. break;
  6252. case SC_KAITE:
  6253. status_change_end(bl, SC_ASSUMPTIO, INVALID_TIMER);
  6254. break;
  6255. case SC_CARTBOOST:
  6256. if(sc->data[SC_DECREASEAGI])
  6257. { //Cancel Decrease Agi, but take no further effect [Skotlex]
  6258. status_change_end(bl, SC_DECREASEAGI, INVALID_TIMER);
  6259. return 0;
  6260. }
  6261. break;
  6262. case SC_FUSION:
  6263. status_change_end(bl, SC_SPIRIT, INVALID_TIMER);
  6264. break;
  6265. case SC_ADJUSTMENT:
  6266. status_change_end(bl, SC_MADNESSCANCEL, INVALID_TIMER);
  6267. break;
  6268. case SC_MADNESSCANCEL:
  6269. status_change_end(bl, SC_ADJUSTMENT, INVALID_TIMER);
  6270. break;
  6271. //NPC_CHANGEUNDEAD will debuff Blessing and Agi Up
  6272. case SC_CHANGEUNDEAD:
  6273. status_change_end(bl, SC_BLESSING, INVALID_TIMER);
  6274. status_change_end(bl, SC_INCREASEAGI, INVALID_TIMER);
  6275. break;
  6276. case SC_STRFOOD:
  6277. status_change_end(bl, SC_FOOD_STR_CASH, INVALID_TIMER);
  6278. break;
  6279. case SC_AGIFOOD:
  6280. status_change_end(bl, SC_FOOD_AGI_CASH, INVALID_TIMER);
  6281. break;
  6282. case SC_VITFOOD:
  6283. status_change_end(bl, SC_FOOD_VIT_CASH, INVALID_TIMER);
  6284. break;
  6285. case SC_INTFOOD:
  6286. status_change_end(bl, SC_FOOD_INT_CASH, INVALID_TIMER);
  6287. break;
  6288. case SC_DEXFOOD:
  6289. status_change_end(bl, SC_FOOD_DEX_CASH, INVALID_TIMER);
  6290. break;
  6291. case SC_LUKFOOD:
  6292. status_change_end(bl, SC_FOOD_LUK_CASH, INVALID_TIMER);
  6293. break;
  6294. case SC_FOOD_STR_CASH:
  6295. status_change_end(bl, SC_STRFOOD, INVALID_TIMER);
  6296. break;
  6297. case SC_FOOD_AGI_CASH:
  6298. status_change_end(bl, SC_AGIFOOD, INVALID_TIMER);
  6299. break;
  6300. case SC_FOOD_VIT_CASH:
  6301. status_change_end(bl, SC_VITFOOD, INVALID_TIMER);
  6302. break;
  6303. case SC_FOOD_INT_CASH:
  6304. status_change_end(bl, SC_INTFOOD, INVALID_TIMER);
  6305. break;
  6306. case SC_FOOD_DEX_CASH:
  6307. status_change_end(bl, SC_DEXFOOD, INVALID_TIMER);
  6308. break;
  6309. case SC_FOOD_LUK_CASH:
  6310. status_change_end(bl, SC_LUKFOOD, INVALID_TIMER);
  6311. break;
  6312. case SC_FIGHTINGSPIRIT:
  6313. status_change_end(bl, type, INVALID_TIMER); // Remove previous one.
  6314. break;
  6315. case SC_MARSHOFABYSS:
  6316. status_change_end(bl, SC_INCAGI, INVALID_TIMER);
  6317. status_change_end(bl, SC_WINDWALK, INVALID_TIMER);
  6318. status_change_end(bl, SC_ASPDPOTION0, INVALID_TIMER);
  6319. status_change_end(bl, SC_ASPDPOTION1, INVALID_TIMER);
  6320. status_change_end(bl, SC_ASPDPOTION2, INVALID_TIMER);
  6321. status_change_end(bl, SC_ASPDPOTION3, INVALID_TIMER);
  6322. break;
  6323. case SC_SWINGDANCE:
  6324. case SC_SYMPHONYOFLOVER:
  6325. case SC_MOONLITSERENADE:
  6326. case SC_RUSHWINDMILL:
  6327. case SC_ECHOSONG:
  6328. case SC_HARMONIZE: //group A doesn't overlap
  6329. if (type != SC_SWINGDANCE) status_change_end(bl, SC_SWINGDANCE, INVALID_TIMER);
  6330. if (type != SC_SYMPHONYOFLOVER) status_change_end(bl, SC_SYMPHONYOFLOVER, INVALID_TIMER);
  6331. if (type != SC_MOONLITSERENADE) status_change_end(bl, SC_MOONLITSERENADE, INVALID_TIMER);
  6332. if (type != SC_RUSHWINDMILL) status_change_end(bl, SC_RUSHWINDMILL, INVALID_TIMER);
  6333. if (type != SC_ECHOSONG) status_change_end(bl, SC_ECHOSONG, INVALID_TIMER);
  6334. if (type != SC_HARMONIZE) status_change_end(bl, SC_HARMONIZE, INVALID_TIMER);
  6335. break;
  6336. case SC_VOICEOFSIREN:
  6337. case SC_DEEPSLEEP:
  6338. case SC_GLOOMYDAY:
  6339. case SC_SONGOFMANA:
  6340. case SC_DANCEWITHWUG:
  6341. case SC_SATURDAYNIGHTFEVER:
  6342. case SC_LERADSDEW:
  6343. case SC_MELODYOFSINK:
  6344. case SC_BEYONDOFWARCRY:
  6345. case SC_UNLIMITEDHUMMINGVOICE: //group B
  6346. if (type != SC_VOICEOFSIREN) status_change_end(bl, SC_VOICEOFSIREN, INVALID_TIMER);
  6347. if (type != SC_DEEPSLEEP) status_change_end(bl, SC_DEEPSLEEP, INVALID_TIMER);
  6348. if (type != SC_LERADSDEW) status_change_end(bl, SC_LERADSDEW, INVALID_TIMER);
  6349. if (type != SC_MELODYOFSINK) status_change_end(bl, SC_MELODYOFSINK, INVALID_TIMER);
  6350. if (type != SC_BEYONDOFWARCRY) status_change_end(bl, SC_BEYONDOFWARCRY, INVALID_TIMER);
  6351. if (type != SC_UNLIMITEDHUMMINGVOICE) status_change_end(bl, SC_UNLIMITEDHUMMINGVOICE, INVALID_TIMER);
  6352. if (type != SC_GLOOMYDAY) {
  6353. status_change_end(bl, SC_GLOOMYDAY, INVALID_TIMER);
  6354. status_change_end(bl, SC_GLOOMYDAY_SK, INVALID_TIMER);
  6355. }
  6356. if (type != SC_SONGOFMANA) status_change_end(bl, SC_SONGOFMANA, INVALID_TIMER);
  6357. if (type != SC_DANCEWITHWUG) status_change_end(bl, SC_DANCEWITHWUG, INVALID_TIMER);
  6358. if (type != SC_SATURDAYNIGHTFEVER) {
  6359. if (sc->data[SC_SATURDAYNIGHTFEVER]) {
  6360. sc->data[SC_SATURDAYNIGHTFEVER]->val2 = 0; //mark to not lose hp
  6361. status_change_end(bl, SC_SATURDAYNIGHTFEVER, INVALID_TIMER);
  6362. }
  6363. }
  6364. break;
  6365. case SC_REFLECTSHIELD:
  6366. status_change_end(bl, SC_REFLECTDAMAGE, INVALID_TIMER);
  6367. break;
  6368. case SC_REFLECTDAMAGE:
  6369. status_change_end(bl, SC_REFLECTSHIELD, INVALID_TIMER);
  6370. break;
  6371. case SC_SHIELDSPELL_DEF:
  6372. case SC_SHIELDSPELL_MDEF:
  6373. case SC_SHIELDSPELL_REF:
  6374. status_change_end(bl, SC_MAGNIFICAT, INVALID_TIMER);
  6375. if( type != SC_SHIELDSPELL_DEF )
  6376. status_change_end(bl, SC_SHIELDSPELL_DEF, INVALID_TIMER);
  6377. if( type != SC_SHIELDSPELL_MDEF )
  6378. status_change_end(bl, SC_SHIELDSPELL_MDEF, INVALID_TIMER);
  6379. if( type != SC_SHIELDSPELL_REF )
  6380. status_change_end(bl, SC_SHIELDSPELL_REF, INVALID_TIMER);
  6381. break;
  6382. case SC_GT_ENERGYGAIN:
  6383. case SC_GT_CHANGE:
  6384. case SC_GT_REVITALIZE:
  6385. if( type != SC_GT_REVITALIZE )
  6386. status_change_end(bl, SC_GT_REVITALIZE, INVALID_TIMER);
  6387. if( type != SC_GT_ENERGYGAIN )
  6388. status_change_end(bl, SC_GT_ENERGYGAIN, INVALID_TIMER);
  6389. if( type != SC_GT_CHANGE )
  6390. status_change_end(bl, SC_GT_CHANGE, INVALID_TIMER);
  6391. break;
  6392. case SC_INVINCIBLE:
  6393. status_change_end(bl, SC_INVINCIBLEOFF, INVALID_TIMER);
  6394. break;
  6395. case SC_INVINCIBLEOFF:
  6396. status_change_end(bl, SC_INVINCIBLE, INVALID_TIMER);
  6397. break;
  6398. case SC_MAGICPOWER:
  6399. status_change_end(bl, type, INVALID_TIMER);
  6400. break;
  6401. }
  6402. //Check for overlapping fails
  6403. if( (sce = sc->data[type]) ) {
  6404. switch( type ) {
  6405. case SC_MERC_FLEEUP:
  6406. case SC_MERC_ATKUP:
  6407. case SC_MERC_HPUP:
  6408. case SC_MERC_SPUP:
  6409. case SC_MERC_HITUP:
  6410. if( sce->val1 > val1 )
  6411. val1 = sce->val1;
  6412. break;
  6413. case SC_ADRENALINE:
  6414. case SC_ADRENALINE2:
  6415. case SC_WEAPONPERFECTION:
  6416. case SC_OVERTHRUST:
  6417. if (sce->val2 > val2)
  6418. return 0;
  6419. break;
  6420. case SC_S_LIFEPOTION:
  6421. case SC_L_LIFEPOTION:
  6422. case SC_BOSSMAPINFO:
  6423. case SC_STUN:
  6424. case SC_SLEEP:
  6425. case SC_POISON:
  6426. case SC_CURSE:
  6427. case SC_SILENCE:
  6428. case SC_CONFUSION:
  6429. case SC_BLIND:
  6430. case SC_BLEEDING:
  6431. case SC_DPOISON:
  6432. case SC_CLOSECONFINE2: //Can't be re-closed in.
  6433. case SC_MARIONETTE:
  6434. case SC_MARIONETTE2:
  6435. case SC_NOCHAT:
  6436. case SC_CHANGE: //Otherwise your Hp/Sp would get refilled while still within effect of the last invocation.
  6437. case SC__INVISIBILITY:
  6438. case SC__ENERVATION:
  6439. case SC__GROOMY:
  6440. case SC__IGNORANCE:
  6441. case SC__LAZINESS:
  6442. case SC__WEAKNESS:
  6443. case SC__UNLUCKY:
  6444. return 0;
  6445. case SC_COMBO:
  6446. case SC_DANCING:
  6447. case SC_DEVOTION:
  6448. case SC_ASPDPOTION0:
  6449. case SC_ASPDPOTION1:
  6450. case SC_ASPDPOTION2:
  6451. case SC_ASPDPOTION3:
  6452. case SC_ATKPOTION:
  6453. case SC_MATKPOTION:
  6454. case SC_ENCHANTARMS:
  6455. case SC_ARMOR_ELEMENT:
  6456. case SC_ARMOR_RESIST:
  6457. break;
  6458. case SC_GOSPEL:
  6459. //Must not override a casting gospel char.
  6460. if(sce->val4 == BCT_SELF)
  6461. return 0;
  6462. if(sce->val1 > val1)
  6463. return 1;
  6464. break;
  6465. case SC_ENDURE:
  6466. if(sce->val4 && !val4)
  6467. return 1; //Don't let you override infinite endure.
  6468. if(sce->val1 > val1)
  6469. return 1;
  6470. break;
  6471. case SC_KAAHI:
  6472. //Kaahi overwrites previous level regardless of existing level.
  6473. //Delete timer if it exists.
  6474. if (sce->val4 != INVALID_TIMER) {
  6475. delete_timer(sce->val4,kaahi_heal_timer);
  6476. sce->val4 = INVALID_TIMER;
  6477. }
  6478. break;
  6479. case SC_JAILED:
  6480. //When a player is already jailed, do not edit the jail data.
  6481. val2 = sce->val2;
  6482. val3 = sce->val3;
  6483. val4 = sce->val4;
  6484. break;
  6485. case SC_LERADSDEW:
  6486. if (sc && (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST]))
  6487. return 0;
  6488. case SC_SHAPESHIFT:
  6489. case SC_PROPERTYWALK:
  6490. break;
  6491. case SC_LEADERSHIP:
  6492. case SC_GLORYWOUNDS:
  6493. case SC_SOULCOLD:
  6494. case SC_HAWKEYES:
  6495. if( sce->val4 && !val4 )//you cannot override master guild aura
  6496. return 0;
  6497. break;
  6498. case SC_JOINTBEAT:
  6499. val2 |= sce->val2; // stackable ailments
  6500. default:
  6501. if(sce->val1 > val1)
  6502. return 1; //Return true to not mess up skill animations. [Skotlex]
  6503. }
  6504. }
  6505. vd = status_get_viewdata(bl);
  6506. calc_flag = StatusChangeFlagTable[type];
  6507. if(!(flag&4)) //&4 - Do not parse val settings when loading SCs
  6508. switch(type)
  6509. {
  6510. case SC_DECREASEAGI:
  6511. case SC_INCREASEAGI:
  6512. val2 = 2 + val1; //Agi change
  6513. break;
  6514. case SC_ENDURE:
  6515. val2 = 7; // Hit-count [Celest]
  6516. if( !(flag&1) && (bl->type&(BL_PC|BL_MER)) && !map_flag_gvg(bl->m) && !map[bl->m].flag.battleground && !val4 )
  6517. {
  6518. struct map_session_data *tsd;
  6519. if( sd )
  6520. {
  6521. int i;
  6522. for( i = 0; i < 5; i++ )
  6523. {
  6524. if( sd->devotion[i] && (tsd = map_id2sd(sd->devotion[i])) )
  6525. status_change_start(&tsd->bl, type, 10000, val1, val2, val3, val4, tick, 1);
  6526. }
  6527. }
  6528. else if( bl->type == BL_MER && ((TBL_MER*)bl)->devotion_flag && (tsd = ((TBL_MER*)bl)->master) )
  6529. status_change_start(&tsd->bl, type, 10000, val1, val2, val3, val4, tick, 1);
  6530. }
  6531. //val4 signals infinite endure (if val4 == 2 it is infinite endure from Berserk)
  6532. if( val4 )
  6533. tick = -1;
  6534. break;
  6535. case SC_AUTOBERSERK:
  6536. if (status->hp < status->max_hp>>2 &&
  6537. (!sc->data[SC_PROVOKE] || sc->data[SC_PROVOKE]->val2==0))
  6538. sc_start4(bl,SC_PROVOKE,100,10,1,0,0,60000);
  6539. tick = -1;
  6540. break;
  6541. case SC_SIGNUMCRUCIS:
  6542. val2 = 10 + 4*val1; //Def reduction
  6543. tick = -1;
  6544. clif_emotion(bl,E_SWT);
  6545. break;
  6546. case SC_MAXIMIZEPOWER:
  6547. tick_time = val2 = tick>0?tick:60000;
  6548. tick = -1; // duration sent to the client should be infinite
  6549. break;
  6550. case SC_EDP: // [Celest]
  6551. val2 = val1 + 2; //Chance to Poison enemies.
  6552. #ifndef RENEWAL_EDP
  6553. val3 = 50*(val1+1); //Damage increase (+50 +50*lv%)
  6554. #endif
  6555. if( sd )//[Ind] - iROwiki says each level increases its duration by 3 seconds
  6556. tick += pc_checkskill(sd,GC_RESEARCHNEWPOISON)*3000;
  6557. break;
  6558. case SC_POISONREACT:
  6559. val2=(val1+1)/2 + val1/10; // Number of counters [Skotlex]
  6560. val3=50; // + 5*val1; //Chance to counter. [Skotlex]
  6561. break;
  6562. case SC_MAGICROD:
  6563. val2 = val1*20; //SP gained
  6564. break;
  6565. case SC_KYRIE:
  6566. val2 = (int64)status->max_hp * (val1 * 2 + 10) / 100; //%Max HP to absorb
  6567. val3 = (val1 / 2 + 5); //Hits
  6568. break;
  6569. case SC_MAGICPOWER:
  6570. //val1: Skill lv
  6571. val2 = 1; //Lasts 1 invocation
  6572. val3 = 5*val1; //Matk% increase
  6573. val4 = 0; // 0 = ready to be used, 1 = activated and running
  6574. break;
  6575. case SC_SACRIFICE:
  6576. val2 = 5; //Lasts 5 hits
  6577. tick = -1;
  6578. break;
  6579. case SC_ENCPOISON:
  6580. val2= 250+50*val1; //Poisoning Chance (2.5+0.5%) in 1/10000 rate
  6581. case SC_ASPERSIO:
  6582. case SC_FIREWEAPON:
  6583. case SC_WATERWEAPON:
  6584. case SC_WINDWEAPON:
  6585. case SC_EARTHWEAPON:
  6586. case SC_SHADOWWEAPON:
  6587. case SC_GHOSTWEAPON:
  6588. skill_enchant_elemental_end(bl,type);
  6589. break;
  6590. case SC_ELEMENTALCHANGE:
  6591. // val1 : Element Lvl (if called by skill lvl 1, takes random value between 1 and 4)
  6592. // val2 : Element (When no element, random one is picked)
  6593. // val3 : 0 = called by skill 1 = called by script (fixed level)
  6594. if( !val2 ) val2 = rnd()%ELE_MAX;
  6595. if( val1 == 1 && val3 == 0 )
  6596. val1 = 1 + rnd()%4;
  6597. else if( val1 > 4 )
  6598. val1 = 4; // Max Level
  6599. val3 = 0; // Not need to keep this info.
  6600. break;
  6601. case SC_PROVIDENCE:
  6602. val2=val1*5; //Race/Ele resist
  6603. break;
  6604. case SC_REFLECTSHIELD:
  6605. val2=10+val1*3; // %Dmg reflected
  6606. if( !(flag&1) && (bl->type&(BL_PC|BL_MER)) )
  6607. {
  6608. struct map_session_data *tsd;
  6609. if( sd )
  6610. {
  6611. int i;
  6612. for( i = 0; i < 5; i++ )
  6613. {
  6614. if( sd->devotion[i] && (tsd = map_id2sd(sd->devotion[i])) )
  6615. status_change_start(&tsd->bl, type, 10000, val1, val2, 0, 0, tick, 1);
  6616. }
  6617. }
  6618. else if( bl->type == BL_MER && ((TBL_MER*)bl)->devotion_flag && (tsd = ((TBL_MER*)bl)->master) )
  6619. status_change_start(&tsd->bl, type, 10000, val1, val2, 0, 0, tick, 1);
  6620. }
  6621. break;
  6622. case SC_STRIPWEAPON:
  6623. if (!sd) //Watk reduction
  6624. val2 = 25;
  6625. break;
  6626. case SC_STRIPSHIELD:
  6627. if (!sd) //Def reduction
  6628. val2 = 15;
  6629. break;
  6630. case SC_STRIPARMOR:
  6631. if (!sd) //Vit reduction
  6632. val2 = 40;
  6633. break;
  6634. case SC_STRIPHELM:
  6635. if (!sd) //Int reduction
  6636. val2 = 40;
  6637. break;
  6638. case SC_AUTOSPELL:
  6639. //Val1 Skill LV of Autospell
  6640. //Val2 Skill ID to cast
  6641. //Val3 Max Lv to cast
  6642. val4 = 5 + val1*2; //Chance of casting
  6643. break;
  6644. case SC_VOLCANO:
  6645. val2 = val1*10; //Watk increase
  6646. #ifndef RENEWAL
  6647. if (status->def_ele != ELE_FIRE)
  6648. val2 = 0;
  6649. #endif
  6650. break;
  6651. case SC_VIOLENTGALE:
  6652. val2 = val1*3; //Flee increase
  6653. #ifndef RENEWAL
  6654. if (status->def_ele != ELE_WIND)
  6655. val2 = 0;
  6656. #endif
  6657. break;
  6658. case SC_DELUGE:
  6659. val2 = deluge_eff[val1-1]; //HP increase
  6660. #ifndef RENEWAL
  6661. if(status->def_ele != ELE_WATER)
  6662. val2 = 0;
  6663. #endif
  6664. break;
  6665. case SC_SUITON:
  6666. if (!val2 || (sd && (sd->class_&MAPID_UPPERMASK) == MAPID_NINJA)) {
  6667. //No penalties.
  6668. val2 = 0; //Agi penalty
  6669. val3 = 0; //Walk speed penalty
  6670. break;
  6671. }
  6672. val3 = 50;
  6673. val2 = 3*((val1+1)/3);
  6674. if (val1 > 4) val2--;
  6675. break;
  6676. case SC_ONEHAND:
  6677. case SC_TWOHANDQUICKEN:
  6678. val2 = 300;
  6679. if (val1 > 10) //For boss casted skills [Skotlex]
  6680. val2 += 20*(val1-10);
  6681. break;
  6682. case SC_MERC_QUICKEN:
  6683. val2 = 300;
  6684. break;
  6685. #ifndef RENEWAL
  6686. case SC_SPEARQUICKEN:
  6687. val2 = 200+10*val1;
  6688. break;
  6689. #endif
  6690. case SC_DANCING:
  6691. //val1 : Skill ID + LV
  6692. //val2 : Skill Group of the Dance.
  6693. //val3 : Brings the skill_lv (merged into val1 here)
  6694. //val4 : Partner
  6695. if (val1 == CG_MOONLIT)
  6696. clif_status_change(bl,SI_MOONLIT,1,tick,0, 0, 0);
  6697. val1|= (val3<<16);
  6698. val3 = tick/1000; //Tick duration
  6699. tick_time = 1000; // [GodLesZ] tick time
  6700. break;
  6701. case SC_LONGING:
  6702. val2 = 500-100*val1; //Aspd penalty.
  6703. break;
  6704. case SC_EXPLOSIONSPIRITS:
  6705. val2 = 75 + 25*val1; //Cri bonus
  6706. break;
  6707. case SC_ASPDPOTION0:
  6708. case SC_ASPDPOTION1:
  6709. case SC_ASPDPOTION2:
  6710. case SC_ASPDPOTION3:
  6711. val2 = 50*(2+type-SC_ASPDPOTION0);
  6712. break;
  6713. case SC_WEDDING:
  6714. case SC_XMAS:
  6715. case SC_SUMMER:
  6716. if (!vd) return 0;
  6717. //Store previous values as they could be removed.
  6718. val1 = vd->class_;
  6719. val2 = vd->weapon;
  6720. val3 = vd->shield;
  6721. val4 = vd->cloth_color;
  6722. unit_stop_attack(bl);
  6723. clif_changelook(bl,LOOK_WEAPON,0);
  6724. clif_changelook(bl,LOOK_SHIELD,0);
  6725. clif_changelook(bl,LOOK_BASE,type==SC_WEDDING?JOB_WEDDING:type==SC_XMAS?JOB_XMAS:JOB_SUMMER);
  6726. clif_changelook(bl,LOOK_CLOTHES_COLOR,vd->cloth_color);
  6727. break;
  6728. case SC_NOCHAT:
  6729. // [GodLesZ] FIXME: is this correct? a hardcoded interval of 60sec? what about configuration ?_?
  6730. tick = 60000;
  6731. val1 = battle_config.manner_system; //Mute filters.
  6732. if (sd)
  6733. {
  6734. clif_changestatus(sd,SP_MANNER,sd->status.manner);
  6735. clif_updatestatus(sd,SP_MANNER);
  6736. }
  6737. break;
  6738. case SC_STONE:
  6739. val3 = tick/1000; //Petrified HP-damage iterations.
  6740. if(val3 < 1) val3 = 1;
  6741. tick = val4; //Petrifying time.
  6742. tick = max(tick, 1000); //Min time
  6743. calc_flag = 0; //Actual status changes take effect on petrified state.
  6744. break;
  6745. case SC_DPOISON:
  6746. //Lose 10/15% of your life as long as it doesn't brings life below 25%
  6747. if (status->hp > status->max_hp>>2) {
  6748. int diff = status->max_hp*(bl->type==BL_PC?10:15)/100;
  6749. if (status->hp - diff < status->max_hp>>2)
  6750. diff = status->hp - (status->max_hp>>2);
  6751. if( val2 && bl->type == BL_MOB ) {
  6752. struct block_list* src = map_id2bl(val2);
  6753. if( src )
  6754. mob_log_damage((TBL_MOB*)bl,src,diff);
  6755. }
  6756. status_zap(bl, diff, 0);
  6757. }
  6758. // fall through
  6759. case SC_POISON:
  6760. val3 = tick/1000; //Damage iterations
  6761. if(val3 < 1) val3 = 1;
  6762. tick_time = 1000; // [GodLesZ] tick time
  6763. //val4: HP damage
  6764. if (bl->type == BL_PC)
  6765. val4 = (type == SC_DPOISON) ? 3 + status->max_hp/50 : 3 + status->max_hp*3/200;
  6766. else
  6767. val4 = (type == SC_DPOISON) ? 3 + status->max_hp/100 : 3 + status->max_hp/200;
  6768. break;
  6769. case SC_CONFUSION:
  6770. clif_emotion(bl,E_WHAT);
  6771. break;
  6772. case SC_BLEEDING:
  6773. val4 = tick/10000;
  6774. if (!val4) val4 = 1;
  6775. tick_time = 10000; // [GodLesZ] tick time
  6776. break;
  6777. case SC_S_LIFEPOTION:
  6778. case SC_L_LIFEPOTION:
  6779. if( val1 == 0 ) return 0;
  6780. // val1 = heal percent/amout
  6781. // val2 = seconds between heals
  6782. // val4 = total of heals
  6783. if( val2 < 1 ) val2 = 1;
  6784. if( (val4 = tick/(val2 * 1000)) < 1 )
  6785. val4 = 1;
  6786. tick_time = val2 * 1000; // [GodLesZ] tick time
  6787. break;
  6788. case SC_BOSSMAPINFO:
  6789. if( sd != NULL )
  6790. {
  6791. struct mob_data *boss_md = map_getmob_boss(bl->m); // Search for Boss on this Map
  6792. if( boss_md == NULL || boss_md->bl.prev == NULL )
  6793. { // No MVP on this map - MVP is dead
  6794. clif_bossmapinfo(sd->fd, boss_md, 1);
  6795. return 0; // No need to start SC
  6796. }
  6797. val1 = boss_md->bl.id;
  6798. if( (val4 = tick/1000) < 1 )
  6799. val4 = 1;
  6800. tick_time = 1000; // [GodLesZ] tick time
  6801. }
  6802. break;
  6803. case SC_HIDING:
  6804. val2 = tick/1000;
  6805. tick_time = 1000; // [GodLesZ] tick time
  6806. val3 = 0; // unused, previously speed adjustment
  6807. val4 = val1+3; //Seconds before SP substraction happen.
  6808. break;
  6809. case SC_CHASEWALK:
  6810. val2 = tick>0?tick:10000; //Interval at which SP is drained.
  6811. val3 = 35 - 5 * val1; //Speed adjustment.
  6812. if (sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_ROGUE)
  6813. val3 -= 40;
  6814. val4 = 10+val1*2; //SP cost.
  6815. if (map_flag_gvg(bl->m) || map[bl->m].flag.battleground) val4 *= 5;
  6816. break;
  6817. case SC_CLOAKING:
  6818. if (!sd) //Monsters should be able to walk with no penalties. [Skotlex]
  6819. val1 = 10;
  6820. tick_time = val2 = tick>0?tick:60000; //SP consumption rate.
  6821. tick = -1; // duration sent to the client should be infinite
  6822. val3 = 0; // unused, previously walk speed adjustment
  6823. //val4&1 signals the presence of a wall.
  6824. //val4&2 makes cloak not end on normal attacks [Skotlex]
  6825. //val4&4 makes cloak not end on using skills
  6826. if (bl->type == BL_PC || (bl->type == BL_MOB && ((TBL_MOB*)bl)->special_state.clone) ) //Standard cloaking.
  6827. val4 |= battle_config.pc_cloak_check_type&7;
  6828. else
  6829. val4 |= battle_config.monster_cloak_check_type&7;
  6830. break;
  6831. case SC_SIGHT: /* splash status */
  6832. case SC_RUWACH:
  6833. case SC_SIGHTBLASTER:
  6834. val3 = skill_get_splash(val2, val1); //Val2 should bring the skill-id.
  6835. val2 = tick/250;
  6836. tick_time = 10; // [GodLesZ] tick time
  6837. break;
  6838. //Permanent effects.
  6839. case SC_AETERNA:
  6840. case SC_MODECHANGE:
  6841. case SC_WEIGHT50:
  6842. case SC_WEIGHT90:
  6843. case SC_BROKENWEAPON:
  6844. case SC_BROKENARMOR:
  6845. case SC_READYSTORM:
  6846. case SC_READYDOWN:
  6847. case SC_READYCOUNTER:
  6848. case SC_READYTURN:
  6849. case SC_DODGE:
  6850. case SC_PUSH_CART:
  6851. tick = -1;
  6852. break;
  6853. case SC_AUTOGUARD:
  6854. if( !(flag&1) )
  6855. {
  6856. struct map_session_data *tsd;
  6857. int i,t;
  6858. for( i = val2 = 0; i < val1; i++)
  6859. {
  6860. t = 5-(i>>1);
  6861. val2 += (t < 0)? 1:t;
  6862. }
  6863. if( bl->type&(BL_PC|BL_MER) )
  6864. {
  6865. if( sd )
  6866. {
  6867. for( i = 0; i < 5; i++ )
  6868. {
  6869. if( sd->devotion[i] && (tsd = map_id2sd(sd->devotion[i])) )
  6870. status_change_start(&tsd->bl, type, 10000, val1, val2, 0, 0, tick, 1);
  6871. }
  6872. }
  6873. else if( bl->type == BL_MER && ((TBL_MER*)bl)->devotion_flag && (tsd = ((TBL_MER*)bl)->master) )
  6874. status_change_start(&tsd->bl, type, 10000, val1, val2, 0, 0, tick, 1);
  6875. }
  6876. }
  6877. break;
  6878. case SC_DEFENDER:
  6879. if (!(flag&1))
  6880. {
  6881. val2 = 5 + 15*val1; //Damage reduction
  6882. val3 = 0; // unused, previously speed adjustment
  6883. val4 = 250 - 50*val1; //Aspd adjustment
  6884. if (sd)
  6885. {
  6886. struct map_session_data *tsd;
  6887. int i;
  6888. for (i = 0; i < 5; i++)
  6889. { //See if there are devoted characters, and pass the status to them. [Skotlex]
  6890. if (sd->devotion[i] && (tsd = map_id2sd(sd->devotion[i])))
  6891. status_change_start(&tsd->bl,type,10000,val1,5+val1*5,val3,val4,tick,1);
  6892. }
  6893. }
  6894. }
  6895. break;
  6896. case SC_TENSIONRELAX:
  6897. if (sd) {
  6898. pc_setsit(sd);
  6899. clif_sitting(&sd->bl);
  6900. }
  6901. val2 = 12; //SP cost
  6902. val4 = 10000; //Decrease at 10secs intervals.
  6903. val3 = tick/val4;
  6904. tick = -1; // duration sent to the client should be infinite
  6905. tick_time = val4; // [GodLesZ] tick time
  6906. break;
  6907. case SC_PARRYING:
  6908. val2 = 20 + val1*3; //Block Chance
  6909. break;
  6910. case SC_WINDWALK:
  6911. val2 = (val1+1)/2; // Flee bonus is 1/1/2/2/3/3/4/4/5/5
  6912. break;
  6913. case SC_JOINTBEAT:
  6914. if( val2&BREAK_NECK )
  6915. sc_start2(bl,SC_BLEEDING,100,val1,val3,skill_get_time2(status_sc2skill(type),val1));
  6916. break;
  6917. case SC_BERSERK:
  6918. if (!sc->data[SC_ENDURE] || !sc->data[SC_ENDURE]->val4)
  6919. sc_start4(bl, SC_ENDURE, 100,10,0,0,2, tick);
  6920. case SC__BLOODYLUST:
  6921. //HP healing is performing after the calc_status call.
  6922. //Val2 holds HP penalty
  6923. if (!val4) val4 = skill_get_time2(status_sc2skill(type),val1);
  6924. if (!val4) val4 = 10000; //Val4 holds damage interval
  6925. val3 = tick/val4; //val3 holds skill duration
  6926. tick_time = val4; // [GodLesZ] tick time
  6927. break;
  6928. case SC_GOSPEL:
  6929. if(val4 == BCT_SELF) { // self effect
  6930. val2 = tick/10000;
  6931. tick_time = 10000; // [GodLesZ] tick time
  6932. status_change_clear_buffs(bl,3); //Remove buffs/debuffs
  6933. }
  6934. break;
  6935. case SC_MARIONETTE:
  6936. {
  6937. int stat;
  6938. val3 = 0;
  6939. val4 = 0;
  6940. stat = ( sd ? sd->status.str : status_get_base_status(bl)->str ) / 2; val3 |= cap_value(stat,0,0xFF)<<16;
  6941. stat = ( sd ? sd->status.agi : status_get_base_status(bl)->agi ) / 2; val3 |= cap_value(stat,0,0xFF)<<8;
  6942. stat = ( sd ? sd->status.vit : status_get_base_status(bl)->vit ) / 2; val3 |= cap_value(stat,0,0xFF);
  6943. stat = ( sd ? sd->status.int_: status_get_base_status(bl)->int_) / 2; val4 |= cap_value(stat,0,0xFF)<<16;
  6944. stat = ( sd ? sd->status.dex : status_get_base_status(bl)->dex ) / 2; val4 |= cap_value(stat,0,0xFF)<<8;
  6945. stat = ( sd ? sd->status.luk : status_get_base_status(bl)->luk ) / 2; val4 |= cap_value(stat,0,0xFF);
  6946. break;
  6947. }
  6948. case SC_MARIONETTE2:
  6949. {
  6950. int stat,max_stat;
  6951. // fetch caster information
  6952. struct block_list *pbl = map_id2bl(val1);
  6953. struct status_change *psc = pbl?status_get_sc(pbl):NULL;
  6954. struct status_change_entry *psce = psc?psc->data[SC_MARIONETTE]:NULL;
  6955. // fetch target's stats
  6956. struct status_data* status = status_get_status_data(bl); // battle status
  6957. if (!psce)
  6958. return 0;
  6959. val3 = 0;
  6960. val4 = 0;
  6961. max_stat = battle_config.max_parameter; //Cap to 99 (default)
  6962. stat = (psce->val3 >>16)&0xFF; stat = min(stat, max_stat - status->str ); val3 |= cap_value(stat,0,0xFF)<<16;
  6963. stat = (psce->val3 >> 8)&0xFF; stat = min(stat, max_stat - status->agi ); val3 |= cap_value(stat,0,0xFF)<<8;
  6964. stat = (psce->val3 >> 0)&0xFF; stat = min(stat, max_stat - status->vit ); val3 |= cap_value(stat,0,0xFF);
  6965. stat = (psce->val4 >>16)&0xFF; stat = min(stat, max_stat - status->int_); val4 |= cap_value(stat,0,0xFF)<<16;
  6966. stat = (psce->val4 >> 8)&0xFF; stat = min(stat, max_stat - status->dex ); val4 |= cap_value(stat,0,0xFF)<<8;
  6967. stat = (psce->val4 >> 0)&0xFF; stat = min(stat, max_stat - status->luk ); val4 |= cap_value(stat,0,0xFF);
  6968. break;
  6969. }
  6970. case SC_REJECTSWORD:
  6971. val2 = 15*val1; //Reflect chance
  6972. val3 = 3; //Reflections
  6973. tick = -1;
  6974. break;
  6975. case SC_MEMORIZE:
  6976. val2 = 5; //Memorized casts.
  6977. tick = -1;
  6978. break;
  6979. case SC_GRAVITATION:
  6980. val2 = 50*val1; //aspd reduction
  6981. break;
  6982. case SC_REGENERATION:
  6983. if (val1 == 1)
  6984. val2 = 2;
  6985. else
  6986. val2 = val1; //HP Regerenation rate: 200% 200% 300%
  6987. val3 = val1; //SP Regeneration Rate: 100% 200% 300%
  6988. //if val4 comes set, this blocks regen rather than increase it.
  6989. break;
  6990. case SC_DEVOTION:
  6991. {
  6992. struct block_list *d_bl;
  6993. struct status_change *d_sc;
  6994. if( (d_bl = map_id2bl(val1)) && (d_sc = status_get_sc(d_bl)) && d_sc->count )
  6995. { // Inherits Status From Source
  6996. const enum sc_type types[] = { SC_AUTOGUARD, SC_DEFENDER, SC_REFLECTSHIELD, SC_ENDURE };
  6997. enum sc_type type2;
  6998. int i = (map_flag_gvg(bl->m) || map[bl->m].flag.battleground)?2:3;
  6999. while( i >= 0 )
  7000. {
  7001. type2 = types[i];
  7002. if( d_sc->data[type2] )
  7003. sc_start(bl, type2, 100, d_sc->data[type2]->val1, skill_get_time(status_sc2skill(type2),d_sc->data[type2]->val1));
  7004. i--;
  7005. }
  7006. }
  7007. break;
  7008. }
  7009. case SC_COMA: //Coma. Sends a char to 1HP. If val2, do not zap sp
  7010. if( val3 && bl->type == BL_MOB ) {
  7011. struct block_list* src = map_id2bl(val3);
  7012. if( src )
  7013. mob_log_damage((TBL_MOB*)bl,src,status->hp - 1);
  7014. }
  7015. status_zap(bl, status->hp-1, val2?0:status->sp);
  7016. return 1;
  7017. break;
  7018. case SC_CLOSECONFINE2:
  7019. {
  7020. struct block_list *src = val2?map_id2bl(val2):NULL;
  7021. struct status_change *sc2 = src?status_get_sc(src):NULL;
  7022. struct status_change_entry *sce2 = sc2?sc2->data[SC_CLOSECONFINE]:NULL;
  7023. if (src && sc2) {
  7024. if (!sce2) //Start lock on caster.
  7025. sc_start4(src,SC_CLOSECONFINE,100,val1,1,0,0,tick+1000);
  7026. else { //Increase count of locked enemies and refresh time.
  7027. (sce2->val2)++;
  7028. delete_timer(sce2->timer, status_change_timer);
  7029. sce2->timer = add_timer(gettick()+tick+1000, status_change_timer, src->id, SC_CLOSECONFINE);
  7030. }
  7031. } else //Status failed.
  7032. return 0;
  7033. }
  7034. break;
  7035. case SC_KAITE:
  7036. val2 = 1+val1/5; //Number of bounces: 1 + skill_lv/5
  7037. break;
  7038. case SC_KAUPE:
  7039. switch (val1) {
  7040. case 3: //33*3 + 1 -> 100%
  7041. val2++;
  7042. case 1:
  7043. case 2: //33, 66%
  7044. val2 += 33*val1;
  7045. val3 = 1; //Dodge 1 attack total.
  7046. break;
  7047. default: //Custom. For high level mob usage, higher level means more blocks. [Skotlex]
  7048. val2 = 100;
  7049. val3 = val1-2;
  7050. break;
  7051. }
  7052. break;
  7053. case SC_COMBO: {
  7054. //val1: Skill ID
  7055. //val2: When given, target (for autotargetting skills)
  7056. //val3: When set, this combo time should NOT delay attack/movement
  7057. //val3: TK: Last used kick
  7058. //val4: TK: Combo time
  7059. struct unit_data *ud = unit_bl2ud(bl);
  7060. if (ud && !val3) {
  7061. tick += 300 * battle_config.combo_delay_rate/100;
  7062. ud->attackabletime = gettick()+tick;
  7063. unit_set_walkdelay(bl, gettick(), tick, 1);
  7064. }
  7065. val3 = 0;
  7066. val4 = tick;
  7067. }
  7068. break;
  7069. case SC_EARTHSCROLL:
  7070. val2 = 11-val1; //Chance to consume: 11-skill_lv%
  7071. break;
  7072. case SC_RUN:
  7073. val4 = gettick(); //Store time at which you started running.
  7074. tick = -1;
  7075. break;
  7076. case SC_KAAHI:
  7077. val2 = 200*val1; //HP heal
  7078. val3 = 5*val1; //SP cost
  7079. val4 = INVALID_TIMER; //Kaahi Timer.
  7080. break;
  7081. case SC_BLESSING:
  7082. if ((!undead_flag && status->race!=RC_DEMON) || bl->type == BL_PC)
  7083. val2 = val1;
  7084. else
  7085. val2 = 0; //0 -> Half stat.
  7086. break;
  7087. case SC_TRICKDEAD:
  7088. if (vd) vd->dead_sit = 1;
  7089. tick = -1;
  7090. break;
  7091. case SC_CONCENTRATE:
  7092. val2 = 2 + val1;
  7093. if (sd) { //Store the card-bonus data that should not count in the %
  7094. val3 = sd->param_bonus[1]; //Agi
  7095. val4 = sd->param_bonus[4]; //Dex
  7096. } else {
  7097. val3 = val4 = 0;
  7098. }
  7099. break;
  7100. case SC_MAXOVERTHRUST:
  7101. val2 = 20*val1; //Power increase
  7102. break;
  7103. case SC_OVERTHRUST:
  7104. //val2 holds if it was casted on self, or is bonus received from others
  7105. val3 = 5*val1; //Power increase
  7106. if(sd && pc_checkskill(sd,BS_HILTBINDING)>0)
  7107. tick += tick / 10;
  7108. break;
  7109. case SC_ADRENALINE2:
  7110. case SC_ADRENALINE:
  7111. val3 = (val2) ? 300 : 200; // aspd increase
  7112. case SC_WEAPONPERFECTION:
  7113. if(sd && pc_checkskill(sd,BS_HILTBINDING)>0)
  7114. tick += tick / 10;
  7115. break;
  7116. case SC_CONCENTRATION:
  7117. val2 = 5*val1; //Batk/Watk Increase
  7118. val3 = 10*val1; //Hit Increase
  7119. val4 = 5*val1; //Def reduction
  7120. break;
  7121. case SC_ANGELUS:
  7122. val2 = 5*val1; //def increase
  7123. break;
  7124. case SC_IMPOSITIO:
  7125. val2 = 5*val1; //watk increase
  7126. break;
  7127. case SC_MELTDOWN:
  7128. val2 = 100*val1; //Chance to break weapon
  7129. val3 = 70*val1; //Change to break armor
  7130. break;
  7131. case SC_TRUESIGHT:
  7132. val2 = 10*val1; //Critical increase
  7133. val3 = 3*val1; //Hit increase
  7134. break;
  7135. case SC_SUN_COMFORT:
  7136. val2 = (status_get_lv(bl) + status->dex + status->luk)/2; //def increase
  7137. break;
  7138. case SC_MOON_COMFORT:
  7139. val2 = (status_get_lv(bl) + status->dex + status->luk)/10; //flee increase
  7140. break;
  7141. case SC_STAR_COMFORT:
  7142. val2 = (status_get_lv(bl) + status->dex + status->luk); //Aspd increase
  7143. break;
  7144. case SC_QUAGMIRE:
  7145. val2 = (sd?5:10)*val1; //Agi/Dex decrease.
  7146. break;
  7147. // gs_something1 [Vicious]
  7148. case SC_GATLINGFEVER:
  7149. val2 = 20*val1; //Aspd increase
  7150. val3 = 20+10*val1; //Batk increase
  7151. val4 = 5*val1; //Flee decrease
  7152. break;
  7153. case SC_FLING:
  7154. if (bl->type == BL_PC)
  7155. val2 = 0; //No armor reduction to players.
  7156. else
  7157. val2 = 5*val1; //Def reduction
  7158. val3 = 5*val1; //Def2 reduction
  7159. break;
  7160. case SC_PROVOKE:
  7161. //val2 signals autoprovoke.
  7162. val3 = 2+3*val1; //Atk increase
  7163. val4 = 5+5*val1; //Def reduction.
  7164. break;
  7165. case SC_AVOID:
  7166. //val2 = 10*val1; //Speed change rate.
  7167. break;
  7168. case SC_DEFENCE:
  7169. val2 = 2*val1; //Def bonus
  7170. break;
  7171. case SC_BLOODLUST:
  7172. val2 = 20+10*val1; //Atk rate change.
  7173. val3 = 3*val1; //Leech chance
  7174. val4 = 20; //Leech percent
  7175. break;
  7176. case SC_FLEET:
  7177. val2 = 30*val1; //Aspd change
  7178. val3 = 5+5*val1; //bAtk/wAtk rate change
  7179. break;
  7180. case SC_MINDBREAKER:
  7181. val2 = 20*val1; //matk increase.
  7182. val3 = 12*val1; //mdef2 reduction.
  7183. break;
  7184. case SC_SKA:
  7185. val2 = tick/1000;
  7186. val3 = rnd()%100; //Def changes randomly every second...
  7187. tick_time = 1000; // [GodLesZ] tick time
  7188. break;
  7189. case SC_JAILED:
  7190. //Val1 is duration in minutes. Use INT_MAX to specify 'unlimited' time.
  7191. tick = val1>0?1000:250;
  7192. if (sd)
  7193. {
  7194. if (sd->mapindex != val2)
  7195. {
  7196. int pos = (bl->x&0xFFFF)|(bl->y<<16), //Current Coordinates
  7197. map = sd->mapindex; //Current Map
  7198. //1. Place in Jail (val2 -> Jail Map, val3 -> x, val4 -> y
  7199. pc_setpos(sd,(unsigned short)val2,val3,val4, CLR_TELEPORT);
  7200. //2. Set restore point (val3 -> return map, val4 return coords
  7201. val3 = map;
  7202. val4 = pos;
  7203. } else if (!val3 || val3 == sd->mapindex) { //Use save point.
  7204. val3 = sd->status.save_point.map;
  7205. val4 = (sd->status.save_point.x&0xFFFF)
  7206. |(sd->status.save_point.y<<16);
  7207. }
  7208. }
  7209. break;
  7210. case SC_UTSUSEMI:
  7211. val2=(val1+1)/2; // number of hits blocked
  7212. val3=skill_get_blewcount(NJ_UTSUSEMI, val1); //knockback value.
  7213. break;
  7214. case SC_BUNSINJYUTSU:
  7215. val2=(val1+1)/2; // number of hits blocked
  7216. break;
  7217. case SC_CHANGE:
  7218. val2= 30*val1; //Vit increase
  7219. val3= 20*val1; //Int increase
  7220. break;
  7221. case SC_SWOO:
  7222. if(status->mode&MD_BOSS)
  7223. tick /= 5; //TODO: Reduce skill's duration. But for how long?
  7224. break;
  7225. case SC_SPIDERWEB:
  7226. if( bl->type == BL_PC )
  7227. tick /= 2;
  7228. break;
  7229. case SC_ARMOR:
  7230. //NPC_DEFENDER:
  7231. val2 = 80; //Damage reduction
  7232. //Attack requirements to be blocked:
  7233. val3 = BF_LONG; //Range
  7234. val4 = BF_WEAPON|BF_MISC; //Type
  7235. break;
  7236. case SC_ENCHANTARMS:
  7237. //end previous enchants
  7238. skill_enchant_elemental_end(bl,type);
  7239. //Make sure the received element is valid.
  7240. if (val2 >= ELE_MAX)
  7241. val2 = val2%ELE_MAX;
  7242. else if (val2 < 0)
  7243. val2 = rnd()%ELE_MAX;
  7244. break;
  7245. case SC_CRITICALWOUND:
  7246. val2 = 20*val1; //Heal effectiveness decrease
  7247. break;
  7248. case SC_MAGICMIRROR:
  7249. case SC_SLOWCAST:
  7250. val2 = 20*val1; //Magic reflection/cast rate
  7251. break;
  7252. case SC_ARMORCHANGE:
  7253. if (val2 == NPC_ANTIMAGIC)
  7254. { //Boost mdef
  7255. val2 =-20;
  7256. val3 = 20;
  7257. } else { //Boost def
  7258. val2 = 20;
  7259. val3 =-20;
  7260. }
  7261. val2*=val1; //20% per level
  7262. val3*=val1;
  7263. break;
  7264. case SC_EXPBOOST:
  7265. case SC_JEXPBOOST:
  7266. if (val1 < 0)
  7267. val1 = 0;
  7268. break;
  7269. case SC_INCFLEE2:
  7270. case SC_INCCRI:
  7271. val2 = val1*10; //Actual boost (since 100% = 1000)
  7272. break;
  7273. case SC_SUFFRAGIUM:
  7274. val2 = 15 * val1; //Speed cast decrease
  7275. break;
  7276. case SC_INCHEALRATE:
  7277. if (val1 < 1)
  7278. val1 = 1;
  7279. break;
  7280. case SC_HALLUCINATION:
  7281. val2 = 5+val1; //Factor by which displayed damage is increased by
  7282. break;
  7283. case SC_DOUBLECAST:
  7284. val2 = 30+10*val1; //Trigger rate
  7285. break;
  7286. case SC_KAIZEL:
  7287. val2 = 10*val1; //% of life to be revived with
  7288. break;
  7289. // case SC_ARMOR_ELEMENT:
  7290. // case SC_ARMOR_RESIST:
  7291. // Mod your resistance against elements:
  7292. // val1 = water | val2 = earth | val3 = fire | val4 = wind
  7293. // break;
  7294. //case ????:
  7295. //Place here SCs that have no SCB_* data, no skill associated, no ICON
  7296. //associated, and yet are not wrong/unknown. [Skotlex]
  7297. //break;
  7298. case SC_MERC_FLEEUP:
  7299. case SC_MERC_ATKUP:
  7300. case SC_MERC_HITUP:
  7301. val2 = 15 * val1;
  7302. break;
  7303. case SC_MERC_HPUP:
  7304. case SC_MERC_SPUP:
  7305. val2 = 5 * val1;
  7306. break;
  7307. case SC_REBIRTH:
  7308. val2 = 20*val1; //% of life to be revived with
  7309. break;
  7310. case SC_MANU_DEF:
  7311. case SC_MANU_ATK:
  7312. case SC_MANU_MATK:
  7313. val2 = 1; // Manuk group
  7314. break;
  7315. case SC_SPL_DEF:
  7316. case SC_SPL_ATK:
  7317. case SC_SPL_MATK:
  7318. val2 = 2; // Splendide group
  7319. break;
  7320. /**
  7321. * General
  7322. **/
  7323. case SC_FEAR:
  7324. val2 = 2;
  7325. val4 = tick / 1000;
  7326. tick_time = 1000; // [GodLesZ] tick time
  7327. break;
  7328. case SC_BURNING:
  7329. val4 = tick / 2000; // Total Ticks to Burn!!
  7330. tick_time = 2000; // [GodLesZ] tick time
  7331. break;
  7332. /**
  7333. * Rune Knight
  7334. **/
  7335. case SC_DEATHBOUND:
  7336. val2 = 500 + 100 * val1;
  7337. break;
  7338. case SC_FIGHTINGSPIRIT:
  7339. val_flag |= 1|2;
  7340. break;
  7341. case SC_ABUNDANCE:
  7342. val4 = tick / 10000;
  7343. tick_time = 10000; // [GodLesZ] tick time
  7344. break;
  7345. case SC_GIANTGROWTH:
  7346. val2 = 10; // Triple damage success rate.
  7347. break;
  7348. /**
  7349. * Arch Bishop
  7350. **/
  7351. case SC_RENOVATIO:
  7352. val4 = tick / 5000;
  7353. tick_time = 5000;
  7354. break;
  7355. case SC_SECRAMENT:
  7356. val2 = 10 * val1;
  7357. break;
  7358. case SC_VENOMIMPRESS:
  7359. val2 = 10 * val1;
  7360. val_flag |= 1|2;
  7361. break;
  7362. case SC_POISONINGWEAPON:
  7363. val_flag |= 1|2|4;
  7364. break;
  7365. case SC_WEAPONBLOCKING:
  7366. val2 = 10 + 2 * val1; // Chance
  7367. val4 = tick / 3000;
  7368. tick_time = 3000; // [GodLesZ] tick time
  7369. val_flag |= 1|2;
  7370. break;
  7371. case SC_TOXIN:
  7372. val4 = tick / 10000;
  7373. tick_time = 10000; // [GodLesZ] tick time
  7374. break;
  7375. case SC_MAGICMUSHROOM:
  7376. val4 = tick / 4000;
  7377. tick_time = 4000; // [GodLesZ] tick time
  7378. break;
  7379. case SC_PYREXIA:
  7380. status_change_start(bl,SC_BLIND,10000,val1,0,0,0,30000,11); // Blind status that last for 30 seconds
  7381. val4 = tick / 3000;
  7382. tick_time = 3000; // [GodLesZ] tick time
  7383. break;
  7384. case SC_LEECHESEND:
  7385. val4 = tick / 1000;
  7386. tick_time = 1000; // [GodLesZ] tick time
  7387. break;
  7388. case SC_OBLIVIONCURSE:
  7389. val4 = tick / 3000;
  7390. tick_time = 3000; // [GodLesZ] tick time
  7391. break;
  7392. case SC_ROLLINGCUTTER:
  7393. val_flag |= 1;
  7394. break;
  7395. case SC_CLOAKINGEXCEED:
  7396. val2 = ( val1 + 1 ) / 2; // Hits
  7397. val3 = 90 + val1 * 10; // Walk speed
  7398. val_flag |= 1|2|4;
  7399. if (bl->type == BL_PC)
  7400. val4 |= battle_config.pc_cloak_check_type&7;
  7401. else
  7402. val4 |= battle_config.monster_cloak_check_type&7;
  7403. tick_time = 1000; // [GodLesZ] tick time
  7404. break;
  7405. case SC_HALLUCINATIONWALK:
  7406. val2 = 50 * val1; // Evasion rate of physical attacks. Flee
  7407. val3 = 10 * val1; // Evasion rate of magical attacks.
  7408. val_flag |= 1|2|4;
  7409. break;
  7410. case SC_WHITEIMPRISON:
  7411. status_change_end(bl, SC_BURNING, INVALID_TIMER);
  7412. status_change_end(bl, SC_FREEZING, INVALID_TIMER);
  7413. status_change_end(bl, SC_FREEZE, INVALID_TIMER);
  7414. status_change_end(bl, SC_STONE, INVALID_TIMER);
  7415. break;
  7416. case SC_FREEZING:
  7417. status_change_end(bl, SC_BURNING, INVALID_TIMER);
  7418. break;
  7419. case SC_READING_SB:
  7420. // val2 = sp reduction per second
  7421. tick_time = 5000; // [GodLesZ] tick time
  7422. break;
  7423. case SC_SPHERE_1:
  7424. case SC_SPHERE_2:
  7425. case SC_SPHERE_3:
  7426. case SC_SPHERE_4:
  7427. case SC_SPHERE_5:
  7428. if( !sd )
  7429. return 0; // Should only work on players.
  7430. val4 = tick / 1000;
  7431. if( val4 < 1 )
  7432. val4 = 1;
  7433. tick_time = 1000; // [GodLesZ] tick time
  7434. val_flag |= 1;
  7435. break;
  7436. case SC_SHAPESHIFT:
  7437. switch( val1 )
  7438. {
  7439. case 1: val2 = ELE_FIRE; break;
  7440. case 2: val2 = ELE_EARTH; break;
  7441. case 3: val2 = ELE_WIND; break;
  7442. case 4: val2 = ELE_WATER; break;
  7443. }
  7444. break;
  7445. case SC_ELECTRICSHOCKER:
  7446. case SC_CRYSTALIZE:
  7447. case SC_MEIKYOUSISUI:
  7448. val4 = tick / 1000;
  7449. if( val4 < 1 )
  7450. val4 = 1;
  7451. tick_time = 1000; // [GodLesZ] tick time
  7452. break;
  7453. case SC_CAMOUFLAGE:
  7454. val4 = tick/1000;
  7455. tick_time = 1000; // [GodLesZ] tick time
  7456. break;
  7457. case SC_WUGDASH:
  7458. val4 = gettick(); //Store time at which you started running.
  7459. tick = -1;
  7460. break;
  7461. case SC__SHADOWFORM: {
  7462. struct map_session_data * s_sd = map_id2sd(val2);
  7463. if( s_sd )
  7464. s_sd->shadowform_id = bl->id;
  7465. val4 = tick / 1000;
  7466. val_flag |= 1|2|4;
  7467. tick_time = 1000; // [GodLesZ] tick time
  7468. }
  7469. break;
  7470. case SC__STRIPACCESSORY:
  7471. if (!sd)
  7472. val2 = 20;
  7473. break;
  7474. case SC__INVISIBILITY:
  7475. val2 = 50 - 10 * val1; // ASPD
  7476. val3 = 20 * val1; // CRITICAL
  7477. val4 = tick / 1000;
  7478. tick_time = 1000; // [GodLesZ] tick time
  7479. val_flag |= 1|2;
  7480. break;
  7481. case SC__ENERVATION:
  7482. val2 = 20 + 10 * val1; // ATK Reduction
  7483. val_flag |= 1|2;
  7484. if( sd ) pc_delspiritball(sd,sd->spiritball,0);
  7485. break;
  7486. case SC__GROOMY:
  7487. val2 = 20 + 10 * val1; //ASPD. Need to confirm if Movement Speed reduction is the same. [Jobbie]
  7488. val3 = 20 * val1; //HIT
  7489. val_flag |= 1|2|4;
  7490. if( sd )
  7491. { // Removes Animals
  7492. if( pc_isriding(sd) ) pc_setriding(sd, 0);
  7493. if( pc_isridingdragon(sd) ) pc_setoption(sd, sd->sc.option&~OPTION_DRAGON);
  7494. if( pc_iswug(sd) ) pc_setoption(sd, sd->sc.option&~OPTION_WUG);
  7495. if( pc_isridingwug(sd) ) pc_setoption(sd, sd->sc.option&~OPTION_WUGRIDER);
  7496. if( pc_isfalcon(sd) ) pc_setoption(sd, sd->sc.option&~OPTION_FALCON);
  7497. if( sd->status.pet_id > 0 ) pet_menu(sd, 3);
  7498. if( merc_is_hom_active(sd->hd) ) merc_hom_vaporize(sd,1);
  7499. if( sd->md ) merc_delete(sd->md,3);
  7500. }
  7501. break;
  7502. case SC__LAZINESS:
  7503. val2 = 10 + 10 * val1; // Cast reduction
  7504. val3 = 10 * val1; // Flee Reduction
  7505. val_flag |= 1|2|4;
  7506. break;
  7507. case SC__UNLUCKY:
  7508. val2 = 10 * val1; // Crit and Flee2 Reduction
  7509. val_flag |= 1|2|4;
  7510. break;
  7511. case SC__WEAKNESS:
  7512. val2 = 10 * val1;
  7513. val_flag |= 1|2;
  7514. // bypasses coating protection and MADO
  7515. sc_start(bl,SC_STRIPWEAPON,100,val1,tick);
  7516. sc_start(bl,SC_STRIPSHIELD,100,val1,tick);
  7517. break;
  7518. break;
  7519. case SC_GN_CARTBOOST:
  7520. if( val1 < 3 )
  7521. val2 = 50;
  7522. else if( val1 < 5 )
  7523. val2 = 75;
  7524. else
  7525. val2 = 100;
  7526. break;
  7527. case SC_PROPERTYWALK:
  7528. val_flag |= 1|2;
  7529. val3 = 0;
  7530. break;
  7531. case SC_WARMER:
  7532. status_change_end(bl, SC_FREEZE, INVALID_TIMER);
  7533. status_change_end(bl, SC_FREEZING, INVALID_TIMER);
  7534. status_change_end(bl, SC_CRYSTALIZE, INVALID_TIMER);
  7535. break;
  7536. case SC_STRIKING:
  7537. val1 = 6 - val1;//spcost = 6 - level (lvl1:5 ... lvl 5: 1)
  7538. val4 = tick / 1000;
  7539. tick_time = 1000; // [GodLesZ] tick time
  7540. break;
  7541. case SC_BLOODSUCKER:
  7542. val4 = tick / 1000;
  7543. tick_time = 1000; // [GodLesZ] tick time
  7544. break;
  7545. case SC_VACUUM_EXTREME:
  7546. tick -= (status->str / 20) * 1000;
  7547. val4 = val3 = tick / 100;
  7548. tick_time = 100; // [GodLesZ] tick time
  7549. break;
  7550. case SC_SWINGDANCE:
  7551. val2 = 4 * val1; // Walk speed and aspd reduction.
  7552. break;
  7553. case SC_SYMPHONYOFLOVER:
  7554. case SC_RUSHWINDMILL:
  7555. case SC_ECHOSONG:
  7556. val2 = 6 * val1;
  7557. val2 += val3; //Adding 1% * Lesson Bonus
  7558. val2 += (int)(val4*2/10); //Adding 0.2% per JobLevel
  7559. break;
  7560. case SC_MOONLITSERENADE:
  7561. val2 = 10 * val1;
  7562. break;
  7563. case SC_HARMONIZE:
  7564. val2 = 5 + 5 * val1;
  7565. break;
  7566. case SC_VOICEOFSIREN:
  7567. val4 = tick / 2000;
  7568. tick_time = 2000; // [GodLesZ] tick time
  7569. break;
  7570. case SC_DEEPSLEEP:
  7571. val4 = tick / 2000;
  7572. tick_time = 2000; // [GodLesZ] tick time
  7573. break;
  7574. case SC_SIRCLEOFNATURE:
  7575. val2 = 1 + val1; //SP consume
  7576. val3 = 40 * val1; //HP recovery
  7577. val4 = tick / 1000;
  7578. tick_time = 1000; // [GodLesZ] tick time
  7579. break;
  7580. case SC_SONGOFMANA:
  7581. val3 = 10 + (2 * val2);
  7582. val4 = tick/3000;
  7583. tick_time = 3000; // [GodLesZ] tick time
  7584. break;
  7585. case SC_SATURDAYNIGHTFEVER:
  7586. if (!val4) val4 = skill_get_time2(status_sc2skill(type),val1);
  7587. if (!val4) val4 = 3000;
  7588. val3 = tick/val4;
  7589. tick_time = val4; // [GodLesZ] tick time
  7590. break;
  7591. case SC_GLOOMYDAY:
  7592. val2 = 20 + 5 * val1; // Flee reduction.
  7593. val3 = 15 + 5 * val1; // ASPD reduction.
  7594. if( sd && rand()%100 < val1 ){ // (Skill Lv) %
  7595. val4 = 1; // reduce walk speed by half.
  7596. if( pc_isriding(sd) ) pc_setriding(sd, 0);
  7597. if( pc_isridingdragon(sd) ) pc_setoption(sd, sd->sc.option&~OPTION_DRAGON);
  7598. }
  7599. break;
  7600. case SC_GLOOMYDAY_SK:
  7601. // Random number between [15 ~ (Voice Lesson Skill Level x 5) + (Skill Level x 10)] %.
  7602. val2 = 15 + rand()%( (sd?pc_checkskill(sd, WM_LESSON)*5:0) + val1*10 );
  7603. break;
  7604. case SC_SITDOWN_FORCE:
  7605. case SC_BANANA_BOMB_SITDOWN:
  7606. if( sd && !pc_issit(sd) )
  7607. {
  7608. pc_setsit(sd);
  7609. skill_sit(sd,1);
  7610. clif_sitting(bl);
  7611. }
  7612. break;
  7613. case SC_DANCEWITHWUG:
  7614. val3 = (5 * val1) + (1 * val2); //Still need official value.
  7615. break;
  7616. case SC_LERADSDEW:
  7617. val3 = (5 * val1) + (1 * val2);
  7618. break;
  7619. case SC_MELODYOFSINK:
  7620. val3 = (5 * val1) + (1 * val2);
  7621. break;
  7622. case SC_BEYONDOFWARCRY:
  7623. val3 = (5 * val1) + (1 * val2);
  7624. break;
  7625. case SC_UNLIMITEDHUMMINGVOICE:
  7626. {
  7627. struct unit_data *ud = unit_bl2ud(bl);
  7628. if( ud == NULL ) return 0;
  7629. ud->state.skillcastcancel = 0;
  7630. val3 = 15 - (2 * val2);
  7631. }
  7632. break;
  7633. case SC_REFLECTDAMAGE:
  7634. val2 = 15 + 5 * val1;
  7635. val3 = (val1==5)?20:(val1+4)*2; // SP consumption
  7636. val4 = tick/10000;
  7637. tick_time = 10000; // [GodLesZ] tick time
  7638. break;
  7639. case SC_FORCEOFVANGUARD: // This is not the official way to handle it but I think we should use it. [pakpil]
  7640. val2 = 20 + 12 * (val1 - 1); // Chance
  7641. val3 = 5 + (2 * val1); // Max rage counters
  7642. tick = -1; //endless duration in the client
  7643. tick_time = 6000; // [GodLesZ] tick time
  7644. val_flag |= 1|2|4;
  7645. break;
  7646. case SC_EXEEDBREAK:
  7647. val1 *= 150; // 150 * skill_lv
  7648. if( sd && sd->inventory_data[sd->equip_index[EQI_HAND_R]] ) { // Chars.
  7649. val1 += (sd->inventory_data[sd->equip_index[EQI_HAND_R]]->weight/10 * sd->inventory_data[sd->equip_index[EQI_HAND_R]]->wlv * status_get_lv(bl) / 100);
  7650. val1 += 15 * (sd ? sd->status.job_level:50) + 100;
  7651. }
  7652. else // Mobs
  7653. val1 += (400 * status_get_lv(bl) / 100) + (15 * (status_get_lv(bl) / 2)); // About 1138% at mob_lvl 99. Is an aproximation to a standard weapon. [pakpil]
  7654. break;
  7655. case SC_PRESTIGE: // Bassed on suggested formula in iRO Wiki and some test, still need more test. [pakpil]
  7656. val2 = ((status->int_ + status->luk) / 6) + 5; // Chance to evade magic damage.
  7657. val1 *= 15; // Defence added
  7658. if( sd )
  7659. val1 += 10 * pc_checkskill(sd,CR_DEFENDER);
  7660. val_flag |= 1|2;
  7661. break;
  7662. case SC_BANDING:
  7663. tick_time = 5000; // [GodLesZ] tick time
  7664. val_flag |= 1;
  7665. break;
  7666. case SC_SHIELDSPELL_DEF:
  7667. case SC_SHIELDSPELL_MDEF:
  7668. case SC_SHIELDSPELL_REF:
  7669. val_flag |= 1|2;
  7670. break;
  7671. case SC_MAGNETICFIELD:
  7672. val3 = tick / 1000;
  7673. tick_time = 1000; // [GodLesZ] tick time
  7674. break;
  7675. case SC_INSPIRATION:
  7676. if( sd )
  7677. {
  7678. val2 = (40 * val1) + (3 * sd->status.job_level); // ATK bonus
  7679. val3 = (sd->status.job_level / 10) * 2 + 12; // All stat bonus
  7680. }
  7681. val4 = tick / 1000;
  7682. tick_time = 1000; // [GodLesZ] tick time
  7683. status_change_clear_buffs(bl,3); //Remove buffs/debuffs
  7684. break;
  7685. case SC_SPELLFIST:
  7686. case SC_CURSEDCIRCLE_ATKER:
  7687. val_flag |= 1|2|4;
  7688. break;
  7689. case SC_CRESCENTELBOW:
  7690. val2 = 94 + val1;
  7691. val_flag |= 1|2;
  7692. break;
  7693. case SC_LIGHTNINGWALK: // [(Job Level / 2) + (40 + 5 * Skill Level)] %
  7694. val1 = (sd?sd->status.job_level:2)/2 + 40 + 5 * val1;
  7695. val_flag |= 1;
  7696. break;
  7697. case SC_RAISINGDRAGON:
  7698. val3 = tick / 5000;
  7699. tick_time = 5000; // [GodLesZ] tick time
  7700. break;
  7701. case SC_GT_CHANGE:
  7702. {// take note there is no def increase as skill desc says. [malufett]
  7703. struct block_list * src;
  7704. val3 = status->agi * val1 / 60; // ASPD increase: [(Target AGI x Skill Level) / 60] %
  7705. if( (src = map_id2bl(val2)) )
  7706. val4 = ( 200/status_get_int(src) ) * val1;// MDEF decrease: MDEF [(200 / Caster INT) x Skill Level]
  7707. }
  7708. break;
  7709. case SC_GT_REVITALIZE:
  7710. {// take note there is no vit,aspd,speed increase as skill desc says. [malufett]
  7711. struct block_list * src;
  7712. val3 = val1 * 30 + 150; // Natural HP recovery increase: [(Skill Level x 30) + 50] %
  7713. if( (src = map_id2bl(val2)) ) // the stat def is not shown in the status window and it is process differently
  7714. val4 = ( status_get_vit(src)/4 ) * val1; // STAT DEF increase: [(Caster VIT / 4) x Skill Level]
  7715. }
  7716. break;
  7717. case SC_PYROTECHNIC_OPTION:
  7718. val_flag |= 1|2|4;
  7719. break;
  7720. case SC_HEATER_OPTION:
  7721. val2 = 120; // Watk. TODO: Renewal (Atk2)
  7722. val3 = 33; // % Increase effects.
  7723. val4 = 3; // Change into fire element.
  7724. val_flag |= 1|2|4;
  7725. break;
  7726. case SC_TROPIC_OPTION:
  7727. val2 = 180; // Watk. TODO: Renewal (Atk2)
  7728. val3 = MG_FIREBOLT;
  7729. break;
  7730. case SC_AQUAPLAY_OPTION:
  7731. val2 = 40;
  7732. val_flag |= 1|2|4;
  7733. break;
  7734. case SC_COOLER_OPTION:
  7735. val2 = 80; // % Freezing chance
  7736. val3 = 33; // % increased damage
  7737. val4 = 1; // Change into water elemet
  7738. val_flag |= 1|2|4;
  7739. break;
  7740. case SC_CHILLY_AIR_OPTION:
  7741. val2 = 120; // Matk. TODO: Renewal (Matk1)
  7742. val3 = MG_COLDBOLT;
  7743. val_flag |= 1|2;
  7744. break;
  7745. case SC_GUST_OPTION:
  7746. val_flag |= 1|2;
  7747. break;
  7748. case SC_WIND_STEP_OPTION:
  7749. val2 = 50; // % Increase speed and flee.
  7750. break;
  7751. case SC_BLAST_OPTION:
  7752. val2 = 20;
  7753. val3 = ELE_WIND;
  7754. val_flag |= 1|2|4;
  7755. break;
  7756. case SC_WILD_STORM_OPTION:
  7757. val2 = MG_LIGHTNINGBOLT;
  7758. val_flag |= 1|2;
  7759. break;
  7760. case SC_PETROLOGY_OPTION:
  7761. val2 = 5;
  7762. val3 = 50;
  7763. val_flag |= 1|2|4;
  7764. break;
  7765. case SC_CURSED_SOIL_OPTION:
  7766. val2 = 10;
  7767. val3 = 33;
  7768. val4 = 2;
  7769. val_flag |= 1|2|4;
  7770. break;
  7771. case SC_UPHEAVAL_OPTION:
  7772. val2 = WZ_EARTHSPIKE;
  7773. val_flag |= 1|2;
  7774. break;
  7775. case SC_CIRCLE_OF_FIRE_OPTION:
  7776. val2 = 300;
  7777. val_flag |= 1|2;
  7778. break;
  7779. case SC_FIRE_CLOAK_OPTION:
  7780. case SC_WATER_DROP_OPTION:
  7781. case SC_WIND_CURTAIN_OPTION:
  7782. case SC_STONE_SHIELD_OPTION:
  7783. val2 = 20; // Elemental modifier. Not confirmed.
  7784. break;
  7785. case SC_CIRCLE_OF_FIRE:
  7786. case SC_FIRE_CLOAK:
  7787. case SC_WATER_DROP:
  7788. case SC_WATER_SCREEN:
  7789. case SC_WIND_CURTAIN:
  7790. case SC_WIND_STEP:
  7791. case SC_STONE_SHIELD:
  7792. case SC_SOLID_SKIN:
  7793. val2 = 10;
  7794. tick_time = 2000; // [GodLesZ] tick time
  7795. break;
  7796. case SC_WATER_BARRIER:
  7797. val2 = 40; // Increasement. Mdef1 ???
  7798. val3 = 20; // Reductions. Atk2, Flee1, Matk1 ????
  7799. val_flag |= 1|2|4;
  7800. break;
  7801. case SC_ZEPHYR:
  7802. val2 = 22; // Flee.
  7803. break;
  7804. case SC_TIDAL_WEAPON:
  7805. val2 = 20; // Increase Elemental's attack.
  7806. break;
  7807. case SC_ROCK_CRUSHER:
  7808. case SC_ROCK_CRUSHER_ATK:
  7809. case SC_POWER_OF_GAIA:
  7810. val2 = 33;
  7811. break;
  7812. case SC_MELON_BOMB:
  7813. case SC_BANANA_BOMB:
  7814. val1 = 15;
  7815. break;
  7816. case SC_STOMACHACHE:
  7817. val2 = 8; // SP consume.
  7818. val4 = tick / 10000;
  7819. tick_time = 10000; // [GodLesZ] tick time
  7820. break;
  7821. case SC_KYOUGAKU:
  7822. val2 = 2*val1 + rand()%val1;
  7823. clif_status_change(bl,SI_ACTIVE_MONSTER_TRANSFORM,1,0,1002,0,0);
  7824. break;
  7825. case SC_KAGEMUSYA:
  7826. val3 = val1 * 2;
  7827. case SC_IZAYOI:
  7828. val2 = tick/1000;
  7829. tick_time = 1000;
  7830. break;
  7831. case SC_ZANGETSU:
  7832. if( (status_get_hp(bl)+status_get_sp(bl)) % 2 == 0)
  7833. val2 = status_get_lv(bl) / 2 + 50;
  7834. else
  7835. val2 -= 50;
  7836. break;
  7837. case SC_GENSOU:
  7838. {
  7839. int hp = status_get_hp(bl), lv = 5;
  7840. short per = 100 / (status_get_max_hp(bl) / hp);
  7841. if( per <= 15 )
  7842. lv = 1;
  7843. else if( per <= 30 )
  7844. lv = 2;
  7845. else if( per <= 50 )
  7846. lv = 3;
  7847. else if( per <= 75 )
  7848. lv = 4;
  7849. if( hp % 2 == 0)
  7850. status_heal(bl, hp * (6-lv) * 4 / 100, status_get_sp(bl) * (6-lv) * 3 / 100, 1);
  7851. else
  7852. status_zap(bl, hp * (lv*4) / 100, status_get_sp(bl) * (lv*3) / 100);
  7853. }
  7854. break;
  7855. case SC_ANGRIFFS_MODUS:
  7856. val2 = 50 + 20 * val1; //atk bonus
  7857. val3 = 40 + 20 * val1; // Flee reduction.
  7858. val4 = tick/1000; // hp/sp reduction timer
  7859. tick_time = 1000;
  7860. break;
  7861. case SC_GOLDENE_FERSE:
  7862. val2 = 10 + 10*val1; //max hp bonus
  7863. val3 = 6 + 4 * val1; // Aspd Bonus
  7864. val4 = 2 + 2 * val1; // Chance of holy attack
  7865. break;
  7866. case SC_OVERED_BOOST:
  7867. val2 = 300 + 40*val1; //flee bonus
  7868. val3 = 179 + 2*val1; //aspd bonus
  7869. break;
  7870. case SC_GRANITIC_ARMOR:
  7871. val2 = 2*val1; //dmg reduction
  7872. val3 = 6*val1; //dmg on status end
  7873. break;
  7874. case SC_MAGMA_FLOW:
  7875. val2 = 3*val1; //activation chance
  7876. break;
  7877. case SC_PYROCLASTIC:
  7878. val2 += 10*val1; //atk bonus
  7879. break;
  7880. case SC_PARALYSIS: //[Lighta] need real info
  7881. val2 = 2*val1; //def reduction
  7882. val3 = 500*val1; //varcast augmentation
  7883. break;
  7884. case SC_PAIN_KILLER: //[Lighta] need real info
  7885. val2 = 2*val1; //aspd reduction %
  7886. val3 = 2*val1; //dmg reduction %
  7887. if(sc->data[SC_PARALYSIS])
  7888. sc_start(bl, SC_ENDURE, 100, val1, tick); //start endure for same duration
  7889. break;
  7890. case SC_STYLE_CHANGE: //[Lighta] need real info
  7891. tick = -1;
  7892. if(val2 == MH_MD_FIGHTING) val2 = MH_MD_GRAPPLING;
  7893. else val2 = MH_MD_FIGHTING;
  7894. break;
  7895. default:
  7896. if( calc_flag == SCB_NONE && StatusSkillChangeTable[type] == 0 && StatusIconChangeTable[type] == 0 )
  7897. { //Status change with no calc, no icon, and no skill associated...?
  7898. ShowError("UnknownStatusChange [%d]\n", type);
  7899. return 0;
  7900. }
  7901. }
  7902. else //Special considerations when loading SC data.
  7903. switch( type )
  7904. {
  7905. case SC_WEDDING:
  7906. case SC_XMAS:
  7907. case SC_SUMMER:
  7908. clif_changelook(bl,LOOK_WEAPON,0);
  7909. clif_changelook(bl,LOOK_SHIELD,0);
  7910. clif_changelook(bl,LOOK_BASE,type==SC_WEDDING?JOB_WEDDING:type==SC_XMAS?JOB_XMAS:JOB_SUMMER);
  7911. clif_changelook(bl,LOOK_CLOTHES_COLOR,val4);
  7912. break;
  7913. case SC_KAAHI:
  7914. val4 = INVALID_TIMER;
  7915. break;
  7916. }
  7917. //Those that make you stop attacking/walking....
  7918. switch (type) {
  7919. case SC_FREEZE:
  7920. case SC_STUN:
  7921. case SC_SLEEP:
  7922. case SC_STONE:
  7923. case SC_DEEPSLEEP:
  7924. if (sd && pc_issit(sd)) //Avoid sprite sync problems.
  7925. pc_setstand(sd);
  7926. case SC_TRICKDEAD:
  7927. status_change_end(bl, SC_DANCING, INVALID_TIMER);
  7928. // Cancel cast when get status [LuzZza]
  7929. if (battle_config.sc_castcancel&bl->type)
  7930. unit_skillcastcancel(bl, 0);
  7931. case SC_WHITEIMPRISON:
  7932. unit_stop_attack(bl);
  7933. case SC_STOP:
  7934. case SC_CONFUSION:
  7935. case SC_CLOSECONFINE:
  7936. case SC_CLOSECONFINE2:
  7937. case SC_ANKLE:
  7938. case SC_SPIDERWEB:
  7939. case SC_ELECTRICSHOCKER:
  7940. case SC_BITE:
  7941. case SC_THORNSTRAP:
  7942. case SC__MANHOLE:
  7943. case SC_CRYSTALIZE:
  7944. case SC_CURSEDCIRCLE_ATKER:
  7945. case SC_CURSEDCIRCLE_TARGET:
  7946. case SC_FEAR:
  7947. case SC_NETHERWORLD:
  7948. case SC_MEIKYOUSISUI:
  7949. case SC_KYOUGAKU:
  7950. case SC_PARALYSIS:
  7951. unit_stop_walking(bl,1);
  7952. break;
  7953. case SC_HIDING:
  7954. case SC_CLOAKING:
  7955. case SC_CLOAKINGEXCEED:
  7956. case SC_CHASEWALK:
  7957. case SC_WEIGHT90:
  7958. case SC_CAMOUFLAGE:
  7959. case SC_VOICEOFSIREN:
  7960. unit_stop_attack(bl);
  7961. break;
  7962. case SC_SILENCE:
  7963. if (battle_config.sc_castcancel&bl->type)
  7964. unit_skillcastcancel(bl, 0);
  7965. break;
  7966. }
  7967. // Set option as needed.
  7968. opt_flag = 1;
  7969. switch(type)
  7970. {
  7971. //OPT1
  7972. case SC_STONE: sc->opt1 = OPT1_STONEWAIT; break;
  7973. case SC_FREEZE: sc->opt1 = OPT1_FREEZE; break;
  7974. case SC_STUN: sc->opt1 = OPT1_STUN; break;
  7975. case SC_DEEPSLEEP: opt_flag = 0;
  7976. case SC_SLEEP: sc->opt1 = OPT1_SLEEP; break;
  7977. case SC_BURNING: sc->opt1 = OPT1_BURNING; break; // Burning need this to be showed correctly. [pakpil]
  7978. case SC_WHITEIMPRISON: sc->opt1 = OPT1_IMPRISON; break;
  7979. case SC_CRYSTALIZE: sc->opt1 = OPT1_CRYSTALIZE; break;
  7980. //OPT2
  7981. case SC_POISON: sc->opt2 |= OPT2_POISON; break;
  7982. case SC_CURSE: sc->opt2 |= OPT2_CURSE; break;
  7983. case SC_SILENCE: sc->opt2 |= OPT2_SILENCE; break;
  7984. case SC_SIGNUMCRUCIS:
  7985. sc->opt2 |= OPT2_SIGNUMCRUCIS;
  7986. break;
  7987. case SC_BLIND: sc->opt2 |= OPT2_BLIND; break;
  7988. case SC_ANGELUS: sc->opt2 |= OPT2_ANGELUS; break;
  7989. case SC_BLEEDING: sc->opt2 |= OPT2_BLEEDING; break;
  7990. case SC_DPOISON: sc->opt2 |= OPT2_DPOISON; break;
  7991. //OPT3
  7992. case SC_TWOHANDQUICKEN:
  7993. case SC_ONEHAND:
  7994. case SC_SPEARQUICKEN:
  7995. case SC_CONCENTRATION:
  7996. case SC_MERC_QUICKEN:
  7997. sc->opt3 |= OPT3_QUICKEN;
  7998. opt_flag = 0;
  7999. break;
  8000. case SC_MAXOVERTHRUST:
  8001. case SC_OVERTHRUST:
  8002. case SC_SWOO: //Why does it shares the same opt as Overthrust? Perhaps we'll never know...
  8003. sc->opt3 |= OPT3_OVERTHRUST;
  8004. opt_flag = 0;
  8005. break;
  8006. case SC_ENERGYCOAT:
  8007. case SC_SKE:
  8008. sc->opt3 |= OPT3_ENERGYCOAT;
  8009. opt_flag = 0;
  8010. break;
  8011. case SC_INCATKRATE:
  8012. //Simulate Explosion Spirits effect for NPC_POWERUP [Skotlex]
  8013. if (bl->type != BL_MOB) {
  8014. opt_flag = 0;
  8015. break;
  8016. }
  8017. case SC_EXPLOSIONSPIRITS:
  8018. sc->opt3 |= OPT3_EXPLOSIONSPIRITS;
  8019. opt_flag = 0;
  8020. break;
  8021. case SC_STEELBODY:
  8022. case SC_SKA:
  8023. sc->opt3 |= OPT3_STEELBODY;
  8024. opt_flag = 0;
  8025. break;
  8026. case SC_BLADESTOP:
  8027. sc->opt3 |= OPT3_BLADESTOP;
  8028. opt_flag = 0;
  8029. break;
  8030. case SC_AURABLADE:
  8031. sc->opt3 |= OPT3_AURABLADE;
  8032. opt_flag = 0;
  8033. break;
  8034. case SC_BERSERK:
  8035. opt_flag = 0;
  8036. // case SC__BLOODYLUST:
  8037. sc->opt3 |= OPT3_BERSERK;
  8038. break;
  8039. // case ???: // doesn't seem to do anything
  8040. // sc->opt3 |= OPT3_LIGHTBLADE;
  8041. // opt_flag = 0;
  8042. // break;
  8043. case SC_DANCING:
  8044. if ((val1&0xFFFF) == CG_MOONLIT)
  8045. sc->opt3 |= OPT3_MOONLIT;
  8046. opt_flag = 0;
  8047. break;
  8048. case SC_MARIONETTE:
  8049. case SC_MARIONETTE2:
  8050. sc->opt3 |= OPT3_MARIONETTE;
  8051. opt_flag = 0;
  8052. break;
  8053. case SC_ASSUMPTIO:
  8054. sc->opt3 |= OPT3_ASSUMPTIO;
  8055. opt_flag = 0;
  8056. break;
  8057. case SC_WARM: //SG skills [Komurka]
  8058. sc->opt3 |= OPT3_WARM;
  8059. opt_flag = 0;
  8060. break;
  8061. case SC_KAITE:
  8062. sc->opt3 |= OPT3_KAITE;
  8063. opt_flag = 0;
  8064. break;
  8065. case SC_BUNSINJYUTSU:
  8066. sc->opt3 |= OPT3_BUNSIN;
  8067. opt_flag = 0;
  8068. break;
  8069. case SC_SPIRIT:
  8070. sc->opt3 |= OPT3_SOULLINK;
  8071. opt_flag = 0;
  8072. break;
  8073. case SC_CHANGEUNDEAD:
  8074. sc->opt3 |= OPT3_UNDEAD;
  8075. opt_flag = 0;
  8076. break;
  8077. // case ???: // from DA_CONTRACT (looks like biolab mobs aura)
  8078. // sc->opt3 |= OPT3_CONTRACT;
  8079. // opt_flag = 0;
  8080. // break;
  8081. //OPTION
  8082. case SC_HIDING:
  8083. sc->option |= OPTION_HIDE;
  8084. opt_flag = 2;
  8085. break;
  8086. case SC_CLOAKING:
  8087. case SC_CLOAKINGEXCEED:
  8088. case SC__INVISIBILITY:
  8089. sc->option |= OPTION_CLOAK;
  8090. opt_flag = 2;
  8091. break;
  8092. case SC_CHASEWALK:
  8093. sc->option |= OPTION_CHASEWALK|OPTION_CLOAK;
  8094. opt_flag = 2;
  8095. break;
  8096. case SC_SIGHT:
  8097. sc->option |= OPTION_SIGHT;
  8098. break;
  8099. case SC_RUWACH:
  8100. sc->option |= OPTION_RUWACH;
  8101. break;
  8102. case SC_WEDDING:
  8103. sc->option |= OPTION_WEDDING;
  8104. break;
  8105. case SC_XMAS:
  8106. sc->option |= OPTION_XMAS;
  8107. break;
  8108. case SC_SUMMER:
  8109. sc->option |= OPTION_SUMMER;
  8110. break;
  8111. case SC_ORCISH:
  8112. sc->option |= OPTION_ORCISH;
  8113. break;
  8114. case SC_FUSION:
  8115. sc->option |= OPTION_FLYING;
  8116. break;
  8117. default:
  8118. opt_flag = 0;
  8119. }
  8120. //On Aegis, when turning on a status change, first goes the option packet, then the sc packet.
  8121. if(opt_flag)
  8122. clif_changeoption(bl);
  8123. if (calc_flag&SCB_DYE)
  8124. { //Reset DYE color
  8125. if (vd && vd->cloth_color)
  8126. {
  8127. val4 = vd->cloth_color;
  8128. clif_changelook(bl,LOOK_CLOTHES_COLOR,0);
  8129. }
  8130. calc_flag&=~SCB_DYE;
  8131. }
  8132. clif_status_change(bl,StatusIconChangeTable[type],1,tick,(val_flag&1)?val1:1,(val_flag&2)?val2:0,(val_flag&4)?val3:0);
  8133. /**
  8134. * used as temporary storage for scs with interval ticks, so that the actual duration is sent to the client first.
  8135. **/
  8136. if( tick_time )
  8137. tick = tick_time;
  8138. //Don't trust the previous sce assignment, in case the SC ended somewhere between there and here.
  8139. if((sce=sc->data[type])) {// reuse old sc
  8140. if( sce->timer != INVALID_TIMER )
  8141. delete_timer(sce->timer, status_change_timer);
  8142. sc_isnew = false;
  8143. } else {// new sc
  8144. ++(sc->count);
  8145. sce = sc->data[type] = ers_alloc(sc_data_ers, struct status_change_entry);
  8146. }
  8147. sce->val1 = val1;
  8148. sce->val2 = val2;
  8149. sce->val3 = val3;
  8150. sce->val4 = val4;
  8151. if (tick >= 0)
  8152. sce->timer = add_timer(gettick() + tick, status_change_timer, bl->id, type);
  8153. else
  8154. sce->timer = INVALID_TIMER; //Infinite duration
  8155. if (calc_flag)
  8156. status_calc_bl(bl,calc_flag);
  8157. if ( sc_isnew && StatusChangeStateTable[type] ) /* non-zero */
  8158. status_calc_state(bl,sc,( enum scs_flag ) StatusChangeStateTable[type],true);
  8159. if(sd && sd->pd)
  8160. pet_sc_check(sd, type); //Skotlex: Pet Status Effect Healing
  8161. switch (type) {
  8162. case SC__BLOODYLUST:
  8163. case SC_BERSERK:
  8164. if (!(sce->val2)) { //don't heal if already set
  8165. status_heal(bl, status->max_hp, 0, 1); //Do not use percent_heal as this healing must override BERSERK's block.
  8166. status_set_sp(bl, 0, 0); //Damage all SP
  8167. }
  8168. sce->val2 = 5 * status->max_hp / 100;
  8169. break;
  8170. case SC_CHANGE:
  8171. status_percent_heal(bl, 100, 100);
  8172. break;
  8173. case SC_RUN:
  8174. {
  8175. struct unit_data *ud = unit_bl2ud(bl);
  8176. if( ud )
  8177. ud->state.running = unit_run(bl);
  8178. }
  8179. break;
  8180. case SC_BOSSMAPINFO:
  8181. clif_bossmapinfo(sd->fd, map_id2boss(sce->val1), 0); // First Message
  8182. break;
  8183. case SC_MERC_HPUP:
  8184. status_percent_heal(bl, 100, 0); // Recover Full HP
  8185. break;
  8186. case SC_MERC_SPUP:
  8187. status_percent_heal(bl, 0, 100); // Recover Full SP
  8188. break;
  8189. /**
  8190. * Ranger
  8191. **/
  8192. case SC_WUGDASH:
  8193. {
  8194. struct unit_data *ud = unit_bl2ud(bl);
  8195. if( ud )
  8196. ud->state.running = unit_wugdash(bl, sd);
  8197. }
  8198. break;
  8199. case SC_COMBO:
  8200. switch (sce->val1) {
  8201. case TK_STORMKICK:
  8202. clif_skill_nodamage(bl,bl,TK_READYSTORM,1,1);
  8203. break;
  8204. case TK_DOWNKICK:
  8205. clif_skill_nodamage(bl,bl,TK_READYDOWN,1,1);
  8206. break;
  8207. case TK_TURNKICK:
  8208. clif_skill_nodamage(bl,bl,TK_READYTURN,1,1);
  8209. break;
  8210. case TK_COUNTER:
  8211. clif_skill_nodamage(bl,bl,TK_READYCOUNTER,1,1);
  8212. break;
  8213. case MO_COMBOFINISH:
  8214. case CH_TIGERFIST:
  8215. case CH_CHAINCRUSH:
  8216. if (sd)
  8217. clif_skillinfo(sd,MO_EXTREMITYFIST, INF_SELF_SKILL);
  8218. break;
  8219. case TK_JUMPKICK:
  8220. if (sd)
  8221. clif_skillinfo(sd,TK_JUMPKICK, INF_SELF_SKILL);
  8222. break;
  8223. case MO_TRIPLEATTACK:
  8224. if (sd && pc_checkskill(sd, SR_DRAGONCOMBO) > 0)
  8225. clif_skillinfo(sd,SR_DRAGONCOMBO, INF_SELF_SKILL);
  8226. break;
  8227. case SR_FALLENEMPIRE:
  8228. if (sd){
  8229. clif_skillinfo(sd,SR_GATEOFHELL, INF_SELF_SKILL);
  8230. clif_skillinfo(sd,SR_TIGERCANNON, INF_SELF_SKILL);
  8231. }
  8232. break;
  8233. }
  8234. break;
  8235. case SC_RAISINGDRAGON:
  8236. sce->val2 = status->max_hp / 100;// Officially tested its 1%hp drain. [Jobbie]
  8237. break;
  8238. }
  8239. if( opt_flag&2 && sd && sd->touching_id )
  8240. npc_touchnext_areanpc(sd,false); // run OnTouch_ on next char in range
  8241. return 1;
  8242. }
  8243. /*==========================================
  8244. * Ending all status except those listed.
  8245. * @TODO maybe usefull for dispel instead reseting a liste there.
  8246. * type:
  8247. * 0 - PC killed -> Place here statuses that do not dispel on death.
  8248. * 1 - If for some reason status_change_end decides to still keep the status when quitting.
  8249. * 2 - Do clif
  8250. * 3 - Do not remove some permanent/time-independent effects
  8251. *------------------------------------------*/
  8252. int status_change_clear(struct block_list* bl, int type)
  8253. {
  8254. struct status_change* sc;
  8255. int i;
  8256. sc = status_get_sc(bl);
  8257. if (!sc || !sc->count)
  8258. return 0;
  8259. for(i = 0; i < SC_MAX; i++)
  8260. {
  8261. if(!sc->data[i])
  8262. continue;
  8263. if(type == 0)
  8264. switch (i)
  8265. { //Type 0: PC killed -> Place here statuses that do not dispel on death.
  8266. case SC_ELEMENTALCHANGE://Only when its Holy or Dark that it doesn't dispell on death
  8267. if( sc->data[i]->val2 != ELE_HOLY && sc->data[i]->val2 != ELE_DARK )
  8268. break;
  8269. case SC_WEIGHT50:
  8270. case SC_WEIGHT90:
  8271. case SC_EDP:
  8272. case SC_MELTDOWN:
  8273. case SC_XMAS:
  8274. case SC_SUMMER:
  8275. case SC_NOCHAT:
  8276. case SC_FUSION:
  8277. case SC_EARTHSCROLL:
  8278. case SC_READYSTORM:
  8279. case SC_READYDOWN:
  8280. case SC_READYCOUNTER:
  8281. case SC_READYTURN:
  8282. case SC_DODGE:
  8283. case SC_JAILED:
  8284. case SC_EXPBOOST:
  8285. case SC_ITEMBOOST:
  8286. case SC_HELLPOWER:
  8287. case SC_JEXPBOOST:
  8288. case SC_AUTOTRADE:
  8289. case SC_WHISTLE:
  8290. case SC_ASSNCROS:
  8291. case SC_POEMBRAGI:
  8292. case SC_APPLEIDUN:
  8293. case SC_HUMMING:
  8294. case SC_DONTFORGETME:
  8295. case SC_FORTUNE:
  8296. case SC_SERVICE4U:
  8297. case SC_FOOD_STR_CASH:
  8298. case SC_FOOD_AGI_CASH:
  8299. case SC_FOOD_VIT_CASH:
  8300. case SC_FOOD_DEX_CASH:
  8301. case SC_FOOD_INT_CASH:
  8302. case SC_FOOD_LUK_CASH:
  8303. case SC_DEF_RATE:
  8304. case SC_MDEF_RATE:
  8305. case SC_INCHEALRATE:
  8306. case SC_INCFLEE2:
  8307. case SC_INCHIT:
  8308. case SC_ATKPOTION:
  8309. case SC_MATKPOTION:
  8310. case SC_S_LIFEPOTION:
  8311. case SC_L_LIFEPOTION:
  8312. case SC_PUSH_CART:
  8313. continue;
  8314. }
  8315. if( type == 3 )
  8316. {
  8317. switch (i)
  8318. {// TODO: This list may be incomplete
  8319. case SC_WEIGHT50:
  8320. case SC_WEIGHT90:
  8321. case SC_NOCHAT:
  8322. case SC_PUSH_CART:
  8323. continue;
  8324. }
  8325. }
  8326. status_change_end(bl, (sc_type)i, INVALID_TIMER);
  8327. if( type == 1 && sc->data[i] )
  8328. { //If for some reason status_change_end decides to still keep the status when quitting. [Skotlex]
  8329. (sc->count)--;
  8330. if (sc->data[i]->timer != INVALID_TIMER)
  8331. delete_timer(sc->data[i]->timer, status_change_timer);
  8332. ers_free(sc_data_ers, sc->data[i]);
  8333. sc->data[i] = NULL;
  8334. }
  8335. }
  8336. sc->opt1 = 0;
  8337. sc->opt2 = 0;
  8338. sc->opt3 = 0;
  8339. sc->option &= OPTION_MASK;
  8340. if( type == 0 || type == 2 )
  8341. clif_changeoption(bl);
  8342. return 1;
  8343. }
  8344. /*==========================================
  8345. * Special condition we want to effectuate, check before ending a status.
  8346. *------------------------------------------*/
  8347. int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const char* file, int line)
  8348. {
  8349. struct map_session_data *sd;
  8350. struct status_change *sc;
  8351. struct status_change_entry *sce;
  8352. struct status_data *status;
  8353. struct view_data *vd;
  8354. int opt_flag=0, calc_flag;
  8355. nullpo_ret(bl);
  8356. sc = status_get_sc(bl);
  8357. status = status_get_status_data(bl);
  8358. if(type < 0 || type >= SC_MAX || !sc || !(sce = sc->data[type]))
  8359. return 0;
  8360. sd = BL_CAST(BL_PC,bl);
  8361. if (sce->timer != tid && tid != INVALID_TIMER)
  8362. return 0;
  8363. if (tid == INVALID_TIMER) {
  8364. if (type == SC_ENDURE && sce->val4)
  8365. //Do not end infinite endure.
  8366. return 0;
  8367. if (sce->timer != INVALID_TIMER) //Could be a SC with infinite duration
  8368. delete_timer(sce->timer,status_change_timer);
  8369. if (sc->opt1)
  8370. switch (type) {
  8371. //"Ugly workaround" [Skotlex]
  8372. //delays status change ending so that a skill that sets opt1 fails to
  8373. //trigger when it also removed one
  8374. case SC_STONE:
  8375. sce->val3 = 0; //Petrify time counter.
  8376. case SC_FREEZE:
  8377. case SC_STUN:
  8378. case SC_SLEEP:
  8379. if (sce->val1) {
  8380. //Removing the 'level' shouldn't affect anything in the code
  8381. //since these SC are not affected by it, and it lets us know
  8382. //if we have already delayed this attack or not.
  8383. sce->val1 = 0;
  8384. sce->timer = add_timer(gettick()+10, status_change_timer, bl->id, type);
  8385. return 1;
  8386. }
  8387. }
  8388. }
  8389. (sc->count)--;
  8390. if ( StatusChangeStateTable[type] )
  8391. status_calc_state(bl,sc,( enum scs_flag ) StatusChangeStateTable[type],false);
  8392. sc->data[type] = NULL;
  8393. vd = status_get_viewdata(bl);
  8394. calc_flag = StatusChangeFlagTable[type];
  8395. switch(type){
  8396. case SC_GRANITIC_ARMOR:{
  8397. int dammage = status->max_hp*sce->val3/100;
  8398. if(status->hp < dammage) //to not kill him
  8399. dammage = status->hp-1;
  8400. status_damage(NULL, bl, dammage,0,0,1);
  8401. break;
  8402. }
  8403. case SC_PYROCLASTIC:
  8404. if(bl->type == BL_PC)
  8405. skill_break_equip(bl,EQP_WEAPON,10000,BCT_SELF);
  8406. break;
  8407. case SC_WEDDING:
  8408. case SC_XMAS:
  8409. case SC_SUMMER:
  8410. if (!vd) break;
  8411. if (sd)
  8412. { //Load data from sd->status.* as the stored values could have changed.
  8413. //Must remove OPTION to prevent class being rechanged.
  8414. sc->option &= type==SC_WEDDING?~OPTION_WEDDING:type==SC_XMAS?~OPTION_XMAS:~OPTION_SUMMER;
  8415. clif_changeoption(&sd->bl);
  8416. status_set_viewdata(bl, sd->status.class_);
  8417. } else {
  8418. vd->class_ = sce->val1;
  8419. vd->weapon = sce->val2;
  8420. vd->shield = sce->val3;
  8421. vd->cloth_color = sce->val4;
  8422. }
  8423. clif_changelook(bl,LOOK_BASE,vd->class_);
  8424. clif_changelook(bl,LOOK_CLOTHES_COLOR,vd->cloth_color);
  8425. clif_changelook(bl,LOOK_WEAPON,vd->weapon);
  8426. clif_changelook(bl,LOOK_SHIELD,vd->shield);
  8427. if(sd) clif_skillinfoblock(sd);
  8428. break;
  8429. case SC_RUN:
  8430. {
  8431. struct unit_data *ud = unit_bl2ud(bl);
  8432. bool begin_spurt = true;
  8433. if (ud) {
  8434. if(!ud->state.running)
  8435. begin_spurt = false;
  8436. ud->state.running = 0;
  8437. if (ud->walktimer != INVALID_TIMER)
  8438. unit_stop_walking(bl,1);
  8439. }
  8440. if (begin_spurt && sce->val1 >= 7 &&
  8441. DIFF_TICK(gettick(), sce->val4) <= 1000 &&
  8442. (!sd || (sd->weapontype1 == 0 && sd->weapontype2 == 0))
  8443. )
  8444. sc_start(bl,SC_SPURT,100,sce->val1,skill_get_time2(status_sc2skill(type), sce->val1));
  8445. }
  8446. break;
  8447. case SC_AUTOBERSERK:
  8448. if (sc->data[SC_PROVOKE] && sc->data[SC_PROVOKE]->val2 == 1)
  8449. status_change_end(bl, SC_PROVOKE, INVALID_TIMER);
  8450. break;
  8451. case SC_ENDURE:
  8452. case SC_DEFENDER:
  8453. case SC_REFLECTSHIELD:
  8454. case SC_AUTOGUARD:
  8455. {
  8456. struct map_session_data *tsd;
  8457. if( bl->type == BL_PC )
  8458. { // Clear Status from others
  8459. int i;
  8460. for( i = 0; i < 5; i++ )
  8461. {
  8462. if( sd->devotion[i] && (tsd = map_id2sd(sd->devotion[i])) && tsd->sc.data[type] )
  8463. status_change_end(&tsd->bl, type, INVALID_TIMER);
  8464. }
  8465. }
  8466. else if( bl->type == BL_MER && ((TBL_MER*)bl)->devotion_flag )
  8467. { // Clear Status from Master
  8468. tsd = ((TBL_MER*)bl)->master;
  8469. if( tsd && tsd->sc.data[type] )
  8470. status_change_end(&tsd->bl, type, INVALID_TIMER);
  8471. }
  8472. }
  8473. break;
  8474. case SC_DEVOTION:
  8475. {
  8476. struct block_list *d_bl = map_id2bl(sce->val1);
  8477. if( d_bl )
  8478. {
  8479. if( d_bl->type == BL_PC )
  8480. ((TBL_PC*)d_bl)->devotion[sce->val2] = 0;
  8481. else if( d_bl->type == BL_MER )
  8482. ((TBL_MER*)d_bl)->devotion_flag = 0;
  8483. clif_devotion(d_bl, NULL);
  8484. }
  8485. status_change_end(bl, SC_AUTOGUARD, INVALID_TIMER);
  8486. status_change_end(bl, SC_DEFENDER, INVALID_TIMER);
  8487. status_change_end(bl, SC_REFLECTSHIELD, INVALID_TIMER);
  8488. status_change_end(bl, SC_ENDURE, INVALID_TIMER);
  8489. }
  8490. break;
  8491. case SC_BLADESTOP:
  8492. if(sce->val4)
  8493. {
  8494. int tid = sce->val4;
  8495. struct block_list *tbl = map_id2bl(tid);
  8496. struct status_change *tsc = status_get_sc(tbl);
  8497. sce->val4 = 0;
  8498. if(tbl && tsc && tsc->data[SC_BLADESTOP])
  8499. {
  8500. tsc->data[SC_BLADESTOP]->val4 = 0;
  8501. status_change_end(tbl, SC_BLADESTOP, INVALID_TIMER);
  8502. }
  8503. clif_bladestop(bl, tid, 0);
  8504. }
  8505. break;
  8506. case SC_DANCING:
  8507. {
  8508. const char* prevfile = "<unknown>";
  8509. int prevline = 0;
  8510. struct map_session_data *dsd;
  8511. struct status_change_entry *dsc;
  8512. struct skill_unit_group *group;
  8513. if( sd )
  8514. {
  8515. if( sd->delunit_prevfile )
  8516. {// initially this is NULL, when a character logs in
  8517. prevfile = sd->delunit_prevfile;
  8518. prevline = sd->delunit_prevline;
  8519. }
  8520. else
  8521. {
  8522. prevfile = "<none>";
  8523. }
  8524. sd->delunit_prevfile = file;
  8525. sd->delunit_prevline = line;
  8526. }
  8527. if(sce->val4 && sce->val4 != BCT_SELF && (dsd=map_id2sd(sce->val4)))
  8528. {// end status on partner as well
  8529. dsc = dsd->sc.data[SC_DANCING];
  8530. if(dsc) {
  8531. //This will prevent recursive loops.
  8532. dsc->val2 = dsc->val4 = 0;
  8533. status_change_end(&dsd->bl, SC_DANCING, INVALID_TIMER);
  8534. }
  8535. }
  8536. if(sce->val2)
  8537. {// erase associated land skill
  8538. group = skill_id2group(sce->val2);
  8539. if( group == NULL )
  8540. {
  8541. ShowDebug("status_change_end: SC_DANCING is missing skill unit group (val1=%d, val2=%d, val3=%d, val4=%d, timer=%d, tid=%d, char_id=%d, map=%s, x=%d, y=%d, prev=%s:%d, from=%s:%d). Please report this! (#3504)\n",
  8542. sce->val1, sce->val2, sce->val3, sce->val4, sce->timer, tid,
  8543. sd ? sd->status.char_id : 0,
  8544. mapindex_id2name(map_id2index(bl->m)), bl->x, bl->y,
  8545. prevfile, prevline,
  8546. file, line);
  8547. }
  8548. sce->val2 = 0;
  8549. skill_delunitgroup(group);
  8550. }
  8551. if((sce->val1&0xFFFF) == CG_MOONLIT)
  8552. clif_status_change(bl,SI_MOONLIT,0,0,0,0,0);
  8553. status_change_end(bl, SC_LONGING, INVALID_TIMER);
  8554. }
  8555. break;
  8556. case SC_NOCHAT:
  8557. if (sd && sd->status.manner < 0 && tid != INVALID_TIMER)
  8558. sd->status.manner = 0;
  8559. if (sd && tid == INVALID_TIMER)
  8560. {
  8561. clif_changestatus(sd,SP_MANNER,sd->status.manner);
  8562. clif_updatestatus(sd,SP_MANNER);
  8563. }
  8564. break;
  8565. case SC_SPLASHER:
  8566. {
  8567. struct block_list *src=map_id2bl(sce->val3);
  8568. if(src && tid != INVALID_TIMER)
  8569. skill_castend_damage_id(src, bl, sce->val2, sce->val1, gettick(), SD_LEVEL );
  8570. }
  8571. break;
  8572. case SC_CLOSECONFINE2:
  8573. {
  8574. struct block_list *src = sce->val2?map_id2bl(sce->val2):NULL;
  8575. struct status_change *sc2 = src?status_get_sc(src):NULL;
  8576. if (src && sc2 && sc2->data[SC_CLOSECONFINE]) {
  8577. //If status was already ended, do nothing.
  8578. //Decrease count
  8579. if (--(sc2->data[SC_CLOSECONFINE]->val1) <= 0) //No more holds, free him up.
  8580. status_change_end(src, SC_CLOSECONFINE, INVALID_TIMER);
  8581. }
  8582. }
  8583. case SC_CLOSECONFINE:
  8584. if (sce->val2 > 0) {
  8585. //Caster has been unlocked... nearby chars need to be unlocked.
  8586. int range = 1
  8587. +skill_get_range2(bl, status_sc2skill(type), sce->val1)
  8588. +skill_get_range2(bl, TF_BACKSLIDING, 1); //Since most people use this to escape the hold....
  8589. map_foreachinarea(status_change_timer_sub,
  8590. bl->m, bl->x-range, bl->y-range, bl->x+range,bl->y+range,BL_CHAR,bl,sce,type,gettick());
  8591. }
  8592. break;
  8593. case SC_COMBO:
  8594. if( sd )
  8595. switch (sce->val1) {
  8596. case MO_COMBOFINISH:
  8597. case CH_TIGERFIST:
  8598. case CH_CHAINCRUSH:
  8599. clif_skillinfo(sd, MO_EXTREMITYFIST, 0);
  8600. break;
  8601. case TK_JUMPKICK:
  8602. clif_skillinfo(sd, TK_JUMPKICK, 0);
  8603. break;
  8604. case MO_TRIPLEATTACK:
  8605. if (pc_checkskill(sd, SR_DRAGONCOMBO) > 0)
  8606. clif_skillinfo(sd, SR_DRAGONCOMBO, 0);
  8607. break;
  8608. case SR_FALLENEMPIRE:
  8609. clif_skillinfo(sd, SR_GATEOFHELL, 0);
  8610. clif_skillinfo(sd, SR_TIGERCANNON, 0);
  8611. break;
  8612. }
  8613. break;
  8614. case SC_MARIONETTE:
  8615. case SC_MARIONETTE2: /// Marionette target
  8616. if (sce->val1)
  8617. { // check for partner and end their marionette status as well
  8618. enum sc_type type2 = (type == SC_MARIONETTE) ? SC_MARIONETTE2 : SC_MARIONETTE;
  8619. struct block_list *pbl = map_id2bl(sce->val1);
  8620. struct status_change* sc2 = pbl?status_get_sc(pbl):NULL;
  8621. if (sc2 && sc2->data[type2])
  8622. {
  8623. sc2->data[type2]->val1 = 0;
  8624. status_change_end(pbl, type2, INVALID_TIMER);
  8625. }
  8626. }
  8627. break;
  8628. case SC_BERSERK:
  8629. case SC_SATURDAYNIGHTFEVER:
  8630. //If val2 is removed, no HP penalty (dispelled?) [Skotlex]
  8631. if (status->hp > 100 && sce->val2)
  8632. status_set_hp(bl, 100, 0);
  8633. if(sc->data[SC_ENDURE] && sc->data[SC_ENDURE]->val4 == 2)
  8634. {
  8635. sc->data[SC_ENDURE]->val4 = 0;
  8636. status_change_end(bl, SC_ENDURE, INVALID_TIMER);
  8637. }
  8638. case SC__BLOODYLUST:
  8639. sc_start4(bl, SC_REGENERATION, 100, 10,0,0,(RGN_HP|RGN_SP), skill_get_time(LK_BERSERK, sce->val1));
  8640. if( type == SC_SATURDAYNIGHTFEVER ) //Sit down force of Saturday Night Fever has the duration of only 3 seconds.
  8641. sc_start(bl,SC_SITDOWN_FORCE,100,sce->val1,skill_get_time2(WM_SATURDAY_NIGHT_FEVER,sce->val1));
  8642. break;
  8643. case SC_GOSPEL:
  8644. if (sce->val3) { //Clear the group.
  8645. struct skill_unit_group* group = skill_id2group(sce->val3);
  8646. sce->val3 = 0;
  8647. skill_delunitgroup(group);
  8648. }
  8649. break;
  8650. case SC_HERMODE:
  8651. if(sce->val3 == BCT_SELF)
  8652. skill_clear_unitgroup(bl);
  8653. break;
  8654. case SC_BASILICA: //Clear the skill area. [Skotlex]
  8655. skill_clear_unitgroup(bl);
  8656. break;
  8657. case SC_TRICKDEAD:
  8658. if (vd) vd->dead_sit = 0;
  8659. break;
  8660. case SC_WARM:
  8661. case SC__MANHOLE:
  8662. if (sce->val4) { //Clear the group.
  8663. struct skill_unit_group* group = skill_id2group(sce->val4);
  8664. sce->val4 = 0;
  8665. if( group ) /* might have been cleared before status ended, e.g. land protector */
  8666. skill_delunitgroup(group);
  8667. }
  8668. break;
  8669. case SC_KAAHI:
  8670. //Delete timer if it exists.
  8671. if (sce->val4 != INVALID_TIMER)
  8672. delete_timer(sce->val4,kaahi_heal_timer);
  8673. break;
  8674. case SC_JAILED:
  8675. if(tid == INVALID_TIMER)
  8676. break;
  8677. //natural expiration.
  8678. if(sd && sd->mapindex == sce->val2)
  8679. pc_setpos(sd,(unsigned short)sce->val3,sce->val4&0xFFFF, sce->val4>>16, CLR_TELEPORT);
  8680. break; //guess hes not in jail :P
  8681. case SC_CHANGE:
  8682. if (tid == INVALID_TIMER)
  8683. break;
  8684. // "lose almost all their HP and SP" on natural expiration.
  8685. status_set_hp(bl, 10, 0);
  8686. status_set_sp(bl, 10, 0);
  8687. break;
  8688. case SC_AUTOTRADE:
  8689. if (tid == INVALID_TIMER)
  8690. break;
  8691. // Note: vending/buying is closed by unit_remove_map, no
  8692. // need to do it here.
  8693. map_quit(sd);
  8694. // Because map_quit calls status_change_end with tid -1
  8695. // from here it's not neccesary to continue
  8696. return 1;
  8697. break;
  8698. case SC_STOP:
  8699. if( sce->val2 )
  8700. {
  8701. struct block_list* tbl = map_id2bl(sce->val2);
  8702. sce->val2 = 0;
  8703. if( tbl && (sc = status_get_sc(tbl)) && sc->data[SC_STOP] && sc->data[SC_STOP]->val2 == bl->id )
  8704. status_change_end(tbl, SC_STOP, INVALID_TIMER);
  8705. }
  8706. break;
  8707. /**
  8708. * 3rd Stuff
  8709. **/
  8710. case SC_MILLENNIUMSHIELD:
  8711. clif_millenniumshield(sd,0);
  8712. break;
  8713. case SC_HALLUCINATIONWALK:
  8714. sc_start(bl,SC_HALLUCINATIONWALK_POSTDELAY,100,sce->val1,skill_get_time2(GC_HALLUCINATIONWALK,sce->val1));
  8715. break;
  8716. case SC_WHITEIMPRISON:
  8717. {
  8718. struct block_list* src = map_id2bl(sce->val2);
  8719. if( tid == -1 || !src)
  8720. break; // Terminated by Damage
  8721. status_fix_damage(src,bl,400*sce->val1,clif_damage(bl,bl,gettick(),0,0,400*sce->val1,0,0,0));
  8722. }
  8723. break;
  8724. case SC_WUGDASH:
  8725. {
  8726. struct unit_data *ud = unit_bl2ud(bl);
  8727. if (ud) {
  8728. ud->state.running = 0;
  8729. if (ud->walktimer != -1)
  8730. unit_stop_walking(bl,1);
  8731. }
  8732. }
  8733. break;
  8734. case SC_ADORAMUS:
  8735. status_change_end(bl, SC_BLIND, INVALID_TIMER);
  8736. break;
  8737. case SC__SHADOWFORM: {
  8738. struct map_session_data *s_sd = map_id2sd(sce->val2);
  8739. if( !s_sd )
  8740. break;
  8741. s_sd->shadowform_id = 0;
  8742. }
  8743. break;
  8744. case SC_SITDOWN_FORCE:
  8745. if( sd && pc_issit(sd) ) {
  8746. pc_setstand(sd);
  8747. clif_standing(bl);
  8748. }
  8749. break;
  8750. case SC_NEUTRALBARRIER_MASTER:
  8751. case SC_STEALTHFIELD_MASTER:
  8752. if( sce->val2 ) {
  8753. struct skill_unit_group* group = skill_id2group(sce->val2);
  8754. sce->val2 = 0;
  8755. if( group ) /* might have been cleared before status ended, e.g. land protector */
  8756. skill_delunitgroup(group);
  8757. }
  8758. break;
  8759. case SC_BANDING:
  8760. if(sce->val4) {
  8761. struct skill_unit_group *group = skill_id2group(sce->val4);
  8762. sce->val4 = 0;
  8763. if( group ) /* might have been cleared before status ended, e.g. land protector */
  8764. skill_delunitgroup(group);
  8765. }
  8766. break;
  8767. case SC_CURSEDCIRCLE_ATKER:
  8768. if( sce->val2 ) // used the default area size cause there is a chance the caster could knock back and can't clear the target.
  8769. map_foreachinrange(status_change_timer_sub, bl, battle_config.area_size,BL_CHAR, bl, sce, SC_CURSEDCIRCLE_TARGET, gettick());
  8770. break;
  8771. case SC_RAISINGDRAGON:
  8772. if( sd && sce->val2 && !pc_isdead(sd) ) {
  8773. int i;
  8774. i = min(sd->spiritball,5);
  8775. pc_delspiritball(sd, sd->spiritball, 0);
  8776. status_change_end(bl, SC_EXPLOSIONSPIRITS, INVALID_TIMER);
  8777. while( i > 0 ) {
  8778. pc_addspiritball(sd, skill_get_time(MO_CALLSPIRITS, pc_checkskill(sd,MO_CALLSPIRITS)), 5);
  8779. --i;
  8780. }
  8781. }
  8782. break;
  8783. case SC_CURSEDCIRCLE_TARGET:
  8784. {
  8785. struct block_list *src = map_id2bl(sce->val2);
  8786. struct status_change *sc = status_get_sc(src);
  8787. if( sc && sc->data[SC_CURSEDCIRCLE_ATKER] && --(sc->data[SC_CURSEDCIRCLE_ATKER]->val2) == 0 ){
  8788. status_change_end(src, SC_CURSEDCIRCLE_ATKER, INVALID_TIMER);
  8789. clif_bladestop(bl, sce->val2, 0);
  8790. }
  8791. }
  8792. break;
  8793. case SC_BLOODSUCKER:
  8794. if( sce->val2 ){
  8795. struct block_list *src = map_id2bl(sce->val2);
  8796. if(src){
  8797. struct status_change *sc = status_get_sc(src);
  8798. sc->bs_counter--;
  8799. }
  8800. }
  8801. break;
  8802. case SC_VACUUM_EXTREME:
  8803. if(sc && sc->cant.move > 0) sc->cant.move--;
  8804. break;
  8805. case SC_KYOUGAKU:
  8806. clif_status_load(bl, SI_KYOUGAKU, 0); // Avoid client crash
  8807. clif_status_load(bl, SI_ACTIVE_MONSTER_TRANSFORM, 0);
  8808. break;
  8809. case SC_INTRAVISION:
  8810. calc_flag = SCB_ALL;/* required for overlapping */
  8811. break;
  8812. }
  8813. opt_flag = 1;
  8814. switch(type){
  8815. case SC_STONE:
  8816. case SC_FREEZE:
  8817. case SC_STUN:
  8818. case SC_SLEEP:
  8819. case SC_DEEPSLEEP:
  8820. case SC_BURNING:
  8821. case SC_WHITEIMPRISON:
  8822. case SC_CRYSTALIZE:
  8823. sc->opt1 = 0;
  8824. break;
  8825. case SC_POISON:
  8826. case SC_CURSE:
  8827. case SC_SILENCE:
  8828. case SC_BLIND:
  8829. sc->opt2 &= ~(1<<(type-SC_POISON));
  8830. break;
  8831. case SC_DPOISON:
  8832. sc->opt2 &= ~OPT2_DPOISON;
  8833. break;
  8834. case SC_SIGNUMCRUCIS:
  8835. sc->opt2 &= ~OPT2_SIGNUMCRUCIS;
  8836. break;
  8837. case SC_HIDING:
  8838. sc->option &= ~OPTION_HIDE;
  8839. opt_flag|= 2|4; //Check for warp trigger + AoE trigger
  8840. break;
  8841. case SC_CLOAKING:
  8842. case SC_CLOAKINGEXCEED:
  8843. case SC__INVISIBILITY:
  8844. sc->option &= ~OPTION_CLOAK;
  8845. case SC_CAMOUFLAGE:
  8846. opt_flag|= 2;
  8847. break;
  8848. case SC_CHASEWALK:
  8849. sc->option &= ~(OPTION_CHASEWALK|OPTION_CLOAK);
  8850. opt_flag|= 2;
  8851. break;
  8852. case SC_SIGHT:
  8853. sc->option &= ~OPTION_SIGHT;
  8854. break;
  8855. case SC_WEDDING:
  8856. sc->option &= ~OPTION_WEDDING;
  8857. break;
  8858. case SC_XMAS:
  8859. sc->option &= ~OPTION_XMAS;
  8860. break;
  8861. case SC_SUMMER:
  8862. sc->option &= ~OPTION_SUMMER;
  8863. break;
  8864. case SC_ORCISH:
  8865. sc->option &= ~OPTION_ORCISH;
  8866. break;
  8867. case SC_RUWACH:
  8868. sc->option &= ~OPTION_RUWACH;
  8869. break;
  8870. case SC_FUSION:
  8871. sc->option &= ~OPTION_FLYING;
  8872. break;
  8873. //opt3
  8874. case SC_TWOHANDQUICKEN:
  8875. case SC_ONEHAND:
  8876. case SC_SPEARQUICKEN:
  8877. case SC_CONCENTRATION:
  8878. case SC_MERC_QUICKEN:
  8879. sc->opt3 &= ~OPT3_QUICKEN;
  8880. opt_flag = 0;
  8881. break;
  8882. case SC_OVERTHRUST:
  8883. case SC_MAXOVERTHRUST:
  8884. case SC_SWOO:
  8885. sc->opt3 &= ~OPT3_OVERTHRUST;
  8886. if( type == SC_SWOO )
  8887. opt_flag = 8;
  8888. else
  8889. opt_flag = 0;
  8890. break;
  8891. case SC_ENERGYCOAT:
  8892. case SC_SKE:
  8893. sc->opt3 &= ~OPT3_ENERGYCOAT;
  8894. opt_flag = 0;
  8895. break;
  8896. case SC_INCATKRATE: //Simulated Explosion spirits effect.
  8897. if (bl->type != BL_MOB)
  8898. {
  8899. opt_flag = 0;
  8900. break;
  8901. }
  8902. case SC_EXPLOSIONSPIRITS:
  8903. sc->opt3 &= ~OPT3_EXPLOSIONSPIRITS;
  8904. opt_flag = 0;
  8905. break;
  8906. case SC_STEELBODY:
  8907. case SC_SKA:
  8908. sc->opt3 &= ~OPT3_STEELBODY;
  8909. opt_flag = 0;
  8910. break;
  8911. case SC_BLADESTOP:
  8912. sc->opt3 &= ~OPT3_BLADESTOP;
  8913. opt_flag = 0;
  8914. break;
  8915. case SC_AURABLADE:
  8916. sc->opt3 &= ~OPT3_AURABLADE;
  8917. opt_flag = 0;
  8918. break;
  8919. case SC_BERSERK:
  8920. opt_flag = 0;
  8921. // case SC__BLOODYLUST:
  8922. sc->opt3 &= ~OPT3_BERSERK;
  8923. break;
  8924. // case ???: // doesn't seem to do anything
  8925. // sc->opt3 &= ~OPT3_LIGHTBLADE;
  8926. // opt_flag = 0;
  8927. // break;
  8928. case SC_DANCING:
  8929. if ((sce->val1&0xFFFF) == CG_MOONLIT)
  8930. sc->opt3 &= ~OPT3_MOONLIT;
  8931. opt_flag = 0;
  8932. break;
  8933. case SC_MARIONETTE:
  8934. case SC_MARIONETTE2:
  8935. sc->opt3 &= ~OPT3_MARIONETTE;
  8936. opt_flag = 0;
  8937. break;
  8938. case SC_ASSUMPTIO:
  8939. sc->opt3 &= ~OPT3_ASSUMPTIO;
  8940. opt_flag = 0;
  8941. break;
  8942. case SC_WARM: //SG skills [Komurka]
  8943. sc->opt3 &= ~OPT3_WARM;
  8944. opt_flag = 0;
  8945. break;
  8946. case SC_KAITE:
  8947. sc->opt3 &= ~OPT3_KAITE;
  8948. opt_flag = 0;
  8949. break;
  8950. case SC_BUNSINJYUTSU:
  8951. sc->opt3 &= ~OPT3_BUNSIN;
  8952. opt_flag = 0;
  8953. break;
  8954. case SC_SPIRIT:
  8955. sc->opt3 &= ~OPT3_SOULLINK;
  8956. opt_flag = 0;
  8957. break;
  8958. case SC_CHANGEUNDEAD:
  8959. sc->opt3 &= ~OPT3_UNDEAD;
  8960. opt_flag = 0;
  8961. break;
  8962. // case ???: // from DA_CONTRACT (looks like biolab mobs aura)
  8963. // sc->opt3 &= ~OPT3_CONTRACT;
  8964. // opt_flag = 0;
  8965. // break;
  8966. default:
  8967. opt_flag = 0;
  8968. }
  8969. if (calc_flag&SCB_DYE)
  8970. { //Restore DYE color
  8971. if (vd && !vd->cloth_color && sce->val4)
  8972. clif_changelook(bl,LOOK_CLOTHES_COLOR,sce->val4);
  8973. calc_flag&=~SCB_DYE;
  8974. }
  8975. //On Aegis, when turning off a status change, first goes the sc packet, then the option packet.
  8976. clif_status_change(bl,StatusIconChangeTable[type],0,0,0,0,0);
  8977. if( opt_flag&8 ) //bugreport:681
  8978. clif_changeoption2(bl);
  8979. else if(opt_flag)
  8980. clif_changeoption(bl);
  8981. if (calc_flag)
  8982. status_calc_bl(bl,calc_flag);
  8983. if(opt_flag&4) //Out of hiding, invoke on place.
  8984. skill_unit_move(bl,gettick(),1);
  8985. if(opt_flag&2 && sd && map_getcell(bl->m,bl->x,bl->y,CELL_CHKNPC))
  8986. npc_touch_areanpc(sd,bl->m,bl->x,bl->y); //Trigger on-touch event.
  8987. ers_free(sc_data_ers, sce);
  8988. return 1;
  8989. }
  8990. int kaahi_heal_timer(int tid, unsigned int tick, int id, intptr_t data)
  8991. {
  8992. struct block_list *bl;
  8993. struct status_change *sc;
  8994. struct status_change_entry *sce;
  8995. struct status_data *status;
  8996. int hp;
  8997. if(!((bl=map_id2bl(id))&&
  8998. (sc=status_get_sc(bl)) &&
  8999. (sce = sc->data[SC_KAAHI])))
  9000. return 0;
  9001. if(sce->val4 != tid) {
  9002. ShowError("kaahi_heal_timer: Timer mismatch: %d != %d\n", tid, sce->val4);
  9003. sce->val4 = INVALID_TIMER;
  9004. return 0;
  9005. }
  9006. status=status_get_status_data(bl);
  9007. if(!status_charge(bl, 0, sce->val3)) {
  9008. sce->val4 = INVALID_TIMER;
  9009. return 0;
  9010. }
  9011. hp = status->max_hp - status->hp;
  9012. if (hp > sce->val2)
  9013. hp = sce->val2;
  9014. if (hp)
  9015. status_heal(bl, hp, 0, 2);
  9016. sce->val4 = INVALID_TIMER;
  9017. return 1;
  9018. }
  9019. /*==========================================
  9020. * For recusive status, like for each 5s we drop sp etc.
  9021. * Reseting the end timer.
  9022. *------------------------------------------*/
  9023. int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
  9024. {
  9025. enum sc_type type = (sc_type)data;
  9026. struct block_list *bl;
  9027. struct map_session_data *sd;
  9028. struct status_data *status;
  9029. struct status_change *sc;
  9030. struct status_change_entry *sce;
  9031. bl = map_id2bl(id);
  9032. if(!bl)
  9033. {
  9034. ShowDebug("status_change_timer: Null pointer id: %d data: %d\n", id, data);
  9035. return 0;
  9036. }
  9037. sc = status_get_sc(bl);
  9038. status = status_get_status_data(bl);
  9039. if(!(sc && (sce = sc->data[type])))
  9040. {
  9041. ShowDebug("status_change_timer: Null pointer id: %d data: %d bl-type: %d\n", id, data, bl->type);
  9042. return 0;
  9043. }
  9044. if( sce->timer != tid )
  9045. {
  9046. ShowError("status_change_timer: Mismatch for type %d: %d != %d (bl id %d)\n",type,tid,sce->timer, bl->id);
  9047. return 0;
  9048. }
  9049. sd = BL_CAST(BL_PC, bl);
  9050. // set the next timer of the sce (don't assume the status still exists)
  9051. #define sc_timer_next(t,f,i,d) \
  9052. if( (sce=sc->data[type]) ) \
  9053. sce->timer = add_timer(t,f,i,d); \
  9054. else \
  9055. ShowError("status_change_timer: Unexpected NULL status change id: %d data: %d\n", id, data)
  9056. switch(type)
  9057. {
  9058. case SC_MAXIMIZEPOWER:
  9059. case SC_CLOAKING:
  9060. if(!status_charge(bl, 0, 1))
  9061. break; //Not enough SP to continue.
  9062. sc_timer_next(sce->val2+tick, status_change_timer, bl->id, data);
  9063. return 0;
  9064. case SC_CHASEWALK:
  9065. if(!status_charge(bl, 0, sce->val4))
  9066. break; //Not enough SP to continue.
  9067. if (!sc->data[SC_INCSTR]) {
  9068. sc_start(bl, SC_INCSTR,100,1<<(sce->val1-1),
  9069. (sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_ROGUE?10:1) //SL bonus -> x10 duration
  9070. *skill_get_time2(status_sc2skill(type),sce->val1));
  9071. }
  9072. sc_timer_next(sce->val2+tick, status_change_timer, bl->id, data);
  9073. return 0;
  9074. break;
  9075. case SC_SKA:
  9076. if(--(sce->val2)>0){
  9077. sce->val3 = rnd()%100; //Random defense.
  9078. sc_timer_next(1000+tick, status_change_timer,bl->id, data);
  9079. return 0;
  9080. }
  9081. break;
  9082. case SC_HIDING:
  9083. if(--(sce->val2)>0){
  9084. if(sce->val2 % sce->val4 == 0 && !status_charge(bl, 0, 1))
  9085. break; //Fail if it's time to substract SP and there isn't.
  9086. sc_timer_next(1000+tick, status_change_timer,bl->id, data);
  9087. return 0;
  9088. }
  9089. break;
  9090. case SC_SIGHT:
  9091. case SC_RUWACH:
  9092. case SC_SIGHTBLASTER:
  9093. if(type == SC_SIGHTBLASTER)
  9094. map_foreachinrange( status_change_timer_sub, bl, sce->val3, BL_CHAR|BL_SKILL, bl, sce, type, tick);
  9095. else
  9096. map_foreachinrange( status_change_timer_sub, bl, sce->val3, BL_CHAR, bl, sce, type, tick);
  9097. if( --(sce->val2)>0 ){
  9098. sce->val4 += 250; // use for Shadow Form 2 seconds checking.
  9099. sc_timer_next(250+tick, status_change_timer, bl->id, data);
  9100. return 0;
  9101. }
  9102. break;
  9103. case SC_PROVOKE:
  9104. if(sce->val2) { //Auto-provoke (it is ended in status_heal)
  9105. sc_timer_next(1000*60+tick,status_change_timer, bl->id, data );
  9106. return 0;
  9107. }
  9108. break;
  9109. case SC_STONE:
  9110. if(sc->opt1 == OPT1_STONEWAIT && sce->val3) {
  9111. sce->val4 = 0;
  9112. unit_stop_walking(bl,1);
  9113. unit_stop_attack(bl);
  9114. sc->opt1 = OPT1_STONE;
  9115. clif_changeoption(bl);
  9116. sc_timer_next(1000+tick,status_change_timer, bl->id, data );
  9117. status_calc_bl(bl, StatusChangeFlagTable[type]);
  9118. return 0;
  9119. }
  9120. if(--(sce->val3) > 0) {
  9121. if(++(sce->val4)%5 == 0 && status->hp > status->max_hp/4)
  9122. status_percent_damage(NULL, bl, 1, 0, false);
  9123. sc_timer_next(1000+tick,status_change_timer, bl->id, data );
  9124. return 0;
  9125. }
  9126. break;
  9127. case SC_POISON:
  9128. if(status->hp <= max(status->max_hp>>2, sce->val4)) //Stop damaging after 25% HP left.
  9129. break;
  9130. case SC_DPOISON:
  9131. if (--(sce->val3) > 0) {
  9132. if (!sc->data[SC_SLOWPOISON]) {
  9133. if( sce->val2 && bl->type == BL_MOB ) {
  9134. struct block_list* src = map_id2bl(sce->val2);
  9135. if( src )
  9136. mob_log_damage((TBL_MOB*)bl,src,sce->val4);
  9137. }
  9138. map_freeblock_lock();
  9139. status_zap(bl, sce->val4, 0);
  9140. if (sc->data[type]) { // Check if the status still last ( can be dead since then ).
  9141. sc_timer_next(1000 + tick, status_change_timer, bl->id, data );
  9142. }
  9143. map_freeblock_unlock();
  9144. }
  9145. return 0;
  9146. }
  9147. break;
  9148. case SC_TENSIONRELAX:
  9149. if(status->max_hp > status->hp && --(sce->val3) > 0){
  9150. sc_timer_next(sce->val4+tick, status_change_timer, bl->id, data);
  9151. return 0;
  9152. }
  9153. break;
  9154. case SC_KNOWLEDGE:
  9155. if (!sd) break;
  9156. if(bl->m == sd->feel_map[0].m ||
  9157. bl->m == sd->feel_map[1].m ||
  9158. bl->m == sd->feel_map[2].m)
  9159. { //Timeout will be handled by pc_setpos
  9160. sce->timer = INVALID_TIMER;
  9161. return 0;
  9162. }
  9163. break;
  9164. case SC_BLEEDING:
  9165. if (--(sce->val4) >= 0) {
  9166. int hp = rnd()%600 + 200;
  9167. struct block_list* src = map_id2bl(sce->val2);
  9168. map_freeblock_lock();
  9169. status_fix_damage(src, bl, sd||hp<status->hp?hp:status->hp-1, 1);
  9170. if( sc->data[type] ) {
  9171. if( status->hp == 1 ) {
  9172. map_freeblock_unlock();
  9173. break;
  9174. }
  9175. sc_timer_next(10000 + tick, status_change_timer, bl->id, data);
  9176. }
  9177. map_freeblock_unlock();
  9178. return 0;
  9179. }
  9180. break;
  9181. case SC_S_LIFEPOTION:
  9182. case SC_L_LIFEPOTION:
  9183. if( sd && --(sce->val4) >= 0 )
  9184. {
  9185. // val1 < 0 = per max% | val1 > 0 = exact amount
  9186. int hp = 0;
  9187. if( status->hp < status->max_hp )
  9188. hp = (sce->val1 < 0) ? (int)(sd->status.max_hp * -1 * sce->val1 / 100.) : sce->val1 ;
  9189. status_heal(bl, hp, 0, 2);
  9190. sc_timer_next((sce->val2 * 1000) + tick, status_change_timer, bl->id, data);
  9191. return 0;
  9192. }
  9193. break;
  9194. case SC_BOSSMAPINFO:
  9195. if( sd && --(sce->val4) >= 0 )
  9196. {
  9197. struct mob_data *boss_md = map_id2boss(sce->val1);
  9198. if( boss_md && sd->bl.m == boss_md->bl.m )
  9199. {
  9200. clif_bossmapinfo(sd->fd, boss_md, 1); // Update X - Y on minimap
  9201. if (boss_md->bl.prev != NULL) {
  9202. sc_timer_next(5000 + tick, status_change_timer, bl->id, data);
  9203. return 0;
  9204. }
  9205. }
  9206. }
  9207. break;
  9208. case SC_DANCING: //SP consumption by time of dancing skills
  9209. {
  9210. int s = 0;
  9211. int sp = 1;
  9212. if (--sce->val3 <= 0)
  9213. break;
  9214. switch(sce->val1&0xFFFF){
  9215. case BD_RICHMANKIM:
  9216. case BD_DRUMBATTLEFIELD:
  9217. case BD_RINGNIBELUNGEN:
  9218. case BD_SIEGFRIED:
  9219. case BA_DISSONANCE:
  9220. case BA_ASSASSINCROSS:
  9221. case DC_UGLYDANCE:
  9222. s=3;
  9223. break;
  9224. case BD_LULLABY:
  9225. case BD_ETERNALCHAOS:
  9226. case BD_ROKISWEIL:
  9227. case DC_FORTUNEKISS:
  9228. s=4;
  9229. break;
  9230. case CG_HERMODE:
  9231. case BD_INTOABYSS:
  9232. case BA_WHISTLE:
  9233. case DC_HUMMING:
  9234. case BA_POEMBRAGI:
  9235. case DC_SERVICEFORYOU:
  9236. s=5;
  9237. break;
  9238. case BA_APPLEIDUN:
  9239. #ifdef RENEWAL
  9240. s=5;
  9241. #else
  9242. s=6;
  9243. #endif
  9244. break;
  9245. case CG_MOONLIT:
  9246. //Moonlit's cost is 4sp*skill_lv [Skotlex]
  9247. sp= 4*(sce->val1>>16);
  9248. //Upkeep is also every 10 secs.
  9249. case DC_DONTFORGETME:
  9250. s=10;
  9251. break;
  9252. }
  9253. if( s != 0 && sce->val3 % s == 0 )
  9254. {
  9255. if (sc->data[SC_LONGING])
  9256. sp*= 3;
  9257. if (!status_charge(bl, 0, sp))
  9258. break;
  9259. }
  9260. sc_timer_next(1000+tick, status_change_timer, bl->id, data);
  9261. return 0;
  9262. }
  9263. break;
  9264. case SC__BLOODYLUST:
  9265. case SC_BERSERK:
  9266. // 5% every 10 seconds [DracoRPG]
  9267. if( --( sce->val3 ) > 0 && status_charge(bl, sce->val2, 0) && status->hp > 100 )
  9268. {
  9269. sc_timer_next(sce->val4+tick, status_change_timer, bl->id, data);
  9270. return 0;
  9271. }
  9272. break;
  9273. case SC_NOCHAT:
  9274. if(sd){
  9275. sd->status.manner++;
  9276. clif_changestatus(sd,SP_MANNER,sd->status.manner);
  9277. clif_updatestatus(sd,SP_MANNER);
  9278. if (sd->status.manner < 0)
  9279. { //Every 60 seconds your manner goes up by 1 until it gets back to 0.
  9280. sc_timer_next(60000+tick, status_change_timer, bl->id, data);
  9281. return 0;
  9282. }
  9283. }
  9284. break;
  9285. case SC_SPLASHER:
  9286. // custom Venom Splasher countdown timer
  9287. //if (sce->val4 % 1000 == 0) {
  9288. // char timer[10];
  9289. // snprintf (timer, 10, "%d", sce->val4/1000);
  9290. // clif_message(bl, timer);
  9291. //}
  9292. if((sce->val4 -= 500) > 0) {
  9293. sc_timer_next(500 + tick, status_change_timer, bl->id, data);
  9294. return 0;
  9295. }
  9296. break;
  9297. case SC_MARIONETTE:
  9298. case SC_MARIONETTE2:
  9299. {
  9300. struct block_list *pbl = map_id2bl(sce->val1);
  9301. if( pbl && check_distance_bl(bl, pbl, 7) )
  9302. {
  9303. sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
  9304. return 0;
  9305. }
  9306. }
  9307. break;
  9308. case SC_GOSPEL:
  9309. if(sce->val4 == BCT_SELF && --(sce->val2) > 0)
  9310. {
  9311. int hp, sp;
  9312. hp = (sce->val1 > 5) ? 45 : 30;
  9313. sp = (sce->val1 > 5) ? 35 : 20;
  9314. if(!status_charge(bl, hp, sp))
  9315. break;
  9316. sc_timer_next(10000+tick, status_change_timer, bl->id, data);
  9317. return 0;
  9318. }
  9319. break;
  9320. case SC_JAILED:
  9321. if(sce->val1 == INT_MAX || --(sce->val1) > 0)
  9322. {
  9323. sc_timer_next(60000+tick, status_change_timer, bl->id,data);
  9324. return 0;
  9325. }
  9326. break;
  9327. case SC_BLIND:
  9328. if(sc->data[SC_FOGWALL])
  9329. { //Blind lasts forever while you are standing on the fog.
  9330. sc_timer_next(5000+tick, status_change_timer, bl->id, data);
  9331. return 0;
  9332. }
  9333. break;
  9334. case SC_ABUNDANCE:
  9335. if(--(sce->val4) > 0) {
  9336. status_heal(bl,0,60,0);
  9337. sc_timer_next(10000+tick, status_change_timer, bl->id, data);
  9338. }
  9339. break;
  9340. case SC_PYREXIA:
  9341. if( --(sce->val4) >= 0 ) {
  9342. map_freeblock_lock();
  9343. clif_damage(bl,bl,tick,status_get_amotion(bl),status_get_dmotion(bl)+500,100,0,0,0);
  9344. status_fix_damage(NULL,bl,100,0);
  9345. if( sc->data[type] ) {
  9346. sc_timer_next(3000+tick,status_change_timer,bl->id,data);
  9347. }
  9348. map_freeblock_unlock();
  9349. return 0;
  9350. }
  9351. break;
  9352. case SC_LEECHESEND:
  9353. if( --(sce->val4) >= 0 ) {
  9354. int damage = status->max_hp/100; // {Target VIT x (New Poison Research Skill Level - 3)} + (Target HP/100)
  9355. damage += status->vit * (sce->val1 - 3);
  9356. unit_skillcastcancel(bl,2);
  9357. map_freeblock_lock();
  9358. status_damage(bl, bl, damage, 0, clif_damage(bl,bl,tick,status_get_amotion(bl),status_get_dmotion(bl)+500,damage,1,0,0), 1);
  9359. if( sc->data[type] ) {
  9360. sc_timer_next(1000 + tick, status_change_timer, bl->id, data );
  9361. }
  9362. map_freeblock_unlock();
  9363. return 0;
  9364. }
  9365. break;
  9366. case SC_MAGICMUSHROOM:
  9367. if( --(sce->val4) >= 0 ) {
  9368. bool flag = 0;
  9369. int damage = status->max_hp * 3 / 100;
  9370. if( status->hp <= damage )
  9371. damage = status->hp - 1; // Cannot Kill
  9372. if( damage > 0 ) { // 3% Damage each 4 seconds
  9373. map_freeblock_lock();
  9374. status_zap(bl,damage,0);
  9375. flag = !sc->data[type]; // Killed? Should not
  9376. map_freeblock_unlock();
  9377. }
  9378. if( !flag ) { // Random Skill Cast
  9379. if (sd && !pc_issit(sd)) { //can't cast if sit
  9380. int mushroom_skill_id = 0, i;
  9381. unit_stop_attack(bl);
  9382. unit_skillcastcancel(bl,1);
  9383. do {
  9384. i = rnd() % MAX_SKILL_MAGICMUSHROOM_DB;
  9385. mushroom_skill_id = skill_magicmushroom_db[i].skill_id;
  9386. }
  9387. while( mushroom_skill_id == 0 );
  9388. switch( skill_get_casttype(mushroom_skill_id) ) { // Magic Mushroom skills are buffs or area damage
  9389. case CAST_GROUND:
  9390. skill_castend_pos2(bl,bl->x,bl->y,mushroom_skill_id,1,tick,0);
  9391. break;
  9392. case CAST_NODAMAGE:
  9393. skill_castend_nodamage_id(bl,bl,mushroom_skill_id,1,tick,0);
  9394. break;
  9395. case CAST_DAMAGE:
  9396. skill_castend_damage_id(bl,bl,mushroom_skill_id,1,tick,0);
  9397. break;
  9398. }
  9399. }
  9400. clif_emotion(bl,E_HEH);
  9401. sc_timer_next(4000+tick,status_change_timer,bl->id,data);
  9402. }
  9403. return 0;
  9404. }
  9405. break;
  9406. case SC_TOXIN:
  9407. if( --(sce->val4) >= 0 )
  9408. { //Damage is every 10 seconds including 3%sp drain.
  9409. map_freeblock_lock();
  9410. clif_damage(bl,bl,tick,status_get_amotion(bl),1,1,0,0,0);
  9411. status_damage(NULL, bl, 1, status->max_sp * 3 / 100, 0, 0); //cancel dmg only if cancelable
  9412. if( sc->data[type] ) {
  9413. sc_timer_next(10000 + tick, status_change_timer, bl->id, data );
  9414. }
  9415. map_freeblock_unlock();
  9416. return 0;
  9417. }
  9418. break;
  9419. case SC_OBLIVIONCURSE:
  9420. if( --(sce->val4) >= 0 )
  9421. {
  9422. clif_emotion(bl,E_WHAT);
  9423. sc_timer_next(3000 + tick, status_change_timer, bl->id, data );
  9424. return 0;
  9425. }
  9426. break;
  9427. case SC_WEAPONBLOCKING:
  9428. if( --(sce->val4) >= 0 )
  9429. {
  9430. if( !status_charge(bl,0,3) )
  9431. break;
  9432. sc_timer_next(3000+tick,status_change_timer,bl->id,data);
  9433. return 0;
  9434. }
  9435. break;
  9436. case SC_CLOAKINGEXCEED:
  9437. if(!status_charge(bl,0,10-sce->val1))
  9438. break;
  9439. sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
  9440. return 0;
  9441. case SC_RENOVATIO:
  9442. if( --(sce->val4) >= 0 )
  9443. {
  9444. int heal = status->max_hp * 3 / 100;
  9445. if( sc && sc->data[SC_AKAITSUKI] && heal )
  9446. heal = ~heal + 1;
  9447. status_heal(bl, heal, 0, 2);
  9448. sc_timer_next(5000 + tick, status_change_timer, bl->id, data);
  9449. return 0;
  9450. }
  9451. break;
  9452. case SC_BURNING:
  9453. if( --(sce->val4) >= 0 )
  9454. {
  9455. struct block_list *src = map_id2bl(sce->val3);
  9456. int damage = 1000 + 3 * status_get_max_hp(bl) / 100; // Deals fixed (1000 + 3%*MaxHP)
  9457. map_freeblock_lock();
  9458. clif_damage(bl,bl,tick,0,0,damage,1,9,0); //damage is like endure effect with no walk delay
  9459. status_damage(src, bl, damage, 0, 0, 1);
  9460. if( sc->data[type]){ // Target still lives. [LimitLine]
  9461. sc_timer_next(2000 + tick, status_change_timer, bl->id, data);
  9462. }
  9463. map_freeblock_unlock();
  9464. return 0;
  9465. }
  9466. break;
  9467. case SC_FEAR:
  9468. if( --(sce->val4) >= 0 )
  9469. {
  9470. if( sce->val2 > 0 )
  9471. sce->val2--;
  9472. sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
  9473. return 0;
  9474. }
  9475. break;
  9476. case SC_SPHERE_1:
  9477. case SC_SPHERE_2:
  9478. case SC_SPHERE_3:
  9479. case SC_SPHERE_4:
  9480. case SC_SPHERE_5:
  9481. if( --(sce->val4) >= 0 )
  9482. {
  9483. if( !status_charge(bl, 0, 1) )
  9484. break;
  9485. sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
  9486. return 0;
  9487. }
  9488. break;
  9489. case SC_READING_SB:
  9490. if( !status_charge(bl, 0, sce->val2) ){
  9491. int i;
  9492. for(i = SC_SPELLBOOK1; i <= SC_MAXSPELLBOOK; i++) // Also remove stored spell as well.
  9493. status_change_end(bl, (sc_type)i, INVALID_TIMER);
  9494. break;
  9495. }
  9496. sc_timer_next(5000 + tick, status_change_timer, bl->id, data);
  9497. return 0;
  9498. case SC_ELECTRICSHOCKER:
  9499. if( --(sce->val4) >= 0 )
  9500. {
  9501. status_charge(bl, 0, status->max_sp / 100 * sce->val1 );
  9502. sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
  9503. return 0;
  9504. }
  9505. break;
  9506. case SC_CAMOUFLAGE:
  9507. if(--(sce->val4) > 0){
  9508. status_charge(bl,0,7 - sce->val1);
  9509. sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
  9510. return 0;
  9511. }
  9512. break;
  9513. case SC__REPRODUCE:
  9514. if(!status_charge(bl, 0, 1))
  9515. break;
  9516. sc_timer_next(1000+tick, status_change_timer, bl->id, data);
  9517. return 0;
  9518. case SC__SHADOWFORM:
  9519. if( --(sce->val4) >= 0 )
  9520. {
  9521. if( !status_charge(bl, 0, sce->val1 - (sce->val1 - 1)) )
  9522. break;
  9523. sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
  9524. return 0;
  9525. }
  9526. break;
  9527. case SC__INVISIBILITY:
  9528. if( --(sce->val4) >= 0 )
  9529. {
  9530. if( !status_charge(bl, 0, (status->sp * 6 - sce->val1) / 100) )// 6% - skill_lv.
  9531. break;
  9532. sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
  9533. return 0;
  9534. }
  9535. break;
  9536. case SC_STRIKING:
  9537. if( --(sce->val4) >= 0 )
  9538. {
  9539. if( !status_charge(bl,0, sce->val1 ) )
  9540. break;
  9541. sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
  9542. return 0;
  9543. }
  9544. break;
  9545. case SC_VACUUM_EXTREME:
  9546. if( --(sce->val4) >= 0 ){
  9547. if( !unit_is_walking(bl) && !sce->val2 ){
  9548. sc->cant.move++;
  9549. sce->val2 = 1;
  9550. }
  9551. sc_timer_next(100 + tick, status_change_timer, bl->id, data);
  9552. return 0;
  9553. }
  9554. break;
  9555. case SC_BLOODSUCKER:
  9556. if( --(sce->val4) >= 0 ) {
  9557. struct block_list *src = map_id2bl(sce->val2);
  9558. int damage;
  9559. if( !src || (src && (status_isdead(src) || src->m != bl->m || distance_bl(src, bl) >= 12)) )
  9560. break;
  9561. map_freeblock_lock();
  9562. damage = 200 + 100 * sce->val1 + status_get_int(src);
  9563. status_damage(src, bl, damage, 0, clif_damage(bl,bl,tick,status->amotion,status->dmotion+200,damage,1,0,0), 1);
  9564. unit_skillcastcancel(bl,1);
  9565. if ( sc->data[type] ) {
  9566. sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
  9567. }
  9568. map_freeblock_unlock();
  9569. status_heal(src, damage*(5 + 5 * sce->val1)/100, 0, 0); // 5 + 5% per level
  9570. return 0;
  9571. }
  9572. break;
  9573. case SC_VOICEOFSIREN:
  9574. if( --(sce->val4) >= 0 )
  9575. {
  9576. clif_emotion(bl,E_LV);
  9577. sc_timer_next(2000 + tick, status_change_timer, bl->id, data);
  9578. return 0;
  9579. }
  9580. break;
  9581. case SC_DEEPSLEEP:
  9582. if( --(sce->val4) >= 0 )
  9583. { // Recovers 1% HP/SP every 2 seconds.
  9584. status_heal(bl, status->max_hp / 100, status->max_sp / 100, 2);
  9585. sc_timer_next(2000 + tick, status_change_timer, bl->id, data);
  9586. return 0;
  9587. }
  9588. break;
  9589. case SC_SIRCLEOFNATURE:
  9590. if( --(sce->val4) >= 0 )
  9591. {
  9592. if( !status_charge(bl,0,sce->val2) )
  9593. break;
  9594. status_heal(bl, sce->val3, 0, 1);
  9595. sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
  9596. return 0;
  9597. }
  9598. break;
  9599. case SC_SONGOFMANA:
  9600. if( --(sce->val4) >= 0 )
  9601. {
  9602. status_heal(bl,0,sce->val3,3);
  9603. sc_timer_next(3000 + tick, status_change_timer, bl->id, data);
  9604. return 0;
  9605. }
  9606. break;
  9607. case SC_SATURDAYNIGHTFEVER:
  9608. // 1% HP/SP drain every val4 seconds [Jobbie]
  9609. if( --(sce->val3) >= 0 )
  9610. {
  9611. int hp = status->hp / 100;
  9612. int sp = status->sp / 100;
  9613. if( !status_charge(bl, hp, sp) )
  9614. break;
  9615. sc_timer_next(sce->val4+tick, status_change_timer, bl->id, data);
  9616. return 0;
  9617. }
  9618. break;
  9619. case SC_CRYSTALIZE:
  9620. if( --(sce->val4) >= 0 )
  9621. { // Drains 2% of HP and 1% of SP every seconds.
  9622. if( bl->type != BL_MOB) // doesn't work on mobs
  9623. status_charge(bl, status->max_hp * 2 / 100, status->max_sp / 100);
  9624. sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
  9625. return 0;
  9626. }
  9627. break;
  9628. case SC_FORCEOFVANGUARD:
  9629. if( !status_charge(bl,0,20) )
  9630. break;
  9631. sc_timer_next(6000 + tick, status_change_timer, bl->id, data);
  9632. return 0;
  9633. case SC_BANDING:
  9634. if( status_charge(bl, 0, 7 - sce->val1) )
  9635. {
  9636. if( sd ) pc_banding(sd, sce->val1);
  9637. sc_timer_next(5000 + tick, status_change_timer, bl->id, data);
  9638. return 0;
  9639. }
  9640. break;
  9641. case SC_REFLECTDAMAGE:
  9642. if( --(sce->val4) >= 0 ) {
  9643. if( !status_charge(bl,0,sce->val3) )
  9644. break;
  9645. sc_timer_next(10000 + tick, status_change_timer, bl->id, data);
  9646. return 0;
  9647. }
  9648. break;
  9649. case SC_OVERHEAT_LIMITPOINT:
  9650. if( --(sce->val1) > 0 ) { // Cooling
  9651. sc_timer_next(30000 + tick, status_change_timer, bl->id, data);
  9652. }
  9653. break;
  9654. case SC_OVERHEAT:
  9655. {
  9656. int damage = status->max_hp / 100; // Suggestion 1% each second
  9657. if( damage >= status->hp ) damage = status->hp - 1; // Do not kill, just keep you with 1 hp minimum
  9658. map_freeblock_lock();
  9659. status_fix_damage(NULL,bl,damage,clif_damage(bl,bl,tick,0,0,damage,0,0,0));
  9660. if( sc->data[type] ) {
  9661. sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
  9662. }
  9663. map_freeblock_unlock();
  9664. }
  9665. break;
  9666. case SC_MAGNETICFIELD:
  9667. {
  9668. if( --(sce->val3) <= 0 )
  9669. break; // Time out
  9670. if( sce->val2 == bl->id )
  9671. {
  9672. if( !status_charge(bl,0,14 + (3 * sce->val1)) )
  9673. break; // No more SP status should end, and in the next second will end for the other affected players
  9674. }
  9675. else
  9676. {
  9677. struct block_list *src = map_id2bl(sce->val2);
  9678. struct status_change *ssc;
  9679. if( !src || (ssc = status_get_sc(src)) == NULL || !ssc->data[SC_MAGNETICFIELD] )
  9680. break; // Source no more under Magnetic Field
  9681. }
  9682. sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
  9683. }
  9684. break;
  9685. case SC_INSPIRATION:
  9686. if(--(sce->val4) >= 0)
  9687. {
  9688. int hp = status->max_hp * (7-sce->val1) / 100;
  9689. int sp = status->max_sp * (9-sce->val1) / 100;
  9690. if( !status_charge(bl,hp,sp) ) break;
  9691. sc_timer_next(1000+tick,status_change_timer,bl->id, data);
  9692. return 0;
  9693. }
  9694. break;
  9695. case SC_RAISINGDRAGON:
  9696. // 1% every 5 seconds [Jobbie]
  9697. if( --(sce->val3)>0 && status_charge(bl, sce->val2, 0) )
  9698. {
  9699. if( !sc->data[type] ) return 0;
  9700. sc_timer_next(5000 + tick, status_change_timer, bl->id, data);
  9701. return 0;
  9702. }
  9703. break;
  9704. case SC_CIRCLE_OF_FIRE:
  9705. case SC_FIRE_CLOAK:
  9706. case SC_WATER_DROP:
  9707. case SC_WATER_SCREEN:
  9708. case SC_WIND_CURTAIN:
  9709. case SC_WIND_STEP:
  9710. case SC_STONE_SHIELD:
  9711. case SC_SOLID_SKIN:
  9712. if( !status_charge(bl,0,sce->val2) ){
  9713. struct block_list *s_bl = battle_get_master(bl);
  9714. if( s_bl )
  9715. status_change_end(s_bl,type+1,INVALID_TIMER);
  9716. status_change_end(bl,type,INVALID_TIMER);
  9717. break;
  9718. }
  9719. sc_timer_next(2000 + tick, status_change_timer, bl->id, data);
  9720. return 0;
  9721. case SC_STOMACHACHE:
  9722. if( --(sce->val4) > 0 ){
  9723. status_charge(bl,0,sce->val2); // Reduce 8 every 10 seconds.
  9724. if( sd && !pc_issit(sd) ) // Force to sit every 10 seconds.
  9725. {
  9726. pc_stop_walking(sd,1|4);
  9727. pc_stop_attack(sd);
  9728. pc_setsit(sd);
  9729. clif_sitting(bl);
  9730. }
  9731. sc_timer_next(10000 + tick, status_change_timer, bl->id, data);
  9732. return 0;
  9733. }
  9734. break;
  9735. case SC_LEADERSHIP:
  9736. case SC_GLORYWOUNDS:
  9737. case SC_SOULCOLD:
  9738. case SC_HAWKEYES:
  9739. /* they only end by status_change_end */
  9740. sc_timer_next(600000 + tick, status_change_timer, bl->id, data);
  9741. return 0;
  9742. case SC_MEIKYOUSISUI:
  9743. if( --(sce->val4) > 0 ){
  9744. status_heal(bl, status->max_hp * (sce->val1+1) / 100, status->max_sp * sce->val1 / 100, 0);
  9745. sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
  9746. return 0;
  9747. }
  9748. break;
  9749. case SC_IZAYOI:
  9750. case SC_KAGEMUSYA:
  9751. if( --(sce->val2) > 0 ){
  9752. if(!status_charge(bl, 0, 1)) break;
  9753. sc_timer_next(1000+tick, status_change_timer, bl->id, data);
  9754. return 0;
  9755. }
  9756. break;
  9757. case SC_ANGRIFFS_MODUS:
  9758. if(--(sce->val4) >= 0) { //drain hp/sp
  9759. if( !status_charge(bl,100,20) ) break;
  9760. sc_timer_next(1000+tick,status_change_timer,bl->id, data);
  9761. return 0;
  9762. }
  9763. break;
  9764. }
  9765. // default for all non-handled control paths is to end the status
  9766. return status_change_end( bl,type,tid );
  9767. #undef sc_timer_next
  9768. }
  9769. /*==========================================
  9770. * Foreach iteration of repetitive status
  9771. *------------------------------------------*/
  9772. int status_change_timer_sub(struct block_list* bl, va_list ap)
  9773. {
  9774. struct status_change* tsc;
  9775. struct block_list* src = va_arg(ap,struct block_list*);
  9776. struct status_change_entry* sce = va_arg(ap,struct status_change_entry*);
  9777. enum sc_type type = (sc_type)va_arg(ap,int); //gcc: enum args get promoted to int
  9778. unsigned int tick = va_arg(ap,unsigned int);
  9779. if (status_isdead(bl))
  9780. return 0;
  9781. tsc = status_get_sc(bl);
  9782. switch( type ) {
  9783. case SC_SIGHT: /* Reveal hidden ennemy on 3*3 range */
  9784. if( tsc && tsc->data[SC__SHADOWFORM] && (sce && sce->val4 >0 && sce->val4%2000 == 0) && // for every 2 seconds do the checking
  9785. rnd()%100 < 100-tsc->data[SC__SHADOWFORM]->val1*10 ) // [100 - (Skill Level x 10)] %
  9786. status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER);
  9787. case SC_CONCENTRATE:
  9788. status_change_end(bl, SC_HIDING, INVALID_TIMER);
  9789. status_change_end(bl, SC_CLOAKING, INVALID_TIMER);
  9790. status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER);
  9791. status_change_end(bl, SC_CAMOUFLAGE, INVALID_TIMER);
  9792. status_change_end(bl, SC__INVISIBILITY, INVALID_TIMER);
  9793. break;
  9794. case SC_RUWACH: /* Reveal hidden target and deal little dammages if ennemy */
  9795. if (tsc && (tsc->data[SC_HIDING] || tsc->data[SC_CLOAKING] ||
  9796. tsc->data[SC_CAMOUFLAGE] || tsc->data[SC_CLOAKINGEXCEED] ||
  9797. tsc->data[SC__INVISIBILITY])) {
  9798. status_change_end(bl, SC_HIDING, INVALID_TIMER);
  9799. status_change_end(bl, SC_CLOAKING, INVALID_TIMER);
  9800. status_change_end(bl, SC_CAMOUFLAGE, INVALID_TIMER);
  9801. status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER);
  9802. status_change_end(bl, SC__INVISIBILITY, INVALID_TIMER);
  9803. if(battle_check_target( src, bl, BCT_ENEMY ) > 0)
  9804. skill_attack(BF_MAGIC,src,src,bl,AL_RUWACH,1,tick,0);
  9805. }
  9806. if( tsc && tsc->data[SC__SHADOWFORM] && (sce && sce->val4 >0 && sce->val4%2000 == 0) && // for every 2 seconds do the checking
  9807. rnd()%100 < 100-tsc->data[SC__SHADOWFORM]->val1*10 ) // [100 - (Skill Level x 10)] %
  9808. status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER);
  9809. break;
  9810. case SC_SIGHTBLASTER:
  9811. if (battle_check_target( src, bl, BCT_ENEMY ) > 0 &&
  9812. status_check_skilluse(src, bl, WZ_SIGHTBLASTER, 2))
  9813. {
  9814. skill_attack(BF_MAGIC,src,src,bl,WZ_SIGHTBLASTER,1,tick,0);
  9815. if (sce && !(bl->type&BL_SKILL)) //The hit is not counted if it's against a trap
  9816. sce->val2 = 0; //This signals it to end.
  9817. }
  9818. break;
  9819. case SC_CLOSECONFINE:
  9820. //Lock char has released the hold on everyone...
  9821. if (tsc && tsc->data[SC_CLOSECONFINE2] && tsc->data[SC_CLOSECONFINE2]->val2 == src->id) {
  9822. tsc->data[SC_CLOSECONFINE2]->val2 = 0;
  9823. status_change_end(bl, SC_CLOSECONFINE2, INVALID_TIMER);
  9824. }
  9825. break;
  9826. case SC_CURSEDCIRCLE_TARGET:
  9827. if( tsc && tsc->data[SC_CURSEDCIRCLE_TARGET] && tsc->data[SC_CURSEDCIRCLE_TARGET]->val2 == src->id ) {
  9828. clif_bladestop(bl, tsc->data[SC_CURSEDCIRCLE_TARGET]->val2, 0);
  9829. status_change_end(bl, type, INVALID_TIMER);
  9830. }
  9831. break;
  9832. }
  9833. return 0;
  9834. }
  9835. /*==========================================
  9836. * Clears buffs/debuffs of a character.
  9837. * type&1 -> buffs, type&2 -> debuffs
  9838. * type&4 -> especific debuffs(implemented with refresh)
  9839. *------------------------------------------*/
  9840. int status_change_clear_buffs (struct block_list* bl, int type)
  9841. {
  9842. int i;
  9843. struct status_change *sc= status_get_sc(bl);
  9844. if (!sc || !sc->count)
  9845. return 0;
  9846. if (type&6) //Debuffs
  9847. for (i = SC_COMMON_MIN; i <= SC_COMMON_MAX; i++)
  9848. status_change_end(bl, (sc_type)i, INVALID_TIMER);
  9849. for( i = SC_COMMON_MAX+1; i < SC_MAX; i++ )
  9850. {
  9851. if(!sc->data[i])
  9852. continue;
  9853. switch (i) {
  9854. //Stuff that cannot be removed
  9855. case SC_WEIGHT50:
  9856. case SC_WEIGHT90:
  9857. case SC_COMBO:
  9858. case SC_SMA:
  9859. case SC_DANCING:
  9860. case SC_LEADERSHIP:
  9861. case SC_GLORYWOUNDS:
  9862. case SC_SOULCOLD:
  9863. case SC_HAWKEYES:
  9864. case SC_GUILDAURA:
  9865. case SC_SAFETYWALL:
  9866. case SC_PNEUMA:
  9867. case SC_NOCHAT:
  9868. case SC_JAILED:
  9869. case SC_ANKLE:
  9870. case SC_BLADESTOP:
  9871. case SC_CP_WEAPON:
  9872. case SC_CP_SHIELD:
  9873. case SC_CP_ARMOR:
  9874. case SC_CP_HELM:
  9875. case SC_STRFOOD:
  9876. case SC_AGIFOOD:
  9877. case SC_VITFOOD:
  9878. case SC_INTFOOD:
  9879. case SC_DEXFOOD:
  9880. case SC_LUKFOOD:
  9881. case SC_HITFOOD:
  9882. case SC_FLEEFOOD:
  9883. case SC_BATKFOOD:
  9884. case SC_WATKFOOD:
  9885. case SC_MATKFOOD:
  9886. case SC_FOOD_STR_CASH:
  9887. case SC_FOOD_AGI_CASH:
  9888. case SC_FOOD_VIT_CASH:
  9889. case SC_FOOD_DEX_CASH:
  9890. case SC_FOOD_INT_CASH:
  9891. case SC_FOOD_LUK_CASH:
  9892. case SC_EXPBOOST:
  9893. case SC_JEXPBOOST:
  9894. case SC_ITEMBOOST:
  9895. case SC_ELECTRICSHOCKER:
  9896. case SC__MANHOLE:
  9897. case SC_GIANTGROWTH:
  9898. case SC_MILLENNIUMSHIELD:
  9899. case SC_REFRESH:
  9900. case SC_STONEHARDSKIN:
  9901. case SC_VITALITYACTIVATION:
  9902. case SC_FIGHTINGSPIRIT:
  9903. case SC_ABUNDANCE:
  9904. case SC_CURSEDCIRCLE_ATKER:
  9905. case SC_CURSEDCIRCLE_TARGET:
  9906. continue;
  9907. //Debuffs that can be removed.
  9908. case SC_DEEPSLEEP:
  9909. case SC_BURNING:
  9910. case SC_FREEZING:
  9911. case SC_CRYSTALIZE:
  9912. case SC_TOXIN:
  9913. case SC_PARALYSE:
  9914. case SC_VENOMBLEED:
  9915. case SC_MAGICMUSHROOM:
  9916. case SC_DEATHHURT:
  9917. case SC_PYREXIA:
  9918. case SC_OBLIVIONCURSE:
  9919. case SC_LEECHESEND:
  9920. case SC_MARSHOFABYSS:
  9921. case SC_MANDRAGORA:
  9922. if(!(type&4))
  9923. continue;
  9924. break;
  9925. case SC_HALLUCINATION:
  9926. case SC_QUAGMIRE:
  9927. case SC_SIGNUMCRUCIS:
  9928. case SC_DECREASEAGI:
  9929. case SC_SLOWDOWN:
  9930. case SC_MINDBREAKER:
  9931. case SC_WINKCHARM:
  9932. case SC_STOP:
  9933. case SC_ORCISH:
  9934. case SC_STRIPWEAPON:
  9935. case SC_STRIPSHIELD:
  9936. case SC_STRIPARMOR:
  9937. case SC_STRIPHELM:
  9938. case SC_BITE:
  9939. case SC_ADORAMUS:
  9940. case SC_VACUUM_EXTREME:
  9941. case SC_FEAR:
  9942. case SC_MAGNETICFIELD:
  9943. case SC_NETHERWORLD:
  9944. if (!(type&2))
  9945. continue;
  9946. break;
  9947. //The rest are buffs that can be removed.
  9948. case SC__BLOODYLUST:
  9949. case SC_BERSERK:
  9950. case SC_SATURDAYNIGHTFEVER:
  9951. if (!(type&1))
  9952. continue;
  9953. sc->data[i]->val2 = 0;
  9954. break;
  9955. default:
  9956. if (!(type&1))
  9957. continue;
  9958. break;
  9959. }
  9960. status_change_end(bl, (sc_type)i, INVALID_TIMER);
  9961. }
  9962. return 0;
  9963. }
  9964. int status_change_spread( struct block_list *src, struct block_list *bl ) {
  9965. int i, flag = 0;
  9966. struct status_change *sc = status_get_sc(src);
  9967. const struct TimerData *timer;
  9968. unsigned int tick;
  9969. struct status_change_data data;
  9970. if( !sc || !sc->count )
  9971. return 0;
  9972. tick = gettick();
  9973. for( i = SC_COMMON_MIN; i < SC_MAX; i++ ) {
  9974. if( !sc->data[i] || i == SC_COMMON_MAX )
  9975. continue;
  9976. switch( i ) {
  9977. //Debuffs that can be spreaded.
  9978. // NOTE: We'll add/delte SCs when we are able to confirm it.
  9979. case SC_CURSE:
  9980. case SC_SILENCE:
  9981. case SC_CONFUSION:
  9982. case SC_BLIND:
  9983. case SC_NOCHAT:
  9984. case SC_HALLUCINATION:
  9985. case SC_SIGNUMCRUCIS:
  9986. case SC_DECREASEAGI:
  9987. case SC_SLOWDOWN:
  9988. case SC_MINDBREAKER:
  9989. case SC_WINKCHARM:
  9990. case SC_STOP:
  9991. case SC_ORCISH:
  9992. //case SC_STRIPWEAPON://Omg I got infected and had the urge to strip myself physically.
  9993. //case SC_STRIPSHIELD://No this is stupid and shouldnt be spreadable at all.
  9994. //case SC_STRIPARMOR:// Disabled until I can confirm if it does or not. [Rytech]
  9995. //case SC_STRIPHELM:
  9996. //case SC__STRIPACCESSORY:
  9997. case SC_BITE:
  9998. case SC_FREEZING:
  9999. case SC_VENOMBLEED:
  10000. case SC_DEATHHURT:
  10001. case SC_PARALYSE:
  10002. if( sc->data[i]->timer != INVALID_TIMER ) {
  10003. timer = get_timer(sc->data[i]->timer);
  10004. if (timer == NULL || timer->func != status_change_timer || DIFF_TICK(timer->tick,tick) < 0)
  10005. continue;
  10006. data.tick = DIFF_TICK(timer->tick,tick);
  10007. } else
  10008. data.tick = INVALID_TIMER;
  10009. break;
  10010. // Special cases
  10011. case SC_POISON:
  10012. case SC_DPOISON:
  10013. data.tick = sc->data[i]->val3 * 1000;
  10014. break;
  10015. case SC_FEAR:
  10016. case SC_LEECHESEND:
  10017. data.tick = sc->data[i]->val4 * 1000;
  10018. break;
  10019. case SC_BURNING:
  10020. data.tick = sc->data[i]->val4 * 2000;
  10021. break;
  10022. case SC_PYREXIA:
  10023. case SC_OBLIVIONCURSE:
  10024. data.tick = sc->data[i]->val4 * 3000;
  10025. break;
  10026. case SC_MAGICMUSHROOM:
  10027. data.tick = sc->data[i]->val4 * 4000;
  10028. break;
  10029. case SC_TOXIN:
  10030. case SC_BLEEDING:
  10031. data.tick = sc->data[i]->val4 * 10000;
  10032. break;
  10033. default:
  10034. continue;
  10035. break;
  10036. }
  10037. if( i ){
  10038. data.val1 = sc->data[i]->val1;
  10039. data.val2 = sc->data[i]->val2;
  10040. data.val3 = sc->data[i]->val3;
  10041. data.val4 = sc->data[i]->val4;
  10042. status_change_start(bl,(sc_type)i,10000,data.val1,data.val2,data.val3,data.val4,data.tick,1|2|8);
  10043. flag = 1;
  10044. }
  10045. }
  10046. return flag;
  10047. }
  10048. //Natural regen related stuff.
  10049. static unsigned int natural_heal_prev_tick,natural_heal_diff_tick;
  10050. static int status_natural_heal(struct block_list* bl, va_list args)
  10051. {
  10052. struct regen_data *regen;
  10053. struct status_data *status;
  10054. struct status_change *sc;
  10055. struct unit_data *ud;
  10056. struct view_data *vd = NULL;
  10057. struct regen_data_sub *sregen;
  10058. struct map_session_data *sd;
  10059. int val,rate,bonus = 0,flag;
  10060. regen = status_get_regen_data(bl);
  10061. if (!regen) return 0;
  10062. status = status_get_status_data(bl);
  10063. sc = status_get_sc(bl);
  10064. if (sc && !sc->count)
  10065. sc = NULL;
  10066. sd = BL_CAST(BL_PC,bl);
  10067. flag = regen->flag;
  10068. if (flag&RGN_HP && (status->hp >= status->max_hp || regen->state.block&1))
  10069. flag&=~(RGN_HP|RGN_SHP);
  10070. if (flag&RGN_SP && (status->sp >= status->max_sp || regen->state.block&2))
  10071. flag&=~(RGN_SP|RGN_SSP);
  10072. if (flag && (
  10073. status_isdead(bl) ||
  10074. (sc && (sc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) || sc->data[SC__INVISIBILITY]))
  10075. ))
  10076. flag=0;
  10077. if (sd) {
  10078. if (sd->hp_loss.value || sd->sp_loss.value)
  10079. pc_bleeding(sd, natural_heal_diff_tick);
  10080. if (sd->hp_regen.value || sd->sp_regen.value)
  10081. pc_regen(sd, natural_heal_diff_tick);
  10082. }
  10083. if(flag&(RGN_SHP|RGN_SSP) && regen->ssregen &&
  10084. (vd = status_get_viewdata(bl)) && vd->dead_sit == 2)
  10085. { //Apply sitting regen bonus.
  10086. sregen = regen->ssregen;
  10087. if(flag&(RGN_SHP))
  10088. { //Sitting HP regen
  10089. val = natural_heal_diff_tick * sregen->rate.hp;
  10090. if (regen->state.overweight)
  10091. val>>=1; //Half as fast when overweight.
  10092. sregen->tick.hp += val;
  10093. while(sregen->tick.hp >= (unsigned int)battle_config.natural_heal_skill_interval)
  10094. {
  10095. sregen->tick.hp -= battle_config.natural_heal_skill_interval;
  10096. if(status_heal(bl, sregen->hp, 0, 3) < sregen->hp)
  10097. { //Full
  10098. flag&=~(RGN_HP|RGN_SHP);
  10099. break;
  10100. }
  10101. }
  10102. }
  10103. if(flag&(RGN_SSP))
  10104. { //Sitting SP regen
  10105. val = natural_heal_diff_tick * sregen->rate.sp;
  10106. if (regen->state.overweight)
  10107. val>>=1; //Half as fast when overweight.
  10108. sregen->tick.sp += val;
  10109. while(sregen->tick.sp >= (unsigned int)battle_config.natural_heal_skill_interval)
  10110. {
  10111. sregen->tick.sp -= battle_config.natural_heal_skill_interval;
  10112. if(status_heal(bl, 0, sregen->sp, 3) < sregen->sp)
  10113. { //Full
  10114. flag&=~(RGN_SP|RGN_SSP);
  10115. break;
  10116. }
  10117. }
  10118. }
  10119. }
  10120. if (flag && regen->state.overweight)
  10121. flag=0;
  10122. ud = unit_bl2ud(bl);
  10123. if (flag&(RGN_HP|RGN_SHP|RGN_SSP) && ud && ud->walktimer != INVALID_TIMER)
  10124. {
  10125. flag&=~(RGN_SHP|RGN_SSP);
  10126. if(!regen->state.walk)
  10127. flag&=~RGN_HP;
  10128. }
  10129. if (!flag)
  10130. return 0;
  10131. if (flag&(RGN_HP|RGN_SP))
  10132. {
  10133. if(!vd) vd = status_get_viewdata(bl);
  10134. if(vd && vd->dead_sit == 2)
  10135. bonus++;
  10136. if(regen->state.gc)
  10137. bonus++;
  10138. }
  10139. //Natural Hp regen
  10140. if (flag&RGN_HP)
  10141. {
  10142. rate = natural_heal_diff_tick*(regen->rate.hp+bonus);
  10143. if (ud && ud->walktimer != INVALID_TIMER)
  10144. rate/=2;
  10145. // Homun HP regen fix (they should regen as if they were sitting (twice as fast)
  10146. if(bl->type==BL_HOM) rate *=2;
  10147. regen->tick.hp += rate;
  10148. if(regen->tick.hp >= (unsigned int)battle_config.natural_healhp_interval)
  10149. {
  10150. val = 0;
  10151. do {
  10152. val += regen->hp;
  10153. regen->tick.hp -= battle_config.natural_healhp_interval;
  10154. } while(regen->tick.hp >= (unsigned int)battle_config.natural_healhp_interval);
  10155. if (status_heal(bl, val, 0, 1) < val)
  10156. flag&=~RGN_SHP; //full.
  10157. }
  10158. }
  10159. //Natural SP regen
  10160. if(flag&RGN_SP)
  10161. {
  10162. rate = natural_heal_diff_tick*(regen->rate.sp+bonus);
  10163. // Homun SP regen fix (they should regen as if they were sitting (twice as fast)
  10164. if(bl->type==BL_HOM) rate *=2;
  10165. regen->tick.sp += rate;
  10166. if(regen->tick.sp >= (unsigned int)battle_config.natural_healsp_interval)
  10167. {
  10168. val = 0;
  10169. do {
  10170. val += regen->sp;
  10171. regen->tick.sp -= battle_config.natural_healsp_interval;
  10172. } while(regen->tick.sp >= (unsigned int)battle_config.natural_healsp_interval);
  10173. if (status_heal(bl, 0, val, 1) < val)
  10174. flag&=~RGN_SSP; //full.
  10175. }
  10176. }
  10177. if (!regen->sregen)
  10178. return flag;
  10179. //Skill regen
  10180. sregen = regen->sregen;
  10181. if(flag&RGN_SHP)
  10182. { //Skill HP regen
  10183. sregen->tick.hp += natural_heal_diff_tick * sregen->rate.hp;
  10184. while(sregen->tick.hp >= (unsigned int)battle_config.natural_heal_skill_interval)
  10185. {
  10186. sregen->tick.hp -= battle_config.natural_heal_skill_interval;
  10187. if(status_heal(bl, sregen->hp, 0, 3) < sregen->hp)
  10188. break; //Full
  10189. }
  10190. }
  10191. if(flag&RGN_SSP)
  10192. { //Skill SP regen
  10193. sregen->tick.sp += natural_heal_diff_tick * sregen->rate.sp;
  10194. while(sregen->tick.sp >= (unsigned int)battle_config.natural_heal_skill_interval)
  10195. {
  10196. val = sregen->sp;
  10197. if (sd && sd->state.doridori) {
  10198. val*=2;
  10199. sd->state.doridori = 0;
  10200. if ((rate = pc_checkskill(sd,TK_SPTIME)))
  10201. sc_start(bl,status_skill2sc(TK_SPTIME),
  10202. 100,rate,skill_get_time(TK_SPTIME, rate));
  10203. if (
  10204. (sd->class_&MAPID_UPPERMASK) == MAPID_STAR_GLADIATOR &&
  10205. rnd()%10000 < battle_config.sg_angel_skill_ratio
  10206. ) { //Angel of the Sun/Moon/Star
  10207. clif_feel_hate_reset(sd);
  10208. pc_resethate(sd);
  10209. pc_resetfeel(sd);
  10210. }
  10211. }
  10212. sregen->tick.sp -= battle_config.natural_heal_skill_interval;
  10213. if(status_heal(bl, 0, val, 3) < val)
  10214. break; //Full
  10215. }
  10216. }
  10217. return flag;
  10218. }
  10219. //Natural heal main timer.
  10220. static int status_natural_heal_timer(int tid, unsigned int tick, int id, intptr_t data)
  10221. {
  10222. natural_heal_diff_tick = DIFF_TICK(tick,natural_heal_prev_tick);
  10223. map_foreachregen(status_natural_heal);
  10224. natural_heal_prev_tick = tick;
  10225. return 0;
  10226. }
  10227. /**
  10228. * Get the chance to upgrade a piece of equipment.
  10229. * @param wlv The weapon type of the item to refine (see see enum refine_type)
  10230. * @param refine The target refine level
  10231. * @return The chance to refine the item, in percent (0~100)
  10232. **/
  10233. int status_get_refine_chance(enum refine_type wlv, int refine) {
  10234. if ( refine < 0 || refine >= MAX_REFINE)
  10235. return 0;
  10236. return refine_info[wlv].chance[refine];
  10237. }
  10238. /*------------------------------------------
  10239. * DB reading.
  10240. * job_db1.txt - weight, hp, sp, aspd
  10241. * job_db2.txt - job level stat bonuses
  10242. * size_fix.txt - size adjustment table for weapons
  10243. * refine_db.txt - refining data table
  10244. *------------------------------------------*/
  10245. static bool status_readdb_job1(char* fields[], int columns, int current)
  10246. {// Job-specific values (weight, HP, SP, ASPD)
  10247. int idx, class_;
  10248. unsigned int i;
  10249. class_ = atoi(fields[0]);
  10250. if(!pcdb_checkid(class_))
  10251. {
  10252. ShowWarning("status_readdb_job1: Invalid job class %d specified.\n", class_);
  10253. return false;
  10254. }
  10255. idx = pc_class2idx(class_);
  10256. max_weight_base[idx] = atoi(fields[1]);
  10257. hp_coefficient[idx] = atoi(fields[2]);
  10258. hp_coefficient2[idx] = atoi(fields[3]);
  10259. sp_coefficient[idx] = atoi(fields[4]);
  10260. #ifdef RENEWAL_ASPD
  10261. for(i = 0; i <= MAX_WEAPON_TYPE; i++)
  10262. #else
  10263. for(i = 0; i < MAX_WEAPON_TYPE; i++)
  10264. #endif
  10265. {
  10266. aspd_base[idx][i] = atoi(fields[i+5]);
  10267. }
  10268. return true;
  10269. }
  10270. static bool status_readdb_job2(char* fields[], int columns, int current)
  10271. {
  10272. int idx, class_, i;
  10273. class_ = atoi(fields[0]);
  10274. if(!pcdb_checkid(class_))
  10275. {
  10276. ShowWarning("status_readdb_job2: Invalid job class %d specified.\n", class_);
  10277. return false;
  10278. }
  10279. idx = pc_class2idx(class_);
  10280. for(i = 1; i < columns; i++)
  10281. {
  10282. job_bonus[idx][i-1] = atoi(fields[i]);
  10283. }
  10284. return true;
  10285. }
  10286. static bool status_readdb_sizefix(char* fields[], int columns, int current)
  10287. {
  10288. unsigned int i;
  10289. for(i = 0; i < MAX_WEAPON_TYPE; i++)
  10290. {
  10291. atkmods[current][i] = atoi(fields[i]);
  10292. }
  10293. return true;
  10294. }
  10295. static bool status_readdb_refine(char* fields[], int columns, int current)
  10296. {
  10297. int i, bonus_per_level, random_bonus, random_bonus_start_level;
  10298. current = atoi(fields[0]);
  10299. if (current < 0 || current >= REFINE_TYPE_MAX)
  10300. return false;
  10301. bonus_per_level = atoi(fields[1]);
  10302. random_bonus_start_level = atoi(fields[2]);
  10303. random_bonus = atoi(fields[3]);
  10304. for(i = 0; i < MAX_REFINE; i++)
  10305. {
  10306. char* delim;
  10307. if (!(delim = strchr(fields[4+i], ':')))
  10308. return false;
  10309. *delim = '\0';
  10310. refine_info[current].chance[i] = atoi(fields[4+i]);
  10311. if (i >= random_bonus_start_level - 1)
  10312. refine_info[current].randombonus_max[i] = random_bonus * (i - random_bonus_start_level + 2);
  10313. refine_info[current].bonus[i] = bonus_per_level + atoi(delim+1);
  10314. if (i > 0)
  10315. refine_info[current].bonus[i] += refine_info[current].bonus[i-1];
  10316. }
  10317. return true;
  10318. }
  10319. /*
  10320. * Read status db
  10321. * job1.txt
  10322. * job2.txt
  10323. * size_fixe.txt
  10324. * refine_db.txt
  10325. */
  10326. int status_readdb(void)
  10327. {
  10328. int i, j;
  10329. // initialize databases to default
  10330. //
  10331. // reset job_db1.txt data
  10332. memset(max_weight_base, 0, sizeof(max_weight_base));
  10333. memset(hp_coefficient, 0, sizeof(hp_coefficient));
  10334. memset(hp_coefficient2, 0, sizeof(hp_coefficient2));
  10335. memset(sp_coefficient, 0, sizeof(sp_coefficient));
  10336. memset(aspd_base, 0, sizeof(aspd_base));
  10337. // reset job_db2.txt data
  10338. memset(job_bonus,0,sizeof(job_bonus)); // Job-specific stats bonus
  10339. // size_fix.txt
  10340. for(i=0;i<ARRAYLENGTH(atkmods);i++)
  10341. for(j=0;j<MAX_WEAPON_TYPE;j++)
  10342. atkmods[i][j]=100;
  10343. // refine_db.txt
  10344. for(i=0;i<ARRAYLENGTH(refine_info);i++)
  10345. {
  10346. for(j=0;j<MAX_REFINE; j++)
  10347. {
  10348. refine_info[i].chance[j] = 100;
  10349. refine_info[i].bonus[j] = 0;
  10350. refine_info[i].randombonus_max[j] = 0;
  10351. }
  10352. }
  10353. // read databases
  10354. //
  10355. #ifdef RENEWAL_ASPD
  10356. sv_readdb(db_path, "re/job_db1.txt", ',', 6+MAX_WEAPON_TYPE, 6+MAX_WEAPON_TYPE, -1, &status_readdb_job1);
  10357. #else
  10358. sv_readdb(db_path, "pre-re/job_db1.txt", ',', 5+MAX_WEAPON_TYPE, 5+MAX_WEAPON_TYPE, -1, &status_readdb_job1);
  10359. #endif
  10360. sv_readdb(db_path, "job_db2.txt", ',', 1, 1+MAX_LEVEL, -1, &status_readdb_job2);
  10361. sv_readdb(db_path, "size_fix.txt", ',', MAX_WEAPON_TYPE, MAX_WEAPON_TYPE, ARRAYLENGTH(atkmods), &status_readdb_sizefix);
  10362. sv_readdb(db_path, DBPATH"refine_db.txt", ',', 4+MAX_REFINE, 4+MAX_REFINE, ARRAYLENGTH(refine_info), &status_readdb_refine);
  10363. return 0;
  10364. }
  10365. /*==========================================
  10366. * Status db init and destroy.
  10367. *------------------------------------------*/
  10368. int do_init_status(void)
  10369. {
  10370. add_timer_func_list(status_change_timer,"status_change_timer");
  10371. add_timer_func_list(kaahi_heal_timer,"kaahi_heal_timer");
  10372. add_timer_func_list(status_natural_heal_timer,"status_natural_heal_timer");
  10373. initChangeTables();
  10374. initDummyData();
  10375. status_readdb();
  10376. status_calc_sigma();
  10377. natural_heal_prev_tick = gettick();
  10378. sc_data_ers = ers_new(sizeof(struct status_change_entry),"status.c::sc_data_ers",ERS_OPT_NONE);
  10379. add_timer_interval(natural_heal_prev_tick + NATURAL_HEAL_INTERVAL, status_natural_heal_timer, 0, 0, NATURAL_HEAL_INTERVAL);
  10380. return 0;
  10381. }
  10382. void do_final_status(void)
  10383. {
  10384. ers_destroy(sc_data_ers);
  10385. }